writing-python
Imported from alexei-led/cc-thingz/dist/claude/programming/skills/writing-python.
Install
npx skills add https://github.com/alexei-led/cc-thingz/tree/master/dist/claude/programming/skills/writing-python
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install alexei-led-cc-thingz@llmmart
git clone https://github.com/alexei-led/cc-thingz.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole alexei-led/cc-thingz collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Python Development
pyproject.toml is the source of truth for the Python target, tools, scripts, and dependencies. Check it, .python-version, and CI before using 3.12-only syntax. Project conventions win over these defaults.
Toolchain
- uv for environments and commands (
uv run,uv add); never callpipdirectly. Match the lockfile already in use. - Ruff for lint and format. Pyright for types, or
tyonly when the project has adopted it. - pytest for tests.
Defaults
- Stdlib before packages:
argparse,dataclasses,pathlib,json,urllib,logging. Do not add Rich, pydantic, or dotenv only for polish. - 3.12+ typing:
X | Y, builtin generics, PEP 695 generics andtypealiases. Keep legacyTypeVarstyle when editing pre-3.12 modules. @dataclass(frozen=True, slots=True)for small values;TypedDictwithNotRequiredat recurring JSON boundaries;Protocolowned by the consumer. Keepdict[str, Any]at the boundary only.- Import collection ABCs from
collections.abc. TakeSequence[T]for read-only inputs. - Wrap errors with
raise DomainError(...) from exc. Catch broad exceptions only where they become an exit code, response, log entry, or re-raise. - Async:
asyncio.TaskGroupfor sibling tasks,asyncio.timeoutaround external waits. Keep references to background tasks so their exceptions surface. - Text I/O takes an explicit
encoding. Sort glob results when order reaches output or tests. - Libraries log through
logging; they never print diagnostics.
CLIs
argparsefor small tools; Click or Typer only when the project already uses them.main(argv: Sequence[str] | None = None) -> int; callasyncio.runonly there. Expose it via[project.scripts]and keeppython -m pkgworking.- Config precedence: flag, env, config file, default.
References
- testing.md: read when adding or reshaping tests, or when the suite is slow.
- linting.md: read when changing Ruff or type-checker config, or the lint/type-check commands.
Done when the relevant build/test/lint checks pass on what you changed, or you name each check that did not run and why.
Files (cc-thingz)
-
references
-
linting.md 878 B
# Python Linting Use the project's configured commands first. Edit loop, scoped to changed files: ```bash uv run ruff check --fix path/to/file.py uv run ruff format path/to/file.py uv run pyright path/to/file.py ``` Full gate before finishing: ```bash uv run ruff check . uv run ruff format --check . uv run pyright # or: uv run ty check, when the project adopted ty ``` - Fall back to the project's mypy command when that is what it configures. - Fix the code instead of loosening Ruff rules or type strictness. Ask before changing rule config in `pyproject.toml` or `pyrightconfig.json`. - A `# type: ignore` or `# pyright: ignore` names the rule and the reason. No blanket ignores. - Missing imports or stubs: check `uv.lock` and declared dependencies before adding a suppression. - Exclude generated and vendored code in config, not with ad hoc command filters. -
testing.md 1.5 KB
# Python Testing ## Pytest Setup - New config: `testpaths`, `--import-mode=importlib`, `--strict-markers`, `-ra`. - Mark slow tiers (`integration`, `e2e`, `live`) and keep them out of the default run. - Add `pytest-asyncio`, `pytest-cov`, `pytest-timeout`, `pytest-xdist`, `pytest-mock`, or Hypothesis only when tests need them or the project already has them. - With `pytest-asyncio` in `asyncio_mode = "auto"`, async tests need no marker. - Keep coverage in a dedicated command or job, not the edit loop. ## Style - `pytest.param(..., id="...")` when case names make failures readable. - Factory fixtures for data with per-test variation. Widen fixture scope only for immutable setup. Use autouse only for isolation every test needs. - Prefer `tmp_path` over mocking the local filesystem. - Mock with `spec`/`autospec`, and patch where the name is looked up, not where it is defined. - CLIs: Click's `CliRunner`, or call `main(argv)` and assert exit code plus `capsys` output. Spawn a subprocess only when `main(argv)` cannot give the same signal. - Hypothesis fits parsers, serializers, and normalizers with many edge cases. ## Slow Suites - Find the cost first: `pytest -q --durations=10 --durations-min=0.5`. - Common waste: fixed sleeps, real I/O in unit tests, repeated expensive setup, heavy import-time work. Replace waits with poll-until-condition helpers or a controlled clock. - Use `pytest-xdist` only when configured or approved. Key shared external resources by `PYTEST_XDIST_WORKER`.
-
-
SKILL.md 2.6 KB
--- {"agent":"engineer","allowed-tools":["Read","Bash","Grep","Glob","Edit","Write","LS"],"context":"fork","description":"Idiomatic Python 3.12+ development. Use when writing Python code, CLI tools, scripts, or services. Emphasizes stdlib, type hints, fast pytest feedback, uv/ruff/pyright toolchain, optional project-adopted ty, and minimal dependencies. NOT for Go, Rust, TypeScript, or shell-only tasks.","name":"writing-python","user-invocable":false} --- # Python Development `pyproject.toml` is the source of truth for the Python target, tools, scripts, and dependencies. Check it, `.python-version`, and CI before using 3.12-only syntax. Project conventions win over these defaults. ## Toolchain - uv for environments and commands (`uv run`, `uv add`); never call `pip` directly. Match the lockfile already in use. - Ruff for lint and format. Pyright for types, or `ty` only when the project has adopted it. - pytest for tests. ## Defaults - Stdlib before packages: `argparse`, `dataclasses`, `pathlib`, `json`, `urllib`, `logging`. Do not add Rich, pydantic, or dotenv only for polish. - 3.12+ typing: `X | Y`, builtin generics, PEP 695 generics and `type` aliases. Keep legacy `TypeVar` style when editing pre-3.12 modules. - `@dataclass(frozen=True, slots=True)` for small values; `TypedDict` with `NotRequired` at recurring JSON boundaries; `Protocol` owned by the consumer. Keep `dict[str, Any]` at the boundary only. - Import collection ABCs from `collections.abc`. Take `Sequence[T]` for read-only inputs. - Wrap errors with `raise DomainError(...) from exc`. Catch broad exceptions only where they become an exit code, response, log entry, or re-raise. - Async: `asyncio.TaskGroup` for sibling tasks, `asyncio.timeout` around external waits. Keep references to background tasks so their exceptions surface. - Text I/O takes an explicit `encoding`. Sort glob results when order reaches output or tests. - Libraries log through `logging`; they never print diagnostics. ## CLIs - `argparse` for small tools; Click or Typer only when the project already uses them. - `main(argv: Sequence[str] | None = None) -> int`; call `asyncio.run` only there. Expose it via `[project.scripts]` and keep `python -m pkg` working. - Config precedence: flag, env, config file, default. ## References - [testing.md](references/testing.md): read when adding or reshaping tests, or when the suite is slow. - [linting.md](references/linting.md): read when changing Ruff or type-checker config, or the lint/type-check commands. Done when the relevant build/test/lint checks pass on what you changed, or you name each check that did not run and why.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.