I am writing and running Python programs on a machine that I don't have much control over. The global environment has Python 3.6 installed along with dozens of packages. There are many scripts available to me in that environment that I need to be able to run.
I run most of the scripts I develop in a Python 3.9 virtual environment. It is not practical to install the dozens of packages from the Py3.6 global environment into my venv, but I do want to be able to run some of the scripts that were designed for the 3.6 environment from my own 3.9 scripts.
I don't need to interact with the 3.6 script I'm running. I want to print the output as it is generated, and then process any files it produces.
This is basically what I want to do, although it doesn't actually work:
def run36 (scriptname):
p = subprocess.Popen("deactivate;", "python3", scriptname, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, universal_newlines=True)
for l in p.stdout():
print(l.rstrip())
return p.returncode
run36("some36prog.py") # will generate somenewfile.txt
with open("somenewfile.txt") as f:
...
If the correct answer is that I need to explicitly call the Python3.6 executable to make this work, I need to be able to discover its path somehow without hard coding it.
Just use the absolute path to the global interpreter. Or, if you just need the python version, create another virtualenv and use the interpreter in there.
For example
# create a Python3.6 virtualenv
python3.6 -m venv venv36
# use the python3.6 interpreter from code running with python3.12
python3.12 -c "import subprocess; subprocess.run(['venv36/bin/python', 'some_script.py'])"