reloading modules (was Re: [Zope3-dev] Re: Google SoC Project)

Jim Fulton jim at zope.com
Fri May 12 09:28:56 EDT 2006


Shane Hathaway wrote:
...
> 2) Make reloadable code fundamentally different. 

Yes.

 > If module X is
> supposed to be reloadable, and X creates a module-level global variable 
> Y, and module Z imports Y, then Y needs to be decorated in such a way 
> that Z's view of Y can change automatically when X is reloaded.

A variation on this theme is cause reload to update anything that
can be exported (rather than replacing it).  Of course, this means that
you couldn't export immutable objects, or oreload shouldn't be allowed
to provide a new value for an immutable variable.

Our work on persistent modules should shed some light on this.

I also think there is a real opportunity in allowing reload to fail.
That is, it should be possible for reload to visibly fail so the user
knows that they have to restart.  Then we only reload when we *know*
we can make changes safely and fail otherwise.  For example, in the common
case of updating a class, we can update the class in place.  If there
aren't any other changes, then we know the reload is safe.

> This second approach has subtle limitations, though.  What if Y has the 
> value 10 and Z defines a global variable A whose value is (Y**2)?  The 
> value of A might need to change when Y changes, but how can we arrange 
> for that to happen without making a mess of the code?  I doubt there's 
> any reasonable general solution.

Sure, but realize that this isn't unique to reload.  A client needs to
know if something is idempotent or not.  It should not cache the result of
a non-idempotent operation.

> Even more subtle is what happens when a reloadable module holds a 
> registry of things imported from other modules.  When the module is 
> reloaded, should the registry get cleared?  Zope 2's refresh says the 
> registry should be cleared, but in practice, this confuses everyone.

It causes pain and suffering.  :)

 > To solve this, I think reloadable modules need to have a special global
 > namespace.  Everything in the global namespace, as well as everything
 > reachable from the global namespace, must be explicit about what happens
 > at the time another module imports it or the module is reloaded.  I
 > think this could make a refresh mechanism like the one in Zope 2
 > reliable.  It has a lot of similarity with persistent modules, but it
 > might be simpler.  I haven't thought it all the way through.  The idea
 > came to me about halfway through this post. :-)

Here's an idea: When we do a new-improved reload, we:

1. Reevaluate the code in the pyc, getting the original dictionary.

2. Recompile and evaluate the code without writing a new pyc.

3. Compare the old and new dictionaries to find changes.  If we
    don't know how to compare 2 items, we assume a change.  Note
    removing a variable is considered an unsafe change.  Adding a
    variable is assumed to be a safe change as long as a variable of
    the same name hasn't been added to the module dynamically.

4. We consider whether each of the changes is safe.  If any change
    is unsafe, we raise and error, aborting the reload.  A change is
    safe if the original and new variables are of the same type, the
    values are mutable and if we know how to update the old value
    based on the new value.  In addition, for a change to be safe,
    the original value and the value currently in the module must be
    the same and have the same value.  That is, it can't have been
    changed dynamically.

5. We apply the changes and write a new pyc.

This boils down to merging differences at the Python level.
We fail if we don't know how to apply the diff. At that point,
the user knows they need to restart to get the change.

Hm. This feels kind of workable.  It might even make a good PEP
for a "safe reload".

What do you think?

Jim

-- 
Jim Fulton           mailto:jim at zope.com       Python Powered!
CTO                  (540) 361-1714            http://www.python.org
Zope Corporation     http://www.zope.com       http://www.zope.org


More information about the Zope3-dev mailing list