Alan Davies
alan at goatpunch.com
Fri Mar 4 13:42:09 EST 2005
Hi, I just wanted to contribute some information about a problem I'd been having, for a while that I couldn't find a clear answer to anywhere. It's a combination of two problems that I'd seen discussed in different places. The problem was this: I created a class 'A', in it's own module, that serves up a dynamic site. I then derived a class 'B' from 'A', that adds a few extras. Some of 'A's methods were overridden, deferring functionality to the base class by explicitly calling 'A' (e.g. calling A.foo(self) from within B::foo()). Everything seemed to work as expected, but once in a while I would get an error like this when a method on 'B' was called: TypeError: unbound method foo() must be called with A instance as first argument (got B instance instead) The error would go away when I restarted Apache. The problem was, of course, caused by the module containing 'A' being reloaded. The reloads would happen when I made a change to 'A', which is called directly by mod python. Module 'A' would reload when I modified it, which I would do occasionally, without thinking to test 'B' which shouldn't have been impacted by the changes. The reloaded class 'A' is a different class from the original 'A'. I suppose this has to happen when a module is reloaded, and it's probably a feature that just looks like a bug. The problem can be demonstrated without even using mod_python, by the following simple example: ------ file testa.py --------- class A: def foo(self): print "A:foo" -----file testderive.py ----- import testa class B(testa.A): def foo(self): print "B::foo" testa.A.foo(self) b = B() print "first request:" b.foo() # simulate mod_python performing a reload reload(testa) print "second request:" b.foo() ---- testderive.py output --------- >>> first request: B::foo A:foo second request: B::foo Traceback (most recent call last): File "testderive.py", line 16, in ? b.foo() File "testderive.py", line 6, in foo testa.A.foo(self) TypeError: unbound method foo() must be called with A instance as first argument (got B instance instead) ------------------------------------ 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. Hope someone finds this useful, --Alan
|