All skills
docling-project avatar

/dignified-python

@2d1dcde
by Docling Projectdocling-project/docling68k stars
4,979

Opinionated production Python standards with automatic version detection (3.10-3.13). Use when writing, reviewing, or refactoring Python in repos that want modern type syntax, explicit condition checks where practical, pathlib operations, interface guidance, and pragmatic production patterns.

Use this Skill: https://skilld.dev/gh/docling-project/docling/dignified-python

This session only. Nothing lands on disk.

referencesadvancedtyping-advanced.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Advanced Typing Reference

Read when: Using typing.cast(), creating Literal type aliases, narrowing types


Using typing.cast()

Core Rule

ALWAYS verify cast() with a runtime assertion, unless there's a documented reason not to.

typing.cast() is a compile-time only construct—it tells the type checker to trust you but performs no runtime verification. If your assumption is wrong, you'll get silent misbehavior instead of a clear error.

Required Pattern

from collections.abc import MutableMapping
from typing import Any, cast

# CORRECT: Runtime assertion before cast
assert isinstance(doc, MutableMapping), f"Expected MutableMapping, got {type(doc)}"
cast(dict[str, Any], doc)["key"] = value

# CORRECT: Alternative with hasattr for duck typing
assert hasattr(obj, '__setitem__'), f"Expected subscriptable, got {type(obj)}"
cast(dict[str, Any], obj)["key"] = value

Anti-Pattern

# WRONG: Cast without runtime verification
cast(dict[str, Any], doc)["key"] = value  # If doc isn't a dict-like, silent failure

When to Skip Runtime Verification

Default: Always add the assertion when cost is trivial (O(1) checks like in, isinstance).

Skip the assertion only in these narrow cases:

  1. Immediately after a type guard: The check was just performed and would be redundant

    if isinstance(value, str):
        # No assertion needed - we just checked
        result = cast(str, value).upper()
  2. Performance-critical hot path: Add a comment explaining the measured overhead

    # Skip assertion: called 10M times/sec, isinstance adds 15% overhead
    # Type invariant maintained by _validate_input() at entry point
    cast(int, cached_value)

What is NOT a valid reason to skip:

  • "Click validates the choice set" - Add assertion anyway; cost is trivial
  • "The library guarantees the type" - Add assertion anyway; defense in depth
  • "It's obvious from context" - Add assertion anyway; future readers benefit

Why This Matters

  • Silent bugs are worse than loud bugs: An assertion failure gives you a stack trace and clear error message
  • Documentation: The assertion documents your assumption for future readers
  • Defense in depth: Third-party libraries can change behavior between versions

Programmatically Significant Strings

Use Literal types for strings that have programmatic meaning.

When strings represent a fixed set of valid values (error codes, status values, command types), model them in the type system using Literal.

Why This Matters

  1. Type safety - Typos caught at type-check time, not runtime
  2. IDE support - Autocomplete shows valid options
  3. Documentation - Valid values are explicit in the code
  4. Refactoring - Rename operations work correctly

Naming Convention

Use kebab-case for all internal Literal string values:

# CORRECT: kebab-case for internal values
IssueCode = Literal["orphan-state", "orphan-dir", "missing-branch"]
ErrorType = Literal["not-found", "invalid-format", "timeout-exceeded"]

Exception: When modeling external systems, match the external API's convention:

# CORRECT: Match GitHub API's UPPER_CASE
PRState = Literal["OPEN", "MERGED", "CLOSED"]

# CORRECT: Match GitHub Actions API's lowercase
WorkflowStatus = Literal["completed", "in_progress", "queued"]

The rule is: kebab-case by default, external convention when modeling external APIs.

Pattern

from dataclasses import dataclass
from typing import Literal

# CORRECT: Define a type alias for the valid values
IssueCode = Literal["orphan-state", "orphan-dir", "missing-branch"]

@dataclass(frozen=True)
class Issue:
    code: IssueCode
    message: str

def check_state() -> list[Issue]:
    issues: list[Issue] = []
    if problem_detected:
        issues.append(Issue(code="orphan-state", message="description"))  # Type-checked!
    return issues

# WRONG: Bare strings without type constraint
def check_state() -> list[tuple[str, str]]:
    issues: list[tuple[str, str]] = []
    issues.append(("orphen-state", "desc"))  # Typo goes unnoticed!
    return issues

When to Use Literal

  • Error/issue codes
  • Status values (pending, complete, failed)
  • Command types or action names
  • Configuration keys with fixed valid values
  • Any string that is compared programmatically

Decision Checklist

Before using a bare str type, ask:

  • Is this string compared with == or in anywhere?
  • Is there a fixed set of valid values?
  • Would a typo in this string cause a bug?

If any answer is "yes", use Literal instead.

Source: SKILL.md on GitHub

No alerts3mo3 checks · Risk SAFE
  • Gen Agent Trust Hub3mo

    The skill provides comprehensive and safe guidance for modern Python development practices, including type annotations, exception handling, and CLI design. No security risks or malicious patterns were detected.

  • Socket3mo

    No alerts

  • Snyk3mo

    Risk: LOW · No issues

Signed by skilld at 2d1dcde. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 hours ago.

Activeupdated 5 months ago
Other metadata
references
[
  "dignified-python-core",
  "cli-patterns",
  "versions/python-3.10",
  "versions/python-3.11",
  "versions/python-3.12",
  "versions/python-3.13",
  "references/advanced/api-design",
  "references/advanced/exception-handling",
  "references/advanced/interfaces",
  "references/advanced/typing-advanced"
]

README badge

README badge for docling-project/docling/dignified-python