60

I am trying to make a module discoverable on a system where I don't have write access to the global site-packages directory, and without changing the environment (PYTHONPATH). I have tried to place a .pth file in the same directory as a script I'm executing, but it seems to be ignored. E.g., I created a file extras.pth with the following content:

N:\PythonExtras\lib\site-packages

But the following script, placed and run in the same directory, prints False.

import sys
print r"N:\PythonExtras\lib\site-packages" in sys.paths

The only directory in sys.path to which I have write access is the directory containing the script. Is there another (currently non-existent) directory where I could place extras.pth and have it be seen? Is there a better way to go about this?

I'm using python 2.7 on Windows. All .pth questions I could find here use the system module directories.

Edit: I've tracked down the Windows per-user installation directory, at %APPDATA%\Python\Python27\site-packages. I can place a module there and it will be imported, but if I put a .pth file there, it has no effect. Is this really not supposed to work, or am I doing something wrong?

alexis
  • 48,685
  • 16
  • 101
  • 161

2 Answers2

75

As described in the documentation, PTH files are only processed if they are in the site-packages directory. (More precisely, they are processed if they are in a "site directory", but "site directory" itself is a setting global to the Python installation and does not depend on the current directory or the directory where the script resides.)

If the directory containing your script is on sys.path, you could create a sitecustomize.py in that directory. This will be loaded when Python starts up. Inside sitecustomize.py, you can do:

import site
site.addsitedir('/some/dir/you/want/on/the/path')

This will not only add that directory, but will add it as a "site directory", causing PTH files there to be processed. This is handy if you want to create your own personal site-packages-like-directory.

If you only need to add one or two directories to the path, you could do so more simply. Just create a tiny Python library that manipulates sys.path, and then import that library from your script. Something like:

# makepath.py
import sys
sys.path.append('/whatever/dir/you/want')

# script.py
import makepath

Edit: Again, according to the documentation, there is the possibility of a site-specific directory in %APPDATA%\Python\PythonXY\site-packages (on Windows). You could try that, if in fact you have write access to that (and not just to your script directory).

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • The problem is that this is for teaching a class, and I'm trying to make it work as close to transparently as possible. People are always starting a new python and running into trouble. Aren't there some folders under `Documents and Settings` that count as "site directories"? IIRC various installers will put stuff there-- but not sure where, or if they're examined for `.pth` files. – alexis Mar 04 '13 at 19:18
  • Yes, there is, and it's documented along with everything else at http://docs.python.org/2/library/site.html#site.USER_SITE . I thought you said you had write access only to the script directory, but I see now I misread. – BrenBarn Mar 04 '13 at 19:28
  • Yes thanks, I'm figuring out that `site.html` is the place to look. However, putting a `.pth` there doesn't seem to be working... – alexis Mar 04 '13 at 19:43
  • @alexis: Works fine for me. Are you sure you got the directory name right (and restarted Python, if you were testing this interactively)? Also, are you sure the PTH you're putting in that directory has the right stuff in it? – BrenBarn Mar 04 '13 at 19:53
  • I was afraid of that... I checked thoroughly, but if it works for you I'll triple-check. – alexis Mar 04 '13 at 20:22
  • Yes! I was trying to import an egg, and they play additional games with their own `.pth` (which is not read recursively, grrr..). So this problem is solved, but I'm not out of the woods yet... – alexis Mar 04 '13 at 20:26
  • 1
    **Clarification:** Your solution will not work (even appending to `sys.path`) if the path in question contains eggs. That was the real source of my problem. For regular modules, it works fine. Perhaps you can clarify for future readers (or if you know how to resolve this, I'd be even happier ;-)) – alexis Mar 04 '13 at 20:28
  • 1
    I think for eggs you're supposed to add the egg itself as a path, not the directory containing it. But yes, in any case I wouldn't assume that things that work for regular modules work for eggs. In general you should probably mention if you're working with eggs instead of just regular installed modules, as eggs are a bit peculiar in some ways (as you discovered). – BrenBarn Mar 04 '13 at 20:31
  • Grate description! Used it on a linux server where I only have `/usr/local/` write access: set my `PYTHONPATH` to `/usr/local/lib/pythonXY/site-packages`; create a `sitecustomize.py` with import site; site.addsitedir('.'). Works like a charm, now I can install in `/usr/local/` modules that are packaged assuming to be installed in `/usr/` – Davide Nov 29 '13 at 13:44
  • Fix: site.addsitedir('.') should be site.addsitedir('/usr/local/lib/pythonXY/site-packages'), or things will not work as expected. – Davide Nov 29 '13 at 14:42
  • After installing python in Windows and modified the environment variable `path`, I create three files `__init__.py`, `main.py` and `sitecustomize.py` (with a print('foo') inside). After try run `python main` I can't get `foo` so, are you sure 'sitecustomize.py' run when path `sitecustomize.py` is inside `sys.path` ? (I printed `sys.path` to check if paht to `main.py` is inside and I fact it is there). – rvcristiand Jul 28 '21 at 04:49
  • @rvcristiand: If you're having difficulty, probably best to ask a separate question where you can explain your setup more completely. – BrenBarn Jul 28 '21 at 06:21
-4

You can make a .pth (path) file in a directory already in sys.path so it can be included/

Wool
  • 17
  • 6
  • 4
    Not according to the accepted answer. Can you point to a place in the documentation that supports your claim? – alexis Jan 05 '19 at 19:49
  • I've been having a problem with venv settings after installing opencv - seems to have affected all of my venv's so I'm guessing some global has changed. Readin the documentation here https://docs.python.org/3.7/install/index.html#modifying-python-s-search-path paragraph 3 it clearly say you can add a .pth file to any directory on the python path: "The most convenient way is to add a path configuration file to a directory that’s already on Python’s path, usually to the .../site-packages/ directory." I've done that and you're right it doesn't work! maybe you could help with my interpretation? – creativemateriel Apr 10 '19 at 12:38
  • @alexis The code responsible for loading these files is /usr/lib/python3.7/site.py (depends on your platform and python version). I'm read a bit and I am not sure. Not all entry in sys.path are made equal. I think only the python install directory and site-packages are looked up for .pth files. – Adrien H Aug 22 '19 at 08:18