home / skills / dagster-io / erk / dignified-python

dignified-python skill

/.claude/skills/dignified-python

This skill enforces dignified Python coding standards with automatic version detection, guiding you through modern typing, pathlib usage, and robust error

npx playbooks add skill dagster-io/erk --skill dignified-python

Review the files below or copy the command above to add this skill to your agents.

Files (14)
SKILL.md
3.4 KB
---
name: dignified-python
description: Python coding standards with automatic version detection.
  Use when writing, reviewing, or refactoring Python to ensure adherence to LBYL exception
  handling patterns, modern type syntax (list[str], str | None), pathlib operations,
  ABC-based interfaces, absolute imports, and explicit error boundaries at CLI level.
  Also provides production-tested code smell patterns from Dagster Labs for API design,
  parameter complexity, and code organization. Essential for maintaining erk's dignified
  Python standards.
---

# Dignified Python Coding Standards

## Core Knowledge (ALWAYS Loaded)

@dignified-python-core.md

## Version Detection

**Identify the project's minimum Python version** by checking (in order):

1. `pyproject.toml` - Look for `requires-python` field (e.g., `requires-python = ">=3.12"`)
2. `setup.py` or `setup.cfg` - Look for `python_requires`
3. `.python-version` file - Contains version like `3.12` or `3.12.0`
4. Default to Python 3.12 if no version specifier found

**Once identified, load the appropriate version-specific file:**

- Python 3.10: Load `versions/python-3.10.md`
- Python 3.11: Load `versions/python-3.11.md`
- Python 3.12: Load `versions/python-3.12.md`
- Python 3.13: Load `versions/python-3.13.md`

## Conditional Loading (Load Based on Task Patterns)

Core files above cover 80%+ of Python code patterns. Only load these additional files when you detect specific patterns:

Pattern detection examples:

- If task mentions "click" or "CLI" -> Load `cli-patterns.md`
- If task mentions "subprocess" -> Load `subprocess.md`

## When to Read Each Reference Document

The `references/` directory contains detailed guidance for specialized topics. Load these on-demand when you encounter relevant patterns:

### `references/exception-handling.md`

**Read when**:

- Writing try/except blocks
- Wrapping third-party APIs that may raise
- Seeing or writing `from e` or `from None`
- Unsure if LBYL alternative exists

### `references/interfaces.md`

**Read when**:

- Creating ABC or Protocol classes
- Writing @abstractmethod decorators
- Designing gateway layer interfaces
- Choosing between ABC and Protocol

### `references/typing-advanced.md`

**Read when**:

- Using typing.cast()
- Creating Literal type aliases
- Narrowing types in conditional blocks

### `references/module-design.md`

**Read when**:

- Creating new Python modules
- Adding module-level code (beyond simple constants)
- Using @cache decorator at module level
- Seeing Path() or computation at module level
- Considering inline imports

### `references/api-design.md`

**Read when**:

- Adding default parameter values to functions
- Defining functions with 5 or more parameters
- Using ThreadPoolExecutor.submit()
- Reviewing function signatures

### `references/checklists.md`

**Read when**:

- Final review before committing Python code
- Unsure if you've followed all rules
- Need a quick lookup of requirements

## How to Use This Skill

1. **Core knowledge** is loaded automatically (LBYL, pathlib, basic imports, anti-patterns)
2. **Version detection** happens once - identify the minimum Python version and load the appropriate version file
3. **Reference documents** are loaded on-demand based on the triggers above
4. **Additional patterns** may require extra loading (CLI patterns, subprocess)
5. **Each file is self-contained** with complete guidance for its domain

Overview

This skill enforces dignified Python coding standards with automatic project Python version detection. It guides writing, reviewing, and refactoring code to match LBYL exception handling, modern typing syntax, pathlib usage, ABC-based interfaces, absolute imports, and explicit CLI-level error boundaries. It also integrates production-tested code smell patterns from Dagster Labs to improve API design and parameter complexity. Use it to keep erk codebases consistent, maintainable, and forward-compatible with targeted Python versions.

How this skill works

The skill first detects the project's minimum Python version by scanning pyproject.toml, setup.py/setup.cfg, and .python-version, defaulting to 3.12 when unspecified. Once the version is determined it loads the corresponding version-specific guidance file and always loads the core ruleset. Additional reference documents and pattern files are loaded on demand when the task mentions specific concerns like CLI, subprocess, exception handling, interfaces, typing, or module design. Each loaded document contains actionable rules, examples, and checklist items tailored to the detected Python version.

When to use it

  • Writing new Python modules or CLIs for erk to ensure consistent style and error boundaries
  • Reviewing or refactoring code to modernize types (e.g., list[str], str | None) and pathlib usage
  • Designing interfaces with ABCs or Protocols and deciding between them
  • Wrapping third-party APIs where LBYL error handling or explicit from e/from None decisions matter
  • Assessing function signatures for API design and parameter complexity issues

Best practices

  • Detect and respect the project's declared minimum Python version before applying rules
  • Prefer LBYL for predictable exception handling and reserve broad except blocks only at CLI boundaries
  • Use modern typing syntax and minimize cast() usage by narrowing types in logic
  • Favor pathlib.Path for filesystem work and avoid module-level side effects
  • Define clear ABC-based interfaces for gateway layers and keep implementations decoupled
  • Keep CLI-level error handling explicit and convert internal exceptions to user-facing messages there

Example use cases

  • Reviewing a pull request to ensure types use PEP 585/604 syntax when the project supports it
  • Refactoring a module that performs Path() operations at import time into lazy functions
  • Designing a public API function and applying Dagster Labs patterns to reduce parameter complexity
  • Converting ad-hoc try/except blocks to LBYL checks or documented boundary handlers
  • Creating a CLI entrypoint that centralizes error translation and exit codes

FAQ

What if the project targets multiple Python versions?

Detect the declared minimum and apply guidance for that baseline; prefer patterns compatible with all supported versions and avoid syntax requiring newer releases unless pinned.

When should I use ABC vs Protocol?

Use ABCs when you need enforcement and shared implementation; use Protocols for structural typing and lighter coupling, consulting the interfaces reference for details.