4

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 = "asd@ads.asd",
    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.

Sam
  • 387
  • 2
  • 9
  • 22
  • Is the package you are importing (or its parent directory) in the PYTHONPATH? – tuned Jan 08 '16 at 21:00
  • no, only `['', '/usr/local/lib/python2.7/dist-packages/EpiPy-0.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/peppercorn-0.5-py2.7.egg', ...]`. The folder EpiPy-0.1-py2.7.egg includes the following packages: `EGG-INFO` and `epipy` ` – Sam Jan 08 '16 at 21:07
  • https://docs.python.org/2.5/whatsnew/pep-328.html You have to use `from .model.sir import SIR` – JBGreen Jan 08 '16 at 21:32
  • @JBChouinard this is the error: `Traceback (most recent call last): File "main.py", line 5, in from ui.mainwindow import MainWindow File "/home/sam/Documents/workspace/EpiPy/epipy/ui/__init__.py", line 4, in from mainwindow import MainWindow File "/home/sam/Documents/workspace/EpiPy/epipy/ui/mainwindow.py", line 9, in from .model.sir import SIR ImportError: No module named model.sir` – Sam Jan 08 '16 at 21:37
  • Oh yeah, .model works if you are within the model subpackage. Since you are in ui you have to use ..model (two dots). It works just like Unix relative paths. The recommended usage though, is to use absolute imports everywhere. – JBGreen Jan 08 '16 at 22:16
  • @JBChouinard i updated my question – Sam Jan 08 '16 at 22:57

2 Answers2

4

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.

JBGreen
  • 534
  • 2
  • 6
  • Thanks, your note `pip install -e` was very helpfully. Now I use the import structure `package.subpackage.module` -> `epipy.model.sir`. – Sam Jan 09 '16 at 05:38
1

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 :-)

Moshe Vayner
  • 738
  • 1
  • 8
  • 23