In-place %editing of methods
By Robert Kern on the dev-list
It just occurred to me that someone could write a very useful magic for editing
methods and functions in-place. The following is a loose sketch to record my
thoughts in public.
You think you have a problem with a particular method. You use Foo.bar?? to view
its source. You realize that you need a print statement somewhere in there. What
This will inspect the source for just the method and open it in your editor.
When you are finished, it will create a new module object with an ad hoc name
for tracebacks and future %inplaces. The globals dict is populated with the
entries from the method object's globals dict (.im_func.
to ensure that you have the appropriate global referents (be sure to fix the
__file__ entry to the ad hoc name). If the new function needs extra imports or
other module-level functions, that's fine (untested). No new methods, though.
Execute the code in this module's namespace. Extract the function object by
name. If the original is a method, look up the class and assign the new function
object to it. If the original is a function, look up the module and assign it.
None of this is particularly difficult or problematic. Only when you need to
edit whole classes and adjust living objects to use the new type do you run into
difficulties. There are solutions on PyPI, but they are larger and more
error-prone than we probably care for.
%inplace should keep a record of these modifications. Many of them are going to
be throwaway debugging things, but some will be genuine modifications that
should be propagated into the actual source code. A SQLite database in
~/.ipython/ is a nice, robust location to keep them. Upon exit, IPython should
print out the final versions of the modified functions. Additionally, you can
have a couple of --options for %inplace that let you view/clean up the database
instead of editing something. For bonus points, generate a unified diff against
the actual files.