| ############# |
| Explanation |
| ############# |
| |
| This page explains the design decisions and concepts behind virtualenv. It focuses on understanding why things work the |
| way they do. |
| |
| ************************** |
| virtualenv vs venv vs uv |
| ************************** |
| |
| Since Python 3.3, the standard library includes the ``venv`` module, which provides basic virtual environment creation |
| following `PEP 405 <https://www.python.org/dev/peps/pep-0405/>`_. `uv <https://docs.astral.sh/uv/pip/environments/>`_ is |
| a newer, Rust-based tool that also creates virtual environments via ``uv venv``. |
| |
| virtualenv occupies a middle ground: faster and more featureful than ``venv``, while remaining a pure Python solution |
| with a plugin system for extensibility. |
| |
| .. list-table:: |
| :header-rows: 1 |
| :widths: 20 27 27 26 |
| |
| - - |
| - ``venv`` |
| - ``virtualenv`` |
| - `uv <https://docs.astral.sh/uv/>`_ |
| - - Performance |
| - Slowest (60s+); spawns `pip <https://pip.pypa.io>`_ as a subprocess to seed. |
| - Fast; caches pre-built install images, subsequent creation < 1 second. |
| - Fastest; Rust implementation, milliseconds. Does not seed pip/setuptools by default. |
| - - Extensibility |
| - No plugin system. |
| - Plugin system for discovery, creation, seeding, and activation. |
| - No plugin system. |
| - - Cross-version |
| - Only the Python version it runs under. |
| - Any installed Python via auto-discovery (registry, uv-managed, PATH). |
| - Any installed or uv-managed Python. |
| - - Upgradeability |
| - Tied to Python releases. |
| - Independent via `PyPI <https://pypi.org/project/virtualenv/>`_. |
| - Independent via its own release cycle. |
| - - Programmatic API |
| - Basic ``create()`` function only. |
| - Full Python API; can describe environments without creating them. Used by `tox <https://tox.readthedocs.io>`_, |
| `poetry <https://python-poetry.org/>`_, `pipx <https://pipx.pypa.io>`_, etc. |
| - Command line only. |
| - - Type annotations |
| - No ``py.typed`` marker; limited annotations. |
| - Fully typed with :PEP:`561` ``py.typed`` marker; checked by `ty <https://docs.astral.sh/ty/>`_. |
| - Not applicable (Rust binary). |
| - - Best for |
| - Zero dependencies, basic needs. |
| - Plugin extensibility, programmatic API, tool compatibility (`tox <https://tox.readthedocs.io>`_, |
| `virtualenvwrapper <https://virtualenvwrapper.readthedocs.io>`_). |
| - Maximum speed, already using ``uv`` for package management. |
| |
| .. mermaid:: |
| |
| flowchart TD |
| A{Need plugins or programmatic API?} -->|Yes| V[virtualenv] |
| A -->|No| B{Already using uv?} |
| B -->|Yes| U[uv venv] |
| B -->|No| C{Can install external tools?} |
| C -->|Yes| D{Speed matters?} |
| C -->|No| VENV[venv] |
| D -->|Yes| U |
| D -->|No| V |
| |
| style A fill:#d97706,stroke:#b45309,color:#fff |
| style B fill:#d97706,stroke:#b45309,color:#fff |
| style C fill:#d97706,stroke:#b45309,color:#fff |
| style D fill:#d97706,stroke:#b45309,color:#fff |
| style V fill:#16a34a,stroke:#15803d,color:#fff |
| style U fill:#2563eb,stroke:#1d4ed8,color:#fff |
| style VENV fill:#7c3aed,stroke:#6d28d9,color:#fff |
| |
| *************************** |
| Supported Python versions |
| *************************** |
| |
| virtualenv distinguishes between the **host** interpreter (the Python running virtualenv itself) and the **target** |
| interpreter (the Python for which the virtual environment is created). When ``--python`` is not specified, the host and |
| target are the same interpreter. |
| |
| Host interpreter |
| ================ |
| |
| virtualenv requires CPython or PyPy **3.9 or later** as the host interpreter. This is enforced by ``requires-python >= |
| 3.9`` in the package metadata. |
| |
| Target interpreter |
| ================== |
| |
| The target interpreter can differ from the host. virtualenv can create virtual environments for any Python interpreter |
| it can discover on the system, provided a matching creator exists. |
| |
| .. list-table:: |
| :header-rows: 1 |
| :widths: 20 15 65 |
| |
| - - Implementation |
| - Platforms |
| - Notes |
| - - CPython |
| - Linux, macOS, Windows |
| - 3.9+. Free-threaded builds supported on 3.13+. Includes macOS framework, Homebrew, Microsoft Store, and Windows |
| debug build support. |
| - - PyPy |
| - Linux, macOS, Windows |
| - 3.9+. |
| - - GraalPy |
| - Linux, macOS, Windows |
| - 24.1+. Minimal test coverage, marked experimental. |
| - - RustPython |
| - Linux, macOS, Windows |
| - Minimal test coverage, marked experimental. |
| |
| Seed packages (``pip``, ``setuptools``) are bundled for CPython 3.9 through 3.16. A target newer than the highest |
| bundled version reuses the newest bundle. A target older than the oldest bundled version has no compatible bundled |
| wheel, so the bundled seeders refuse it before the environment is created; pass ``--no-seed`` for an empty environment, |
| or select a seeder that ships wheels for that version. |
| |
| ********************** |
| How virtualenv works |
| ********************** |
| |
| Python packaging often faces a fundamental problem: different applications require different versions of the same |
| library. If Application A needs ``requests==2.25.1`` but Application B needs ``requests==2.28.0``, installing both into |
| the global site-packages directory creates a conflict. Only one version can exist in a given location. |
| |
| virtualenv solves this by creating isolated Python environments. Each environment has its own installation directories |
| and can maintain its own set of installed packages, independent of other environments and the system Python. |
| |
| virtualenv operates in two distinct phases: |
| |
| .. mermaid:: |
| |
| flowchart TD |
| Start([virtualenv command]) --> Phase1[Phase 1: Python Discovery] |
| Phase1 --> Discover{Find Python interpreter} |
| Discover -->|Default| SameVersion[Use virtualenv's own Python] |
| Discover -->|--python flag| CustomVersion[Use specified Python] |
| CustomVersion --> Phase2[Phase 2: Environment Creation] |
| SameVersion --> Phase2 |
| Phase2 --> CreatePython[Create Python matching target interpreter] |
| CreatePython --> SeedPackages[Install seed packages: pip, setuptools, wheel] |
| SeedPackages --> ActivationScripts[Install activation scripts] |
| ActivationScripts --> VCSIgnore[Create VCS ignore files] |
| VCSIgnore --> Complete([Virtual environment ready]) |
| |
| style Start fill:#2563eb,stroke:#1d4ed8,color:#fff |
| style Phase1 fill:#6366f1,stroke:#4f46e5,color:#fff |
| style Phase2 fill:#6366f1,stroke:#4f46e5,color:#fff |
| style Complete fill:#16a34a,stroke:#15803d,color:#fff |
| style Discover fill:#d97706,stroke:#b45309,color:#fff |
| |
| **Phase 1: Discover a Python interpreter** |
| virtualenv first identifies which Python interpreter to use as the template for the virtual environment. By default, |
| it uses the same Python version that virtualenv itself is running on. You can override this with the ``--python`` |
| flag to specify a different interpreter. |
| |
| **Phase 2: Create the virtual environment** |
| Once the target interpreter is identified, virtualenv creates the environment in four steps: |
| |
| 1. Create a Python executable matching the target interpreter |
| 2. Install seed packages (pip, setuptools, wheel) to enable package installation |
| 3. Install activation scripts for various shells |
| 4. Create VCS ignore files (currently Git's ``.gitignore``, skip with ``--no-vcs-ignore``) |
| |
| An important design principle: virtual environments are not self-contained. A complete Python installation consists of |
| thousands of files, and copying all of them into every virtual environment would be wasteful. Instead, virtual |
| environments are lightweight shells that borrow most content from the system Python. They contain only what's needed to |
| redirect Python's behavior. |
| |
| This design has two implications: |
| |
| - Environment creation is fast because only a small number of files need to be created. |
| - Upgrading the system Python might affect existing virtual environments, since they reference the system Python's |
| standard library and binary extensions. |
| |
| The Python executable in a virtual environment is effectively isolated from the one used to create it, but the |
| supporting files are shared. |
| |
| .. warning:: |
| |
| If you upgrade your system Python, existing virtual environments will still report the old version (the version |
| number is embedded in the Python executable itself), but they will use the new version's standard library and binary |
| extensions. This normally works without issues, but be aware that the environment is effectively running a hybrid of |
| old and new Python versions. |
| |
| ****************** |
| Python discovery |
| ****************** |
| |
| Before creating a virtual environment, virtualenv must locate a Python interpreter. The interpreter determines the |
| virtual environment's Python version, implementation (CPython, PyPy, etc.), and architecture (32-bit or 64-bit). |
| |
| The ``--python`` flag accepts several specifier formats: |
| |
| **Path specifier** |
| An absolute or relative path to a Python executable, such as ``/usr/bin/python3.14`` or ``./python``. |
| |
| **Version specifier** |
| A string following the format ``{implementation}{version}{architecture}{machine}`` where: |
| |
| - Implementation is alphabetic characters (``python`` means any implementation; if omitted, defaults to ``python``). |
| - Version is dot-separated numbers, optionally followed by ``t`` for free-threading builds. |
| - Architecture is ``-64`` or ``-32`` (if omitted, means any architecture). |
| - Machine is the CPU instruction set architecture, e.g. ``-arm64``, ``-x86_64``, ``-aarch64`` (if omitted, means any |
| machine). Cross-platform aliases are normalized automatically (``amd64`` ↔ ``x86_64``, ``aarch64`` ↔ ``arm64``). |
| |
| Examples: |
| |
| - ``python3.14.1`` - Any Python implementation with version 3.14.1 |
| - ``3`` - Any Python implementation with major version 3 |
| - ``3.13t`` - Any Python implementation version 3.13 with free-threading enabled |
| - ``cpython3`` - CPython implementation with major version 3 |
| - ``pypy2`` - PyPy implementation with major version 2 |
| - ``cpython3.12-64-arm64`` - CPython 3.12, 64-bit, ARM64 architecture |
| - ``3.11-64-x86_64`` - Any implementation, version 3.11, 64-bit, x86_64 architecture |
| - ``rustpython`` - RustPython implementation |
| |
| **PEP 440 version specifier** |
| Version constraints using PEP 440 operators: |
| |
| - ``>=3.12`` - Any Python 3.12 or later |
| - ``~=3.11.0`` - Compatible with Python 3.11.0 |
| - ``cpython>=3.10`` - CPython 3.10 or later |
| |
| When you provide a specifier, virtualenv searches for matching interpreters using this strategy: |
| |
| .. mermaid:: |
| |
| flowchart TD |
| Start([Python specifier provided]) --> Windows{Running on Windows?} |
| Windows -->|Yes| Registry[Check Windows Registry per PEP-514] |
| Windows -->|No| UVManaged |
| Registry --> RegistryMatch{Match found?} |
| RegistryMatch -->|Yes| Found([Use matched Python]) |
| RegistryMatch -->|No| UVManaged[Check uv-managed Python installations] |
| UVManaged --> UVMatch{Match found?} |
| UVMatch -->|Yes| Found |
| UVMatch -->|No| PATH[Search PATH for matching executable] |
| PATH --> PATHMatch{Match found?} |
| PATHMatch -->|Yes| Found |
| PATHMatch -->|No| NotFound([Discovery fails]) |
| |
| style Start fill:#2563eb,stroke:#1d4ed8,color:#fff |
| style Found fill:#16a34a,stroke:#15803d,color:#fff |
| style NotFound fill:#dc2626,stroke:#b91c1c,color:#fff |
| style Windows fill:#d97706,stroke:#b45309,color:#fff |
| style RegistryMatch fill:#d97706,stroke:#b45309,color:#fff |
| style UVMatch fill:#d97706,stroke:#b45309,color:#fff |
| style PATHMatch fill:#d97706,stroke:#b45309,color:#fff |
| |
| 1. **Windows Registry** (Windows only): Check registered Python installations per `PEP 514 |
| <https://www.python.org/dev/peps/pep-0514/>`_. |
| 2. **uv-managed installations**: Check the ``UV_PYTHON_INSTALL_DIR`` environment variable or platform-specific uv Python |
| directories for managed Python installations. |
| 3. **PATH search**: Search for executables on the ``PATH`` environment variable with names matching the specification. |
| |
| Version manager shim resolution |
| =============================== |
| |
| Version managers like `pyenv <https://github.com/pyenv/pyenv>`_, `mise <https://mise.jdx.dev/>`_, and `asdf |
| <https://asdf-vm.com/>`_ place lightweight shim scripts on ``PATH`` that delegate to the real Python binary. When |
| virtualenv discovers a Python interpreter by running it as a subprocess, shims may resolve to the wrong Python version |
| (typically the system Python) because the shim's resolution logic depends on shell environment state that doesn't fully |
| propagate to child processes. |
| |
| virtualenv detects shims by checking whether the candidate executable lives in a known shim directory |
| (``$PYENV_ROOT/shims``, ``$MISE_DATA_DIR/shims``, or ``$ASDF_DATA_DIR/shims``). When a shim is detected, virtualenv |
| bypasses it and locates the real binary directly under the version manager's ``versions`` directory, using the active |
| version from: |
| |
| 1. The ``PYENV_VERSION`` environment variable (colon-separated for multiple versions). |
| 2. A ``.python-version`` file in the current directory or any parent directory. |
| 3. The global version file at ``$PYENV_ROOT/version``. |
| |
| This convention is shared across pyenv, mise, and asdf, so the same resolution logic works for all three. |
| |
| .. warning:: |
| |
| Virtual environments typically reference the system Python's standard library. If you upgrade the system Python, the |
| virtual environment will report the old version (embedded in its Python executable) but will actually use the new |
| version's standard library content. This can cause confusion when debugging version-specific behavior. |
| |
| If you use a virtual environment's Python as the target for creating another virtual environment, virtualenv will |
| detect the system Python version and create an environment matching the actual (upgraded) version, not the version |
| reported by the virtual environment. |
| |
| ********** |
| Creators |
| ********** |
| |
| Creators are responsible for constructing the virtual environment structure. virtualenv supports two types of creators: |
| |
| **venv creator** |
| This creator delegates the entire creation process to the standard library's ``venv`` module, following `PEP 405 |
| <https://www.python.org/dev/peps/pep-0405/>`_. The venv creator requires spawning a subprocess to invoke the venv |
| module, unless virtualenv is installed in the system Python. |
| |
| The subprocess overhead can be significant, especially on Windows where process creation is expensive. |
| |
| **builtin creator** |
| This creator means virtualenv performs the creation itself by knowing exactly which files to create and which system |
| files to reference. The builtin creator is actually a family of specialized creators for different combinations of |
| Python implementation (CPython, PyPy, GraalPy, RustPython) and platform (Windows, POSIX). The name ``builtin`` is an |
| alias that selects the first available builtin creator for the target environment. |
| |
| Because builtin creators don't require subprocess invocation, they're generally faster than the venv creator. |
| |
| .. mermaid:: |
| |
| flowchart TD |
| Start([Select creator]) --> Builtin{Builtin creator available?} |
| Builtin -->|Yes| UseBuiltin([Use builtin creator - faster, no subprocess]) |
| Builtin -->|No| UseVenv([Use venv creator - delegates to stdlib]) |
| |
| style Start fill:#2563eb,stroke:#1d4ed8,color:#fff |
| style UseBuiltin fill:#16a34a,stroke:#15803d,color:#fff |
| style UseVenv fill:#7c3aed,stroke:#6d28d9,color:#fff |
| style Builtin fill:#d97706,stroke:#b45309,color:#fff |
| |
| virtualenv defaults to using the builtin creator if one is available for the target environment, falling back to the |
| venv creator otherwise. |
| |
| ********* |
| Seeders |
| ********* |
| |
| After creating the virtual environment structure, virtualenv installs seed packages that enable package management |
| within the environment. The seed packages are: |
| |
| - ``pip`` - The package installer for Python (always installed). |
| - ``setuptools`` - Package development and installation library (disabled by default on Python 3.12+). |
| |
| virtualenv supports two seeding methods with dramatically different performance characteristics: |
| |
| **pip seeder** |
| This method uses the bundled pip wheel to install seed packages by spawning a child pip process. The subprocess |
| performs a full installation, including unpacking wheels and generating metadata. This method is reliable but slow, |
| typically consuming 98% of the total virtual environment creation time. |
| |
| **app-data seeder** |
| This method creates reusable install images in a user application data directory. The first time you create an |
| environment with specific seed package versions, the app-data seeder builds complete install images and stores them |
| in the cache. Subsequent environment creations simply link or copy these pre-built images into the virtual |
| environment's ``site-packages`` directory. |
| |
| Performance comparison for creating virtual environments: |
| |
| .. mermaid:: |
| |
| xychart-beta horizontal |
| title "Seeding time (seconds, lower is better)" |
| x-axis ["pip seeder (70s)", "app-data copy Win (8s)", "app-data symlink Win (0.8s)", "app-data symlink Linux/macOS (0.1s)"] |
| y-axis "Seconds" 0 --> 80 |
| bar [70, 8, 0.8, 0.1] |
| |
| On platforms that support symlinks efficiently (Linux, macOS), the app-data seeder provides nearly instant seeding. |
| |
| You can override the cache location using the ``VIRTUALENV_OVERRIDE_APP_DATA`` environment variable. |
| |
| .. _wheels: |
| |
| Wheel acquisition |
| ================= |
| |
| Both seeding methods require wheel files for the seed packages. virtualenv acquires wheels using a priority system: |
| |
| .. mermaid:: |
| |
| flowchart TD |
| Start([Need wheel file]) --> Embedded{Found in embedded wheels?} |
| Embedded -->|Yes| UseEmbedded([Use embedded wheel]) |
| Embedded -->|No| Upgraded{Found in upgraded wheels?} |
| Upgraded -->|Yes| UseUpgraded([Use upgraded wheel]) |
| Upgraded -->|No| Extra{Found in extra-search-dir?} |
| Extra -->|Yes| UseExtra([Use extra wheel]) |
| Extra -->|No| Download{Download enabled?} |
| Download -->|Yes| DownloadPyPI([Download from PyPI]) |
| Download -->|No| Fail([Seeding fails]) |
| |
| style Start fill:#2563eb,stroke:#1d4ed8,color:#fff |
| style UseEmbedded fill:#16a34a,stroke:#15803d,color:#fff |
| style UseUpgraded fill:#16a34a,stroke:#15803d,color:#fff |
| style UseExtra fill:#16a34a,stroke:#15803d,color:#fff |
| style DownloadPyPI fill:#16a34a,stroke:#15803d,color:#fff |
| style Fail fill:#dc2626,stroke:#b91c1c,color:#fff |
| style Embedded fill:#d97706,stroke:#b45309,color:#fff |
| style Upgraded fill:#d97706,stroke:#b45309,color:#fff |
| style Extra fill:#d97706,stroke:#b45309,color:#fff |
| style Download fill:#d97706,stroke:#b45309,color:#fff |
| |
| **Embedded wheels** |
| virtualenv ships with a set of wheels bundled directly into the package. These are tested with the virtualenv |
| release and provide a baseline set of seed packages. Different Python versions require different package versions, |
| so virtualenv bundles multiple wheels to support its wide Python version range. |
| |
| **Upgraded embedded wheels** |
| Users can manually upgrade the embedded wheels by running virtualenv with the ``--upgrade-embed-wheels`` flag. This |
| fetches newer versions of seed packages from PyPI and stores them in the user application data directory. Subsequent |
| virtualenv invocations will use these upgraded wheels instead of the embedded ones. |
| |
| virtualenv can also perform periodic automatic upgrades (see below). |
| |
| **Extra search directories** |
| Users can specify additional directories containing wheels using the ``--extra-search-dir`` flag. This is useful in |
| air-gapped environments or when using custom package builds. |
| |
| **PyPI download** |
| If no suitable wheel is found in the above locations, or if the ``--download`` flag is set, virtualenv will use pip |
| to download the latest compatible version from PyPI. |
| |
| Periodic update mechanism |
| ========================= |
| |
| To keep the seed packages reasonably current without requiring users to manually upgrade virtualenv or run |
| ``--upgrade-embed-wheels``, virtualenv implements a periodic automatic update system: |
| |
| .. mermaid:: |
| |
| timeline |
| title Periodic update safety gates |
| section PyPI release |
| Package published : New wheel available on PyPI |
| section 28-day wait |
| Day 1-28 : Wheel is too new, ignored by virtualenv |
| section Check interval |
| Every 14 days : virtualenv checks for eligible wheels |
| section 1-hour hold |
| After download : Wheel downloaded but not yet used |
| +1 hour : Wheel becomes active for new environments |
| |
| The 28-day waiting period protects users from automatically adopting newly released packages that might contain bugs. |
| The 1-hour delay after download ensures continuous integration systems don't start using different package versions |
| mid-run, which could cause confusing test failures. |
| |
| You can disable the periodic update mechanism with the ``--no-periodic-update`` flag. |
| |
| .. _distribution_wheels: |
| |
| Distribution maintainer patching |
| ================================ |
| |
| Operating system distributions and package managers sometimes need to customize which seed package versions virtualenv |
| uses. They want to align virtualenv's bundled packages with system package versions. |
| |
| Distributions can patch the ``virtualenv.seed.wheels.embed`` module, replacing the ``get_embed_wheel`` function with |
| their own implementation that returns distribution-provided wheels. If they want to use virtualenv's test suite for |
| validation, they should also provide the ``BUNDLE_FOLDER``, ``BUNDLE_SUPPORT``, ``MIN``, ``MAX``, and |
| ``OLDEST_SUPPORTED`` variables. ``OLDEST_SUPPORTED`` (the parsed form of ``MIN``) sets the floor below which the bundled |
| seeders refuse to seed, so a distribution that bundles wheels for an older Python must lower it to match. |
| |
| Distributions should also consider patching ``virtualenv.seed.embed.base_embed.PERIODIC_UPDATE_ON_BY_DEFAULT`` to |
| ``False``, allowing the system package manager to control seed package updates rather than virtualenv's periodic update |
| mechanism. Users can still manually request upgrades via ``--upgrade-embed-wheels``, but automatic updates won't |
| interfere with system-managed packages. |
| |
| ************ |
| Activators |
| ************ |
| |
| Activation scripts modify the current shell environment to prioritize the virtual environment's executables. This is |
| purely a convenience mechanism - you can always use absolute paths to virtual environment executables without |
| activating. |
| |
| What activation does: |
| |
| .. mermaid:: |
| |
| flowchart TD |
| Before([Before activation]) --> ModifyPATH[Prepend venv/bin to PATH] |
| ModifyPATH --> SetVENV[Set VIRTUAL_ENV variable] |
| SetVENV --> SetPROMPT[Set VIRTUAL_ENV_PROMPT variable] |
| SetPROMPT --> SetPKG[Set PKG_CONFIG_PATH] |
| SetPKG --> ModifyPrompt[Modify shell prompt] |
| ModifyPrompt --> After([After activation]) |
| |
| style Before fill:#2563eb,stroke:#1d4ed8,color:#fff |
| style After fill:#16a34a,stroke:#15803d,color:#fff |
| style ModifyPATH fill:#6366f1,stroke:#4f46e5,color:#fff |
| style SetVENV fill:#6366f1,stroke:#4f46e5,color:#fff |
| style SetPROMPT fill:#6366f1,stroke:#4f46e5,color:#fff |
| style SetPKG fill:#6366f1,stroke:#4f46e5,color:#fff |
| style ModifyPrompt fill:#6366f1,stroke:#4f46e5,color:#fff |
| |
| **PATH modification** |
| The activation script prepends the virtual environment's ``bin`` directory (``Scripts`` on Windows) to the ``PATH`` |
| environment variable. This ensures that when you run ``python``, ``pip``, or other executables, the shell finds the |
| virtual environment's versions first. |
| |
| **Environment variables** |
| Activation sets several environment variables: |
| |
| - ``VIRTUAL_ENV`` - Absolute path to the virtual environment directory. |
| - ``VIRTUAL_ENV_PROMPT`` - The prompt prefix (the environment name or custom value from ``--prompt``). |
| - ``PKG_CONFIG_PATH`` - Modified to include the virtual environment's ``lib/pkgconfig`` directory. |
| |
| **Prompt modification** |
| By default, activation prepends the environment name to your shell prompt, typically shown as ``(venv)`` before the |
| regular prompt. This visual indicator helps you remember which environment is active. You can customize this with |
| the ``--prompt`` flag when creating the environment, or disable it entirely by setting the |
| ``VIRTUAL_ENV_DISABLE_PROMPT`` environment variable. |
| |
| **Deactivation** |
| Activation scripts also provide a ``deactivate`` command that reverses the changes, restoring your original PATH and |
| removing the environment variables and prompt modifications. |
| |
| virtualenv provides activation scripts for multiple shells: |
| |
| - `Bash <https://www.gnu.org/software/bash/>`_ (``activate``) |
| - `Fish <https://fishshell.com/>`_ (``activate.fish``) |
| - `Csh/Tcsh <https://www.tcsh.org/>`_ (``activate.csh``) |
| - `PowerShell <https://learn.microsoft.com/en-us/powershell/>`_ (``activate.ps1``) |
| - `Windows Batch <https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmd>`_ |
| (``activate.bat``) |
| - `Nushell <https://www.nushell.sh/>`_ (``activate.nu``) |
| - Python (``activate_this.py``) -- for programmatic activation from within a running Python process, see |
| :ref:`how-to/usage:Programmatic activation` |
| |
| .. note:: |
| |
| On Windows 7 and later, PowerShell's default execution policy is ``Restricted``, which prevents running the |
| ``activate.ps1`` script. You can allow locally-generated scripts to run by changing the execution policy: |
| |
| .. code-block:: powershell |
| |
| Set-ExecutionPolicy RemoteSigned |
| |
| Since virtualenv generates ``activate.ps1`` locally for each environment, PowerShell considers it a local script |
| rather than a remote one and allows execution under the ``RemoteSigned`` policy. |
| |
| Remember: activation is optional. The following commands are equivalent: |
| |
| .. code-block:: console |
| |
| # With activation |
| source venv/bin/activate |
| python script.py |
| deactivate |
| |
| # Without activation |
| venv/bin/python script.py |
| |
| For a deeper dive into how activation works under the hood, see Allison Kaptur's blog post `There's no magic: virtualenv |
| edition <https://www.recurse.com/blog/14-there-is-no-magic-virtualenv-edition>`_, which explains how virtualenv uses |
| ``PATH`` and ``PYTHONHOME`` to isolate virtual environments. |
| |
| ********** |
| See also |
| ********** |
| |
| - :doc:`how-to/usage` - Practical guides for common virtualenv tasks. |
| - :doc:`reference/cli` - Complete CLI reference documentation. |