[Import-SIG] Dabeaz's weird import discovery

Guido van Rossum guido at python.org
Wed Apr 22 20:06:06 CEST 2015


On Wed, Apr 22, 2015 at 10:54 AM, Eric Snow <ericsnowcurrently at gmail.com>
wrote:

> On Wed, Apr 22, 2015 at 11:37 AM, Guido van Rossum <guido at python.org>
> wrote:
> > On Wed, Apr 22, 2015 at 10:33 AM, Eric Snow <ericsnowcurrently at gmail.com
> >
> > wrote:
> >> The surprising part is that it also happens for explicit relative
> >> imports.  I'm guessing that part was unintentional and simply not
> >> noticed when PEP 328 was implemented.
> >
> >
> > No, that must also have been intentional, because even when you use
> relative
> > import, the module you imported knows its full name, and that full name
> is
> > used as its key in sys.modules. If someone else uses absolute import for
> the
> > same module they should still get the same module object.
>
> I see what you're saying.  __name__ and sys.modules definitely need to
> reflect the fully resolved name.  I just mean that for relative import
> there is no need to bind the submodule to the parent, is there?


But there *is* a reason. The submodule must still be an attribute of the
parent package, because of the invariant that if you have
sys.modules['foo'] and sys.modules['foo.bar'], the latter must appear as
the 'bar' attribute of the former. This is an invariant of module loading,
and (I feel I'm repeating myself) the form of import used does not affect
loading.


> I'd
> consider it a code smell if I saw a module that imports just the
> parent and expecting the submodule to be bound there due to an import
> in yet another module.


It is indeed a code smell, and linters should point it out. (Unless this is
a documented part of the contract of the parent package, like it is for os
and os.path.)

But it *is* required that if you are sure you have loaded foo.bar, bar is
an attribute of foo.

There is another import rule that is relevant here; while `import foo.bar`
requires that bar is a module, `from foo import bar` accepts bar as any
attribute that exists in foo. The rule is then that after `import foo.bar`,
if you later do `from foo import bar`, it will use the bar attribute, and
that will be the bar submodule. (Unless foo's __import__.py messed around
with it.)


> EIBTI.  That's not specific to relative
> imports, but it does demonstrate the only case I can think of where
> someone might be relying on this behavior of relative imports.  That's
> why I think it was unintentional.
>
> Regardless, there's nothing to be done at this point besides document
> the behavior. :)
>

I expect if we redesigned it from first principles we'd end up with the
same rules in this case.

-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/import-sig/attachments/20150422/182c4ee8/attachment.html>


More information about the Import-SIG mailing list