2

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?

Community
  • 1
  • 1
nepix32
  • 3,012
  • 2
  • 14
  • 29
  • For more about how sys.path works, see this answer http://stackoverflow.com/a/38403654/850326 – djhaskin987 Jul 15 '16 at 20:18
  • for "no module named" error: http://stackoverflow.com/questions/23417941/python-import-error-no-module-named-does-exist/40883739#40883739 – JinSnow Nov 30 '16 at 08:45

2 Answers2

2

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()
justengel
  • 6,132
  • 4
  • 26
  • 42
  • I've tried `develop` and is exactly what I wanted (also works for double-clicking). Downside is that it requires a `setup.py` (which I do not need otherwise because PyInstaller uses `.spec`files).Thanks for pointing out the location in `setuptools` documentation. – nepix32 May 09 '14 at 19:14
  • Regarding `pip install -e .`: for me it did not work **without** a `setup.py`. What do you mean with: "… does not use a setup.py, but a directory …"? – nepix32 May 13 '14 at 08:17
  • 1
    @nepix32 Sorry, I had that wrong. I meant to say that you don't call the setup.py file or the setup methods directly. The directory must have a setup.py file. – justengel May 13 '14 at 11:56
  • I figured something like that already :) Remains the last quuestion: When doing `pip uninstall %mypackage%`, is there something wich will remove the directory `%mypackage%.egg-info` also ? – nepix32 May 13 '14 at 12:11
  • @nepix32 When I tried the uninstall methods they didn't work. Setuptools should also have a "python setup.py develop --uninstall", but that didn't work for me either. You can go in your lib/site-packages python folder and delete the egg-link file and remove the directory from "easy-install.pth" – justengel May 13 '14 at 12:18
  • Ok, this is interesting, because both `pip uninstall %mypackage%` and `setup.py develop --uninstall` did the necessary changes in `site-packages`, but left the `egg-info` in the developer package location (so basically the uninstall works, but leaves some files over in the developer package location). – nepix32 May 13 '14 at 12:31
1

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.

jrennie
  • 1,937
  • 12
  • 16