Borrowing it
Nothing to install: this file belongs to deephaven/deephaven-mcp. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/deephaven/deephaven-mcp/main/.agents/skills/ref-python-coding-practices/SKILL.mdgit clone --depth 1 https://github.com/deephaven/deephaven-mcpWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/deephaven/deephaven-mcp/ref-python-coding-practices)<a href="https://agentmods.dev/skills/deephaven/deephaven-mcp/ref-python-coding-practices"><img src="https://agentmods.dev/badge/skills/deephaven/deephaven-mcp/ref-python-coding-practices/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/deephaven/deephaven-mcp/ref-python-coding-practices"><img src="https://agentmods.dev/badge/skills/deephaven/deephaven-mcp/ref-python-coding-practices.svg" alt="Reviewed on agentmods" width="80" height="20"></a>- NVIDIA SkillSpector pass
What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00125 | $0.05698 |
| Opus 5.5 | $0.00050 | $0.02279 |
| Sonnet 5.5 | $0.00025 | $0.01140 |
| Haiku 4.5 | $0.00013 | $0.00570 |
Grade A, and why
ref-python-coding-practices scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 1mo ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 104 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Python Coding Practices
- A Python file must not access private variables, functions, or methods in another file or package. It is ok for the test file for a package to access and use the package being tested, even if it is private, and it is ok for the test file to access private variables, functions, and methods in the package.
- All MCP tools (async functions registered via
server.tool()(fn)insideregister_tools(server: FastMCP)) have specific docstring requirements — apply thepydocs-improveskill for the full rules, including required "Terminology Note" and "Format Accuracy for AI Agents" sections. - f-strings are preferred over
%and.format()in format statements. - File moves and renames preserve history — use
git mvandgit rm, never delete-plus-create. Canonical source:AGENTS.mdVersion Control. - A Python file named
<file>.pyshould have a single test file namedtest_<file>.py. An exception is made for integration tests which are namedtest_<file>_integration.py. Both the unit test and the integration test live in the sametests/<package>/directory that mirrors the source's package — not in a separate top-level directory liketests/<package>_integration/. The correct shape istests/test__logging.pyandtests/test__logging_integration.pyas siblings; the wrong shape is a paralleltests/integration/tree.- The mirror root follows the source root.
src/deephaven_mcp/cli/_help.py→tests/cli/test__help.py; the top-levelscripts/convert_config_v1_to_v2.py→tests/scripts/test_convert_config_v1_to_v2.py. A directory that is not a Python package of the shipped library still gets its mirror. test__<name>.py(double underscore) is reserved for mirroring a private module or package named_<name>.tests/cli/test__daemon_integration.pyis correct becausecli/_daemon/exists. Applying that form to theconfigintegration test would have been wrong — there is nocli/_configmodule or package — which is why it lives attests/cli/_commands/test_config_integration.py, mirroringcli/_commands/config.py. Using the double-underscore form for anything else advertises a source file that was never written, the single most common way test layout drifts.- A test whose subject is broader than one source file — a guardrail/contract test, or a package-scope integration test — is named for its subject or invariant (never for a module it does not mirror) and lives in the directory mirroring the narrowest scope containing everything it validates. A guardrail test also carries
@pytest.mark.guardrail, so the project's convention-enforcement suite is selectable withuv run pytest -m guardrail. Guardrails are deliberately not collected into one directory: each sits with the code it guards, and the marker — not a shared path — is what makes the family selectable.- Scope means the declarations a guardrail audits, not every package it imports. A drift check reads one side's declarations and compares them against the other side as reference data; it belongs with the declaring side.
tests/cli/test_tool_wrapper_drift.pyimports from bothcli/andmcp_systems_server/_tools/, but thewraps_tooldeclarations it audits exist only incli/, so it lives intests/cli/rather than at thetests/root. - Canonical implementations:
tests/test_field_docs_contract.py(walks the whole package, so thetests/root is the only scope wide enough),tests/cli/test_help_contract.py(every command's help satisfies the help contract),tests/cli/test_tool_wrapper_drift.py(every CLI wrapper matches its MCP tool),tests/agents/test_skills_catalog.py(mirrors.agents/, not asrc/package at all),tests/mcp_systems_server/_tools/test_tool_module_inventory.py(the tool-module set matches its documented inventory).
- Scope means the declarations a guardrail audits, not every package it imports. A drift check reads one side's declarations and compares them against the other side as reference data; it belongs with the declaring side.
- The mirror root follows the source root.
- Prefer specific type hints over
Any. UsingAnyrequires an inline justification comment naming the external constraint (third-party stub gap, dynamic plugin interface) that forces it. Without the comment, mypy and reviewers cannot distinguish a deliberateAnyfrom a lazy one. - Do not use
hasattrorgetattrfor type narrowing or feature detection. They silently maskAttributeErrors and bypass mypy. Preferisinstance, structural typing (typing.Protocol), or restructuring the API so the attribute is always present. Whengetattris genuinely required (reflection over a closed set of names), pair it with an inline comment naming the constraint. - Use American English spelling throughout all code, comments, docstrings, and documentation. For example: "initialized" not "initialised", "recognized" not "recognised", "color" not "colour". Mechanically enforced by
uv run codespell(part of./bin/precommit.sh) using the en-GB-to-en-US dictionary; silence an intentional non-American form (e.g. a quoted counterexample) with an inlinecodespell:ignorecomment on the same line, followed by the comma-separated words to ignore. - Unused function parameters should be indicated by prefixing the parameter name with a single underscore (e.g.,
_request,_host,*_args,**_kwargs). This is the conventionruff/pyright/pylintrecognize out of the box and derives from PEP 8's throwaway-variable convention. Do not usedel paramat the top of a function body to silence unused-argument warnings. The leading-underscore prefix is preferred overdel paramfor all new code.- Exception: when callers of the function pass the argument by keyword (and changing the public name would be a breaking change), keep the original name. In that case, either suppress the lint warning locally or use
*_args/**_kwargsfor generic stubs. - Framework/dispatcher-driven handlers (Starlette route handlers, protocol-dispatch callbacks in
_run_server, etc.) receive their arguments positionally — the framework does not pass them by keyword name — so the previous exception does not apply and you should use the_prefix on unused parameters there.
- Exception: when callers of the function pass the argument by keyword (and changing the public name would be a breaking change), keep the original name. In that case, either suppress the lint warning locally or use
- In tests, use
AsyncMockfor async functions/coroutines andMagicMockfor synchronous ones. UsingMagicMockwhereAsyncMockis needed is a common mistake — it causes tests to pass or fail misleadingly because the mock does not properly handleawait. - Do not use
assertfor invariants or defensive checks in production code undersrc/. Python's-Oflag strips assertions, and the project's lint config (ruffruleS101) flags them — adding# noqa: S101to bypass that rule is not acceptable. For internal invariant violations, raisedeephaven_mcp._exceptions.InternalError(or a more specific subclass) with a descriptive message. Every defensive raise must have a unit test that triggers it — if the path is "unreachable in normal use," construct the test fixture that proves the guard fires when bypassed.assertis fine in test files (tests/) where it is the standard expression of test expectations. - Docstrings describe what the function, method, class, value, module, or package is and does — never why it exists. Design rationale, API-symmetry justifications, cross-call-site narratives, and meta-commentary about how the code fits with other code belong in commit messages, PR descriptions, or — when truly load-bearing — a brief comment near the relevant line. Deletion test: if a docstring's body would not make sense to a caller trying to use the function (it explains the author's reasoning rather than the contract), delete that body.
- Contract-level details are part of the what. Details that affect how a caller uses the function (e.g., "returns
Nonewhen X so the caller can skip the retry") belong in the docstring. - Constants and getters stay minimal. A constant's docstring is one line stating what the value represents. A getter that reads a config key describes the key it reads and the fallback — it does not narrate the larger API's design.
- Package
__init__.pydocstrings are the most-violated case. Apply thepydocs-improve"Module and package docstrings" section for the required shape. - MCP tool docstrings under rule 2 are a deliberate exception — their extra sections are part of the contract for AI-agent callers.
- Contract-level details are part of the what. Details that affect how a caller uses the function (e.g., "returns
- Configuration tunables live in the JSON configuration tree as Pydantic-validated fields, not as ad-hoc
os.environreads or asDEFAULT_FOOconstants. The only configuration-location environment variable the server itself reads isDH_AI_DATA_DIR; the log level comes fromPYTHONLOGLEVELviasetup_logging()(docs/ENV.mdis the canonical inventory). Apply theref-configuration-conventionsskill before adding a new tunable, refactoring a config model, or wiring an environment variable into the code. - Every field on a field-bearing value class — a Pydantic
StrictSchema/RedactableSchemasubclass, a@dataclass, or atyping.NamedTuple— carries a PEP 257 trailing docstring, never a class-levelAttributes:block. Trailing docstrings sit next to the field, survive refactors, and (for Pydantic) reach runtime consumers (model_fields[name].description,model_json_schema(), MCP tool schemas) that anAttributes:block does not; explicitField(description="...")works but violates project style. The Pydantic subset is enforced bytests/test_field_docs_contract.py;@dataclassandNamedTupleare convention. Canonical implementations:cli/_runtime.py(Runtime, a dataclass),cli/_help.py(OutputField,OutputSpec); apply theref-configuration-conventionsskill for the Pydantic rule and examples.- Plain enums follow the same rule. A plain
enum.StrEnum/enum.IntEnum/enum.Enummember carries a PEP 257 trailing docstring next to its value, never a class-levelMembers:/Values:block. Canonical implementations:SignalOutcome(_processes.py),DaemonState(cli/_commands/daemon.py),InitializationPhase(resource_manager/_registry.py),SystemType/SessionOrigin(_taxonomy.py),ResourceLivenessStatus(resource_manager/_manager.py). - Carve-out: metadata-bearing enums that bind per-member attributes via
__new__. When an enum stores per-member metadata (help text, exit codes, structured payload) by overriding__new__and constructing each member with positional metadata args, the metadata strings are the documentation and trailing docstrings would be redundant. Canonical implementations:ExitCode,ErrorCode(cli/_errors.py). This is the only exception to the per-member-docstring rule for enums.
- Plain enums follow the same rule. A plain
dhcliCLI isclick+@run_async+CliError. Click commands live undersrc/deephaven_mcp/cli/_commands/*.py;argparseis not used. Async callbacks must be wrapped with@run_asyncfromcli/_async.py— never callasyncio.runinline. User-facing failures mustraise CliError(message, code=ErrorCode.X)fromcli/_errors.py— neverprint(..., file=sys.stderr); return 2. Apply thecli-command-addskill when adding or renaming a CLI command.- Surfaced help is plain text, governed by
ref-cli-help-standards, not pydocs. CommandHelpSpecstrings (rendered bybuild_help), everyclick.option(help=...), group docstrings used as help, andErrorCode.help_textare rendered verbatim by click and surfaced in the agents manifest, so they carry no reStructuredText markup (no``, no:func:/:class:). This is the inverse of rule 12, which governs internal (non-surfaced) docstrings — those keep the RST convention. Applycli-help-improve/cli-help-accuracyto the surfaced strings.
- Surfaced help is plain text, governed by
- Python version floor. The supported Python floor is authoritative in
pyproject.tomlunderrequires-python. Rungrep requires-python pyproject.tomlbefore using version-gated syntax — PEP 695 generics (def f[T](...)),tomllib,typing.override,StrEnum, etc. — and re-check whenever you introduce a feature that landed in a recent Python release. Do not duplicate the version number elsewhere in code, docs, or skills; letpyproject.tomlbe the single source of truth. - Named domain exceptions live in
src/deephaven_mcp/_exceptions.py. Inline definitions in the raising module are forbidden — the exceptions module is the single source of truth for the project exception hierarchy.- Inheritance: every named exception inherits — directly or transitively — from
McpError, so unified handling (catch-all middleware, structured logging, the CLI'sCliErrormapping) sees it. - Organization: file is sectioned by domain (
# Session Exceptions,# Configuration Exceptions,# Daemon Registry Exceptions, …). New domains add a base class plus specific subclasses, mirroringSessionError→SessionCreationErrorandDaemonRegistryError→RegistryCorruptError. - Exports: every new name appears in
_exceptions.__all__and in the equality check intests/test__exceptions.py::test_all_exceptions_exported— that test is the enforcement mechanism. The raising module imports from_exceptions; the package__init__.pymay re-export for ergonomic call sites. - Carve-out: plain
RuntimeError/ValueErrorsubclasses are reserved for genuinely-internal helpers that callers never name.
- Inheritance: every named exception inherits — directly or transitively — from
- Closed-set dispatches must be statically exhaustive. When code dispatches on a value drawn from a closed set — a
Literal, anEnum, or a tuple of accepted values — every member must have an explicit case and the fallthrough must calltyping.assert_never(value). Adding a new member must surface as a mypy error in every consumer until each branch is written.- Canonical
matchform:
- Canonical
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 1mo ago Changed · +6 lines a4729c780b05
- 1mo ago First seen · 98 lines · 125 tokens per session scan A 2baf7241f794
ref-python-coding-practices is a skill published in the GitHub repository deephaven/deephaven-mcp (5 stars, last pushed 2d ago), licensed Apache-2.0. It adds 125 tokens to every session and 5,698 once invoked, about $0.0005 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
matlab
Builds, reviews, migrates, and plans MATLAB or GNU Octave numerical workflows. Use for arrays, tabular/time data, tests, projects, graphics, MAT files, and explicit Python interoperability.
pennylane
Builds and differentiates PennyLane quantum circuits, hybrid PyTorch or JAX models, molecular VQE and QAOA workflows. Use for variational quantum algorithms, quantum machine learning, simulator validation, and moving validated circuits to provider plugins. For hardware-specific compilation use qiskit or cirq; for…
holoscan-install-wheel
Install Holoscan SDK 5.x CUDA 13 Python wheels in an isolated environment, choosing the full stack or version-matched components.
rocm-kernels
Provides guidance for writing and benchmarking optimized Triton kernels for AMD GPUs (MI355X, R9700) on ROCm, targeting HuggingFace diffusers (LTX-Video, SD3, FLUX) and transformers. Core kernels: RMSNorm, RoPE 3D, GEGLU, AdaLN. Includes XCD swizzle, autotune, diffusers integration patterns, and LTX-Video pipeline…
typing-exclusion-worker
Python typing exclusion worker: remove assigned mypy exclusion modules in small scoped batches, fix typing issues, run validation, and produce a structured completion summary. Use when running parallel typing-debt workers or when asked to remove modules from pyproject mypy exclusion overrides.
python
Python development with ruff, mypy, pytest - TDD and type safety.