Back to Talks
Sentinel Values in Python: Semantics, Double Dispatch, and the Limits of Typing

Sentinel Values in Python: Semantics, Double Dispatch, and the Limits of Typing

Florian Wilhelm

Date
Tuesday, April 14, 2026
Time
11:45 AM - 12:15 PM
Room
Merck Plenary (Spectrum) [1st Floor]
Talk PyCon: Programming & Software Engineering & Testing
Transcription

Sentinel values are a fundamental but under-documented part of Python’s design. They are used to represent absence, unsupported operations, incomplete state, and to coordinate control flow between objects. Yet, they are often treated as ad-hoc implementation details.

This talk starts by clarifying what sentinel values are and why None is frequently semantically overloaded and incorrect for modelling “missing” or “unset” values. We then examine built-in sentinels such as NotImplemented, Ellipsis, and dataclasses.MISSING, with a detailed look at how NotImplemented enables double dispatch in equality and ordering operations.

The second half of the talk focuses on typing, where sentinel values expose fundamental tensions between Python’s dynamic semantics and static type systems. We will discuss:

  • why Optional[T] does not mean “unset”
  • why Literal appears attractive for sentinels but rarely works in practice
  • what limited type narrowing is possible today and under which assumptions
  • why a fully reliable, user-defined sentinel with correct narrowing is currently not achievable in a portable way

To ground this in practice, we will look at real-world patterns used in production code, including Pydantic’s experimental missing concept, and explain the trade-offs these designs make.

Finally, we will examine PEP 661, the proposal to standardize sentinel values and their typing semantics. We will explain what it would solve, why it was deferred, and what that deferral means for library and API authors today.

The talk concludes with concrete, honest guidelines: when sentinel values are the right tool, how to design APIs around them, and how to communicate absence clearly in typed Python code without pretending the type system can do more than it currently can.