[Python-ideas] Module aliases and/or "real names"
rrr at ronadam.com
Wed Jan 12 11:31:12 CET 2011
On 12/29/2010 03:52 PM, Nick Coghlan wrote:
> Disclaimer: this is a currently half-baked idea that needs some
> discussion here if it is going to turn into something a bit more
> coherent :)
> On and off, I've been pondering the problem of the way implementation
> details (like the real file structures of the multiprocessing and
> unittest packages, or whether or not an interpreter use the pure
> Python or the C accelerated version of various modules) leak out into
> the world via the __module__ attribute on various components. This
> mostly comes up when discussing pickle compatibility between 2.x and
> 3.x, but in can show up in various guises whenever you start relying
> on dynamic introspection.
> As, I see it, there are 3 basic ways of dealing with the problem:
> 1. Allow objects to lie about their source module
> This is likely a terrible idea, since a function's global namespace
> reference would disagree with its module reference. I suspect much
> weirdness would result.
> 2. A pickle-specific module alias registry, since that is where the
> problem comes up most often
> A possible approach, but not necessarily a good one (since it isn't
> really a pickle-specific problem).
> 3. An inspect-based module alias registry
> That is, an additional query API (get_canonical_module_name?) in the
> inspect module that translates from the implementation detail module
> name to the "preferred" module name. The implementation could be as
> simple as a "__canonical__" attribute in the module namespace.
> I actually quite like option 3, with various things (such as pydoc)
> updated to show *both* names when they're different. That way people
> will know where to find official documentation for objects from
> pseudo-packages and acceleration modules (i.e. under the canonical
> name), without hiding where the actual implementation came from.
> Pickle *generation* could then be updated to only send canonical
> module names during normal operation, reducing the exposure of
> implementation details like pseudo-packages and acceleration modules.
> Whether or not runpy should set __canonical__ on the main module would
> be an open question (probably not, *unless* runpy was also updated to
> add the main module to sys.modules under its real name as well
This makes more sense now that we've discussed it a bit.
Here's a rough sketch of a context manager that temporarily overrides the
This works well for simple introspection. For example, you can use it to
call inspect functions without changing them.
But pickling is recursive, so this probably wouldn't work very well for that.
from contextlib import contextmanager
def method(self): pass
c = cls()
InstanceMethod = type(c.method)
def _getter(self, value):
if value == "__module__" and hasattr(self, "__alt_module__"):
return object.__getattribute__(self, "__alt_module__")
return object.__getattribute__(self, value)
obj.__class__.__getattribute__ = InstanceMethod(_getter, obj)
# gets __alt__module__ if it exists, else gets __module__
with alt_module_getter(obj) as obj:
module_name = get_module_name(obj)
More information about the Python-ideas