Talks

Beyond Optional in Real-World Projects: Missing, None, and Unset

Saturday, May 16th, 2026 11:15 a.m.–11:45 a.m. in Room 104AB

Presented by

Koudai Aono

Description

Have you ever merged a config file, applied an input that says "update only these fields", or handled an API payload, only to overwrite data because "missing", None, and "unset" were treated as the same thing?

In real-world projects, "no value" has at least three meanings:

  • a missing key (the field is absent),
  • an explicit None (the value is present and intentionally null),
  • an unset input (the caller didn't specify the field, so you must not touch it).

When we collapse these into T | None (a nullable type) or fall back to dict[str, Any], type checking becomes noisy, branching becomes fragile, and refactors get risky. Every field nullable, every check defensive, every change scary.

This is a practical talk about using typing to model and safely consume real-world data with TypedDict and dataclasses, not a typing tutorial or a framework pitch. We'll walk through one end-to-end example (payload -> normalization -> domain model -> safe updates) with before/after code and focus on patterns you can apply immediately:

  • Use Required / NotRequired to model missing keys instead of abusing T | None.
  • Use T | None only when None is a meaningful value.
  • Represent unset inputs with a sentinel pattern (starting from UNSET = object() and optionally evolving to typing_extensions.Sentinel) so partial updates don't silently overwrite data and the type checker can distinguish unset from None.
  • Keep extraction code honest with type aliases, TypeIs, and (optionally) small match cases for readability.

After this session, you'll be able to define stricter data models, write safer extraction code, and make schema changes less painful, because your types will reflect what your data actually means. This talk is for intermediate Python developers who already use type hints in production.

Search