python-best-practices
Original:🇺🇸 English
Translated
3 scripts
Python software engineering guidelines from real PR review patterns. This skill should be used when writing, reviewing, or refactoring Python code — especially dataclasses, service interfaces, error handling, and type annotations. Triggers on tasks involving Python modules, API design, data modeling, type safety, exception handling, or refactoring for maintainability.
7installs
Added on
NPX Install
npx skill4agent add nathan-gage/python-skills python-best-practicesTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Python Best Practices
Guidelines for writing and reviewing Python. 70 rules across 8 categories, prioritized by impact.
A rule match is a signal, not a verdict. Most rules are design preferences for new code, not bugs to fix across the repo — check the rule's impact level before flagging in review or refactoring stable code.
When to Apply
- Writing new Python modules, functions, classes, or data models
- Reviewing code for correctness or type safety
- Refactoring patterns in code that's being edited anyway
Avoid applying these rules as a blanket sweep across stable code — the churn rarely pays off.
Impact Levels
- — prevents a real bug class (data corruption, swallowed cancellations, insecure defaults). Fix when found.
CRITICAL - — meaningful correctness or maintainability win. Worth fixing in most contexts.
HIGH - — good practice; clarity or drift prevention. Apply to new code; don't churn stable code.
MEDIUM - /
LOW-MEDIUM— style or micro-optimizations. Apply opportunistically.LOW
Python Version Baseline
Rules assume Python 3.11+. Rules depending on higher versions call it out inline:
- — 3.13+
warnings.deprecated() - — 3.9+
zoneinfo - Union types in — 3.10+
isinstance() - — 3.11+ (backport via
assert_never)typing_extensions
Rules tagged are Pydantic-specific.
applicability:pydanticRule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Data Modeling | HIGH | |
| 2 | Error Handling | MEDIUM-HIGH | |
| 3 | Type Safety | MEDIUM-HIGH | |
| 4 | API Design | MEDIUM | |
| 5 | Code Simplification | LOW-MEDIUM | |
| 6 | Performance | LOW-MEDIUM | |
| 7 | Naming | LOW-MEDIUM | |
| 8 | Imports & Structure | LOW | |
Section impact is a typical-case label; individual rules range one level above or below — check the rule file.
Quick Reference
Data Modeling (data-
)
data-- — Never
data-mutable-defaults; usedef f(items=[])+ body construction orNonedefault_factory - — Compute booleans from state; don't cache flags that mirror each other
data-derive-dont-store - — Mutate OR return; not both
data-mutation-contract - — Timezone-aware
data-aware-datetimes;datetime.now(timezone.utc)is deprecatedutcnow() - — Tag variants instead of optional-field bags
data-discriminated-unions - — Concrete classes per mode beat
data-explicit-variants/is_threadflagsis_edit - — Group co-present optionals into one nested optional
data-phased-composition - — Trap mutable state in the narrowest clear scope
data-encapsulate-mutable-state - — Private sentinel when
data-sentinel-when-none-is-validis a meaningful valueNone - —
data-newtype-for-idsso IDs aren't interchangeableNewType('UserId', str) - — Remove union arms that aren't constructed
data-delete-dead-variants
Error Handling (error-
)
error-- — Catch specific types; never bare
error-specific-exceptionsorexcept:(breaks Ctrl-C and async cancellation);except BaseException:is cancellation-safe on 3.8+except Exception: - —
error-context-managers/withfor files, locks, sessionsasync with - —
error-assert-debug-onlyvanishes underassert; not for runtime contracts-O - — Fail fast at system edges before expensive work
error-validate-at-boundaries - — Trust immutable, locally-constructed state
error-trust-validated-state - — Merge blocks with the same catch and handling
error-consolidate-try-except - —
error-assert-never-exhaustivenessfor exhaustivenesstyping.assert_never - —
error-raise-from-for-chainsto preserve causalityraise NewErr(...) from original - — New exceptions inherit existing bases for compatibility
error-inherit-base-exceptions - —
error-log-exception-contextinsidelogger.exception(...); keep the traceback in the logexcept - —
error-repr-in-messagesfor identifiers in error textf"tool {name!r}"
Type Safety (types-
)
types-- — Fix type errors;
types-fix-errors-not-ignoreis a last resort# type: ignore - — Protocols, TypeVars, unions over
types-avoid-anyAny - —
types-typeddict-over-dict-any/ dataclass when structure is knownTypedDict - —
types-literal-for-fixed-setsfor fixed stringsLiteral["a", "b"] - — Fix the definition;
types-fix-types-not-castonly when runtime genuinely narrowscast() - —
types-isinstance-for-narrowingoverisinstance()/hasattrtype(x).__name__ - — Annotations match what control flow actually allows
types-narrow-to-runtime-reality - — Drop runtime checks the types already enforce
types-trust-the-checker - — Drop
types-remove-redundant-optionalwhen values are guaranteed present| None - —
types-type-checking-importsfor optional or heavy importsif TYPE_CHECKING:
API Design (api-
)
api-- — Required fields before optional (Python enforces this)
api-required-before-optional - —
api-keyword-only-paramsmarker for optional/config params* - —
api-no-boolean-flag-params/LiteraloverEnumsoupTrue, False - — Return new collections; don't mutate inputs
api-immutable-transforms - — Flat models; no duplicate or single-key-wrapped fields
api-model-cohesion - —
api-underscore-for-privatefor internals; exclude from_prefix__all__ - —
api-deprecated-aliases(3.13+) for renamed APIswarnings.deprecated() - — Don't reach into
api-no-private-accessnames from outside the module_prefixed - — Pick the namespace that matches ownership
api-instance-vs-module-fn
Code Simplification (simplify-
)
simplify-- — Return early; don't nest the happy path
simplify-early-return - — Second copy is the decision point; third is the safe default
simplify-extract-after-duplication - —
simplify-cached-propertyon immutable instances; not thread-safe@cached_property - — Comprehensions over
simplify-comprehensions+for.append() - —
simplify-any-all-builtins/any()over manual flag +all()break - —
simplify-fallback-orwhen falsy values aren't semanticx or default - —
simplify-flatten-nested-ifwhen no intervening codeif cond1 and cond2: - — Drop intermediates used once
simplify-inline-single-use-vars - — Delete commented-out code; git preserves history
simplify-remove-dead-code
Performance (perf-
)
perf-- —
perf-set-for-membershipfor repeatedsetchecksin - — Build a
perf-dict-index-over-nested-loopsfor lookupsdict - —
perf-lru-cache-pure-fns/functools.lru_cacheon pure functionsfunctools.cache - — Stream with generators when memory or latency matters
perf-generator-over-list - — Fuse
perf-combine-iterations+filterinto one passmap - — Compile static regex at module scope; matters in tight loops
perf-compile-regex-module-level - — Module-scope
perf-type-adapter-constant(applicability: pydantic)TypeAdapter - — Tuple form is marginally faster; profiled hot paths only
perf-isinstance-tuple-syntax
Naming (naming-
)
naming-- — Rename when behavior changes; stale names mislead
naming-rename-on-behavior-change - — Same concept, same word across code/docs/errors
naming-consistent-terminology - —
naming-specific-over-generic; not baretoolset_idid - —
naming-drop-redundant-prefixes; notToolConfig.descriptionToolConfig.tool_description - —
naming-upper-case-constants;MAX_RETRIESprefix for internal_ - — No
naming-no-type-suffixes/_dictsuffixes; types annotate types_list
Imports & Structure (imports-
)
imports-- — Modules must be cheap to import — no network/model/env reads at import
imports-no-side-effects - — Imports at the top; documented exceptions for circular / optional / deferred
imports-top-of-file - —
imports-optional-dependencies/trywith install hintsexcept ImportError - — Define helpers near where they're used
imports-scope-helpers-to-usage - — Delete unused imports
imports-remove-unused - — One import per name
imports-no-duplicates
How to Use
Read individual rule files for detail:
rules/data-mutable-defaults.md
rules/error-specific-exceptions.mdEach rule has:
- Impact level in frontmatter
- Brief explanation
- Incorrect example
- Correct example
- Optional note on edge cases
For the full compiled guide with all rules expanded: .
AGENTS.md