122

I recently upgraded versions of pylint, a popular Python style-checker.

It has gone ballistic throughout my code, pointing out places where I import modules in the same package, without specifying the full package path.

The new error message is W0403.

W0403: Relative import %r, should be %r

Used when an import relative to the package directory is detected.


Example

For example, if my packages are structured like this:

/cake
  /__init__.py
  /icing.py
  /sponge.py
/drink

and in the sponge package I write:

import icing

instead of

import cake.icing

I will get this error.


While I understand that not all Pylint messages are of equal importance, and I am not afraid to dismiss them, I don't understand why such a practice is considered a poor idea.

I was hoping someone could explain the pitfalls, so I could improve my coding style rather than (as I currently plan to do) turning off this apparently spurious warning.

Oddthinking
  • 1,988

2 Answers2

118

The problem of import icing is that you don't know whether it's an absolute import or a relative import. icing could be a module in python's path, or a package in the current module. This is quite annoying when a local package has the same name as a python standard library package.

You can do from __future__ import absolute_import which turns off implicit relative imports altogether. It is described, including with this justification about ambiguity, in PEP 328. I believe Python 3 has implicit relative imports turned off completely.

You still can do relative imports, but you have to do them explicitly, like this:

from . import icing
lennon310
  • 3,242
Winston Ewert
  • 25,052
66

There are a few good reasons:

  1. Relative imports break easily, when you move a module around.

    Imagine you have a foo.bar, a foo.baz and a baz module in your package. foo.bar imports foo.baz, but using a relative import.

    Now, if you were to move foo.bar to bar, your module suddenly is importing a different baz!

  2. Relative imports are ambiguous. Even without moving around the bar module in the above example, a new developer coming to your project could be forgiven for not realizing that baz is really foo.baz instead of the root-level baz package.

    Absolute imports make it explicit what module is being used. And as import this preaches, explicit is better than implicit.

  3. Python 3 has disabled implicit relative imports altogether; imports are now always interpreted as absolute, meaning that in the above example import baz will always import the top-level module. You will have to use the explicit import syntax instead (from . import baz).

    Porting the example from Python 2 to 3 would thus lead to unexpected problems, using absolute imports now will make your code future-proof.