Search code examples
pythonpippython-importeasy-install

Python ImportError after setup.py


After installing my python project with setup.py and executing it in terminal I get the following error:

...
from ui.mainwindow import MainWindow
  File "/usr/local/lib/python2.7/dist-packages/EpiPy-0.1-py2.7.egg/epipy/ui/mainwindow.py", line 9, in <module>
    from model.sir import SIR
ImportError: No module named model.sir

...

We assume we have the following structure of our project cookies:

.
├── setup.py
└── src
    ├── a
    │   ├── aa.py
    │   └── __init__.py
    ├── b
    │   ├── bb.py
    │   └── __init__.py
    ├── __init__.py
    └── main.py

File: cookies/src/main.py

from a import aa

def main():
    print aa.get_aa()

File cookies/src/a/aa.py

from b import bb

def get_aa():
    return bb.get_bb()

File: cookies/src/b/bb.py

def get_bb():
    return 'bb'

File: cookies/setup.py

#!/usr/bin/env python

import os
import sys

try:
    from setuptools import setup, find_packages
except ImportError:
    raise ImportError("Install setup tools")

setup(
    name = "cookies",
    version = "0.1",
    author = "sam",
    description = ("test"),
    license = "MIT",
    keywords = "test",
    url = "[email protected]",
    packages=find_packages(),
    classifiers=[
    """\
    Development Status :: 3 - Alpha
    Operating System :: Unix
    """
    ],
    entry_points = {'console_scripts': ['cookies = src.main:main',],},
)

If I install cookies as root with $ python setup.py install and execute cookies I get the following error: ImportError: No module named b. How can I solve the problem.


Solution

  • What I would do is to use absolute imports everywhere (from epipy import ...). That's what is recommanded in PEP 328.

    Your imports won't work anymore if the project is not installed. You can add the project directory to your PYTHONPATH, install the package, or, what I do when I'm in the middle of developing packages, install with the 'editable' option : pip install -e

    In editable mode, instead of installing the package code in your python distribution, a pointer to your project is created. That way it is importable, but the package uses the live code in development.

    Example:

    I am developing a package in /home/jbchouinard/mypackage. Inside my code, I use absolute imports, e.g. from mypackage import subpackage.

    If I install with pip install, the package will be installed in my distribution, let's say in /usr/lib/python2.7/dist-packages. If I make further changes to the package, I have to upgrade or uninstall/reinstall the package. This can get tedious quickly.

    If I install with pip install -e, a pointer (a .pth file) is created in /usr/lib/python2.7/dist-packages towards /home/jbchouinard/mypackage. I can import mypackage as if it was installed normally, but the code used is the code at /home/jbchouinard/mypackage; any change is reflected immediately.