-1

I think the following is bad style:

# In foo_pkg/bla_mod.py:
magic_value=42

# In foo_pkg/bar_mod.py:
from .bla_mod import magic_value

# In doit.py:
from foo_pkg.bar_mod import magic_value

Instead, I'd like that to always import an object from the module where it has been defined, i.e. in this case:

# In doit.py:
from foo_pkg.bla_mod import magic_value

Finding issues of this sort by hand is getting tedious very quickly (for each imported object, you have to open the module and check if it defines the object, or if it imports in from another module).

What is the best way to automate this check? To my surprise, neither pylint nor pyflakes seem to have an appropriate checker, but maybe there's another tool (or even some trick that can be used in Python itself)?

Problem statement in a nutshell: given a bunch of python source files, find every import of an object from a module that does not itself define the object.

I know there are libraries (including the standard library) where one module provides the main external API and imports the necessary symbols from other modules internally. However, that's not the case in the code base I'm working with, here these are artifacts of refactorings that I really want to eliminate.

Nikratio
  • 2,338
  • 2
  • 29
  • 43
  • 4
    Be warned: It is quite common for modules to do this deliberately. For example, `collections.defaultdict` is actually imported into `collections` from the `_collections` module. See the source: http://hg.python.org/cpython/file/2.7/Lib/collections.py This is probably why the tools you looked at have no checker for this. – user2357112 Jul 19 '14 at 22:50
  • I would probably either specify an [`__all__` list](http://stackoverflow.com/questions/44834/can-someone-explain-all-in-python) or make sure everything that isn't supposed to be part of a module's public API is defined with a leading underscore (e.g. `from .bla_mod import magic_value as _magic_value`). Either course of action would specify which parts of the module are in its public API (in particular, `import *` would ignore the non-public parts). Then, I'd try to find a checker that checks for importing non-public module contents. – user2357112 Jul 19 '14 at 23:27

1 Answers1

-1

Here's a draft script that solves the problem less than 100 lines: http://pastebin.com/CFsR6b3s

Nikratio
  • 2,338
  • 2
  • 29
  • 43