[Python-ideas] a standard approach to module-replace-itself-in-sys.modules

Eric Snow ericsnowcurrently at gmail.com
Thu Mar 13 09:01:03 CET 2014


Not that long ago we had a discussion about the esoteric, yet totally
supported and not going anywhere, trick of having a module replace
itself in sys.modules.  Presently there isn't any convention
surrounding the technique.  It's simply a matter of sticking something
else into sys.modules[__name__].

The problem is that there are some subtle things that can go wrong in
the import system if you aren't careful and people generally won't
know that.  (Then again the whole technique isn't exactly in the
mainstream!)  To help reduce the risk here, I propose that we provide
a helper in importlib.util and an associated convention.

The helper will be a class decorator and the convention will be to
decorate 1 class at the bottom of the module, where the class will
contain any relevant customizations.  The decorator will do the
following:

1. create a new module subclass;
2. merge the decorated class namespace into the subclass;
3. create an instance of the subclass;
4. merge the original module namespace into the instance;
5. set sys.modules[__name__] to the new instance.

For example:

@importlib.util.replace_module
class CustomModule:
    CHEDDAR = None
    @property
    def limburger (self):
        return None

There's more to it but that captures the gist. I've been exploring API
ideas, but ultimately we don't need much to get the ball rolling.  In
the meantime, I've published an unrefined but mostly working version
of replace_module() online:

https://bitbucket.org/ericsnowcurrently/odds_and_ends/src/default/replace_module.py

-eric


More information about the Python-ideas mailing list