validate-pyproject
validate-pyproject is a Python library and CLI tool designed for validating `pyproject.toml` files against various Python packaging standards (like PEP 517, PEP 518, PEP 621, PEP 639, and PEP 735) using JSON Schema. It is currently at version 0.25 and maintains an active development and release cadence.
Common errors
-
validate_pyproject.errors.ValidationError: Invalid Document: ...
cause The `pyproject.toml` file contains data that does not conform to the expected JSON Schema for Python packaging metadata (e.g., missing required fields, incorrect types, invalid values).fixReview the error message details (`ex.message`, `ex.details` if using the API) to identify the specific validation failure. Consult the official `pyproject.toml` specifications (PEPs like 621) or `validate-pyproject` documentation for schema requirements. Example: `[project]` table might be missing `name` or `version`. -
ImportError: cannot import name 'tomli' from 'validate_pyproject.api' (or similar for other dependencies)
cause The `tomli` package (or `packaging`, `trove-classifiers`) is a conditional dependency for `validate-pyproject`'s full functionality. If you installed `validate-pyproject` without the `[all]` extra, these might be missing for Python versions that require them (e.g., `tomli` for Python < 3.11).fixInstall `validate-pyproject` with the `[all]` extra: `pip install 'validate-pyproject[all]'`. This ensures all necessary optional dependencies are included for full validation capabilities. -
validate-pyproject --help ... Command 'validate-pyproject' not found ...
cause The `validate-pyproject` CLI tool is not in your system's PATH, likely because it was installed into a virtual environment that isn't activated, or `pipx` was used without linking the executables globally.fixEnsure your virtual environment is activated, or if installed via `pipx`, run `pipx ensurepath` to add pipx-managed executables to your PATH. Alternatively, you can run it directly: `python -m validate_pyproject.cli --help`.
Warnings
- breaking Starting from `v0.24`, the way `validate-pyproject` handles test and documentation dependencies changed. It no longer communicates these via `tests` or `docs/requirements.txt` files, adopting `dependency-groups` instead.
- gotcha In `v0.22`, a change was introduced to prevent the validator from injecting default values or modifying the input dictionary in-place. This ensures that the original `pyproject.toml` data structure remains unaltered during validation.
- gotcha If `trove-classifiers` is not installed (e.g., using a minimal installation without `[all]` extra), `validate-pyproject` will attempt to download a list of valid classifiers from PyPI. This can lead to network requests during validation.
- gotcha Earlier versions (prior to `v0.25`) could have issues with nested properties in schema stores or incorrect handling of integer types, leading to validation failures for valid `pyproject.toml` files.
Install
-
pip install validate-pyproject -
pip install 'validate-pyproject[all]'
Imports
- api.Validator
from validate_pyproject import api
- errors.ValidationError
from validate_pyproject import errors
- cli.main
from validate_pyproject import cli
Quickstart
import tomli
from validate_pyproject import api, errors
import os
# Example pyproject.toml content
PYPROJECT_TOML_CONTENT = '''
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-package"
version = "1.0.0"
description = "A simple Python package"
requires-python = ">=3.8"
keywords = ["packaging", "example"]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
authors = [
{name = "Example Author", email = "author@example.com"},
]
maintainers = [
{name = "Example Maintainer", email = "maintainer@example.com"},
]
'''
# Parse the TOML string into a dictionary
pyproject_as_dict = tomli.loads(PYPROJECT_TOML_CONTENT)
# Instantiate the validator (can be configured with extra schemas or plugins)
validator = api.Validator()
try:
# Perform the validation
validator(pyproject_as_dict)
print("pyproject.toml is valid!")
except errors.ValidationError as ex:
print(f"Invalid pyproject.toml: {ex.message}")
# More detailed errors can be accessed via ex.details
for error in ex.details:
print(f" - {error.message} at {error.json_path}")