Lesson 4 of 9 · 20m
Virtual Environments and pyproject.toml
Why every project gets its own venv, what pyproject.toml replaced, and how a real project is laid out.
Every Python developer's first production bug is a dependency conflict: Project A needs requests==2.28, Project B needs requests==2.31, and installing one breaks the other because they share a global site-packages. A virtual environment is a per-project Python install — its own interpreter, its own packages. Nothing outside it, nothing shared.
The workflow everyone actually uses
python -m venv .venv # create the isolated environment
source .venv/bin/activate # enter it (Windows: .venv\Scriptsctivate)
pip install requests # installs INTO .venv, not globally
python -c "import requests" # uses the venv's copy
deactivate # leave.venv/ goes in .gitignore — it is a local artifact, reproducible from your dependency list. The project travels; the environment is rebuilt on each machine.
pyproject.toml is the project's file
[project]
name = "sudosec-tools"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"requests>=2.31,<3",
"rich>=13",
]
[project.optional-dependencies]
dev = ["pytest", "ruff", "mypy"]One file now holds everything setup.py, requirements.txt, setup.cfg, and MANIFEST.in used to scatter across. pip install -e ".[dev]" installs your package in editable mode plus the dev tools — the standard first command on any clone.
A project that scales past one file
mytool/
pyproject.toml
README.md
src/mytool/__init__.py
src/mytool/cli.py
tests/test_mytool.pyThe src/ layout forces you to test the installed package, not whatever happens to be in the working directory — the classic "works on my machine" bug where a dev accidentally imports their uninstalled local copy.
Try it yourself
// The pyproject idea in JS terms — one manifest for deps + dev deps:
const project = { deps: ["requests>=2.31"], dev: ["pytest", "ruff", "mypy"] };
console.log("One file:", Object.keys(project).join(", "));The rule
One venv per project, src/ layout, pyproject.toml as the single manifest. Anything else is debt.