Question

I want to revisit the question as specified in PYTHONPATH vs. sys.path. Basically it is concerned with developing a package like:

Project
    setup.py
    package
        __init__.py
        lib.py
        script.py

Assuming script.py does from package.lib import foo it does work when calling:

python -m package.script

from the directory where setup.py is sitting, but not when calling (on windows, CPython 2.7):

.\package\script.py

ImportError: No module named package

In first case when printing sys.path first entry is '', but in second case the first entry is the absolute path to where script.py is sitting. And of course in that case it does not know anything about package and the import fails. This will also be the case when double-clicking in Explorer.

The original stackoverflow question recommends package installation by setup.py develop. However, in current setuptools 3.5 (I am aware+confused of the distutils/setuptools renaming) this option is not even documented (I have setuptools 3.4.x, but did not try it).

Can anyone point out to me what the recommended ("… only obvious way to do it …") procedere is on windows (for CPython 2.7 but also having Python 3 in mind) for double-clicking the file and having it work. Relative imports?

Was it helpful?

Solution

The better way of doing this now is to use pip install with the -e option.

pip install -e .

It uses a directory with the setup.py file. The "." indicates this directory. This works the same way as the setuptools develop method.

I believe that the develop creates an egg link in your sight packages folder which points to the folder of the library. http://pythonhosted.org/setuptools/setuptools.html#develop-deploy-the-project-source-in-development-mode

python setup.py develop

I believe this is why you get the absolute path. There may be a conflict with a develop link and an install. Things could have also been moved.

For double clicking just have something that checks sys.argv. If there is no value for sys.argv[1] append build, install, or develop.

In addition, I've always heard that you want to import the modules then call the functions from the modules. from package import lib. lib.foo() that way you know where the method came from. I believe the import does the same thing for both ways; this may clean up your import. Python pathing and packaging can be a pain.

from package import lib
lib.foo()

OTHER TIPS

You may want to carefully read the module search path documentation. Note that the search path will include "the directory containing the input script (or the current directory)". When you invoke python -m package.script, the current directory is used since there is no input script (script.py is used as a module). When you run .\package\script.py, it ads .\package to the search path.

A solution to your situation is to put all executable scripts in the base directory of your library hierarchy. I.e. move script.py up one directory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top