def test_update_constant_with_custom_code(self): SAMPLE_CODE1 = """ class B(object): CONSTANT = 1 def foo(self): return self.CONSTANT """ SAMPLE_CODE2 = """ class B(object): CONSTANT = 2 def __xreload_old_new__(cls, name, old, new): if name == 'CONSTANT': cls.CONSTANT = new __xreload_old_new__ = classmethod(__xreload_old_new__) def foo(self): return self.CONSTANT """ self.make_mod(sample=SAMPLE_CODE1) import x foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual(foo(), 2) #Actually updated it now!
def test_reload_custom_code_after_changes(self): SAMPLE_CODE1 = """ CONSTANT = 1 class B(object): def foo(self): return CONSTANT """ SAMPLE_CODE2 = """ CONSTANT = 1 def __xreload_after_reload_update__(namespace): namespace['CONSTANT'] = 2 class B(object): def foo(self): return CONSTANT """ self.make_mod(sample=SAMPLE_CODE1) import x foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual(foo(), 2) #Actually updated it now!
def test_reload_custom_code_after_changes_in_class(self): SAMPLE_CODE1 = """ class B(object): CONSTANT = 1 def foo(self): return self.CONSTANT """ SAMPLE_CODE2 = """ class B(object): CONSTANT = 1 @classmethod def __xreload_after_reload_update__(cls): cls.CONSTANT = 2 def foo(self): return self.CONSTANT """ self.make_mod(sample=SAMPLE_CODE1) import x foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual(foo(), 2) #Actually updated it now!
def test_update_constant_with_custom_code(self): SAMPLE_CODE1 = """ CONSTANT = 1 class B(object): def foo(self): return CONSTANT """ SAMPLE_CODE2 = """ CONSTANT = 2 def __xreload_old_new__(namespace, name, old, new): if name == 'CONSTANT': namespace[name] = new class B(object): def foo(self): return CONSTANT """ self.make_mod(sample=SAMPLE_CODE1) import x foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual(foo(), 2) #Actually updated it now!
def test_parent_function(self): SAMPLE_CODE1 = """ class B(object): def foo(self): return 0 class C(B): def call(self): return self.foo() """ # Creating a new class and using it from old class SAMPLE_CODE2 = """ class B(object): def foo(self): return 0 def bar(self): return 'bar' class C(B): def call(self): return self.bar() """ self.make_mod(sample=SAMPLE_CODE1) import x call = x.C().call self.assertEqual(call(), 0) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual(call(), 'bar')
def test_update_with_slots(self): SAMPLE_CODE1 = """ class B(object): __slots__ = ['bar'] """ SAMPLE_CODE2 = """ class B(object): __slots__ = ['bar', 'foo'] def m1(self): self.bar = 10 return 1 """ self.make_mod(sample=SAMPLE_CODE1) import x B = x.B self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) b = B() self.assertEqual(1, b.m1()) self.assertEqual(10, b.bar) self.assertRaises(Exception, setattr, b, 'foo', 20) #__slots__ can't be updated
def testMet1(self): self.make_mod() import x #@UnresolvedImport -- this is the module we created at runtime. from x import C as Foo #@UnresolvedImport C = x.C Cfoo = C.foo Cbar = C.bar Cstomp = C.stomp b = C() bfoo = b.foo in_list = [C] self.assertEqual(b.foo(), 42) self.assertEqual(bfoo(), 42) self.assertEqual(Cfoo(b), 42) self.assertEqual(Cbar(), (42, 42)) self.assertEqual(Cstomp(), (42, 42, 42)) self.assertEqual(in_list[0].attr, 42) self.assertEqual(Foo.attr, 42) self.make_mod(repl="42", subst="24") xreload(x) self.assertEqual(b.foo(), 24) self.assertEqual(bfoo(), 24) self.assertEqual(Cfoo(b), 24) self.assertEqual(Cbar(), (24, 24)) self.assertEqual(Cstomp(), (24, 24, 24)) self.assertEqual(in_list[0].attr, 24) self.assertEqual(Foo.attr, 24)
def doIt(self, dbg): self.lock.acquire() try: if self.executed: return self.executed = True finally: self.lock.release() module_name = self.module_name if not DictContains(sys.modules, module_name): if '.' in module_name: new_module_name = module_name.split('.')[-1] if DictContains(sys.modules, new_module_name): module_name = new_module_name if not DictContains(sys.modules, module_name): sys.stderr.write('pydev debugger: Unable to find module to reload: "' + module_name + '".\n') sys.stderr.write('pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n') else: sys.stderr.write('pydev debugger: Start reloading module: "' + module_name + '" ... ') import pydevd_reload pydevd_reload.xreload(sys.modules[module_name]) sys.stderr.write('reload finished\n')
def doIt(self, dbg): self.lock.acquire() try: if self.executed: return self.executed = True finally: self.lock.release() module_name = self.module_name if not DictContains(sys.modules, module_name): if '.' in module_name: new_module_name = module_name.split('.')[-1] if DictContains(sys.modules, new_module_name): module_name = new_module_name if not DictContains(sys.modules, module_name): sys.stderr.write( 'pydev debugger: Unable to find module to reload: "' + module_name + '".\n') sys.stderr.write( 'pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n' ) else: sys.stderr.write('pydev debugger: Start reloading module: "' + module_name + '" ... ') import pydevd_reload pydevd_reload.xreload(sys.modules[module_name]) sys.stderr.write('reload finished\n')
def run(self): while 1: sleep(1) try: oldasync = self.ctx["m"].async.func_code pydevd_reload.xreload(self.ctx["m"]) if self.ctx["m"].async.func_code != oldasync: self.ctx["m"].async() except Exception, e: print e
def test_pydevd_reload2(self): self.make_mod() import x c = x.C() cfoo = c.foo self.assertEqual(0, c.foo()) self.assertEqual(0, cfoo()) self.make_mod(repl="0", subst='1') pydevd_reload.xreload(x) self.assertEqual(1, c.foo()) self.assertEqual(1, cfoo())
def test_pydevd_reload(self): self.make_mod() import x C = x.C COut = C Cfoo = C.foo Cbar = C.bar Cstomp = C.stomp def check2(expected): C = x.C Cfoo = C.foo Cbar = C.bar Cstomp = C.stomp b = C() bfoo = b.foo self.assertEqual(expected, b.foo()) self.assertEqual(expected, bfoo()) self.assertEqual(expected, Cfoo(b)) def check(expected): b = COut() bfoo = b.foo self.assertEqual(expected, b.foo()) self.assertEqual(expected, bfoo()) self.assertEqual(expected, Cfoo(b)) self.assertEqual((expected, expected), Cbar()) self.assertEqual((expected, expected, expected), Cstomp()) check2(expected) check(0) # modify mod and reload count = 0 while count < 1: count += 1 self.make_mod(repl="0", subst=str(count)) pydevd_reload.xreload(x) check(count)
def test_create_class2(self): SAMPLE_CODE1 = """ class C(object): def foo(self): return 0 """ # Creating a new class and using it from old class SAMPLE_CODE2 = """ class B(object): pass class C(object): def foo(self): return B """ self.make_mod(sample=SAMPLE_CODE1) import x foo = x.C().foo self.assertEqual(foo(), 0) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual(foo().__name__, 'B')
def test_update_constant(self): SAMPLE_CODE1 = """ CONSTANT = 1 class B(object): def foo(self): return CONSTANT """ SAMPLE_CODE2 = """ CONSTANT = 2 class B(object): def foo(self): return CONSTANT """ self.make_mod(sample=SAMPLE_CODE1) import x foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual(foo(), 1) #Just making it explicit we don't reload constants.
def test_update_constant(self): SAMPLE_CODE1 = """ CONSTANT = 1 class B(object): def foo(self): return CONSTANT """ SAMPLE_CODE2 = """ CONSTANT = 2 class B(object): def foo(self): return CONSTANT """ self.make_mod(sample=SAMPLE_CODE1) import x foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) self.assertEqual( foo(), 1) #Just making it explicit we don't reload constants.
def processNetCommand(self, cmd_id, seq, text): '''Processes a command received from the Java side @param cmd_id: the id of the command @param seq: the sequence of the command @param text: the text received in the command @note: this method is run as a big switch... after doing some tests, it's not clear whether changing it for a dict id --> function call will have better performance result. A simple test with xrange(10000000) showed that the gains from having a fast access to what should be executed are lost because of the function call in a way that if we had 10 elements in the switch the if..elif are better -- but growing the number of choices makes the solution with the dispatch look better -- so, if this gets more than 20-25 choices at some time, it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before probably will give better performance). ''' self.acquire() try: try: cmd = None if cmd_id == CMD_RUN: self.readyToRun = True elif cmd_id == CMD_VERSION: # response is version number cmd = self.cmdFactory.makeVersionMessage(seq) elif cmd_id == CMD_LIST_THREADS: # response is a list of threads cmd = self.cmdFactory.makeListThreadsMessage(seq) elif cmd_id == CMD_THREAD_KILL: int_cmd = InternalTerminateThread(text) self.postInternalCommand(int_cmd, text) elif cmd_id == CMD_THREAD_SUSPEND: t = PydevdFindThreadById(text) if t: additionalInfo = None try: additionalInfo = t.additionalInfo except AttributeError: pass #that's ok, no info currently set if additionalInfo is not None: for frame in additionalInfo.IterFrames(): frame.f_trace = self.trace_dispatch SetTraceForParents(frame, self.trace_dispatch) del frame self.setSuspend(t, CMD_THREAD_SUSPEND) elif cmd_id == CMD_THREAD_RUN: t = PydevdFindThreadById(text) if t: t.additionalInfo.pydev_step_cmd = None t.additionalInfo.pydev_step_stop = None t.additionalInfo.pydev_state = STATE_RUN elif cmd_id == CMD_STEP_INTO or cmd_id == CMD_STEP_OVER or cmd_id == CMD_STEP_RETURN: #we received some command to make a single step t = PydevdFindThreadById(text) if t: t.additionalInfo.pydev_step_cmd = cmd_id t.additionalInfo.pydev_state = STATE_RUN elif cmd_id == CMD_RUN_TO_LINE: #we received some command to make a single step thread_id, line, func_name = text.split('\t', 2) t = PydevdFindThreadById(thread_id) if t: t.additionalInfo.pydev_step_cmd = cmd_id t.additionalInfo.pydev_next_line = int(line) t.additionalInfo.pydev_func_name = func_name t.additionalInfo.pydev_state = STATE_RUN elif cmd_id == CMD_RELOAD_CODE: #we received some command to make a reload of a module module_name = text.strip() from pydevd_reload import xreload if not DictContains(sys.modules, module_name): if '.' in module_name: new_module_name = module_name.split('.')[-1] if DictContains(sys.modules, new_module_name): module_name = new_module_name if not DictContains(sys.modules, module_name): sys.stderr.write('pydev debugger: Unable to find module to reload: "'+module_name+'".\n') sys.stderr.write('pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n') else: sys.stderr.write('pydev debugger: Reloading: '+module_name+'\n') xreload(sys.modules[module_name]) elif cmd_id == CMD_CHANGE_VARIABLE: #the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change try: thread_id, frame_id, scope, attr_and_value = text.split('\t', 3) tab_index = attr_and_value.rindex('\t') attr = attr_and_value[0:tab_index].replace('\t', '.') value = attr_and_value[tab_index + 1:] int_cmd = InternalChangeVariable(seq, thread_id, frame_id, scope, attr, value) self.postInternalCommand(int_cmd, thread_id) except: traceback.print_exc() elif cmd_id == CMD_GET_VARIABLE: #we received some command to get a variable #the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes* try: thread_id, frame_id, scopeattrs = text.split('\t', 2) if scopeattrs.find('\t') != -1: # there are attributes beyond scope scope, attrs = scopeattrs.split('\t', 1) else: scope, attrs = (scopeattrs, None) int_cmd = InternalGetVariable(seq, thread_id, frame_id, scope, attrs) self.postInternalCommand(int_cmd, thread_id) except: traceback.print_exc() elif cmd_id == CMD_GET_COMPLETIONS: #we received some command to get a variable #the text is: thread_id\tframe_id\tactivation token try: thread_id, frame_id, scope, act_tok = text.split('\t', 3) int_cmd = InternalGetCompletions(seq, thread_id, frame_id, act_tok) self.postInternalCommand(int_cmd, thread_id) except: traceback.print_exc() elif cmd_id == CMD_GET_FRAME: thread_id, frame_id, scope = text.split('\t', 2) int_cmd = InternalGetFrame(seq, thread_id, frame_id) self.postInternalCommand(int_cmd, thread_id) elif cmd_id == CMD_SET_BREAK: #func name: 'None': match anything. Empty: match global, specified: only method context. #command to add some breakpoint. # text is file\tline. Add to breakpoints dictionary file, line, condition = text.split('\t', 2) if condition.startswith('**FUNC**'): func_name, condition = condition.split('\t', 1) #We must restore new lines and tabs as done in #AbstractDebugTarget.breakpointAdded condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').\ replace("@_@TAB_CHAR@_@", '\t').strip() func_name = func_name[8:] else: func_name = 'None' #Match anything if not specified. file = NormFileToServer(file) if not os.path.exists(file): sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\ ' to file that does not exist: %s (will have no effect)\n' % (file,)) line = int(line) if DEBUG_TRACE_BREAKPOINTS > 0: sys.stderr.write('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name)) if DictContains(self.breakpoints, file): breakDict = self.breakpoints[file] else: breakDict = {} if len(condition) <= 0 or condition == None or condition == "None": breakDict[line] = (True, None, func_name) else: breakDict[line] = (True, condition, func_name) self.breakpoints[file] = breakDict #and enable the tracing for existing threads (because there may be frames being executed that #are currently untraced). threads = threadingEnumerate() for t in threads: if not t.getName().startswith('pydevd.'): #TODO: optimize so that we only actually add that tracing if it's in #the new breakpoint context. additionalInfo = None try: additionalInfo = t.additionalInfo except AttributeError: pass #that's ok, no info currently set if additionalInfo is not None: for frame in additionalInfo.IterFrames(): frame.f_trace = self.trace_dispatch SetTraceForParents(frame, self.trace_dispatch) del frame elif cmd_id == CMD_REMOVE_BREAK: #command to remove some breakpoint #text is file\tline. Remove from breakpoints dictionary file, line = text.split('\t', 1) file = NormFileToServer(file) try: line = int(line) except ValueError: pass else: try: del self.breakpoints[file][line] #remove the breakpoint in that line if DEBUG_TRACE_BREAKPOINTS > 0: sys.stderr.write('Removed breakpoint:%s\n' % (file,)) except KeyError: #ok, it's not there... if DEBUG_TRACE_BREAKPOINTS > 0: #Sometimes, when adding a breakpoint, it adds a remove command before (don't really know why) sys.stderr.write("breakpoint not found: %s - %s\n" % (file, line)) elif cmd_id == CMD_EVALUATE_EXPRESSION or cmd_id == CMD_EXEC_EXPRESSION: #command to evaluate the given expression #text is: thread\tstackframe\tLOCAL\texpression thread_id, frame_id, scope, expression = text.split('\t', 3) int_cmd = InternalEvaluateExpression(seq, thread_id, frame_id, expression, cmd_id == CMD_EXEC_EXPRESSION) self.postInternalCommand(int_cmd, thread_id) else: #I have no idea what this is all about cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(cmd_id)) if cmd is not None: self.writer.addCommand(cmd) del cmd except Exception: traceback.print_exc() cmd = self.cmdFactory.makeErrorMessage(seq, "Unexpected exception in processNetCommand.\nInitial params: %s" % ((cmd_id, seq, text),)) self.writer.addCommand(cmd) finally: self.release()
def processNetCommand(self, cmd_id, seq, text): '''Processes a command received from the Java side @param cmd_id: the id of the command @param seq: the sequence of the command @param text: the text received in the command @note: this method is run as a big switch... after doing some tests, it's not clear whether changing it for a dict id --> function call will have better performance result. A simple test with xrange(10000000) showed that the gains from having a fast access to what should be executed are lost because of the function call in a way that if we had 10 elements in the switch the if..elif are better -- but growing the number of choices makes the solution with the dispatch look better -- so, if this gets more than 20-25 choices at some time, it may be worth refactoring it (actually, reordering the ifs so that the ones used mostly come before probably will give better performance). ''' self.acquire() try: try: cmd = None if cmd_id == CMD_RUN: self.readyToRun = True elif cmd_id == CMD_VERSION: # response is version number cmd = self.cmdFactory.makeVersionMessage(seq) elif cmd_id == CMD_LIST_THREADS: # response is a list of threads cmd = self.cmdFactory.makeListThreadsMessage(seq) elif cmd_id == CMD_THREAD_KILL: int_cmd = InternalTerminateThread(text) self.postInternalCommand(int_cmd, text) elif cmd_id == CMD_THREAD_SUSPEND: t = PydevdFindThreadById(text) if t: additionalInfo = None try: additionalInfo = t.additionalInfo except AttributeError: pass #that's ok, no info currently set if additionalInfo is not None: for frame in additionalInfo.IterFrames(): frame.f_trace = self.trace_dispatch SetTraceForParents(frame, self.trace_dispatch) del frame self.setSuspend(t, CMD_THREAD_SUSPEND) elif cmd_id == CMD_THREAD_RUN: t = PydevdFindThreadById(text) if t: t.additionalInfo.pydev_step_cmd = None t.additionalInfo.pydev_step_stop = None t.additionalInfo.pydev_state = STATE_RUN elif cmd_id == CMD_STEP_INTO or cmd_id == CMD_STEP_OVER or cmd_id == CMD_STEP_RETURN: #we received some command to make a single step t = PydevdFindThreadById(text) if t: t.additionalInfo.pydev_step_cmd = cmd_id t.additionalInfo.pydev_state = STATE_RUN elif cmd_id == CMD_RUN_TO_LINE or cmd_id == CMD_SET_NEXT_STATEMENT: #we received some command to make a single step thread_id, line, func_name = text.split('\t', 2) t = PydevdFindThreadById(thread_id) if t: t.additionalInfo.pydev_step_cmd = cmd_id t.additionalInfo.pydev_next_line = int(line) t.additionalInfo.pydev_func_name = func_name t.additionalInfo.pydev_state = STATE_RUN elif cmd_id == CMD_RELOAD_CODE: #we received some command to make a reload of a module module_name = text.strip() from pydevd_reload import xreload if not DictContains(sys.modules, module_name): if '.' in module_name: new_module_name = module_name.split('.')[-1] if DictContains(sys.modules, new_module_name): module_name = new_module_name if not DictContains(sys.modules, module_name): sys.stderr.write( 'pydev debugger: Unable to find module to reload: "' + module_name + '".\n') sys.stderr.write( 'pydev debugger: This usually means you are trying to reload the __main__ module (which cannot be reloaded).\n' ) else: sys.stderr.write('pydev debugger: Reloading: ' + module_name + '\n') xreload(sys.modules[module_name]) elif cmd_id == CMD_CHANGE_VARIABLE: #the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change try: thread_id, frame_id, scope, attr_and_value = text.split( '\t', 3) tab_index = attr_and_value.rindex('\t') attr = attr_and_value[0:tab_index].replace('\t', '.') value = attr_and_value[tab_index + 1:] int_cmd = InternalChangeVariable( seq, thread_id, frame_id, scope, attr, value) self.postInternalCommand(int_cmd, thread_id) except: traceback.print_exc() elif cmd_id == CMD_GET_VARIABLE: #we received some command to get a variable #the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes* try: thread_id, frame_id, scopeattrs = text.split('\t', 2) if scopeattrs.find( '\t' ) != -1: # there are attributes beyond scope scope, attrs = scopeattrs.split('\t', 1) else: scope, attrs = (scopeattrs, None) int_cmd = InternalGetVariable(seq, thread_id, frame_id, scope, attrs) self.postInternalCommand(int_cmd, thread_id) except: traceback.print_exc() elif cmd_id == CMD_GET_COMPLETIONS: #we received some command to get a variable #the text is: thread_id\tframe_id\tactivation token try: thread_id, frame_id, scope, act_tok = text.split( '\t', 3) int_cmd = InternalGetCompletions( seq, thread_id, frame_id, act_tok) self.postInternalCommand(int_cmd, thread_id) except: traceback.print_exc() elif cmd_id == CMD_GET_FRAME: thread_id, frame_id, scope = text.split('\t', 2) int_cmd = InternalGetFrame(seq, thread_id, frame_id) self.postInternalCommand(int_cmd, thread_id) elif cmd_id == CMD_SET_BREAK: #func name: 'None': match anything. Empty: match global, specified: only method context. #command to add some breakpoint. # text is file\tline. Add to breakpoints dictionary file, line, condition = text.split('\t', 2) if condition.startswith('**FUNC**'): func_name, condition = condition.split('\t', 1) #We must restore new lines and tabs as done in #AbstractDebugTarget.breakpointAdded condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').\ replace("@_@TAB_CHAR@_@", '\t').strip() func_name = func_name[8:] else: func_name = 'None' #Match anything if not specified. file = NormFileToServer(file) if not os.path.exists(file): sys.stderr.write('pydev debugger: warning: trying to add breakpoint'\ ' to file that does not exist: %s (will have no effect)\n' % (file,)) line = int(line) if DEBUG_TRACE_BREAKPOINTS > 0: sys.stderr.write( 'Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name)) if DictContains(self.breakpoints, file): breakDict = self.breakpoints[file] else: breakDict = {} if len(condition ) <= 0 or condition == None or condition == "None": breakDict[line] = (True, None, func_name) else: breakDict[line] = (True, condition, func_name) self.breakpoints[file] = breakDict #and enable the tracing for existing threads (because there may be frames being executed that #are currently untraced). threads = threadingEnumerate() for t in threads: if not t.getName().startswith('pydevd.'): #TODO: optimize so that we only actually add that tracing if it's in #the new breakpoint context. additionalInfo = None try: additionalInfo = t.additionalInfo except AttributeError: pass #that's ok, no info currently set if additionalInfo is not None: for frame in additionalInfo.IterFrames(): frame.f_trace = self.trace_dispatch SetTraceForParents(frame, self.trace_dispatch) del frame elif cmd_id == CMD_REMOVE_BREAK: #command to remove some breakpoint #text is file\tline. Remove from breakpoints dictionary file, line = text.split('\t', 1) file = NormFileToServer(file) try: line = int(line) except ValueError: pass else: try: del self.breakpoints[file][ line] #remove the breakpoint in that line if DEBUG_TRACE_BREAKPOINTS > 0: sys.stderr.write('Removed breakpoint:%s\n' % (file, )) except KeyError: #ok, it's not there... if DEBUG_TRACE_BREAKPOINTS > 0: #Sometimes, when adding a breakpoint, it adds a remove command before (don't really know why) sys.stderr.write( "breakpoint not found: %s - %s\n" % (file, line)) elif cmd_id == CMD_EVALUATE_EXPRESSION or cmd_id == CMD_EXEC_EXPRESSION: #command to evaluate the given expression #text is: thread\tstackframe\tLOCAL\texpression thread_id, frame_id, scope, expression = text.split( '\t', 3) int_cmd = InternalEvaluateExpression( seq, thread_id, frame_id, expression, cmd_id == CMD_EXEC_EXPRESSION) self.postInternalCommand(int_cmd, thread_id) else: #I have no idea what this is all about cmd = self.cmdFactory.makeErrorMessage( seq, "unexpected command " + str(cmd_id)) if cmd is not None: self.writer.addCommand(cmd) del cmd except Exception: traceback.print_exc() cmd = self.cmdFactory.makeErrorMessage( seq, "Unexpected exception in processNetCommand.\nInitial params: %s" % ((cmd_id, seq, text), )) self.writer.addCommand(cmd) finally: self.release()
""" 使用说明 实时修改module,调用cluster_controller runscript reload 可以在不重启服务器的情况下reload module模块 """ import pydevd_reload as r module = "" r.xreload(module)