[Python-ideas] Implicit submodule imports

Steven D'Aprano steve at pearwood.info
Sat Sep 27 02:33:29 CEST 2014


On Fri, Sep 26, 2014 at 12:43:12PM -0700, Ethan Furman wrote:

> What about
> 
>   Option 4: have reload work with modules converted into classes
> 
> ?
> 
> This may mean having some extra fields in the class, and probably some 
> extra code in the module loading, but it might be the simplest approach.


I don't know that this is strictly necessary. You can put anything you 
like into sys.modules, and reload() just raises a TypeError:


py> sys.modules['spam'] = 23
py> import spam
py> spam
23
py> reload(spam)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: reload() argument must be module


Since reload() is mostly intended as a convenience at the REPL, I'd be 
willing to forgo that convenience for special "modules".

Or perhaps these special "modules" could subclass ModuleType and somehow 
get reloading to work correctly. In 2.7 at least you can manually copy a 
module to a module subclass, install it into sys.modules, and reload 
will accept it. Not only that, but after reloading it still uses the 
same subclass.

Unfortunately, when I tried it in 3.3, imp.reload complained about my 
custom module subclass not being a module, so it seems that 3.3 at least 
is more restrictive than 2.7. (Perhaps 3.3 reload does a "type(obj) is 
ModuleType" instead of isinstance test?)

Nevertheless, I got this proof of concept more-or-less working in 2.7 
and 3.3:

import sys
from types import ModuleType

class MagicModule(ModuleType):
    def __getattr__(self, name):
        if name == "spam":
            return "Spam spam spam!"
        raise AttributeError

eggs = 23

_tmp = MagicModule(__name__)
_tmp.__dict__.update(sys.modules[__name__].__dict__)
sys.modules[__name__] = _tmp
del _tmp



-- 
Steven


More information about the Python-ideas mailing list