This document describes the configuration of development tools used in the StackOne AI SDK, including linting, formatting, testing, type checking, and coverage reporting. All tool configurations are centralized in pyproject.toml using standardized [tool.*] sections.
For package metadata and dependencies, see Package Configuration. For CI/CD pipeline usage of these tools, see CI Workflow. For task automation commands that invoke these tools, see Task Automation with just.
All development tool configurations are defined in pyproject.toml using the [tool.*] namespace convention defined by PEP 518. This centralized approach eliminates the need for separate configuration files like .ruff.toml, pytest.ini, or .coveragerc.
Sources: pyproject.toml61-112
Ruff is the primary linting and formatting tool, providing fast Python code quality enforcement. Configuration spans three sections in pyproject.toml.
The base [tool.ruff] section defines project-wide behavior:
| Setting | Value | Purpose |
|---|---|---|
line-length | 110 | Maximum characters per line (more permissive than default 88) |
target-version | "py310" | Python 3.10 syntax and features |
Sources: pyproject.toml75-77
The [tool.ruff.lint] section enables specific rule categories:
| Rule Code | Category | Description |
|---|---|---|
E | pycodestyle errors | PEP 8 error violations |
W | pycodestyle warnings | PEP 8 warning violations |
F | pyflakes | Unused imports, undefined names |
I | isort | Import sorting and organization |
B | flake8-bugbear | Bug and design problems |
C4 | flake8-comprehensions | List/set/dict comprehension issues |
UP | pyupgrade | Modern Python syntax upgrades |
Sources: pyproject.toml79-88
The [tool.ruff.lint.per-file-ignores] section allows specific files to bypass certain rules:
| Path Pattern | Ignored Rules | Reason |
|---|---|---|
bin/**.py | T201, T203 | Print statements allowed in CLI scripts |
scripts/**.py | T201, T203 | Print statements allowed in utility scripts |
tests/**.py | T201, T203 | Print statements allowed in tests |
examples/**.py | T201, T203, E501, F841, E402 | Relaxed rules for example code |
The examples/ directory has additional exemptions:
E501: Line length limit (examples prioritize readability)F841: Unused local variables (demonstration purposes)E402: Module-level import not at top (examples may have setup code)Sources: pyproject.toml69-73
Ruff is invoked through multiple pathways:
Sources: .claude/rules/development-workflow.md12-16 .claude/rules/development-workflow.md34-43
Pytest is the testing framework with configuration focused on async test execution and test categorization.
The asyncio_mode and asyncio_default_fixture_loop_scope settings control async test behavior:
| Setting | Value | Purpose |
|---|---|---|
asyncio_mode | "strict" | Enforce explicit async test marking |
asyncio_default_fixture_loop_scope | "function" | Create new event loop per test function |
The "strict" mode requires explicit @pytest.mark.asyncio decorators on async test functions, preventing accidental synchronous execution of coroutines.
Sources: pyproject.toml61-63
Custom markers enable test categorization and selective execution:
| Marker | Usage | Purpose |
|---|---|---|
asyncio | @pytest.mark.asyncio | Identify async tests |
integration | @pytest.mark.integration | Mark tests requiring MCP mock server |
These markers allow running subsets of tests:
pytest -m "not integration" - Skip integration testspytest -m asyncio - Run only async testsSources: pyproject.toml64-67
Sources: pyproject.toml61-67
Coverage.py tracks code execution during tests, generating reports in multiple formats. Configuration spans three sections for run settings, reporting, and output formats.
The [tool.coverage.run] section controls data collection:
| Setting | Value | Purpose |
|---|---|---|
source | ["stackone_ai"] | Limit coverage to main package only |
branch | true | Track both line and branch coverage |
omit | ["stackone_ai/__init__.py", "**/py.typed"] | Exclude package metadata files |
Branch coverage measures whether both True and False paths of conditionals are tested, providing more thorough coverage metrics than line coverage alone.
Sources: pyproject.toml90-93
The [tool.coverage.report] section excludes lines that shouldn't affect coverage metrics:
| Pattern | Purpose |
|---|---|
pragma: no cover | Explicit coverage exemption |
def __repr__ | String representation methods |
raise NotImplementedError | Abstract method stubs |
if TYPE_CHECKING: | Type-only imports (runtime-excluded) |
Sources: pyproject.toml95-102
Coverage generates three output formats:
| Format | Configuration | Output Path | Purpose |
|---|---|---|---|
| JSON | [tool.coverage.json] | coverage/coverage.json | Machine-readable for CI badges |
| HTML | [tool.coverage.html] | coverage/html/ | Human-readable web interface |
| Terminal | Built-in | stdout | Quick review during development |
Sources: pyproject.toml104-108
ty is a Python type checker that enforces type annotation correctness. While not configured in pyproject.toml, it's a required development tool with strict enforcement.
Type checking is enforced through:
just ty command for local checksThe codebase enforces strict type annotation requirements:
list[str] instead of List[str])Example from codebase:
Sources: .claude/rules/development-workflow.md17-23 pyproject.toml100-101
uv is the Python package manager with minimal configuration in pyproject.toml.
The [tool.uv] section contains a single configuration:
| Setting | Value | Purpose |
|---|---|---|
link-mode | "clone" | Copy files instead of hardlinks/symlinks |
This setting ensures compatibility across different filesystems and environments, particularly in Nix-based development environments where hardlinks may not work as expected.
Sources: pyproject.toml110-111
Hatch is the build backend configured in [tool.hatch.build.targets.wheel] for package distribution.
The wheel target specifies which directories to include:
| Setting | Value | Purpose |
|---|---|---|
packages | ["stackone_ai"] | Include main package directory |
force-include | py.typed marker | Declare PEP 561 type stub support |
The py.typed file is a zero-byte marker file that indicates the package includes inline type annotations, enabling type checkers like mypy and pyright to use the package's type information.
Sources: pyproject.toml32-36
All development tools are orchestrated through multiple layers of automation:
Sources: .claude/rules/development-workflow.md24-43 pyproject.toml61-112
| Tool | Config Section | Primary Purpose | Invocation |
|---|---|---|---|
| ruff | [tool.ruff], [tool.ruff.lint] | Linting & formatting | just lint, pre-commit, CI |
| pytest | [tool.pytest.ini_options] | Test execution | just test, CI |
| coverage | [tool.coverage.*] | Coverage reporting | pytest --cov, CI |
| ty | External config | Type checking | just ty, pre-commit, CI |
| uv | [tool.uv] | Package management | uv install, uv build |
| hatch | [tool.hatch.*] | Build system | uv build (uses hatch) |
All tool configurations follow a consistent pattern:
pyproject.toml - Single source of truthjust commandsSources: pyproject.toml61-112 .claude/rules/development-workflow.md1-64
Refresh this wiki