source .venv/bin/activate doesn't do anything magical — it just prepends .venv/bin to your shell's PATH, so the next time you type python or pip, the shell finds the venv's copies first.
Every venv gets its own pip binary at creation time, pointed at its own site-packages directory. This is why "pip install" behaves completely differently depending on activation — it's literally a different pip executable, not a mode switch.
IsolationFor pip install requests, pip reads any version constraint given, checks what's already installed in this venv, and begins building a dependency resolution problem — requests itself depends on urllib3, certifi, charset-normalizer, idna.
The resolver's job is to find a single set of package versions that satisfies every constraint simultaneously — requests' pin on urllib3, any pin in your own requirements.txt, etc. — before a single byte is downloaded.
Checkpointpip queries pypi.org (or a configured private index/mirror) for available versions and metadata of each required package, over HTTPS.
Indexpip prefers a prebuilt wheel (.whl) matching your Python version/OS/architecture — no compilation needed. If no matching wheel exists, it falls back to a source distribution (sdist) that must be built locally.
DownloadIf a wheel wasn't available, pip invokes the package's build backend (commonly setuptools) to compile it locally — this is where missing system libraries or a missing C compiler cause install failures that a wheel would have avoided entirely.
BuildThe package's actual Python files are unpacked into .venv/lib/python3.x/site-packages/ — this is precisely the directory that ends up on sys.path for anything run inside the activated venv.
pip writes a *.dist-info directory recording exactly which files were installed and the package version — this is what makes pip uninstall and pip list reliable later.
Run the identical command with no venv activated, and PATH resolves to the system pip instead — installing into the global/user site-packages, potentially affecting every other project (or requiring sudo, or being blocked by an externally-managed-environment guard on modern distros).
Global Path| Term | Meaning |
|---|---|
| venv | An isolated Python environment with its own interpreter symlink, pip, and site-packages |
| PATH | Ordered list of directories the shell searches to resolve a command name |
| Wheel (.whl) | Prebuilt, ready-to-install package format — no local compilation needed |
| Sdist | Source distribution — must be built locally if no matching wheel exists |
| site-packages | The directory inside a venv (or global install) where installed packages live |
| Resolver | pip's component that finds a version set satisfying all dependency constraints |
| dist-info | Metadata directory pip writes per package, recording installed files & version |
| requirements.txt | A plain list of version constraints fed into the resolver on install |
| PyPI | The default public package index pip queries (pypi.org) |
| externally-managed-environment | Modern Linux guard blocking global pip installs outside a venv |