23

I'm using Python 3.4, and having created a pyvenv, I'm looking to activate it from within a python process. With virtualenv, I used to use activate_this.py, but that appears to be gone in pyvenv.

Is there now an easy way to effectively change the current interpreter to the virtualenv interpreter? I could probably mess around with the PATH (which is what activate_this.py did), but I'd like a simpler and stabler way.

This is for use in a wsgi.py.

David Heffernan
  • 587,191
  • 41
  • 1,025
  • 1,442
Chris Cooper
  • 16,826
  • 9
  • 51
  • 70
  • Yes, the activation script depends on your platform: https://docs.python.org/3/library/venv.html – Simeon Visser Dec 13 '14 at 19:13
  • 1
    Also, activating within a Python process doesn't entirely make sense. You can only activate a virtualenv and then afterwards use the Python interpreter that belongs to that virtualenv. – Simeon Visser Dec 13 '14 at 19:19
  • I think if you read here, you'll see why it makes sense: http://virtualenv.readthedocs.org/en/latest/virtualenv.html#using-virtualenv-without-bin-python This is the feature I'm looking for which appears to be gone in pyvenv. – Chris Cooper Dec 13 '14 at 19:35
  • Hmm, that's true. It could be a missing feature; Python 3.x isn't used much yet so it could be a legitimate missing feature. – Simeon Visser Dec 13 '14 at 20:28
  • Could be. I'll probably just end up messing with Apache's httpd.conf and try to point it at the right interpreter/python home. – Chris Cooper Dec 13 '14 at 20:49
  • 1
    @ChrisCooper the above link is broken. Which version of virtualenv? I got 12.1.0 and `activate_this.py` is there for me or I didn't get something right from your question. – Wtower Apr 24 '15 at 12:55
  • 2
    "Python 3.x isn't used much yet" That is definitely not true. – Harald Nordgren Jan 22 '17 at 19:30

2 Answers2

8

pyvenv and the venv module don't support this out of the box. The third party virtualenv package does support this using activate_this.py, but that feature was not included in the built-in venv module.

You could try to borrow a copy of activate_this.py from a virtualenv based environment; it seems to work, though I can't swear it will be perfect (venv/pyvenv uses some magic during startup; unclear if all of it is replicated via activate_this.py).

The virtualenv docs for it are out of date for Python 3 (they claim you use execfile, which doesn't exist). The Python 3 compatible alternative would be:

activator = 'some/path/to/activate_this.py'  # Looted from virtualenv; should not require modification, since it's defined relatively
with open(activator) as f:
    exec(f.read(), {'__file__': activator})

Nothing activate_this.py does is magical, so you could manually perform the same changes without looting from virtualenv (adjusting PATH, sys.path, sys.prefix, etc.), but borrowing makes it much simpler in this case.

ShadowRanger
  • 124,179
  • 11
  • 158
  • 228
  • Thanks, I looted it from [here](https://github.com/pypa/virtualenv/blob/master/virtualenv_embedded/activate_this.py) as [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv) did not seem to have one. – cardamom Jul 03 '17 at 17:35
0

I used a different approach used in virtualenv itself:

# the current Python interpreter is not from the virtual environment
file = __file__
if file.endswith('.pyc'):
    file = file[:-1]
venv_executable = PROJECT_DIR / 'venv' / 'bin' / 'python'
popen = subprocess.Popen([venv_executable, file] + sys.argv[1:])
raise SystemExit(popen.wait())
warvariuc
  • 53,721
  • 35
  • 166
  • 222