Skip to content
Development
Skill

/python

Apply when writing Python code. Type hints, error handling, mutable defaults, async patterns, and packaging conventions.

From plugin
skill-everything
2023 skills
Install
$ npx -y skills add sordi-ai/skill-everything --skill python --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/python

Context preview

The summary Claude sees to decide when to auto-load this skill.

Apply when writing Python code. Type hints, error handling, mutable defaults, async patterns, and packaging conventions.

SKILL.md

python.SKILL.md
name: python
description: Apply when writing Python code. Type hints, error handling, mutable defaults, async patterns, and packaging conventions.
license: MIT
version: 1.1.0
tokens_target: 2900
triggers:
  - python code
  - type hints
  - python packaging
loads_after:
  - code-quality
supersedes: []

Sub-Skill: Python Best Practices

<!-- target: ~2200 tokens (real tiktoken count) | 20 rules with severity classification -->

**Purpose:** Prevents the Python-specific mistakes LLMs make on autopilot — mutable defaults, bare excepts, missing guards, and subtle performance traps that pass review but break in production.

Rule classification

  • **MUST** — load-bearing. Violating causes bugs, security issues, or invisible failures. Never break.
  • **SHOULD** — default behavior. Deviation needs a documented reason in the code or PR.
  • **AVOID** — usually wrong; documented exception inline where needed.

**Where these rules don't strictly apply:** test fixtures, generated code, throwaway scripts, REPL exploration, and tutorial snippets may legitimately differ. The rules below apply to **production code paths and reusable libraries**.

---

Rules

Type Hints

1. **SHOULD: Annotate function signatures with types.** `def process(data)` tells callers nothing. Use `def process(data: list[str]) -> dict[str, int]:`. Return type `None` should be explicit too. *Exception: lambdas and short generator helpers in private scope.*

2. **SHOULD: Use built-in lowercase generics for Python 3.9+.** `list[str]`, `dict[str, int]`, `tuple[int, ...]` rather than `List`, `Dict`, `Tuple` from `typing`.

3. **MUST: Use `Optional[X]` or `X | None` for nullable parameters, never a bare default of `None` without a type annotation.** `def find(id: int) -> User | None:` not `def find(id):`.

4. **AVOID: `Any` as a shortcut.** If the type is genuinely unknown, document why with a comment. `Any` silences the type checker and hides bugs. *Exception: third-party libraries without stubs and explicit dynamic-data boundaries (e.g. JSON decode at the API edge).*

---

Error Handling

5. **MUST: Never use bare `except:`.** It catches `SystemExit`, `KeyboardInterrupt`, and `GeneratorExit`. Always catch `except Exception:` at minimum, or a specific exception class.

   # Wrong
   try:
       risky()
   except:
       pass

   # Correct
   try:
       risky()
   except ValueError as e:
       logger.warning("Invalid value: %s", e)

6. **MUST: Never silently swallow exceptions with `pass`.** At minimum log the error. Silent failures produce ghost bugs that are impossible to trace.

7. **SHOULD: Raise with context when re-raising.** Use `raise NewError("msg") from original_error` to preserve the traceback chain, not `raise NewError("msg")` alone.

---

Common Pitfalls

8. **MUST: Never use mutable default arguments.** Python evaluates defaults once at function definition, not per call. The list or dict is shared across all calls.

   # Wrong — items accumulates across calls
   def append_item(val, items=[]):
       items.append(val)
       return items

   # Correct
   def append_item(val, items=None):
       if items is None:
           items = []
       items.append(val)
       return items

9. **MUST: Guard script entry points with `if __name__ == "__main__":`.** Without it, importing the module executes top-level code, breaking tests and imports.

10. **MUST: Use `with` for file handles, sockets, and locks.** Never open a file without a context manager. `f = open(...)` without `with` leaks handles on exceptions.

    # Wrong
    f = open("data.txt")
    data = f.read()
    f.close()

    # Correct
    with open("data.txt") as f:
        data = f.read()

11. **AVOID: String concatenation in loops.** Each `+=` on a string creates a new object. Collect into a list and call `"".join(parts)` at the end.

    # Wrong — O(n^2) memory
    result = ""
    for word in words:
        result += word + " "

    # Correct
    result = " ".join(words)

12. **SHOULD: Use f-strings for string interpolation in Python 3.6+.** Avoid `%` formatting or `"Hello " + name`. F-strings are faster, safer, and readable.

    # Avoid
    msg = "User %s has %d items" % (name, count)

    # Prefer
    msg = f"User {name} has {count} items"

13. **AVOID: `dict()` constructor when a literal suffices.** `{}` is faster and more idiomatic. `dict(key=value)` is only justified when keys are dynamic or come from variables.

---

Performance

14. **SHOULD: Use list comprehensions or generator expressions instead of `map`/`filter` with `lambda`.** Comprehensions are more readable and equally fast. Use generators when the full list is not needed at once.

    # Avoid
    result = list(map(lambda x: x * 2, items))

    # Prefer
    result = [x * 2 for x in items]

    # For large data, use a generator
    total = sum(x * 2 for x in items)

15. **SHOULD: Use a `set` for membership lookups, not a `list`.** `x in list` is O(n). `x in set` is O(1). Convert once, query many times.

    # Wrong for repeated lookups
    valid_ids = [1, 2, 3, ...]
    if user_id in valid_ids:  # O(n) every call

    # Correct
    valid_ids = {1, 2, 3, ...}
    if user_id in valid_ids:  # O(1)

---

Testing

16. **SHOULD: Name test functions to describe the scenario, not just the function under test.** `test_process_returns_empty_dict_on_empty_input` not `test_process`.

17. **MUST: Never use `assert` statements in production code for validation.** `assert` is stripped with `python -O`. Use explicit `if` checks with `raise ValueError(...)` for runtime validation.

18. **MUST: Use `pytest.raises` as a context manager to assert exceptions, never wrap in try/except inside a test.** A bare try/except can mask a missing exception.

    # Wrong
    def test_bad_input():
        try:
            process(None)
Read more
Ships withskill-everything

Git-versioned agent memory: agents that never make the same mistake twice. Anthropic-Skill folder standard, multi-runtime (Claude Code, Cursor, Gemini CLI, OpenCode).

Get the whole plugin
Stats
20
Stars
3
Forks
Maintained
Maintenance
Python
Language
MIT
License
4mo ago
Last commit
4mo ago
Created

Repo: sordi-ai/skill-everything

Other skills on skill-everything.