[Import-SIG] PEP 395 (Module aliasing) and the namespace PEPs

Eric Snow ericsnowcurrently at gmail.com
Wed Nov 16 23:41:34 CET 2011

On Wed, Nov 16, 2011 at 1:06 PM, PJ Eby <pje at telecommunity.com> wrote:
> On Wed, Nov 16, 2011 at 1:21 PM, Eric Snow <ericsnowcurrently at gmail.com>
> wrote:
>> But which is more astonishing (POLA and all that): running your module
>> in Python, it behaves differently than when you import it (especially
>> __name__); or you add an __init__.py to a directory and your *scripts*
>> there start to behave differently?
> To me it seems that the latter is more astonishing because there's less
> connection between your action and the result.  If you're running something
> differently, it makes more sense that it acts differently, because you've
> changed what you're *doing*.  In the scripts case, you haven't changed how
> you run the scripts, and you haven't changed the scripts, so the change in
> behavior seems to appear out of nowhere.

Well, then I suppose both are astonishing and, for me at least, the
module-as-script side of it has bit me more.  Regardless, both are a
consequence of the script vs. module situation.

>> When I was learning Python, it took quite a while before I realized
>> that modules are imported and scripts are passed at the commandline;
>> and to understand the whole __main__ thing.
> It doesn't seem to me that PEP 395 fixes this problem.  In order to
> *actually* fix it, we'd need to have some sort of "package" statement like
> in other languages - then you'd declare right there in the code what package
> it's supposed to be part of.

Certainly an effective indicator that a file's a module and not a
script.  Still, I'd rather we find a way to maintain the
filesystem-based package approach we have now.  It's nice not having
to look in each file to figure out the package it belongs to or if
it's a script or not.

The consequence is that a package that's spread across multiple
directories is likewise addressed through the filesystem, hence PEPs
382 and 402.  However, the namespace package issue is a separate one
from script-vs-module.

>>  It has always been a pain, particularly when I wanted to
>>  just check a module really quickly for errors.
> What, specifically, was a pain?  That information might be of more use in
> determining a solution.
> If you mean that you had other modules importing the module that was also
> __main__, then I agree that having a solution for __main__-aliasing is a
> good idea.

PEP 395 spells out several pretty well.  Additionally, running a
module as a script can cause trouble if your module otherwise relies
on the value of __name__.  Finally, sometimes I rely on a module
triggering an import hook, though that is likely a problem just for

>  I just think it might be more cleanly fixed by checking whether
> the __file__ of a to-be-imported module is going to end up matching
> __main__.__file__, and if so, alias __main__ instead.

Currently the only promise regarding __file__ is that it will be set
on module object once the module has been loaded but before the
implicit binding for the import statement.  So, unless I'm mistaken,
that would have to change to allow for import hooks.  Otherwise, sure.

>> However, lately I've actually taken to the idea that it's better to
>> write a test script that imports the module and running that, rather
>> than running the module itself.  But that came with the understanding
>> that the module doesn't go through the import machinery when you *run*
>> it, which I don't think is obvious, particularly to beginners.  So
>> Nick's solution, to me, is an appropriate concession to the reality
>> that most folks will expect Python to treat their modules like modules
>> and their scripts like scripts.
> You lost me there: if most people don't understand the difference, then why
> are they expecting a difference?

Yeah, that wasn't clear.  :)

When someone learns Python, they probably are not going to recognize
the difference between running their module and importing it.  They'll
expect their module to work identically if run as a script or
imported.  They won't even think about the distinction.  Or maybe I'm
really out of touch (quite possible :).

It'll finally bite them when they implicitly or explicitly rely on the
module state set by the import machinery (__name__, __file__, etc.),
or on customization of that machinery (a la import hooks).

Educating developers on the distinction between scripts and modules is
good, but it seems like PEP 395 is trying to bring the behavior more
in line with the intuitive behavior, which sounds good to me.

Regarding the PEP 402 conflict, if using .pyp on directory names
addresses Nick's concern, would you be opposed to that solution?


p.s. where should I bring up general discussion on PEP 395?

More information about the Import-SIG mailing list