--- a/DebugClients/Python2/DebugClientBase.py Wed Sep 14 20:08:16 2016 +0200 +++ b/DebugClients/Python2/DebugClientBase.py Fri Sep 16 19:28:39 2016 +0200 @@ -27,6 +27,7 @@ from DebugConfig import ConfigVarTypeStrings from FlexCompleter import Completer from DebugUtilities import prepareJsonCommand +import DebugVariables DebugClientInstance = None @@ -164,6 +165,9 @@ """ clientCapabilities = DebugClientCapabilities.HasAll + # keep these in sync with VariablesViewer.VariableItem.Indicators + Indicators = ("()", "[]", "{:}", "{}") # __IGNORE_WARNING__ + def __init__(self): """ Constructor @@ -1431,217 +1435,25 @@ varlist = [] if scope != -1: - # search the correct dictionary - i = 0 - rvar = var[:] - dictkeys = None - obj = None - isDict = False - formatSequences = False - access = "" - oaccess = "" - odict = dict - - qtVariable = False - qvar = None - qvtype = "" - - while i < len(var): - if len(dict): - udict = dict - ndict = {} - # this has to be in line with VariablesViewer.indicators - if var[i][-2:] in ["[]", "()", "{}"]: # __IGNORE_WARNING__ - if i + 1 == len(var): - if var[i][:-2] == '...': - dictkeys = [var[i - 1]] - else: - dictkeys = [var[i][:-2]] - formatSequences = True - if not access and not oaccess: - if var[i][:-2] == '...': - access = '["%s"]' % var[i - 1] - dict = odict - else: - access = '["%s"]' % var[i][:-2] - else: - if var[i][:-2] == '...': - if oaccess: - access = oaccess - else: - access = '%s[%s]' % (access, var[i - 1]) - dict = odict - else: - if oaccess: - access = '%s[%s]' % (oaccess, var[i][:-2]) - oaccess = '' - else: - access = '%s[%s]' % (access, var[i][:-2]) - if var[i][-2:] == "{}": # __IGNORE_WARNING__ - isDict = True - break - else: - if not access: - if var[i][:-2] == '...': - access = '["%s"]' % var[i - 1] - dict = odict - else: - access = '["%s"]' % var[i][:-2] - else: - if var[i][:-2] == '...': - access = '%s[%s]' % (access, var[i - 1]) - dict = odict - else: - if oaccess: - access = '%s[%s]' % (oaccess, var[i][:-2]) - oaccess = '' - else: - access = '%s[%s]' % (access, var[i][:-2]) + variable = dict + for attribute in var: + attribute = self.__extractIndicators(attribute)[0] + typeObject, typeName, typeStr, resolver = \ + DebugVariables.getType(variable) + if resolver: + variable = resolver.resolve(variable, attribute) else: - if access: - if oaccess: - access = '%s[%s]' % (oaccess, var[i]) - else: - access = '%s[%s]' % (access, var[i]) - if var[i - 1][:-2] == '...': - oaccess = access - else: - oaccess = '' - try: - exec 'mdict = dict%s.__dict__' % access - ndict.update(mdict) # __IGNORE_WARNING__ - exec 'obj = dict%s' % access - if "PyQt4." in str(type(obj)) or \ - "PyQt5." in str(type(obj)): - qtVariable = True - qvar = obj - qvtype = ("%s" % type(qvar))[1:-1]\ - .split()[1][1:-1] - except Exception: - pass - try: - exec 'mcdict = dict%s.__class__.__dict__' % access - ndict.update(mcdict) # __IGNORE_WARNING__ - if mdict and "sipThis" not in mdict.keys(): # __IGNORE_WARNING__ - del rvar[0:2] - access = "" - except Exception: - pass - try: - cdict = {} - exec 'slv = dict%s.__slots__' % access - for v in slv: # __IGNORE_WARNING__ - try: - exec 'cdict[v] = dict%s.%s' % (access, v) - except Exception: - pass - ndict.update(cdict) - exec 'obj = dict%s' % access - access = "" - if "PyQt4." in str(type(obj)) or \ - "PyQt5." in str(type(obj)): - qtVariable = True - qvar = obj - qvtype = ("%s" % type(qvar))[1:-1]\ - .split()[1][1:-1] - except Exception: - pass - else: - try: - ndict.update(dict[var[i]].__dict__) - ndict.update(dict[var[i]].__class__.__dict__) - del rvar[0] - obj = dict[var[i]] - if "PyQt4." in str(type(obj)) or \ - "PyQt5." in str(type(obj)): - qtVariable = True - qvar = obj - qvtype = ("%s" % type(qvar))[1:-1]\ - .split()[1][1:-1] - except Exception: - pass - try: - cdict = {} - slv = dict[var[i]].__slots__ - for v in slv: - try: - exec 'cdict[v] = dict[var[i]].%s' % v - except Exception: - pass - ndict.update(cdict) - obj = dict[var[i]] - if "PyQt4." in str(type(obj)) or \ - "PyQt5." in str(type(obj)): - qtVariable = True - qvar = obj - qvtype = ("%s" % type(qvar))[1:-1]\ - .split()[1][1:-1] - except Exception: - pass - odict = dict - dict = ndict - i += 1 - - if qtVariable: - vlist = self.__formatQtVariable(qvar, qvtype) - elif ("sipThis" in dict.keys() and len(dict) == 1) or \ - (len(dict) == 0 and len(udict) > 0): - if access: - exec 'qvar = udict%s' % access - # this has to be in line with VariablesViewer.indicators - elif rvar and rvar[0][-2:] in ["[]", "()", "{}"]: # __IGNORE_WARNING__ - exec 'qvar = udict["%s"][%s]' % (rvar[0][:-2], rvar[1]) - else: - qvar = udict[var[-1]] - qvtype = ("%s" % type(qvar))[1:-1].split()[1][1:-1] - if qvtype.startswith(("PyQt4", "PyQt5")): - vlist = self.__formatQtVariable(qvar, qvtype) - else: - vlist = [] - else: - qtVariable = False - if len(dict) == 0 and len(udict) > 0: - if access: - exec 'qvar = udict%s' % access - # this has to be in line with VariablesViewer.indicators - elif rvar and rvar[0][-2:] in ["[]", "()", "{}"]: # __IGNORE_WARNING__ - exec 'qvar = udict["%s"][%s]' % (rvar[0][:-2], rvar[1]) - else: - qvar = udict[var[-1]] - qvtype = ("%s" % type(qvar))[1:-1].split()[1][1:-1] - if qvtype.startswith(("PyQt4", "PyQt5")): - qtVariable = True - - if qtVariable: - vlist = self.__formatQtVariable(qvar, qvtype) - else: - # format the dictionary found - if dictkeys is None: - dictkeys = dict.keys() - else: - # treatment for sequences and dictionaries - if access: - exec "dict = dict%s" % access - else: - dict = dict[dictkeys[0]] - if isDict: - dictkeys = dict.keys() - else: - dictkeys = range(len(dict)) - vlist = self.__formatVariablesList( - dictkeys, dict, scope, filter, formatSequences) - varlist.extend(vlist) - - if obj is not None and not formatSequences: - try: - if unicode(repr(obj)).startswith('{'): - varlist.append(('...', 'dict', "%d" % len(obj.keys()))) - elif unicode(repr(obj)).startswith('['): - varlist.append(('...', 'list', "%d" % len(obj))) - elif unicode(repr(obj)).startswith('('): - varlist.append(('...', 'tuple', "%d" % len(obj))) - except Exception: - pass + break + typeObject, typeName, typeStr, resolver = \ + DebugVariables.getType(variable) + if typeStr.startswith(("PyQt5.", "PyQt4.")): + vlist = self.__formatQtVariable(variable, typeName) + varlist.extend(vlist) + elif resolver: + dict = resolver.getDictionary(variable) + vlist = self.__formatVariablesList( + list(dict.keys()), dict, scope, filter) + varlist.extend(vlist) self.sendJsonCommand("ResponseVariable", { "scope": scope, @@ -1649,17 +1461,32 @@ "variables": varlist, }) - def __formatQtVariable(self, value, vtype): + def __extractIndicators(self, var): + """ + Private method to extract the indicator string from a variable text. + + @param var variable text + @type str + @return tuple containing the variable text without indicators and the + indicator string + @rtype tuple of two str """ - Private method to produce a formated output of a simple Qt4/Qt5 type. + for indicator in DebugClientBase.Indicators: + if var.endswith(indicator): + return var[:-len(indicator)], indicator + + return var, "" - @param value variable to be formated - @param vtype type of the variable to be formatted (string) + def __formatQtVariable(self, value, qttype): + """ + Private method to produce a formatted output of a simple Qt4/Qt5 type. + + @param value variable to be formatted + @param qttype type of the Qt variable to be formatted (string) @return A tuple consisting of a list of formatted variables. Each variable entry is a tuple of three elements, the variable name, its type and value. """ - qttype = vtype.split('.')[-1] varlist = [] if qttype == 'QChar': varlist.append(("", "QChar", "%s" % unichr(value.unicode()))) @@ -1782,7 +1609,7 @@ return varlist def __formatVariablesList(self, keylist, dict, scope, filter=[], - formatSequences=0): + formatSequences=False): """ Private method to produce a formated variables list. @@ -1825,7 +1652,9 @@ continue # filter hidden attributes (filter #0) - if 0 in filter and unicode(key)[:2] == '__': + if 0 in filter and unicode(key)[:2] == '__' and not ( + key == "___len___" and + DebugVariables.TooLargeAttribute in keylist): continue # special handling for '__builtins__' (it's way too big) @@ -1835,7 +1664,7 @@ else: value = dict[key] valtypestr = ("%s" % type(value))[1:-1] - + if valtypestr.split(' ', 1)[0] == 'class': # handle new class type of python 2.2+ if ConfigVarTypeStrings.index('instance') in filter: @@ -1853,7 +1682,7 @@ continue elif valtype == "sip.methoddescriptor": if ConfigVarTypeStrings.index( - 'instance method') in filter: + 'method') in filter: continue elif valtype == "sip.enumtype": if ConfigVarTypeStrings.index('class') in filter: @@ -1863,7 +1692,8 @@ continue try: - if valtype not in ['list', 'tuple', 'dict']: + if valtype not in ['list', 'tuple', 'dict', 'set', + 'frozenset']: rvalue = repr(value) if valtype.startswith('class') and \ rvalue[0] in ['{', '(', '[']: