39

When one tries to import a module foo while being in the source directory, one gets an rather confusing ImportError message: ImportError: No module named foo.

How can I easily catch this case and return a more informative message, e.g. 'Please do not load module foo from the source directory'?

Having the __init__.py, I would start with:

try:
    from _foo import *
except ImportError:
    ## check whether in the source directory...

So I would like to distinguish the different causes for an ImportError (e.g. because a module named foo is not installed at all), and detect the case in which the setup.py is located in the current directory. What would be a elegant way of doing this?

Paolo
  • 20,112
  • 21
  • 72
  • 113
Julian
  • 1,271
  • 2
  • 12
  • 17

1 Answers1

55

ImportError: No module named foo actually means the module foo.py or package foo/__init__.py could not be found in any of the directories in the search path (sys.path list).

Since sys.path usually contains . (the current directory), that's probably what you meant by being in the source directory. You are in the top-level directory of package foo (where the __init__.py file is) so obviously you can't find foo/__init__.py.

Finally, you've answered your own question, more or less:

try:
    from _foo import *
except ImportError:
    raise ImportError('<any message you want here>')

Alternatively, you could check the contents of sys.path, the current directory and, if known, the expected package directory and produce an even detailed and context-aware message.

Or add .. to the PYTHONPATH environment variable (on Unix) to allow you to run from your source directory. Might even work on Windows, but I wouldn't know.

isedev
  • 18,848
  • 3
  • 60
  • 59
  • Thanks for the quick answer. I'm rather looking for a way to check whether the `ImportError` is raised by the `setup.py` being located in the current directory and distinguish it from other cases. – Julian Feb 07 '13 at 12:33
  • So use the second option I mentioned. You know which package you are trying to import (as a last resort, extract it from the `ImportError` message) and you can get the current directory name. The condition you are looking for corresponds to the package and directory name being the same, no? – isedev Feb 07 '13 at 12:47