Pyproject Development Guide
This is a brief overview of the Python packaging
specification,
in addition to some narrowed conventions for Python development in the pntOS-Python
repository.
Project Configuration (pyproject.toml)
Each Python package is configured via pyproject.toml, which defines metadata, dependencies, and build settings.
Basic Package Metadata
[project]
name = "pntos-api"
version = "0.1.0.dev0"
description = "The API specification for pntOS"
readme = "README.md"
authors = [ { name = "IS4S", email = "pntos@is4s.com" } ]
requires-python = ">=3.10"
classifiers = [
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
See the Python packaging specification for all available fields.
Versioning
By convention, the version should adhere to semantic versioning. In short:
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes
MINOR version when you add functionality in a backward compatible manner
PATCH version when you make backward compatible bug fixes
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
Here are some concrete examples of when to increment each version number:
Version Type |
Example Change |
Why It Matters |
Impact on Downstream Projects |
|---|---|---|---|
MAJOR |
Renaming a function from |
Breaking change - the old function name no longer exists |
Projects using |
MAJOR |
Changing a function signature from |
Breaking change - existing calls are no longer valid |
Projects must update all |
MINOR |
Adding a new function |
New functionality added |
Projects can choose to use the new |
MINOR |
Adding an optional parameter: |
New functionality that’s backward compatible |
Projects can use the new |
PATCH |
Fixing a bug where |
Bug fix with no API changes |
Projects get the correct behavior automatically; no code changes needed |
PATCH |
Improving performance of |
Internal improvement with no API changes |
Projects benefit from better performance; no code changes needed |
For pre-release versions, the convention is to append .devN where N corresponds to
the pre-release version number (e.g. 0.1.0.dev0).
Note
These conventions are a subset of the full Python versioning specification.
Dependencies
By convention, dependencies are categorized into two types:
Type |
Purpose |
Location In |
Example Use Case |
|---|---|---|---|
Core |
Required to use the package |
|
Package function |
Dev |
Only needed for development |
|
Package uses |
Example:
[project]
dependencies = [
"numpy", # Core: needed by package users
]
[dependency-groups]
dev = [
"pytest", # Dev: only for testing
"ruff", # Dev: only for linting
]
The simplest dependency specification is just the package name. Version constraints and other options are covered in the next section.
Dependency Specifiers
Common patterns for specifying dependencies (see Python dependency specifiers for full details):
Type |
Syntax |
Example |
Use Case |
|---|---|---|---|
Version constraints |
|
|
Exact version |
Git dependencies |
|
|
Latest from default branch |
Local paths |
|
|
Absolute path |