Dependency Management
Managing dependencies correctly makes your project reproducible and safe.
Virtual Environments
A virtual environment is an isolated Python installation for your project.
Why Use Virtual Environments?
- Projects do not interfere with each other
- You control exact versions of every package
- Easy to recreate the same environment on any machine
Create with uv
uv venv
source .venv/bin/activate # Linux/Mac
Never install packages globally
Always use a virtual environment. Global installations cause version conflicts.
pyproject.toml
The central configuration file for modern Python projects:
[project]
name = "my-test-project"
version = "1.0.0"
description = "Test automation project"
requires-python = ">=3.12"
dependencies = [
"requests>=2.32.0",
"pydantic>=2.9.0",
"pytest>=8.3.0",
]
[project.optional-dependencies]
dev = [
"ruff>=0.8.0",
"mypy>=1.13.0",
"pytest-cov>=6.0.0",
"pre-commit>=4.0.0",
]
Managing Dependencies with uv
Add a Dependency
uv add requests # production dependency
uv add --dev ruff mypy # development dependency
Remove a Dependency
uv remove requests
Update Dependencies
uv lock --upgrade # update all
uv lock --upgrade-package requests # update one
Install All Dependencies
uv sync # install production + dev
uv sync --no-dev # install production only
Lockfile (uv.lock)
The lockfile pins exact versions of every package (including transitive dependencies).
| Without Lockfile | With Lockfile |
|---|---|
| Different versions on different machines | Same versions everywhere |
| "Works on my machine" problems | Reproducible builds |
| Unexpected updates can break things | Controlled updates |
Rules
- Always commit
uv.lockto Git - Never commit
.venv/folder - Never edit
uv.lockmanually
.gitignore for Python
.venv/
__pycache__/
*.pyc
.mypy_cache/
.ruff_cache/
.pytest_cache/
htmlcov/
dist/
*.egg-info/
.env
Version Pinning
| Syntax | Meaning | Example |
|---|---|---|
>=2.0 |
At least 2.0 | requests>=2.32.0 |
>=2.0,<3.0 |
2.x only | pydantic>=2.9.0,<3.0 |
~=2.32 |
Compatible release | requests~=2.32.0 |
Use >= for most dependencies
The lockfile handles exact pinning. In pyproject.toml, use flexible ranges.
Python Version Management
uv can also manage Python versions:
uv python install 3.12 # install Python 3.12
uv python list # list available versions
uv python pin 3.12 # set project Python version
Best Practices
- Always use virtual environments
- Use
uvfor dependency management (fast, modern) - Commit
uv.lockto version control - Never commit
.venv/ - Keep
pyproject.tomlas the single source of project configuration - Update dependencies regularly but carefully
- Use separate dev dependencies for development tools
- Set
requires-pythonto specify minimum Python version