PLAIN PYTHON · ZERO RUNTIME DEPS

Missing keys, None, and defaults

Distinguish optional keys from nullable values and understand released default ownership.

Missing and None are different inputs

Optional(str) permits an absent key, which is omitted from the result. str | None accepts a present null value but still requires the key. Optional(str, 'Ada') inserts a default only when the key is absent.

Python · tested on 0.6.0Download .py
from zodify import Optional, validate

assert validate({"name": Optional(str)}, {}) == {}
assert validate({"name": str | None}, {"name": None}) == {"name": None}
assert validate({"name": Optional(str, "Ada")}, {}) == {"name": "Ada"}
# Released 0.6.0 defaults are inserted as supplied, without validation or copying.
default = []
result = validate({"items": Optional([str], default)}, {})
assert result["items"] is default
assert validate({"count": Optional(int, "unchecked")}, {})["count"] == "unchecked"
try:
    validate({"name": str | None}, {})
except ValueError:
    pass  # Nullable still requires the key.
else:
    raise AssertionError("Expected missing-key failure")
print("optional-defaults: passed")

Expected output: optional-defaults: passed

Defaults in the released version

In 0.6.0, a default is inserted as supplied. It is not independently validated or copied. Mutable defaults may be shared between calls. The executable example deliberately demonstrates an invalid default being inserted; this documents behavior, not a recommended configuration.

Prefer immutable, type-correct defaults and construct fresh mutable values in application code. A future default policy belongs to a separately released migration; do not assume unreleased source changes apply to an installed package.

Updated 2026-09-09 · Edit this page