pythonista-debugging
Debugging and Root Cause Fixing
Core Philosophy
Find and fix the root cause. NEVER work around problems with wrappers or complexity.
Debugging Workflow
1. Read the Stack Trace
# Stack traces read bottom-to-top. The last frame is where error occurred.
Traceback (most recent call last):
File "main.py", line 10, in <module> # Entry point
result = process_data(data) # Calling function
File "processor.py", line 25, in process_data
return transform(item) # Where it failed
TypeError: 'NoneType' has no attribute 'items' # What went wrong
Key info: File, line number, function name, actual error message.
2. Reproduce the Bug
# Create minimal reproduction
pytest tests/test_module.py::test_specific -v
# Or write a quick script
python -c "from module import func; func(problematic_input)"
3. Use Debugger or Print Statements
# Quick debugging with print (remove after!)
print(f"DEBUG: {variable=}, {type(variable)=}")
# Better: Use debugger
import pdb; pdb.set_trace() # Interactive debugger
# Or breakpoint() in Python 3.7+
breakpoint()
4. Bisect if Needed
# Find which commit introduced the bug
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
# Git will guide you through testing commits
The Anti-Pattern: Working Around Instead of Fixing
When you encounter an error, your instinct may be to:
- Add a wrapper class
- Use
__getattr__for dynamic delegation - Use
# type: ignoreto suppress errors - Create helper classes that "adapt" interfaces
This is WRONG. These are signs you're working around instead of fixing.
Common Workarounds to Avoid
Wrapper Classes with __getattr__
# WRONG - Magic delegation
class TestWrapper:
def __init__(self, obj):
self.obj = obj
def __getattr__(self, name):
return getattr(self.obj, name)
# CORRECT - Simple helper function
def test_helper(obj):
pass
Adapter Classes
# WRONG - Adapter to hide interface mismatch
class TestAdapter:
def __init__(self, production_obj):
self.obj = production_obj
def adapted_method(self):
return self.obj.method().to_dict()
# CORRECT - Transform inline, fix the interface
def test_something(production_obj):
result = production_obj.method()
assert result.to_dict()["field"] == expected
Type Ignores to Hide Problems
# WRONG - Hiding the problem
result = maybe_none.items() # type: ignore
# CORRECT - Handle the None case
if maybe_none is not None:
result = maybe_none.items()
Red Flags
You're working around instead of fixing if you're:
- Creating a wrapper class "just for tests"
- Using
__getattr__or other magic methods - Adding complexity to avoid changing existing code
- Thinking "I'll just adapt this interface..."
- Using
# type: ignorewithout investigating why
The Right Approach
- Stop when you realize you're working around
- Identify the root cause (read stack trace, reproduce)
- Fix the root cause with simple, explicit code
- Delete any workarounds you created
Questions to Ask
- Am I adding complexity to avoid fixing the real problem?
- Is there a simpler, more direct way to do this?
- Would someone reading this code understand what's happening?
- Can I reproduce this bug with a minimal test case?
Related Skills
- /pythonista-testing - TDD for bug fixes
- /pythonista-typing - Type safety
- /pythonista-patterning - Pattern discovery
More from gigaverse-app/skillet
metaskill-authoring
Write Claude Code skills and SKILL.md files. Use when creating new skills, writing skill content, structuring SKILL.md, organizing skill directories, or when user mentions "write skill", "create skill", "author skill", "new skill", "skill structure", "SKILL.md", "skill content", "skill template".
9metaskill-triggering
Optimize skill triggers and descriptions for reliable activation. Use when skill is not triggering, optimizing trigger keywords, writing frontmatter, debugging activation, or when user mentions "trigger", "frontmatter", "description", "skill not triggering", "optimize trigger", "skill won't fire", "skill activation", "trigger keywords".
8metaskill-packaging
Package skills, agents, commands, and hooks as Claude Code plugins. Use when creating plugins, packaging skills for distribution, setting up plugin structure, dogfooding plugins, or when user mentions "plugin structure", "plugin.json", "package plugin", "distribute plugin", "marketplace", "dogfood", "install plugin", "plugin placement", "--plugin-dir".
8metaskill-naming
Brainstorm and validate names for plugins, skills, agents, and commands. Use when naming a new plugin, choosing atom names, validating naming conventions, or when user mentions "name plugin", "name skill", "naming convention", "brainstorm names", "what should I call", "plugin name", "good name for".
7metaskill-grouping
Create skill groups (multiple related skills packaged as a plugin). Use when creating plugins, organizing multiple related skills, building skill families, packaging tools together, or when user mentions "plugin", "multiple skills", "related skills", "skill group", "skill family", "organize skills", "cross-reference", "package skills", "shared agents". ALWAYS consider this pattern when someone asks to "create a skill" - they often need a skill GROUP packaged as a plugin.
7nicegui-development
Use when building UI with NiceGUI, creating components, fixing styling issues, or when user mentions "nicegui", "quasar", "tailwind", "ui.row", "ui.column", "gap spacing", "state management", "controller", "dialog", "modal", "ui component", "ui layout".
6