classification
Title: absolute import doesn't work for standard python modules
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.0, Python 2.6, Python 2.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: dangyogi, ncoghlan
Priority: normal Keywords:

Created on 2008-03-18 21:27 by dangyogi, last changed 2008-04-09 03:21 by ncoghlan. This issue is now closed.

Messages (4)
msg63993 - (view) Author: Bruce Frederiksen (dangyogi) Date: 2008-03-18 21:27
Try this to reproduce error:

$ mkdir -p test/email
$ cd test
$ touch __init__.py email/__init__.py
$ cat <<! > foo.py
from __future__ import absolute_import
import smtplib
!
$ python
>>> import foo
...
  File "/usr/lib/python2.6/smtplib.py", line 46, in <module>
    import email.utils
ImportError: No module named utils

If you rename the email subdirectory, it will find email.utils where it
should find it.

Strangely, this doesn't happen if you have an 'os' subdirectory and try
to import shlex, which does: import os.path ??
msg65166 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2008-04-08 15:09
Running the interactive interpreter like that places the current
directory on sys.path, so it *is* doing an absolute import of your
pseudo email package. (If it didn't do that, your test would fail at the
"import foo" line)

Instead of cd'ing into test the way you did, invoke the interpreter from
the next directory up and do an import of 'test.foo', and you should see
the absolute imports in the foo module having the desired effect.

(I expect the reason you didn't run into this for the os module is
because the os module is bootstrapped quite early in Python's startup
process, so you'd have to try really hard to get it to see something
other than the builtin standard library version of os)
msg65206 - (view) Author: Bruce Frederiksen (dangyogi) Date: 2008-04-08 19:17
OK, I see where I mis-diagnosed the problem.  It seems that importing
smtplib (for example) shouldn't get confused with my email package.  As
I understand it, using relative imports within a package should avoid
the problem of the names of subordinate packages/modules colliding with
those in other packages.  Should the problem have been written up that
the standard modules (e.g., smtplib) should use relative imports to
avoid name collision problems like this?  (I'm not sure if relative
imports work for standard modules).

If this is the correct statement of the problem, I can resubmit it if
that's easier.

Thanks in advance!
msg65231 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2008-04-09 03:21
Using relative imports within smtplib wouldn't have made any difference
in this case. Your dummy email package was the first one encountered on
sys.path, so the "import email.smtplib" line (which does an "import
email" internally as the first step in resolving the import, and then
tries to find "smtplib" in email.__path__) picked it up.

Putting an internal package directory on sys.path (as your example does)
is seriously bad ju-ju. It's one of the main reason why people are so
strongly discouraged from directly executing files that are stored in
package directories (along with another nasty side effect in getting two
different copies of the same module using different names, it also has
the same effect as what you did here - subpackages/modules can end up
overriding standard library modules and packages because the script
directory gets placed on sys.path).
History
Date User Action Args
2008-04-09 03:21:16ncoghlansetmessages: + msg65231
2008-04-08 19:17:38dangyogisetmessages: + msg65206
2008-04-08 15:09:50ncoghlansetstatus: open -> closed
resolution: not a bug
messages: + msg65166
nosy: + ncoghlan
2008-03-18 21:27:55dangyogicreate