| name | pyproject-style |
| description | Applies pyproject.toml conventions when creating or modifying pyproject.toml files. Covers section ordering, metadata fields, dependency specifications, tool configurations (ruff, mypy, coverage, hatch), and classifier templates. Use when creating a new project, modifying an existing pyproject.toml, adding dependencies, or when the user asks about pyproject.toml conventions. |
| user-invocable | false |
pyproject.toml style guide
Applies conventions for pyproject.toml files.
You MUST read this skill and load the relevant reference files before creating or modifying any
pyproject.toml file. You MUST verify your changes against the checklist before submitting.
Scope
Covers:
- pyproject.toml section ordering and structure
- Project metadata fields (name, version, description, license, classifiers, etc.)
- Dependency specifications and version constraint conventions
- Dependency groups (PEP 735) and entry point conventions
- Tool configurations (ruff, mypy, coverage, hatch build targets)
- TOML formatting and comment style
- Project type distinctions (core library vs application, pure-Python vs C-extension)
Does not cover:
- Python code style (see
/python-style)
- README file conventions (see
/readme-style)
- Commit message conventions (see
/commit)
- tox.ini configuration (see
/tox-config)
Workflow
You MUST follow these steps when this skill is invoked.
Step 1: Read this skill
Read this entire file. The section ordering and core rules below apply to ALL pyproject.toml files.
Step 2: Load relevant reference files
Based on the task, load the appropriate reference files:
Step 3: Determine project type
Identify the project type to apply the correct configuration tier:
| Project type | Naming pattern | MyPy mode | Python support | Dependency style |
|---|
| Core library | ataraxis-* | Full strict | >=3.12,<3.15 | Range (>=X,<Y) |
| Application | (project-specific) | Minimal | >=3.14,<3.15 | Range (>=X,<Y) |
| C-extension | Any | Full strict | >=3.12,<3.15 | Range (>=X,<Y) |
Step 4: Apply conventions
Write or modify the pyproject.toml following all conventions from this file and the loaded
references.
Step 5: Verify compliance
Complete the verification checklist at the end of this file. Every item must pass before
submitting work.
Section ordering
pyproject.toml files use the following section order. This order is mandatory for all
projects.
[build-system]
[project]
[project.urls]
[project.scripts] (if applicable)
[dependency-groups]
[tool.hatch.build.targets.sdist]
[tool.hatch.build.targets.wheel]
[tool.ruff] and sub-tables
[tool.mypy]
[tool.coverage.paths]
[tool.coverage.html]
[tool.coverage.report]
When present, [tool.coverage.run] is placed either before [tool.coverage.paths] (e.g. for a
coverage omit list) or after [tool.coverage.report] (e.g. for parallel / concurrency
settings).
For C-extension projects using scikit-build-core, replace the hatch build targets with
[tool.scikit-build] and [tool.cibuildwheel] sections at positions 6-7.
TOML formatting
Block comments
Use block comments above sections to describe their purpose:
[project]
Inline comments
Use inline comments for individual values when clarification is needed. Align inline comments
vertically within a section:
case-sensitive = true
combine-as-imports = true
force-wrap-aliases = true
force-sort-within-sections = true
length-sort = true
Category comments in arrays
Group related items within dependency and classifier arrays using category comments:
dependencies = [
"click>=8,<9",
"tomli>=2,<3",
"pytest>=9,<10",
"pytest-cov>=7,<8",
]
Separate category groups with a blank line. The comment line has no leading blank line before the
first category.
Ruff ignore comments
Each ruff ignore entry must have an inline comment explaining the reason:
lint.ignore = [
"COM812",
"ISC001",
"D107",
]
Array formatting
- Use multi-line format for arrays with more than two elements
- Always use trailing commas in multi-line arrays
- One element per line
- Single-line format is acceptable for arrays with one or two short elements
Build system
All pure-Python projects use hatchling:
[build-system]
requires = ["hatchling>=1,<2"]
build-backend = "hatchling.build"
C-extension projects use scikit-build-core with nanobind:
[build-system]
requires = ["scikit-build-core>=0,<1", "nanobind>=2,<3"]
build-backend = "scikit_build_core.build"
Version constraints
Projects use the major-version range pattern for all dependencies:
"numpy>=2,<3"
"click>=8,<9"
"scipy>=1,<2"
This pattern allows patch and minor updates while preventing breaking major version changes. This
convention applies to both runtime and development dependencies.
For pre-release or unstable packages (major version 0), pin to the minor version when the minor
version is significant, or use >=0,<1 when the full range is acceptable:
"ruff>=0,<1"
"httpx>=0.28,<1"
Platform-specific dependencies
Use environment markers for platform-conditional dependencies:
"intel-cmplr-lib-rt>=2025,<2026
"tbb4py>=2022,<2023
Project layout
All Python projects use the src layout. For complete directory trees, invoke
/project-layout.
The wheel configuration always points to the src directory:
[tool.hatch.build.targets.wheel]
packages = ["src/package_name"]
Additional directories (e.g., notebooks, examples) may be included in the wheel when they are
part of the distributed package.
Related skills
| Skill | Relationship |
|---|
/explore-dependencies | Explores ataraxis dependency APIs after adding ataraxis deps |
/python-style | Provides coding conventions that pyproject.toml tool configs enforce |
/readme-style | Provides README conventions; the readme field references the README |
/project-layout | Provides complete directory trees; this skill owns wheel config |
/tox-config | Consumes dependency groups for tox environments; co-evolves with deps |
/commit | Should be invoked after completing pyproject.toml changes |
/explore-codebase | Provides project context needed when writing project-specific configs |
Proactive behavior
When creating a new project, proactively offer to generate a pyproject.toml following
these conventions. When modifying Python version support, dependencies, or tool configurations,
proactively suggest updating the pyproject.toml to reflect the changes. After substantial
dependency or configuration changes, proactively offer to run the verification checklist.
Verification checklist
You MUST verify your edits against this checklist before submitting any changes to
pyproject.toml files.
pyproject.toml Style Compliance:
Structure:
- [ ] Section ordering follows canonical order (build-system, project, urls, scripts, deps, ...)
- [ ] All required sections present for project type
- [ ] No duplicate sections or keys
Build System:
- [ ] [build-system] uses hatchling (pure-Python) or scikit-build-core (C-extension)
- [ ] Build requirements use range constraints (>=X,<Y)
Project Metadata:
- [ ] name uses lowercase hyphenated format
- [ ] version follows semantic versioning (X.Y.Z or X.Y.ZrcN)
- [ ] description is a single descriptive sentence
- [ ] readme = "README.md"
- [ ] license uses SPDX expression string (PEP 639)
- [ ] license-files includes the LICENSE file
- [ ] No License :: classifiers present (removed per PEP 639)
- [ ] requires-python specifies supported range
- [ ] authors and maintainers arrays present with correct format
- [ ] keywords array present with relevant terms
- [ ] Classifiers grouped with category comments
- [ ] Classifiers match official PyPI classifier list exactly
- [ ] "Typing :: Typed" classifier present
Dependencies:
- [ ] All dependencies use major-version range format (>=X,<Y)
- [ ] Dependencies grouped by category with comments
- [ ] Platform-specific deps use environment markers
- [ ] Trailing commas on all array elements
Dependency Groups (PEP 735):
- [ ] [dependency-groups] used instead of [project.optional-dependencies] for dev deps
- [ ] dev group includes tox, uv, tox-uv, and ataraxis-automation
- [ ] Type stub packages included in dev group where needed
URLs:
- [ ] Homepage points to GitHub repository
- [ ] Documentation URL present (if hosted docs exist)
Scripts:
- [ ] Entry points use package.module:function format
- [ ] Command names are descriptive and do not conflict with system commands
Build Targets:
- [ ] sdist excludes [".github", "recipe"]
- [ ] wheel packages lists src/package_name
Tool Configurations:
- [ ] Ruff: line-length = 120, indent-width = 4
- [ ] Ruff: target-version matches lowest supported Python
- [ ] Ruff: src = ["src"]
- [ ] Ruff: lint.select = ["ALL"] with project-specific ignores
- [ ] Ruff: format uses double quotes, space indentation
- [ ] Ruff: Google docstring convention
- [ ] Ruff: isort configured (case-sensitive, combine-as-imports, etc.)
- [ ] Ruff: __init__.py ignores F401 and F403
- [ ] Ruff: test-file ignores present when a tests/ directory exists
- [ ] Ruff: Each ignore has an explanatory inline comment
- [ ] MyPy: Configuration tier matches project type (full strict or minimal)
- [ ] MyPy: Standard exclusion list present
- [ ] Coverage: paths, html, and report sections present
- [ ] Coverage: Standard exclude_lines list present
Formatting:
- [ ] Block comments above section headers
- [ ] Inline comments aligned within sections
- [ ] Multi-line arrays with trailing commas
- [ ] One element per line in multi-line arrays
- [ ] Category comments in dependency and classifier arrays