On Fri, Jan 7, 2011 at 12:38 PM, Ron Adam firstname.lastname@example.org wrote:
You could add a private dictionary to sys, that is updated along with sys.modules, which maps module names to real names. And have a function in inspect to retrieve the real name for an object.
That sounds like it would do pretty much what you need and doesn't add a top level builtin or global, or change "if __name__ == '__main__': main()".
My original suggestion was along those lines, but I've come to the conclusion that it isn't sufficiently granular - when existing code tinkers with "__module__" it tends to do it at the object level rather than by modifying __name__ in the module globals.
To turn this into a concrete proposal, here is what I am thinking of specifying in a PEP for 3.3:
Implicit configuration of __module__ attributes is updated to check for a definition of "__import_name__" at the module level. If found, then this is used as the value for the __module__ attribute. Otherwise, __module__ is set to __name__ as usual.
Any code that currently sets a __module__ attribute (i.e. function and class definitions) will also set an __impl_module__ attribute. This attribute will always be set to the value of __name__.
Update and/or augment the relevant C APIs to make it easy to do this for affected extension modules
Update inspect.getsource() (and possibly some other introspection functions) to look at __impl_module__ rather than __module__
Update all acceleration (such as _datetime) and "implementation packages" (such as unittest) to set __module__ and __impl_module__ appropriately on exported objects
Update the __main__ execution logic (including both the builtin logic and runpy) to insert the __main__ module into sys.modules as both "__main__" and the module's real name (i.e. the name that would result in a second copy of the module ending up in sys.modules if you imported it)
Update the __main__ execution logic to set __import_name__ to the actual name of the module.
So we end up with two new magic attributes:
__import_name__: optional module level attribute that indicates a preferred alternative to __name__ for accessing the module. contents. Alters the value of __module__ for classes and functions defined in the module. Implicitly set for the __main__ module. __impl_module__: implicitly set on objects with a __module__ attribute to allow __module__ to be altered to refer to an object's preferred import location without losing the actual implementation location of the object
-- Nick Coghlan | email@example.com | Brisbane, Australia