[Python-ideas] Packages and Import
Brett Cannon
brett at python.org
Sat Feb 10 01:50:45 CET 2007
On 2/9/07, Josiah Carlson <jcarlson at uci.edu> wrote:
>
> "Brett Cannon" <brett at python.org> wrote:
> > On 2/9/07, Josiah Carlson <jcarlson at uci.edu> wrote:
> > > "Brett Cannon" <brett at python.org> wrote:
> > > > On 2/9/07, Ron Adam <rrr at 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].
>
Right, but "path" in this case is not file path but an ambiguous path.
Relative imports work for modules stored in file systems, files
(e.g., zip files), databases, etc.
> 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__ .
But what about modules stored in a sqlite3 database? How is that
supposed to work? What made basing relative imports off of __name__
so nice is that it allowed the import machinery figure out what the
resulting absolute module name was. That allowed the modules to be
stored any way that you wanted without making any assumptions about
how the modules are stored or their location is determined by an
importer's find_module method.
> 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).
>
But it isn't a file path, it's an absolute module name that you are after.
> 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.
-Brett
More information about the Python-ideas
mailing list