119

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,732
  • 2
  • 12
  • 14

2 Answers2

117

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,132
  • 6
  • 16
  • 33
Winston Ewert
  • 24,732
  • 12
  • 72
  • 103
  • 2
    +1 especially for the compromise solution, which is probably the way I should go. – Oddthinking Aug 04 '12 at 15:46
  • 4
    Note you can also do `import .icing` instead of `from . import icing` – Jack Oct 14 '15 at 01:43
  • 18
    @Jack actually I don't think you can. From [this part of PEP328](https://www.python.org/dev/peps/pep-0328/#guido-s-decision): Relative imports must always use `from <> import` ; `import <>` is always absolute. Of course, absolute imports can use `from <> import` by omitting the leading dots. The reason `import .foo` is prohibited is because after `import XXX.YYY.ZZZ` then `XXX.YYY.ZZZ` is usable in an expression. But `.moduleY` is not usable in an expression. – A.Wan Nov 13 '15 at 19:50
64

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.

Martijn Pieters
  • 14,499
  • 10
  • 57
  • 58
  • 14
    +1 for #2 and #3. But #1 must be offset against what happens when the whole directory is moved (e.g. pushed down a level). – Oddthinking Aug 04 '12 at 15:46
  • foo, bar and baz are the equivalents of variable names *d*, *b*, *p* and *q*, confusing and requiring additional mental load to tell them appart. Therefore downvote. – problemofficer - n.f. Monica Sep 06 '21 at 16:01
  • 1
    @problemofficer: those variable names are going to cause you problems everywhere in your career, I'm afraid. They are pretty much standard. – Martijn Pieters Sep 06 '21 at 16:05
  • @MartijnPieters: I agree but "Everyone else does it, therefore it is OK" is not a valid counter-argument. – problemofficer - n.f. Monica Sep 06 '21 at 16:11
  • 2
    @problemofficer: every professional software developer also uses terms like queues and frontend and backend. Jargon is part of the job, of the way we communicate. When posting answers on a Software Engineering Q&A, I use standard terminology. I'm sorry that you feel that *foo*, *bar* and *baz* are not part of the normal vocabulary, but all I can tell you is that I'm not going to follow you trying to get rid of them. – Martijn Pieters Sep 06 '21 at 16:17