I am using subprocess.Popen
to call an external Python script from my installed Application, bundled using PyInstaller.
The format of this command is something like this:
subprocess.Popen(["/usr/bin/python", "/path/to/exe/SDK.py"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=False)
I have successfully tested this on both Windows and MacOS - both can run the external script. However, on other Posix OS' I get the following error:
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
ImportError: No module named site
Now, I realize that this question has been asked before, and generally it is down to PYTHONHOME
having an incorrect value. However, if I run the command in a format similar to:
PYTHONHOME=/usr /usr/bin/python /path/to/exe/SDK.py
I get no errors in the logs, but the script SDK.py doesn't execute.
Therefore to prove that this isn't an issue with my script; I installed my own version of Python onto the machine - after doing this, the script executed successfully. I tested with both /usr/bin/python
and /home/vagrant/Python-2.7.15/python
, without needing to specify a PYTHONHOME
in the subprocess command.
However, I still need to allow users to execute the SDK.py script using the built in, OS version of Python.
So to do this I have tried these other things:
- Using
sys.executable
in thesubprocess.Popen
call to execute SDK.py.
(The value of which was: /opt/program_name/lib/program_name
)
Forcing
PYTHONPATH
&PYTHONHOME
to be empty by explicitly setting the environment:import os env = os.environ.copy() env['PYTHONHOME'] = '' env['PYTHONPATH'] = '' subprocess.Popen(["/usr/bin/python", "/path/to/exe/SDK.py"], env=env)
Can anyone explain how I can call the system version of Python from an external subprocess like this?
EDIT: Output when calling Python in verbose mode (from the CLI):
>>> from sys import executable
>>> executable
'/usr/bin/python'
>>> import _csv
# trying _csv.so
# trying _csvmodule.so
# trying _csv.py
# trying _csv.pyc
# trying /usr/lib64/python2.7/_csv.so
# trying /usr/lib64/python2.7/_csvmodule.so
# trying /usr/lib64/python2.7/_csv.py
# trying /usr/lib64/python2.7/_csv.pyc
# trying /usr/lib64/python2.7/plat-linux2/_csv.so
# trying /usr/lib64/python2.7/plat-linux2/_csvmodule.so
# trying /usr/lib64/python2.7/plat-linux2/_csv.py
# trying /usr/lib64/python2.7/plat-linux2/_csv.pyc
# trying /usr/lib64/python2.7/lib-dynload/_csv.so
dlopen("/usr/lib64/python2.7/lib-dynload/_csv.so", 2);
import _csv # dynamically loaded from /usr/lib64/python2.7/lib-dynload/_csv.so