--- a/DebugClients/Python/DebugClientBase.py Thu Mar 23 18:58:56 2017 +0100 +++ b/DebugClients/Python/DebugClientBase.py Fri Apr 07 18:33:59 2017 +0200 @@ -179,7 +179,7 @@ clientCapabilities = DebugClientCapabilities.HasAll # keep these in sync with VariablesViewer.VariableItem.Indicators - Indicators = ("()", "[]", "{:}", "{}") # __IGNORE_WARNING__ + Indicators = ("()", "[]", "{:}", "{}") # __IGNORE_WARNING_M613__ def __init__(self): """ @@ -223,9 +223,6 @@ self.variant = 'You should not see this' - # commandline completion stuff - self.complete = Completer(self.debugMod.__dict__).complete - self.compile_command = codeop.CommandCompiler() self.coding_re = re.compile(r"coding[:=]\s*([-\w_.]+)") @@ -292,12 +289,12 @@ """ return eval(self.raw_input(prompt, True)) - def sessionClose(self, exit=True): + def sessionClose(self, terminate=True): """ Public method to close the session with the debugger and optionally terminate. - @param exit flag indicating to terminate (boolean) + @param terminate flag indicating to terminate (boolean) """ try: self.set_quit() @@ -313,7 +310,7 @@ self.writestream.close(True) self.errorstream.close(True) - if exit: + if terminate: # Ok, go away. sys.exit() @@ -726,6 +723,10 @@ self.set_quit() self.eventExit = True + elif method == "RequestMoveIP": + newLine = params["newLine"] + self.currentThreadExec.move_instruction_pointer(newLine) + elif method == "RequestContinue": self.currentThreadExec.go(params["special"]) self.eventExit = True @@ -1320,14 +1321,14 @@ # reset coding self.__coding = self.defaultCoding - def __dumpVariables(self, frmnr, scope, filter): + def __dumpVariables(self, frmnr, scope, filterList): """ Private method to return the variables of a frame to the debug server. @param frmnr distance of frame reported on. 0 is the current frame (int) @param scope 1 to report global variables, 0 for local variables (int) - @param filter the indices of variable types to be filtered + @param filterList the indices of variable types to be filtered (list of int) """ if self.currentThread is None: @@ -1345,22 +1346,23 @@ if f is None: if scope: - dict = self.debugMod.__dict__ + varDict = self.debugMod.__dict__ else: scope = -1 elif scope: - dict = f.f_globals + varDict = f.f_globals elif f.f_globals is f.f_locals: scope = -1 else: - dict = f.f_locals + varDict = f.f_locals varlist = [] if scope != -1: - keylist = dict.keys() + keylist = varDict.keys() - vlist = self.__formatVariablesList(keylist, dict, scope, filter) + vlist = self.__formatVariablesList( + keylist, varDict, scope, filterList) varlist.extend(vlist) self.sendJsonCommand("ResponseVariables", { @@ -1368,7 +1370,7 @@ "variables": varlist, }) - def __dumpVariable(self, var, frmnr, scope, filter): + def __dumpVariable(self, var, frmnr, scope, filterList): """ Private method to return the variables of a frame to the debug server. @@ -1377,7 +1379,7 @@ @param frmnr distance of frame reported on. 0 is the current frame (int) @param scope 1 to report global variables, 0 for local variables (int) - @param filter the indices of variable types to be filtered + @param filterList the indices of variable types to be filtered (list of int) """ if self.currentThread is None: @@ -1392,20 +1394,20 @@ if f is None: if scope: - dict = self.debugMod.__dict__ + varDict = self.debugMod.__dict__ else: scope = -1 elif scope: - dict = f.f_globals + varDict = f.f_globals elif f.f_globals is f.f_locals: scope = -1 else: - dict = f.f_locals + varDict = f.f_locals varlist = [] if scope != -1: - variable = dict + variable = varDict for attribute in var: attribute = self.__extractIndicators(attribute)[0] typeObject, typeName, typeStr, resolver = \ @@ -1425,9 +1427,9 @@ vlist = self.__formatQtVariable(variable, typeName) varlist.extend(vlist) elif resolver: - dict = resolver.getDictionary(variable) + varDict = resolver.getDictionary(variable) vlist = self.__formatVariablesList( - list(dict.keys()), dict, scope, filter) + list(varDict.keys()), varDict, scope, filterList) varlist.extend(vlist) self.sendJsonCommand("ResponseVariable", { @@ -1597,7 +1599,7 @@ return varlist - def __formatVariablesList(self, keylist, dict_, scope, filter=[], + def __formatVariablesList(self, keylist, dict_, scope, filterList=None, formatSequences=False): """ Private method to produce a formated variables list. @@ -1614,9 +1616,9 @@ filter (int). Variables are only added to the list, if their name do not match any of the filter expressions. - @param filter the indices of variable types to be filtered. Variables - are only added to the list, if their type is not contained in the - filter list. + @param filterList the indices of variable types to be filtered. + Variables are only added to the list, if their type is not + contained in the filter list. @param formatSequences flag indicating, that sequence or dictionary variables should be formatted. If it is 0 (or false), just the number of items contained in these variables is returned. (boolean) @@ -1624,6 +1626,8 @@ variable entry is a tuple of three elements, the variable name, its type and value. """ + filterList = [] if filterList is None else filterList[:] + varlist = [] if scope: patternFilterObjects = self.globalsFilterObjects @@ -1641,7 +1645,7 @@ continue # filter hidden attributes (filter #0) - if 0 in filter and str(key)[:2] == '__' and not ( + if 0 in filterList and str(key)[:2] == '__' and not ( key == "___len___" and DebugVariables.TooLargeAttribute in keylist): continue @@ -1658,19 +1662,19 @@ valtypename = type(value).__name__ if valtype not in ConfigVarTypeStrings: if valtype in ["numpy.ndarray", "array.array"]: - if ConfigVarTypeStrings.index('list') in filter: + if ConfigVarTypeStrings.index('list') in filterList: continue elif valtypename == "MultiValueDict": - if ConfigVarTypeStrings.index('dict') in filter: + if ConfigVarTypeStrings.index('dict') in filterList: continue elif valtype == "sip.methoddescriptor": if ConfigVarTypeStrings.index( - 'method') in filter: + 'method') in filterList: continue elif valtype == "sip.enumtype": - if ConfigVarTypeStrings.index('class') in filter: + if ConfigVarTypeStrings.index('class') in filterList: continue - elif ConfigVarTypeStrings.index('instance') in filter: + elif ConfigVarTypeStrings.index('instance') in filterList: continue if (not valtypestr.startswith('type ') and @@ -1683,22 +1687,24 @@ if valtype == "instancemethod": valtype = "method" - if ConfigVarTypeStrings.index(valtype) in filter: + if ConfigVarTypeStrings.index(valtype) in filterList: continue except ValueError: if valtype == "classobj": if ConfigVarTypeStrings.index( - 'instance') in filter: + 'instance') in filterList: continue elif valtype == "sip.methoddescriptor": if ConfigVarTypeStrings.index( - 'method') in filter: + 'method') in filterList: continue elif valtype == "sip.enumtype": - if ConfigVarTypeStrings.index('class') in filter: + if ConfigVarTypeStrings.index('class') in \ + filterList: continue elif not valtype.startswith("PySide") and \ - ConfigVarTypeStrings.index('other') in filter: + (ConfigVarTypeStrings.index('other') in + filterList): continue try: @@ -1773,7 +1779,20 @@ self.__getCompletionList(text, localCompleter, completions) except AttributeError: pass - self.__getCompletionList(text, self.complete, completions) + + cf = self.currentThread.getCurrentFrame() + frmnr = self.framenr + while cf is not None and frmnr > 0: + cf = cf.f_back + frmnr -= 1 + + if cf is None: + globaldict = self.debugMod.__dict__ + else: + globaldict = cf.f_globals + + globalCompleter = Completer(globaldict).complete + self.__getCompletionList(text, globalCompleter, completions) self.sendJsonCommand("ResponseCompletion", { "completions": list(completions), @@ -2002,7 +2021,8 @@ else: # unknown option del args[0] if not args: - print("No program given. Aborting!") # __IGNORE_WARNING__ + print("No program given. Aborting!") + # __IGNORE_WARNING_M801__ else: if not self.noencoding: self.__coding = self.defaultCoding @@ -2043,7 +2063,8 @@ self.connectDebugger(port, remoteAddress, redirect) self.__interact() else: - print("No network port given. Aborting...") # __IGNORE_WARNING__ + print("No network port given. Aborting...") + # __IGNORE_WARNING_M801__ def fork(self): """ @@ -2061,13 +2082,13 @@ if not self.fork_child: sys.settrace(None) sys.setprofile(None) - self.sessionClose(0) + self.sessionClose(False) else: # parent if self.fork_child: sys.settrace(None) sys.setprofile(None) - self.sessionClose(0) + self.sessionClose(False) return pid def close(self, fd):