Is there an IDE/utility to refactor Python * imports to use standard module.member syntax?
-
05-07-2021 - |
Question
I was recently tasked with maintaining a bunch of code that uses from module import *
fairly heavily.
This codebase has gotten big enough that import conflicts/naming ambiguity/"where the heck did this function come from, there are like eight imported modules that have one with the same name?!"ism have become more and more common.
Moving forward, I've been using explicit members (i.e. import module ... module.object.function()
to make the maintenance work I do more readable.
But I was wondering: is there an IDE or utility which robustly parses Python code and refactors * import statements into module import statements, and then prepends the full module path onto all references to members of that module?
We're not using metaprogramming/reflection/inspect
/monkeypatching heavily, so if aforementened IDE/util behaves poorly with such things, that is OK.
Solution
Not a perfect solution, but what I usually do is this:
- Open Pydev
- Remove all
*
imports - Use the
optimize imports
command (ctrl+shift+o
) to re-add all the imports
Roughly solves the problem :)
If you want to build a solution yourself, try http://docs.python.org/library/modulefinder.html
OTHER TIPS
Here are the other related tools mentioned:
- working with AST directly, which is very low-level for your use.
- working with modulefinder which may have a lot of the boilerplate code you are looking for,
- rope, a refactoring library (@Lucas Graf),
- the bicycle repair man, a refactoring libary
- the logilab-astng library used in
pylint
More about pylint
pylint
is a very good tool built on top of ast
that is already able to tell you where in your code there are from somemodule import *
statements, as well as telling you which imports are not necessary.
example:
# next is what's on line 32
from re import *
this will complain:
W: 32,0: Wildcard import re
W: 32,0: Unused import finditer from wildcard import
W: 32,0: Unused import LOCALE from wildcard import
... # this is a long list ...
Towards a solution?
Note that in the above output pylint
gives you the line numbers. it might be some effort, but a refactoring tool can look at those particular warnings, get the line number, import the module and look at the __all__
list, or using a sandboxed execfile()
statement to see the module's global names (would modulefinder
help with that? maybe...). With the list of global names from __all__
and the names that pylint
complains about, you can have two set()
and proceed to get the difference. Replace the line featuring wildcard imports with specific imports.