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.

Python · tested on 0.6.0Download .py
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.

Updated 2026-09-09 · Edit this page