Why doesn't `from pkg import mod' work after `del pkg.mod'?

Piet van Oostrum piet at cs.uu.nl
Sun Jul 26 12:13:22 EDT 2009

>>>>> ryles <rylesny at gmail.com> (r) wrote:

>r> On Jul 25, 8:57 am, Piet van Oostrum <p... at cs.uu.nl> wrote:
>>> >>>>> ryles <ryle... at gmail.com> (r) wrote:
>>> >r> According tohttp://www.python.org/doc/essays/packages.html:
>>> >r> "The import statement first tests whether the item is defined in the
>>> >r> package; if not, it assumes it is a module and attempts to load it."
>>> >r> However, I've noticed that once a module is imported using the
>>> >r> `from pkg import mod' syntax, if its name is deleted from the
>>> >r> package namespace then subsequent imports with `from' will fail.
>>> This is incorrectly stated. Also on the initial import it will fail, not
>>> just on subsequent imports.
>>> piet$ python
>>> Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
>>> [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
>>> Type "help", "copyright", "credits" or "license" for more information.
>>> from pkg import _impl
>>> _impl # this is from a print statement in _impl to show that it did import
>>> Traceback (most recent call last):
>>>   File "<stdin>", line 1, in <module>
>>> ImportError: cannot import name _impl

>r> Well, since __init__.py is executed first, I would regard it as
>r> causing the initial (successful) import, and yours being the
>r> subsequent one, so that the "initial" import does not fail, the
>r> subsequent one does. Wording aside, though, I think we are on the same
>r> page here.

I was talking about the 'from pkg import _impl' statements because I
thought that's what we were talking about. Of course this does an
implicit 'import pkg' first, but that doesn't fail. In your OP you were
also talking about `from pkg import mod' imports and said that the
subsequent ones of these fails. I noticed that also the first one of
these would fail.

>>> According to the documentation
>>> <http://docs.python.org/library/functions.html#__import__> the statement
>>> from pkg import _impl
>>> _temp = __import__('pkg', globals(), locals(), ['_impl'], -1)
>>> _impl = _temp._impl
>>> This fails because _temp (the imported module) doesn't have a binding
>>> for _impl because you deleted it.

>r> But supposing we hadn't deleted it, and __init__.py didn't import
>r> _impl, there would still be no binding. Yet the importer would still
>r> import and make the module available (presumably it "knows" to do this
>r> since it was not already in sys.modules). The question really is that
>r> since in our example pkg._impl is still in sys.modules, why won't the
>r> importer add it to the pkg namespace again as it previous had? I would
>r> imagine this is either by design, or is a case that was never
>r> considered.

Yes, that is also something I don't understand.

>>> for _impl because you deleted it. By the way, if you have a `normal'
>>> package that doesn't do anything with the name _impl, after the import
>>> the pkg module namespace will have got a binding for _impl although it is not
>>> in your code. It will have been put there by the import code.

>r> Yes, this was noted further down in the original post with an example.

Sorry, I missed that.
Piet van Oostrum <piet at cs.uu.nl>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: piet at vanoostrum.org

More information about the Python-list mailing list