[Python-3000] PEP to change how the main module is delineated

Jim Jewett jimjjewett at gmail.com
Mon Apr 23 22:17:35 CEST 2007


On 4/23/07, Brett Cannon <brett at python.org> wrote:
> On 4/22/07, Steven Bethard <steven.bethard at gmail.com> wrote:

> In other words they are possible if we want to pay the startup cost of
> trying to infer the module's name.

This doesn't need to be a startup cost for python; it can be delayed
until an actual relative import is requested.  (Though I suppose that
might mean making __name__ a lazy attribute, which itself seems like
overkill.)

Call me cynical, but the problem seems to crop up only when *all* of
the following are true:

(a)  Your helper modules are not on sys.path.   (and you won't add
them -- or at the very least, you want to ensure using a local copy
instead of one that might be earlier on sys.path.)

(b)  You helper modules are not in the same directory as your main
code, or even a subdirectory of it.  (Maybe someone else is supplying
a black-box API, but you can't tell them where to install/symlink it.
Maybe your code is so complex that nothing is at the top level.)

(c)  You insist on running as __main__, instead of getting called as a
library by a better-placed wrapper script.  (Because doing it that way
is more convenient, for a quick-and-dirty version?  This conflicts
with (b).)

(d)  You have either a *lot* of imports or a very slow filesystem, and
can't afford much slop.  This also conflicts with (c).

I won't say this use case doesn't matter, but I'm not sure it is worth
any extra complexity in the import rules.

I *am* convinced that people needing that much complexity should be
the only ones to pay the extra startup cost -- but extending it to all
uses of -m might be OK.

The choice for those people who actually use it is really (1) Do it
right, despite the cost or (2) Accept that you don't really need such
a comprehensive install/config framework, and simplify your code.

> * For spam/bacon.py w/ with spam/__init__.py existing:

>   - Should we infer it as spam.bacon?
>     Startup cost, but accurate name allows for relative imports.

uh ... how much cost?  To me it looks like one extra file check --
less than the cost of having more than one directory in sys.path.

>   - Should we infer as bacon?
>     Cheap but breaks relative imports.
>   - Should we infer the name as __main__?
>     Status quo and breaks relative imports.

But still probably good enough most of the time ... just put "." on
sys.path.  If you can't do that, you're in the special-case zone.

> * For spam/bacon.py with *no* spam/__init__.py:

>   - Should we infer the name as bacon?
>     No relative imports possible since not in a package.
>   - Should we infer the name as __main__?
>     Status quo and no relative import issue as not in a package.

So does it matter which you choose?
Would it really be all that awful even if you did allow relative
imports based strictly on the directory structure?

> * For ../bacon.py
>
>    - With ../__init__.py defined and ../../ on sys.path:

So you can't change directory before launching, *and* you are
launching with a relative filename instead of an absolute ... which
suggests quick-hack.  You may not need the fancy inferences, nor
should you object to the price.

>       + Should we infer the name as bacon?
>          Simple, but breaks relative imports.

>       + Should we walk up the directories until __init__.py is not
> found and check for that directory on sys.path?
>           Costly startup, but allows for relative imports to work.

So if you care about startup costs, launch from the right directory...

-jJ


More information about the Python-3000 mailing list