<< All versions
Skill v1.0.0
currentAutomated scan100/100lugassawan/swe-workbench/language-python
──Details
PublishedSeptember 28, 2026 at 02:22 AM
Content Hashsha256:4501a9b426685da2...
Git SHA
──Files
Files (1 file, 5.0 KB)
SKILL.md5.0 KBactive
SKILL.md · 138 lines · 5.0 KB
version: "1.0.0" name: language-python description: Python idioms — PEP 8, context managers, generators, asyncio, and testing. Auto-load when working with .py files, pyproject.toml, requirements.txt, or when the user mentions Python, pytest, asyncio, dataclass, type hints, or virtualenv.
Python
Type hints
- Annotate all function signatures;
Anyis a smell unless at a genuine boundary. - Use
dataclassfor data containers with behavior;TypedDictfor dict-shaped data at boundaries. - Prefer
Protocolover ABC when duck typing suffices — no inheritance required. from __future__ import annotationsfor forward refs in 3.9 and earlier.
python
from dataclasses import dataclass, field@dataclassclass Order:id: stritems: list[str] = field(default_factory=list)total: float = 0.0
Errors and exceptions
- Use exceptions for exceptional paths, not flow control.
- Raise specific subclasses; catch the narrowest class you can handle.
except Exception:is almost always wrong — at minimum log and re-raise.contextlib.suppress(SomeError)for intentional ignore; bareexcept:never.
python
try:result = load(path)except FileNotFoundError:raise MissingConfigError(path) from None
Context managers
withfor any resource with a cleanup obligation: files, locks, DB connections.@contextlib.contextmanagerfor ad-hoc managers without a full class.- Never hold a resource longer than the
withblock.
python
@contextlib.contextmanagerdef managed_resource():r = acquire()try:yield rfinally:release(r)
Generators and iterators
- Prefer generators over materializing full lists when you only iterate once.
yield fromto delegate to sub-generators.- Reach for
itertoolsbefore writing loops:chain,islice,groupby,product.
python
def read_chunks(path: Path, size: int = 4096):with open(path, "rb") as f:while chunk := f.read(size): # walrus operator, 3.8+yield chunk
Concurrency
- GIL caveat: threads don't parallelize CPU-bound work — use
ProcessPoolExecutorormultiprocessing. asynciofor IO-bound concurrency;asyncio.TaskGroup(3.11+) for structured fan-out.ThreadPoolExecutorfor legacy sync IO or blocking C extensions.- One event loop per process; never nest or mix loops.
python
async def fetch_all(urls: list[str]) -> list[str]:async with asyncio.TaskGroup() as tg:tasks = [tg.create_task(fetch(u)) for u in urls]return [t.result() for t in tasks]
Pattern matching (3.10+)
Use match for structural dispatch on data shapes; avoid it as a glorified if/elif chain.
python
match command:case {"action": "move", "direction": dir}:move(dir)case {"action": "quit"}:quit()case _:raise ValueError(f"unknown command: {command}")
Dependencies and packaging
pyproject.tomlis the standard — nosetup.pyin new projects.uvfor fast installs;poetryfor lockfile publishing workflows.- Pin transitive deps via lockfile (
uv.lock,poetry.lock) in applications; use version ranges in libraries. - Always isolate with a virtualenv — never install into the system Python.
Doc comments
- docstring (PEP 257) — a one-line summary in imperative mood —
"""Return the parsed config.""", not a description of what the function is. - Expand to
Args:/Returns:/Raises:sections only when the contract isn't obvious from the signature and type hints.
python
def load_config(path: Path) -> Config:"""Load and validate the config at `path`."""...
Tooling
- Imports:
ruff check --select I --fix - Format:
ruff format/black . - Lint:
ruff check(+mypyfor types) - Test:
pytest(see Testing below)
Testing
pytestoverunittest— fixtures, parametrize, and plugins make it richer.@pytest.mark.parametrizeinstead of loops inside tests.unittest.mock.patchfor external boundaries only; don't mock internals.pytest-asynciofor async tests;respxorhttpxmock transport for HTTP clients.
python
@pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (0, 0, 0)])def test_add(a, b, expected):assert add(a, b) == expected
Performance
- Profile before optimizing:
cProfilefor CPU hotspots,tracemallocfor memory. py-spysamples live processes without code changes.- C extensions (
cffi,Cython) only after profiling confirms a Python bottleneck. - Cache attribute lookups in tight loops:
fn = obj.methodoutside the loop.
Avoid
- Mutable default arguments (
def f(x=[])— useNone, assign inside). from module import *— pollutes namespace, breaks static analysis.global/nonlocalexcept in narrow closures.- Broad
try/exceptblocks that swallow errors silently. subprocess.run(shell=True)with user-controlled input — use the list form.- Reimplementing what
itertools,functools, orcollectionsalready provide.