python-patterns
/python-patterns
Pisze czytelny, typowany i dobrze utrzymywalny kod Python, dobiera model współbieżności i strukturę projektu.
- Autor
- Sanit-mann ↗
- Repozytorium
- The-Insectoids ↗
- Licencja
- MIT
- Ostatnia zmiana repozytorium
- 12.11.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 2
- Skrypty
- 0
- Komentarze HTML
- 0
- Adresy URL w SKILL.md
- 0
Brak sygnałów. Repozytorium zmienione 12.11.2026, bez odwołań do wycofanych modeli i API.
MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.
Co robi i kiedy
Pisze czytelny, typowany i dobrze utrzymywalny kod Python, dobiera model współbieżności i strukturę projektu.
Oryginalny opis (EN)
Idiomatic, typed, maintainable Python. Covers readability rules, type hints, exceptions, context managers, generators, dataclasses, choosing a concurrency model, project layout and tooling. Use when writing, refactoring or reviewing Python code. For tests load python-testing; for FastAPI or Django load those skills.
Jak działa
- When to use
- Before you write
- Core rules
- Type hints
- Exceptions
- Resources and data
- Decorators
- Concurrency: pick by workload
- Project layout
- Tooling (as of late 2026; use what the project already has)
Podgląd SKILL.md
---
name: python-patterns
description: Idiomatic, typed, maintainable Python. Covers readability rules, type hints, exceptions, context managers, generators, dataclasses, choosing a concurrency model, project layout and tooling. Use when writing, refactoring or reviewing Python code. For tests load python-testing; for FastAPI or Django load those skills.
metadata:
kind: skill
castes: [coder, reviewer]
tags: [python, style, typing]
version: 1
status: vetted
sources:
- repo: affaan-m/ecc
path: skills/python-patterns/SKILL.md
license: MIT
---
# Python Patterns
Write Python that is obvious to read, typed at its boundaries, and fails loudly.
## When to use
- Writing or changing Python modules, packages or scripts.
- Reviewing Python for idiom, typing and structure.
Not for: test design (python-testing), framework specifics (fastapi-patterns, django-patterns), cross-language error design (error-handling).
## Before you write
1. Read `pyproject.toml` (or `setup.cfg` / requirements files): `requires-python`, formatter, linter, type checker, test runner.
2. Use only language features the project's minimum Python version supports. For new projects pick a supported version (3.11 or newer as of late 2026; 3.10 reached end of life in October 2026).
3. Follow the tools and layout already in use. Do not introduce a new tool in the same change as a feature.
## Core rules
- **Readability beats cleverness.** Descriptive names. A comprehension only when the logic stays simple; otherwise a loop or a helper function.
- **Explicit beats implicit.** No side effects at import time (no DB connections, no config loading, no logging setup in library modules). Do setup in a function called from the entry point.
- **EAFP where it fits.** `try/except KeyError` is idiomatic for lookups and races (file may vanish). Use `dict.get(key, default)` for simple defaults. Use a check first (LBYL) when the check is cheap and a broad `except` would hide other bugs.
- **Formatting is the formatter's job.** Do not hand-format against PEP 8; run the project formatter.
## Type hints
- Annotate parameters and return types of every public function; internal helpers too unless trivial.
- Use built-in generics and union syntax: `list[str]`, `dict[str, int]`, `X | None`. `typing.List`, `Dict`, `Optional`, `Union` are legacy forms.
- Accept abstract, return concrete: parameters as `Iterable[T]`, `Sequence[T]`, `Mapping[K, V]` (from `collections.abc`); return `list[T]`, `dict[K, V]`.
- Use `typing.Protocol` for duck-typed interfaces instead of inheritance added only for typing.
- Generics and aliases: on 3.12+ use `def first[T](items: list[T]) -> T | None` and `type JSON = ...`; on older versions use `TypeVar` and `TypeAlias`.
- Avoid `Any` except at true boundaries (parsed JSON, untyped libraries) and narrow it straight away.
- Run the project's type checker (mypy or pyright) on changed code before calling it done.
## Exceptions
- Catch the narrowest exception you can actually handle. Never bare `except:`. `except Exception` only at a top-level boundary that logs and re-raises or converts.
- Chain when translating: `raise ConfigError(f"bad config: {path}") from e`. Use `from None` only to deliberately hide irrelevant internals.
- One base exception per package (`class AppError(Exception)`) and specific subclasses for conditions callers act on.
- Do not return `None` to signal failure when the caller needs to know why; raise instead.
- For envelopes, retries and user-facing messages, load error-handling.
## Resources and data
- Use `with` for files, locks, connections and transactions. Write custom managers with `contextlib.contextmanager` (wrap the `yield` in `try/finally`) or a class whose `__exit__` returns `False` so exceptions propagate. Use `contextlib.ExitStack` for a variable number of resources.
- `pathlib.Path` for paths. f-strings for formatting, but pass lazy arguments to logging: `log.info("user=%s", user_id)`.
- Generators for large or streaming data: `sum(x * x for x in xs)`, not `sum([...])`. Read big files line by line.
- Build strings with `"".join(parts)`, not `+=` in a loop.
- Data containers: `@dataclass` (prefer `frozen=True, slots=True`; `field(default_factory=list)` for mutable defaults; check invariants in `__post_init__`). `NamedTuple` for small immutable records. Pydantic or attrs when you need validation of untrusted input at a boundary.
- `__slots__` only when there are many instances and memory matters.
- `enum.Enum` / `StrEnum` instead of bare string constants for closed sets of values.
## Decorators
- Always use `functools.wraps`. Keep the wrapper thin; put real logic in plain functions so it can be tested directly.
- Prefer `functools.cache` / `lru_cache` to hand-rolled memoisation. Do not cache instance methods without care: the cache holds `self` alive.
## Concurrency: pick by workload
| Workload | Use |
|---|---|
| I/O-bound, modest fan-out, sync codebase | `concurrent.futures.ThreadPoolExecutor` |
| I/O-bound, high fan-out, async codebase | `asyncio` with `asyncio.TaskGroup` (3.11+) or `gather(..., return_exceptions=True)` |
| CPU-bound | `ProcessPoolExecutor`, or a native/vectorised library |
Rules:
- Never call blocking I/O inside `async def`. Use an async client or `asyncio.to_thread`.
- Every network call has a timeout.
- Bound concurrency (pool size, `asyncio.Semaphore`).
- Do not swallow per-task errors; collect them and report or re-raise.
## Project layout
- `src/<package>/` layout, `tests/` beside it, all tool config in `pyproject.toml`.
- Import order: standard library, third-party, local; let the linter sort them. No `from module import *`. Absolute imports for package code.
- `__init__.py` exposes only the public API; set `__all__` when re-exporting.
- Lock dependencies with the project's tool (uv, Poetry, pip-tools or similar). Adding a new dependency needs approval in the hive.
## Tooling (as of late 2026; use what the project already has)
- Format and lint: Ruff (`ruff format`, `ruff check`) commonly replaces black, isort and flake8.
- Types: mypy or pyright.
- Tests and coverage: pytest (see python-testing).
- Security: `pip-audit` for dependency CVEs; Ruff's `S` rules (bandit) for code.
Sample `pyproject.toml`: [references/idioms.md](references/idioms.md#pyprojecttoml).
## Anti-patterns (flag in review)
- Mutable default argument `def f(items=[])` → default `None`, create inside.
- `type(x) == list` → `isinstance(x, list)`.
- `x == None` → `x is None`.
- Bare `except:` or `except Exception: pass`.
- `from module import *`.
- Blocking calls inside async code.
- `print` for diagnostics in library code → `logging`.
- Shadowing builtins (`list`, `id`, `type`, `input`) in non-trivial scopes.
- Module-level mutable state or connections created on import.
- Over-long comprehensions with several `if`/`for` clauses.
## Done when
- Formatter, linter and type checker pass with the project's config.
- Public functions are typed; docstrings exist where behaviour is not obvious from the name.
- No anti-pattern above remains in the changed code.
Code examples for every section: [references/idioms.md](references/idioms.md).
Pliki w paczce (2)
- SKILL.md 7 KB
- references/idioms.md 7 KB
Wersje
| Repozytorium | Wynik | Licencja |
|---|---|---|
| Ta strona · Sanit-mann/The-Insectoids | 100 | MIT |
| Reprograme/redevkit | 100 | MIT |
| komluk/scaffolding | 100 | MIT |
| affaan-m/ECC | 100 | MIT |
| jeffersonvalente/cardume | 100 | MIT |
| affaan-m/ECC | 95 | MIT |
| SHRIJANAGAIN/Nemo-Cli | 95 | Apache-2.0 |
Migawka bazy z 13.11.2026 · wersja paczki 84dd9d1da302 (skrót SHA-256 całej paczki)
Pobrania w ostatnich 30 dniach: 0 · ranking
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 100python
Wspiera pisanie aplikacji w Python 3.10 do 3.14: typowanie, async, dataclasses, menedżery kontekstu, instrukcja match i nowoczesne wzorce. - 100rc-python
Wspiera idiomatyczny, typowany Python 3.12+ z asyncio, dataclasses, pytest, ruff i uv przy pisaniu oraz przeglądzie kodu. - 100python
Pomaga pisać idiomatyczny kod Python 3.11+: adnotacje typów, async/await, generatory, dataclasses, menedżery kontekstu, środowiska wirtualne i optymalizacja wydajności. - 86python-engineering
Wdraża lub przegląda utrzymywalny kod Python: moduły, skrypty, biblioteki, testy i pakowanie. - 90modern-python
Pisze i przegląda idiomatyczny, bezpieczny Python 3.13+: kolekcje, generatory, typowanie, dataclassy, asyncio i testy pytest. - 90python-guide
Podpowiada przy pisaniu i edycji Pythona 3.12+ dla API, przetwarzania danych, skryptów i narzędzi: async, typy, pathlib i pytest.