Debugging casebook — Python and JavaScript pitfalls — DedSec Project
Debugging casebook — Python and JavaScript pitfalls Python: mutable default argument Broken example — DO NOT USE Fixed example Why it fails and the repair works A default list is created…
Python: mutable default argument
Broken example — DO NOT USE
def add(item, items=[]):
items.append(item)
return items
Fixed example
def add(item, items=None):
if items is None:
items = []
items.append(item)
return items
Why it fails and the repair works
A default list is created once and shared across calls.
Check the surrounding imports, function signature and environment: fragments may require integration before execution.
Root cause and precise failure
A list used as a default is allocated when the function is defined, so separate no-argument calls share the same list. The fixed function allocates fresh storage unless a caller explicitly passes a collection.
Repeatable regression exercise
Call the broken function with 'Ada' and then 'Grace'. Show that the second result unexpectedly includes both. Call the fixed function twice and require independent outputs, then supply a shared list explicitly to demonstrate intentional sharing.
Acceptance rule: preserve the original failure as a test, verify the corrected version on both the ordinary case and the boundary case, and avoid modifying real user data.
Python: missing file encoding
Broken example — DO NOT USE
text = open("notes.txt").read()
Fixed example
from pathlib import Path
text = Path("notes.txt").read_text(encoding="utf-8")
Why it fails and the repair works
Use explicit UTF-8 to handle Greek filenames/content consistently.
Root cause and precise failure
Text files contain bytes, not an intrinsic Python string encoding. Choosing a mismatched codec corrupts or rejects characters; suppressing Unicode errors with ignore irreversibly drops information.
Repeatable regression exercise
Write 'Καλημέρα' to a disposable UTF-8 file, reopen with encoding='utf-8' and compare bytes with code-point counts. Deliberately decode an invalid byte fixture and inspect UnicodeDecodeError without changing the original file.
Python: swallowed exceptions
Broken example — DO NOT USE
try:
work()
except Exception:
pass
Fixed example
try:
work()
except ValueError as exc:
print(f"Invalid value: {exc}")
Why it fails and the repair works
Catch only anticipated errors and report them.
Root cause and precise failure
A blanket except that returns an empty result can make a failed operation look successful. Error recovery belongs at a layer that knows whether retry, user explanation or abort is appropriate.
Repeatable regression exercise
Trigger ValueError in a parser and FileNotFoundError at the file-reading boundary. Confirm only expected errors are translated into user-facing messages; an unexpected programming error must remain visible in tests.
JavaScript: equality confusion
Broken example — DO NOT USE
if (count = 3) console.log("three");
Fixed example
if (count === 3) console.log("three");
Why it fails and the repair works
Assignment is not comparison; prefer strict equality.
Root cause and precise failure
Loose equality performs type conversion: the string '0' can compare equal to the numeric zero. Strict equality preserves the distinction, but runtime input conversion still needs its own validation.
Repeatable regression exercise
Compare the pairs ('0',0), (false,0) and (null,undefined) with == and ===. Refactor the application to convert the intended input type before comparison instead of depending on coercion.