17

Imagine the directory structure:

/
    a/
        __init__.py
        b.py
        c.py
    c.py

File /a/b.py looks like:

import c
should_be_absolute = c

All the other files (including __init__) are empty.

When running a test script (using python 2.7):

import a.b
print a.b.should_be_absolute

with PYTHONPATH=/ from an empty directory (so nothing is added to PYTHONPATH from current directory) I get

<module 'a.c' from '/a/c.py'>

where according to PEP 328 and the statement import <> is always absolute I would expect:

<module 'c' from '/c.py'>

The output is as expected when I remove the /a/c.py file.

What am I missing? And if this is the correct behavior - how to import the c module from b (instead of a.c)?

Update:

According to python dev mailing list it appears to be a bug in the documentation. The imports are not absolute by default in python27.

karolx
  • 508
  • 4
  • 9

3 Answers3

27

you need to add from __future__ import absolute_import or use importlib.import_module('c') on Python 2.7

It is default on Python 3.

There was a bug in Python: __future__.py and its documentation claim absolute imports became mandatory in 2.7, but they didn't.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • 2
    You are right! After further digging I found the link to the [python-dev mailing list](http://python.6.n6.nabble.com/status-of-absolute-import-w-python-2-7-td1850742.html) confirming that the absolute_import feature is not on by default in python27. – karolx Jul 31 '12 at 14:58
0

If you are only adding / to your PYTHONPATH, then the search order could still be looking for c in the current directory. It would be a lot better if you placed everything under a root package, and referred to it absolutely:

/myPackage
    a/
        __init__.py
        b.py
        c.py
    __init__.py
    c.py

And a PYTHONPATH like: export PYTHONPATH=/:$PYTHONPATH

So in your a.c you would do and of these:

from myPackage import c
from myPackage.c import Foo
import myPackage.c

This way, it is always relative to your package.

jdi
  • 90,542
  • 19
  • 167
  • 203
  • Thanks but the question is more is this a correct behavior rather than how to reorganize the code to make it work. The actual problem that I am solving is that the 'c' is the name of the python build-in module and the code in the package that I am working is shadowing it (and according to the python docs should not) – karolx Jul 31 '12 at 08:42
-1

"Absolute" doesn't mean the one that you think it does; instead, it means that the "usual" package resolving procedure takes place: first, it looks in the directory of the package, then in all the elements of sys.path; which includes the elements from PYTHONPATH.

If you really want to, you can use tools like the imp module, but I'd recommend against it for something like this. Because in general, you shouldn't ever have to create a module with the same name as one in the standard Python distribution.

Ivo
  • 3,481
  • 1
  • 25
  • 29
  • Thanks @Ivo but the [PEP 328#rationale-for-absolute-imports](http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports) states that the absolute import _will always be a module or package reachable from sys.path_. There is nothing about the lookup in the package directory first. Can you point to some resource that documents the behavior that your described please? – karolx Jul 31 '12 at 10:42
  • http://docs.python.org/reference/simple_stmts.html#import is very clear on the process as it is implemented: "If the module being imported is supposed to be contained within a package then the second argument passed to find_module(), __path__ on the parent package, is used as the source of paths." – Ivo Jul 31 '12 at 13:28
  • "first, it looks in the directory of the package". Nope, that's relative import. – Peter Graham Apr 23 '13 at 23:12