DebugClients/Python3/DebugClientBase.py

branch
jsonrpc
changeset 5124
1ba8ee313b57
parent 5120
c5189d404cc7
child 5125
eb1b3e0577e4
equal deleted inserted replaced
5123:d07dd3cf0dc3 5124:1ba8ee313b57
189 self.localsFilterObjects = [] 189 self.localsFilterObjects = []
190 190
191 self.pendingResponse = DebugProtocol.ResponseOK 191 self.pendingResponse = DebugProtocol.ResponseOK
192 self._fncache = {} 192 self._fncache = {}
193 self.dircache = [] 193 self.dircache = []
194 self.inRawMode = False 194 ## self.inRawMode = False
195 self.mainProcStr = None # used for the passive mode 195 self.mainProcStr = None # used for the passive mode
196 self.passive = False # used to indicate the passive mode 196 self.passive = False # used to indicate the passive mode
197 self.running = None 197 self.running = None
198 self.test = None 198 self.test = None
199 self.tracePython = False 199 self.tracePython = False
300 d["broken"] = self.isBroken() 300 d["broken"] = self.isBroken()
301 else: 301 else:
302 d["broken"] = False 302 d["broken"] = False
303 threadList.append(d) 303 threadList.append(d)
304 304
305 self.write("{0}{1!r}\n".format(DebugProtocol.ResponseThreadList, 305 ## self.write("{0}{1!r}\n".format(DebugProtocol.ResponseThreadList,
306 (currentId, threadList))) 306 ## (currentId, threadList)))
307 self.__sendJsonCommand("ResponseThreadList", {
308 "currentID": currentId,
309 "threadList": threadList,
310 })
307 311
308 def input(self, prompt, echo=True): 312 def input(self, prompt, echo=True):
309 """ 313 """
310 Public method to implement input() using the event loop. 314 Public method to implement input() using the event loop.
311 315
317 ## DebugProtocol.ResponseRaw, (prompt, echo))) 321 ## DebugProtocol.ResponseRaw, (prompt, echo)))
318 self.__sendJsonCommand("RequestRaw", { 322 self.__sendJsonCommand("RequestRaw", {
319 "prompt": prompt, 323 "prompt": prompt,
320 "echo": echo, 324 "echo": echo,
321 }) 325 })
322 self.inRawMode = True 326 ## self.inRawMode = True
323 self.eventLoop(True) 327 self.eventLoop(True)
324 return self.rawLine 328 return self.rawLine
325 329
326 def __exceptionRaised(self): 330 def __exceptionRaised(self):
327 """ 331 """
328 Private method called in the case of an exception. 332 Private method called in the case of an exception.
329 333
330 It ensures that the debug server is informed of the raised exception. 334 It ensures that the debug server is informed of the raised exception.
331 """ 335 """
332 self.pendingResponse = DebugProtocol.ResponseException 336 ## self.pendingResponse = DebugProtocol.ResponseException
337 self.__sendJsonCommand("ResponseException", {})
333 338
334 def sessionClose(self, exit=True): 339 def sessionClose(self, exit=True):
335 """ 340 """
336 Public method to close the session with the debugger and optionally 341 Public method to close the session with the debugger and optionally
337 terminate. 342 terminate.
374 except SyntaxError: 379 except SyntaxError:
375 exctype, excval, exctb = sys.exc_info() 380 exctype, excval, exctb = sys.exc_info()
376 try: 381 try:
377 message = str(excval) 382 message = str(excval)
378 filename = excval.filename 383 filename = excval.filename
379 linenr = excval.lineno 384 lineno = excval.lineno
380 charnr = excval.offset 385 charno = excval.offset
381 except (AttributeError, ValueError): 386 except (AttributeError, ValueError):
382 exclist = [] 387 message = ""
383 else: 388 filename = ""
384 exclist = [message, [filename, linenr, charnr]] 389 lineno = 0
385 390 charno = 0
386 self.write("{0}{1}\n".format( 391 self.sendSyntaxError(message, filename, lineno, charno)
387 DebugProtocol.ResponseSyntax, str(exclist)))
388 return None 392 return None
389 393
390 return code 394 return code
391 395
392 def handleLine(self, line): 396 def handleLine(self, line):
403 line = line[:-1] 407 line = line[:-1]
404 408
405 ## printerr(line) ##debug 409 ## printerr(line) ##debug
406 410
407 if "jsonrpc" in line: 411 if "jsonrpc" in line:
408 return self.__handleJsonCommand(line) 412 return self.handleJsonCommand(line)
409 413
410 eoc = line.find('<') 414 eoc = line.find('<')
411 415
412 if eoc >= 0 and line[0] == '>': 416 if eoc >= 0 and line[0] == '>':
413 # Get the command part and any argument. 417 # Get the command part and any argument.
414 cmd = line[:eoc + 1] 418 cmd = line[:eoc + 1]
415 arg = line[eoc + 1:] 419 arg = line[eoc + 1:]
416 420
417 if cmd == DebugProtocol.RequestVariables: 421 ## if cmd == DebugProtocol.RequestVariables:
418 frmnr, scope, filter = eval(arg.replace("u'", "'")) 422 ## frmnr, scope, filter = eval(arg.replace("u'", "'"))
419 self.__dumpVariables(int(frmnr), int(scope), filter) 423 ## self.__dumpVariables(int(frmnr), int(scope), filter)
420 return 424 ## return
421 425 ##
422 if cmd == DebugProtocol.RequestVariable: 426 ## if cmd == DebugProtocol.RequestVariable:
423 var, frmnr, scope, filter = eval(arg.replace("u'", "'")) 427 ## var, frmnr, scope, filter = eval(arg.replace("u'", "'"))
424 self.__dumpVariable(var, int(frmnr), int(scope), filter) 428 ## self.__dumpVariable(var, int(frmnr), int(scope), filter)
425 return 429 ## return
426 430 ##
427 if cmd == DebugProtocol.RequestThreadList: 431 ## if cmd == DebugProtocol.RequestThreadList:
428 self.__dumpThreadList() 432 ## self.__dumpThreadList()
429 return 433 ## return
430 434 ##
431 if cmd == DebugProtocol.RequestThreadSet: 435 ## if cmd == DebugProtocol.RequestThreadSet:
432 tid = eval(arg) 436 ## tid = eval(arg)
433 if tid in self.threads: 437 ## if tid in self.threads:
434 self.setCurrentThread(tid) 438 ## self.setCurrentThread(tid)
435 self.write(DebugProtocol.ResponseThreadSet + '\n') 439 ## self.write(DebugProtocol.ResponseThreadSet + '\n')
436 stack = self.currentThread.getStack() 440 ## stack = self.currentThread.getStack()
437 self.write('{0}{1!r}\n'.format( 441 ## self.write('{0}{1!r}\n'.format(
438 DebugProtocol.ResponseStack, stack)) 442 ## DebugProtocol.ResponseStack, stack))
439 return 443 ## return
440 444 ##
441 ## if cmd == DebugProtocol.RequestStep: 445 ## if cmd == DebugProtocol.RequestStep:
442 ## self.currentThread.step(True) 446 ## self.currentThread.step(True)
443 ## self.eventExit = True 447 ## self.eventExit = True
444 ## return 448 ## return
445 ## 449 ##
470 ## if cmd == DebugProtocol.RequestOK: 474 ## if cmd == DebugProtocol.RequestOK:
471 ## self.write(self.pendingResponse + '\n') 475 ## self.write(self.pendingResponse + '\n')
472 ## self.pendingResponse = DebugProtocol.ResponseOK 476 ## self.pendingResponse = DebugProtocol.ResponseOK
473 ## return 477 ## return
474 ## 478 ##
475 if cmd == DebugProtocol.RequestCallTrace: 479 ## if cmd == DebugProtocol.RequestCallTrace:
476 if arg.strip().lower() == "on": 480 ## if arg.strip().lower() == "on":
477 callTraceEnabled = True 481 ## callTraceEnabled = True
478 else: 482 ## else:
479 callTraceEnabled = False 483 ## callTraceEnabled = False
480 if self.debugging: 484 ## if self.debugging:
481 self.callTraceEnabled = callTraceEnabled 485 ## self.callTraceEnabled = callTraceEnabled
482 else: 486 ## else:
483 self.__newCallTraceEnabled = callTraceEnabled 487 ## self.__newCallTraceEnabled = callTraceEnabled
484 # remember for later 488 ## # remember for later
485 return 489 ## return
486 490 ##
487 ## if cmd == DebugProtocol.RequestEnv: 491 ## if cmd == DebugProtocol.RequestEnv:
488 ## env = eval(arg.replace("u'", "'")) 492 ## env = eval(arg.replace("u'", "'"))
489 ## for key, value in env.items(): 493 ## for key, value in env.items():
490 ## if key.endswith("+"): 494 ## if key.endswith("+"):
491 ## if key[:-1] in os.environ: 495 ## if key[:-1] in os.environ:
674 ## self.cover.stop() 678 ## self.cover.stop()
675 ## self.cover.save() 679 ## self.cover.save()
676 ## self.writestream.flush() 680 ## self.writestream.flush()
677 ## self.progTerminated(res) 681 ## self.progTerminated(res)
678 ## return 682 ## return
679 683 ##
680 if cmd == DebugProtocol.RequestShutdown: 684 ## if cmd == DebugProtocol.RequestShutdown:
681 self.sessionClose() 685 ## self.sessionClose()
682 return 686 ## return
683 687 ##
684 if cmd == DebugProtocol.RequestBreak: 688 ## if cmd == DebugProtocol.RequestBreak:
685 fn, line, temporary, set, cond = arg.split('@@') 689 ## fn, line, temporary, set, cond = arg.split('@@')
686 line = int(line) 690 ## line = int(line)
687 set = int(set) 691 ## set = int(set)
688 temporary = int(temporary) 692 ## temporary = int(temporary)
689 693 ##
690 if set: 694 ## if set:
691 if cond == 'None' or cond == '': 695 ## if cond == 'None' or cond == '':
692 cond = None 696 ## cond = None
693 else: 697 ## else:
694 try: 698 ## try:
695 compile(cond, '<string>', 'eval') 699 ## compile(cond, '<string>', 'eval')
696 except SyntaxError: 700 ## except SyntaxError:
697 self.write('{0}{1},{2:d}\n'.format( 701 ## self.write('{0}{1},{2:d}\n'.format(
698 DebugProtocol.ResponseBPConditionError, 702 ## DebugProtocol.ResponseBPConditionError,
699 fn, line)) 703 ## fn, line))
700 return 704 ## return
701 self.mainThread.set_break(fn, line, temporary, cond) 705 ## self.mainThread.set_break(fn, line, temporary, cond)
702 else: 706 ## else:
703 self.mainThread.clear_break(fn, line) 707 ## self.mainThread.clear_break(fn, line)
704 708 ##
705 return 709 ## return
706 710 ##
707 if cmd == DebugProtocol.RequestBreakEnable: 711 ## if cmd == DebugProtocol.RequestBreakEnable:
708 fn, line, enable = arg.split(',') 712 ## fn, line, enable = arg.split(',')
709 line = int(line) 713 ## line = int(line)
710 enable = int(enable) 714 ## enable = int(enable)
711 715 ##
712 bp = self.mainThread.get_break(fn, line) 716 ## bp = self.mainThread.get_break(fn, line)
713 if bp is not None: 717 ## if bp is not None:
714 if enable: 718 ## if enable:
715 bp.enable() 719 ## bp.enable()
716 else: 720 ## else:
717 bp.disable() 721 ## bp.disable()
718 722 ##
719 return 723 ## return
720 724 ##
721 if cmd == DebugProtocol.RequestBreakIgnore: 725 ## if cmd == DebugProtocol.RequestBreakIgnore:
722 fn, line, count = arg.split(',') 726 ## fn, line, count = arg.split(',')
723 line = int(line) 727 ## line = int(line)
724 count = int(count) 728 ## count = int(count)
725 729 ##
726 bp = self.mainThread.get_break(fn, line) 730 ## bp = self.mainThread.get_break(fn, line)
727 if bp is not None: 731 ## if bp is not None:
728 bp.ignore = count 732 ## bp.ignore = count
729 733 ##
730 return 734 ## return
731 735 ##
732 if cmd == DebugProtocol.RequestWatch: 736 ## if cmd == DebugProtocol.RequestWatch:
733 cond, temporary, set = arg.split('@@') 737 ## cond, temporary, set = arg.split('@@')
734 set = int(set) 738 ## set = int(set)
735 temporary = int(temporary) 739 ## temporary = int(temporary)
736 740 ##
737 if set: 741 ## if set:
738 if not cond.endswith('??created??') and \ 742 ## if not cond.endswith('??created??') and \
739 not cond.endswith('??changed??'): 743 ## not cond.endswith('??changed??'):
740 try: 744 ## try:
741 compile(cond, '<string>', 'eval') 745 ## compile(cond, '<string>', 'eval')
742 except SyntaxError: 746 ## except SyntaxError:
743 self.write('{0}{1}\n'.format( 747 ## self.write('{0}{1}\n'.format(
744 DebugProtocol.ResponseWPConditionError, cond)) 748 ## DebugProtocol.ResponseWPConditionError, cond))
745 return 749 ## return
746 self.mainThread.set_watch(cond, temporary) 750 ## self.mainThread.set_watch(cond, temporary)
747 else: 751 ## else:
748 self.mainThread.clear_watch(cond) 752 ## self.mainThread.clear_watch(cond)
749 753 ##
750 return 754 ## return
751 755 ##
752 if cmd == DebugProtocol.RequestWatchEnable: 756 ## if cmd == DebugProtocol.RequestWatchEnable:
753 cond, enable = arg.split(',') 757 ## cond, enable = arg.split(',')
754 enable = int(enable) 758 ## enable = int(enable)
755 759 ##
756 bp = self.mainThread.get_watch(cond) 760 ## bp = self.mainThread.get_watch(cond)
757 if bp is not None: 761 ## if bp is not None:
758 if enable: 762 ## if enable:
759 bp.enable() 763 ## bp.enable()
760 else: 764 ## else:
761 bp.disable() 765 ## bp.disable()
762 766 ##
763 return 767 ## return
764 768 ##
765 if cmd == DebugProtocol.RequestWatchIgnore: 769 ## if cmd == DebugProtocol.RequestWatchIgnore:
766 cond, count = arg.split(',') 770 ## cond, count = arg.split(',')
767 count = int(count) 771 ## count = int(count)
768 772 ##
769 bp = self.mainThread.get_watch(cond) 773 ## bp = self.mainThread.get_watch(cond)
770 if bp is not None: 774 ## if bp is not None:
771 bp.ignore = count 775 ## bp.ignore = count
772 776 ##
773 return 777 ## return
774 778 ##
775 if cmd == DebugProtocol.RequestEval: 779 ## if cmd == DebugProtocol.RequestEval:
776 try: 780 ## try:
777 value = eval( 781 ## value = eval(
778 arg, 782 ## arg,
779 self.currentThread.getCurrentFrame().f_globals, 783 ## self.currentThread.getCurrentFrame().f_globals,
780 self.currentThread.getFrameLocals(self.framenr)) 784 ## self.currentThread.getFrameLocals(self.framenr))
781 self.currentThread.storeFrameLocals(self.framenr) 785 ## self.currentThread.storeFrameLocals(self.framenr)
782 except Exception: 786 ## except Exception:
783 # Report the exception and the traceback 787 ## # Report the exception and the traceback
784 try: 788 ## try:
785 type, value, tb = sys.exc_info() 789 ## type, value, tb = sys.exc_info()
786 sys.last_type = type 790 ## sys.last_type = type
787 sys.last_value = value 791 ## sys.last_value = value
788 sys.last_traceback = tb 792 ## sys.last_traceback = tb
789 tblist = traceback.extract_tb(tb) 793 ## tblist = traceback.extract_tb(tb)
790 del tblist[:1] 794 ## del tblist[:1]
791 list = traceback.format_list(tblist) 795 ## list = traceback.format_list(tblist)
792 if list: 796 ## if list:
793 list.insert(0, "Traceback (innermost last):\n") 797 ## list.insert(0, "Traceback (innermost last):\n")
794 list[len(list):] = \ 798 ## list[len(list):] = \
795 traceback.format_exception_only(type, value) 799 ## traceback.format_exception_only(type, value)
796 finally: 800 ## finally:
797 tblist = tb = None 801 ## tblist = tb = None
798 802 ##
799 for l in list: 803 ## for l in list:
800 self.write(l) 804 ## self.write(l)
801 805 ##
802 self.write(DebugProtocol.ResponseException + '\n') 806 ## self.write(DebugProtocol.ResponseException + '\n')
803 807 ##
804 else: 808 ## else:
805 self.write(str(value) + '\n') 809 ## self.write(str(value) + '\n')
806 self.write(DebugProtocol.ResponseOK + '\n') 810 ## self.write(DebugProtocol.ResponseOK + '\n')
807 811 ##
808 return 812 ## return
809 813 ##
810 if cmd == DebugProtocol.RequestExec: 814 ## if cmd == DebugProtocol.RequestExec:
811 _globals = self.currentThread.getCurrentFrame().f_globals 815 ## _globals = self.currentThread.getCurrentFrame().f_globals
812 _locals = self.currentThread.getFrameLocals(self.framenr) 816 ## _locals = self.currentThread.getFrameLocals(self.framenr)
813 try: 817 ## try:
814 code = compile(arg + '\n', '<stdin>', 'single') 818 ## code = compile(arg + '\n', '<stdin>', 'single')
815 exec(code, _globals, _locals) 819 ## exec(code, _globals, _locals)
816 self.currentThread.storeFrameLocals(self.framenr) 820 ## self.currentThread.storeFrameLocals(self.framenr)
817 except Exception: 821 ## except Exception:
818 # Report the exception and the traceback 822 ## # Report the exception and the traceback
819 try: 823 ## try:
820 type, value, tb = sys.exc_info() 824 ## type, value, tb = sys.exc_info()
821 sys.last_type = type 825 ## sys.last_type = type
822 sys.last_value = value 826 ## sys.last_value = value
823 sys.last_traceback = tb 827 ## sys.last_traceback = tb
824 tblist = traceback.extract_tb(tb) 828 ## tblist = traceback.extract_tb(tb)
825 del tblist[:1] 829 ## del tblist[:1]
826 list = traceback.format_list(tblist) 830 ## list = traceback.format_list(tblist)
827 if list: 831 ## if list:
828 list.insert(0, "Traceback (innermost last):\n") 832 ## list.insert(0, "Traceback (innermost last):\n")
829 list[len(list):] = \ 833 ## list[len(list):] = \
830 traceback.format_exception_only(type, value) 834 ## traceback.format_exception_only(type, value)
831 finally: 835 ## finally:
832 tblist = tb = None 836 ## tblist = tb = None
833 837 ##
834 for l in list: 838 ## for l in list:
835 self.write(l) 839 ## self.write(l)
836 840 ##
837 self.write(DebugProtocol.ResponseException + '\n') 841 ## self.write(DebugProtocol.ResponseException + '\n')
838 842 ##
839 return 843 ## return
840 844 ##
841 ## if cmd == DebugProtocol.RequestBanner: 845 ## if cmd == DebugProtocol.RequestBanner:
842 ## self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner, 846 ## self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner,
843 ## str(("Python {0}".format(sys.version), 847 ## str(("Python {0}".format(sys.version),
844 ## socket.gethostname(), self.variant)))) 848 ## socket.gethostname(), self.variant))))
845 ## return 849 ## return
848 ## self.write('{0}{1:d}, "Python3"\n'.format( 852 ## self.write('{0}{1:d}, "Python3"\n'.format(
849 ## DebugProtocol.ResponseCapabilities, 853 ## DebugProtocol.ResponseCapabilities,
850 ## self.__clientCapabilities())) 854 ## self.__clientCapabilities()))
851 ## return 855 ## return
852 ## 856 ##
853 if cmd == DebugProtocol.RequestCompletion: 857 ## if cmd == DebugProtocol.RequestCompletion:
854 self.__completionList(arg.replace("u'", "'")) 858 ## self.__completionList(arg.replace("u'", "'"))
855 return 859 ## return
856 860 ##
857 if cmd == DebugProtocol.RequestSetFilter: 861 ## if cmd == DebugProtocol.RequestSetFilter:
858 scope, filterString = eval(arg.replace("u'", "'")) 862 ## scope, filterString = eval(arg.replace("u'", "'"))
859 self.__generateFilterObjects(int(scope), filterString) 863 ## self.__generateFilterObjects(int(scope), filterString)
860 return 864 ## return
861 865 ##
862 if cmd == DebugProtocol.RequestUTPrepare: 866 if cmd == DebugProtocol.RequestUTPrepare:
863 fn, tn, tfn, failed, cov, covname, erase = arg.split('|') 867 fn, tn, tfn, failed, cov, covname, erase = arg.split('|')
864 sys.path.insert(0, os.path.dirname(os.path.abspath(fn))) 868 sys.path.insert(0, os.path.dirname(os.path.abspath(fn)))
865 os.chdir(sys.path[0]) 869 os.chdir(sys.path[0])
866 failed = eval(failed) 870 failed = eval(failed)
1022 ## tblist = exc_tb = None 1026 ## tblist = exc_tb = None
1023 ## 1027 ##
1024 ## for l in list: 1028 ## for l in list:
1025 ## self.write(l) 1029 ## self.write(l)
1026 1030
1027 def __handleJsonCommand(self, jsonStr): 1031 def handleJsonCommand(self, jsonStr):
1028 """ 1032 """
1029 Private method to handle a command serialized as a JSON string. 1033 Public method to handle a command serialized as a JSON string.
1030 """ 1034 """
1031 import json 1035 import json
1032 1036
1033 try: 1037 try:
1034 commandDict = json.loads(jsonStr.strip()) 1038 commandDict = json.loads(jsonStr.strip())
1036 printerr(str(err)) 1040 printerr(str(err))
1037 return 1041 return
1038 1042
1039 method = commandDict["method"] 1043 method = commandDict["method"]
1040 params = commandDict["params"] 1044 params = commandDict["params"]
1045
1046 if method == "RequestVariables":
1047 self.__dumpVariables(
1048 params["frameNumber"], params["scope"], params["filters"])
1049 return
1050
1051 if method == "RequestVariable":
1052 self.__dumpVariable(
1053 params["variable"], params["frameNumber"],
1054 params["scope"], params["filters"])
1055 return
1056
1057 if method == "RequestThreadList":
1058 self.__dumpThreadList()
1059 return
1060
1061 if method == "RequestThreadSet":
1062 if params["threadID"] in self.threads:
1063 self.setCurrentThread(params["threadID"])
1064 self.__sendJsonCommand("ResponseThreadSet", {})
1065 stack = self.currentThread.getStack()
1066 self.__sendJsonCommand("ResponseStack", {
1067 "stack": stack,
1068 })
1069 return
1041 1070
1042 if method == "RequestCapabilities": 1071 if method == "RequestCapabilities":
1043 self.__sendJsonCommand("ResponseCapabilities", { 1072 self.__sendJsonCommand("ResponseCapabilities", {
1044 "capabilities": self.__clientCapabilities(), 1073 "capabilities": self.__clientCapabilities(),
1045 "clientType": "Python3" 1074 "clientType": "Python3"
1050 self.__sendJsonCommand("ResponseBanner", { 1079 self.__sendJsonCommand("ResponseBanner", {
1051 "version": "Python {0}".format(sys.version), 1080 "version": "Python {0}".format(sys.version),
1052 "platform": socket.gethostname(), 1081 "platform": socket.gethostname(),
1053 "dbgclient": self.variant, 1082 "dbgclient": self.variant,
1054 }) 1083 })
1084 return
1085
1086 if method == "RequestSetFilter":
1087 self.__generateFilterObjects(params["scope"], params["filter"])
1088 return
1089
1090 if method == "RequestCallTrace":
1091 if self.debugging:
1092 self.callTraceEnabled = params["enable"]
1093 else:
1094 self.__newCallTraceEnabled = params["enable"]
1095 # remember for later
1055 return 1096 return
1056 1097
1057 if method == "RequestEnvironment": 1098 if method == "RequestEnvironment":
1058 for key, value in params["environment"].items(): 1099 for key, value in params["environment"].items():
1059 if key.endswith("+"): 1100 if key.endswith("+"):
1078 else: 1119 else:
1079 os.chdir(params["workdir"]) 1120 os.chdir(params["workdir"])
1080 1121
1081 self.running = sys.argv[0] 1122 self.running = sys.argv[0]
1082 self.mainFrame = None 1123 self.mainFrame = None
1083 self.inRawMode = False 1124 ## self.inRawMode = False
1084 self.debugging = True 1125 self.debugging = True
1085 1126
1086 self.fork_auto = params["autofork"] 1127 self.fork_auto = params["autofork"]
1087 self.fork_child = params["forkChild"] 1128 self.fork_child = params["forkChild"]
1088 1129
1122 os.chdir(params["workdir"]) 1163 os.chdir(params["workdir"])
1123 1164
1124 self.running = sys.argv[0] 1165 self.running = sys.argv[0]
1125 self.mainFrame = None 1166 self.mainFrame = None
1126 self.botframe = None 1167 self.botframe = None
1127 self.inRawMode = False 1168 ## self.inRawMode = False
1128 1169
1129 self.fork_auto = params["autofork"] 1170 self.fork_auto = params["autofork"]
1130 self.fork_child = params["forkChild"] 1171 self.fork_child = params["forkChild"]
1131 1172
1132 self.threads.clear() 1173 self.threads.clear()
1365 self.currentThread.go(params["special"]) 1406 self.currentThread.go(params["special"])
1366 self.eventExit = True 1407 self.eventExit = True
1367 return 1408 return
1368 1409
1369 if method == "RawInput": 1410 if method == "RawInput":
1370 # If we are handling raw mode input then reset the mode and break out 1411 # If we are handling raw mode input then break out of the current
1371 # of the current event loop. 1412 # event loop.
1372 ## if self.inRawMode:
1373 ## self.inRawMode = False
1374 self.rawLine = params["input"] 1413 self.rawLine = params["input"]
1375 self.eventExit = True 1414 self.eventExit = True
1376 return 1415 return
1377 1416
1417 if method == "RequestBreakpoint":
1418 if params["setBreakpoint"]:
1419 if params["condition"] in ['None', '']:
1420 params["condition"] = None
1421 elif params["condition"] is not None:
1422 try:
1423 compile(params["condition"], '<string>', 'eval')
1424 except SyntaxError:
1425 self.__sendJsonCommand("ResponseBPConditionError", {
1426 "filename": params["filename"],
1427 "line": params["line"],
1428 })
1429 return
1430 self.mainThread.set_break(
1431 params["filename"], params["line"], params["temporary"],
1432 params["condition"])
1433 else:
1434 self.mainThread.clear_break(params["filename"], params["line"])
1435
1436 return
1437
1438 if method == "RequestBreakpointEnable":
1439 bp = self.mainThread.get_break(params["filename"], params["line"])
1440 if bp is not None:
1441 if params["enable"]:
1442 bp.enable()
1443 else:
1444 bp.disable()
1445 return
1446
1447 if method == "RequestBreakpointIgnore":
1448 bp = self.mainThread.get_break(params["filename"], params["line"])
1449 if bp is not None:
1450 bp.ignore = params["count"]
1451 return
1452
1453 if method == "RequestWatch":
1454 if params["setWatch"]:
1455 if not params["condition"].endswith(
1456 ('??created??', '??changed??')):
1457 try:
1458 compile(params["condition"], '<string>', 'eval')
1459 except SyntaxError:
1460 self.__sendJsonCommand("ResponseWatchConditionError", {
1461 "condition": params["condition"],
1462 })
1463 return
1464 self.mainThread.set_watch(
1465 params["condition"], params["temporary"])
1466 else:
1467 self.mainThread.clear_watch(params["condition"])
1468 return
1469
1470 if method == "RequestWatchEnable":
1471 wp = self.mainThread.get_watch(params["condition"])
1472 if wp is not None:
1473 if params["enable"]:
1474 wp.enable()
1475 else:
1476 wp.disable()
1477 return
1478
1479 if method == "RequestWatchIgnore":
1480 wp = self.mainThread.get_watch(params["condition"])
1481 if wp is not None:
1482 wp.ignore = params["count"]
1483 return
1484
1485 if method == "RequestShutdown":
1486 self.sessionClose()
1487 return
1488
1489 if method == "RequestCompletion":
1490 self.__completionList(params["text"])
1491 return
1378 1492
1379 def __sendJsonCommand(self, command, params): 1493 def __sendJsonCommand(self, command, params):
1380 """ 1494 """
1381 Private method to send a single command to the client. 1495 Private method to send a single command to the client.
1382 1496
1392 "method": command, 1506 "method": command,
1393 "params": params, 1507 "params": params,
1394 } 1508 }
1395 cmd = json.dumps(commandDict) + '\n' 1509 cmd = json.dumps(commandDict) + '\n'
1396 self.write(cmd) 1510 self.write(cmd)
1511
1512 def sendClearTemporaryBreakpoint(self, filename, lineno):
1513 """
1514 Public method to signal the deletion of a temporary breakpoint.
1515
1516 @param filename name of the file the bp belongs to
1517 @type str
1518 @param lineno linenumber of the bp
1519 @type int
1520 """
1521 self.__sendJsonCommand("ResponseClearBreakpoint", {
1522 "filename": filename,
1523 "line": lineno
1524 })
1525
1526 def sendClearTemporaryWatch(self, condition):
1527 """
1528 Public method to signal the deletion of a temporary watch expression.
1529
1530 @param condition condition of the watch expression to be cleared
1531 @type str
1532 """
1533 self.__sendJsonCommand("ResponseClearWatch", {
1534 "condition": condition,
1535 })
1536
1537 def sendResponseLine(self, stack):
1538 """
1539 Public method to send the current call stack.
1540
1541 @param stack call stack
1542 @type list
1543 """
1544 self.__sendJsonCommand("ResponseLine", {
1545 "stack": stack,
1546 })
1547
1548 def sendCallTrace(self, event, fromStr, toStr):
1549 """
1550 Public method to send a call trace entry.
1551
1552 @param event trace event (call or return)
1553 @type str
1554 @param fromstr pre-formatted origin info
1555 @type str
1556 @param toStr pre-formatted target info
1557 @type str
1558 """
1559 self.__sendJsonCommand("CallTrace", {
1560 "event": event[0],
1561 "from": fromStr,
1562 "to": toStr,
1563 })
1564
1565 def sendException(self, exceptionType, exceptionMessage, stack):
1566 """
1567 Public method to send information for an exception.
1568
1569 @param exceptionType type of exception raised
1570 @type str
1571 @param exceptionMessage message of the exception
1572 @type str
1573 @param stack stack trace information
1574 @param list
1575 """
1576 self.__sendJsonCommand("ResponseException", {
1577 "type": exceptionType,
1578 "message": exceptionMessage,
1579 "stack": stack,
1580 })
1581
1582 def sendSyntaxError(self, message, filename, lineno, charno):
1583 """
1584 Public method to send information for a syntax error.
1585
1586 @param message syntax error message
1587 @type str
1588 @param filename name of the faulty file
1589 @type str
1590 @param lineno line number info
1591 @type int
1592 @param charno character number info
1593 @tyoe int
1594 """
1595 self.__sendJsonCommand("ResponseSyntax", {
1596 "message": message,
1597 "filename": filename,
1598 "linenumber": lineno,
1599 "characternumber": charno,
1600 })
1601
1602 def sendPassiveStartup(self, filename, exceptions):
1603 """
1604 Public method to send the passive start information.
1605
1606 @param filename name of the script
1607 @type str
1608 @param exceptions flag to enable exception reporting of the IDE
1609 @type bool
1610 """
1611 self.__sendJsonCommand("PassiveStartup", {
1612 "filename": filename,
1613 "exceptions": exceptions,
1614 })
1397 1615
1398 def __clientCapabilities(self): 1616 def __clientCapabilities(self):
1399 """ 1617 """
1400 Private method to determine the clients capabilities. 1618 Private method to determine the clients capabilities.
1401 1619
1604 except Exception: 1822 except Exception:
1605 fargs = "" 1823 fargs = ""
1606 else: 1824 else:
1607 fargs = "" 1825 fargs = ""
1608 1826
1609 siglist = [message, [filename, linenr, ffunc, fargs]] 1827 ## siglist = [message, [filename, linenr, ffunc, fargs]]
1610 1828 ##
1611 self.write("{0}{1}".format(DebugProtocol.ResponseSignal, str(siglist))) 1829 ## self.write("{0}{1}".format(DebugProtocol.ResponseSignal, str(siglist)))
1830 self.__sendJsonCommand("ResponseSignal", {
1831 "message": message,
1832 "filename": filename,
1833 "linenumber": linenr,
1834 "function": ffunc,
1835 "arguments": fargs,
1836 })
1612 1837
1613 def absPath(self, fn): 1838 def absPath(self, fn):
1614 """ 1839 """
1615 Public method to convert a filename to an absolute name. 1840 Public method to convert a filename to an absolute name.
1616 1841
1699 status = 1 1924 status = 1
1700 1925
1701 if self.running: 1926 if self.running:
1702 self.set_quit() 1927 self.set_quit()
1703 self.running = None 1928 self.running = None
1704 self.write('{0}{1:d}\n'.format(DebugProtocol.ResponseExit, status)) 1929 ## self.write('{0}{1:d}\n'.format(DebugProtocol.ResponseExit, status))
1930 self.__sendJsonCommand("ResponseExit", {
1931 "status": status,
1932 })
1705 1933
1706 # reset coding 1934 # reset coding
1707 self.__coding = self.defaultCoding 1935 self.__coding = self.defaultCoding
1708 1936
1709 def __dumpVariables(self, frmnr, scope, filter): 1937 def __dumpVariables(self, frmnr, scope, filter):
1738 elif f.f_globals is f.f_locals: 1966 elif f.f_globals is f.f_locals:
1739 scope = -1 1967 scope = -1
1740 else: 1968 else:
1741 dict = f.f_locals 1969 dict = f.f_locals
1742 1970
1743 varlist = [scope] 1971 varlist = []
1744 1972
1745 if scope != -1: 1973 if scope != -1:
1746 keylist = dict.keys() 1974 keylist = dict.keys()
1747 1975
1748 vlist = self.__formatVariablesList(keylist, dict, scope, filter) 1976 vlist = self.__formatVariablesList(keylist, dict, scope, filter)
1749 varlist.extend(vlist) 1977 varlist.extend(vlist)
1750 1978
1751 self.write('{0}{1}\n'.format( 1979 ## self.write('{0}{1}\n'.format(
1752 DebugProtocol.ResponseVariables, str(varlist))) 1980 ## DebugProtocol.ResponseVariables, str(varlist)))
1981 self.__sendJsonCommand("ResponseVariables", {
1982 "scope": scope,
1983 "variables": varlist,
1984 })
1753 1985
1754 def __dumpVariable(self, var, frmnr, scope, filter): 1986 def __dumpVariable(self, var, frmnr, scope, filter):
1755 """ 1987 """
1756 Private method to return the variables of a frame to the debug server. 1988 Private method to return the variables of a frame to the debug server.
1757 1989
1782 elif f.f_globals is f.f_locals: 2014 elif f.f_globals is f.f_locals:
1783 scope = -1 2015 scope = -1
1784 else: 2016 else:
1785 dict = f.f_locals 2017 dict = f.f_locals
1786 2018
1787 varlist = [scope, var] 2019 varlist = []
1788 2020
1789 if scope != -1: 2021 if scope != -1:
1790 # search the correct dictionary 2022 # search the correct dictionary
1791 i = 0 2023 i = 0
1792 rvar = var[:] 2024 rvar = var[:]
1805 while i < len(var): 2037 while i < len(var):
1806 if len(dict): 2038 if len(dict):
1807 udict = dict 2039 udict = dict
1808 ndict = {} 2040 ndict = {}
1809 # this has to be in line with VariablesViewer.indicators 2041 # this has to be in line with VariablesViewer.indicators
1810 if var[i][-2:] in ["[]", "()", "{}"]: # __IGNORE_WARNING__ 2042 if var[i][-2:] in ["[]", "()", "{}"]: # __IGNORE_WARNING__
1811 if i + 1 == len(var): 2043 if i + 1 == len(var):
1812 if var[i][:-2] == '...': 2044 if var[i][:-2] == '...':
1813 dictkeys = [var[i - 1]] 2045 dictkeys = [var[i - 1]]
1814 else: 2046 else:
1815 dictkeys = [var[i][:-2]] 2047 dictkeys = [var[i][:-2]]
2031 varlist.append( 2263 varlist.append(
2032 ('...', 'tuple', "{0:d}".format(len(obj)))) 2264 ('...', 'tuple', "{0:d}".format(len(obj))))
2033 except Exception: 2265 except Exception:
2034 pass 2266 pass
2035 2267
2036 self.write('{0}{1}\n'.format( 2268 ## self.write('{0}{1}\n'.format(
2037 DebugProtocol.ResponseVariable, str(varlist))) 2269 ## DebugProtocol.ResponseVariable, str(varlist)))
2270 self.__sendJsonCommand("ResponseVariable", {
2271 "scope": scope,
2272 "variable": var,
2273 "variables": varlist,
2274 })
2038 2275
2039 def __formatQtVariable(self, value, vtype): 2276 def __formatQtVariable(self, value, vtype):
2040 """ 2277 """
2041 Private method to produce a formatted output of a simple Qt4/Qt5 type. 2278 Private method to produce a formatted output of a simple Qt4/Qt5 type.
2042 2279
2328 self.__getCompletionList(text, localCompleter, completions) 2565 self.__getCompletionList(text, localCompleter, completions)
2329 except AttributeError: 2566 except AttributeError:
2330 pass 2567 pass
2331 self.__getCompletionList(text, self.complete, completions) 2568 self.__getCompletionList(text, self.complete, completions)
2332 2569
2333 self.write("{0}{1}||{2}\n".format(DebugProtocol.ResponseCompletion, 2570 ## self.write("{0}{1}||{2}\n".format(DebugProtocol.ResponseCompletion,
2334 str(list(completions)), text)) 2571 ## str(list(completions)), text))
2572 self.__sendJsonCommand("ResponseCompletion", {
2573 "completions": list(completions),
2574 "text": text,
2575 })
2335 2576
2336 def __getCompletionList(self, text, completer, completions): 2577 def __getCompletionList(self, text, completer, completions):
2337 """ 2578 """
2338 Private method to create a completions list. 2579 Private method to create a completions list.
2339 2580
2387 except IndexError: 2628 except IndexError:
2388 self.running = None 2629 self.running = None
2389 if self.running: 2630 if self.running:
2390 self.__setCoding(self.running) 2631 self.__setCoding(self.running)
2391 self.passive = True 2632 self.passive = True
2392 self.write("{0}{1}|{2:d}\n".format(DebugProtocol.PassiveStartup, 2633 self.sendPassiveStartup(self.running, exceptions)
2393 self.running, exceptions))
2394 self.__interact() 2634 self.__interact()
2395 2635
2396 # setup the debugger variables 2636 # setup the debugger variables
2397 self._fncache = {} 2637 self._fncache = {}
2398 self.dircache = [] 2638 self.dircache = []
2399 self.mainFrame = None 2639 self.mainFrame = None
2400 self.inRawMode = False 2640 ## self.inRawMode = False
2401 self.debugging = True 2641 self.debugging = True
2402 2642
2403 self.attachThread(mainThread=True) 2643 self.attachThread(mainThread=True)
2404 self.mainThread.tracePython = tracePython 2644 self.mainThread.tracePython = tracePython
2405 2645
2448 else: 2688 else:
2449 os.chdir(wd) 2689 os.chdir(wd)
2450 self.running = sys.argv[0] 2690 self.running = sys.argv[0]
2451 self.__setCoding(self.running) 2691 self.__setCoding(self.running)
2452 self.mainFrame = None 2692 self.mainFrame = None
2453 self.inRawMode = False 2693 ## self.inRawMode = False
2454 self.debugging = True 2694 self.debugging = True
2455 2695
2456 self.passive = True 2696 self.passive = True
2457 self.write("{0}{1}|{2:d}\n".format( 2697 self.sendPassiveStartup(self.running, exceptions)
2458 DebugProtocol.PassiveStartup, self.running, exceptions)) 2698 ## self.write("{0}{1}|{2:d}\n".format(
2699 ## DebugProtocol.PassiveStartup, self.running, exceptions))
2459 self.__interact() 2700 self.__interact()
2460 2701
2461 self.attachThread(mainThread=True) 2702 self.attachThread(mainThread=True)
2462 self.mainThread.tracePython = tracePython 2703 self.mainThread.tracePython = tracePython
2463 2704

eric ide

mercurial