python-skills 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. python_skills/__init__.py +10 -0
  2. python_skills/__main__.py +6 -0
  3. python_skills/adapters/__init__.py +48 -0
  4. python_skills/adapters/agent_skills.py +415 -0
  5. python_skills/adapters/aider_adapter.py +226 -0
  6. python_skills/adapters/base.py +153 -0
  7. python_skills/adapters/claude.py +474 -0
  8. python_skills/adapters/cline.py +332 -0
  9. python_skills/adapters/codex.py +24 -0
  10. python_skills/adapters/continue_adapter.py +198 -0
  11. python_skills/adapters/cursor.py +327 -0
  12. python_skills/adapters/gemini.py +26 -0
  13. python_skills/adapters/goose.py +26 -0
  14. python_skills/adapters/junie.py +25 -0
  15. python_skills/adapters/kiro.py +382 -0
  16. python_skills/adapters/opencode.py +27 -0
  17. python_skills/adapters/roo.py +25 -0
  18. python_skills/adapters/universal.py +203 -0
  19. python_skills/adapters/vscode.py +27 -0
  20. python_skills/adapters/windsurf.py +26 -0
  21. python_skills/adapters/zed.py +27 -0
  22. python_skills/cli.py +326 -0
  23. python_skills/config.py +160 -0
  24. python_skills/detector.py +152 -0
  25. python_skills/installer.py +163 -0
  26. python_skills/markers.py +115 -0
  27. python_skills/skills/__init__.py +14 -0
  28. python_skills/skills/loader.py +171 -0
  29. python_skills/skills/metadata.py +152 -0
  30. python_skills/skills/registry.py +101 -0
  31. python_skills/state.py +204 -0
  32. python_skills-1.0.0.dist-info/METADATA +99 -0
  33. python_skills-1.0.0.dist-info/RECORD +105 -0
  34. python_skills-1.0.0.dist-info/WHEEL +4 -0
  35. python_skills-1.0.0.dist-info/entry_points.txt +2 -0
  36. python_skills-1.0.0.dist-info/licenses/LICENSE +21 -0
  37. skills/advanced_python.md +239 -0
  38. skills/anti_patterns/index.md +406 -0
  39. skills/comprehensions.md +167 -0
  40. skills/control_flow.md +175 -0
  41. skills/data_structures.md +243 -0
  42. skills/debugging/common_bugs.md +222 -0
  43. skills/debugging/inspection_techniques.md +249 -0
  44. skills/debugging/root_cause.md +203 -0
  45. skills/engineering/application_logging.md +195 -0
  46. skills/engineering/cli_apps.md +207 -0
  47. skills/engineering/configuration.md +218 -0
  48. skills/engineering/database.md +240 -0
  49. skills/engineering/dependency_management.md +205 -0
  50. skills/engineering/http_clients.md +267 -0
  51. skills/engineering/modules_packages.md +211 -0
  52. skills/engineering/packaging.md +197 -0
  53. skills/engineering/project_structure.md +155 -0
  54. skills/engineering/pyproject_toml.md +302 -0
  55. skills/engineering/virtual_environments.md +206 -0
  56. skills/functions.md +244 -0
  57. skills/generation/async_concurrency.md +291 -0
  58. skills/generation/error_handling.md +276 -0
  59. skills/generation/protocols_generics.md +243 -0
  60. skills/generation/type_hints.md +290 -0
  61. skills/generation/validation_pipeline.md +274 -0
  62. skills/generation/workflow.md +190 -0
  63. skills/oop.md +228 -0
  64. skills/quality/abstractions.md +154 -0
  65. skills/quality/comments.md +177 -0
  66. skills/quality/documentation.md +176 -0
  67. skills/quality/duplication.md +137 -0
  68. skills/quality/maintainability.md +142 -0
  69. skills/quality/naming.md +171 -0
  70. skills/quality/quality_functions.md +245 -0
  71. skills/quality/readability.md +239 -0
  72. skills/quality/type_annotations.md +192 -0
  73. skills/refactoring/behavior_preservation.md +157 -0
  74. skills/refactoring/incremental.md +187 -0
  75. skills/refactoring/interface_stability.md +199 -0
  76. skills/refactoring/safe_refactoring.md +206 -0
  77. skills/security/auth_boundaries.md +200 -0
  78. skills/security/command_injection.md +207 -0
  79. skills/security/dependency_risks.md +282 -0
  80. skills/security/file_handling.md +156 -0
  81. skills/security/input_validation.md +190 -0
  82. skills/security/path_traversal.md +172 -0
  83. skills/security/secrets.md +171 -0
  84. skills/security/sql_injection.md +188 -0
  85. skills/security/unsafe_deserialization.md +164 -0
  86. skills/stdlib/argparse.md +178 -0
  87. skills/stdlib/collections.md +212 -0
  88. skills/stdlib/datetime.md +187 -0
  89. skills/stdlib/functools.md +238 -0
  90. skills/stdlib/itertools.md +183 -0
  91. skills/stdlib/json.md +162 -0
  92. skills/stdlib/logging.md +185 -0
  93. skills/stdlib/os_sys.md +184 -0
  94. skills/stdlib/pathlib.md +218 -0
  95. skills/stdlib/re.md +171 -0
  96. skills/stdlib/statistics.md +112 -0
  97. skills/stdlib/subprocess.md +211 -0
  98. skills/testing/async_tests.md +249 -0
  99. skills/testing/coverage.md +168 -0
  100. skills/testing/edge_cases.md +197 -0
  101. skills/testing/fixtures_mocks.md +203 -0
  102. skills/testing/organization.md +205 -0
  103. skills/testing/parameterized.md +174 -0
  104. skills/testing/regression_tests.md +165 -0
  105. skills/variables_types.md +107 -0
@@ -0,0 +1,171 @@
1
+ # Quality: Naming
2
+
3
+ **Purpose**: Meaningful, consistent naming conventions.
4
+
5
+ **When to use**: All code generation. Names are the first documentation.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Naming Conventions (PEP 8)
12
+ | Type | Convention | Example |
13
+ |------|------------|---------|
14
+ | Module | lowercase, short | `utils`, `http_client` |
15
+ | Package | lowercase, short | `mypackage`, `api_client` |
16
+ | Class | PascalCase | `UserService`, `HTTPClient` |
17
+ | Function | snake_case | `get_user`, `process_order` |
18
+ | Method | snake_case | `save`, `validate` |
19
+ | Constant | UPPER_SNAKE_CASE | `MAX_RETRIES`, `DEFAULT_TIMEOUT` |
20
+ | Variable | snake_case | `user_count`, `is_active` |
21
+ | Type variable | PascalCase | `T`, `UserT`, `KeyT` |
22
+ | Exception | PascalCase + Error/Exception | `ValidationError`, `NotFoundError` |
23
+
24
+ ### Descriptive Names
25
+ ```python
26
+ # GOOD
27
+ user_count = len(users)
28
+ max_retry_attempts = 3
29
+ is_user_active = user.status == "active"
30
+ process_payment(payment)
31
+
32
+ # BAD
33
+ n = len(users)
34
+ m = 3
35
+ flag = user.status == "active"
36
+ proc(p)
37
+ ```
38
+
39
+ ### Boolean Names
40
+ ```python
41
+ # GOOD — positive, question form
42
+ is_active = True
43
+ has_permission = False
44
+ can_edit = True
45
+ should_retry = True
46
+
47
+ # BAD
48
+ not_inactive = True
49
+ no_permission = False
50
+ active = True # Ambiguous: noun or adj?
51
+ ```
52
+
53
+ ### Collection Names
54
+ ```python
55
+ # GOOD — plural for collections
56
+ users = get_users()
57
+ active_users = [u for u in users if u.is_active]
58
+ user_by_id = {u.id: u for u in users}
59
+
60
+ # BAD
61
+ user_list = get_users()
62
+ user_dict = {u.id: u for u in users}
63
+ ```
64
+
65
+ ### Function Names
66
+ ```python
67
+ # GOOD — verb phrase
68
+ get_user(user_id)
69
+ create_user(data)
70
+ validate_email(email)
71
+ calculate_total(items)
72
+ save_to_database(record)
73
+
74
+ # BAD
75
+ user(user_id) # Noun
76
+ user_create(data) # Verb-noun reversed
77
+ check(email) # Vague
78
+ total(items) # Noun
79
+ persist(record) # Too generic
80
+ ```
81
+
82
+ ### Class Names
83
+ ```python
84
+ # GOOD — noun phrase
85
+ class UserService:
86
+ class PaymentProcessor:
87
+ class DatabaseConnection:
88
+ class HTTPClient:
89
+ class ValidationError:
90
+
91
+ # BAD
92
+ class UserManager: # "Manager" is vague
93
+ class Utils: # Namespace, not class
94
+ class Data: # Too generic
95
+ class HandleUser: # Verb phrase
96
+ ```
97
+
98
+ ### Module Names
99
+ ```python
100
+ # GOOD
101
+ http_client.py
102
+ user_service.py
103
+ payment_processor.py
104
+
105
+ # BAD
106
+ client.py # Too generic
107
+ user.py # Conflicts with class User
108
+ service.py # Vague
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Decision Rules
114
+
115
+ | Context | Convention |
116
+ |---------|------------|
117
+ | Public API | Full descriptive names |
118
+ | Internal helper | Can be shorter if context clear |
119
+ | Loop variable | `i`, `j`, `k` or `idx` |
120
+ | Comprehension | `x`, `item`, `elem` |
121
+ | Type variable | `T`, `K`, `V`, `T_co` |
122
+ | Private | Leading `_` (`_internal`) |
123
+ | Dunder | `__special__` (Python reserved) |
124
+
125
+ ---
126
+
127
+ ## Preferred Patterns
128
+
129
+ ```python
130
+ # Consistent prefixes for related functions
131
+ def fetch_user(user_id: int) -> User:
132
+ def fetch_users(filters: UserFilters) -> list[User]:
133
+ def fetch_user_by_email(email: str) -> User | None:
134
+
135
+ # Consistent suffixes for related classes
136
+ class UserRepository:
137
+ class OrderRepository:
138
+ class ProductRepository:
139
+
140
+ # Clear boolean naming
141
+ if user.can_access(resource):
142
+ if config.should_retry_on_failure:
143
+ if not order.is_cancelled:
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Avoid
149
+
150
+ - Single letters (except loops/math)
151
+ - Abbreviations (`cfg`, `msg`, `usr`, `tmp`)
152
+ - Hungarian notation (`str_name`, `int_count`)
153
+ - Redundant prefixes (`my_`, `the_`, `obj_`)
154
+ - Name shadowing (`list = [...]`, `dict = {}`)
155
+ - Similar names differing only by case (`user` vs `User`)
156
+
157
+ ---
158
+
159
+ ## Validation Considerations
160
+
161
+ - Linter naming checks (`ruff` N800 series)
162
+ - `pylint` naming conventions
163
+ - Code review for clarity
164
+
165
+ ---
166
+
167
+ ## Related Skills
168
+
169
+ - `quality/readability.md`
170
+ - `quality/functions.md`
171
+ - `core/variables_types.md`
@@ -0,0 +1,245 @@
1
+ # Quality: Functions
2
+
3
+ **Purpose**: Function design principles for maintainable code.
4
+
5
+ **When to use**: Writing or reviewing functions.
6
+
7
+ ---
8
+ ---
9
+ name: quality_functions
10
+ purpose: Function design principles for maintainable code
11
+ category: quality
12
+ triggers:
13
+ - function
14
+ - method
15
+ - parameter
16
+ - signature
17
+ - complexity
18
+ - cyclomatic
19
+ dependencies:
20
+ - quality/readability.md
21
+ - quality/maintainability.md
22
+ - quality/abstractions.md
23
+ - generation/error_handling.md
24
+ - testing/organization.md
25
+ priority: primary
26
+ estimated_tokens: 1500
27
+ ---
28
+
29
+ ## Core Rules
30
+
31
+ ### Size
32
+ - **Target**: < 30 lines (excluding docstrings)
33
+ - **Maximum**: 50 lines
34
+ - Split if exceeded
35
+
36
+ ### Single Responsibility
37
+ - One logical operation per function
38
+ - Name describes what it does
39
+ - If "and" in name → split
40
+
41
+ ### Parameters
42
+ - **Target**: ≤ 4 parameters
43
+ - **Maximum**: 7 parameters
44
+ - Use config object for more
45
+
46
+ ```python
47
+ # BAD — too many params
48
+ def process(a, b, c, d, e, f, g, h):
49
+ ...
50
+
51
+ # GOOD — config object
52
+ @dataclass
53
+ class ProcessConfig:
54
+ a: int
55
+ b: str
56
+ c: float
57
+ ...
58
+
59
+ def process(config: ProcessConfig):
60
+ ...
61
+ ```
62
+
63
+ ### Return Values
64
+ - Single return type (union if needed)
65
+ - Early returns for guard clauses
66
+ - Explicit `return` at end (or implicit `None`)
67
+
68
+ ```python
69
+ # GOOD — early returns
70
+ def find_user(users: list[User], id: int) -> User | None:
71
+ if not users:
72
+ return None
73
+
74
+ for user in users:
75
+ if user.id == id:
76
+ return user
77
+
78
+ return None
79
+
80
+ # BAD — nested
81
+ def find_user(users: list[User], id: int) -> User | None:
82
+ result = None
83
+ if users:
84
+ for user in users:
85
+ if user.id == id:
86
+ result = user
87
+ break
88
+ return result
89
+ ```
90
+
91
+ ### Side Effects
92
+ - Document side effects in docstring
93
+ - Prefer pure functions (same input → same output)
94
+ - Separate pure logic from I/O
95
+
96
+ ```python
97
+ # Pure
98
+ def calculate_total(items: list[Item]) -> Decimal:
99
+ return sum(item.price for item in items)
100
+
101
+ # Impure (I/O) — separate
102
+ def save_order(order: Order) -> Order:
103
+ db.save(order)
104
+ return order
105
+ ```
106
+
107
+ ### Function Responsibility
108
+ - One logical operation per function
109
+ - Name describes what it does (verb + object: `validate_email`, `fetch_user`)
110
+ - If name contains "and" → split
111
+ - Each function should be testable in isolation
112
+
113
+ ### Parameter Design
114
+ - **Positional-only** (`/`) for `self`, `cls`, or API stability
115
+ - **Keyword-only** (`*`) for boolean flags and optional config
116
+ - **Default values** must be immutable (use `None` sentinel)
117
+ - **Type hints** required for public API, optional for private helpers
118
+
119
+ ```python
120
+ # GOOD — clear signature
121
+ def fetch_users(
122
+ client: APIClient,
123
+ filters: UserFilters | None = None,
124
+ limit: int = 100,
125
+ *,
126
+ include_inactive: bool = False,
127
+ ) -> list[User]:
128
+ ...
129
+
130
+ # BAD — ambiguous
131
+ def fetch_users(client, filters=None, limit=100, include_inactive=False):
132
+ ...
133
+ ```
134
+
135
+ ### Return Value Design
136
+ - Single return type (union if needed for errors)
137
+ - Early returns for guard clauses
138
+ - Explicit `return` at end (or implicit `None`)
139
+ - Use `Result` pattern for operations that can fail
140
+
141
+ ```python
142
+ # GOOD — early returns, single type
143
+ def find_user(users: list[User], id: int) -> User | None:
144
+ if not users:
145
+ return None
146
+
147
+ for user in users:
148
+ if user.id == id:
149
+ return user
150
+
151
+ return None
152
+
153
+ # GOOD — Result pattern for fallible operations
154
+ def parse_user(data: dict) -> Result[User, ValidationError]:
155
+ try:
156
+ return Result.ok(User.model_validate(data))
157
+ except ValidationError as e:
158
+ return Result.err(e)
159
+ ```
160
+
161
+ ### Side Effects
162
+ - Document side effects in docstring (`"""Creates user and sends welcome email."""`)
163
+ - Prefer pure functions (same input → same output, no external mutation)
164
+ - Separate pure logic from I/O
165
+ - Pass dependencies explicitly, not via global state
166
+
167
+ ```python
168
+ # Pure
169
+ def calculate_total(items: list[Item]) -> Decimal:
170
+ return sum(item.price for item in items)
171
+
172
+ # Impure (I/O) — separate, inject dependencies
173
+ def save_order(order: Order, repo: OrderRepository) -> Order:
174
+ repo.save(order)
175
+ return order
176
+ ```
177
+
178
+ ---
179
+
180
+ ## Decision Rules
181
+
182
+ | Situation | Pattern |
183
+ |-----------|---------|
184
+ | Repeated logic | Extract function |
185
+ | Complex condition | Extract predicate function |
186
+ | Multiple returns | Early returns |
187
+ | Many parameters | Config dataclass |
188
+ | Logic + I/O | Separate functions |
189
+ | Boolean flag controls behavior | Split into two functions |
190
+ | Output parameter (modify argument) | Return new value instead |
191
+ | Recursive without clear base case | Use iteration |
192
+
193
+ ---
194
+
195
+ ## Preferred Patterns
196
+
197
+ ```python
198
+ # Composed from small functions
199
+ def process_order(order: Order) -> Result[Fulfillment, OrderError]:
200
+ validate_order(order)
201
+ payment = charge_payment(order)
202
+ fulfillment = create_fulfillment(order)
203
+ notify_customer(order, fulfillment)
204
+ return Result.ok(fulfillment)
205
+
206
+ # Each small, testable
207
+ def validate_order(order: Order) -> None:
208
+ if not order.items:
209
+ raise ValidationError("items", "Order must have items")
210
+ if order.total <= 0:
211
+ raise ValidationError("total", "Total must be positive")
212
+ ```
213
+
214
+ ---
215
+
216
+ ## Avoid
217
+
218
+ - Functions doing 3+ distinct things
219
+ - Boolean parameters controlling behavior (`process(data, True, False)`)
220
+ - Output parameters (modify argument)
221
+ - Global state modification
222
+ - Recursive functions without clear base case (use iteration)
223
+ - `*args`/`**kwargs` without documentation of expected keys
224
+ - Modifying `**kwargs` in place (copy first)
225
+ - Deeply nested functions (limit closure depth)
226
+
227
+ ---
228
+
229
+ ## Validation Considerations
230
+
231
+ - Cyclomatic complexity per function (< 10)
232
+ - Function length (lines) (< 50)
233
+ - Parameter count (≤ 7)
234
+ - Test coverage per function
235
+ - `ruff` rules: B006 (mutable default), B007 (loop var in closure), B008 (func call in default)
236
+
237
+ ---
238
+
239
+ ## Related Skills
240
+
241
+ - `quality/readability.md`
242
+ - `quality/maintainability.md`
243
+ - `quality/abstractions.md`
244
+ - `generation/error_handling.md`
245
+ - `testing/organization.md`
@@ -0,0 +1,239 @@
1
+ # Quality: Readability
2
+
3
+ **Purpose**: Code should be easy for another developer to understand.
4
+
5
+ **When to use**: All code generation and review.
6
+ ---
7
+ ---
8
+ name: quality_readability
9
+ purpose: Code should be easy for another developer to understand
10
+ category: quality
11
+ triggers:
12
+ - readability
13
+ - cognitive load
14
+ - nesting
15
+ - line length
16
+ - naming
17
+ - guard clause
18
+ dependencies:
19
+ - quality/naming.md
20
+ - quality/functions.md
21
+ - quality/abstractions.md
22
+ - quality/comments.md
23
+ priority: primary
24
+ estimated_tokens: 1500
25
+ ---
26
+
27
+ ## Core Rules
28
+
29
+ ### Cognitive Load
30
+ - Limit concepts per function
31
+ - Use meaningful names (see naming.md)
32
+ - Avoid clever tricks
33
+ - Prefer explicit over implicit
34
+
35
+ ### Vertical Density
36
+ ```python
37
+ # GOOD — spaced out
38
+ def process_user(user: User) -> Result:
39
+ validate(user)
40
+
41
+ enriched = enrich(user)
42
+
43
+ saved = save(enriched)
44
+
45
+ notify(saved)
46
+
47
+ return Result.ok(saved)
48
+
49
+ # BAD — cramped
50
+ def process_user(user): validate(user); enriched=enrich(user); saved=save(enriched); notify(saved); return Result.ok(saved)
51
+ ```
52
+
53
+ ### Horizontal Density
54
+ ```python
55
+ # GOOD — within line length
56
+ result = process(
57
+ user=user,
58
+ options=default_options,
59
+ callback=on_complete,
60
+ )
61
+
62
+ # BAD — too wide
63
+ result = process(user=user, options=default_options, callback=on_complete, timeout=30, retry=True, validate=True)
64
+ ```
65
+
66
+ ### Line Length
67
+ - Target: 88-100 chars (configurable per project)
68
+ - Break long lines at logical points
69
+ - Use parentheses for implicit continuation
70
+
71
+ ```python
72
+ # Good breaks
73
+ long_function_call(
74
+ argument_one=value1,
75
+ argument_two=value2,
76
+ argument_three=value3,
77
+ )
78
+
79
+ # Dictionary
80
+ config = {
81
+ "key_one": "value1",
82
+ "key_two": "value2",
83
+ }
84
+
85
+ # Type hints
86
+ def func(
87
+ arg1: VeryLongTypeName,
88
+ arg2: AnotherVeryLongTypeName,
89
+ ) -> ReturnTypeName:
90
+ ...
91
+ ```
92
+
93
+ ### Blank Lines
94
+ - Between logical sections in function
95
+ - Between class methods
96
+ - Around top-level definitions (2 blank lines)
97
+
98
+ ```python
99
+ def process(data: Data) -> Result:
100
+ # Validation
101
+ if not data.is_valid:
102
+ return Result.error("invalid")
103
+
104
+ # Transformation
105
+ transformed = transform(data)
106
+
107
+ # Persistence
108
+ saved = save(transformed)
109
+
110
+ return Result.ok(saved)
111
+ ```
112
+
113
+ ### Guard Clauses (Reduce Nesting)
114
+ ```python
115
+ # GOOD — flat structure
116
+ def process(user: User) -> Result:
117
+ if not user.active:
118
+ return Result.error("inactive")
119
+
120
+ if not user.has_permission("write"):
121
+ return Result.error("forbidden")
122
+
123
+ # Main logic at base indent
124
+ data = fetch_data(user)
125
+ return Result.ok(transform(data))
126
+
127
+ # BAD — deeply nested
128
+ def process(user: User) -> Result:
129
+ if user.active:
130
+ if user.has_permission("write"):
131
+ data = fetch_data(user)
132
+ return Result.ok(transform(data))
133
+ else:
134
+ return Result.error("forbidden")
135
+ else:
136
+ return Result.error("inactive")
137
+ ```
138
+
139
+ ### Named Intermediate Values
140
+ ```python
141
+ # GOOD — self-documenting
142
+ def calculate_price(item: Item, user: User) -> Price:
143
+ base_price = item.base_price
144
+ discount = user.discount_rate
145
+ tax_rate = get_tax_rate(user.region)
146
+
147
+ discounted = base_price * (1 - discount)
148
+ final = discounted * (1 + tax_rate)
149
+
150
+ return Price(amount=final, currency=item.currency)
151
+
152
+ # BAD — magic calculations
153
+ def calculate_price(item: Item, user: User) -> Price:
154
+ return Price(amount=item.base_price * (1 - user.discount_rate) * (1 + get_tax_rate(user.region)), currency=item.currency)
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Decision Rules
160
+
161
+ | Situation | Pattern |
162
+ |-----------|---------|
163
+ | Complex condition | Extract to variable/function |
164
+ | Long expression | Break across lines |
165
+ | Multiple operations | Separate with blank lines |
166
+ | Nested logic | Early return / guard clauses |
167
+ | Magic numbers | Named constants |
168
+ | Boolean flag controls behavior | Split into two functions |
169
+
170
+ ---
171
+
172
+ ## Preferred Patterns
173
+
174
+ ```python
175
+ # Guard clauses (reduce nesting)
176
+ def process(user: User) -> Result:
177
+ if not user.active:
178
+ return Result.error("inactive")
179
+
180
+ if not user.has_permission("write"):
181
+ return Result.error("forbidden")
182
+
183
+ # Main logic at base indent
184
+ data = fetch_data(user)
185
+ return Result.ok(transform(data))
186
+
187
+ # Named intermediate values
188
+ def calculate_price(item: Item, user: User) -> Price:
189
+ base_price = item.base_price
190
+ discount = user.discount_rate
191
+ tax_rate = get_tax_rate(user.region)
192
+
193
+ discounted = base_price * (1 - discount)
194
+ final = discounted * (1 + tax_rate)
195
+
196
+ return Price(amount=final, currency=item.currency)
197
+
198
+ # Extract complex conditions
199
+ def is_eligible(user: User) -> bool:
200
+ has_active_sub = user.subscription and user.subscription.active
201
+ within_trial = user.trial_end and user.trial_end > datetime.now()
202
+ return has_active_sub or within_trial
203
+
204
+ def process(user: User) -> Result:
205
+ if not is_eligible(user):
206
+ return Result.error("not eligible")
207
+ ...
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Avoid
213
+
214
+ - Single-letter variables (except loop counters: `i`, `j`, `k`)
215
+ - Abbreviations (`usr`, `cfg`, `msg` — use `user`, `config`, `message`)
216
+ - Deep nesting (>3 levels)
217
+ - Long functions (>50 lines)
218
+ - Multiple statements per line
219
+ - Clever one-liners that require mental parsing
220
+ - Single-letter type variables (`T`, `U`) without context
221
+ - Shadowing built-ins (`list`, `dict`, `str`, `type`, `id`)
222
+
223
+ ---
224
+
225
+ ## Validation Considerations
226
+
227
+ - Linter line-length checks (ruff: `line-length`)
228
+ - Cyclomatic complexity (radon, xenon)
229
+ - Code review readability assessment
230
+ - `ruff` rules: B007 (loop var in closure), B008 (func call in default)
231
+
232
+ ---
233
+
234
+ ## Related Skills
235
+
236
+ - `quality/naming.md`
237
+ - `quality/functions.md`
238
+ - `quality/abstractions.md`
239
+ - `quality/comments.md`