# How Virtual Environments Work

## Metadata
- Author: [[Tall, Snarky Canadian]]
- Full Title: How Virtual Environments Work
- Category: #articles
- URL: https://snarky.ca/how-virtual-environments-work/
## Highlights
- The configuration file is `pyvenv.cfg` and it lives at the top of your virtual environment directory (e.v. `.venv/pyvenv.cfg`). As of Python 3.11, it contains a few entries:
1. `home` (the directory where the executable used to create the virtual environment lives; `os.path.dirname([sys._base_executable](https://docs.python.org/3/c-api/init_config.html?highlight=base_executable#c.PyConfig.base_executable))`)
2. `include-system-packages` (should the global `site-packages` be included, effectively turning off isolation?)
3. `version` (the Python version down to the micro version, but not with the release level, e.g. `3.12.0`, but not `3.12.0a6`)
4. `executable` (the executable used to create the virtual environment; `os.path.realpath([sys._base_executable](https://docs.python.org/3/c-api/init_config.html?highlight=base_executable#c.PyConfig.base_executable))`)
5. `command` (the CLI command that could have recreated the virtual environment) ([View Highlight](https://read.readwise.io/read/01h5e3rv97r0y4q53jgkhhamaz))
- One interesting thing to note is `pyvenv.cfg` is **not** a valid INI file according to the [`configparser` module](https://docs.python.org/3/library/configparser.html#module-configparser) due to lacking any sections. To read fields in the file you are expected to use `line.partition("=")` and to strip the resulting key and value.
And that's all there is to a virtual environment! When you don't install `pip` they are extremely fast to create: 3 files, a symlink, and a single file. And they are simple enough you can probably create one manually. ([View Highlight](https://read.readwise.io/read/01h5e3rzqeexd8w3zhbgm1cwct))
- How Python uses a virtual environment
During start-up, Python automatically calls the [`site.main()` function](https://docs.python.org/3/library/site.html#site.main) (unless you specify the `-S` flag). That function calls `[site.venv()](https://github.com/python/cpython/blob/90f1d777177e28b6c7b8d9ba751550e373d61b0a/Lib/site.py#L487)` which handles setting up your Python executable to use the virtual environment appropriately. Specifically, the `site` module:
1. Looks for `pyvenv.cfg` in either the same or parent directory as the running executable (which is **not** resolved, so the location of the symlink is used)
2. Looks for `include-system-site-packages` in `pyvenv.cfg` to decide whether the system `site-packages` ends up on `sys.path`
3. Sets `sys._home` if `home` is found in `pyvenv.cfg` (`sys._home` is used by `sysconfig`) ([View Highlight](https://read.readwise.io/read/01h5e3s401wbw8m8xf44r9hh1v))