[mod_python] Module reload/derived class problem

Graham Dumpleton grahamd at dscpl.com.au
Fri Mar 4 21:55:32 EST 2005

On 05/03/2005, at 5:42 AM, Alan Davies wrote:

> Now that I've realised why I get that error message, I can avoid the
> problem by brute force either by 'touch'ing 'B' every time I change
> 'A', or by restarting Apache after a change to 'A' (instead of a week
> later when I notice the problem).
> More advanced ideas for fixing the module reloading problem would be
> appreciated.

The problem derives from two short comings of the present module loading
system used by mod_python. The first is that module reloads are done on
top of the already loaded module. This in itself can cause some issues.
The second is that the module loading system isn't able to determine 
a parent module should be reloaded when a child module it depends on has
been changed.

The trigger for your problem is the second of these issues, but the 
of the error actually derives from the first issue.

Namely, the parent module module has what are effectively stale 
to a type object which has since been superseded because the child 
was re-imported as a result of some other request. When the child module
code is called it no longer identifies the instance as being of the same
type because the type object for the child has since been changed.

FWIW, the module loading system in Vampire doesn't suffer the problem.
When I write the code as:

## testa.py

class A:
   def foo(self):
     return "A:foo"

## testdrive.py

import vampire
import os

directory = os.path.dirname(__file__)
testa = vampire.importModule("testa",directory,__req__)

class B(testa.A):
   def foo(self):
     return "B::foo", testa.A.foo(self)

b = B()

and using the new publisher support in version of Vampire I am working 
if I access "/testdrive/b/foo" and then touch "testa.py" it still works
when I access "/testdrive/b/foo" again.

This is because Vampire has a means of determining that "testdrive.py"
depends on "testa.py" and thus when "testa.py" is modified, it will 
any prompting reload both "testdrive.py" and "testa.py" on the 
request even though "testdrive.py" hadn't actually been touched.

This is illustrated by logged messages. After a fresh restart, access 

[Sat Mar 05 13:41:57 2005] [notice] mod_python: (Re)importing module 
[Sat Mar 05 13:41:57 2005] [notice] vampire: Importing module 
[Sat Mar 05 13:41:57 2005] [notice] vampire: Importing module 

Then run "touch testa.py". The "testdrive.py" file has not been touched 
modified in any way and thus still has same modification time. Then 
the URL again:

[Sat Mar 05 13:42:10 2005] [notice] vampire: Reimporting module 
[Sat Mar 05 13:42:10 2005] [notice] vampire: Reimporting module 

Thereby showing how both parent and child were reimported even though 
child had been changed.

It is because it was detected that the parent depended on the modified 
child and
was also reloaded, you don't suffer the sort of problem you are seeing.

Thus for most cases the Vampire module loading system is a bit more 
that the default provided with mod_python. I still know of some cases 
it wouldn't be able to handle, but it is impossible to make any 
system completely perfect because of the various ways that type objects 
class instances could be cached and then later used again in the 
context of
freshly reloaded code which has a different idea of what it then 

Thus, as to a technical solution, you might consider using Vampire. If 
want the publisher support, you'll either have to wait for the next 
of Vampire or indicate that you are prepared to work with a beta version
which some others are also trying.


More information about the Mod_python mailing list