Zero is a value, not a missing field
An accepts a notification limit. Zero means “send none”. A missing field means “use the default”. The shortcut value or 10 treats both alike and silently replaces zero with ten.
Run one small example
Save as limit.py and run python3 limit.py with 3.11 or newer. No packages or server are needed.
def limit(data: dict) -> int:
if "limit" not in data:
return 10
value = data["limit"]
if type(value) is not int or not 0 <= value <= 100:
raise ValueError("limit must be an integer from 0 to 100")
return value
print(limit({}))
print(limit({"limit": 0}))
try:
limit({"limit": None})
except ValueError:
print("invalid")Expected output:
10
0
invalidThe key check decides whether the caller supplied the field. The type/range check decides whether its value satisfies the . Here explicit None is invalid; that is a deliberate API rule, not a universal rule for every application.
bool is a subclass of int in Python. The exact type check deliberately rejects True; a boolean is not a meaningful notification count in this contract. The annotation alone does not validate input.
Try the tempting shortcut
Replace the body with return data.get("limit") or 10. Run the same cases. Both zero and explicit None become ten. An response could still be successful while the business rule is wrong.
the original function. Add checks for 100, 101, True and the string "2". Before running, classify each input as accepted or rejected. Do not convert text unless the API contract explicitly allows it.
Transfer the rule
A request updates a profile: a missing nickname means “leave unchanged”, while null means “clear it”. This is a different contract. Write down those outcomes before choosing get, a default or a . Never assume captures the business meaning of absence.
Sources
CHECK YOUR INTUITION

