I've installed IPython globally with the distro's package manager. When I launch it from a virtual environment I get the message UserWarning: Attempting to work in a virtualenv. …
. I've tried to use the methods described by florisla on Determine if Python is running inside virtualenv to figure out whether it's working properly. The piece of code I'm actually running is slightly modified to print out all the booleans when run:
# 1) VIRTUAL_ENV environment variable
# Both 'virtualenv' and 'venv' set the environment variable '$VIRTUAL_ENV' when activating an environment. See PEP 405.
# You can read out this variable in shell scripts, or use this Python code to determine if it's set.
import os
running_in_virtualenv = "VIRTUAL_ENV" in os.environ
# alternative ways to write this, also supporting the case where
# the variable is set but contains an empty string to indicate
# 'not in a virtual environment':
running_in_virtualenv1a = bool(os.environ.get("VIRTUAL_ENV"))
running_in_virtualenv1b = bool(os.getenv("VIRTUAL_ENV"))
# The problem is, this only works when the environment is activated by the 'activate' shell script.
# You can start the environment's scripts without activating the environment, so if that is a concern, you have to use a different method.
print("1a:", running_in_virtualenv1a)
print("1b:", running_in_virtualenv1b)
# 2) sys.real_prefix and sys.base_prefix
# Virtualenv points 'sys.prefix' to the Python installed inside of the virtualenv as you would expect.
# At the same time, the original value of 'sys.prefix' is also made available as a new attribute of 'sys': 'sys.real_prefix'. This is what we're using to detect if we're in a virtualenv.
import sys
running_in_virtualenv = hasattr(sys, "real_prefix")
# There's a problem though: 'venv' and 'pyvenv' do this differently from 'virtualenv' -- they don't set 'real_prefix'. Instead, they set 'base_prefix' to a different value from 'sys.prefix'.
# So to be safe, check both as suggested in hroncok's answer:
import sys
virtualenv_prefix = getattr(sys, "real_prefix", None)
venv_prefix = getattr(sys, "base_prefix", sys.prefix)
running_in_virtualenv2 = virtualenv_prefix or venv_prefix != sys.prefix
print("2:", running_in_virtualenv2)
Now, if I run this code from outside of a virtual environment I get three False
both with the python3
shell and ipython3
, but if I'm in a virtual environment, IPython returns False
for the last boolean (running_in_virtualenv2
), while python3
returns True
for all of them.
Can I still tinker within my virtual enviroment, using IPython, without risk of messing up the system installation?