For some functional tests, I invoke a couple of utilities directly from the project directory, using Python's subprocess.call
(or check_call
which invokes the latter). This works well when the libraries (PyYAML in particular) are installed globally. Running in a virtualenv, such as under Travis-CI, causes problems, especially if the virtualenv is running Python 3.x and the global Python is 2.7.
If both Pythons are 2.7, I still had to inject the location of PyYAML within the virtualenv, using the env
argument to subprocess.call
, in order not to cause an ImportError. However, this doesn't work when the virtualenv is 3.x. It appears the invoked utility runs outside the virtualenv because its sys.path
looks as follows:
'/home/travis/build/jmafc/Pyrseas/pyrseas', '/usr/local/lib/python2.7/dist-packages/distribute-0.6.35-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/pip-1.3.1-py2.7.egg', '/home/travis/build/jmafc/Pyrseas', '/home/travis/virtualenv/python3.3/lib/python3.3/site-packages', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info', '/usr/lib/python2.7/dist-packages']
Notice the mixture of 2.7 and 3.3 paths, the latter being expressly injected as mentioned above.
Is there some way from either virtualenv
or in the subprocess
functions to ensure the subprocess runs "within" the virtualenv?
If you pass in a copy of your environment variables and use the current Python interpreter as the target of the subprocess, the virtualenv environment should be preserved. Something like this:
subprocess.call([sys.executable, 'yourscript.py'], env=os.environ.copy())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With