DebugClients/Python3/DebugClientBase.py

branch
jsonrpc
changeset 5119
80bd41498eef
parent 5115
ed2f37c1f6b6
child 5120
c5189d404cc7
equal deleted inserted replaced
5118:4a79a6153485 5119:80bd41498eef
397 # Remove any newline. 397 # Remove any newline.
398 if line[-1] == '\n': 398 if line[-1] == '\n':
399 line = line[:-1] 399 line = line[:-1]
400 400
401 ## printerr(line) ##debug 401 ## printerr(line) ##debug
402
403 if "jsonrpc" in line:
404 return self.__handleJsonCommand(line)
402 405
403 eoc = line.find('<') 406 eoc = line.find('<')
404 407
405 if eoc >= 0 and line[0] == '>': 408 if eoc >= 0 and line[0] == '>':
406 # Get the command part and any argument. 409 # Get the command part and any argument.
475 else: 478 else:
476 self.__newCallTraceEnabled = callTraceEnabled 479 self.__newCallTraceEnabled = callTraceEnabled
477 # remember for later 480 # remember for later
478 return 481 return
479 482
480 if cmd == DebugProtocol.RequestEnv: 483 ## if cmd == DebugProtocol.RequestEnv:
481 env = eval(arg.replace("u'", "'")) 484 ## env = eval(arg.replace("u'", "'"))
482 for key, value in env.items(): 485 ## for key, value in env.items():
483 if key.endswith("+"): 486 ## if key.endswith("+"):
484 if key[:-1] in os.environ: 487 ## if key[:-1] in os.environ:
485 os.environ[key[:-1]] += value 488 ## os.environ[key[:-1]] += value
486 else: 489 ## else:
487 os.environ[key[:-1]] = value 490 ## os.environ[key[:-1]] = value
488 else: 491 ## else:
489 os.environ[key] = value 492 ## os.environ[key] = value
490 return 493 ## return
491 494 ##
492 if cmd == DebugProtocol.RequestLoad: 495 ## if cmd == DebugProtocol.RequestLoad:
493 self._fncache = {} 496 ## self._fncache = {}
494 self.dircache = [] 497 ## self.dircache = []
495 sys.argv = [] 498 ## sys.argv = []
496 wd, fn, args, tracePython = arg.split('|') 499 ## wd, fn, args, tracePython = arg.split('|')
497 self.__setCoding(fn) 500 ## self.__setCoding(fn)
498 sys.argv.append(fn) 501 ## sys.argv.append(fn)
499 sys.argv.extend(eval(args)) 502 ## sys.argv.extend(eval(args))
500 sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) 503 ## sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
501 if wd == '': 504 ## if wd == '':
502 os.chdir(sys.path[1]) 505 ## os.chdir(sys.path[1])
503 else: 506 ## else:
504 os.chdir(wd) 507 ## os.chdir(wd)
505 tracePython = int(tracePython) 508 ## tracePython = int(tracePython)
506 self.running = sys.argv[0] 509 ## self.running = sys.argv[0]
507 self.mainFrame = None 510 ## self.mainFrame = None
508 self.inRawMode = False 511 ## self.inRawMode = False
509 self.debugging = True 512 ## self.debugging = True
510 513 ##
511 self.threads.clear() 514 ## self.threads.clear()
512 self.attachThread(mainThread=True) 515 ## self.attachThread(mainThread=True)
513 516 ##
514 # set the system exception handling function to ensure, that 517 ## # set the system exception handling function to ensure, that
515 # we report on all unhandled exceptions 518 ## # we report on all unhandled exceptions
516 sys.excepthook = self.__unhandled_exception 519 ## sys.excepthook = self.__unhandled_exception
517 self.__interceptSignals() 520 ## self.__interceptSignals()
518 521 ##
519 # clear all old breakpoints, they'll get set after we have 522 ## # clear all old breakpoints, they'll get set after we have
520 # started 523 ## # started
521 self.mainThread.clear_all_breaks() 524 ## self.mainThread.clear_all_breaks()
522 525 ##
523 self.mainThread.tracePython = tracePython 526 ## self.mainThread.tracePython = tracePython
524 527 ##
525 # This will eventually enter a local event loop. 528 ## # This will eventually enter a local event loop.
526 # Note the use of backquotes to cause a repr of self.running. 529 ## self.debugMod.__dict__['__file__'] = self.running
527 # The need for this is on Windows os where backslash is the 530 ## sys.modules['__main__'] = self.debugMod
528 # path separator. They will get inadvertantly stripped away 531 ## code = self.__compileFileSource(self.running)
529 # during the eval causing IOErrors, if self.running is passed 532 ## if code:
530 # as a normal str. 533 ## self.callTraceEnabled = self.__newCallTraceEnabled
531 self.debugMod.__dict__['__file__'] = self.running 534 ## res = self.mainThread.run(code, self.debugMod.__dict__)
532 sys.modules['__main__'] = self.debugMod 535 ## self.progTerminated(res)
533 code = self.__compileFileSource(self.running) 536 ## return
534 if code: 537 ##
535 self.callTraceEnabled = self.__newCallTraceEnabled
536 res = self.mainThread.run(code, self.debugMod.__dict__)
537 self.progTerminated(res)
538 return
539
540 if cmd == DebugProtocol.RequestRun: 538 if cmd == DebugProtocol.RequestRun:
541 sys.argv = [] 539 sys.argv = []
542 wd, fn, args = arg.split('|') 540 wd, fn, args = arg.split('|')
543 self.__setCoding(fn) 541 self.__setCoding(fn)
544 sys.argv.append(fn) 542 sys.argv.append(fn)
834 832
835 self.write(DebugProtocol.ResponseException + '\n') 833 self.write(DebugProtocol.ResponseException + '\n')
836 834
837 return 835 return
838 836
839 if cmd == DebugProtocol.RequestBanner: 837 ## if cmd == DebugProtocol.RequestBanner:
840 self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner, 838 ## self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner,
841 str(("Python {0}".format(sys.version), 839 ## str(("Python {0}".format(sys.version),
842 socket.gethostname(), self.variant)))) 840 ## socket.gethostname(), self.variant))))
843 return 841 ## return
844 842 ##
845 if cmd == DebugProtocol.RequestCapabilities: 843 ## if cmd == DebugProtocol.RequestCapabilities:
846 self.write('{0}{1:d}, "Python3"\n'.format( 844 ## self.write('{0}{1:d}, "Python3"\n'.format(
847 DebugProtocol.ResponseCapabilities, 845 ## DebugProtocol.ResponseCapabilities,
848 self.__clientCapabilities())) 846 ## self.__clientCapabilities()))
849 return 847 ## return
850 848 ##
851 if cmd == DebugProtocol.RequestCompletion: 849 if cmd == DebugProtocol.RequestCompletion:
852 self.__completionList(arg.replace("u'", "'")) 850 self.__completionList(arg.replace("u'", "'"))
853 return 851 return
854 852
855 if cmd == DebugProtocol.RequestSetFilter: 853 if cmd == DebugProtocol.RequestSetFilter:
1019 finally: 1017 finally:
1020 tblist = exc_tb = None 1018 tblist = exc_tb = None
1021 1019
1022 for l in list: 1020 for l in list:
1023 self.write(l) 1021 self.write(l)
1024 1022
1023 def __handleJsonCommand(self, jsonStr):
1024 """
1025 Private method to handle a command serialized as a JSON string.
1026 """
1027 import json
1028
1029 try:
1030 commandDict = json.loads(jsonStr.strip())
1031 except json.JSONDecodeError as err:
1032 printerr(str(err))
1033 return
1034
1035 method = commandDict["method"]
1036 params = commandDict["params"]
1037
1038 if method == "RequestCapabilities":
1039 self.__sendJsonCommand("ResponseCapabilities", {
1040 "capabilities": self.__clientCapabilities(),
1041 "clientType": "Python3"
1042 })
1043 return
1044
1045 if method == "RequestBanner":
1046 self.__sendJsonCommand("ResponseBanner", {
1047 "version": "Python {0}".format(sys.version),
1048 "platform": socket.gethostname(),
1049 "dbgclient": self.variant,
1050 })
1051 return
1052
1053 if method == "RequestEnvironment":
1054 for key, value in params["environment"].items():
1055 if key.endswith("+"):
1056 if key[:-1] in os.environ:
1057 os.environ[key[:-1]] += value
1058 else:
1059 os.environ[key[:-1]] = value
1060 else:
1061 os.environ[key] = value
1062 return
1063
1064 if method == "RequestLoad":
1065 printerr(method)
1066 self._fncache = {}
1067 self.dircache = []
1068 sys.argv = []
1069 self.__setCoding(params["filename"])
1070 sys.argv.append(params["filename"])
1071 sys.argv.extend(params["argv"])
1072 sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
1073 if params["workdir"] == '':
1074 os.chdir(sys.path[1])
1075 else:
1076 os.chdir(params["workdir"])
1077 self.running = sys.argv[0]
1078 self.mainFrame = None
1079 self.inRawMode = False
1080 self.debugging = True
1081
1082 self.fork_auto = params["autofork"]
1083 self.fork_child = params["forkChild"]
1084
1085 self.threads.clear()
1086 self.attachThread(mainThread=True)
1087
1088 # set the system exception handling function to ensure, that
1089 # we report on all unhandled exceptions
1090 sys.excepthook = self.__unhandled_exception
1091 self.__interceptSignals()
1092
1093 # clear all old breakpoints, they'll get set after we have
1094 # started
1095 self.mainThread.clear_all_breaks()
1096
1097 self.mainThread.tracePython = params["traceInterpreter"]
1098
1099 # This will eventually enter a local event loop.
1100 self.debugMod.__dict__['__file__'] = self.running
1101 sys.modules['__main__'] = self.debugMod
1102 code = self.__compileFileSource(self.running)
1103 if code:
1104 self.callTraceEnabled = self.__newCallTraceEnabled
1105 res = self.mainThread.run(code, self.debugMod.__dict__)
1106 self.progTerminated(res)
1107 return
1108
1109
1110 def __sendJsonCommand(self, command, params):
1111 """
1112 Private method to send a single command to the client.
1113
1114 @param command command name to be sent
1115 @type str
1116 @param params dictionary of named parameters for the command
1117 @type dict
1118 """
1119 import json
1120
1121 commandDict = {
1122 "jsonrpc": "2.0",
1123 "method": command,
1124 "params": params,
1125 }
1126 cmd = json.dumps(commandDict) + '\n'
1127 self.write(cmd)
1128
1025 def __clientCapabilities(self): 1129 def __clientCapabilities(self):
1026 """ 1130 """
1027 Private method to determine the clients capabilities. 1131 Private method to determine the clients capabilities.
1028 1132
1029 @return client capabilities (integer) 1133 @return client capabilities (integer)

eric ide

mercurial