PYTHONPATH works in interactive mode but fails in script

Question:

Problem

I’ve been trying to run a python script which imports from the Foundation package:

from Foundation import ...

Whenever I try to run this I get the following error:
Terminal output

Things I’ve done:

I’ve installed the Foundation package and verified that it was installed in /usr/local/lib/python3.7/site-packages

I’ve added export PYTHONPATH='/usr/local/lib/python3.7/site-packages' to my .zshrc file.

When I go into interactive mode, sys.path includes /usr/local/lib/python3.7/site-packages and I can successfully import Foundation:

enter image description here

When I run the script using /usr/local/bin/python3.7, sys.path does not include /usr/local/lib/python3.7/site-packages and importing Foundation fails:

enter image description here

Does anyone know why this might be happening and/or how to fix this? Why does running this script have a different sys.path than running the same python executable in interactive mode?

(I know I could use sys.path.extend(desired path) or something like that but that’s not an ideal solution)

Asked By: griffin97

||

Answers:

First, you run Python as your user (say ~joe or whatever your UID is) but then you bring sudo to the table. And that’s where things starts to differ, because it will not inherit your environment. Simple test for you to replay (substitute python3 by whatever path/version you want):

$ python3
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', 
'/usr/lib/python3.10/lib-dynload', '/usr/lib/python3/dist-packages', 
'/usr/local/lib/python3.10/dist-packages', 
'/home/<USER>/.local/lib/python3.10/site-packages']

then the same but with sudo:

$ sudo python3
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', 
'/usr/lib/python3.10/lib-dynload', '/usr/lib/python3/dist-packages', 
'/usr/local/lib/python3.10/dist-packages']

To work this around you either need to ensure your superuser’s environment fits your needs or you feed python interpreter with needed value of PYTHONPATH on the fly:

$ sudo PYTHONPATH=/FOO/BAR python3
>>> import sys
>>> sys.path
['', '/FOO/BAR', '/usr/lib/python310.zip', '/usr/lib/python3.10', 
'/usr/lib/python3.10/lib-dynload', '/usr/lib/python3/dist-packages', 
'/usr/local/lib/python3.10/dist-packages']
Answered By: Marcin Orlowski
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.