79 |
79 |
80 def DebugClientClose(fd): |
80 def DebugClientClose(fd): |
81 """ |
81 """ |
82 Replacement for the standard os.close(fd). |
82 Replacement for the standard os.close(fd). |
83 |
83 |
84 @param fd open file descriptor to be closed (integer) |
84 @param fd open file descriptor to be closed |
|
85 @type int |
85 """ |
86 """ |
86 if DebugClientInstance is None: |
87 if DebugClientInstance is None: |
87 DebugClientOrigClose(fd) |
88 DebugClientOrigClose(fd) |
88 else: |
89 else: |
89 DebugClientInstance.close(fd) |
90 DebugClientInstance.close(fd) |
99 |
100 |
100 def DebugClientSetRecursionLimit(limit): |
101 def DebugClientSetRecursionLimit(limit): |
101 """ |
102 """ |
102 Replacement for the standard sys.setrecursionlimit(limit). |
103 Replacement for the standard sys.setrecursionlimit(limit). |
103 |
104 |
104 @param limit recursion limit (integer) |
105 @param limit recursion limit |
|
106 @type int |
105 """ |
107 """ |
106 rl = max(limit, 64) |
108 rl = max(limit, 64) |
107 setRecursionLimit(rl) |
109 setRecursionLimit(rl) |
108 DebugClientOrigSetRecursionLimit(rl + 64) |
110 DebugClientOrigSetRecursionLimit(rl + 64) |
109 |
111 |
205 |
207 |
206 def getCoding(self): |
208 def getCoding(self): |
207 """ |
209 """ |
208 Public method to return the current coding. |
210 Public method to return the current coding. |
209 |
211 |
210 @return codec name (string) |
212 @return codec name |
|
213 @rtype str |
211 """ |
214 """ |
212 return self.__coding |
215 return self.__coding |
213 |
216 |
214 def __setCoding(self, filename): |
217 def __setCoding(self, filename): |
215 """ |
218 """ |
216 Private method to set the coding used by a python file. |
219 Private method to set the coding used by a python file. |
217 |
220 |
218 @param filename name of the file to inspect (string) |
221 @param filename name of the file to inspect |
|
222 @type str |
219 """ |
223 """ |
220 if self.noencoding: |
224 if self.noencoding: |
221 self.__coding = sys.getdefaultencoding() |
225 self.__coding = sys.getdefaultencoding() |
222 else: |
226 else: |
223 default = "utf-8" |
227 default = "utf-8" |
261 def sessionClose(self, terminate=True): |
265 def sessionClose(self, terminate=True): |
262 """ |
266 """ |
263 Public method to close the session with the debugger and optionally |
267 Public method to close the session with the debugger and optionally |
264 terminate. |
268 terminate. |
265 |
269 |
266 @param terminate flag indicating to terminate (boolean) |
270 @param terminate flag indicating to terminate |
|
271 @type bool |
267 """ |
272 """ |
268 with contextlib.suppress(Exception): # secok |
273 with contextlib.suppress(Exception): # secok |
269 self.set_quit() |
274 self.set_quit() |
270 |
275 |
271 self.debugging = False |
276 self.debugging = False |
291 @param filename name of the source file |
296 @param filename name of the source file |
292 @type str |
297 @type str |
293 @param mode kind of code to be generated (exec or eval) |
298 @param mode kind of code to be generated (exec or eval) |
294 @type str |
299 @type str |
295 @return compiled code object (None in case of errors) |
300 @return compiled code object (None in case of errors) |
|
301 @rtype Code |
296 """ |
302 """ |
297 with codecs.open(filename, encoding=self.__coding) as fp: |
303 with codecs.open(filename, encoding=self.__coding) as fp: |
298 statement = fp.read() |
304 statement = fp.read() |
299 |
305 |
300 return self.__compileCommand(statement, filename=filename, mode=mode) |
306 return self.__compileCommand(statement, filename=filename, mode=mode) |
308 @param filename name of the source file |
314 @param filename name of the source file |
309 @type str |
315 @type str |
310 @param mode kind of code to be generated (exec or eval) |
316 @param mode kind of code to be generated (exec or eval) |
311 @type str |
317 @type str |
312 @return compiled code object (None in case of errors) |
318 @return compiled code object (None in case of errors) |
|
319 @rtype Code |
313 """ |
320 """ |
314 try: |
321 try: |
315 code = compile(statement + "\n", filename, mode) |
322 code = compile(statement + "\n", filename, mode) |
316 except SyntaxError: |
323 except SyntaxError: |
317 exctype, excval, exctb = sys.exc_info() |
324 exctype, excval, exctb = sys.exc_info() |
339 Public method to handle a command serialized as a JSON string. |
346 Public method to handle a command serialized as a JSON string. |
340 |
347 |
341 @param jsonStr string containing the command received from the IDE |
348 @param jsonStr string containing the command received from the IDE |
342 @type str |
349 @type str |
343 """ |
350 """ |
344 ## printerr(jsonStr) ## debug # __IGNORE_WARNING_M891__ |
351 ## printerr(jsonStr) ## debug # noqa: M891 |
345 |
352 |
346 try: |
353 try: |
347 commandDict = json.loads(jsonStr.strip()) |
354 commandDict = json.loads(jsonStr.strip()) |
348 except (TypeError, ValueError) as err: |
355 except (TypeError, ValueError) as err: |
349 printerr("Error handling command: " + jsonStr) |
356 printerr("Error handling command: " + jsonStr) |
890 """ |
897 """ |
891 Public method to signal the deletion of a temporary breakpoint. |
898 Public method to signal the deletion of a temporary breakpoint. |
892 |
899 |
893 @param filename name of the file the bp belongs to |
900 @param filename name of the file the bp belongs to |
894 @type str |
901 @type str |
895 @param lineno linenumber of the bp |
902 @param lineno line number of the bp |
896 @type int |
903 @type int |
897 """ |
904 """ |
898 self.sendJsonCommand( |
905 self.sendJsonCommand( |
899 "ResponseClearBreakpoint", {"filename": filename, "line": lineno} |
906 "ResponseClearBreakpoint", {"filename": filename, "line": lineno} |
900 ) |
907 ) |
1027 |
1034 |
1028 def __clientCapabilities(self): |
1035 def __clientCapabilities(self): |
1029 """ |
1036 """ |
1030 Private method to determine the clients capabilities. |
1037 Private method to determine the clients capabilities. |
1031 |
1038 |
1032 @return client capabilities (integer) |
1039 @return client capabilities |
|
1040 @rtype int |
1033 """ |
1041 """ |
1034 if importlib.util.find_spec("PyProfile") is None: |
1042 if importlib.util.find_spec("PyProfile") is None: |
1035 return self.clientCapabilities & ~DebugClientCapabilities.HasProfiler |
1043 return self.clientCapabilities & ~DebugClientCapabilities.HasProfiler |
1036 else: |
1044 else: |
1037 return self.clientCapabilities |
1045 return self.clientCapabilities |
1086 def eventLoop(self, disablePolling=False): |
1096 def eventLoop(self, disablePolling=False): |
1087 """ |
1097 """ |
1088 Public method implementing our event loop. |
1098 Public method implementing our event loop. |
1089 |
1099 |
1090 @param disablePolling flag indicating to enter an event loop with |
1100 @param disablePolling flag indicating to enter an event loop with |
1091 polling disabled (boolean) |
1101 polling disabled |
|
1102 @type bool |
1092 """ |
1103 """ |
1093 self.eventExit = False |
1104 self.eventExit = False |
1094 self.pollingDisabled = disablePolling |
1105 self.pollingDisabled = disablePolling |
1095 selectErrors = 0 |
1106 selectErrors = 0 |
1096 |
1107 |
1218 |
1229 |
1219 def __unhandled_exception(self, exctype, excval, exctb): |
1230 def __unhandled_exception(self, exctype, excval, exctb): |
1220 """ |
1231 """ |
1221 Private method called to report an uncaught exception. |
1232 Private method called to report an uncaught exception. |
1222 |
1233 |
1223 @param exctype the type of the exception |
1234 @param exctype class of the exception |
1224 @param excval data about the exception |
1235 @type type |
|
1236 @param excval exception instance |
|
1237 @type Exception |
1225 @param exctb traceback for the exception |
1238 @param exctb traceback for the exception |
|
1239 @type traceback |
1226 """ |
1240 """ |
1227 self.mainThread.user_exception((exctype, excval, exctb), True) |
1241 self.mainThread.user_exception((exctype, excval, exctb), True) |
1228 |
1242 |
1229 def __interceptSignals(self): |
1243 def __interceptSignals(self): |
1230 """ |
1244 """ |
1293 Public method to convert a filename to an absolute name. |
1307 Public method to convert a filename to an absolute name. |
1294 |
1308 |
1295 sys.path is used as a set of possible prefixes. The name stays |
1309 sys.path is used as a set of possible prefixes. The name stays |
1296 relative if a file could not be found. |
1310 relative if a file could not be found. |
1297 |
1311 |
1298 @param fn filename (string) |
1312 @param fn filename |
1299 @return the converted filename (string) |
1313 @type str |
|
1314 @return the converted filename |
|
1315 @rtype str |
1300 """ |
1316 """ |
1301 if os.path.isabs(fn): |
1317 if os.path.isabs(fn): |
1302 return fn |
1318 return fn |
1303 |
1319 |
1304 # Check the cache. |
1320 # Check the cache. |
1331 |
1347 |
1332 def getRunning(self): |
1348 def getRunning(self): |
1333 """ |
1349 """ |
1334 Public method to return the main script we are currently running. |
1350 Public method to return the main script we are currently running. |
1335 |
1351 |
1336 @return flag indicating a running debug session (boolean) |
1352 @return flag indicating a running debug session |
|
1353 @rtype bool |
1337 """ |
1354 """ |
1338 return self.running |
1355 return self.running |
1339 |
1356 |
1340 def progTerminated(self, status, message="", closeSession=True): |
1357 def progTerminated(self, status, message="", closeSession=True): |
1341 """ |
1358 """ |
1673 def __generateFilterObjects(self, scope, filterString): |
1690 def __generateFilterObjects(self, scope, filterString): |
1674 """ |
1691 """ |
1675 Private slot to convert a filter string to a list of filter objects. |
1692 Private slot to convert a filter string to a list of filter objects. |
1676 |
1693 |
1677 @param scope 1 to generate filter for global variables, 0 for local |
1694 @param scope 1 to generate filter for global variables, 0 for local |
1678 variables (int) |
1695 variables |
|
1696 @type int |
1679 @param filterString string of filter patterns separated by ';' |
1697 @param filterString string of filter patterns separated by ';' |
|
1698 @type str |
1680 """ |
1699 """ |
1681 patternFilterObjects = None |
1700 patternFilterObjects = None |
1682 filterString = filterString.strip() |
1701 filterString = filterString.strip() |
1683 if filterString: |
1702 if filterString: |
1684 if filterString[0] == "~": |
1703 if filterString[0] == "~": |
1701 |
1720 |
1702 def __completionList(self, text): |
1721 def __completionList(self, text): |
1703 """ |
1722 """ |
1704 Private slot to handle the request for a commandline completion list. |
1723 Private slot to handle the request for a commandline completion list. |
1705 |
1724 |
1706 @param text the text to be completed (string) |
1725 @param text the text to be completed |
|
1726 @type str |
1707 """ |
1727 """ |
1708 completerDelims = " \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?" |
1728 completerDelims = " \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?" |
1709 |
1729 |
1710 completions = set() |
1730 completions = set() |
1711 # find position of last delim character |
1731 # find position of last delim character |
1740 |
1760 |
1741 def __getCompletionList(self, text, completer, completions): |
1761 def __getCompletionList(self, text, completer, completions): |
1742 """ |
1762 """ |
1743 Private method to create a completions list. |
1763 Private method to create a completions list. |
1744 |
1764 |
1745 @param text text to complete (string) |
1765 @param text text to complete |
|
1766 @type str |
1746 @param completer completer method |
1767 @param completer completer method |
1747 @param completions set where to add new completions strings (set) |
1768 @type function |
|
1769 @param completions set where to add new completions strings |
|
1770 @type set |
1748 """ |
1771 """ |
1749 state = 0 |
1772 state = 0 |
1750 try: |
1773 try: |
1751 comp = completer(text, state) |
1774 comp = completer(text, state) |
1752 except Exception: |
1775 except Exception: |
1964 |
1987 |
1965 def run_call(self, scriptname, func, *args): |
1988 def run_call(self, scriptname, func, *args): |
1966 """ |
1989 """ |
1967 Public method used to start the remote debugger and call a function. |
1990 Public method used to start the remote debugger and call a function. |
1968 |
1991 |
1969 @param scriptname name of the script to be debugged (string) |
1992 @param scriptname name of the script to be debugged |
|
1993 @type str |
1970 @param func function to be called |
1994 @param func function to be called |
|
1995 @type function |
1971 @param *args arguments being passed to func |
1996 @param *args arguments being passed to func |
|
1997 @type list |
1972 @return result of the function call |
1998 @return result of the function call |
|
1999 @rtype Any |
1973 """ |
2000 """ |
1974 self.startDebugger(scriptname, enableTrace=False) |
2001 self.startDebugger(scriptname, enableTrace=False) |
1975 res = self.mainThread.runcall(func, *args) |
2002 res = self.mainThread.runcall(func, *args) |
1976 self.progTerminated(res, closeSession=False) |
2003 self.progTerminated(res, closeSession=False) |
1977 return res |
2004 return res |
1978 |
2005 |
1979 def __resolveHost(self, host): |
2006 def __resolveHost(self, host): |
1980 """ |
2007 """ |
1981 Private method to resolve a hostname to an IP address. |
2008 Private method to resolve a hostname to an IP address. |
1982 |
2009 |
1983 @param host hostname of the debug server (string) |
2010 @param host hostname of the debug server |
1984 @return IP address (string) |
2011 @type str |
|
2012 @return IP address |
|
2013 @rtype str |
1985 """ |
2014 """ |
1986 try: |
2015 try: |
1987 host, version = host.split("@@") |
2016 host, version = host.split("@@") |
1988 except ValueError: |
2017 except ValueError: |
1989 version = "v4" |
2018 version = "v4" |
2166 Public method implementing a close method as a replacement for |
2195 Public method implementing a close method as a replacement for |
2167 os.close(). |
2196 os.close(). |
2168 |
2197 |
2169 It prevents the debugger connections from being closed. |
2198 It prevents the debugger connections from being closed. |
2170 |
2199 |
2171 @param fd file descriptor to be closed (integer) |
2200 @param fd file descriptor to be closed |
|
2201 @type int |
2172 """ |
2202 """ |
2173 if fd in [ |
2203 if fd in [ |
2174 self.readstream.fileno(), |
2204 self.readstream.fileno(), |
2175 self.writestream.fileno(), |
2205 self.writestream.fileno(), |
2176 self.errorstream.fileno(), |
2206 self.errorstream.fileno(), |
2182 def __getSysPath(self, firstEntry): |
2212 def __getSysPath(self, firstEntry): |
2183 """ |
2213 """ |
2184 Private slot to calculate a path list including the PYTHONPATH |
2214 Private slot to calculate a path list including the PYTHONPATH |
2185 environment variable. |
2215 environment variable. |
2186 |
2216 |
2187 @param firstEntry entry to be put first in sys.path (string) |
2217 @param firstEntry entry to be put first in sys.path |
2188 @return path list for use as sys.path (list of strings) |
2218 @type str |
|
2219 @return path list for use as sys.path |
|
2220 @rtype list of str |
2189 """ |
2221 """ |
2190 sysPath = [ |
2222 sysPath = [ |
2191 path |
2223 path |
2192 for path in os.environ.get("PYTHONPATH", "").split(os.pathsep) |
2224 for path in os.environ.get("PYTHONPATH", "").split(os.pathsep) |
2193 if path not in sys.path |
2225 if path not in sys.path |