Hi Pythonistas!
Python’s virtualenv (or venv in modern Python versions) is a powerful tool that allows you to create isolated environments for your projects. But how does it actually work? Let’s dive into the internals of virtualenv and understand what happens when you create and activate a virtual environment. If you are not familiar with virtualenv we have post on the basics
What is Virtualenv?
virtualenv is a tool that creates an isolated Python environment where you can install packages without affecting the system-wide Python installation. This helps in:
- Avoiding package version conflicts across projects.
- Preventing accidental modifications to system Python.
- Creating reproducible environments for deployment.
How Virtualenv is Created
When you create a virtual environment with:
python -m venv myenv
or using virtualenv
virtualenv myenv
it performs several key actions:
Creates a Directory Structure
A new folder (myenv/) is created, which contains:
myenv/
│── bin/ (or Scripts/ on Windows)
│ ├── python (or python.exe)
│ ├── pip
│ ├── activate
│── lib/ (or Lib/ on Windows)
│ ├── site-packages/
│── pyvenv.cfg
Let’s break it down:
bin/ (or Scripts/ on Windows) → Contains Python executables (python, pip, etc.).
lib/site-packages/ → Stores installed packages for this virtual environment.
pyvenv.cfg → A configuration file storing details about the environment, including the Python version used.
Copies the Python Executable
The python executable inside the virtual environment is not a full copy of Python but a symlink (on Unix) or a lightweight wrapper (on Windows). It ensures that Python runs within this isolated environment.
Sets Up site-packages
Normally, Python’s global packages are stored in /usr/lib/pythonX.X/site-packages. Virtualenv redirects package installation to the lib/site-packages/ folder inside myenv/, so dependencies remain project-specific.
What Happens During Activation?
When you run:
source myenv/bin/activate # macOS/Linux
myenv\Scripts\Activate # Windows PowerShell
the activation script does the following:
Modifies $PATH: Prepends myenv/bin/ (or myenv\Scripts\) to PATH, ensuring that python and pip point to the virtual environment’s versions.
Sets $VIRTUAL_ENV: Adds an environment variable to store the virtual environment’s location.
Changes the shell prompt: Displays (myenv) in the terminal as a reminder.
afsal@afsal:~/Desktop/experiments$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
afsal@afsal:~/Desktop/experiments$ echo $VIRTUAL_ENV
afsal@afsal:~/Desktop/experiments$ source myvenv/bin/activate
(myvenv) afsal@afsal:~/Desktop/experiments$ echo $PATH
/home/afsal/Desktop/experiments/myvenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
(myvenv) afsal@afsal:~/Desktop/experiments$ echo $VIRTUAL_ENV
/home/afsal/Desktop/experiments/myvenv
(myvenv) afsal@afsal:~/Desktop/experiments$
What Happens on Deactivation?
Running:
deactivate
Restores the original PATH.
Removes $VIRTUAL_ENV.
Resets the shell prompt.
(myvenv) afsal@afsal:~/Desktop/experiments$ deactivate
afsal@afsal:~/Desktop/experiments$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
afsal@afsal:~/Desktop/experiments$ echo $VIRTUAL_ENV
afsal@afsal:~/Desktop/experiments$
How Does Virtualenv Isolate Dependencies?
Any package installed via pip install inside the virtual environment goes into lib/site-packages/ instead of the global Python installation. Running python inside the virtual environment ensures that it only has access to the packages installed in the environment, avoiding conflicts with system-wide libraries.
To confirm, run:
afsal@afsal:~/Desktop/experiments$ which python3
/usr/bin/python3
afsal@afsal:~/Desktop/experiments$ source myvenv/bin/activate
(myvenv) afsal@afsal:~/Desktop/experiments$ which python3
/home/afsal/Desktop/experiments/myvenv/bin/python3
(myvenv) afsal@afsal:~/Desktop/experiments$
How Virtualenv Differs from System Python
Feature | System Python | Virtual Environment |
---|---|---|
Package Scope | Global | Project-specific |
Dependencies | Shared | Isolated |
Risk of Conflict | High | Low |
Requires Admin Privileges | Yes | No |
How to Delete a Virtual Environment
Since virtualenv is just a directory, deleting it is as simple as running:
rm -rf myenv # macOS/Linux
rmdir /s /q myenv # Windows
Virtualenv (or venv) works by creating an isolated directory, setting up a local Python binary, and modifying environment variables to ensure packages remain project-specific. This makes it an essential tool for Python development!