Skip to content

Commit 6a53a75

Browse files
authored
Add comprehensive pre-commit hooks for local development (#26)
* docs: add comprehensive Google-style docstrings to all public APIs (#24) Added comprehensive API documentation following Google-style docstring format: - python/dioxide/__init__.py: Enhanced module docstring with quick start example - python/dioxide/scope.py: Detailed Scope enum docs with usage examples - python/dioxide/decorators.py: Complete @component decorator documentation - python/dioxide/container.py: Comprehensive Container class documentation All public methods now include: - Clear description of purpose and behavior - Args with types and detailed explanations - Returns with type information - Raises documenting exceptions - Working, tested examples - Usage notes and best practices Documentation features: - All examples are executable and tested - Type hints match docstring descriptions - IDE autocomplete shows full documentation - help() function displays useful information - Examples demonstrate common use cases This completes issue #24 - Complete API Documentation * feat: add comprehensive pre-commit hooks configuration (#25) This commit adds a complete pre-commit hooks configuration that matches CI checks: Changes: - Updated .pre-commit-config.yaml with latest hook versions - Python checks: ruff format, ruff check --fix, isort, mypy --strict - Rust checks: cargo fmt, cargo clippy with strict flags - General checks: trailing whitespace, YAML/TOML validation - Updated CONTRIBUTING.md with comprehensive pre-commit documentation Technical notes: - Tests are not included in pre-commit hooks due to uv/maturin interaction - uv run reinstalls packages on each invocation, breaking the Rust extension - Developers should run tests manually: uv run pytest tests/ - Hooks run in < 5 seconds for fast local development Closes #25 * style: apply ruff formatting to Python files These files were reformatted by ruff during pre-commit hook setup. No functional changes.
1 parent c34f4a3 commit 6a53a75

File tree

4 files changed

+95
-34
lines changed

4 files changed

+95
-34
lines changed

.pre-commit-config.yaml

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
repos:
2+
# General file hygiene
23
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.5.0
4+
rev: v6.0.0
45
hooks:
56
- id: trailing-whitespace
67
- id: end-of-file-fixer
@@ -10,48 +11,59 @@ repos:
1011
- id: check-merge-conflict
1112
- id: mixed-line-ending
1213

14+
# Python formatting and linting (must match CI exactly)
1315
- repo: https://github.com/astral-sh/ruff-pre-commit
14-
rev: v0.1.15
16+
rev: v0.14.3
1517
hooks:
1618
- id: ruff
1719
args: [--fix, --unsafe-fixes]
20+
files: ^(python/|tests/)
1821
- id: ruff-format
22+
files: ^(python/|tests/)
1923

24+
# Import sorting
2025
- repo: https://github.com/pycqa/isort
21-
rev: 5.13.2
26+
rev: 7.0.0
2227
hooks:
2328
- id: isort
2429
args: [--profile=black, --line-length=120]
30+
files: ^(python/|tests/)
2531

32+
# Type checking (strict mode to match CI)
2633
- repo: https://github.com/pre-commit/mirrors-mypy
27-
rev: v1.8.0
34+
rev: v1.18.2
2835
hooks:
2936
- id: mypy
3037
additional_dependencies: [pytest>=8.0]
31-
args: [--python-version=3.11]
38+
args: [--strict, --config-file=pyproject.toml]
39+
files: ^(python/|tests/)
3240
exclude: ^features/
3341

42+
# Rust formatting and linting (local hooks)
3443
- repo: local
3544
hooks:
3645
- id: cargo-fmt
3746
name: cargo fmt
38-
entry: cargo fmt
47+
entry: bash -c 'cd rust && cargo fmt --all --check'
3948
language: system
4049
types: [rust]
4150
pass_filenames: false
4251

4352
- id: cargo-clippy
4453
name: cargo clippy
45-
entry: cargo clippy
54+
entry: bash -c 'cd rust && cargo clippy --all-targets --all-features -- -D warnings -A non-local-definitions'
4655
language: system
4756
types: [rust]
4857
pass_filenames: false
49-
args: [--all-targets, --all-features, --, -D, warnings, -A, non-local-definitions]
5058

51-
- id: pytest-cov
52-
name: pytest with coverage
53-
entry: uv run pytest
54-
language: system
55-
types: [python]
56-
pass_filenames: false
57-
args: [tests/, --cov=dioxide, --cov-fail-under=95, --cov-branch, -q]
59+
# NOTE: Tests are intentionally NOT included in pre-commit hooks.
60+
# Reason: The Rust extension requires maturin build, but `uv run` reinstalls
61+
# packages on each invocation, which undoes the maturin-built extension.
62+
# This creates a chicken-and-egg problem that significantly slows down commits.
63+
#
64+
# Developer workflow:
65+
# 1. Pre-commit catches linting/formatting issues (< 5 seconds)
66+
# 2. Run tests manually: `uv run pytest tests/` (< 10 seconds)
67+
# 3. CI runs full test suite on push
68+
#
69+
# This keeps local commits fast while ensuring quality via CI.

CONTRIBUTING.md

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ Be respectful, inclusive, and professional. We're all here to build something us
1818
```bash
1919
uv venv
2020
source .venv/bin/activate
21-
uv pip install -e ".[dev]"
22-
maturin develop
21+
uv sync --all-extras
22+
uv run maturin develop
2323
pre-commit install
2424
```
2525

@@ -40,22 +40,24 @@ Be respectful, inclusive, and professional. We're all here to build something us
4040

4141
2. **Write tests first** (TDD approach):
4242
- Add failing tests in `tests/`
43-
- Run `pytest` to confirm they fail
43+
- Run `uv run pytest tests/` to confirm they fail
4444
- Implement the feature
45-
- Run `pytest` to confirm they pass
45+
- Run `uv run pytest tests/` to confirm they pass
4646

47-
3. **Follow code style**:
48-
- Python: Single quotes, vertical hanging indent for imports
49-
- Rust: Standard `rustfmt` style
50-
- Run `tox -e format` to auto-format
51-
- Run `tox -e lint` to check
47+
3. **Pre-commit hooks will automatically**:
48+
- Format Python code (ruff format)
49+
- Fix linting issues (ruff check --fix)
50+
- Sort imports (isort)
51+
- Check types (mypy --strict)
52+
- Format Rust code (cargo fmt)
53+
- Lint Rust code (cargo clippy)
5254

53-
4. **Type check**:
55+
4. **Run tests before pushing**:
5456
```bash
55-
tox -e type
57+
uv run pytest tests/ --cov=dioxide --cov-branch
5658
```
5759

58-
5. **Run full test suite**:
60+
5. **Run full quality checks** (optional, CI will run these):
5961
```bash
6062
tox
6163
```
@@ -70,6 +72,54 @@ Be respectful, inclusive, and professional. We're all here to build something us
7072
- `test: Add tests for shutdown lifecycle`
7173
- `refactor: Simplify graph construction logic`
7274

75+
### Pre-commit Hooks
76+
77+
Pre-commit hooks run automatically when you commit, catching issues before they reach CI.
78+
79+
**What hooks do**:
80+
- ✅ Format Python code (ruff format)
81+
- ✅ Auto-fix linting issues (ruff check --fix --unsafe-fixes)
82+
- ✅ Sort imports (isort)
83+
- ✅ Type check (mypy --strict)
84+
- ✅ Format Rust code (cargo fmt)
85+
- ✅ Lint Rust code (cargo clippy)
86+
- ✅ Check YAML/TOML syntax
87+
- ✅ Remove trailing whitespace
88+
89+
**Installation**:
90+
```bash
91+
pre-commit install
92+
```
93+
94+
**Running manually**:
95+
```bash
96+
# Run all hooks on all files
97+
pre-commit run --all-files
98+
99+
# Run specific hook
100+
pre-commit run ruff --all-files
101+
102+
# Update hook versions
103+
pre-commit autoupdate
104+
```
105+
106+
**Bypassing hooks** (use sparingly):
107+
```bash
108+
# Skip hooks for WIP commits
109+
git commit --no-verify -m "WIP: work in progress"
110+
```
111+
112+
**Performance**:
113+
- Hooks run in < 5 seconds for incremental commits
114+
- First run may take longer (installing hook environments)
115+
116+
**Note on tests**:
117+
Tests are NOT run in pre-commit hooks due to technical limitations with the Rust extension build.
118+
Always run tests manually before pushing:
119+
```bash
120+
uv run pytest tests/ --cov=dioxide --cov-branch
121+
```
122+
73123
### Pull Request Process
74124

75125
1. **Update documentation** if needed (README, docstrings, etc.)

tests/test_type_safety.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Runtime tests for type safety and type inference."""
22

3-
43
from dioxide import Container, Scope, component
54

65

tests/type_checking/test_mypy_catches_errors.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ def it_catches_invalid_resolve_usage(self) -> None:
4646
output = result.stdout + result.stderr
4747

4848
# Should catch attr-defined errors
49-
assert (
50-
'has no attribute' in output or 'attr-defined' in output
51-
), f'mypy should catch attribute errors\nOutput: {output}'
49+
assert 'has no attribute' in output or 'attr-defined' in output, (
50+
f'mypy should catch attribute errors\nOutput: {output}'
51+
)
5252

5353
# Should catch arg-type errors
54-
assert (
55-
'Argument' in output or 'arg-type' in output
56-
), f'mypy should catch argument type errors\nOutput: {output}'
54+
assert 'Argument' in output or 'arg-type' in output, (
55+
f'mypy should catch argument type errors\nOutput: {output}'
56+
)
5757

5858
finally:
5959
# Clean up temp file

0 commit comments

Comments
 (0)