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.