pyproject-metadata
pyproject-metadata is a Python library that provides a dataclass for parsing and validating project metadata according to PEP 621. It takes an already parsed Python dictionary (representing the `[project]` table from `pyproject.toml`) and validates it against the PEP 621 specification, subsequently generating PEP 643-compliant metadata (e.g., PKG-INFO). The current version is 0.11.0, and it generally follows a release cadence tied to advancements in Python packaging standards.
Warnings
- gotcha pyproject-metadata does NOT parse `pyproject.toml` files directly. It expects a pre-parsed Python dictionary corresponding to the `[project]` table. You must use a separate TOML parser (e.g., `tomli` for Python < 3.11 or `tomllib` for Python 3.11+) to read the `.toml` file first.
- gotcha By default, extra (non-standard) fields in the `[project]` table will issue a `pyproject_metadata.errors.ExtraKeyWarning`. If unhandled, this might be unexpected. You can configure this behavior during instantiation.
- gotcha When using `project.license` as a string (representing an SPDX expression) or `project.license-files`, it's recommended to additionally validate and normalize the license expression using a dedicated tool, such as `packaging.licenses.canonicalize_license_expression` (requires `packaging` 24.2+), as `pyproject-metadata` itself does not perform full SPDX validation.
- breaking The `project.dynamic` field requires careful handling by build backends. If a field is listed in `dynamic` but also specified statically, `pyproject-metadata` (following PEP 621) will raise an error. Also, build backends *must* provide data for dynamic fields and *must* raise an error if they fail to do so.
Install
-
pip install pyproject-metadata
Imports
- StandardMetadata
from pyproject_metadata import StandardMetadata
- ExtraKeyWarning
from pyproject_metadata.errors import ExtraKeyWarning
Quickstart
import tomli
from pyproject_metadata import StandardMetadata
# Example pyproject.toml [project] data as a Python dictionary
# In a real scenario, you'd load this from a pyproject.toml file using a TOML parser like 'tomli'
project_data = {
"name": "my-project",
"version": "0.1.0",
"description": "A short description",
"requires-python": ">=3.8",
"dependencies": [
"requests~=2.28",
"tomli>=1.1.0; python_version < \"3.11\""
],
"authors": [
{"name": "Your Name", "email": "your.email@example.com"}
],
"license": {"file": "LICENSE"},
"readme": "README.md",
"classifiers": [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License"
],
"urls": {
"Homepage": "https://github.com/my-project",
"Bug Tracker": "https://github.com/my-project/issues"
}
}
# Validate the project metadata
try:
metadata = StandardMetadata.from_pyproject(project_data, allow_extra_keys=False)
# Access validated fields
print(f"Project Name: {metadata.name}")
print(f"Project Version: {metadata.version}")
print(f"Requires Python: {metadata.requires_python}")
print(f"Dependencies: {metadata.dependencies}")
# Generate PEP 643-compliant Core Metadata (e.g., PKG-INFO content)
pkg_info = metadata.as_rfc822()
print("\n--- Generated PKG-INFO ---")
print(str(pkg_info))
except Exception as e:
print(f"Error validating metadata: {e}")