Type unification and modules

Guido van Rossum guido at python.org
Tue Sep 11 13:44:33 EDT 2001


Ben Wolfson <rumjuggler at cryptarchy.org> writes:

> I have a program in which I place a class instance in sys.modules, and one
> of the things that bothered me when testing it in the interpreter was that
> I couldn't call reload() on it because it wasn't a module.  So with this
> news I tried the following:
> 
> 
> #file modtest.py
> import types, os, sys
> 
> class Mod(types.ModuleType):
>     def __getattr__(self, k):
>         return getattr(os, k)
>     def __setattr__(self, k, v):
>         setattr(os, k, v)
> 
> sys.modules['modtest'] = Mod()
> 
> #interactive IDLE session
> Python 2.2a3 (#23, Sep  7 2001, 01:43:22) [MSC 32 bit (Intel)] on win32
> Type "copyright", "credits" or "license" for more information.
> IDLE 0.8 -- press F1 for help
> >>> import modtest
> >>> modtest
> <module '?' (built-in)>
> >>> modtest.sep
> Traceback (most recent call last):
>   File "<pyshell#9>", line 1, in ?
>     modtest.sep
>   File "C:\Python22\modtest.py", line 5, in __getattr__
>     return getattr(os, k)
> AttributeError: 'NoneType' object has no attribute 'sep'

The problem is that the *original* module object is destroyed when you
assign to sys.modules['modtest'], because there are no other
references to it.  Destroying a module has the (normally desirable)
side effect of replacing all the values in the module's __dict__ with
None, in order to break circular references.  But here, the __dict__
is still referenced as the globals of the methods of the Mod class.

So a trick is needed to keep the original module object alive.  Add
this before that the assignment to sys.modules in modtest.py:

sys.modules['_modtest'] = sys.modtest['modtest']

--Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-list mailing list