Search code examples
pythonsubprocessvirtualenvironment

Python calling subprocess that requires no virtual environment


I have a Python 3.6 script that calls out to a third-party tool using subprocess.

main_script.py:

#!/usr/bin/env python
import subprocess
result = subprocess.run(['third-party-tool', '-arg1'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

The problem is, main_script.py must be run from within a virtual environment, and third-party-tool must be run from no virtual environment whatsoever.

I don't know much about third-party-tool, except that it is on my path. Calling it while I have a virtual environment active causes it to jam up and throw an exception later on. I do not know if it uses the default python binary or it it spins up its own virtual env and does stuff in there. It is not a Python script, but apparently calls one somehow.

How do I tell subprocess to drop out of my virtual environment and run the command in the default shell environment?

I've examined a couple of similar questions:


Solution

  • From the documentation of subprocess:

    https://docs.python.org/3/library/subprocess.html

    The accepted args are

    subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None,
        capture_output=False, shell=False, cwd=None, timeout=None, check=False,
        encoding=None, errors=None, text=None, env=None, universal_newlines=None)
    

    In particular,

    If env is not None, it must be a mapping that defines the environment variables for the new process; these are used instead of the default behavior of inheriting the current process’ environment. It is passed directly to Popen.

    Thus, passing an empty dictionary env={} (start with empty environment) and using bash --login (run as login shell, which reads env defaults) should do the trick.

    subprocess.run(['bash', '--login', '-c', '/full/path/to/third-party-tool', '-arg1'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={})