4

In a project I have the same imports in multiple files. For example:

import os
import logging
import json
import time
import pathlib

and pylint will tell me I have duplicate code. I know that there is a way to disable this message: https://stackoverflow.com/questions/29206482/pylint-duplicate-code-false-positive. However, I want to know if there is a general consensus on best coding practice. I image there is a reason that pylint has ignore-imports=no by default. Should one change this? If so how?

One that I can think of is: create a file called imports.py that just has imports and include from imports import * at the beginning of each file, but this seems like bad coding practice to me since it would obscure the imports.

1 Answer 1

10

Pylint is a tool. A helpful tool, but ultimately just a bunch of dumb heuristics. These heuristics are fairly opinionated, so it's entirely normal to find false positives in code that looks reasonable to you. Luckily, Pylint is pretty configurable. If you disagree with Pylint (and it's reasonable to disagree), you can tell Pylint to shut up. This is normal and good.

That Pylint's similarity checker even has an ignore-imports option is an indication that they expect you to disagree on this matter, and have made it easy to make the tool match your expectations.

Still, when disabling or changing a linter rule, it's a good idea to think for a moment why your expectations differ. Sometimes, repeated code (including imports) is an indication of a missing abstraction. But not always! You might be importing the same modules for entirely different reasons. If so, creating an abstraction would be a bad idea, and the linter warning should just be disabled.

If you find that multiple files import the same set of modules for the same set of reasons, you might consider creating an abstraction for that. You suggest creating a file imports.py and then doing from .imports import * (plz use relative imports). In other languages like Rust or Haskell, such a file is sometimes called a “prelude”. In your case, I'd maybe consider importing each module individually through such a convenience module, e.g. from .utils import os, logging, json, time, pathlib.

But is this the right abstraction? I don't know. That depends on the rest of the code. I have a feeling that just looking at the modules does not lead to a good abstraction. Logging and file path manipulation don't really have anything to do with each other, so why should they be grouped together? Does each file really do it's own JSON handling? I suspect that the actual contents of your files might have some actual behaviour that you could extract into a separate model, making repetitive imports unnecessary.

A bad abstraction does indeed obscure things. So if you're not somewhat sure that you have found a sensible abstraction to improve your design, it's usually better to avoid it. Code smells like repeated code are just an indication that something might be wrong, but they aren't proof of anything. Sometimes, repeated code is just repeated code, and it's necessary to repeat the code in that context. If so, we can circle back to my initial point: configuring Pylint and disabling annoying rules is a perfectly reasonable thing to do.

1
  • 1
    Thank you for the very detailed response! It's extremely helpful.
    – Chris Z
    Commented Nov 12, 2021 at 15:05

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.