def changeAttrExpression(thread_id, frame_id, attr, expression): '''Changes some attribute in a given frame. ''' frame = findFrame(thread_id, frame_id) if frame is None: return try: expression = expression.replace('@LINE@', '\n') # if isinstance(frame, DjangoTemplateFrame): # TODO: implemente for plugins # result = eval(expression, frame.f_globals, frame.f_locals) # frame.changeVariable(attr, result) # return if attr[:7] == "Globals": attr = attr[8:] if attr in frame.f_globals: frame.f_globals[attr] = eval(expression, frame.f_globals, frame.f_locals) return frame.f_globals[attr] else: if pydevd_save_locals.is_save_locals_available(): frame.f_locals[attr] = eval(expression, frame.f_globals, frame.f_locals) pydevd_save_locals.save_locals(frame) return frame.f_locals[attr] #default way (only works for changing it in the topmost frame) result = eval(expression, frame.f_globals, frame.f_locals) Exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals) return result except Exception: traceback.print_exc()
def changeAttrExpression(thread_id, frame_id, attr, expression): '''Changes some attribute in a given frame. @note: it will not (currently) work if we're not in the topmost frame (that's a python deficiency -- and it appears that there is no way of making it currently work -- will probably need some change to the python internals) ''' frame = findFrame(thread_id, frame_id) if frame is None: return try: expression = expression.replace('@LINE@', '\n') if attr[:7] == "Globals": attr = attr[8:] if attr in frame.f_globals: frame.f_globals[attr] = eval(expression, frame.f_globals, frame.f_locals) else: if pydevd_save_locals.is_save_locals_available(): frame.f_locals[attr] = eval(expression, frame.f_globals, frame.f_locals) pydevd_save_locals.save_locals(frame) return #default way (only works for changing it in the topmost frame) Exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals) except Exception: traceback.print_exc()
def changeAttrExpression(thread_id, frame_id, attr, expression, dbg): '''Changes some attribute in a given frame. ''' frame = findFrame(thread_id, frame_id) if frame is None: return try: expression = expression.replace('@LINE@', '\n') if dbg.plugin: result = dbg.plugin.change_variable(frame, attr, expression) if result: return result if attr[:7] == "Globals": attr = attr[8:] if attr in frame.f_globals: frame.f_globals[attr] = eval(expression, frame.f_globals, frame.f_locals) return frame.f_globals[attr] else: if pydevd_save_locals.is_save_locals_available(): frame.f_locals[attr] = eval(expression, frame.f_globals, frame.f_locals) pydevd_save_locals.save_locals(frame) return frame.f_locals[attr] #default way (only works for changing it in the topmost frame) result = eval(expression, frame.f_globals, frame.f_locals) Exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals) return result except Exception: traceback.print_exc()
def evaluateExpression(thread_id, frame_id, expression, doExec): '''returns the result of the evaluated expression @param doExec: determines if we should do an exec or an eval ''' frame = findFrame(thread_id, frame_id) if frame is None: return expression = str(expression.replace('@LINE@', '\n')) #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329 #(Names not resolved in generator expression in method) #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html updated_globals = {} updated_globals.update(frame.f_globals) updated_globals.update( frame.f_locals ) #locals later because it has precedence over the actual globals try: if doExec: try: #try to make it an eval (if it is an eval we can print it, otherwise we'll exec it and #it will have whatever the user actually did) compiled = compile(expression, '<string>', 'eval') except: Exec(expression, updated_globals, frame.f_locals) pydevd_save_locals.save_locals(frame) else: result = eval(compiled, updated_globals, frame.f_locals) if result is not None: #Only print if it's not None (as python does) sys.stdout.write('%s\n' % (result, )) return else: result = None try: result = eval(expression, updated_globals, frame.f_locals) except Exception: s = StringIO() traceback.print_exc(file=s) result = s.getvalue() try: try: etype, value, tb = sys.exc_info() result = value finally: etype = value = tb = None except: pass result = ExceptionOnEvaluate(result) return result finally: #Should not be kept alive if an exception happens and this frame is kept in the stack. del updated_globals del frame
def changeAttrExpression(thread_id, frame_id, attr, expression): '''Changes some attribute in a given frame. @note: it will not (currently) work if we're not in the topmost frame (that's a python deficiency -- and it appears that there is no way of making it currently work -- will probably need some change to the python internals) ''' frame = findFrame(thread_id, frame_id) if frame is None: return try: expression = expression.replace('@LINE@', '\n') #tests (needs proposed patch in python accepted) # if hasattr(frame, 'savelocals'): # if attr in frame.f_locals: # frame.f_locals[attr] = eval(expression, frame.f_globals, frame.f_locals) # frame.savelocals() # return # # elif attr in frame.f_globals: # frame.f_globals[attr] = eval(expression, frame.f_globals, frame.f_locals) # return if attr[:7] == "Globals": attr = attr[8:] if attr in frame.f_globals: frame.f_globals[attr] = eval(expression, frame.f_globals, frame.f_locals) else: #default way (only works for changing it in the topmost frame) Exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals) except Exception: traceback.print_exc()
def runcode(self, code): """Execute a code object. When an exception occurs, self.showtraceback() is called to display a traceback. All exceptions are caught except SystemExit, which is reraised. A note about KeyboardInterrupt: this exception may occur elsewhere in this code, and may not always be caught. The caller should be prepared to deal with it. """ try: Exec(code, self.frame.f_globals, self.frame.f_locals) except SystemExit: raise except: self.showtraceback()
def consoleExec(thread_id, frame_id, expression): """returns 'False' in case expression is partially correct """ frame = pydevd_vars.findFrame(thread_id, frame_id) expression = str(expression.replace('@LINE@', '\n')) #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329 #(Names not resolved in generator expression in method) #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html updated_globals = {} updated_globals.update(frame.f_globals) updated_globals.update( frame.f_locals ) #locals later because it has precedence over the actual globals if IPYTHON: return exec_code(CodeFragment(expression), updated_globals, frame.f_locals) interpreter = ConsoleWriter() try: code = compile_command(expression) except (OverflowError, SyntaxError, ValueError): # Case 1 interpreter.showsyntaxerror() return False if code is None: # Case 2 return True #Case 3 try: Exec(code, updated_globals, frame.f_locals) except SystemExit: raise except: interpreter.showtraceback() return False
def customOperation(thread_id, frame_id, scope, attrs, style, code_or_file, operation_fn_name): """ We'll execute the code_or_file and then search in the namespace the operation_fn_name to execute with the given var. code_or_file: either some code (i.e.: from pprint import pprint) or a file to be executed. operation_fn_name: the name of the operation to execute after the exec (i.e.: pprint) """ expressionValue = getVariable(thread_id, frame_id, scope, attrs) try: namespace = {'__name__': '<customOperation>'} if style == "EXECFILE": namespace['__file__'] = code_or_file execfile(code_or_file, namespace, namespace) else: # style == EXEC namespace['__file__'] = '<customOperationCode>' Exec(code_or_file, namespace, namespace) return str(namespace[operation_fn_name](expressionValue)) except: traceback.print_exc()
def do_change_variable(): Exec('%s=%s' % (attr, value), self.getNamespace(), self.getNamespace())
def apply(self): mod = self.mod self._on_finish_callbacks = [] try: # Get the module name, e.g. 'foo.bar.whatever' modname = mod.__name__ # Get the module namespace (dict) early; this is part of the type check modns = mod.__dict__ # Parse it into package name and module name, e.g. 'foo.bar' and 'whatever' i = modname.rfind(".") if i >= 0: pkgname, modname = modname[:i], modname[i + 1:] else: pkgname = None # Compute the search path if pkgname: # We're not reloading the package, only the module in it pkg = sys.modules[pkgname] path = pkg.__path__ # Search inside the package else: # Search the top-level module path pkg = None path = None # Make find_module() uses the default search path # Find the module; may raise ImportError (stream, filename, (suffix, mode, kind)) = imp.find_module(modname, path) # Turn it into a code object try: # Is it Python source code or byte code read from a file? if kind not in (imp.PY_COMPILED, imp.PY_SOURCE): # Fall back to built-in reload() notify_error('Could not find source to reload (mod: %s)' % (modname, )) return if kind == imp.PY_SOURCE: source = stream.read() code = compile(source, filename, "exec") else: import marshal code = marshal.load(stream) finally: if stream: stream.close() # Execute the code. We copy the module dict to a temporary; then # clear the module dict; then execute the new code in the module # dict; then swap things back and around. This trick (due to # Glyph Lefkowitz) ensures that the (readonly) __globals__ # attribute of methods and functions is set to the correct dict # object. new_namespace = modns.copy() new_namespace.clear() new_namespace["__name__"] = modns["__name__"] Exec(code, new_namespace) # Now we get to the hard part oldnames = set(modns) newnames = set(new_namespace) # Create new tokens (note: not deleting existing) for name in newnames - oldnames: notify_info0('Added:', name, 'to namespace') modns[name] = new_namespace[name] # Update in-place what we can for name in oldnames & newnames: self._update(modns, name, modns[name], new_namespace[name]) self._handle_namespace(modns) for c in self._on_finish_callbacks: c() del self._on_finish_callbacks[:] except: traceback.print_exc()
def xreload(mod): """Reload a module in place, updating classes, methods and functions. Args: mod: a module object Returns: The (updated) input object itself. """ # Get the module name, e.g. 'foo.bar.whatever' modname = mod.__name__ # Get the module namespace (dict) early; this is part of the type check modns = mod.__dict__ # Parse it into package name and module name, e.g. 'foo.bar' and 'whatever' i = modname.rfind(".") if i >= 0: pkgname, modname = modname[:i], modname[i + 1:] else: pkgname = None # Compute the search path if pkgname: # We're not reloading the package, only the module in it pkg = sys.modules[pkgname] path = pkg.__path__ # Search inside the package else: # Search the top-level module path pkg = None path = None # Make find_module() uses the default search path # Find the module; may raise ImportError (stream, filename, (suffix, mode, kind)) = imp.find_module(modname, path) # Turn it into a code object try: # Is it Python source code or byte code read from a file? if kind not in (imp.PY_COMPILED, imp.PY_SOURCE): # Fall back to built-in reload() return reload(mod) if kind == imp.PY_SOURCE: source = stream.read() code = compile(source, filename, "exec") else: import marshal code = marshal.load(stream) finally: if stream: stream.close() # Execute the code. We copy the module dict to a temporary; then # clear the module dict; then execute the new code in the module # dict; then swap things back and around. This trick (due to # Glyph Lefkowitz) ensures that the (readonly) __globals__ # attribute of methods and functions is set to the correct dict # object. tmpns = modns.copy() modns.clear() modns["__name__"] = tmpns["__name__"] Exec(code, modns) # Now we get to the hard part oldnames = set(tmpns) newnames = set(modns) # Update attributes in place for name in oldnames & newnames: modns[name] = _update(tmpns[name], modns[name]) # Done! return mod