This commit is contained in:
ВяткинАртём
2026-04-06 17:54:07 +03:00
parent 6d4e45d407
commit d00f858d98
15 changed files with 1319 additions and 0 deletions
@@ -0,0 +1,56 @@
# Default Config
Baseline mypy and ruff settings used when `pyproject.toml` is absent or incomplete.
## mypy (strict mode)
```ini
[mypy]
python_version = 3.13
strict = true
warn_return_any = true
warn_unused_ignores = true
warn_redundant_casts = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_any_generics = true
no_implicit_reexport = true
```
## ruff
```toml
[tool.ruff]
target-version = "py313"
line-length = 88
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"UP", # pyupgrade
"B", # flake8-bugbear
"SIM", # flake8-simplify
"I", # isort
"RUF", # ruff-specific
"ANN", # flake8-annotations (public API must be typed)
]
ignore = [
"ANN101", # missing type for self
"ANN102", # missing type for cls
]
```
## pyproject.toml Priority Rules
When `pyproject.toml` exists, always prefer its values over these defaults:
| Config key | Behaviour |
|---|---|
| `[tool.mypy] strict = false` | Still enforce strict — mention the deviation to the user |
| `[tool.mypy] python_version` | Use as-is; warn if < 3.13 |
| `[tool.ruff.lint] ignore` | Respect fully — do not flag ignored rules |
| `[tool.ruff] line-length` | Use for E501; default 88 if absent |
| `[tool.ruff.lint] select` | Merge with defaults — do not drop user selections |
@@ -0,0 +1,97 @@
# Fix Application Rules
Rules the agent must follow when applying accepted review fixes.
## General Rules
1. **One file at a time** — edit files sequentially, not in parallel, to avoid conflicts
2. **Minimal diff** — change only what is needed; do not reformat unrelated code
3. **Preserve comments** — keep existing comments unless they are part of the fix
4. **No behaviour changes** — fixes must not alter runtime behaviour unless the original was a bug
5. **Add imports sparingly** — only add imports that are strictly required by the fix
## Type Annotation Fixes
- Add annotations using Python 3.13+ syntax: `X | None` not `Optional[X]`
- Use `list[str]` not `List[str]`, `dict[str, int]` not `Dict[str, int]`
- For functions with no return: annotate as `-> None`
- For `*args` / `**kwargs`: annotate properly, e.g. `*args: str`, `**kwargs: int`
- Do not add `from __future__ import annotations` — use native syntax directly
## mypy `# type: ignore` Usage
- Never add bare `# type: ignore` — always use specific code: `# type: ignore[assignment]`
- Only use `type: ignore` as last resort when fixing the root cause is not feasible
- Add a comment explaining why: `# type: ignore[misc] # third-party stub incomplete`
## ruff Auto-fix Rules
- Run `ruff check --fix <file>` only for safe auto-fixable rules (F401, UP*, I*)
- Do NOT use `--unsafe-fixes` without explicit user confirmation
- After auto-fix, re-read the file to verify no logic was altered
## Mutable Default Arguments
```python
# Before
def process(items: list[str] = []) -> None: ...
# After
def process(items: list[str] | None = None) -> None:
if items is None:
items = []
```
## Union Type Modernization (Python 3.13+)
```python
# Before
from typing import Optional, Union
def f(x: Optional[str]) -> Union[int, str]: ...
# After
def f(x: str | None) -> int | str: ...
```
Remove now-unused `Optional` / `Union` imports after rewriting.
## TypeAlias Modernization (PEP 695)
```python
# Before
from typing import TypeAlias
Vector: TypeAlias = list[float]
# After
type Vector = list[float]
```
## Broad Exception Handling
```python
# Before
try:
...
except Exception:
pass
# After — option A: log and re-raise
except Exception:
logger.exception("Unexpected error")
raise
# After — option B: specific exception (preferred when possible)
except ValueError as exc:
logger.warning("Invalid value: %s", exc)
```
## Post-Fix Validation Sequence
After applying all accepted fixes to a file:
1. `mypy --strict <file>` — must return exit code 0
2. `ruff check <file>` — must return exit code 0
3. If any new violations appear that were NOT in the original report — fix them silently and note in the summary
4. Report final status:
- ✅ Clean — zero violations remaining
- ⚠️ Remaining — list unresolved items with reason
@@ -0,0 +1,73 @@
# Review Checklist
Full criteria for categorizing findings in the Python review skill.
## 🔴 Must Fix — Correctness & Type Safety
These block merge. Apply by default.
### mypy strict violations
- `error:` any mypy error (all are must-fix under strict mode)
- Implicit `Any` — untyped function parameters or return values
- `type: ignore` without a specific error code (e.g. bare `# type: ignore`)
- Incompatible types in assignment or return
- Missing `--strict` compatibility: missing `py.typed`, missing stubs
### Logic & Security (manual review)
- Mutable default arguments: `def f(x: list = [])` → use `None` + guard
- Shadowing built-ins: `list`, `dict`, `id`, `type`, `input`, etc.
- Uncaught exceptions from external I/O without explicit handling
- SQL/shell injection risks (string formatting into queries/commands)
- Hardcoded secrets or credentials
- `assert` used for runtime validation (stripped with `-O`)
---
## 🟡 Should Fix — Code Quality
These hurt maintainability. Fix unless explicitly skipped.
### ruff violations (common)
- `E501` — line too long (respect `line-length` from pyproject.toml)
- `F401` — unused import
- `F841` — local variable assigned but never used
- `B006` — mutable argument default
- `B007` — loop variable unused
- `UP` prefix — pyupgrade rules (use modern Python syntax)
- `SIM` prefix — simplifiable conditions
- `RUF` prefix — Ruff-specific best practices
### Manual quality
- Missing return type annotation on public functions/methods
- Missing docstring on public API (classes, public methods, module)
- `pass` in `except` block without a comment explaining why
- `print()` left in production code (use `logging`)
- Overly broad `except Exception` without re-raise or specific handling
- Dead code: unreachable branches, commented-out code blocks
---
## 🟢 Consider — Optimization & Modern Python 3.13+
Suggestions only. Offer but don't apply without confirmation.
### Python 3.13+ idioms
- Use `type X = ...` (PEP 695) instead of `TypeAlias`
- Use `X | Y` union syntax instead of `Union[X, Y]` or `Optional[X]`
- Use `TypeVar` with `type` statement (PEP 695) instead of old `TypeVar()`
- `@override` decorator (PEP 698) for overriding methods
- `tomllib` (stdlib) instead of third-party TOML parsers
- `pathlib.Path` instead of `os.path` string operations
### Performance
- Generator expressions instead of list comprehensions when result is iterated once
- `__slots__` on data-heavy classes to reduce memory
- `functools.cache` / `functools.lru_cache` for pure deterministic functions
- Avoid repeated attribute lookup in tight loops (`local = self.attr`)
- Prefer `collections.deque` over `list` for O(1) pop from front
### Readability
- Replace long `if/elif` chains with `match/case` (structural pattern matching)
- Extract deeply nested logic into named helper functions
- Use `dataclasses.dataclass` or `pydantic.BaseModel` for plain data containers
- Named tuples or `TypedDict` instead of untyped `dict` returns