In 3.15, this is the way to define a sentinel within a class (example from the documentation):
class Cls:
PICKLABLE = sentinel("Cls.PICKLABLE")
I am personally averse to the common antipattern in Python of:
value = some_function('value', ...)
…where “value” must appear both as the assignment left-hand side and as an argument string. It feels repetitious and, while not especially error-prone, when there is an error it’s hard to diagnose. In this specific case things are complicated by needing to (remember to) give the constructor the qualified name.
What if sentinel were enhanced to provide this alternative?
class Cls:
PICKLABLE = sentinel()
The intended behaviour would be that the sentinel is initially constructed with __name__ is None, but sentinel implements __set_name__ (and a dummy __get__) so Cls later fills in the name via the descriptor protocol.
This feels considerably tidier to me, and would be backward-compatible because the name parameter to sentinel() is currently mandatory.
However, my understanding is that the posted idea is for class members only, correct? Obviously a __set_name__ mechanism wouldn’t work outside classes.
That means the first example in the documentation
MISSING = sentinel("MISSING")
remains requiring the name, leading to a split between class members vs. regular (local or global) values.
The latter split is also undesirable, so it’s choosing between two suboptimal situations.
For regular values that would require inspecting the stack etc., which I believe is being frowned upon (a.o. because not universally possible across other Python implementation than CPython).
If both could omit the name, that would be great. I hope someone smarter than me sees a practical approach to that end.
That’d be a bit of a pain, since modules frequently contain functions, and functions are descriptors. But maybe it’d be nice to have a standard idiom for making a class that becomes the module’s type.