PLAIN PYTHON · ZERO RUNTIME DEPS
Why a Python int check is not JSON Schema integer
An executable explanation of exact Python types and JSON numeric semantics.
The same-looking number can have a different contract
In zodify 0.6.0, int means exact Python int. After standard-library JSON parsing, 1 becomes int and 1.0 becomes float. Python bool is also rejected by the int schema. The following example tests all four cases and the opt-in conversion alternative.
import json
from zodify import validate
accepted = []
for token in ["1", "1.0", "true", '"1"']:
value = json.loads(token)
try:
validate({"count": int}, {"count": value})
except ValueError:
accepted.append(False)
else:
accepted.append(True)
assert accepted == [True, False, False, False]
assert validate({"port": int}, {"port": "8080"}, coerce=True) == {"port": 8080}
assert validate({"value": int | str}, {"value": "1"}, coerce=True)["value"] == 1
assert validate({"value": str | int}, {"value": "1"}, coerce=True)["value"] == "1"
print("exact-types: passed")
Expected output: exact-types: passed
JSON Schema answers a different question
JSON Schema considers a number with zero fractional part an integer, including 1.0. Python runtime type identity and mathematical integrality are distinct contracts. Translating int directly to a JSON Schema integer constraint does not preserve every acceptance decision.
This is a semantic limitation, not a performance result. A future exporter must state its supported subset and this mismatch; it must not imply complete equivalence. Use a JSON Schema validator when that standard is the authority for your payload.