[python] Permanently add a directory to PYTHONPATH?

Whenever I use sys.path.append, the new directory will be added. However, once I close python, the list will revert to the previous (default?) values. How do I permanently add a directory to PYTHONPATH?

This question is related to python windows pythonpath

The answer is


You could add the path via your pythonrc file, which defaults to ~/.pythonrc on linux. ie.

import sys
sys.path.append('/path/to/dir')

You could also set the PYTHONPATH environment variable, in a global rc file, such ~/.profile on mac or linux, or via Control Panel -> System -> Advanced tab -> Environment Variables on windows.


To give a bit more explanation, Python will automatically construct its search paths (as mentioned above and here) using the site.py script (typically located in sys.prefix + lib/python<version>/site-packages as well as lib/site-python). One can obtain the value of sys.prefix:

python -c 'import sys; print(sys.prefix)'

The site.py script then adds a number of directories, dependent upon the platform, such as /usr/{lib,share}/python<version>/dist-packages, /usr/local/lib/python<version>/dist-packages to the search path and also searches these paths for <package>.pth config files which contain specific additional search paths. For example easy-install maintains its collection of installed packages which are added to a system specific file e.g on Ubuntu it's /usr/local/lib/python2.7/dist-packages/easy-install.pth. On a typical system there are a bunch of these .pth files around which can explain some unexpected paths in sys.path:

python -c 'import sys; print(sys.path)'

So one can create a .pth file and put in any of these directories (including the sitedir as mentioned above). This seems to be the way most packages get added to the sys.path as opposed to using the PYTHONPATH.

Note: On OSX there's a special additional search path added by site.py for 'framework builds' (but seems to work for normal command line use of python): /Library/Python/<version>/site-packages (e.g. for Python2.7: /Library/Python/2.7/site-packages/) which is where 3rd party packages are supposed to be installed (see the README in that dir). So one can add a path configuration file in there containing additional search paths e.g. create a file called /Library/Python/2.7/site-packages/pip-usr-local.pth which contains /usr/local/lib/python2.7/site-packages/ and then the system python will add that search path.


If you're using bash (on a Mac or GNU/Linux distro), add this to your ~/.bashrc

export PYTHONPATH="${PYTHONPATH}:/my/other/path"

Just to add on awesomo's answer, you can also add that line into your ~/.bash_profile or ~/.profile


Shortest path between A <-> B is a straight line;

import sys
if not 'NEW_PATH' in sys.path:
  sys.path += ['NEW_PATH']

In Python 3.6.4 you can persist sys.path across python sessions like this:

import sys
import os

print(str(sys.path))

dir_path = os.path.dirname(os.path.realpath(__file__))
print(f"current working dir: {dir_path}")

root_dir = dir_path.replace("/util", '', 1)
print(f"root dir: {root_dir}")

sys.path.insert(0, root_dir)

print(str(sys.path))

I strongly suggest you use virtualenv and virtualenvwrapper otherwise you will clutter your path


In case anyone is still confused - if you are on a Mac, do the following:

  1. Open up Terminal
  2. Type open .bash_profile
  3. In the text file that pops up, add this line at the end: export PYTHONPATH=$PYTHONPATH:foo/bar
  4. Save the file, restart the Terminal, and you're done

This works on Windows

  1. On Windows, with Python 2.7 go to the Python setup folder.
  2. Open Lib/site-packages.
  3. Add an example.pth empty file to this folder.
  4. Add the required path to the file, one per each line.

Then you'll be able to see all modules within those paths from your scripts.


Inspired by andrei-deusteanu answer, here is my version. This allows you to create a number of additional paths in your site-packages directory.

import os

# Add paths here.  Then Run this block of code once and restart kernel. Paths should now be set.
paths_of_directories_to_add = [r'C:\GIT\project1', r'C:\GIT\project2', r'C:\GIT\project3']

# Find your site-packages directory
pathSitePckgs = os.path.join(os.path.dirname(os.__file__), 'site-packages')

# Write a .pth file in your site-packages directory
pthFile = os.path.join(pathSitePckgs,'current_machine_paths.pth')
with open(pthFile,'w') as pth_file:
    pth_file.write('\n'.join(paths_of_directories_to_add))

print(pthFile)

The script below works on all platforms as it's pure Python. It makes use of the pathlib Path, documented here https://docs.python.org/3/library/pathlib.html, to make it work cross-platform. You run it once, restart the kernel and that's it. Inspired by https://medium.com/@arnaud.bertrand/modifying-python-s-search-path-with-pth-files-2a41a4143574. In order to run it it requires administrator privileges since you modify some system files.

from pathlib import Path
to_add=Path(path_of_directory_to_add)
from sys import path

if str(to_add) not in path:
    minLen=999999
    for index,directory in enumerate(path):
        if 'site-packages' in directory and len(directory)<=minLen:
            minLen=len(directory)
            stpi=index
            
    pathSitePckgs=Path(path[stpi])
    with open(str(pathSitePckgs/'current_machine_paths.pth'),'w') as pth_file:
        pth_file.write(str(to_add))

I added permanently in Windows Vista, Python 3.5

System > Control Panel > Advanced system settings > Advanced (tap) Environment Variables > System variables > (if you don't see PYTHONPATH in Variable column) (click) New > Variable name: PYTHONPATH > Variable value:

Please, write the directory in the Variable value. It is details of Blue Peppers' answer.


Adding export PYTHONPATH="${PYTHONPATH}:/my/other/path" to the ~/.bashrc might not work if PYTHONPATH does not currently exist (because of the :).

export PYTHONPATH="/my/other/path1"
export PYTHONPATH="${PYTHONPATH}:/my/other/path2"

Adding the above to my ~/.bashrc did the trick for me on Ubuntu 16.04


On MacOS, Instead of giving path to a specific library. Giving full path to the root project folder in

~/.bash_profile 

made my day, for example:

export PYTHONPATH="${PYTHONPATH}:/Users/<myuser>/project_root_folder_path"

after this do:

source ~/.bash_profile

Instead of manipulating PYTHONPATH you can also create a path configuration file. First find out in which directory Python searches for this information:

python -m site --user-site

For some reason this doesn't seem to work in Python 2.7. There you can use:

python -c 'import site; site._script()' --user-site

Then create a .pth file in that directory containing the path you want to add (create the directory if it doesn't exist).

For example:

# find directory
SITEDIR=$(python -m site --user-site)

# create if it doesn't exist
mkdir -p "$SITEDIR"

# create new .pth file with our path
echo "$HOME/foo/bar" > "$SITEDIR/somelib.pth"

For me it worked when I changed the .bash_profile file. Just changing .bashrc file worked only till I restarted the shell.

For python 2.7 it should look like:

export PYTHONPATH="$PYTHONPATH:/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"

at the end of the .bash_profile file.


The add a new path to PYTHONPATH is doing in manually by:

adding the path to your ~/.bashrc profile, in terminal by:

vim ~/.bashrc

paste the following to your profile

export PYTHONPATH="${PYTHONPATH}:/User/johndoe/pythonModule"

then, make sure to source your bashrc profile when ever you run your code in terminal:

source ~/.bashrc 

Hope this helps.


Fix Python Path issues when you switch from bash to zsh

I ran into Python Path problems when I switched to zsh from bash.

The solution was simple, but I failed to notice.

Pip was showing me, that the scripts blah blah or package blah blah is installed in ~/.local/bin which is not in path.

After reading some solutions to this question, I opened my .zshrc to find that the solution already existed.

I had to simply uncomment a line:

Take a look

Screenshot from 2020-10-07 13-38-17


On linux you can create a symbolic link from your package to a directory of the PYTHONPATH without having to deal with the environment variables. Something like:

ln -s /your/path /usr/lib/pymodules/python2.7/

This is an update to this thread which has some old answers.

For those using MAC-OS Catalina or some newer (>= 10.15), it was introduced a new Terminal named zsh (a substitute to the old bash).

I had some problems with the answers above due to this change, and I somewhat did a workaround by creating the file ~/.zshrc and pasting the file directory to the $PATH and $PYTHONPATH

So, first I did:

nano ~/.zshrc

When the editor opened I pasted the following content:

export PATH="${PATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"
export PYTHONPATH="${PYTHONPATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"

saved it, and restarted the terminal.

IMPORTANT: The path above is set to my computer's path, you would have to adapt it to your python.


Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to windows

"Permission Denied" trying to run Python on Windows 10 A fatal error occurred while creating a TLS client credential. The internal error state is 10013 How to install OpenJDK 11 on Windows? I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? git clone: Authentication failed for <URL> How to avoid the "Windows Defender SmartScreen prevented an unrecognized app from starting warning" XCOPY: Overwrite all without prompt in BATCH Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory how to open Jupyter notebook in chrome on windows Tensorflow import error: No module named 'tensorflow'

Examples related to pythonpath

sys.path different in Jupyter and Python - how to import own modules in Jupyter? Effect of using sys.path.insert(0, path) and sys.path(append) when loading modules PYTHONPATH on Linux How to configure custom PYTHONPATH with VM and PyCharm? How to get the PYTHONPATH in shell? adding directory to sys.path /PYTHONPATH set pythonpath before import statements Why use sys.path.append(path) instead of sys.path.insert(1, path)? Import Error: No module named django django import error - No module named core.management