35

When organising python project, this structure seems to be a standard way of doing it:

myproject\
    bin\
        myscript
    mypackage\
        __init__.py
        core.py
    tests\
        __init__.py
        mypackage_tests.py
setup.py

My question is, how do I import my core.py so I can use it in myscript?

both __init__.py files are empty.

Content of myscript:

#!/usr/bin/env python
from mypackage import core
if __name__ == '__main__':
    core.main()

Content of core.py

def main():
    print 'hello'

When I run myscript from inside myproject directory, I get the following error:

Traceback (most recent call last):
  File "bin/myscript", line 2, in <module>
    from mypackage import core
ImportError: No module named mypackage

What am I missing?

6
  • 1
    Your sys.path value (modified by the PYTHONPATH environment variable or at run time by Python code) determines where import will search for modules. Commented Jul 23, 2012 at 12:43
  • 2
    Consider using entry_points["console_scripts"]' in setup.py. Commented Jul 23, 2012 at 12:43
  • 1
    What are the contents of setup.py? And is it in the myproject directory? Commented Jul 23, 2012 at 12:44
  • Why not install your package (python setup.py etc) before running your script? Commented Jul 23, 2012 at 12:44
  • 10
    I'm in a development stage, so I'd rather not install it every time I make a change to see if it works. Commented Jul 23, 2012 at 13:03

4 Answers 4

8

Usually, setup.py should install the package in a place where the Python interpreter can find it, so after installation import mypackage will work. To facilitate running the scripts in bin right from the development tree, I'd usually simply add a simlink to ../mypackage/ to the bin directory. Of course, this requires a filesystem supporting symlinks…

Sign up to request clarification or add additional context in comments.

6 Comments

Using the symlink as you suggested, the script was able to find mypackage, but I've now run into another issue... See my edit above in the question.
Instead of using "clever" symlinks with development, use a virtualenv and run python setup.py develop to have distutils install the executable in your path (when you have activated that virtualenv)
Actually, I figured it out that other issue.
@TokenMacGuy: virtualenv seems like a good solution, I'll have to learn more about it.
@TokenMacGuy: I agree that virtualenv is the more flexible and robust solution. However, for simple situations (a single module or package), using a symlink always worked fine for me. The symlink is easier to set up and allows testing command-line tools without running python setup.py, so it also has its merits.
|
0

I'm not sure if there is a "best choice", but the following is my normal practice:

  1. Put whatever script I wanna run in /bin

  2. do "python -m bin.script" in the dir myproject

  3. When importing in script.py, consider the dir in which script.py is sitting as root. So

    from ..mypackage import core
    

If the system supports symlink, it's a better choice.

Comments

0

I usually add my bin path into $PYTHONPATH, that will enable python to look for asked module in bin directory too.

export PYTHONPATH=/home/username/bin:$PYTHONPATH
$ python
import module_from_bin

Comments

0

I solved the issue following setuptools specifications.

In setup.py you can specify the modules as an argument for the function setup():

packages = find_packages() 

This finds all modules.

p.s. you have to import this function: from setuptools import setup, find_packages

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.