agentleFS
lordqyxzlordqyxz/claude-skill-marketplace/python-code/SKILL.md

python-code

Skill1 starsChanged 7 months agoMITView on GitHub

Write, refactor, and debug Python code following Pythonic best practices from the official Python style guide, Effective Python, and Fluent Python. Use this skill whenever the user writes, reviews, refactors, or debugs Python code, asks about Python patterns, idioms, or style, mentions writing a script/module/package in Python, or requests code that is "Pythonic." Applies to all Python 3.10+ code.

3 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions3 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 3

    1. DongDuong2001/pudo-code-system★ 5same name
    2. cognis-digital/skillsmith★ 0same name
    3. wachawo/claude-skills★ 0same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository4 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

26 rules. About 0 are common, 9 are distinctive, and 17 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 17

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Write Python code the way experienced Pythonistas write it — idiomatic, clear, and grounded in the principles from Python's official docs, …

    line 8
  2. Distinctive:

    Prefer flat structure over deep nesting.

    line 23
  3. Very specific:

    Use collections (defaultdict, Counter, namedtuple, dataclasses) instead of manual dict tricks.

    line 28
  4. Very specific:

    Use comprehensions and generator expressions instead of manual loops.

    line 29
  5. Very specific:

    Use yield and generator functions for lazy pipelines — process data one item at a time without loading everything into memory.

    line 30
  6. Very specific:

    Use context managers (with) for resource management — files, locks, connections.

    line 31
  7. Very specific:

    Use the pathlib module instead of os.path for filesystem operations.

    line 32
  8. Very specific:

    Use f-strings instead of .format() or % formatting.

    line 33
  9. Very specific:

    Use match/case (3.10+) for destructuring structured data and replacing deep if/elif chains — it's cleaner than isinstance checks for …

    line 34
  10. Very specific:

    Use type annotations. They communicate intent, enable static analysis, and cost nothing at runtime.

    line 41
  11. Distinctive:

    Don't reach for a class just because Java would.

    line 48
  12. Very specific:

    If it's just data, use a dataclass or NamedTuple.

    line 49
  13. Distinctive:

    If it has behavior and state, a class makes sense.

    line 50
  14. Distinctive:

    If you need a class, implement dunder methods so objects behave like native Python objects.

    line 51
  15. Very specific:

    Use try/except/else/finally fully.

    line 60
  16. Very specific:

    Use asyncio for I/O-bound work, concurrent.futures for CPU-bound work.

    line 66
  17. Very specific:

    Prefer asyncio.TaskGroup (3.11+) over manual task creation — automatic cleanup and error propagation.

    line 67
  18. Very specific:

    Never mix sync and async code casually.

    line 68
  19. Distinctive:

    Follow PEP 8 as baseline, but go beyond it:

    line 72
  20. Very specific:

    Type annotations: All function signatures. Use from __future__ import annotations for forward references.

    line 78
  21. Distinctive:

    Docstrings: All public functions have Google-style docstrings.

    line 90
  22. Very specific:

    Subclassing built-in types incorrectly: If you override __setitem__, you probably also need __getitem__, __delitem__, update, etc.

    line 132
  23. Very specific:

    Missing reverse operators: If you implement __add__, Python falls back to __radd__ on the right operand when the left doesn't know how to …

    line 136
  24. Very specific:

    __bool__ vs __len__ confusion: If both are defined, bool(obj) uses __bool__.

    line 137
  25. Distinctive:

    After writing or refactoring code, verify:

    line 143
  26. Distinctive:

    Docstrings: All public functions have Google-style docstrings

    line 148

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Python Code Skill

Write Python code the way experienced Pythonistas write it — idiomatic, clear, and grounded in the principles from Python's official docs, Effective Python (Brett Slatkin), and Fluent Python (Luciano Ramalho).

Why this skill exists

Python is deceptively simple. Code that runs isn't the same as code that's Pythonic. The difference shows up in readability, maintainability, and how well code plays with the rest of the ecosystem. This skill internalizes the accumulated wisdom from the language's core documentation and the two most respected Python methodology books, so every piece of Python code you write benefits from those insights without you having to look them up.

Core Principles

These principles guide every line of Python you write. When trade-offs arise, refer back to these.

1. Readability counts — it's the #1 priority

Code is read far more often than it's written. Optimize for the reader, not the writer. This means:

  • Obvious over clever. A list comprehension that fits one line is great; a nested comprehension that requires a whiteboard to unpack is not.
  • Naming matters. users_by_region beats d or grp. If you need a comment to explain what a variable holds, the name is wrong.
  • Prefer flat structure over deep nesting. Guard clauses (early return) keep indentation shallow and logic linear.

2. Use Python's power — don't fight it

Python has rich built-in types and protocols. Leverage them instead of reinventing:

  • Use collections (defaultdict, Counter, namedtuple, dataclasses) instead of manual dict tricks.
  • Use comprehensions and generator expressions instead of manual loops. List comprehensions are more readable than map+lambda, but map is fine when you already have a callable (map(str, numbers) beats [str(n) for n in numbers]).
  • Use yield and generator functions for lazy pipelines — process data one item at a time without loading everything into memory. yield from delegates to sub-generators. itertools (chain, islice, groupby, tee) is the stdlib toolkit for building iterator pipelines.
  • Use context managers (with) for resource management — files, locks, connections.
  • Use the pathlib module instead of os.path for filesystem operations.
  • Use f-strings instead of .format() or % formatting.
  • Use match/case (3.10+) for destructuring structured data and replacing deep if/elif chains — it's cleaner than isinstance checks for complex branching.

3. Functions are the unit of composition

Small, focused functions with clear input/output contracts beat monolithic blocks:

  • Each function does one thing. If you're writing a docstring and need "and" to list what it does, split it.
  • Return values are better than mutating arguments. Mutating arguments creates hidden coupling that's hard to debug.
  • Use type annotations. They communicate intent, enable static analysis, and cost nothing at runtime. def search(needle: str, haystack: list[str]) -> int: is self-documenting.
  • Separate I/O from logic. Functions that mix file reads, network calls, or database queries with business logic are hard to test and brittle to refactor. Keep pure-data functions (take data in, return data out) separate from I/O adapters (read file, write result). This way the core logic can be tested without mocking filesystem or network, and the I/O layer can be swapped (e.g., from local files to S3) without touching business rules.
  • Choose the right callable form. Prefer closures for simple state capture (a counter, a callback with context) — they're lighter than a class. Use @dataclass or a class only when you need multiple methods or a complex interface. A def make_counter(start=0) returning an inner function is simpler than a Counter class with __call__.
  • Keep function bodies under 30 lines (excluding docstrings). Long functions indicate mixed responsibilities — extract helpers. Guidelines: ≤ 10 lines ideal, 10-20 acceptable, 20-30 borderline, > 30 refactor. Exceptions: dispatch tables, data-driven logic (match/case, dict of handlers).

4. Classes when you need state; functions when you don't

Don't reach for a class just because Java would. Functions and simple data structures cover most needs:

  • If it's just data, use a dataclass or NamedTuple.
  • If it has behavior and state, a class makes sense. Keep inheritance shallow — composition over inheritance.
  • If you need a class, implement dunder methods so objects behave like native Python objects. The minimum depends on the class's role:
    • All classes: __repr__ — so repr(obj) is useful in debugging and logging.
    • Data-like classes: __eq__ and __hash__ (if immutable) — so they work in sets/dicts.
    • Container-like classes (hold items, support lookup): __len__, __contains__, __getitem__ — so len(cache), key in cache, and cache[key] work. Without these, users must remember custom method names like size(), get() — a maintenance burden and a departure from Python conventions.
    • Callable objects: __call__ — when configuration + behavior makes sense.

5. Handle errors explicitly, fail fast

  • Raise specific exceptions (ValueError, KeyError, custom subclasses) — never bare except:.
  • Use try/except/else/finally fully. The else clause runs when no exception occurred, which is clearer than putting success logic inside the try.
  • Validate inputs at system boundaries (public API, user input). Trust internal callers — don't sprinkle validation everywhere.
  • Invalid input should raise, not silently adapt. When a caller passes ttl=-5, raise ValueError("ttl must be positive, got -5") — don't silently treat it as "expire immediately." Silently reinterpreting invalid input hides bugs in the caller's code and makes diagnosing issues much harder. The exception message should include the actual value received so the caller can see what went wrong without adding print statements.

6. Concurrency and async with care

  • Use asyncio for I/O-bound work, concurrent.futures for CPU-bound work.
  • Prefer asyncio.TaskGroup (3.11+) over manual task creation — automatic cleanup and error propagation.
  • Never mix sync and async code casually. If a function is async, everything it calls should be async or offloaded via run_in_executor.

Code Style Rules

Follow PEP 8 as baseline, but go beyond it:

  • Line length: 88 (Black default). Readability over arbitrary 80-char limits.
  • Imports: stdlib → third-party → local, each group separated by a blank line. Use from x import y for specific names, import x for module-level access.
  • String quotes: Consistent within a file. Don't mix without reason.
  • Trailing commas: In multi-line collections, always. Makes diffs cleaner.
  • Type annotations: All function signatures. Use from __future__ import annotations for forward references.
  • Naming conventions:
ElementConventionExample
Variablessnake_casetask_id, is_complete
Functionssnake_case, verb prefixget_tasks(), is_valid()
ClassesPascalCaseTaskRepository, ValidationError
ConstantsUPPER_SNAKEMAX_RETRIES, DEFAULT_TIMEOUT
Private_prefix_internal_method()
Booleanis_, has_, can_is_valid, has_permission
  • Docstrings: All public functions have Google-style docstrings.

Patterns to Prefer

SituationPreferAvoid
Empty dict/list default paramNone default + if x is None: x = {}Mutable default def f(x={})
Simple data container@dataclass or NamedTupleManual __init__
File pathspathlib.Pathos.path string manipulation
CountingCounterdict with if key in d
Groupingdefaultdict(list)if key not in d: d[key] = []
Iteration with indexenumerate()range(len())
Parallel iterationzip()Index-based access
Conditional expressionx if cond else yMulti-line if/else for simple cases
String building"".join(parts)+= in a loop
Resource cleanupwith statementManual close() calls
Attribute access with defaultgetattr(obj, key, default)try/except AttributeError for simple cases
Dictionary merging (3.9+)d1 | d2d1.update(d2) for immutable merging
Container class interface__len__, __contains__, __getitem__Custom size(), has(), get_by_key() methods
Structured data (evolving schema)@dataclass with named fieldsTuple unpacking value, ts = entry
Business logicPure function taking/returning dataFunction mixing I/O + computation
State capture (simple)Closure with nonlocalFull class for a counter/callback
Lazy data pipelineGenerator function with yieldLoading all data into a list
Operator overloading__add__ + __radd__ + __iadd__Only __add__ (breaks 1 + obj)
Structural branching (3.10+)match/case with destructuringDeep isinstance + if/elif chains
Parallel IOasyncio.gatherSequential awaits
Blocking IOThreadPoolExecutorasyncio for CPU-bound work
High-precision timingtime.perf_counter()time.time()
Repeated computation@functools.lru_cacheManual memoization
Many instances__slots__Regular __dict__ class
Context manager@contextmanager + withManual try/finally cleanup

Common Pitfalls to Avoid

These come from Effective Python and Fluent Python — each one has burned real projects:

  1. Mutable default arguments: def f(items=[]): — the list persists across calls. Use None and create a new list inside the function.
  2. Closures over loop variables: lambda: i in a loop captures the variable, not the value. Use lambda i=i: i or functools.partial.
  3. is for value comparison: is checks identity, not equality. x is None is correct; x is 0 or x is [] is a bug.
  4. Star imports in production code: from module import * pollutes the namespace and hides dependencies.
  5. Ignoring __hash__ when overriding __eq__: Unhashable objects break sets and dict keys.
  6. Overusing @property: Complex computation hidden behind property access is misleading. If it's expensive, make it a method.
  7. Subclassing built-in types incorrectly: If you override __setitem__, you probably also need __getitem__, __delitem__, update, etc. Consider composition instead.
  8. Returning True/False from __init__: __init__ should return None. Raise exceptions on failure.
  9. Using tuples for evolving data structures: entry = (value, timestamp) is fine for a one-off script, but if the structure might grow (add created_at, hit_count), every unpacking site breaks. Use @dataclass from the start — the cost is trivial, the maintainability gain is real.
  10. Coupling I/O with business logic: A function that reads a file, parses it, and returns results cannot be unit-tested without filesystem mocking. Split into: parse_data(text: str) -> Result (testable) + read_and_parse(path: Path) -> Result (I/O adapter). The pure function is where bugs live; the I/O adapter is infrastructure.
  11. Missing reverse operators: If you implement __add__, Python falls back to __radd__ on the right operand when the left doesn't know how to handle it. Without __radd__, 1 + Money(5) works but Money(5) + 1 may not — a subtle asymmetry.
  12. __bool__ vs __len__ confusion: If both are defined, bool(obj) uses __bool__; if only __len__, zero is falsy. Forgetting __bool__ when you have __len__ leads to surprises — an empty-yet-valid container evaluates as falsy.
  13. Forgetting nonlocal in closures: A nested function that assigns to an outer variable needs nonlocal x — without it, the assignment creates a local variable that shadows the outer one, and the outer variable is never updated.
  14. __slots__ blocks weakref: Adding __slots__ removes __dict__ and __weakref__ by default. If you need weak references to instances, explicitly add __weakref__ to __slots__.

Verification Checklist

After writing or refactoring code, verify:

  1. Type check: pyright passes
  2. Format: ruff format applied
  3. Lint: ruff check passes
  4. Docstrings: All public functions have Google-style docstrings
  5. Error handling: Specific exceptions, no bare except:
  6. No anti-patterns:
    • ❌ items: list = [] (mutable default)
    • ❌ def get_x(self): return self._x (use @property)
    • ❌ for i in range(len(items)) (use enumerate)
    • ❌ x + " " + y (use f"{x} {y}")
    • ❌ Functions over 30 lines (extract helpers)
  7. Function length: Each function body ≤ 30 lines (excluding docstring)

When to go deeper

This skill covers day-to-day Python writing. For specialized topics, read the relevant reference file:

  • references/advanced-types.md — Protocol, TypeVar, generics, overloads, type narrowing
  • references/async-patterns.md — Async services, TaskGroup, mixing sync/async
  • references/data-model.md — Dunder methods, descriptors, custom containers
  • references/testing.md — Pytest fixtures, mocking, test patterns
  • references/class-metaprogramming.md — __init_subclass__, match/case pattern matching, __class_getitem__
  • references/effective-python/ — Chapter-by-chapter patterns from Effective Python: pythonic thinking, lists/dicts, functions, classes, concurrency, error handling, performance, standard library

These are loaded only when needed to keep context lean — the core principles above cover the vast majority of Python code you'll write.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.