DebugClients/Python3/DebugClientBase.py

changeset 2987
c99695c0f13a
parent 2953
703452a2876f
child 2991
226481ff40d1
equal deleted inserted replaced
2986:cd4e2cab7eb2 2987:c99695c0f13a
27 from FlexCompleter import Completer 27 from FlexCompleter import Completer
28 28
29 29
30 DebugClientInstance = None 30 DebugClientInstance = None
31 31
32 ################################################################################ 32 ###############################################################################
33 33
34 34
35 def DebugClientInput(prompt="", echo=True): 35 def DebugClientInput(prompt="", echo=True):
36 """ 36 """
37 Replacement for the standard input builtin. 37 Replacement for the standard input builtin.
54 except (AttributeError, KeyError): 54 except (AttributeError, KeyError):
55 import __main__ 55 import __main__
56 DebugClientOrigInput = __main__.__builtins__.__dict__['input'] 56 DebugClientOrigInput = __main__.__builtins__.__dict__['input']
57 __main__.__builtins__.__dict__['input'] = DebugClientInput 57 __main__.__builtins__.__dict__['input'] = DebugClientInput
58 58
59 ################################################################################ 59 ###############################################################################
60 60
61 61
62 def DebugClientFork(): 62 def DebugClientFork():
63 """ 63 """
64 Replacement for the standard os.fork(). 64 Replacement for the standard os.fork().
73 # use our own fork(). 73 # use our own fork().
74 if 'fork' in dir(os): 74 if 'fork' in dir(os):
75 DebugClientOrigFork = os.fork 75 DebugClientOrigFork = os.fork
76 os.fork = DebugClientFork 76 os.fork = DebugClientFork
77 77
78 ################################################################################ 78 ###############################################################################
79 79
80 80
81 def DebugClientClose(fd): 81 def DebugClientClose(fd):
82 """ 82 """
83 Replacement for the standard os.close(fd). 83 Replacement for the standard os.close(fd).
92 # use our own close(). 92 # use our own close().
93 if 'close' in dir(os): 93 if 'close' in dir(os):
94 DebugClientOrigClose = os.close 94 DebugClientOrigClose = os.close
95 os.close = DebugClientClose 95 os.close = DebugClientClose
96 96
97 ################################################################################ 97 ###############################################################################
98 98
99 99
100 def DebugClientSetRecursionLimit(limit): 100 def DebugClientSetRecursionLimit(limit):
101 """ 101 """
102 Replacement for the standard sys.setrecursionlimit(limit). 102 Replacement for the standard sys.setrecursionlimit(limit).
111 if 'setrecursionlimit' in dir(sys): 111 if 'setrecursionlimit' in dir(sys):
112 DebugClientOrigSetRecursionLimit = sys.setrecursionlimit 112 DebugClientOrigSetRecursionLimit = sys.setrecursionlimit
113 sys.setrecursionlimit = DebugClientSetRecursionLimit 113 sys.setrecursionlimit = DebugClientSetRecursionLimit
114 DebugClientSetRecursionLimit(sys.getrecursionlimit()) 114 DebugClientSetRecursionLimit(sys.getrecursionlimit())
115 115
116 ################################################################################ 116 ###############################################################################
117 117
118 118
119 class DebugClientBase(object): 119 class DebugClientBase(object):
120 """ 120 """
121 Class implementing the client side of the debugger. 121 Class implementing the client side of the debugger.
122 122
123 It provides access to the Python interpeter from a debugger running in another 123 It provides access to the Python interpeter from a debugger running in
124 process whether or not the Qt event loop is running. 124 another process whether or not the Qt event loop is running.
125 125
126 The protocol between the debugger and the client assumes that there will be 126 The protocol between the debugger and the client assumes that there will be
127 a single source of debugger commands and a single source of Python 127 a single source of debugger commands and a single source of Python
128 statements. Commands and statement are always exactly one line and may be 128 statements. Commands and statement are always exactly one line and may be
129 interspersed. 129 interspersed.
132 debugger and then sends a series of one line commands. A command is either 132 debugger and then sends a series of one line commands. A command is either
133 >Load<, >Step<, >StepInto<, ... or a Python statement. 133 >Load<, >Step<, >StepInto<, ... or a Python statement.
134 See DebugProtocol.py for a listing of valid protocol tokens. 134 See DebugProtocol.py for a listing of valid protocol tokens.
135 135
136 A Python statement consists of the statement to execute, followed (in a 136 A Python statement consists of the statement to execute, followed (in a
137 separate line) by >OK?<. If the statement was incomplete then the response 137 separate line) by >OK?<. If the statement was incomplete then the
138 is >Continue<. If there was an exception then the response is 138 response is >Continue<. If there was an exception then the response
139 >Exception<. 139 is >Exception<. Otherwise the response is >OK<. The reason
140 Otherwise the response is >OK<. The reason for the >OK?< part is to 140 for the >OK?< part is to provide a sentinal (ie. the responding
141 provide a sentinal (ie. the responding >OK<) after any possible output as a 141 >OK<) after any possible output as a result of executing the command.
142 result of executing the command.
143 142
144 The client may send any other lines at any other time which should be 143 The client may send any other lines at any other time which should be
145 interpreted as program output. 144 interpreted as program output.
146 145
147 If the debugger closes the session there is no response from the client. 146 If the debugger closes the session there is no response from the client.
148 The client may close the session at any time as a result of the script 147 The client may close the session at any time as a result of the script
149 being debugged closing or crashing. 148 being debugged closing or crashing.
150 149
151 <b>Note</b>: This class is meant to be subclassed by individual DebugClient classes. 150 <b>Note</b>: This class is meant to be subclassed by individual
152 Do not instantiate it directly. 151 DebugClient classes. Do not instantiate it directly.
153 """ 152 """
154 clientCapabilities = DebugClientCapabilities.HasAll 153 clientCapabilities = DebugClientCapabilities.HasAll
155 154
156 def __init__(self): 155 def __init__(self):
157 """ 156 """
165 # debugger 164 # debugger
166 165
167 # dictionary of all threads running 166 # dictionary of all threads running
168 self.threads = {} 167 self.threads = {}
169 168
170 # the "current" thread, basically the thread we are at a breakpoint for. 169 # the "current" thread, basically the thread we are at a breakpoint
170 # for.
171 self.currentThread = self 171 self.currentThread = self
172 172
173 # special objects representing the main scripts thread and frame 173 # special objects representing the main scripts thread and frame
174 self.mainThread = self 174 self.mainThread = self
175 self.mainFrame = None 175 self.mainFrame = None
254 if m: 254 if m:
255 self.__coding = m.group(1) 255 self.__coding = m.group(1)
256 return 256 return
257 self.__coding = default 257 self.__coding = default
258 258
259 def attachThread(self, target=None, args=None, kwargs=None, mainThread=False): 259 def attachThread(self, target=None, args=None, kwargs=None,
260 mainThread=False):
260 """ 261 """
261 Public method to setup a thread for DebugClient to debug. 262 Public method to setup a thread for DebugClient to debug.
262 263
263 If mainThread is non-zero, then we are attaching to the already 264 If mainThread is non-zero, then we are attaching to the already
264 started mainthread of the app and the rest of the args are ignored. 265 started mainthread of the app and the rest of the args are ignored.
265 266
266 @param target the start function of the target thread (i.e. the user code) 267 @param target the start function of the target thread (i.e. the
268 user code)
267 @param args arguments to pass to target 269 @param args arguments to pass to target
268 @param kwargs keyword arguments to pass to target 270 @param kwargs keyword arguments to pass to target
269 @param mainThread True, if we are attaching to the already 271 @param mainThread True, if we are attaching to the already
270 started mainthread of the app 272 started mainthread of the app
271 """ 273 """
275 def __dumpThreadList(self): 277 def __dumpThreadList(self):
276 """ 278 """
277 Public method to send the list of threads. 279 Public method to send the list of threads.
278 """ 280 """
279 threadList = [] 281 threadList = []
280 if self.threads and self.currentThread: # indication for the threaded debugger 282 if self.threads and self.currentThread:
283 # indication for the threaded debugger
281 currentId = self.currentThread.get_ident() 284 currentId = self.currentThread.get_ident()
282 for t in self.threads.values(): 285 for t in self.threads.values():
283 d = {} 286 d = {}
284 d["id"] = t.get_ident() 287 d["id"] = t.get_ident()
285 d["name"] = t.get_name() 288 d["name"] = t.get_name()
302 305
303 @param prompt the prompt to be shown (string) 306 @param prompt the prompt to be shown (string)
304 @param echo Flag indicating echoing of the input (boolean) 307 @param echo Flag indicating echoing of the input (boolean)
305 @return the entered string 308 @return the entered string
306 """ 309 """
307 self.write("{0}{1!r}\n".format(DebugProtocol.ResponseRaw, (prompt, echo))) 310 self.write("{0}{1!r}\n".format(
311 DebugProtocol.ResponseRaw, (prompt, echo)))
308 self.inRawMode = True 312 self.inRawMode = True
309 self.eventLoop(True) 313 self.eventLoop(True)
310 return self.rawLine 314 return self.rawLine
311 315
312 def __exceptionRaised(self): 316 def __exceptionRaised(self):
317 """ 321 """
318 self.pendingResponse = DebugProtocol.ResponseException 322 self.pendingResponse = DebugProtocol.ResponseException
319 323
320 def sessionClose(self, exit=True): 324 def sessionClose(self, exit=True):
321 """ 325 """
322 Public method to close the session with the debugger and optionally terminate. 326 Public method to close the session with the debugger and optionally
327 terminate.
323 328
324 @param exit flag indicating to terminate (boolean) 329 @param exit flag indicating to terminate (boolean)
325 """ 330 """
326 try: 331 try:
327 self.set_quit() 332 self.set_quit()
357 try: 362 try:
358 code = compile(statement + '\n', filename, mode) 363 code = compile(statement + '\n', filename, mode)
359 except SyntaxError: 364 except SyntaxError:
360 exctype, excval, exctb = sys.exc_info() 365 exctype, excval, exctb = sys.exc_info()
361 try: 366 try:
362 message, (filename, linenr, charnr, text) = excval[0], excval[1] 367 message, (filename, linenr, charnr, text) = \
368 excval[0], excval[1]
363 except ValueError: 369 except ValueError:
364 exclist = [] 370 exclist = []
365 else: 371 else:
366 exclist = [message, [filename, linenr, charnr]] 372 exclist = [message, [filename, linenr, charnr]]
367 373
368 self.write("{0}{1}\n".format(DebugProtocol.ResponseSyntax, str(exclist))) 374 self.write("{0}{1}\n".format(
375 DebugProtocol.ResponseSyntax, str(exclist)))
369 return None 376 return None
370 377
371 return code 378 return code
372 379
373 def handleLine(self, line): 380 def handleLine(self, line):
374 """ 381 """
375 Public method to handle the receipt of a complete line. 382 Public method to handle the receipt of a complete line.
376 383
377 It first looks for a valid protocol token at the start of the line. Thereafter 384 It first looks for a valid protocol token at the start of the line.
378 it trys to execute the lines accumulated so far. 385 Thereafter it trys to execute the lines accumulated so far.
379 386
380 @param line the received line 387 @param line the received line
381 """ 388 """
382 # Remove any newline. 389 # Remove any newline.
383 if line[-1] == '\n': 390 if line[-1] == '\n':
410 tid = eval(arg) 417 tid = eval(arg)
411 if tid in self.threads: 418 if tid in self.threads:
412 self.setCurrentThread(tid) 419 self.setCurrentThread(tid)
413 self.write(DebugProtocol.ResponseThreadSet + '\n') 420 self.write(DebugProtocol.ResponseThreadSet + '\n')
414 stack = self.currentThread.getStack() 421 stack = self.currentThread.getStack()
415 self.write('{0}{1!r}\n'.format(DebugProtocol.ResponseStack, stack)) 422 self.write('{0}{1!r}\n'.format(
423 DebugProtocol.ResponseStack, stack))
416 return 424 return
417 425
418 if cmd == DebugProtocol.RequestStep: 426 if cmd == DebugProtocol.RequestStep:
419 self.currentThread.step(True) 427 self.currentThread.step(True)
420 self.eventExit = True 428 self.eventExit = True
455 else: 463 else:
456 callTraceEnabled = False 464 callTraceEnabled = False
457 if self.debugging: 465 if self.debugging:
458 self.callTraceEnabled = callTraceEnabled 466 self.callTraceEnabled = callTraceEnabled
459 else: 467 else:
460 self.__newCallTraceEnabled = callTraceEnabled # remember for later 468 self.__newCallTraceEnabled = callTraceEnabled
469 # remember for later
461 return 470 return
462 471
463 if cmd == DebugProtocol.RequestEnv: 472 if cmd == DebugProtocol.RequestEnv:
464 env = eval(arg.replace("u'", "'")) 473 env = eval(arg.replace("u'", "'"))
465 for key, value in env.items(): 474 for key, value in env.items():
496 505
497 # set the system exception handling function to ensure, that 506 # set the system exception handling function to ensure, that
498 # we report on all unhandled exceptions 507 # we report on all unhandled exceptions
499 sys.excepthook = self.__unhandled_exception 508 sys.excepthook = self.__unhandled_exception
500 509
501 # clear all old breakpoints, they'll get set after we have started 510 # clear all old breakpoints, they'll get set after we have
511 # started
502 self.mainThread.clear_all_breaks() 512 self.mainThread.clear_all_breaks()
503 513
504 self.mainThread.tracePython = tracePython 514 self.mainThread.tracePython = tracePython
505 515
506 # This will eventually enter a local event loop. 516 # This will eventually enter a local event loop.
507 # Note the use of backquotes to cause a repr of self.running. The 517 # Note the use of backquotes to cause a repr of self.running.
508 # need for this is on Windows os where backslash is the path separator. 518 # The need for this is on Windows os where backslash is the
509 # They will get inadvertantly stripped away during the eval causing 519 # path separator. They will get inadvertantly stripped away
510 # IOErrors, if self.running is passed as a normal str. 520 # during the eval causing IOErrors, if self.running is passed
521 # as a normal str.
511 self.debugMod.__dict__['__file__'] = self.running 522 self.debugMod.__dict__['__file__'] = self.running
512 sys.modules['__main__'] = self.debugMod 523 sys.modules['__main__'] = self.debugMod
513 code = self.__compileFileSource(self.running) 524 code = self.__compileFileSource(self.running)
514 if code: 525 if code:
515 self.callTraceEnabled = self.__newCallTraceEnabled 526 self.callTraceEnabled = self.__newCallTraceEnabled
618 # we report on all unhandled exceptions 629 # we report on all unhandled exceptions
619 sys.excepthook = self.__unhandled_exception 630 sys.excepthook = self.__unhandled_exception
620 631
621 # generate a coverage object 632 # generate a coverage object
622 self.cover = coverage(auto_data=True, 633 self.cover = coverage(auto_data=True,
623 data_file="{0}.coverage".format(os.path.splitext(sys.argv[0])[0])) 634 data_file="{0}.coverage".format(
635 os.path.splitext(sys.argv[0])[0]))
624 self.cover.use_cache(True) 636 self.cover.use_cache(True)
625 637
626 if int(erase): 638 if int(erase):
627 self.cover.erase() 639 self.cover.erase()
628 sys.modules['__main__'] = self.debugMod 640 sys.modules['__main__'] = self.debugMod
666 else: 678 else:
667 try: 679 try:
668 compile(cond, '<string>', 'eval') 680 compile(cond, '<string>', 'eval')
669 except SyntaxError: 681 except SyntaxError:
670 self.write('{0}{1},{2:d}\n'.format( 682 self.write('{0}{1},{2:d}\n'.format(
671 DebugProtocol.ResponseBPConditionError, fn, line)) 683 DebugProtocol.ResponseBPConditionError,
684 fn, line))
672 return 685 return
673 self.mainThread.set_break(fn, line, temporary, cond) 686 self.mainThread.set_break(fn, line, temporary, cond)
674 else: 687 else:
675 self.mainThread.clear_break(fn, line) 688 self.mainThread.clear_break(fn, line)
676 689
744 757
745 return 758 return
746 759
747 if cmd == DebugProtocol.RequestEval: 760 if cmd == DebugProtocol.RequestEval:
748 try: 761 try:
749 value = eval(arg, self.currentThread.getCurrentFrame().f_globals, 762 value = eval(
750 self.currentThread.getCurrentFrameLocals()) 763 arg,
764 self.currentThread.getCurrentFrame().f_globals,
765 self.currentThread.getCurrentFrameLocals())
751 except: 766 except:
752 # Report the exception and the traceback 767 # Report the exception and the traceback
753 try: 768 try:
754 type, value, tb = sys.exc_info() 769 type, value, tb = sys.exc_info()
755 sys.last_type = type 770 sys.last_type = type
850 except AttributeError: 865 except AttributeError:
851 self.test = unittest.defaultTestLoader\ 866 self.test = unittest.defaultTestLoader\
852 .loadTestsFromModule(utModule) 867 .loadTestsFromModule(utModule)
853 except: 868 except:
854 exc_type, exc_value, exc_tb = sys.exc_info() 869 exc_type, exc_value, exc_tb = sys.exc_info()
855 self.write('{0}{1}\n'.format(DebugProtocol.ResponseUTPrepared, 870 self.write('{0}{1}\n'.format(
871 DebugProtocol.ResponseUTPrepared,
856 str((0, str(exc_type), str(exc_value))))) 872 str((0, str(exc_type), str(exc_value)))))
857 self.__exceptionRaised() 873 self.__exceptionRaised()
858 return 874 return
859 875
860 # generate a coverage object 876 # generate a coverage object
861 if int(cov): 877 if int(cov):
862 from coverage import coverage 878 from coverage import coverage
863 self.cover = coverage(auto_data=True, 879 self.cover = coverage(auto_data=True,
864 data_file="{0}.coverage".format(os.path.splitext(covname)[0])) 880 data_file="{0}.coverage".format(
881 os.path.splitext(covname)[0]))
865 self.cover.use_cache(True) 882 self.cover.use_cache(True)
866 if int(erase): 883 if int(erase):
867 self.cover.erase() 884 self.cover.erase()
868 else: 885 else:
869 self.cover = None 886 self.cover = None
914 try: 931 try:
915 code = self.compile_command(self.buffer, self.readstream.name) 932 code = self.compile_command(self.buffer, self.readstream.name)
916 except (OverflowError, SyntaxError, ValueError): 933 except (OverflowError, SyntaxError, ValueError):
917 # Report the exception 934 # Report the exception
918 sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() 935 sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
919 for l in traceback.format_exception_only(sys.last_type, sys.last_value): 936 for l in traceback.format_exception_only(
937 sys.last_type, sys.last_value):
920 self.write(l) 938 self.write(l)
921 self.buffer = '' 939 self.buffer = ''
922 else: 940 else:
923 if code is None: 941 if code is None:
924 self.pendingResponse = DebugProtocol.ResponseContinue 942 self.pendingResponse = DebugProtocol.ResponseContinue
945 frmnr = self.framenr 963 frmnr = self.framenr
946 while cf is not None and frmnr > 0: 964 while cf is not None and frmnr > 0:
947 cf = cf.f_back 965 cf = cf.f_back
948 frmnr -= 1 966 frmnr -= 1
949 _globals = cf.f_globals 967 _globals = cf.f_globals
950 _locals = self.currentThread.getCurrentFrameLocals() 968 _locals = \
969 self.currentThread.getCurrentFrameLocals()
951 # reset sys.stdout to our redirector (unconditionally) 970 # reset sys.stdout to our redirector (unconditionally)
952 if "sys" in _globals: 971 if "sys" in _globals:
953 __stdout = _globals["sys"].stdout 972 __stdout = _globals["sys"].stdout
954 _globals["sys"].stdout = self.writestream 973 _globals["sys"].stdout = self.writestream
955 exec(code, _globals, _locals) 974 exec(code, _globals, _locals)
973 tblist = traceback.extract_tb(exc_tb) 992 tblist = traceback.extract_tb(exc_tb)
974 del tblist[:1] 993 del tblist[:1]
975 list = traceback.format_list(tblist) 994 list = traceback.format_list(tblist)
976 if list: 995 if list:
977 list.insert(0, "Traceback (innermost last):\n") 996 list.insert(0, "Traceback (innermost last):\n")
978 list[len(list):] = \ 997 list[len(list):] = traceback.format_exception_only(
979 traceback.format_exception_only(exc_type, exc_value) 998 exc_type, exc_value)
980 finally: 999 finally:
981 tblist = exc_tb = None 1000 tblist = exc_tb = None
982 1001
983 for l in list: 1002 for l in list:
984 self.write(l) 1003 self.write(l)
995 del sys.modules['PyProfile'] 1014 del sys.modules['PyProfile']
996 except KeyError: 1015 except KeyError:
997 pass 1016 pass
998 return self.clientCapabilities 1017 return self.clientCapabilities
999 except ImportError: 1018 except ImportError:
1000 return self.clientCapabilities & ~DebugClientCapabilities.HasProfiler 1019 return (self.clientCapabilities &
1020 ~DebugClientCapabilities.HasProfiler)
1001 1021
1002 def write(self, s): 1022 def write(self, s):
1003 """ 1023 """
1004 Public method to write data to the output stream. 1024 Public method to write data to the output stream.
1005 1025
1103 It opens a network connection to the debugger, connects it to stdin, 1123 It opens a network connection to the debugger, connects it to stdin,
1104 stdout and stderr and saves these file objects in case the application 1124 stdout and stderr and saves these file objects in case the application
1105 being debugged redirects them itself. 1125 being debugged redirects them itself.
1106 1126
1107 @param port the port number to connect to (int) 1127 @param port the port number to connect to (int)
1108 @param remoteAddress the network address of the debug server host (string) 1128 @param remoteAddress the network address of the debug server host
1109 @param redirect flag indicating redirection of stdin, stdout and stderr (boolean) 1129 (string)
1110 """ 1130 @param redirect flag indicating redirection of stdin, stdout and
1111 if remoteAddress is None: # default: 127.0.0.1 1131 stderr (boolean)
1132 """
1133 if remoteAddress is None: # default: 127.0.0.1
1112 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1134 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1113 sock.connect((DebugProtocol.DebugAddress, port)) 1135 sock.connect((DebugProtocol.DebugAddress, port))
1114 else: 1136 else:
1115 if "@@i" in remoteAddress: 1137 if "@@i" in remoteAddress:
1116 remoteAddress, index = remoteAddress.split("@@i") 1138 remoteAddress, index = remoteAddress.split("@@i")
1117 else: 1139 else:
1118 index = 0 1140 index = 0
1119 if ":" in remoteAddress: # IPv6 1141 if ":" in remoteAddress: # IPv6
1120 sockaddr = socket.getaddrinfo( 1142 sockaddr = socket.getaddrinfo(
1121 remoteAddress, port, 0, 0, socket.SOL_TCP)[0][-1] 1143 remoteAddress, port, 0, 0, socket.SOL_TCP)[0][-1]
1122 sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 1144 sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
1123 sockaddr = sockaddr[:-1] + (int(index),) 1145 sockaddr = sockaddr[:-1] + (int(index),)
1124 sock.connect(sockaddr) 1146 sock.connect(sockaddr)
1125 else: # IPv4 1147 else: # IPv4
1126 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1148 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1127 sock.connect((remoteAddress, port)) 1149 sock.connect((remoteAddress, port))
1128 1150
1129 self.readstream = AsyncFile(sock, sys.stdin.mode, sys.stdin.name) 1151 self.readstream = AsyncFile(sock, sys.stdin.mode, sys.stdin.name)
1130 self.writestream = AsyncFile(sock, sys.stdout.mode, sys.stdout.name) 1152 self.writestream = AsyncFile(sock, sys.stdout.mode, sys.stdout.name)
1193 def shouldSkip(self, fn): 1215 def shouldSkip(self, fn):
1194 """ 1216 """
1195 Public method to check if a file should be skipped. 1217 Public method to check if a file should be skipped.
1196 1218
1197 @param fn filename to be checked 1219 @param fn filename to be checked
1198 @return non-zero if fn represents a file we are 'skipping', zero otherwise. 1220 @return non-zero if fn represents a file we are 'skipping',
1221 zero otherwise.
1199 """ 1222 """
1200 if self.mainThread.tracePython: # trace into Python library 1223 if self.mainThread.tracePython: # trace into Python library
1201 return False 1224 return False
1202 1225
1203 # Eliminate anything that is part of the Python installation. 1226 # Eliminate anything that is part of the Python installation.
1245 1268
1246 def __dumpVariables(self, frmnr, scope, filter): 1269 def __dumpVariables(self, frmnr, scope, filter):
1247 """ 1270 """
1248 Private method to return the variables of a frame to the debug server. 1271 Private method to return the variables of a frame to the debug server.
1249 1272
1250 @param frmnr distance of frame reported on. 0 is the current frame (int) 1273 @param frmnr distance of frame reported on. 0 is the current frame
1274 (int)
1251 @param scope 1 to report global variables, 0 for local variables (int) 1275 @param scope 1 to report global variables, 0 for local variables (int)
1252 @param filter the indices of variable types to be filtered (list of int) 1276 @param filter the indices of variable types to be filtered
1277 (list of int)
1253 """ 1278 """
1254 if self.currentThread is None: 1279 if self.currentThread is None:
1255 return 1280 return
1256 1281
1257 if scope == 0: 1282 if scope == 0:
1280 keylist = dict.keys() 1305 keylist = dict.keys()
1281 1306
1282 vlist = self.__formatVariablesList(keylist, dict, scope, filter) 1307 vlist = self.__formatVariablesList(keylist, dict, scope, filter)
1283 varlist.extend(vlist) 1308 varlist.extend(vlist)
1284 1309
1285 self.write('{0}{1}\n'.format(DebugProtocol.ResponseVariables, str(varlist))) 1310 self.write('{0}{1}\n'.format(
1311 DebugProtocol.ResponseVariables, str(varlist)))
1286 1312
1287 def __dumpVariable(self, var, frmnr, scope, filter): 1313 def __dumpVariable(self, var, frmnr, scope, filter):
1288 """ 1314 """
1289 Private method to return the variables of a frame to the debug server. 1315 Private method to return the variables of a frame to the debug server.
1290 1316
1291 @param var list encoded name of the requested variable (list of strings) 1317 @param var list encoded name of the requested variable
1292 @param frmnr distance of frame reported on. 0 is the current frame (int) 1318 (list of strings)
1319 @param frmnr distance of frame reported on. 0 is the current frame
1320 (int)
1293 @param scope 1 to report global variables, 0 for local variables (int) 1321 @param scope 1 to report global variables, 0 for local variables (int)
1294 @param filter the indices of variable types to be filtered (list of int) 1322 @param filter the indices of variable types to be filtered
1323 (list of int)
1295 """ 1324 """
1296 if self.currentThread is None: 1325 if self.currentThread is None:
1297 return 1326 return
1298 1327
1299 f = self.currentThread.getCurrentFrame() 1328 f = self.currentThread.getCurrentFrame()
1352 else: 1381 else:
1353 if var[i][:-2] == '...': 1382 if var[i][:-2] == '...':
1354 if oaccess: 1383 if oaccess:
1355 access = oaccess 1384 access = oaccess
1356 else: 1385 else:
1357 access = '{0!s}[{1!s}]'.format(access, var[i - 1]) 1386 access = '{0!s}[{1!s}]'.format(
1387 access, var[i - 1])
1358 dict = odict 1388 dict = odict
1359 else: 1389 else:
1360 if oaccess: 1390 if oaccess:
1361 access = '{0!s}[{1!s}]'.format(oaccess, var[i][:-2]) 1391 access = '{0!s}[{1!s}]'.format(
1392 oaccess, var[i][:-2])
1362 oaccess = '' 1393 oaccess = ''
1363 else: 1394 else:
1364 access = '{0!s}[{1!s}]'.format(access, var[i][:-2]) 1395 access = '{0!s}[{1!s}]'.format(
1396 access, var[i][:-2])
1365 if var[i][-2:] == "{}": 1397 if var[i][-2:] == "{}":
1366 isDict = True 1398 isDict = True
1367 break 1399 break
1368 else: 1400 else:
1369 if not access: 1401 if not access:
1372 dict = odict 1404 dict = odict
1373 else: 1405 else:
1374 access = '["{0!s}"]'.format(var[i][:-2]) 1406 access = '["{0!s}"]'.format(var[i][:-2])
1375 else: 1407 else:
1376 if var[i][:-2] == '...': 1408 if var[i][:-2] == '...':
1377 access = '{0!s}[{1!s}]'.format(access, var[i - 1]) 1409 access = '{0!s}[{1!s}]'.format(
1410 access, var[i - 1])
1378 dict = odict 1411 dict = odict
1379 else: 1412 else:
1380 if oaccess: 1413 if oaccess:
1381 access = '{0!s}[{1!s}]'.format(oaccess, var[i][:-2]) 1414 access = '{0!s}[{1!s}]'.format(
1415 oaccess, var[i][:-2])
1382 oaccess = '' 1416 oaccess = ''
1383 else: 1417 else:
1384 access = '{0!s}[{1!s}]'.format(access, var[i][:-2]) 1418 access = '{0!s}[{1!s}]'.format(
1419 access, var[i][:-2])
1385 else: 1420 else:
1386 if access: 1421 if access:
1387 if oaccess: 1422 if oaccess:
1388 access = '{0!s}[{1!s}]'.format(oaccess, var[i]) 1423 access = '{0!s}[{1!s}]'.format(oaccess, var[i])
1389 else: 1424 else:
1420 exec('slv = dict{0!s}.__slots__'.format(access), 1455 exec('slv = dict{0!s}.__slots__'.format(access),
1421 globals(), loc) 1456 globals(), loc)
1422 for v in loc["slv"]: 1457 for v in loc["slv"]:
1423 try: 1458 try:
1424 loc["v"] = v 1459 loc["v"] = v
1425 exec('cdict[v] = dict{0!s}.{1!s}'.format(access, v), 1460 exec('cdict[v] = dict{0!s}.{1!s}'.format(
1461 access, v),
1426 globals, loc) 1462 globals, loc)
1427 except: 1463 except:
1428 pass 1464 pass
1429 ndict.update(loc["cdict"]) 1465 ndict.update(loc["cdict"])
1430 exec('obj = dict{0!s}'.format(access), globals(), loc) 1466 exec('obj = dict{0!s}'.format(access),
1467 globals(), loc)
1431 obj = loc["obj"] 1468 obj = loc["obj"]
1432 access = "" 1469 access = ""
1433 if "PyQt4." in str(type(obj)): 1470 if "PyQt4." in str(type(obj)):
1434 qtVariable = True 1471 qtVariable = True
1435 qvar = obj 1472 qvar = obj
1448 qvtype = str(type(qvar))[1:-1].split()[1][1:-1] 1485 qvtype = str(type(qvar))[1:-1].split()[1][1:-1]
1449 except: 1486 except:
1450 pass 1487 pass
1451 try: 1488 try:
1452 slv = dict[var[i]].__slots__ 1489 slv = dict[var[i]].__slots__
1453 loc = {"cdict": {}, "dict": dict, "var": var, "i": i} 1490 loc = {"cdict": {}, "dict": dict,
1491 "var": var, "i": i}
1454 for v in slv: 1492 for v in slv:
1455 try: 1493 try:
1456 loc["v"] = v 1494 loc["v"] = v
1457 exec('cdict[v] = dict[var[i]].{0!s}'.format(v), 1495 exec('cdict[v] = dict[var[i]].{0!s}'
1496 .format(v),
1458 globals(), loc) 1497 globals(), loc)
1459 except: 1498 except:
1460 pass 1499 pass
1461 ndict.update(loc["cdict"]) 1500 ndict.update(loc["cdict"])
1462 obj = dict[var[i]] 1501 obj = dict[var[i]]
1479 exec('qvar = udict{0!s}'.format(access), globals(), loc) 1518 exec('qvar = udict{0!s}'.format(access), globals(), loc)
1480 qvar = loc["qvar"] 1519 qvar = loc["qvar"]
1481 # this has to be in line with VariablesViewer.indicators 1520 # this has to be in line with VariablesViewer.indicators
1482 elif rvar and rvar[0][-2:] in ["[]", "()", "{}"]: 1521 elif rvar and rvar[0][-2:] in ["[]", "()", "{}"]:
1483 loc = {"udict": udict} 1522 loc = {"udict": udict}
1484 exec('qvar = udict["{0!s}"][{1!s}]'.format(rvar[0][:-2], rvar[1]), 1523 exec('qvar = udict["{0!s}"][{1!s}]'.format(rvar[0][:-2],
1524 rvar[1]),
1485 globals(), loc) 1525 globals(), loc)
1486 qvar = loc["qvar"] 1526 qvar = loc["qvar"]
1487 else: 1527 else:
1488 qvar = udict[var[-1]] 1528 qvar = udict[var[-1]]
1489 qvtype = str(type(qvar))[1:-1].split()[1][1:-1] 1529 qvtype = str(type(qvar))[1:-1].split()[1][1:-1]
1499 exec('qvar = udict{0!s}'.format(access), globals(), loc) 1539 exec('qvar = udict{0!s}'.format(access), globals(), loc)
1500 qvar = loc["qvar"] 1540 qvar = loc["qvar"]
1501 # this has to be in line with VariablesViewer.indicators 1541 # this has to be in line with VariablesViewer.indicators
1502 elif rvar and rvar[0][-2:] in ["[]", "()", "{}"]: 1542 elif rvar and rvar[0][-2:] in ["[]", "()", "{}"]:
1503 loc = {"udict": udict} 1543 loc = {"udict": udict}
1504 exec('qvar = udict["{0!s}"][{1!s}]'.format(rvar[0][:-2], rvar[1]), 1544 exec('qvar = udict["{0!s}"][{1!s}]'.format(
1505 globals(), loc) 1545 rvar[0][:-2], rvar[1]), globals(), loc)
1506 qvar = loc["qvar"] 1546 qvar = loc["qvar"]
1507 else: 1547 else:
1508 qvar = udict[var[-1]] 1548 qvar = udict[var[-1]]
1509 qvtype = str(type(qvar))[1:-1].split()[1][1:-1] 1549 qvtype = str(type(qvar))[1:-1].split()[1][1:-1]
1510 if qvtype.startswith("PyQt4"): 1550 if qvtype.startswith("PyQt4"):
1518 dictkeys = dict.keys() 1558 dictkeys = dict.keys()
1519 else: 1559 else:
1520 # treatment for sequences and dictionaries 1560 # treatment for sequences and dictionaries
1521 if access: 1561 if access:
1522 loc = {"dict": dict} 1562 loc = {"dict": dict}
1523 exec("dict = dict{0!s}".format(access), globals(), loc) 1563 exec("dict = dict{0!s}".format(access), globals(),
1564 loc)
1524 dict = loc["dict"] 1565 dict = loc["dict"]
1525 else: 1566 else:
1526 dict = dict[dictkeys[0]] 1567 dict = dict[dictkeys[0]]
1527 if isDict: 1568 if isDict:
1528 dictkeys = dict.keys() 1569 dictkeys = dict.keys()
1529 else: 1570 else:
1530 dictkeys = range(len(dict)) 1571 dictkeys = range(len(dict))
1531 vlist = self.__formatVariablesList(dictkeys, dict, scope, filter, 1572 vlist = self.__formatVariablesList(
1532 formatSequences) 1573 dictkeys, dict, scope, filter, formatSequences)
1533 varlist.extend(vlist) 1574 varlist.extend(vlist)
1534 1575
1535 if obj is not None and not formatSequences: 1576 if obj is not None and not formatSequences:
1536 try: 1577 try:
1537 if repr(obj).startswith('{'): 1578 if repr(obj).startswith('{'):
1538 varlist.append(('...', 'dict', "{0:d}".format(len(obj.keys())))) 1579 varlist.append(
1580 ('...', 'dict', "{0:d}".format(len(obj.keys()))))
1539 elif repr(obj).startswith('['): 1581 elif repr(obj).startswith('['):
1540 varlist.append(('...', 'list', "{0:d}".format(len(obj)))) 1582 varlist.append(
1583 ('...', 'list', "{0:d}".format(len(obj))))
1541 elif repr(obj).startswith('('): 1584 elif repr(obj).startswith('('):
1542 varlist.append(('...', 'tuple', "{0:d}".format(len(obj)))) 1585 varlist.append(
1586 ('...', 'tuple', "{0:d}".format(len(obj))))
1543 except: 1587 except:
1544 pass 1588 pass
1545 1589
1546 self.write('{0}{1}\n'.format(DebugProtocol.ResponseVariable, str(varlist))) 1590 self.write('{0}{1}\n'.format(
1591 DebugProtocol.ResponseVariable, str(varlist)))
1547 1592
1548 def __formatQt4Variable(self, value, vtype): 1593 def __formatQt4Variable(self, value, vtype):
1549 """ 1594 """
1550 Private method to produce a formatted output of a simple Qt4/Qt5 type. 1595 Private method to produce a formatted output of a simple Qt4/Qt5 type.
1551 1596
1559 varlist = [] 1604 varlist = []
1560 if qttype == 'QChar': 1605 if qttype == 'QChar':
1561 varlist.append(("", "QChar", "{0}".format(chr(value.unicode())))) 1606 varlist.append(("", "QChar", "{0}".format(chr(value.unicode()))))
1562 varlist.append(("", "int", "{0:d}".format(value.unicode()))) 1607 varlist.append(("", "int", "{0:d}".format(value.unicode())))
1563 elif qttype == 'QByteArray': 1608 elif qttype == 'QByteArray':
1564 varlist.append(("bytes", "QByteArray", "{0}".format(bytes(value))[2:-1])) 1609 varlist.append(
1565 varlist.append(("hex", "QByteArray", "{0}".format(value.toHex())[2:-1])) 1610 ("bytes", "QByteArray", "{0}".format(bytes(value))[2:-1]))
1566 varlist.append(("base64", "QByteArray", "{0}".format(value.toBase64())[2:-1])) 1611 varlist.append(
1612 ("hex", "QByteArray", "{0}".format(value.toHex())[2:-1]))
1613 varlist.append(
1614 ("base64", "QByteArray", "{0}".format(value.toBase64())[2:-1]))
1567 varlist.append(("percent encoding", "QByteArray", 1615 varlist.append(("percent encoding", "QByteArray",
1568 "{0}".format(value.toPercentEncoding())[2:-1])) 1616 "{0}".format(value.toPercentEncoding())[2:-1]))
1569 elif qttype == 'QPoint': 1617 elif qttype == 'QPoint':
1570 varlist.append(("x", "int", "{0:d}".format(value.x()))) 1618 varlist.append(("x", "int", "{0:d}".format(value.x())))
1571 varlist.append(("y", "int", "{0:d}".format(value.y()))) 1619 varlist.append(("y", "int", "{0:d}".format(value.y())))
1589 varlist.append(("width", "float", "{0:g}".format(value.width()))) 1637 varlist.append(("width", "float", "{0:g}".format(value.width())))
1590 varlist.append(("height", "float", "{0:g}".format(value.height()))) 1638 varlist.append(("height", "float", "{0:g}".format(value.height())))
1591 elif qttype == 'QColor': 1639 elif qttype == 'QColor':
1592 varlist.append(("name", "str", "{0}".format(value.name()))) 1640 varlist.append(("name", "str", "{0}".format(value.name())))
1593 r, g, b, a = value.getRgb() 1641 r, g, b, a = value.getRgb()
1594 varlist.append(("rgb", "int", 1642 varlist.append(
1595 "{0:d}, {1:d}, {2:d}, {3:d}".format(r, g, b, a))) 1643 ("rgb", "int",
1644 "{0:d}, {1:d}, {2:d}, {3:d}".format(r, g, b, a)))
1596 h, s, v, a = value.getHsv() 1645 h, s, v, a = value.getHsv()
1597 varlist.append(("hsv", "int", 1646 varlist.append(
1598 "{0:d}, {1:d}, {2:d}, {3:d}".format(h, s, v, a))) 1647 ("hsv", "int",
1648 "{0:d}, {1:d}, {2:d}, {3:d}".format(h, s, v, a)))
1599 c, m, y, k, a = value.getCmyk() 1649 c, m, y, k, a = value.getCmyk()
1600 varlist.append(("cmyk", "int", 1650 varlist.append(
1601 "{0:d}, {1:d}, {2:d}, {3:d}, {4:d}".format(c, m, y, k, a))) 1651 ("cmyk", "int",
1652 "{0:d}, {1:d}, {2:d}, {3:d}, {4:d}".format(c, m, y, k, a)))
1602 elif qttype == 'QDate': 1653 elif qttype == 'QDate':
1603 varlist.append(("", "QDate", "{0}".format(value.toString()))) 1654 varlist.append(("", "QDate", "{0}".format(value.toString())))
1604 elif qttype == 'QTime': 1655 elif qttype == 'QTime':
1605 varlist.append(("", "QTime", "{0}".format(value.toString()))) 1656 varlist.append(("", "QTime", "{0}".format(value.toString())))
1606 elif qttype == 'QDateTime': 1657 elif qttype == 'QDateTime':
1613 "{0}".format(value.canonicalPath()))) 1664 "{0}".format(value.canonicalPath())))
1614 elif qttype == 'QFile': 1665 elif qttype == 'QFile':
1615 varlist.append(("fileName", "str", "{0}".format(value.fileName()))) 1666 varlist.append(("fileName", "str", "{0}".format(value.fileName())))
1616 elif qttype == 'QFont': 1667 elif qttype == 'QFont':
1617 varlist.append(("family", "str", "{0}".format(value.family()))) 1668 varlist.append(("family", "str", "{0}".format(value.family())))
1618 varlist.append(("pointSize", "int", "{0:d}".format(value.pointSize()))) 1669 varlist.append(
1670 ("pointSize", "int", "{0:d}".format(value.pointSize())))
1619 varlist.append(("weight", "int", "{0:d}".format(value.weight()))) 1671 varlist.append(("weight", "int", "{0:d}".format(value.weight())))
1620 varlist.append(("bold", "bool", "{0}".format(value.bold()))) 1672 varlist.append(("bold", "bool", "{0}".format(value.bold())))
1621 varlist.append(("italic", "bool", "{0}".format(value.italic()))) 1673 varlist.append(("italic", "bool", "{0}".format(value.italic())))
1622 elif qttype == 'QUrl': 1674 elif qttype == 'QUrl':
1623 varlist.append(("url", "str", "{0}".format(value.toString()))) 1675 varlist.append(("url", "str", "{0}".format(value.toString())))
1630 elif qttype == 'QModelIndex': 1682 elif qttype == 'QModelIndex':
1631 varlist.append(("valid", "bool", "{0}".format(value.isValid()))) 1683 varlist.append(("valid", "bool", "{0}".format(value.isValid())))
1632 if value.isValid(): 1684 if value.isValid():
1633 varlist.append(("row", "int", "{0}".format(value.row()))) 1685 varlist.append(("row", "int", "{0}".format(value.row())))
1634 varlist.append(("column", "int", "{0}".format(value.column()))) 1686 varlist.append(("column", "int", "{0}".format(value.column())))
1635 varlist.append(("internalId", "int", "{0}".format(value.internalId()))) 1687 varlist.append(
1688 ("internalId", "int", "{0}".format(value.internalId())))
1636 varlist.append(("internalPointer", "void *", 1689 varlist.append(("internalPointer", "void *",
1637 "{0}".format(value.internalPointer()))) 1690 "{0}".format(value.internalPointer())))
1638 elif qttype == 'QRegExp': 1691 elif qttype == 'QRegExp':
1639 varlist.append(("pattern", "str", "{0}".format(value.pattern()))) 1692 varlist.append(("pattern", "str", "{0}".format(value.pattern())))
1640 1693
1641 # GUI stuff 1694 # GUI stuff
1642 elif qttype == 'QAction': 1695 elif qttype == 'QAction':
1643 varlist.append(("name", "str", "{0}".format(value.objectName()))) 1696 varlist.append(("name", "str", "{0}".format(value.objectName())))
1644 varlist.append(("text", "str", "{0}".format(value.text()))) 1697 varlist.append(("text", "str", "{0}".format(value.text())))
1645 varlist.append(("icon text", "str", "{0}".format(value.iconText()))) 1698 varlist.append(
1699 ("icon text", "str", "{0}".format(value.iconText())))
1646 varlist.append(("tooltip", "str", "{0}".format(value.toolTip()))) 1700 varlist.append(("tooltip", "str", "{0}".format(value.toolTip())))
1647 varlist.append(("whatsthis", "str", "{0}".format(value.whatsThis()))) 1701 varlist.append(
1648 varlist.append(("shortcut", "str", 1702 ("whatsthis", "str", "{0}".format(value.whatsThis())))
1649 "{0}".format(value.shortcut().toString()))) 1703 varlist.append(
1704 ("shortcut", "str",
1705 "{0}".format(value.shortcut().toString())))
1650 elif qttype == 'QKeySequence': 1706 elif qttype == 'QKeySequence':
1651 varlist.append(("value", "", "{0}".format(value.toString()))) 1707 varlist.append(("value", "", "{0}".format(value.toString())))
1652 1708
1653 # XML stuff 1709 # XML stuff
1654 elif qttype == 'QDomAttr': 1710 elif qttype == 'QDomAttr':
1666 elif qttype == 'QDomText': 1722 elif qttype == 'QDomText':
1667 varlist.append(("data", "str", "{0}".format(value.data()))) 1723 varlist.append(("data", "str", "{0}".format(value.data())))
1668 1724
1669 # Networking stuff 1725 # Networking stuff
1670 elif qttype == 'QHostAddress': 1726 elif qttype == 'QHostAddress':
1671 varlist.append(("address", "QHostAddress", "{0}".format(value.toString()))) 1727 varlist.append(
1728 ("address", "QHostAddress", "{0}".format(value.toString())))
1672 1729
1673 return varlist 1730 return varlist
1674 1731
1675 def __formatVariablesList(self, keylist, dict, scope, filter=[], 1732 def __formatVariablesList(self, keylist, dict, scope, filter=[],
1676 formatSequences=False): 1733 formatSequences=False):
1677 """ 1734 """
1678 Private method to produce a formated variables list. 1735 Private method to produce a formated variables list.
1679 1736
1680 The dictionary passed in to it is scanned. Variables are 1737 The dictionary passed in to it is scanned. Variables are
1681 only added to the list, if their type is not contained 1738 only added to the list, if their type is not contained
1682 in the filter list and their name doesn't match any of the filter expressions. 1739 in the filter list and their name doesn't match any of the filter
1683 The formated variables list (a list of tuples of 3 values) is returned. 1740 expressions. The formated variables list (a list of tuples of 3
1741 values) is returned.
1684 1742
1685 @param keylist keys of the dictionary 1743 @param keylist keys of the dictionary
1686 @param dict the dictionary to be scanned 1744 @param dict the dictionary to be scanned
1687 @param scope 1 to filter using the globals filter, 0 using the locals 1745 @param scope 1 to filter using the globals filter, 0 using the locals
1688 filter (int). 1746 filter (int).
1689 Variables are only added to the list, if their name do not match any of the 1747 Variables are only added to the list, if their name do not match
1690 filter expressions. 1748 any of the filter expressions.
1691 @param filter the indices of variable types to be filtered. Variables are 1749 @param filter the indices of variable types to be filtered. Variables
1692 only added to the list, if their type is not contained in the filter 1750 are only added to the list, if their type is not contained in the
1693 list. 1751 filter list.
1694 @param formatSequences flag indicating, that sequence or dictionary variables 1752 @param formatSequences flag indicating, that sequence or dictionary
1695 should be formatted. If it is 0 (or false), just the number of items contained 1753 variables should be formatted. If it is 0 (or false), just the
1696 in these variables is returned. (boolean) 1754 number of items contained in these variables is returned. (boolean)
1697 @return A tuple consisting of a list of formatted variables. Each variable 1755 @return A tuple consisting of a list of formatted variables. Each
1698 entry is a tuple of three elements, the variable name, its type and 1756 variable entry is a tuple of three elements, the variable name,
1699 value. 1757 its type and value.
1700 """ 1758 """
1701 varlist = [] 1759 varlist = []
1702 if scope: 1760 if scope:
1703 patternFilterObjects = self.globalsFilterObjects 1761 patternFilterObjects = self.globalsFilterObjects
1704 else: 1762 else:
1729 valtype = valtypestr[7:-1] 1787 valtype = valtypestr[7:-1]
1730 if valtype not in ConfigVarTypeStrings: 1788 if valtype not in ConfigVarTypeStrings:
1731 if ConfigVarTypeStrings.index('instance') in filter: 1789 if ConfigVarTypeStrings.index('instance') in filter:
1732 continue 1790 continue
1733 elif valtype == "sip.methoddescriptor": 1791 elif valtype == "sip.methoddescriptor":
1734 if ConfigVarTypeStrings.index('instance method') in filter: 1792 if ConfigVarTypeStrings.index(
1793 'instance method') in filter:
1735 continue 1794 continue
1736 elif valtype == "sip.enumtype": 1795 elif valtype == "sip.enumtype":
1737 if ConfigVarTypeStrings.index('class') in filter: 1796 if ConfigVarTypeStrings.index('class') in filter:
1738 continue 1797 continue
1739 valtype = valtypestr 1798 valtype = valtypestr
1741 try: 1800 try:
1742 if ConfigVarTypeStrings.index(valtype) in filter: 1801 if ConfigVarTypeStrings.index(valtype) in filter:
1743 continue 1802 continue
1744 except ValueError: 1803 except ValueError:
1745 if valtype == "classobj": 1804 if valtype == "classobj":
1746 if ConfigVarTypeStrings.index('instance') in filter: 1805 if ConfigVarTypeStrings.index(
1806 'instance') in filter:
1747 continue 1807 continue
1748 elif valtype == "sip.methoddescriptor": 1808 elif valtype == "sip.methoddescriptor":
1749 if ConfigVarTypeStrings.index('instance method') in filter: 1809 if ConfigVarTypeStrings.index(
1810 'instance method') in filter:
1750 continue 1811 continue
1751 elif valtype == "sip.enumtype": 1812 elif valtype == "sip.enumtype":
1752 if ConfigVarTypeStrings.index('class') in filter: 1813 if ConfigVarTypeStrings.index('class') in filter:
1753 continue 1814 continue
1754 elif not valtype.startswith("PySide") and \ 1815 elif not valtype.startswith("PySide") and \
1829 1890
1830 self.write("{0}{1}||{2}\n".format(DebugProtocol.ResponseCompletion, 1891 self.write("{0}{1}||{2}\n".format(DebugProtocol.ResponseCompletion,
1831 str(completions), text)) 1892 str(completions), text))
1832 1893
1833 def startDebugger(self, filename=None, host=None, port=None, 1894 def startDebugger(self, filename=None, host=None, port=None,
1834 enableTrace=True, exceptions=True, tracePython=False, redirect=True): 1895 enableTrace=True, exceptions=True, tracePython=False,
1896 redirect=True):
1835 """ 1897 """
1836 Public method used to start the remote debugger. 1898 Public method used to start the remote debugger.
1837 1899
1838 @param filename the program to be debugged (string) 1900 @param filename the program to be debugged (string)
1839 @param host hostname of the debug server (string) 1901 @param host hostname of the debug server (string)
1840 @param port portnumber of the debug server (int) 1902 @param port portnumber of the debug server (int)
1841 @param enableTrace flag to enable the tracing function (boolean) 1903 @param enableTrace flag to enable the tracing function (boolean)
1842 @param exceptions flag to enable exception reporting of the IDE (boolean) 1904 @param exceptions flag to enable exception reporting of the IDE
1843 @param tracePython flag to enable tracing into the Python library (boolean) 1905 (boolean)
1844 @param redirect flag indicating redirection of stdin, stdout and stderr (boolean) 1906 @param tracePython flag to enable tracing into the Python library
1907 (boolean)
1908 @param redirect flag indicating redirection of stdin, stdout and
1909 stderr (boolean)
1845 """ 1910 """
1846 global debugClient 1911 global debugClient
1847 if host is None: 1912 if host is None:
1848 host = os.getenv('ERICHOST', 'localhost') 1913 host = os.getenv('ERICHOST', 'localhost')
1849 if port is None: 1914 if port is None:
1891 @param progargs commandline for the program to be debugged 1956 @param progargs commandline for the program to be debugged
1892 (list of strings) 1957 (list of strings)
1893 @param wd working directory for the program execution (string) 1958 @param wd working directory for the program execution (string)
1894 @param host hostname of the debug server (string) 1959 @param host hostname of the debug server (string)
1895 @param port portnumber of the debug server (int) 1960 @param port portnumber of the debug server (int)
1896 @param exceptions flag to enable exception reporting of the IDE (boolean) 1961 @param exceptions flag to enable exception reporting of the IDE
1897 @param tracePython flag to enable tracing into the Python library (boolean) 1962 (boolean)
1898 @param redirect flag indicating redirection of stdin, stdout and stderr (boolean) 1963 @param tracePython flag to enable tracing into the Python library
1964 (boolean)
1965 @param redirect flag indicating redirection of stdin, stdout and
1966 stderr (boolean)
1899 """ 1967 """
1900 if host is None: 1968 if host is None:
1901 host = os.getenv('ERICHOST', 'localhost') 1969 host = os.getenv('ERICHOST', 'localhost')
1902 if port is None: 1970 if port is None:
1903 port = os.getenv('ERICPORT', 42424) 1971 port = os.getenv('ERICPORT', 42424)
1933 sys.excepthook = self.__unhandled_exception 2001 sys.excepthook = self.__unhandled_exception
1934 2002
1935 # This will eventually enter a local event loop. 2003 # This will eventually enter a local event loop.
1936 # Note the use of backquotes to cause a repr of self.running. The 2004 # Note the use of backquotes to cause a repr of self.running. The
1937 # need for this is on Windows os where backslash is the path separator. 2005 # need for this is on Windows os where backslash is the path separator.
1938 # They will get inadvertantly stripped away during the eval causing IOErrors 2006 # They will get inadvertantly stripped away during the eval causing
1939 # if self.running is passed as a normal str. 2007 # IOErrors if self.running is passed as a normal str.
1940 self.debugMod.__dict__['__file__'] = self.running 2008 self.debugMod.__dict__['__file__'] = self.running
1941 sys.modules['__main__'] = self.debugMod 2009 sys.modules['__main__'] = self.debugMod
1942 res = self.mainThread.run('exec(open(' + repr(self.running) + ').read())', 2010 res = self.mainThread.run(
1943 self.debugMod.__dict__) 2011 'exec(open(' + repr(self.running) + ').read())',
2012 self.debugMod.__dict__)
1944 self.progTerminated(res) 2013 self.progTerminated(res)
1945 2014
1946 def run_call(self, scriptname, func, *args): 2015 def run_call(self, scriptname, func, *args):
1947 """ 2016 """
1948 Public method used to start the remote debugger and call a function. 2017 Public method used to start the remote debugger and call a function.
1970 version = 'v4' 2039 version = 'v4'
1971 if version == 'v4': 2040 if version == 'v4':
1972 family = socket.AF_INET 2041 family = socket.AF_INET
1973 else: 2042 else:
1974 family = socket.AF_INET6 2043 family = socket.AF_INET6
1975 return socket.getaddrinfo(host, None, family, socket.SOCK_STREAM)[0][4][0] 2044 return socket.getaddrinfo(host, None,
2045 family, socket.SOCK_STREAM)[0][4][0]
1976 2046
1977 def main(self): 2047 def main(self):
1978 """ 2048 """
1979 Public method implementing the main method. 2049 Public method implementing the main method.
1980 """ 2050 """
2093 self.sessionClose(0) 2163 self.sessionClose(0)
2094 return pid 2164 return pid
2095 2165
2096 def close(self, fd): 2166 def close(self, fd):
2097 """ 2167 """
2098 Private method implementing a close method as a replacement for os.close(). 2168 Private method implementing a close method as a replacement for
2169 os.close().
2099 2170
2100 It prevents the debugger connections from being closed. 2171 It prevents the debugger connections from being closed.
2101 2172
2102 @param fd file descriptor to be closed (integer) 2173 @param fd file descriptor to be closed (integer)
2103 """ 2174 """
2113 environment variable. 2184 environment variable.
2114 2185
2115 @param firstEntry entry to be put first in sys.path (string) 2186 @param firstEntry entry to be put first in sys.path (string)
2116 @return path list for use as sys.path (list of strings) 2187 @return path list for use as sys.path (list of strings)
2117 """ 2188 """
2118 sysPath = [path for path in os.environ.get("PYTHONPATH", "").split(os.pathsep) 2189 sysPath = [path for path in os.environ.get("PYTHONPATH", "")
2190 .split(os.pathsep)
2119 if path not in sys.path] + sys.path[:] 2191 if path not in sys.path] + sys.path[:]
2120 if "" in sysPath: 2192 if "" in sysPath:
2121 sysPath.remove("") 2193 sysPath.remove("")
2122 sysPath.insert(0, firstEntry) 2194 sysPath.insert(0, firstEntry)
2123 sysPath.insert(0, '') 2195 sysPath.insert(0, '')

eric ide

mercurial