python-guidelines
This skill should be used when writing, reviewing, or refactoring Python code. Covers code integration, idiomatic patterns, docstring formatting, anti-abstraction rules, and software engineering basics.
Install
npx skills add https://github.com/fcakyon/claude-codex-settings/tree/main/plugins/python-skills/skills/python-guidelines
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install fcakyon-claude-codex-settings@llmmart
git clone https://github.com/fcakyon/claude-codex-settings.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole fcakyon/claude-codex-settings collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Python Guidelines
Integrate into existing code. Don't append to it.
Simple is better than complex. Flat is better than nested. Errors should never pass silently. Unless explicitly silenced. If the implementation is hard to explain, it's a bad idea.
-- The Zen of Python (PEP 20)
Code Philosophy
- Match existing naming, importing, and signature patterns. Use existing utilities and data structures.
- Functions have a single purpose. Don't hardcode behavior that makes them less general.
- No trivial wrappers for 2 lines or less. Inline it.
- Inline single-use variables at the usage site.
- No try/except unless critical. Let errors surface.
- No duplicate code.
- Functions handle their own input validation. No if-else checks in main.
- Use pathlib, not os.path.
- Consider API and time costs for MongoDB/Gemini/OpenAI/Claude/Voyage.
Don't do this:
# Generate comment report only if requested
if include_comments:
comment_report = generate_comments_report(start_date, end_date, team, verbose)
else:
comment_report = ""
print(" Skipping comment analysis (disabled)")
Do this:
comment_report = generate_comments_report(start_date, end_date, team, verbose) if include_comments else ""
Ask yourself: "Am I adding code, or integrating into what exists?"
Simplicity Over Abstraction
YAGNI: You Aren't Gonna Need It.
Don't build for hypothetical future requirements. Add complexity only when the current task demands it.
Avoid:
- Abstract base classes for a single implementation
- Configuration options nobody asked for
- Error handling for impossible scenarios
- Wrapper classes around a single function
- Dependency injection when direct calls work
- Generic type parameters for one concrete type
Three similar lines of code is better than a premature abstraction. Refactor when the third real use case appears, not before.
But simplicity does not mean chaos. Always maintain:
- Clear function names that describe what they do
- Logical grouping of related code into modules
- Consistent naming conventions across the project
- Clean separation between I/O and logic
- Explicit parameters over global state or side effects
Ask yourself: "Is this abstraction solving a problem I have right now, or one I'm imagining?"
Environment
- Package manager: uv (NOT pip)
- Virtual env:
source .venv/bin/activateoruv run python -c "..." - 3rd party packages: Find source with
python -c "import pkg; print(pkg.__file__)", then Read.
Testing Discipline
Never assume anything. Run python -c "..." to verify hypotheses about code behavior, package functions, or data structures before suggesting a plan or exiting plan mode.
Ask yourself: "Did I verify this with python -c before building on it?"
Google-Style Docstrings
- Summary: Imperative mood ("Calculate", not "Calculates")
- Args: All parameters with types and descriptions. No default values. Indent 4 spaces.
- Types:
int | strunions, uppercase shapes(N, M), lowercase builtinslist/dict/tuple, capitalizeAny/Path - Optional:
name (type, optional): Description - Returns: Always
(type)in parentheses. Never tuple types. Separate named values for multiple returns. - Sections: Examples (>>>), Notes, References (plaintext only). Section titles at 0 indent.
- Omit: "Returns:" if nothing returned, "Args:" if no args, "Raises:" unless critical
- Classes: Attributes section only, omit Methods/Args. Don't convert single-line to multiline.
__init__: Args only. No Examples/Notes/Methods/References.- Tests: Single-line docstrings only.
- Erase default values from existing arg descriptions. Optionally include minimal Examples.
Ask yourself: "Would a new developer understand this function from the docstring alone?"
Reference Files
Read the matching file before you write the code, not after:
references/idiomatic-patterns.md-- read when writing loops, comprehensions, unpacking, context managers, or dataclasses. 18 idioms with before/after codereferences/zen-of-python.md-- read when choosing between two designs or judging whether an abstraction earns its place. PEP 20 with annotationsreferences/google-style-guide.md-- read when deciding on exceptions, mutable defaults, import style, naming, or commentsreferences/effective-python-tips.md-- read when reviewing or refactoring existing code. Key tips from "Effective Python" (Brett Slatkin)
Files (claude-codex-settings)
-
references
-
effective-python-tips.md 2.7 KB
# Effective Python -- Key Tips Source: Brett Slatkin, "Effective Python: 125 Specific Ways to Write Better Python" (3rd ed., Addison-Wesley, 2024) ISBN: 978-0138172183 Item numbers reference the 3rd edition. Selected items organized by relevance to AI-assisted coding. ## Pythonic Thinking (Chapter 1) - **Item 2**: Follow the PEP 8 Style Guide - **Item 4**: Write Helper Functions Instead of Complex Expressions - **Item 5**: Prefer Multiple-Assignment Unpacking over Indexing - **Item 7**: Consider Conditional Expressions for Simple Inline Logic - **Item 8**: Prevent Repetition with Assignment Expressions ## Loops, Iterators, and Dictionaries (Chapters 3-4) - **Item 17**: Prefer `enumerate` over `range` - **Item 18**: Use `zip` to Process Iterators in Parallel - **Item 22**: Never Modify Containers While Iterating over Them - **Item 24**: Consider `itertools` for Working with Iterators and Generators - **Item 27**: Prefer `defaultdict` over `setdefault` to Handle Missing Items - **Item 29**: Compose Classes Instead of Deeply Nesting Dictionaries, Lists, and Tuples ## Functions (Chapter 5) - **Item 32**: Prefer Raising Exceptions to Returning `None` - **Item 33**: Know How Closures Interact with Variable Scope and `nonlocal` - **Item 34**: Reduce Visual Noise with Variable Positional Arguments - **Item 35**: Provide Optional Behavior with Keyword Arguments - **Item 36**: Use `None` and Docstrings to Specify Dynamic Default Arguments - **Item 37**: Enforce Clarity with Keyword-Only and Positional-Only Arguments - **Item 38**: Define Function Decorators with `functools.wraps` ## Comprehensions and Generators (Chapter 6) - **Item 40**: Use Comprehensions Instead of `map` and `filter` - **Item 41**: Avoid More Than Two Control Subexpressions in Comprehensions - **Item 43**: Consider Generators Instead of Returning Lists - **Item 44**: Consider Generator Expressions for Large List Comprehensions ## Classes and Interfaces (Chapter 7) - **Item 48**: Accept Functions Instead of Classes for Simple Interfaces - **Item 51**: Prefer `dataclasses` for Defining Lightweight Classes - **Item 53**: Initialize Parent Classes with `super` - **Item 54**: Consider Composing Functionality with Mix-in Classes - **Item 55**: Prefer Public Attributes over Private Ones - **Item 58**: Use Plain Attributes Instead of Setter and Getter Methods ## Robustness and Performance (Chapters 10-11) - **Item 82**: Consider `contextlib` and `with` Statements for Reusable `try`/`finally` Behavior - **Item 83**: Always Make `try` Blocks as Short as Possible - **Item 85**: Beware of Catching the `Exception` Class - **Item 92**: Profile Before Optimizing - **Item 106**: Use `decimal` When Precision Is Paramount -
google-style-guide.md 3 KB
# Google Python Style Guide -- Key Sections Source: https://google.github.io/styleguide/pyguide.html Maintainer: Google License: CC-BY 3.0 Each section links to the specific guide section for full context. ## Exceptions Source: https://google.github.io/styleguide/pyguide.html#24-exceptions - Raise `ValueError` for programming mistakes like violated preconditions - Never use catch-all `except:` statements, or catch `Exception` unless re-raising or creating an isolation point - Minimize the amount of code in a `try`/`except` block - Do not use `assert` in place of conditionals for critical logic ```python # Yes if minimum < 1024: raise ValueError(f"Min. port must be at least 1024, not {minimum}.") # No assert minimum >= 1024, "Minimum port must be at least 1024." ``` ## Default Argument Values Source: https://google.github.io/styleguide/pyguide.html#212-default-argument-values Do not use mutable objects as default values. ```python # Yes def foo(a, b=None): if b is None: b = [] # No def foo(a, b=[]): ... def foo(a, b=time.time()): ... ``` ## Import Ordering Source: https://google.github.io/styleguide/pyguide.html#313-imports-formatting Imports grouped from most generic to least: 1. `from __future__` imports 2. Python standard library 3. Third-party modules 4. Local/project imports Within each group, sort lexicographically. Use `import x` for packages, `from x import y` where `x` is the package prefix. No relative imports. ```python ``` ## Naming Conventions Source: https://google.github.io/styleguide/pyguide.html#316-naming | Type | Style | Example | | ------------------ | ------------------ | ----------------------- | | Packages/Modules | `lower_with_under` | `my_module` | | Classes/Exceptions | `CapWords` | `MyClass`, `InputError` | | Functions/Methods | `lower_with_under` | `calculate_total` | | Constants | `CAPS_WITH_UNDER` | `MAX_RETRIES` | | Variables | `lower_with_under` | `user_count` | Avoid: single-char names (except `i`, `j`, `k`, `e`, `f`), dashes in names, type-in-name (`id_to_name_dict`). ## Adapting to Existing Code These Google Style Guide rules are defaults. When working in an existing codebase, always match the existing patterns for: - **Type hints**: Follow the repo's existing annotation style (presence/absence, `X | None` vs `Optional[X]`, etc.) - **Naming**: Match the existing naming conventions in the file/module you're editing - **Import style**: Follow the repo's existing import organization - **Docstrings**: Match the existing docstring style in the project The rules above are for greenfield code or when the existing codebase has no clear convention. ## Comments Source: https://google.github.io/styleguide/pyguide.html#385-block-and-inline-comments - Never describe the code. Assume the reader knows Python. - Comments start at least 2 spaces from the code - Use them to explain WHY, not WHAT -
idiomatic-patterns.md 5.3 KB
# Idiomatic Python Patterns Sources: - PEP 8: https://peps.python.org/pep-0008/ - PEP 20: https://peps.python.org/pep-0020/ - Google Python Style Guide: https://google.github.io/styleguide/pyguide.html - Effective Python, 3rd ed. (Brett Slatkin, Addison-Wesley, 2024, ISBN 978-0138172183) Each pattern notes its primary source. Item numbers reference the 3rd edition. ## 1. Enumerate over indexing Source: Effective Python Item 17, PEP 279 ```python # No for i in range(len(items)): print(i, items[i]) # Yes for i, item in enumerate(items): print(i, item) ``` ## 2. Zip for parallel iteration Source: Effective Python Item 18 ```python # No for i in range(min(len(names), len(colors))): print(names[i], colors[i]) # Yes for name, color in zip(names, colors): print(name, color) ``` ## 3. Reversed for backward loops Source: PEP 322 ```python # No for i in range(len(items) - 1, -1, -1): print(items[i]) # Yes for item in reversed(items): print(item) ``` ## 4. List comprehensions over map/filter Source: Effective Python Item 40, PEP 202 ```python # No result = list(map(lambda x: x * 2, filter(lambda x: x > 0, items))) # Yes result = [x * 2 for x in items if x > 0] ``` ## 5. Generator expressions for large data Source: Effective Python Item 44, PEP 289 ```python # No -- builds entire list in memory total = sum([x**2 for x in range(10**6)]) # Yes -- lazy evaluation total = sum(x**2 for x in range(10**6)) ``` ## 6. Context managers for resources Source: PEP 343, Effective Python Item 82 ```python # No f = open("data.txt") try: data = f.read() finally: f.close() # Yes with open("data.txt") as f: data = f.read() ``` ## 7. Keyword arguments for clarity Source: Effective Python Items 35, 37 ```python # No -- what do these booleans mean? search("@obama", False, 20, True) # Yes search("@obama", retweets=False, count=20, popular=True) ``` ## 8. Dataclasses for structured data Source: PEP 557, Effective Python Item 51 ```python # No result = (0, 4) # what are these? # Yes from dataclasses import dataclass @dataclass class TestResults: failed: int attempted: int ``` ## 9. Tuple unpacking for state Source: Core Python feature ```python # No temp = y y = x + y x = temp # Yes x, y = y, x + y ``` ## 10. str.join over concatenation Source: PEP 8, Google Style Guide ```python # No -- O(n^2) string building s = names[0] for name in names[1:]: s += ", " + name # Yes -- O(n) s = ", ".join(names) ``` ## 11. defaultdict/Counter for counting Source: Effective Python Item 27, Python docs collections module ```python # No d = {} for color in colors: if color not in d: d[color] = 0 d[color] += 1 # Yes from collections import Counter d = Counter(colors) ``` ## 12. Helper functions over complex expressions Source: Effective Python Item 4 ```python # No -- hard to read value = first if first is not None else (second if second is not None else default) # Yes def first_valid(*values, default=None): return next((v for v in values if v is not None), default) value = first_valid(first, second, default=default) ``` ## 13. Exceptions over returning None Source: Effective Python Item 32 ```python # No -- caller can't distinguish None result from error def divide(a, b): if b == 0: return None return a / b # Yes def divide(a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b ``` ## 14. Generators for lazy sequences Source: Effective Python Item 43, PEP 255 ```python # No -- builds entire list in memory def read_lines(path): results = [] with open(path) as f: for line in f: results.append(line.strip()) return results # Yes -- yields one at a time def read_lines(path): with open(path) as f: for line in f: yield line.strip() ``` ## 15. Plain attributes, not getters/setters Source: Effective Python Item 58, PEP 8 ```python # No -- Java-style boilerplate class User: def __init__(self, name): self._name = name def get_name(self): return self._name def set_name(self, name): self._name = name # Yes -- use @property only when you need computed access class User: def __init__(self, name): self.name = name ``` ## 16. cache/lru_cache for memoization Source: Python docs functools module, Effective Python Item 38 ```python # No _cache = {} def fib(n): if n in _cache: return _cache[n] result = fib(n - 1) + fib(n - 2) if n > 1 else n _cache[n] = result return result # Yes (Python 3.9+: use @cache for unbounded, @lru_cache for bounded) from functools import cache @cache def fib(n): return fib(n - 1) + fib(n - 2) if n > 1 else n ``` ## 17. Functions for simple interfaces Source: Effective Python Item 48 ```python # No -- single-method class is a function in disguise class Validator: def validate(self, value): return value > 0 # Yes def validate(value): return value > 0 ``` ## 18. No mutable default arguments Source: Effective Python Item 36, Google Style Guide 2.12 ```python # No -- shared mutable state across calls def append_to(element, target=[]): target.append(element) return target # Yes def append_to(element, target=None): if target is None: target = [] target.append(element) return target ``` -
zen-of-python.md 1.8 KB
# The Zen of Python (PEP 20) Source: https://peps.python.org/pep-0020/ Author: Tim Peters Status: Active (since 2004) Run: `python -c "import this"` Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than _right_ now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! ## Most Applicable Lines For AI-assisted coding, these are the lines that matter most: - **Simple is better than complex**: Don't over-engineer. A 5-line function beats a 50-line class hierarchy. - **Flat is better than nested**: Early returns, list comprehensions, avoid deep if/else nesting. - **Explicit is better than implicit**: Name things clearly. Don't hide behavior in magic methods or metaclasses. - **Errors should never pass silently**: No bare `except:`. Let errors surface unless you have a specific reason to catch them. - **Readability counts**: Code is read far more than it is written. Favor clarity over cleverness. - **In the face of ambiguity, refuse the temptation to guess**: Ask for clarification rather than assuming. - **If the implementation is hard to explain, it's a bad idea**: If you can't describe what a function does in one sentence, it's doing too much.
-
-
SKILL.md 4.8 KB
--- name: python-guidelines description: This skill should be used when writing, reviewing, or refactoring Python code. Covers code integration, idiomatic patterns, docstring formatting, anti-abstraction rules, and software engineering basics. --- # Python Guidelines **Integrate into existing code. Don't append to it.** > Simple is better than complex. Flat is better than nested. > Errors should never pass silently. Unless explicitly silenced. > If the implementation is hard to explain, it's a bad idea. > > -- The Zen of Python (PEP 20) ## Code Philosophy - Match existing naming, importing, and signature patterns. Use existing utilities and data structures. - Functions have a single purpose. Don't hardcode behavior that makes them less general. - No trivial wrappers for 2 lines or less. Inline it. - Inline single-use variables at the usage site. - No try/except unless critical. Let errors surface. - No duplicate code. - Functions handle their own input validation. No if-else checks in main. - Use pathlib, not os.path. - Consider API and time costs for MongoDB/Gemini/OpenAI/Claude/Voyage. Don't do this: ```python # Generate comment report only if requested if include_comments: comment_report = generate_comments_report(start_date, end_date, team, verbose) else: comment_report = "" print(" Skipping comment analysis (disabled)") ``` Do this: ```python comment_report = generate_comments_report(start_date, end_date, team, verbose) if include_comments else "" ``` Ask yourself: "Am I adding code, or integrating into what exists?" ## Simplicity Over Abstraction **YAGNI: You Aren't Gonna Need It.** Don't build for hypothetical future requirements. Add complexity only when the current task demands it. Avoid: - Abstract base classes for a single implementation - Configuration options nobody asked for - Error handling for impossible scenarios - Wrapper classes around a single function - Dependency injection when direct calls work - Generic type parameters for one concrete type Three similar lines of code is better than a premature abstraction. Refactor when the third real use case appears, not before. But simplicity does not mean chaos. Always maintain: - Clear function names that describe what they do - Logical grouping of related code into modules - Consistent naming conventions across the project - Clean separation between I/O and logic - Explicit parameters over global state or side effects Ask yourself: "Is this abstraction solving a problem I have right now, or one I'm imagining?" ## Environment - **Package manager**: uv (NOT pip) - **Virtual env**: `source .venv/bin/activate` or `uv run python -c "..."` - **3rd party packages**: Find source with `python -c "import pkg; print(pkg.__file__)"`, then Read. ## Testing Discipline Never assume anything. Run `python -c "..."` to verify hypotheses about code behavior, package functions, or data structures before suggesting a plan or exiting plan mode. Ask yourself: "Did I verify this with `python -c` before building on it?" ## Google-Style Docstrings - **Summary**: Imperative mood ("Calculate", not "Calculates") - **Args**: All parameters with types and descriptions. No default values. Indent 4 spaces. - **Types**: `int | str` unions, uppercase shapes `(N, M)`, lowercase builtins `list`/`dict`/`tuple`, capitalize `Any`/`Path` - **Optional**: `name (type, optional): Description` - **Returns**: Always `(type)` in parentheses. Never tuple types. Separate named values for multiple returns. - **Sections**: Examples (>>>), Notes, References (plaintext only). Section titles at 0 indent. - **Omit**: "Returns:" if nothing returned, "Args:" if no args, "Raises:" unless critical - **Classes**: Attributes section only, omit Methods/Args. Don't convert single-line to multiline. - **`__init__`**: Args only. No Examples/Notes/Methods/References. - **Tests**: Single-line docstrings only. - Erase default values from existing arg descriptions. Optionally include minimal Examples. Ask yourself: "Would a new developer understand this function from the docstring alone?" ## Reference Files Read the matching file before you write the code, not after: - [`references/idiomatic-patterns.md`](references/idiomatic-patterns.md) -- read when writing loops, comprehensions, unpacking, context managers, or dataclasses. 18 idioms with before/after code - [`references/zen-of-python.md`](references/zen-of-python.md) -- read when choosing between two designs or judging whether an abstraction earns its place. PEP 20 with annotations - [`references/google-style-guide.md`](references/google-style-guide.md) -- read when deciding on exceptions, mutable defaults, import style, naming, or comments - [`references/effective-python-tips.md`](references/effective-python-tips.md) -- read when reviewing or refactoring existing code. Key tips from "Effective Python" (Brett Slatkin)
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.