API Reference for Enthought Tool Suite 3.2.0

Live updating of objects in system from module reloads.

The main function exposed by this module is:

refresh(logger=None)

Check for edited python files for modules that are live in the system. If one or more are found, reload the module in such a way that its new class and function definitions are used by all pre-existing objects in the system. This differs from a simple reload(module) which makes no attempt to provide the freshly loaded implementations of classes to objects created with a previous (outdated) version of the class.

This feature allows you to make edits to a module while a program is running and not have to restart the program to get the new behavior in the system. It is particularly handy when working on large GUI applications where you want to update the core code in the system without a lengthy restart.

Example:

# foo.py
class Foo:
    def method(self):
        print "hello"

$ python
>>> from foo import Foo
>>> obj = Foo()
>>> obj.method()
hello
#<edit file>
# foo.py
class Foo:
    def method(self):
        print "goodbye"
#<end edit>
>>> import refresh
>>> refresh.refresh()
# obj will now have the behavior of the updated Foo classes.
>>> obj.method()
goodbye

How It works

In python, classes and functions are mutable objects. Importing a module instantiates an instance of all the classes and functions defined in the module.

Any objects instantiated from the classes have a obj.__class__ attribute the points to the class they are based upon. When you call a method on the object in your code like so:

obj.method()

python actually calls the method othe __class__ object like so:

obj.__class__.method(obj)

with obj passed in as the "self" argument. This indirection allows us to dynamically change the implementation of method().

When you edit a python module and then reload it in a python session, any classes within the module are reinstantiated within that module and any newly created objects created with a call to module.class() will have the behavior and methods of your freshly edited code. But what about objects that are already "live" in the system that were created with a previous version of module.class? Their __class__ attribute is still pointing at the old version of the class, and so they will have the old behavior. The quickest way to fix this is to find the old class object in the system and replace its attributes and methods with those of the freshly imported class. This will instantly give all old objects in the system the new behavior.

Functions are updated in a similar way. All old versions of functions have their internals (func_code, etc.) replaced with those of the freshly loaded implementation.

Caveats

Their are multiple issues with trying insert a new class definition back into classes. Doing this clobbers and class scope variables that were set at runtime. Also, this implementation cleans out old classes completely before inserting new method/attributes. That means that any methods dynamically added to a class are also clobbered. There are ways to potentially get around this, but it isn't clear that it is worth the effort (at least for Enthought applications) as such tricks are not used very often in classes that are often edited. When you do (or anytime you notice suspicious behavior), restart your application.

Enthought people: While refresh() can save you time for working with applications, ALWAYS do a fresh restart and check that everything is working properly before checking edited code in.

Questions

copyright:2005, Enthought, Inc.
author:Eric Jones
license:BSD

Classes

Function summary

Functions

Imported Names

Local nameRefers to
ClassTypetypes.ClassType
compilercompiler
FunctionTypetypes.FunctionType
gcgc
linecachelinecache
logginglogging
osos
Setsets.Set
syssys
UnboundMethodTypetypes.UnboundMethodType

© Copyright 2002-2009 Enthought, Inc.