Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 929
Sam Avatar asked Jan 08 '16 20:01

Sam


2 Answers

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.

like image 196
JBGreen Avatar answered Sep 20 '22 18:09

JBGreen


I had a similar issue with one of my projects. I've been able to solve my issue by adding this line at the start of my module (before all imports besides sys & os, which are required for this insert), so that it would include the parent folder and by that it will be able to see the parent folder (turns out it doesn't do that by default):

import sys
import os
sys.path.insert(1, os.path.join(sys.path[0], '..'))
# all other imports go here...

This way, your main.py will include the parent folder (epipy). Give that a try, hope this helps :-)

like image 25
Moshe Shitrit Avatar answered Sep 23 '22 18:09

Moshe Shitrit