Contribution guideΒΆ
To add a new Linux distribution, you can get inspiration from these pull requests:
https://github.com/kdeldycke/extra-platforms/pull/156
https://github.com/kdeldycke/extra-platforms/pull/94
claude.md fileΒΆ
This file provides guidance to Claude Code when working with code in this repository.
Project overviewΒΆ
Extra Platforms is a Python library for detecting and managing platform/OS information.
It provides:
Detection of architectures, platforms (operating systems), and CI systems
Grouping of platforms into families (e.g.,
LINUX,BSD,UNIX)Pytest decorators for conditional test skipping (
@skip_<id>,@unless_<id>)
Upstream conventionsΒΆ
This repository uses reusable workflows from kdeldycke/workflows and follows the conventions established there. For code style, documentation, testing, and design principles, refer to the upstream claude.md as the canonical reference.
Contributing upstream: If you spot inefficiencies, improvements, or missing features in the reusable workflows, propose changes via a pull request or issue at kdeldycke/workflows.
CommandsΒΆ
TestingΒΆ
# Run all tests with coverage.
$ uv run --group test pytest
# Run a single test file.
$ uv run --group test pytest tests/test_platform_data.py
# Run a specific test.
$ uv run --group test pytest tests/test_platform_data.py::test_function_name
# Run tests in parallel.
$ uv run --group test pytest -n auto
Type checkingΒΆ
$ uv run --group typing mypy extra_platforms
DocumentationΒΆ
Build Sphinx documentation locally:
$ uv run sphinx-build -b html ./docs ./docs/html
ArchitectureΒΆ
Core classesΒΆ
All core classes are defined in trait.py:
Trait (ABC) - Base class for all detectable traits
βββ Platform - Operating systems
βββ Architecture - CPU architectures
βββ CI - CI/CD systems
Group - Collection of Traits with set-like operations (group.py)
Module layoutΒΆ
Module |
Purpose |
|---|---|
|
Base classes: |
|
All |
|
|
|
All |
|
All |
|
All |
|
All |
|
Generates |
|
Internal utilities |
|
Type aliases |
Detection patternΒΆ
Each trait has a corresponding is_<id>() function in detection.py. The Trait.current cached property calls detection.is_{self.id}() to check if the trait matches the current environment.
Dynamic code generationΒΆ
__init__.pygeneratesis_<group_id>()functions for all groups at import timepytest.pygeneratesskip_<id>andunless_<id>decorators for all traits and groups
Documentation requirementsΒΆ
Changelog and readme updatesΒΆ
Always update documentation when making changes:
changelog.md: Add a bullet point describing user-facing changes (new features, bug fixes, behavior changes).readme.md: Update relevant sections when adding/modifying public API, classes, or functions.
Code styleΒΆ
Documenting code decisionsΒΆ
Document design decisions, trade-offs, and non-obvious implementation choices directly in the code:
Use docstring admonitions for important notes:
"""Extract metadata from repository. .. warning:: This method temporarily modifies repository state during execution. .. note:: The commit range is inclusive on both ends. """
Use inline comments for explaining specific code blocks:
# We use a frozenset for O(1) lookups and immutability. SKIP_BRANCHES: Final[frozenset[str]] = frozenset(("branch-a", "branch-b"))
TYPE_CHECKING blockΒΆ
Place a module-level TYPE_CHECKING block immediately after the module docstring:
TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Iterator
from ._types import _T, _TNestedReferences
ImportsΒΆ
Import from the root package (
from extra_platforms import CI), not submodules (from extra_platforms.trait import CI).Place imports at the top of the file, unless avoiding circular imports or improving data registry clarity.
Testing guidelinesΒΆ
Use
@pytest.mark.parametrizewhen testing the same logic for multiple traits/groups.Keep test logic simple with straightforward asserts.
Tests should be sorted logically and alphabetically where applicable.
Enforce naming conventions for traits and groups via tests.
Design principlesΒΆ
PhilosophyΒΆ
Create something that works (to provide business value).
Create something thatβs beautiful (to lower maintenance costs).
Work on performance.
Linting and formattingΒΆ
Linting and formatting are automated via GitHub workflows. Developers donβt need to run these manually during development, but are still expected to do best effort. Push your changes and the workflows will catch any issues.
Data registry priorityΒΆ
The *_data.py files (trait and group definitions) should be clean and easy to maintain. Itβs acceptable to use indirections elsewhere (like function-level imports) to achieve this.
Ordering and uniquenessΒΆ
All IDs must be unique across traits and groups.
High-level objects in data files must be sorted alphabetically by ID.
Tests should verify this ordering.
CachingΒΆ
Detection functions are cached with
@cachedecorator.Use
invalidate_caches()to reset all cached detection results.
Optional dependenciesΒΆ
Pytest integration requires the extra_platforms[pytest] extra.
Comments and docstringsΒΆ
All comments in Python files must end with a period.
Docstrings use reStructuredText format (vanilla style, not Google/NumPy).
Documentation in
./docs/uses MyST markdown format where possible. Fallback to reStructuredText if necessary.Keep lines within 88 characters in Python files, including docstrings and comments (ruff default). Markdown files have no line-length limit.
Titles in markdown use sentence case.