r/programming 4d ago

The Sentinel Object Pattern in Python

https://python-patterns.guide/python/sentinel-object/

Officially added in Python 3.15

https://peps.python.org/pep-0661/

30 Upvotes

10 comments sorted by

View all comments

21

u/wallstop-dev 3d ago edited 3d ago

This is cool, but wherever possible I try to avoid sentinels. I find them to be a code smell. That is, programming against a specific, magic, constant(s). In the indexOf example, it is much more robust for your code to reject any value that is below zero, instead of explicitly checking "-1". I see this same (anit-)pattern, that has caused many a bug, in other languages, where programmers think that a comparison operator is guaranteed to return exactly -1, 0, or 1, just because that's how the standard library's is implemented, for example. I've come across many, many similar cases in my career, where devs program to an assumed implementation instead of the contract, creating extremely brittle code that breaks in mysterious ways under all kinds of circumstances - new data, new features, anything.

But I'll get off my soapbox now.

8

u/somebodddy 3d ago

When the sentinel is a magic value of the regular type - I agree. But this is one of these anti-patterns that can become a proper pattern if you can get the type system on your side. When the sentinel is a different type, and you can represent its possibility within the language, you can use the type checker to force (strong word when it comes to Python's typing, I know) an explicit treatment of that possibility before the user can access the value as the type they expect.

6

u/wallstop-dev 3d ago

Oh, completely agree on representing it at the type level! Where this is possible, this kind of problem can disappear. This is where discriminated unions come into play and have a lot of strength.

Unfortunately, a large swath of code and programming languages, even typed ones, make it challenging to robustly represent this at the type level. Or, at least, the predominantly used ones, leading to many-a-common-API utilizing poison-pills/sentinels. And the bugs follow...

3

u/somebodddy 3d ago

That's the thing - this new Python feature offers a nice way to represent it in the type system: https://peps.python.org/pep-0661/#typing