python-conventions
Python conventions for every repo — typing, dataclasses, return types, docstrings. Use whenever touching Python code.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Python conventions for every repo — typing, dataclasses, return types, docstrings. Use whenever touching Python code.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Model routing for delegated work — use when spawning subagents or workflows, choosing a model for a task, or handing work to the Codex runtime. (Claude Code side; other agents rarely delegate.)
Fleet operations — use when a task involves other machines (discovering, reaching, or reasoning about them), installing/updating/removing any user-level tool, converging a machine, or working with paseo or the agent-fleet repo.
Prove what the Rerun viewer rendered — pixel evidence over logs. Use when a .rrd, blueprint, or Rerun rendering must be visually verified, when a timeline sweep or video of a recording is wanted, when an .rrd must be embedded in an HTML page, or when a gradio/WebViewer surface needs browser validation.
Create self-contained single-file HTML artifacts when an explanation, plan, report, review, comparison, diagram, deck, prototype, or lightweight editor would be more readable, useful, or reusable in a browser than in markdown. Use for making dense information scannable and beautiful with semantic HTML, inline CSS, inline JavaScript, responsive layout, typography, charts, tables, annotations, tabs, collapsibles, timelines, diagrams, and copy/export affordances. Especially use when the user wants an artifact they are likely to open, read, share, or iterate on directly as a .html file.
Create a new single-purpose CV node in the monorepo with API layer (class-based node with verbose Rerun logging, result logging helper, config + result dataclasses), Gradio UI with embedded Rerun viewer (streaming binary stream), CLI entry point (tyro + RerunTyroConfig), and bundled example data. Use when adding a new model, predictor, or pipeline step as a standalone reusable app.
Performs conda-forge operations. Fixes failing builds by analyzing CI logs, creates new packages via staged-recipes, adds cross-compilation and ARM support to feedstocks, and migrates recipes from v0 to v1 format. Use when working with conda-forge feedstocks, staged-recipes, build failures, recipe migrations, or when the user mentions conda-forge.
| name | python-conventions |
| description | Python conventions for every repo — typing, dataclasses, return types, docstrings. Use whenever touching Python code. |
Every section below is a check, not a suggestion: code isn't done until it passes all of them, and a review applies every one.
Projects activate beartype conditionally on the pixi environment:
if os.environ.get("PIXI_DEV_MODE") == "1":
from beartype.claw import beartype_this_package
beartype_this_package()
@beartype decorators manually — the package-level claw covers
everything.Annotate variables at assignment, including intermediates — the verbosity is deliberate: it keeps code self-documenting and gives beartype something to validate at runtime.
Every array annotation carries BOTH dtype and shape:
from jaxtyping import Float, UInt8, Int
rgb: UInt8[np.ndarray, "h w 3"] = load_image(path)
intrinsics: Float[np.ndarray, "3 3"] = calibration.K
indices: Int[np.ndarray, "n"] = np.argsort(scores)
Named/constrained axes are encouraged: Float32[ndarray, "n_verts=778 3"].
Mirror the annotation in the variable NAME with shape/axis/colorspace
suffixes: depth_hw, frames_rgb, bgr_hwc, points_xyz. Redundant with
the type by design — it makes shape/format bugs visible at every call site.
beartype does not support PEP 695 type X = ... statements (ruff's UP040 is
ignored for exactly this reason). Always:
from typing import TypeAlias
ImageBGR: TypeAlias = UInt8[ndarray, "H W 3"]
DeviceChoice: TypeAlias = Literal["auto", "cuda", "cpu"]
from pkg.module import X); relative imports
are legacy, not the target style.@serde, serde.json) — never introduce
pydantic.print(); don't introduce logging frameworks
into packages that don't already have one.DeviceChoice Literal alias + a
resolve_device(device: DeviceChoice = "auto") -> str helper ("auto" →
cuda if available else cpu; explicit "cuda" raises RuntimeError when
unavailable). Pass the resolved device explicitly to
.to(device=..., dtype=...) — never rely on implicit device inference.einops.rearrange/repeat, not manual
.reshape()/.permute() chains.0.0, never 0 — beartype distinguishes
int from float strictly.except Exception around instrumented code without
re-raising BeartypeException first.Each field gets a docstring line directly beneath it (same for pyserde
@serde classes):
@dataclass
class NerfstudioDataParserConfig(DataParserConfig):
"""Nerfstudio dataset config."""
data: Path = Path()
"""Directory or explicit json file path specifying location of data."""
scale_factor: float = 1.0
"""How much to scale the camera origins by."""
downscale_factor: int | None = None
"""How much to downscale images; auto-chosen when None."""
eval_mode: Literal["fraction", "filename", "interval", "all"] = "fraction"
"""Dataset split strategy; see each mode's field below."""
For everything that isn't a dataclass field, follow Google-style docstrings, always including the full jaxtyping shape + dtype for array parameters.
Decision checklist:
@dataclass(slots=True)
(add frozen=True when immutability is wanted). Field annotations +
docstrings stay adjacent; beartype validates per-field.NamedTuple with jaxtyping-annotated fields
(declare __slots__ = () to prevent attribute drift).Do not unpack a call directly into untyped names — route through an annotated intermediate so beartype actually checks the values:
# no: verts, joints = mano_layer(so3, trans)
results: tuple[
Float32[ndarray, "n_frames 778 3"], Float32[ndarray, "n_frames 21 3"]
] = mano_layer(so3, trans)
verts: Float32[ndarray, "n_frames 778 3"] = results[0]
joints: Float32[ndarray, "n_frames 21 3"] = results[1]
When a two-item tuple must travel further, define a TypeAlias (never a
PEP 695 type statement — see Type aliases above) or upgrade to a NamedTuple:
ManoResults: TypeAlias = tuple[Float32[ndarray, "n 778 3"], Float32[ndarray, "n 21 3"]]
ruff: line-length = 150, select = ["E","F","UP","B","SIM","I"],
ignore = ["E501","F722","F821","UP037","UP040"] — F722/F821 suppress
jaxtyping forward-ref false positives; UP037/UP040 protect jaxtyping quotes
and the TypeAlias rule. Typechecking is pyrefly (workspace-level config).