Python Best Practices

Chapter 1 · Practice 3 of 5

Describe the project in pyproject.toml

From Versions, environments and project setup

Why it matters

pyproject.toml is the standard place for a project's metadata, dependencies and tool settings. It replaces setup.py, setup.cfg and most tool-specific config files.

The Python Packaging User Guide recommends:

  • Always include a [build-system] table, copied from your build backend's docs.
  • Declare runtime dependencies in [project], and feature extras in [project.optional-dependencies].
  • Set requires-python to your minimum version, and think twice before adding an upper bound.
  • Use an SPDX expression such as "MIT" for license; the old table format is deprecated.

Keep dev-only tools such as pytest and Ruff in a dependency group, so they never ship with the package.

Example

TOML
[project]
name = "orders-service"
version = "1.4.0"
requires-python = ">=3.14"
license = "MIT"
dependencies = ["httpx>=0.28", "pydantic>=2.11"]

[dependency-groups]
dev = ["pytest>=9", "ruff", "mypy"]

[project.scripts]
orders = "orders.cli:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"