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.

Was it helpful?

Solution

Not a perfect solution, but what I usually do is this:

  1. Open Pydev
  2. Remove all * imports
  3. 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top