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,222 @@
1
+ # Debugging: Common Bugs
2
+
3
+ **Purpose**: Quick reference for frequent Python bug patterns.
4
+
5
+ **When to use**: Debugging, code review, preventing known issues.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Mutable Default Arguments
12
+ ```python
13
+ # BUG
14
+ def append_item(item, items=[]):
15
+ items.append(item)
16
+ return items
17
+
18
+ append_item(1) # [1]
19
+ append_item(2) # [1, 2] — BUG: shared list!
20
+
21
+ # FIX
22
+ def append_item(item, items=None):
23
+ if items is None:
24
+ items = []
25
+ items.append(item)
26
+ return items
27
+ ```
28
+
29
+ ### Late Binding in Closures
30
+ ```python
31
+ # BUG
32
+ funcs = []
33
+ for i in range(3):
34
+ funcs.append(lambda: i)
35
+
36
+ [f() for f in funcs] # [2, 2, 2] — all capture same i!
37
+
38
+ # FIX — bind early
39
+ funcs = []
40
+ for i in range(3):
41
+ funcs.append(lambda i=i: i) # Default binds current value
42
+
43
+ # OR use functools.partial
44
+ from functools import partial
45
+ funcs = [partial(lambda x: x, i) for i in range(3)]
46
+ ```
47
+
48
+ ### Integer Division (Python 2 vs 3)
49
+ ```python
50
+ # Python 3: / is float division, // is integer
51
+ 3 / 2 # 1.5
52
+ 3 // 2 # 1
53
+
54
+ # In Python 2: / was integer division for ints
55
+ # Not an issue in Python 3+
56
+ ```
57
+
58
+ ### Floating Point Precision
59
+ ```python
60
+ # BUG
61
+ 0.1 + 0.2 == 0.3 # False! 0.30000000000000004
62
+
63
+ # FIX — use Decimal for money/precision
64
+ from decimal import Decimal
65
+ Decimal("0.1") + Decimal("0.2") == Decimal("0.3") # True
66
+
67
+ # Or use tolerance
68
+ abs(0.1 + 0.2 - 0.3) < 1e-9 # True
69
+ ```
70
+
71
+ ### Variable Shadowing
72
+ ```python
73
+ # BUG
74
+ def process(items):
75
+ list = [] # Shadows built-in list!
76
+ for item in items:
77
+ list.append(transform(item))
78
+ return list
79
+
80
+ # FIX — never shadow builtins
81
+ def process(items):
82
+ result = []
83
+ for item in items:
84
+ result.append(transform(item))
85
+ return result
86
+ ```
87
+
88
+ ### Iterable Exhaustion
89
+ ```python
90
+ # BUG
91
+ gen = (x for x in range(3))
92
+ list(gen) # [0, 1, 2]
93
+ list(gen) # [] — exhausted!
94
+
95
+ # FIX — convert to list if reused
96
+ gen = list(x for x in range(3))
97
+ list(gen) # [0, 1, 2]
98
+ list(gen) # [0, 1, 2]
99
+ ```
100
+
101
+ ### Default Dict Mutation
102
+ ```python
103
+ # BUG
104
+ from collections import defaultdict
105
+
106
+ def add_item(key, value, d=defaultdict(list)):
107
+ d[key].append(value)
108
+ return d
109
+
110
+ add_item("a", 1) # {"a": [1]}
111
+ add_item("b", 2) # {"a": [1], "b": [2]} — SHARED!
112
+
113
+ # FIX
114
+ def add_item(key, value, d=None):
115
+ if d is None:
116
+ d = defaultdict(list)
117
+ d[key].append(value)
118
+ return d
119
+ ```
120
+
121
+ ### Exception Swallowing
122
+ ```python
123
+ # BUG
124
+ try:
125
+ risky()
126
+ except:
127
+ pass # Swallows everything including KeyboardInterrupt!
128
+
129
+ # FIX — specific exceptions
130
+ try:
131
+ risky()
132
+ except SpecificError:
133
+ handle()
134
+ except Exception:
135
+ logger.exception("Unexpected error")
136
+ raise
137
+ ```
138
+
139
+ ### Modifying During Iteration
140
+ ```python
141
+ # BUG
142
+ items = [1, 2, 3, 4, 5]
143
+ for item in items:
144
+ if item % 2 == 0:
145
+ items.remove(item) # Skips elements!
146
+
147
+ # FIX — iterate over copy
148
+ for item in items[:]: # or list(items)
149
+ if item % 2 == 0:
150
+ items.remove(item)
151
+
152
+ # OR filter
153
+ items = [x for x in items if x % 2 != 0]
154
+ ```
155
+
156
+ ### String/Bytes Confusion
157
+ ```python
158
+ # BUG
159
+ data = b"hello"
160
+ data + " world" # TypeError: can't concat bytes to str
161
+
162
+ # FIX — explicit encode/decode
163
+ data.decode() + " world" # "hello world"
164
+ data + b" world" # b"hello world"
165
+ ```
166
+
167
+ ### Path Traversal (Security)
168
+ ```python
169
+ # BUG
170
+ def read_file(filename):
171
+ with open(filename) as f: # User controls path!
172
+ return f.read()
173
+
174
+ # FIX — validate path
175
+ def read_file(filename, base_dir):
176
+ path = (Path(base_dir) / filename).resolve()
177
+ if not path.is_relative_to(base_dir):
178
+ raise SecurityError("Path traversal")
179
+ return path.read_text()
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Decision Rules
185
+
186
+ | Symptom | Likely Cause |
187
+ |---------|--------------|
188
+ | State persists across calls | Mutable default argument |
189
+ | Loop variable wrong in closure | Late binding |
190
+ | Money calculations wrong | Float precision |
191
+ | First/last element wrong | Off-by-one |
192
+ | Intermittent failures | Race condition / shared state |
193
+ | Unicode errors | Bytes/str confusion |
194
+ | Second iteration empty | Iterator exhaustion |
195
+
196
+ ---
197
+
198
+ ## Avoid
199
+
200
+ - `except:` without exception type
201
+ - `list`, `dict`, `str` as variable names
202
+ - `float` for money
203
+ - Implicit iterator reuse
204
+ - User input in file paths without validation
205
+
206
+ ---
207
+
208
+ ## Validation Considerations
209
+
210
+ - `ruff` catches most of these (B006, B007, B008, etc.)
211
+ - `mypy` catches type issues
212
+ - Unit tests for edge cases
213
+ - Property-based testing finds edge cases
214
+
215
+ ---
216
+
217
+ ## Related Skills
218
+
219
+ - `debugging/root_cause.md`
220
+ - `anti_patterns/index.md`
221
+ - `security/input_validation.md`
222
+ - `generation/type_hints.md`
@@ -0,0 +1,249 @@
1
+ # Debugging: Inspection Techniques
2
+
3
+ **Purpose**: Tools and techniques for runtime inspection and debugging.
4
+
5
+ **When to use**: Investigating bugs, understanding code behavior, profiling.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Runtime Inspection
12
+
13
+ #### Object Inspection
14
+ ```python
15
+ # Type and attributes
16
+ type(obj)
17
+ dir(obj)
18
+ vars(obj) # __dict__
19
+ hasattr(obj, 'attr')
20
+ getattr(obj, 'attr', default)
21
+ isinstance(obj, Type)
22
+ issubclass(cls, Type)
23
+
24
+ # Function inspection
25
+ import inspect
26
+ inspect.signature(func)
27
+ inspect.getsource(func)
28
+ inspect.getfile(func)
29
+ inspect.getmodule(func)
30
+ inspect.iscoroutinefunction(func)
31
+ inspect.isgeneratorfunction(func)
32
+ ```
33
+
34
+ #### Frame Inspection
35
+ ```python
36
+ import sys
37
+
38
+ # Current frame
39
+ frame = sys._getframe()
40
+ frame.f_locals # Local variables
41
+ frame.f_globals # Global variables
42
+ frame.f_code # Code object
43
+ frame.f_lineno # Line number
44
+
45
+ # Call stack
46
+ traceback.print_stack()
47
+ traceback.extract_stack()
48
+
49
+ # In exception handler
50
+ import traceback
51
+ traceback.print_exc()
52
+ traceback.format_exc()
53
+ ```
54
+
55
+ #### Object Graph
56
+ ```python
57
+ import gc
58
+
59
+ # Find referrers (what references this object)
60
+ gc.get_referrers(obj)
61
+
62
+ # Find referents (what this object references)
63
+ gc.get_referents(obj)
64
+
65
+ # All objects of type
66
+ [obj for obj in gc.get_objects() if isinstance(obj, MyClass)]
67
+ ```
68
+
69
+ ### Profiling
70
+
71
+ #### Time Profiling
72
+ ```bash
73
+ # cProfile
74
+ python -m cProfile -o profile.stats script.py
75
+ # Analyze
76
+ python -m pstats profile.stats
77
+ # Sort by cumulative time, show top 20
78
+ # pstats> sort cumulative
79
+ # pstats> stats 20
80
+ ```
81
+
82
+ ```python
83
+ # In code
84
+ import cProfile
85
+ import pstats
86
+
87
+ profiler = cProfile.Profile()
88
+ profiler.enable()
89
+
90
+ # ... code to profile ...
91
+
92
+ profiler.disable()
93
+ stats = pstats.Stats(profiler).sort_stats('cumulative')
94
+ stats.print_stats(20)
95
+ ```
96
+
97
+ #### Memory Profiling
98
+ ```bash
99
+ # memray (modern, fast)
100
+ pip install memray
101
+ memray run script.py
102
+ memray flamegraph memray-results.bin
103
+
104
+ # objgraph (object counts)
105
+ pip install objgraph
106
+ python -c "import objgraph; objgraph.show_most_common_types()"
107
+ ```
108
+
109
+ #### Line Profiling
110
+ ```bash
111
+ # kernprof
112
+ pip install line_profiler
113
+ kernprof -l -v script.py
114
+ ```
115
+
116
+ ### Logging for Debugging
117
+ ```python
118
+ import logging
119
+
120
+ # Structured debug logging
121
+ logging.basicConfig(
122
+ level=logging.DEBUG,
123
+ format="%(asctime)s [%(levelname)s] %(name)s:%(lineno)d: %(message)s"
124
+ )
125
+
126
+ # Context-specific logger
127
+ logger = logging.getLogger("myapp.debug")
128
+
129
+ # Conditional debug
130
+ if logger.isEnabledFor(logging.DEBUG):
131
+ logger.debug("Expensive debug: %s", expensive_computation())
132
+ ```
133
+
134
+ ### REPL Debugging
135
+ ```python
136
+ # In code
137
+ breakpoint()
138
+ # Python 3.7+ opens pdb at this line
139
+ # In pdb: p var, pp var, n, s, c, l, where, up, down
140
+
141
+ # Or embed IPython
142
+ import IPython
143
+ IPython.embed() # Rich REPL with syntax highlighting
144
+ ```
145
+
146
+ ### Async Debugging
147
+ ```python
148
+ # Check running tasks
149
+ async def debug_tasks():
150
+ for task in asyncio.all_tasks():
151
+ print(task.get_name(), task.get_coro())
152
+
153
+ # Current task
154
+ current = asyncio.current_task()
155
+ print(current.get_stack())
156
+
157
+ # Trace async calls
158
+ import asyncio
159
+ asyncio.set_debug(True)
160
+ # Or
161
+ loop = asyncio.get_event_loop()
162
+ loop.set_debug(True)
163
+ ```
164
+
165
+ ### Network Debugging
166
+ ```bash
167
+ # HTTP traffic
168
+ mitmproxy # Interactive
169
+ mitmdump # Scriptable
170
+
171
+ # Or in Python
172
+ import http.client
173
+ http.client.HTTPConnection.debuglevel = 1
174
+
175
+ # requests
176
+ import logging
177
+ logging.getLogger("urllib3").setLevel(logging.DEBUG)
178
+ ```
179
+
180
+ ### Database Debugging
181
+ ```python
182
+ # SQLAlchemy
183
+ import logging
184
+ logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
185
+ # Shows all SQL with parameters
186
+
187
+ # Or echo
188
+ engine = create_engine("postgresql://...", echo=True)
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Decision Rules
194
+
195
+ | Need | Tool |
196
+ |------|------|
197
+ | Quick variable check | `breakpoint()` / `print()` |
198
+ | Performance bottleneck | `cProfile` / `memray` |
199
+ | Memory leak | `memray` / `objgraph` |
200
+ | Async deadlock | `asyncio` debug + task inspection |
201
+ | SQL query issues | SQLAlchemy echo |
202
+ | HTTP issues | `mitmproxy` / request logging |
203
+ | Object lifecycle | `gc` / `weakref` |
204
+
205
+ ---
206
+
207
+ ## Preferred Patterns
208
+
209
+ ```python
210
+ # Debug helper
211
+ def debug_obj(obj, name="obj"):
212
+ print(f"=== {name} ===")
213
+ print(f"Type: {type(obj)}")
214
+ print(f"Dir: {[a for a in dir(obj) if not a.startswith('_')]}")
215
+ if hasattr(obj, '__dict__'):
216
+ print(f"Dict: {vars(obj)}")
217
+ print(f"=== end {name} ===")
218
+
219
+ # Usage
220
+ debug_obj(user, "user")
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Avoid
226
+
227
+ - `print()` in production code
228
+ - Leaving `breakpoint()` in committed code
229
+ - Profiling in production without sampling
230
+ - `gc.get_objects()` in hot paths (slow)
231
+ - Modifying `sys.path` at runtime
232
+
233
+ ---
234
+
235
+ ## Validation Considerations
236
+
237
+ - Debug code removed before commit
238
+ - Profiling overhead acceptable
239
+ - Logs don't contain secrets
240
+ - Async debug doesn't change timing significantly
241
+
242
+ ---
243
+
244
+ ## Related Skills
245
+
246
+ - `debugging/root_cause.md`
247
+ - `debugging/common_bugs.md`
248
+ - `stdlib/logging.md`
249
+ - `generation/async_concurrency.md`
@@ -0,0 +1,203 @@
1
+ # Debugging: Root Cause Analysis
2
+
3
+ **Purpose**: Systematic approach to finding and fixing bugs.
4
+
5
+ **When to use**: Any bug investigation.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Debugging Process
12
+ ```
13
+ 1. REPRODUCE — Create minimal failing case
14
+ 2. ISOLATE — Narrow down location
15
+ 3. HYPOTHESIZE — Form theory of cause
16
+ 4. TEST HYPOTHESIS — Verify with experiment
17
+ 5. FIX — Minimal change addressing root cause
18
+ 6. REGRESSION TEST — Prevent recurrence
19
+ 7. DOCUMENT — Record for future
20
+ ```
21
+
22
+ ### Reproduction
23
+ ```python
24
+ # Minimal reproduction script
25
+ # reproduce_issue.py
26
+ import sys
27
+ sys.path.insert(0, "src")
28
+
29
+ from mypackage import process
30
+
31
+ # Exact input that fails
32
+ input_data = load_failing_case()
33
+
34
+ try:
35
+ result = process(input_data)
36
+ print("UNEXPECTED SUCCESS:", result)
37
+ except Exception as e:
38
+ print(f"REPRODUCED: {type(e).__name__}: {e}")
39
+ import traceback
40
+ traceback.print_exc()
41
+ ```
42
+
43
+ ### Isolation Techniques
44
+
45
+ #### Binary Search (Git Bisect)
46
+ ```bash
47
+ # Find commit that introduced bug
48
+ git bisect start
49
+ git bisect bad HEAD
50
+ git bisect good v1.0.0
51
+ # Git checks out middle commit
52
+ # Run tests: pytest test_failing.py
53
+ # git bisect good/bad
54
+ # Repeats until found
55
+ ```
56
+
57
+ #### Print Debugging (Structured)
58
+ ```python
59
+ import logging
60
+ logging.basicConfig(level=logging.DEBUG)
61
+
62
+ # Or structured
63
+ import structlog
64
+ log = structlog.get_logger()
65
+
66
+ def problematic_function(data):
67
+ log.debug("enter", data_keys=list(data.keys()))
68
+ result = step1(data)
69
+ log.debug("after_step1", result=result)
70
+ result = step2(result)
71
+ log.debug("after_step2", result=result)
72
+ return result
73
+ ```
74
+
75
+ #### Interactive Debugger
76
+ ```python
77
+ # In code
78
+ breakpoint() # Python 3.7+
79
+
80
+ # Or conditional
81
+ if condition:
82
+ breakpoint()
83
+
84
+ # Run: python -m pdb script.py
85
+ # Commands: n (next), s (step), c (continue), p (print), l (list)
86
+ ```
87
+
88
+ ### Common Bug Patterns
89
+
90
+ | Pattern | Symptoms | Investigation |
91
+ |---------|----------|---------------|
92
+ | Off-by-one | First/last element wrong | Check loop bounds, slice indices |
93
+ | Mutable default | State leaks between calls | Check function defaults |
94
+ | Race condition | Intermittent, timing-dependent | Add logging, check thread safety |
95
+ | Null reference | AttributeError/TypeError | Trace None propagation |
96
+ | Type mismatch | Unexpected type at runtime | Add type checks, check boundaries |
97
+ | Resource leak | Slow degradation, OOM | Check cleanup in finally/with |
98
+ | Encoding issue | Unicode errors, corrupt data | Check encode/decode boundaries |
99
+
100
+ ### Hypothesis Testing
101
+ ```python
102
+ # Hypothesis: "The bug is in validate_email()"
103
+ # Test: Call validate_email() directly with failing input
104
+
105
+ def test_hypothesis():
106
+ failing_email = "USER@EXAMPLE.COM"
107
+ result = validate_email(failing_email)
108
+ # If this fails → hypothesis confirmed
109
+ # If this passes → bug is elsewhere
110
+ ```
111
+
112
+ ### Fixing Root Cause
113
+ ```python
114
+ # BAD — symptom fix
115
+ def process(data):
116
+ if data is None: # Handles symptom
117
+ return default()
118
+ return real_process(data)
119
+
120
+ # GOOD — root cause fix
121
+ def get_data() -> Data:
122
+ # Fix upstream to never return None
123
+ data = fetch()
124
+ if data is None:
125
+ raise DataNotFoundError() # Explicit failure
126
+ return data
127
+
128
+ def process(data: Data) -> Result: # Type hint documents non-None
129
+ return real_process(data)
130
+ ```
131
+
132
+ ### Regression Test
133
+ ```python
134
+ # Always add test for the exact bug
135
+ def test_issue_123_uppercase_email_normalized():
136
+ """Regression: Issue #123 - uppercase email caused duplicate"""
137
+ user = create_user("USER@EXAMPLE.COM", "Test")
138
+ assert user.email == "user@example.com"
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Decision Rules
144
+
145
+ | Bug Type | First Step |
146
+ |----------|------------|
147
+ | Crash | Get traceback, reproduce |
148
+ | Wrong output | Create minimal input |
149
+ | Performance | Profile, find bottleneck |
150
+ | Intermittent | Add extensive logging |
151
+ | Security | Isolate, assess impact |
152
+
153
+ ---
154
+
155
+ ## Preferred Patterns
156
+
157
+ ```python
158
+ # Debug context manager
159
+ from contextlib import contextmanager
160
+
161
+ @contextmanager
162
+ def debug_context(name: str):
163
+ log.debug(f"{name}: start")
164
+ try:
165
+ yield
166
+ except Exception as e:
167
+ log.debug(f"{name}: error", error=str(e))
168
+ raise
169
+ else:
170
+ log.debug(f"{name}: success")
171
+
172
+ with debug_context("process_order"):
173
+ result = process_order(order)
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Avoid
179
+
180
+ - Fixing without reproducing
181
+ - Guessing instead of isolating
182
+ - Fixing symptoms, not root cause
183
+ - No regression test
184
+ - Large changes to fix small bug
185
+
186
+ ---
187
+
188
+ ## Validation Considerations
189
+
190
+ - Bug reproduced before fix
191
+ - Fix verified with reproduction case
192
+ - Regression test added
193
+ - Related tests still pass
194
+ - No similar bugs elsewhere (grep for pattern)
195
+
196
+ ---
197
+
198
+ ## Related Skills
199
+
200
+ - `debugging/common_bugs.md`
201
+ - `debugging/inspection_techniques.md`
202
+ - `testing/regression_tests.md`
203
+ - `generation/error_handling.md`