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,239 @@
1
+ # Core: Advanced Python
2
+
3
+ **Purpose**: Iterators, generators, decorators, context managers, descriptors.
4
+
5
+ **When to use**: Implementing advanced patterns, libraries, or frameworks.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Iterators
12
+ ```python
13
+ class Iterator:
14
+ def __iter__(self) -> Iterator:
15
+ return self
16
+
17
+ def __next__(self) -> Item:
18
+ if done:
19
+ raise StopIteration
20
+ return next_item
21
+
22
+ # Usage
23
+ for item in Iterator():
24
+ ...
25
+ ```
26
+
27
+ - Implement `__iter__` (returns self) and `__next__`
28
+ - Raise `StopIteration` when exhausted
29
+ - Prefer generators for simple iterators
30
+
31
+ ### Generators
32
+ ```python
33
+ def generator() -> Generator[Item, None, None]:
34
+ for i in range(10):
35
+ yield i
36
+ yield from other_generator() # Delegate
37
+
38
+ # Generator expression
39
+ gen = (x * 2 for x in range(10))
40
+ ```
41
+
42
+ - `yield` produces value, suspends function
43
+ - `yield from` delegates to sub-generator
44
+ - Lazy evaluation — computes on demand
45
+ - Can receive values via `send()` (rare)
46
+
47
+ ### Decorators
48
+ ```python
49
+ import functools
50
+
51
+ def decorator(func):
52
+ @functools.wraps(func)
53
+ def wrapper(*args, **kwargs):
54
+ pre()
55
+ try:
56
+ return func(*args, **kwargs)
57
+ finally:
58
+ post()
59
+ return wrapper
60
+
61
+ # With arguments
62
+ def decorator_with_args(arg):
63
+ def actual_decorator(func):
64
+ @functools.wraps(func)
65
+ def wrapper(*args, **kwargs):
66
+ return func(*args, **kwargs)
67
+ return wrapper
68
+ return actual_decorator
69
+
70
+ @decorator_with_args("value")
71
+ def func():
72
+ ...
73
+ ```
74
+
75
+ - **Always** use `@functools.wraps(func)` on wrapper
76
+ - Decorators execute at **definition time**
77
+ - Class decorators receive class, return class
78
+
79
+ ### Context Managers
80
+ ```python
81
+ # Class-based
82
+ class Resource:
83
+ def __enter__(self):
84
+ self.acquire()
85
+ return self
86
+
87
+ def __exit__(self, exc_type, exc_val, exc_tb):
88
+ self.release()
89
+ return False # Don't suppress exceptions
90
+
91
+ # Generator-based (contextlib)
92
+ from contextlib import contextmanager
93
+
94
+ @contextmanager
95
+ def resource():
96
+ r = acquire()
97
+ try:
98
+ yield r
99
+ finally:
100
+ r.release()
101
+
102
+ # Usage
103
+ with resource() as r:
104
+ r.use()
105
+ ```
106
+
107
+ - `__exit__` receives exception info; return `True` to suppress
108
+ - `@contextmanager` yields once; cleanup in `finally`
109
+ - Use for resource management (files, locks, connections, transactions)
110
+
111
+ ### Descriptors
112
+ ```python
113
+ class Descriptor:
114
+ def __get__(self, obj, objtype=None):
115
+ if obj is None:
116
+ return self
117
+ return obj._value
118
+
119
+ def __set__(self, obj, value):
120
+ obj._value = value
121
+
122
+ def __delete__(self, obj):
123
+ del obj._value
124
+
125
+ class MyClass:
126
+ attr = Descriptor()
127
+ ```
128
+
129
+ - Protocol: `__get__`, `__set__`, `__delete__`
130
+ - Data descriptors (`__set__` or `__delete__`) override instance `__dict__`
131
+ - Non-data descriptors (only `__get__`) overridden by instance `__dict__`
132
+ - Used by: `property`, `classmethod`, `staticmethod`, `field`
133
+
134
+ ### Metaclasses (Rare)
135
+ ```python
136
+ class Meta(type):
137
+ def __new__(mcs, name, bases, namespace):
138
+ # Modify class creation
139
+ return super().__new__(mcs, name, bases, namespace)
140
+
141
+ class MyClass(metaclass=Meta):
142
+ ...
143
+ ```
144
+
145
+ - Customize class creation
146
+ - Use sparingly; prefer `__init_subclass__` (Python 3.6+)
147
+
148
+ ### `__init_subclass__`
149
+ ```python
150
+ class Base:
151
+ subclasses = []
152
+
153
+ def __init_subclass__(cls, **kwargs):
154
+ super().__init_subclass__(**kwargs)
155
+ Base.subclasses.append(cls)
156
+ ```
157
+
158
+ - Called when subclass is defined
159
+ - Simpler than metaclasses for registration
160
+
161
+ ---
162
+
163
+ ## Decision Rules
164
+
165
+ | Need | Tool |
166
+ |------|------|
167
+ | Simple iteration | Generator function |
168
+ | Complex iterator state | Iterator class |
169
+ | Resource cleanup | Context manager (`@contextmanager` or class) |
170
+ | Cross-cutting behavior | Decorator |
171
+ | Attribute access control | Descriptor / `property` |
172
+ | Class registration | `__init_subclass__` |
173
+ | Class creation control | Metaclass (last resort) |
174
+
175
+ ---
176
+
177
+ ## Preferred Patterns
178
+
179
+ ```python
180
+ # Generator for lazy sequences
181
+ def read_lines(path: Path) -> Generator[str, None, None]:
182
+ with path.open() as f:
183
+ for line in f:
184
+ yield line.rstrip('\n')
185
+
186
+ # Context manager for temp resources
187
+ @contextmanager
188
+ def temp_dir():
189
+ path = Path(tempfile.mkdtemp())
190
+ try:
191
+ yield path
192
+ finally:
193
+ shutil.rmtree(path)
194
+
195
+ # Decorator with args preserving signature
196
+ def retry(times: int = 3, delay: float = 1.0):
197
+ def decorator(func):
198
+ @functools.wraps(func)
199
+ def wrapper(*args, **kwargs):
200
+ for attempt in range(times):
201
+ try:
202
+ return func(*args, **kwargs)
203
+ except Exception:
204
+ if attempt == times - 1:
205
+ raise
206
+ time.sleep(delay)
207
+ return wrapper
208
+ return decorator
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Avoid
214
+
215
+ - Generators that don't clean up resources (use `try/finally` or context manager)
216
+ - Decorators without `@functools.wraps`
217
+ - Complex metaclasses when `__init_subclass__` suffices
218
+ - Descriptors for simple attribute access (use `@property`)
219
+ - `yield` in `finally` block (confusing semantics)
220
+ - Mixing `yield` and `return` with values in same generator
221
+
222
+ ---
223
+
224
+ ## Validation Considerations
225
+
226
+ - `contextlib.closing` for objects with `close()`
227
+ - `contextlib.AsyncExitStack` for async context managers
228
+ - Type checkers understand generator types: `Generator[Yield, Send, Return]`
229
+ - `inspect.isgeneratorfunction()`, `inspect.isgenerator()`
230
+
231
+ ---
232
+
233
+ ## Related Skills
234
+
235
+ - `generation/async_concurrency.md` (async generators, context managers)
236
+ - `generation/error_handling.md` (context manager exception handling)
237
+ - `stdlib/functools.md` (wraps, lru_cache)
238
+ - `quality/functions.md`
239
+ - `anti_patterns/index.md`
@@ -0,0 +1,406 @@
1
+ # Anti-Patterns: Index
2
+
3
+ **Purpose**: Prevent generation of known anti-patterns. This is the master reference.
4
+
5
+ **When to use**: Always active. Check before and during code generation.
6
+
7
+ ---
8
+
9
+ ## Quick Reference
10
+
11
+ | Category | Anti-Pattern | Prevention |
12
+ |----------|--------------|------------|
13
+ | **Exceptions** | Bare `except:` / `except Exception:` | Catch specific exceptions only |
14
+ | **Exceptions** | Swallowed exceptions | Log or re-raise, never silent |
15
+ | **Arguments** | Mutable default arguments | Use `None` sentinel pattern |
16
+ | **State** | Unnecessary global state | Use dependency injection |
17
+ | **Dependencies** | Unnecessary dependencies | Stdlib first, existing deps second |
18
+ | **Inheritance** | Excessive inheritance | Prefer composition |
19
+ | **Abstraction** | Premature abstraction | Wait for 3+ use cases (Rule of Three) |
20
+ | **Functions** | Giant functions (>50 lines) | Extract to smaller functions |
21
+ | **Classes** | God classes | Single responsibility, split |
22
+ | **Duplication** | Duplicated logic | Extract (true duplication only) |
23
+ | **Cleverness** | Unreadable one-liners | Prefer explicit, readable code |
24
+ | **Comprehensions** | Unnecessary/overly complex | Use loops for complex logic |
25
+ | **Async** | Premature async | Only for I/O-bound concurrency |
26
+ | **Optimization** | Premature optimization | Profile first, optimize bottlenecks |
27
+ | **Secrets** | Hardcoded secrets | Environment variables, secret managers |
28
+ | **Subprocess** | Unsafe subprocess usage | List form, no `shell=True`, allowlist |
29
+ | **Deserialization** | Unsafe deserialization | `json`, `yaml.safe_load`, never `pickle` |
30
+ | **SQL** | SQL injection | Parameterized queries only |
31
+ | **Files** | Insecure temp files | `tempfile`, validate paths |
32
+ | **Eval/Exec** | Unnecessary `eval`/`exec` | Never for untrusted input |
33
+
34
+ ---
35
+
36
+ ## Detailed Patterns
37
+
38
+ ### 1. Bare Except
39
+ ```python
40
+ # ANTI-PATTERN
41
+ try:
42
+ risky()
43
+ except:
44
+ pass # Catches KeyboardInterrupt, SystemExit!
45
+
46
+ try:
47
+ risky()
48
+ except Exception:
49
+ pass # Swallows all errors silently
50
+
51
+ # CORRECT
52
+ try:
53
+ risky()
54
+ except SpecificError:
55
+ handle()
56
+ except AnotherError:
57
+ handle()
58
+ ```
59
+
60
+ ### 2. Mutable Default Arguments
61
+ ```python
62
+ # ANTI-PATTERN
63
+ def func(items=[]):
64
+ items.append(1)
65
+ return items
66
+
67
+ # CORRECT
68
+ def func(items=None):
69
+ if items is None:
70
+ items = []
71
+ items.append(1)
72
+ return items
73
+ ```
74
+
75
+ ### 3. Global Mutable State
76
+ ```python
77
+ # ANTI-PATTERN
78
+ cache = {}
79
+
80
+ def get_data(key):
81
+ if key not in cache:
82
+ cache[key] = fetch(key)
83
+ return cache[key]
84
+
85
+ # CORRECT
86
+ class DataService:
87
+ def __init__(self):
88
+ self._cache = {}
89
+
90
+ def get_data(self, key):
91
+ if key not in self._cache:
92
+ self._cache[key] = fetch(key)
93
+ return self._cache[key]
94
+
95
+ # Inject instance where needed
96
+ ```
97
+
98
+ ### 4. Swallowed Exceptions
99
+ ```python
100
+ # ANTI-PATTERN
101
+ try:
102
+ save(user)
103
+ except:
104
+ pass # User not saved, no indication!
105
+
106
+ # CORRECT
107
+ try:
108
+ save(user)
109
+ except DatabaseError as e:
110
+ logger.error("Failed to save user", extra={"user_id": user.id, "error": str(e)})
111
+ raise SaveFailedError() from e
112
+ ```
113
+
114
+ ### 5. Unnecessary Dependencies
115
+ ```python
116
+ # ANTI-PATTERN — adding `requests` for one HTTP call
117
+ # when `urllib` or `http.client` in stdlib works
118
+
119
+ # CORRECT — evaluate need
120
+ # If simple GET: urllib.request
121
+ # If complex: requests/httpx justified
122
+ ```
123
+
124
+ ### 6. Excessive Inheritance
125
+ ```python
126
+ # ANTI-PATTERN
127
+ class Base:
128
+ def a(self): ...
129
+ def b(self): ...
130
+
131
+ class A(Base): ...
132
+ class B(A): ...
133
+ class C(B): ...
134
+ class D(C): ... # 4 levels!
135
+
136
+ # CORRECT — composition
137
+ class Service:
138
+ def __init__(self, a: A, b: B, c: C):
139
+ self.a = a
140
+ self.b = b
141
+ self.c = c
142
+ ```
143
+
144
+ ### 7. Premature Abstraction
145
+ ```python
146
+ # ANTI-PATTERN — abstracting after 1 use
147
+ def process_user(user):
148
+ validate(user)
149
+ save(user)
150
+ notify(user)
151
+
152
+ def process_order(order):
153
+ validate(order)
154
+ save(order)
155
+ notify(order)
156
+
157
+ # Abstracted to:
158
+ def process(entity): # WRONG - different validation!
159
+ validate(entity)
160
+ save(entity)
161
+ notify(entity)
162
+
163
+ # CORRECT — wait for 3rd use case with SAME pattern
164
+ ```
165
+
166
+ ### 8. Giant Functions
167
+ ```python
168
+ # ANTI-PATTERN
169
+ def process_everything(data):
170
+ # 200 lines of validation, calculation, persistence, notification
171
+ ...
172
+
173
+ # CORRECT
174
+ def validate(data): ...
175
+ def calculate(data): ...
176
+ def persist(data): ...
177
+ def notify(data): ...
178
+
179
+ def process(data):
180
+ validate(data)
181
+ result = calculate(data)
182
+ persist(result)
183
+ notify(result)
184
+ ```
185
+
186
+ ### 9. God Classes
187
+ ```python
188
+ # ANTI-PATTERN
189
+ class UserManager:
190
+ def create(self): ...
191
+ def delete(self): ...
192
+ def update(self): ...
193
+ def get(self): ...
194
+ def list(self): ...
195
+ def send_email(self): ...
196
+ def generate_report(self): ...
197
+ def backup(self): ...
198
+ def migrate(self): ...
199
+ # 20+ methods, multiple responsibilities
200
+
201
+ # CORRECT
202
+ class UserRepository: ...
203
+ class UserService: ...
204
+ class EmailService: ...
205
+ class ReportGenerator: ...
206
+ class BackupService: ...
207
+ ```
208
+
209
+ ### 10. Clever One-Liners
210
+ ```python
211
+ # ANTI-PATTERN
212
+ result = [x for y in data for x in y.split() if x.isalnum() and len(x) > 2]
213
+
214
+ # CORRECT
215
+ result = []
216
+ for item in data:
217
+ for word in item.split():
218
+ if word.isalnum() and len(word) > 2:
219
+ result.append(word)
220
+ ```
221
+
222
+ ### 11. Premature Async
223
+ ```python
224
+ # ANTI-PATTERN
225
+ async def process(data): # No I/O, just CPU
226
+ return compute(data)
227
+
228
+ # CORRECT — sync for CPU-bound
229
+ def process(data):
230
+ return compute(data)
231
+
232
+ # CORRECT — async for I/O-bound
233
+ async def fetch_data(url):
234
+ async with httpx.AsyncClient() as client:
235
+ return await client.get(url)
236
+ ```
237
+
238
+ ### 12. Premature Optimization
239
+ ```python
240
+ # ANTI-PATTERN
241
+ # Using complex caching for 10 items
242
+ # Using C extension for simple loop
243
+ # Pre-computing everything at startup
244
+
245
+ # CORRECT
246
+ # Profile first
247
+ # Optimize measured bottlenecks
248
+ # Keep simple until proven necessary
249
+ ```
250
+
251
+ ### 13. Hardcoded Secrets
252
+ ```python
253
+ # ANTI-PATTERN
254
+ API_KEY = "sk_live_abc123"
255
+ DB_PASSWORD = "secret123"
256
+
257
+ # CORRECT
258
+ import os
259
+ API_KEY = os.getenv("API_KEY")
260
+ DB_PASSWORD = os.getenv("DB_PASSWORD")
261
+ ```
262
+
263
+ ### 14. Unsafe Subprocess
264
+ ```python
265
+ # ANTI-PATTERN
266
+ subprocess.run(f"process {user_input}", shell=True)
267
+
268
+ # CORRECT
269
+ subprocess.run(["process", user_input], check=True)
270
+ ```
271
+
272
+ ### 15. Unsafe Deserialization
273
+ ```python
274
+ # ANTI-PATTERN
275
+ import pickle
276
+ data = pickle.loads(untrusted_bytes) # RCE!
277
+
278
+ import yaml
279
+ data = yaml.load(untrusted_string) # RCE!
280
+
281
+ # CORRECT
282
+ import json
283
+ data = json.loads(untrusted_string)
284
+
285
+ import yaml
286
+ data = yaml.safe_load(untrusted_string)
287
+ ```
288
+
289
+ ### 16. SQL Injection
290
+ ```python
291
+ # ANTI-PATTERN
292
+ cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
293
+
294
+ # CORRECT
295
+ cursor.execute("SELECT * FROM users WHERE name = %s", (name,))
296
+ ```
297
+
298
+ ### 17. Insecure Temp Files
299
+ ```python
300
+ # ANTI-PATTERN
301
+ with open("/tmp/myfile.txt", "w") as f: # Predictable, race condition
302
+ f.write(secret)
303
+
304
+ # CORRECT
305
+ import tempfile
306
+ with tempfile.NamedTemporaryFile(mode="w", delete=False) as f:
307
+ f.write(secret)
308
+ # Or
309
+ with tempfile.TemporaryDirectory() as tmpdir:
310
+ path = Path(tmpdir) / "file.txt"
311
+ path.write_text(secret)
312
+ ```
313
+
314
+ ### 18. Unnecessary Eval/Exec
315
+ ```python
316
+ # ANTI-PATTERN
317
+ result = eval(user_input) # RCE!
318
+ exec(user_code) # RCE!
319
+
320
+ # CORRECT
321
+ # Never eval/exec untrusted input
322
+ # Use proper parsing (json, ast.literal_eval for safe subset)
323
+ import ast
324
+ safe = ast.literal_eval(user_input) # Only literals
325
+ ```
326
+
327
+ ---
328
+
329
+ ## Validation Checklist (Before Committing Code)
330
+
331
+ - [ ] No bare `except:` or `except Exception:`
332
+ - [ ] No mutable default arguments
333
+ - [ ] No global mutable state
334
+ - [ ] No swallowed exceptions
335
+ - [ ] No unnecessary dependencies added
336
+ - [ ] No inheritance >2 levels
337
+ - [ ] No abstraction without 3+ use cases
338
+ - [ ] No functions >50 lines
339
+ - [ ] No classes with >10 public methods
340
+ - [ ] No duplicated logic (true duplication)
341
+ - [ ] No clever unreadable one-liners
342
+ - [ ] No unnecessary comprehensions
343
+ - [ ] No async without I/O
344
+ - [ ] No optimization without profiling
345
+ - [ ] No hardcoded secrets
346
+ - [ ] No `shell=True` with user input
347
+ - [ ] No `pickle`/`yaml.load` on untrusted data
348
+ - [ ] No string interpolation in SQL
349
+ - [ ] No predictable temp file names
350
+ - [ ] No `eval`/`exec` on untrusted input
351
+
352
+ ---
353
+
354
+ ## Enforcement
355
+
356
+ ```bash
357
+ # Ruff rules that catch many
358
+ ruff check .
359
+ # B001: bare except
360
+ # B006: mutable default argument
361
+ # B007: loop variable in closure
362
+ # B008: function call in default arg
363
+ # B009: unused loop variable
364
+ # B010: redundant exception caught
365
+ # B011: assert in non-test
366
+ # B012: mutable class attribute
367
+ # B014: unnecessary list comp
368
+ # B015: unnecessary set comp
369
+ # B016: unnecessary dict comp
370
+ # B017: unnecessary generator
371
+ # B018: unnecessary ternary
372
+ # B019: unnecessary lambda
373
+ # S101: assert in test (OK in tests)
374
+ # S102: exec
375
+ # S103: eval
376
+ # S104: hardcoded password
377
+ # S105: hardcoded password in string
378
+ # S106: hardcoded password in config
379
+ # S107: hardcoded password in command
380
+ # S108: hardcoded tmp directory
381
+ # S109: hardcoded password in function call
382
+ # S601: shell=True
383
+ # S602: shell=True with variable
384
+ # S603: shell=True with input
385
+ # S604: shell=True with user input
386
+ # S605: shell=True with command
387
+ # S606: shell=True with user input
388
+ # S607: shell=True with variable
389
+ # S608: SQL injection
390
+ # S609: SQL injection
391
+ # S610: shell=True with variable
392
+ ```
393
+
394
+ ---
395
+
396
+ ## Related Skills
397
+
398
+ All skills reference anti-patterns. Key connections:
399
+ - `generation/error_handling.md` (exceptions)
400
+ - `core/functions.md` (mutable defaults)
401
+ - `quality/abstractions.md` (premature abstraction)
402
+ - `quality/functions.md` (giant functions)
403
+ - `quality/duplication.md` (duplication)
404
+ - `generation/async_concurrency.md` (premature async)
405
+ - `security/*` (secrets, injection, deserialization)
406
+ - `debugging/common_bugs.md` (common bug patterns)