Skip to content

Commit a452073

Browse files
committed
chore: update dependencies and enhance project configuration
- Upgraded ruff to v0.14.10 in .pre-commit-config.yaml for improved linting. - Refined AGENTS.md to streamline coding guidelines and enhance clarity. - Updated Makefile to improve command descriptions and streamline installation processes. - Bumped project version to 0.4.0 in pyproject.toml, reflecting recent changes. - Adjusted various dependencies for better compatibility and performance. These changes aim to enhance code quality and maintainability across the project.
1 parent cac9fb9 commit a452073

5 files changed

Lines changed: 499 additions & 380 deletions

File tree

.pre-commit-config.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ repos:
1212
- id: check-docstring-first
1313

1414
- repo: https://github.com/astral-sh/ruff-pre-commit
15-
rev: v0.14.8
15+
rev: v0.14.10
1616
hooks:
1717
- id: ruff
18-
args: [--fix]
18+
args: [--fix] # optional auto-fix
19+
types_or: [python, pyi, jupyter]
1920
- id: ruff-format
21+
types_or: [python, pyi, jupyter]
2022

2123
- repo: local
2224
hooks:

AGENTS.md

Lines changed: 23 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,32 @@
11
# AI Agent Code Guidelines
22

3-
This document provides coding guidelines for AI agents working on this Python project.
3+
## Core Directives
44

5-
## Environment and Dependencies
5+
- **Tooling**: `uv` (manager), `ty` (checker), Python 3.13+.
6+
- **Format**: 2-space indent, single quotes, 88 chars, `snake_case`, `PascalCase` classes.
7+
- **Typing**: Strict `ty` checking. Pydantic `BaseModel` for interfaces/schemas. `dataclasses` only for internal perf.
8+
- **Docs**: One-line docstrings. Type hints > text. Comments explain *why*, not *what*.
69

7-
- **Tooling**: Use `uv` for all package management
8-
- **Python Version**: 3.13+
9-
- **Package Manager**: uv (fast, modern dependency management)
10-
- **Type Checker**: ty (Astral's fast type checker, alpha stage) - `make typecheck`
11-
- Note: ty is in early development and may have bugs/missing features
10+
## Architecture & Patterns
1211

13-
## Code Style
12+
- **Functional Core, Imperative Shell**: Classes for state/lifecycle, pure functions for logic.
13+
- **Protocols**: Duck-typing over inheritance (`typing.Protocol`).
14+
- **Config**: Frozen dataclasses/Pydantic models with factories (`from_env`).
15+
- **Resource Safety**: Context managers (`with`), reference counting, explicit ownership.
16+
- **Data Flow**: Streaming `Iterator[T]`. RORO (Receive Object, Return Object). Pipeline pattern.
17+
- **Errors**: Custom domain exceptions. No broad catches.
1418

15-
**Format**: 2-space indentation, single quotes, 88-character lines, `snake_case` variables/functions, `PascalCase` classes, boolean flags prefixed with `is_/has_/should_`. Pre-commit hooks ensure code quality on commit.
19+
## Quality Standards
1620

17-
**Docstrings**:
21+
- **Complexity**: Max 25 lines per method. Break large functions into small, focused helpers.
22+
- **Readability**: Optimize for review. Explicit dependencies over global state. No magic values.
23+
- **Testing**: Test behaviors, not implementation details. High coverage on core logic.
24+
- **Reviewability**: Code should be obvious. If it needs a long comment, refactor it.
1825

19-
- Use simple one-line docstrings for most functions - be concise and descriptive
20-
- Type hints replace Args/Returns documentation - don't duplicate what's in the signature
21-
- No Examples section - type hints + function name should be self-explanatory
22-
- Exception: Top-level user-facing APIs may include brief usage notes if necessary
23-
- Rationale: Modern Python with PEP 484 type hints makes verbose docstrings redundant
26+
## Anti-Patterns
2427

25-
**Comments**:
26-
27-
- Avoid narrating the code; prefer clear names and small functions
28-
- Comments should explain *why* (tradeoffs, invariants, pitfalls), not *what*
29-
- Delete commented-out code instead of keeping it around
30-
31-
**Naming**:
32-
33-
- Prefer domain-specific, intention-revealing names over generic ones (`process`, `handle`, `manager`, `util`)
34-
- Keep public API names stable and unsurprising; avoid cleverness
35-
36-
## Architecture Principles
37-
38-
**Classes for state and lifecycle**, pure functions for transformations. Use classes when managing resources, coordinating operations, or defining interfaces.
39-
40-
**Protocols over inheritance**: Define interfaces with `typing.Protocol` for flexible, duck-typed implementations.
41-
42-
**Immutable configs**: Frozen dataclasses with `__post_init__` validation and factory classmethods (`from_uri()`, `from_dict()`).
43-
44-
**Factory functions**: Standalone functions (`get_backend()`, `resolve_config()`) that map configurations to implementations.
45-
46-
**Resource management**:
47-
48-
- Reference counting for expensive resources (connections, clients) with acquire/release semantics
49-
- Context managers (`__enter__`/`__exit__`) for automatic cleanup
50-
- Track ownership with boolean flags to avoid closing borrowed resources
51-
52-
**Streaming over bulk**: Use `Iterator[T]` to yield chunks for large datasets. Implement retry logic within generators for resilience.
53-
54-
**Separation by lifecycle**: Split read and write operations into distinct classes, even when working with the same backend (e.g., `SessionStoreReader`, `SessionStoreWriter`).
55-
56-
**Domain exceptions**: Create specific exception types rather than generic `RuntimeError`.
57-
58-
**Performance**: Use `@dataclass(slots=True)` for frequently-instantiated objects and `TypeVar` for type-safe generic protocols.
59-
60-
**Resilience**: Exponential backoff for network operations, graceful empty returns over exceptions, debug logging for key metrics. Keep error handling targeted (catch specific exceptions, add context, re-raise/convert).
61-
62-
## Best Practices
63-
64-
- RORO pattern: service functions receive/return single Pydantic objects
65-
- Single responsibility: break 150+ line functions into focused 15-25 line methods
66-
- Early returns, no magic values, explicit dependencies
67-
- DRY principle: extract utility functions to eliminate duplication
68-
- Pipeline pattern: chain transformations with clear inputs/outputs
69-
- No excessive error handling or low-value comments
70-
71-
## Code Quality Bar (What to Avoid)
72-
73-
When generating code, optimize for reviewability and long-term maintainability.
74-
75-
- **Unnecessary comments**: If a comment just restates the code, remove it and improve naming/structure instead
76-
- **Long docstrings**: Keep most docstrings to a single line; only expand when a public API truly needs usage notes
77-
- **Overly defensive code**: Don’t add “just in case” checks everywhere; validate at boundaries and trust validated data internally
78-
- **Broad `try/except`**: Avoid wrapping whole functions; don’t swallow exceptions; catch specific errors only to recover or add context
79-
- **Deep nesting**: Prefer guard clauses and extraction to keep indentation shallow (avoid multi-level `if/for/try`)
80-
- **Bad abstractions**: Don’t create classes/protocols/layers without clear value; avoid one-method wrappers and “framework-building”
81-
- **Vague naming**: Avoid generic verbs (`do`, `process`, `handle`) and generic buckets (`utils`, `helpers`) for core logic
82-
- **Weak typing / schemas**: Avoid `Any` and unstructured `dict[str, Any]` in core code; prefer Pydantic models (or narrow typed objects) with explicit fields and validation
83-
- **Noisy error handling**: Prefer a small number of well-placed domain exceptions over many `RuntimeError`/`ValueError` catch-alls
84-
85-
## Pydantic Commitment
86-
87-
- All interface models use Pydantic `BaseModel` (not dataclasses)
88-
- Validation, `.model_dump()`, JSON serialization built-in
89-
- Reserve `@dataclass(slots=True)` only for inner performance-critical helpers (graph traversal caches, etc.)
28+
- **Verbosity**: Long docstrings, narrating comments, redundant type info in docs.
29+
- **Vague Naming**: `manager`, `handler`, `util`, `data`. Be specific.
30+
- **Defensive Coding**: Validate at boundaries, trust internals. No "just in case" checks.
31+
- **Deep Nesting**: Use guard clauses and early returns.
32+
- **Over-Abstraction**: No single-method classes or speculative layers.

Makefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ help:
55
@echo 'Available commands:'
66
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
77

8-
install:
8+
install: ## Install production dependencies
99
uv sync
1010

11-
install-dev:
11+
install-dev: ## Install development dependencies
1212
uv sync --extra dev
1313

14-
setup:
14+
setup: ## Initialize development environment
1515
@if [ ! -d "$(VENV_DIR)" ]; then \
1616
echo 'Creating virtual environment in $(VENV_DIR)...'; \
1717
uv venv; \
@@ -22,16 +22,16 @@ setup:
2222
@uv run pre-commit install
2323
@echo '\n✅ Setup complete. To activate the environment, run:\nsource .venv/bin/activate'
2424

25-
pre-commit-install:
25+
pre-commit-install: ## Install pre-commit hooks
2626
uv run pre-commit install
2727

28-
pre-commit-run:
28+
pre-commit-run: ## Run pre-commit hooks on all files
2929
uv run pre-commit run --all-files
3030

31-
lint:
31+
lint: ## Run linter (ruff)
3232
uv run ruff check . --fix
3333

34-
format:
34+
format: ## Run formatter (ruff)
3535
uv run ruff format .
3636

3737
typecheck: ## Run ty type checker

pyproject.toml

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,36 @@
11
[project]
22
name = "templates.python"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
description = "A boilerplate for Python projects."
55
readme = "README.md"
66
requires-python = ">=3.13"
77
license = {text = "MIT"}
88
authors = [
9-
{name = "Andy Pai", email = "andy@r2pi.co"},
9+
{name = "Andy Pai", email = "andy@r2pi.co"},
1010
]
1111

1212
dependencies = [
13-
"pydantic>=2.12.5",
14-
"pydantic-settings>=2.12.0",
15-
"structlog>=25.4.0",
16-
"tqdm>=4.67.1",
13+
"pydantic>=2.12.5",
14+
"pydantic-settings>=2.12.0",
15+
"structlog>=25.4.0",
1716
]
1817

1918
[project.optional-dependencies]
2019
dev = [
21-
"ipykernel>=6.30.1",
22-
"pre-commit>=4.3.0",
23-
"pytest>=8.4.2",
24-
"pytest-cov>=6.2.1",
25-
"ruff>=0.14.8",
26-
"ty>=0.0.1a33",
20+
"ipykernel>=7.1.0",
21+
"pre-commit>=4.5.1",
22+
"pytest>=9.0.2",
23+
"pytest-cov>=7.0.0",
24+
"ruff>=0.14.10",
25+
"ty>=0.0.5",
2726
]
2827

2928
ml = [
30-
"torch>=2.7.1",
31-
"scikit-learn>=1.7.1",
32-
"mlflow>=3.1.1",
33-
"matplotlib>=3.10.6",
34-
"numpy>=2.3.3",
29+
"torch>=2.9.1",
30+
"scikit-learn>=1.8.0",
31+
"mlflow>=3.8.0",
32+
"matplotlib>=3.10.8",
33+
"numpy>=2.4.0",
3534
"pandas>=2.3.3",
3635
"seaborn>=0.13.2",
3736
]

0 commit comments

Comments
 (0)