diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/DebugClients/Python/DebugUtilities.py --- a/src/eric7/DebugClients/Python/DebugUtilities.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/DebugClients/Python/DebugUtilities.py Wed Jul 13 14:55:47 2022 +0200 @@ -33,14 +33,14 @@ for k, v in COMPILER_FLAG_NAMES.items(): mod_dict["CO_" + v] = k -ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') +ArgInfo = namedtuple("ArgInfo", "args varargs keywords locals") def getargvalues(frame): """ Function to get information about arguments passed into a particular frame. - + @param frame reference to a frame object to be processed @type frame @return tuple of four things, where 'args' is a list of the argument names, @@ -49,7 +49,7 @@ @exception TypeError raised if the input parameter is not a frame object """ if not isframe(frame): - raise TypeError('{0!r} is not a frame object'.format(frame)) + raise TypeError("{0!r} is not a frame object".format(frame)) args, varargs, kwonlyargs, varkw = _getfullargs(frame.f_code) return ArgInfo(args + kwonlyargs, varargs, varkw, frame.f_locals) @@ -59,7 +59,7 @@ """ Protected function to get information about the arguments accepted by a code object. - + @param co reference to a code object to be processed @type code @return tuple of four things, where 'args' and 'kwonlyargs' are lists of @@ -68,13 +68,13 @@ @exception TypeError raised if the input parameter is not a code object """ if not iscode(co): - raise TypeError('{0!r} is not a code object'.format(co)) + raise TypeError("{0!r} is not a code object".format(co)) nargs = co.co_argcount names = co.co_varnames nkwargs = co.co_kwonlyargcount args = list(names[:nargs]) - kwonlyargs = list(names[nargs:nargs + nkwargs]) + kwonlyargs = list(names[nargs : nargs + nkwargs]) nargs += nkwargs varargs = None @@ -87,15 +87,20 @@ return args, varargs, kwonlyargs, varkw -def formatargvalues(args, varargs, varkw, localsDict, - formatarg=str, - formatvarargs=lambda name: '*' + name, - formatvarkw=lambda name: '**' + name, - formatvalue=lambda value: '=' + repr(value)): +def formatargvalues( + args, + varargs, + varkw, + localsDict, + formatarg=str, + formatvarargs=lambda name: "*" + name, + formatvarkw=lambda name: "**" + name, + formatvalue=lambda value: "=" + repr(value), +): """ Function to format an argument spec from the 4 values returned by getargvalues. - + @param args list of argument names @type list of str @param varargs name of the variable arguments @@ -123,9 +128,9 @@ specs.append(formatvarargs(varargs) + formatvalue(localsDict[varargs])) if varkw: specs.append(formatvarkw(varkw) + formatvalue(localsDict[varkw])) - argvalues = '(' + ', '.join(specs) + ')' - if '__return__' in localsDict: - argvalues += " -> " + formatvalue(localsDict['__return__']) + argvalues = "(" + ", ".join(specs) + ")" + if "__return__" in localsDict: + argvalues += " -> " + formatvalue(localsDict["__return__"]) return argvalues @@ -133,7 +138,7 @@ """ Function to prepare a single command or response for transmission to the IDE. - + @param method command or response name to be sent @type str @param params dictionary of named parameters for the command or response @@ -146,7 +151,8 @@ "method": method, "params": params, } - return json.dumps(commandDict) + '\n' + return json.dumps(commandDict) + "\n" + ########################################################################### ## Things related to monkey patching below @@ -159,7 +165,7 @@ def isWindowsPlatform(): """ Function to check, if this is a Windows platform. - + @return flag indicating Windows platform @rtype bool """ @@ -169,7 +175,7 @@ def isExecutable(program): """ Function to check, if the given program is executable. - + @param program program path to be checked @type str @return flag indicating an executable program @@ -181,7 +187,7 @@ def startsWithShebang(program): """ Function to check, if the given program start with a Shebang line. - + @param program program path to be checked @type str @return flag indicating an existing and valid shebang line @@ -193,11 +199,9 @@ for line in f: line = line.strip() if line: - for name in PYTHON_NAMES: # __IGNORE_WARNING_Y110__ - if ( - line.startswith( - '#!/usr/bin/env {0}'.format(name)) or - (line.startswith('#!') and name in line) + for name in PYTHON_NAMES: # __IGNORE_WARNING_Y110__ + if line.startswith("#!/usr/bin/env {0}".format(name)) or ( + line.startswith("#!") and name in line ): return True return False @@ -214,7 +218,7 @@ """ Function to check, if the given program is a Python interpreter or program. - + @param program program to be checked @type str @return flag indicating a Python interpreter or program @@ -222,22 +226,20 @@ """ if not program: return False - + prog = os.path.basename(program).lower() if any(pyname in prog for pyname in PYTHON_NAMES): return True - + return ( - not isWindowsPlatform() and - isExecutable(program) and - startsWithShebang(program) + not isWindowsPlatform() and isExecutable(program) and startsWithShebang(program) ) def removeQuotesFromArgs(args): """ Function to remove quotes from the arguments list. - + @param args list of arguments @type list of str @return list of unquoted strings @@ -257,7 +259,7 @@ def quoteArgs(args): """ Function to quote the given list of arguments. - + @param args list of arguments to be quoted @type list of str @return list of quoted arguments @@ -269,7 +271,7 @@ if x.startswith('"') and x.endswith('"'): quotedArgs.append(x) else: - if ' ' in x: + if " " in x: x = x.replace('"', '\\"') quotedArgs.append('"{0}"'.format(x)) else: @@ -283,7 +285,7 @@ """ Function to patch the arguments given to start a program in order to execute it in our debugger. - + @param debugClient reference to the debug client object @type DebugClient @param arguments list of program arguments @@ -293,30 +295,28 @@ @return modified argument list @rtype list of str """ - debugClientScript = os.path.join( - os.path.dirname(__file__), "DebugClient.py") + debugClientScript = os.path.join(os.path.dirname(__file__), "DebugClient.py") if debugClientScript in arguments: # it is already patched return arguments - - args = list(arguments[:]) # create a copy of the arguments list + + args = list(arguments[:]) # create a copy of the arguments list args = removeQuotesFromArgs(args) - + # support for shebang line program = os.path.basename(args[0]).lower() for pyname in PYTHON_NAMES: if pyname in program: break else: - if ( - (not isWindowsPlatform() and startsWithShebang(args[0])) or - (isWindowsPlatform() and args[0].lower().endswith(".py")) + if (not isWindowsPlatform() and startsWithShebang(args[0])) or ( + isWindowsPlatform() and args[0].lower().endswith(".py") ): # 1. insert our interpreter as first argument if not Windows # 2. insert our interpreter as first argument if on Windows and # it is a Python script args.insert(0, sys.executable) - + # extract list of interpreter arguments, i.e. all arguments before the # first one not starting with '-'. interpreter = args.pop(0) @@ -345,19 +345,30 @@ interpreterArgs.append(args.pop(0)) else: break - - (wd, host, port, exceptions, tracePython, redirect, noencoding - ) = debugClient.startOptions[:7] - + + ( + wd, + host, + port, + exceptions, + tracePython, + redirect, + noencoding, + ) = debugClient.startOptions[:7] + modifiedArguments = [interpreter] modifiedArguments.extend(interpreterArgs) - modifiedArguments.extend([ - debugClientScript, - "-h", host, - "-p", str(port), - "--no-passive", - ]) - + modifiedArguments.extend( + [ + debugClientScript, + "-h", + host, + "-p", + str(port), + "--no-passive", + ] + ) + if wd: modifiedArguments.extend(["-w", wd]) if not exceptions: @@ -378,18 +389,18 @@ modifiedArguments.append(args.pop(0)) modifiedArguments.append("--") # end the arguments for DebugClient - + # append the arguments for the program to be debugged modifiedArguments.extend(args) modifiedArguments = quoteArgs(modifiedArguments) - + return modifiedArguments def stringToArgumentsWindows(args): """ Function to prepare a string of arguments for Windows platform. - + @param args list of command arguments @type str @return list of command arguments @@ -399,20 +410,20 @@ """ # see http://msdn.microsoft.com/en-us/library/a1y7w461.aspx result = [] - + DEFAULT = 0 ARG = 1 IN_DOUBLE_QUOTE = 2 - + state = DEFAULT backslashes = 0 - buf = '' - + buf = "" + argsLen = len(args) i = 0 while i < argsLen: ch = args[i] - if ch == '\\': + if ch == "\\": backslashes += 1 i += 1 continue @@ -420,11 +431,11 @@ if ch == '"': while backslashes >= 2: backslashes -= 2 - buf += '\\' + buf += "\\" if backslashes == 1: if state == DEFAULT: state = ARG - + buf += '"' backslashes = 0 i += 1 @@ -433,12 +444,12 @@ # false alarm, treat passed backslashes literally... if state == DEFAULT: state = ARG - + while backslashes > 0: backslashes -= 1 - buf += '\\' - - if ch in (' ', '\t'): + buf += "\\" + + if ch in (" ", "\t"): if state == DEFAULT: # skip i += 1 @@ -446,13 +457,13 @@ elif state == ARG: state = DEFAULT result.append(buf) - buf = '' + buf = "" i += 1 continue - + if state not in (DEFAULT, ARG, IN_DOUBLE_QUOTE): - raise RuntimeError('Illegal condition') - + raise RuntimeError("Illegal condition") + if state == IN_DOUBLE_QUOTE: if ch == '"': if i + 1 < argsLen and args[i + 1] == '"': @@ -462,32 +473,32 @@ buf += '"' i += 1 elif len(buf) == 0: - result.append("\"\"") + result.append('""') state = DEFAULT else: state = ARG else: buf += ch - + else: if ch == '"': state = IN_DOUBLE_QUOTE else: state = ARG buf += ch - + i += 1 - + if len(buf) > 0 or state != DEFAULT: result.append(buf) - + return result def patchArgumentStringWindows(debugClient, argStr): """ Function to patch an argument string for Windows. - + @param debugClient reference to the debug client object @type DebugClient @param argStr argument string @@ -498,6 +509,6 @@ args = stringToArgumentsWindows(argStr) if not args or not isPythonProgram(args[0]): return argStr - - argStr = ' '.join(patchArguments(debugClient, args)) + + argStr = " ".join(patchArguments(debugClient, args)) return argStr