Function worked 10 times. Failed on the 11th. The bug was in my function signature.
I had a Python function processing user submissions. Worked perfectly for the first 10 calls during testing. Called it the 11th time and suddenly got duplicate data where there shouldn't be any. No error message. Just wrong output.
Simple data processor
Takes a list of items, filters them, returns results:
def process_items(items, results=[]):
for item in items:
if item['status'] == 'active':
results.append(item)
return results
# Usage
batch1 = process_items([{'id': 1, 'status': 'active'}])
batch2 = process_items([{'id': 2, 'status': 'active'}])
print(batch2) # Expected: [{'id': 2, ...}]
# Got: [{'id': 1, ...}, {'id': 2, ...}]
Batch 2 contained items from batch 1. Made zero sense.
Spent an hour checking:
- Database query (fine)
- API request/response (fine)
- Variable names (not reusing anything)
- Cache somewhere (no cache configured)
Added print statements everywhere. Previous results were somehow bleeding into new calls.
That results=[] in the function signature.
Python evaluates default arguments ONCE when the function is defined, not each time it's called. So that empty list gets created once and reused across all function calls.
First call appends to it. Second call appends to the SAME list. Third call adds more to the SAME list. By the 11th call, it's carrying everything from the previous 10.
def process_items(items, results=None):
if results is None:
results = []
for item in items:
if item['status'] == 'active':
results.append(item)
return results
Now each call creates a fresh list.
Mutable defaults (lists, dicts) in Python function signatures are a trap. Use None and create the object inside the function. Classic gotcha. Worked fine during initial testing because I was only calling it once per test. Production environment called it repeatedly and the bug showed up.
Still mad it took me an hour to find a one line fix honestly.
Top comments (0)