Root Cause Fixing - No Workarounds
Core Philosophy
NEVER use overengineering tricks to work around problems. Always fix the root cause with proper, simple code.
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 - Return tuples and unpack them
- Use
# type: ignoreto suppress errors - Create helper classes that "adapt" interfaces
This is WRONG. These are all signs you're working around a problem instead of fixing it.
Common Workarounds to Avoid
1. Wrapper Classes with __getattr__
# WRONG
class TestWrapper:
def __init__(self, obj):
self.obj = obj
def test_helper(self):
pass
def __getattr__(self, name):
return getattr(self.obj, name)
# CORRECT - Just use helper functions
def test_helper(obj):
pass
2. Tuple Unpacking from Fixtures
# WRONG
@pytest.fixture
def my_fixture():
obj1 = create_obj1()
obj2 = create_obj2()
return obj1, obj2 # What does this return?
def test_something(my_fixture):
obj1, obj2 = my_fixture # Unclear
# CORRECT - Separate fixtures
@pytest.fixture
def obj1():
return create_obj1()
@pytest.fixture
def obj2():
return create_obj2()
def test_something(obj1, obj2):
# Clear what we're using
3. Dynamic Attribute Assignment
# WRONG
@pytest.fixture
def enhanced_object():
obj = ProductionClass()
obj.helper = lambda: None # Dynamic attribute - breaks type checking
return obj
# CORRECT
@pytest.fixture
def production_object():
return ProductionClass()
def helper_method(obj):
pass
def test_something(production_object):
helper_method(production_object)
4. Adapter/Wrapper Classes
# WRONG
class TestAdapter:
"""Adapts production class for testing."""
def __init__(self, production_obj):
self.obj = production_obj
def adapted_method(self):
return self.obj.method().to_dict()
# CORRECT - Transform inline
def test_something(production_obj):
result = production_obj.method()
data = result.to_dict()
assert data["field"] == expected
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..."
- Creating an "adapter" or "wrapper" class
- Returning tuples from fixtures
- Using
# type: ignoreto suppress errors instead of fixing types
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?
- Am I using overengineering tricks instead of straightforward code?
The Right Approach
- Stop when you realize you're working around
- Identify the root cause of the problem
- Fix the root cause with simple, explicit code
- Delete any workarounds you created
Real Example
Wrong - Working Around
class VideoModerationSinkWrapper:
def __init__(self, sink, fake_consumer):
self.sink = sink
self.fake_consumer = fake_consumer
async def consume_all(self):
while True:
message = await self.fake_consumer.getone()
if message is None:
break
await self.sink.on_process_message(message)
def __getattr__(self, name):
return getattr(self.sink, name) # Magic delegation
Correct - Fix the Root Cause
@pytest_asyncio.fixture
async def kafka_consumer(kafka_setup):
"""Separate fixture for consumer."""
consumer = FakeAIOKafkaConsumer()
await consumer.start()
yield consumer
await consumer.stop()
@pytest_asyncio.fixture
async def video_moderation_sink(real_mongodb_client):
"""Separate fixture for sink."""
sink = VideoModerationDBSink(db_client=real_mongodb_client)
await sink.pre_run()
yield sink
async def consume_all_messages(sink, consumer):
"""Simple helper function - no wrapper needed."""
while True:
message = await consumer.getone()
if message is None:
break
await sink.on_process_message(message)
# Tests request what they need explicitly
async def test_something(kafka_consumer, video_moderation_sink):
await consume_all_messages(video_moderation_sink, kafka_consumer)
General Principle
Simple, explicit code is ALWAYS better than overengineered workarounds that hide issues.
When faced with a problem:
- Fix the root cause
- Use simple, straightforward solutions
- Write code that's easy to understand
- Don't work around with wrappers
- Don't use magic methods
- Don't create adapters
If you find yourself thinking "I'll just wrap this..." - STOP. Fix the real problem instead.
Related Skills
- For pattern discovery, see
/pythonista-patterning - For testing patterns, see
/pythonista-testing - For type safety, see
/pythonista-typing
