On 01/06/2011 09:28 PM, Nick Coghlan wrote:
On Fri, Jan 7, 2011 at 12:38 PM, Ron Adamrrr@ronadam.com 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.
What do you mean by *tinkers with "__module__"* ?
Do you have an example where/when that is needed?
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.
If __import_name__ is going to match __module__ everywhere else, why not just call it __module__ every where?
Would __package__ be changed in any way?
- 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__.
So we will have: __package__, __module__, __import_name__, __impl_name__, and if you also include __file__ and __path__, that makes six different attributes for describing where something came from.
I don't know about you, but this bothers me a bit. :-/
How about reconsidering going the other direction:
1. Add __module__ to module level name space. +1
2. Add a module registry that uses the __module__ attribute to get a module_location_info object, which would have all the useful location info in it. (including the real name of "__main__")
If __name__ and __module__ are not changed, Programs that use those won't break.
Also consider having virtual modules, where objects in it may have come from different *other* locations. A virtual module would need a way to keep track of that. (I'm not sure this is a good idea.)
Does this fit some of problems you are thinking of where the granularity may matter?
It would take two functions to do this. One to create the virtual module, and another to pre-load it's initial objects. For those objects, the loader would set obj.__module__ to the virtual module name, and also set obj.__original_module__ to the original module name. These would only be seen on objects in virtual modules. A lookup on obj.__module__ will tell you it's in a virtual module. Then a lookup with obj.__original_module__ would give you the actual location info it came from.
By doing it that way, most people will never need to know how these things work or even see them. ie... It's advance/expert Python foo. ;-)
Any way, I hope this gives you some ideas, I know you can figure out the details much better than I can.