Schütze
Schütze

Reputation: 1084

Altering PYTHONPATH at runtime and using a subprocess with a new PYTHONPATH

I would like to alter my PYTHONPATH at runtime (using Python 2), put a new PYTHONPATH, execute a subprocess and run my specific code which requires Python3, and then set it back to what it was.

Here is the logic I came up with:

# save the current PYTHONPATH to a variable
pythonpath = os.environ["PYTHONPATH"]
print('PYTHONPATH (Before Execution): ', pythonpath)

# alter the PYTHONPATH
# append or insert would not be the best
# but rather emptying it and putting the new `PYTHONPATH` each time 

# use the following
# subp.Popen("")
# subp.call("") : python3 mycode.py -i receivedImgPath", shell=True
# to call the code with the new PYTHONPATH


# after the code execution is done, set the PYTHONPATH to back
# since we have saved it, use directly the variable pythonpath

Is there someone who has done something similar? Is my logic correct?

P.S: I know there are threads like In Python script, how do I set PYTHONPATH? but they only give information about appending or inserting, which does not work with my logic.

Upvotes: 1

Views: 745

Answers (1)

tripleee
tripleee

Reputation: 189317

subprocess conveniently lets you pass in a separate environment to the subprocess.

envcopy = os.environ.copy()

# Add '/home/hovercraft/eels' to the start of
# PYTHONPATH in the new copy of the environment
envcopy['PYTHONPATH'] = '/home/hovercraft/eels' + ':' + os.environ['PYTHONPATH']

# Now run a subprocess with env=envcopy
subprocess.check_call(
    ['python3', 'mycode.py', '-i', 'receivedImgPath'],
    env=envcopy)

We are modifying a copy, so the PYTHONPATH of the parent process remains at its original value.

If you need a really simple environment, perhaps all you require is

subprocess.check_call(command,
    env={'PYTHONPATH': '/home/myself/env3/lib'})

Modern Python code should prefer (Python 3.5+ subprocess.run over) subprocess.check_call over subprocess.call (over subprocess.Popen over various legacy cruft like os.system); but I am guessing you are stuck on Python 2.x. For (much!) more, see https://stackoverflow.com/a/51950538/874188

Upvotes: 1

Related Questions