How to determine if Python is running inside a virtualenv?

The reliable and documented way is to compare sys.prefix and sys.base_prefix. If they’re equal, you’re not in a virtual environment, otherwise you are. Inside a venv, sys.prefix points to the directory of the virtual environment, and sys.base_prefix to the Python interpreter used to create the environment.

This is documented under How venvs work:

It is sufficient to check sys.prefix != sys.base_prefix to determine if the current interpreter is running from a virtual environment.

This works for Python stdlib venv and for virtualenv (since version 20):

def in_venv():
    return sys.prefix != sys.base_prefix

Older versions of virtualenv used sys.real_prefix instead of sys.base_prefix, and sys.real_prefix did not exist outside a virtual environment. In Python 3.3 and earlier sys.base_prefix did not ever exist. So a check that also handles some legacy cases could look like this:

import sys

def get_base_prefix_compat():
    """Get base/real prefix, or sys.prefix if there is none."""
    return (
        getattr(sys, "base_prefix", None)
        or getattr(sys, "real_prefix", None)
        or sys.prefix

def in_virtualenv():
    return sys.prefix != get_base_prefix_compat()

Using the VIRTUAL_ENV environment variable is not reliable. It is set by the virtualenv activate shell script, but a virtualenv can be used without activation by directly running an executable from the virtualenv’s bin/ (or Scripts) directory, in which case $VIRTUAL_ENV will not be set. Or a non-virtualenv Python binary can be executed directly while a virtualenv is activated in the shell, in which case $VIRTUAL_ENV may be set in a Python process that is not actually running in that virtualenv.

Leave a Comment