"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, Ron Adam <rrr@ronadam.com> wrote: [snip]
import module module()
And it would just work. ;-)
I like this idea. Makes it very obvious. You just say "when a specific module is specified at the command line it is called. Could even have it take possibly sys.argv[1:] (which I think was supposed to turn into sys.args or sys.arg or something at some point).
What do other people think?
I don't like it. Much of my dislike comes from personal aesthetics, but then there is a logical disconnect. When an instance of a class is created, its __call__ method is not automatically called. By using the semantic of 'the __call__ function in the module namespace is automatically executed if the module is "run" from the command line', we are introducing a different instance creation semantic (an imported module is an instance of ModuleType).
But I don't see the leap of how specifying a module to execute on the command line is any different than doing ``Class()()`` for instantiation with an immediate call. It would still be a separate step.
I feel that there is a disconnect, but maybe it's personal aesthetics again.
I think we should just stick with what has been proposed for *years*, a __main__ function that is automatically executed after the module has been imported if its __name__ == '__main__'.
But that does not solve the problem Ron has been trying to deal with; setting __name__ to __main__ prevents the execution of a module that uses relative imports because the import machinery can then no longer infer what package the module is in.
I may have missed it, but how are either of the following ambiguous... from . import foo from ..bar import baz The leading dot tells me that 'relative to the path of the current module (or __init__.py module in a package), look for packages/modules named [everything else without a single leading dot]. Now, I tried the first of those lines in Python 2.5 and I was surpised that having two files foo and goo, goo importing foo via the first example above, didn't work. What is even worse is that over a year ago I was working on an import semantic for relative imports that would have made the above do as I would have expected. This leads me to believe that *something* about relative imports is broken, but being that I mostly skipped the earlier portions of this particular thread, I'm not certain what it is. I would *guess* that it has to do with the way the current importer comes up with package relative imports, and I believe it could be fixed by switching to a path-relative import. That is, when module goo is performing 'from . import foo', you don't look at goo.__name__ to determine where to look for foo, you look at goo.__file__ . With that change in semantic, both of the above cases work just fine, including 'from ..bar import baz', even without the current module being part of a package. That is, running goo.py in the following tree would succeed with the above two imports... .../ torun/ #include __init__.py if you want this to be a package goo.py foo.py bar/ __init__.py baz.py #I don't know if it would make sense to require __init__.py here It is still possible to handle import hooks, as the relative import stuff is only really applicable to getting the base path from which to start searching for sub packages (after you have stripped off all leading periods). 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. It may also make sense to do path/__name__ normalization relative to __main__ for any relative imports, so if in baz.py above you did 'from ..torun import foo', that it gave you the previously existing foo and not a new copy. I've got a bunch of code that implements the above name/path semantic, but it was never tested (being that I was using Python 2.4 at the time, and relative imports weren't proper syntax). - Josiah