[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