Learning Notes #71 β pyproject.toml
In the evolving Python ecosystem, pyproject.toml
has emerged as a pivotal configuration file, streamlining project management and enhancing interoperability across tools.
In this blog i delve deep into the significance, structure, and usage of pyproject.toml
.
What is pyproject.toml
?
Introduced in PEP 518, pyproject.toml
is a standardized file format designed to specify build system requirements and manage project configurations. Its primary goal is to provide a unified, tool-agnostic approach to project setup, reducing the clutter of multiple configuration files.
Why Use pyproject.toml
?
- Standardization: Offers a consistent way to define project metadata, dependencies, and build tools.
- Interoperability: Supported by various tools like Poetry, Flit, Black, isort, and even pip.
- Simplification: Consolidates multiple configuration files (like
setup.cfg
,requirements.txt
) into one. - Future-Proofing: As Python evolves,
pyproject.toml
is becoming the de facto standard for project configurations, ensuring compatibility with future tools and practices.
Structure of pyproject.toml
The pyproject.toml
file uses the TOML format, which stands for βTomβs Obvious, Minimal Language.β TOML is designed to be easy to read and write while being simple enough for parsing by tools.
1. [build-system]
Defines the build system requirements. Essential for tools like pip to know how to build the project.
[build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta"
requires
: Lists the build dependencies required to build the project. These packages are installed in an isolated environment before the build process starts.
build-backend
: Specifies the backend responsible for building the project. Common backends include:
setuptools.build_meta
(for traditional Python projects)flit_core.buildapi
(for projects managed with Flit)poetry.core.masonry.api
(for Poetry projects)
2. [tool]
This section is used by third-party tools to store their configuration. Each tool manages its own sub-table under [tool]
.
Example with Black (Python code formatter):
[tool.black] line-length = 88 target-version = ["py38"] include = '\.pyi?$' exclude = ''' /( \.git | \.mypy_cache | \.venv | build | dist )/ '''
line-length
: Sets the maximum line length for code formatting.target-version
: Specifies the Python versions the code should be compatible with.include
/exclude
: Regular expressions to define which files Black should format.
Example with isort (import sorter)
[tool.isort] profile = "black" line_length = 88 multi_line_output = 3 include_trailing_comma = true
profile
: Allows easy integration with formatting tools like Black.multi_line_output
: Controls how imports are wrapped.include_trailing_comma
: Ensures trailing commas in multi-line imports.
3. [project]
Introduced in PEP 621, this section standardizes project metadata, reducing reliance on setup.py
.
[project] name = "my-awesome-project" version = "0.1.0" description = "An awesome Python project" readme = "README.md" requires-python = ">=3.8" authors = [ { name="Syed Jafer K", email="syed@example.com" } ] dependencies = [ "requests>=2.25.1", "fastapi" ] license = { file = "LICENSE" } keywords = ["python", "awesome", "project"] classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent" ]
name
,version
,description
: Basic project metadata.readme
: Path to the README file.requires-python
: Specifies compatible Python versions.authors
: List of project authors.dependencies
: Project dependencies.license
: Specifies the projectβs license.keywords
: Helps with project discovery in package repositories.classifiers
: Provides metadata for tools like PyPI to categorize the project.
4. Optional scripts
and entry-points
Define CLI commands:
[project.scripts] mycli = "my_module:main"
scripts
: Maps command-line scripts to Python functions, allowing users to runmycli
directly after installing the package.
Tools That Support pyproject.toml
- Build tools: Poetry, Flit, setuptools
- Linters/Formatters: Black, isort, Ruff
- Test frameworks: Pytest (via
addopts
) - Package managers: Pip (PEP 517/518 compliant)
- Documentation tools: Sphinx
Migration Tips
- Gradual Migration: Move one configuration at a time to avoid breaking changes.
- Backwards Compatibility: Keep older config files during transition if needed.
- Testing: Use CI pipelines to ensure the new configuration doesnβt break the build.
Troubleshooting Common Issues
- Build Failures with Pip: Ensure
build-system.requires
includes all necessary build tools. - Incompatible Tools: Check for the latest versions of tools to ensure
pyproject.toml
support. - Configuration Errors: Validate your TOML file with online validators like TOML Lint.
Further Reading:
- PEP 518: Specifying Minimum Build System Requirements
- PEP 621: Standardizing Project Metadata
- TOML Documentation