pyproject.toml: The Project Contract
intermediate14 min readLesson 101 of 169
Metadata, dependencies, and build config in one standardized file.
Every modern Python project declares itself in pyproject.toml (TOML โ
read it in the sandbox with tomllib):
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "tasknoter"
version = "0.1.0"
description = "A typed, tested task manager"
requires-python = ">=3.12"
dependencies = []
[project.scripts]
tasknoter = "tasknoter.cli:main"
What each block promises:
- build-system โ which tool turns this into an installable package (setuptools here; alternatives exist).
- project โ identity: name, version, supported Python, and dependencies with version constraints (
requests>=2.31,<3). - project.scripts โ console commands to generate (next lesson).
requires-python is a promise to your users: the tool refuses to install on
older interpreters. Versioning your own project with semver-like bumps
(0.1.0 โ 0.2.0 for features, +0.0.1 for fixes) is the cheapest coordination
tool you will ever adopt.
On your own machine, pip install -e . installs the project in editable
mode โ the sandbox can't run pip (no network), so this course verifies the
file is well-formed instead.