Reject NaN in a local JSON fixture
Also published in our primary archive.
Reject NaN in a local JSON fixture
To reject NaN while decoding JSON in Python, provide parse_constant to json.loads and raise from that callback. Python calls it for the non-standard tokens NaN, Infinity, and -Infinity, so one small function can make those tokens invalid for this decode.
The in-memory fixture is the exact text NaN. Default json.loads accepts it and returns a floating-point NaN, although that token is outside the JSON specification. Because NaN is unequal to itself, value != value is a compact assertion for this particular decoded value. The first line makes the contrasting default behavior visible without depending on a platform-specific representation of NaN.
reject_non_finite raises ValueError('non-finite number') whenever the parser invokes it. The try block demonstrates the correction: the same source does not produce a usable value under this narrow policy. It does not impose a document-size limit, restrict ordinary finite numbers, or validate a surrounding object schema. If the fixture could contain Infinity or -Infinity, the same callback rejects those tokens too.
The json documentation describes both the decoder's default handling of non-finite values and parse_constant as the customization point for rejecting them. No newer API is required here: parse_constant predates the Python 3.1 addition of object_pairs_hook; current supported Python versions provide it.
AI assistance disclosure: This article was drafted with AI assistance and verified with the synthetic fixture shown.
Example
import json
source = "NaN"
def reject_non_finite(token):
raise ValueError("non-finite number")
default_value = json.loads(source)
assert default_value != default_value
print("default is nan:", default_value != default_value)
try:
json.loads(source, parse_constant=reject_non_finite)
except ValueError as error:
print("validated:", error)
Expected output:
default is nan: True
validated: non-finite number