
"Brett Cannon" brett@python.org wrote:
On 2/9/07, Josiah Carlson jcarlson@uci.edu wrote:
"Brett Cannon" brett@python.org wrote:
On 2/9/07, Josiah Carlson jcarlson@uci.edu wrote:
[snip]
How is it done now?
Importers and loaders; see PEP 302.
Wow, I should have started there when I was doing my relative import work. That's much nicer to work with.
[snip]
It also naturally leads to a __name__ semantic that Guido had suggested to me when I was talking about relative imports:
goo.__name__ == '__main__' foo.__name__ == '__main__.foo' baz.__name__ == '__main__..bar.baz'
Which could more or less be used with the current importer; it just needs a special-casing of 'from . import ...' in the __main__ module.
And I am trying to avoid special-casing for this.
And it's only really an issue because we can't currently discern between module or package, right?
Basically. It's also where within a package the module is, so it isn't quite that simple.
The issue comes down to that we lose where a module is contained within a package hierarchy once __name__ gets set to __main__. If we came up with another way to delineate that a module was being executed or some other way to specify where a module was in a package then the problem would be solved. I prefer trying to change the former since the latter is perfectly handled with __name__ as-is when it isn't changed to __main__.
Kind-of. It still seems to break in a few cases, which I believe to be the result of current __name__ semantics (which can be fixed if __name__ could be anything, but I'll talk about that again later).
Say I wanted to do relative imports in paths below the current __main__ module. The following works, and gives me the __main__-derived package names that Guido suggested.
>>> __path__ = [os.getcwd()] >>> from . import bar >>> bar <module '__main__.bar' from 'D:\Projects\python\py25\bar.pyc'>
So far so good. What about "cousin" relative imports (an issue I've had to deal with myself)?
>>> from ..py25b import baz Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Relative importpath too deep
No dice. Sub-packages seem to be ok with this hack to __main__, but nothing that goes to a parent of the "root" package of __main__.
My attempts to hack __main__ with...
__name__ = '.'.join(os.getcwd().split('\')[1:])
just got me "parent package not loaded". Adding fake parent packages all the way to the root of the drive, leaving the above name mangling in place, allowed me to do the 'from ..py25b import baz' import in the "main" module.
I like Guido's suggestion; allow multiple trailing dots off of __main__. That is, suppose that we were able to do the "from ..py25b import baz" import, the __name__ of the imported object should be __main__..py25b.baz . Allowing that particular semantic would let us keep the "if __name__ == '__main__':" thing we've been doing. This, however, would require a bunch of extra coding.
Anyways...I hear where you are coming from with your statements of 'if __name__ could be anything, and we could train people to use ismain(), then all of this relative import stuff could *just work*'. It would require inserting a bunch of (fake?) packages in valid Python name parent paths (just in case people want to do cousin, etc., imports from __main__).
You have convinced me.
- Josiah