Return a sentinel instead of catching every Exception
Return a sentinel instead of catching every Exception
Direct answer: create one unique sentinel, pass it as the default to dict.get(), and compare the result with is. Do not catch Exception merely to turn a missing dictionary key into a fallback value.
The broken helper uses subscription and catches every exception. For the intended missing lookup, "blue" in { "red": 1 }, it returns the sentinel. But the same handler also hides a programmer error: a list is unhashable and dictionary lookup raises TypeError, yet the helper converts it into the same “missing” result. A caller can no longer distinguish absence from invalid input.
The repaired helper calls mapping.get(key, MISSING). It returns the sentinel only for an absent key. A stored None remains None, which is why the fixture adds "green": None; identity checks show that neither stored value is confused with absence. The invalid list key still raises TypeError, and the fixture reports that exception explicitly. The assertions establish these outcomes for an ordinary built-in dictionary, not validation rules for all mapping-like objects.
dict.get returns its supplied default when a key is absent, while object provides a suitable unique-instance sentinel pattern. These APIs are available in all supported Python 3 versions.
AI-assistance disclosure: Batu Lab Notes used AI assistance to draft this synthetic example and explanation.
Example
MISSING = object()
def broken_lookup(mapping, key):
try:
return mapping[key]
except Exception:
return MISSING
def lookup(mapping, key):
return mapping.get(key, MISSING)
values = {"red": 1, "green": None}
assert broken_lookup(values, "blue") is MISSING
assert broken_lookup(values, []) is MISSING
blue = lookup(values, "blue")
green = lookup(values, "green")
assert blue is MISSING
assert green is None
try:
lookup(values, [])
except TypeError as error:
invalid_key_result = type(error).__name__
else:
raise AssertionError("an unhashable key must not become missing")
print(f"blue missing: {blue is MISSING}")
print(f"green is None: {green is None}")
print(f"invalid key: {invalid_key_result}")
Expected output:
blue missing: True
green is None: True
invalid key: TypeError