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.
2 Answers 2
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
-
3+1 especially for the compromise solution, which is probably the way I should go.Oddthinking– Oddthinking08/04/2012 15:46:39Commented Aug 4, 2012 at 15:46
-
4Note you can also do
import .icing
instead offrom . import icing
Jack– Jack10/14/2015 01:43:44Commented Oct 14, 2015 at 1:43 -
19@Jack actually I don't think you can. From this part of PEP328: Relative imports must always use
from <> import
;import <>
is always absolute. Of course, absolute imports can usefrom <> import
by omitting the leading dots. The reasonimport .foo
is prohibited is because afterimport XXX.YYY.ZZZ
thenXXX.YYY.ZZZ
is usable in an expression. But.moduleY
is not usable in an expression.A.Wan– A.Wan11/13/2015 19:50:15Commented Nov 13, 2015 at 19:50
There are a few good reasons:
Relative imports break easily, when you move a module around.
Imagine you have a
foo.bar
, afoo.baz
and abaz
module in your package.foo.bar
importsfoo.baz
, but using a relative import.Now, if you were to move
foo.bar
tobar
, your module suddenly is importing a differentbaz
!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 thatbaz
is reallyfoo.baz
instead of the root-levelbaz
package.Absolute imports make it explicit what module is being used. And as
import this
preaches, explicit is better than implicit.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.
-
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– Oddthinking08/04/2012 15:46:08Commented Aug 4, 2012 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– problemofficer - n.f. Monica09/06/2021 16:01:18Commented Sep 6, 2021 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– Martijn Pieters09/06/2021 16:05:57Commented Sep 6, 2021 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– problemofficer - n.f. Monica09/06/2021 16:11:34Commented Sep 6, 2021 at 16:11
-
4@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– Martijn Pieters09/06/2021 16:17:18Commented Sep 6, 2021 at 16:17