If we drop the requirement for pickle round-tripping then I would add a requirement that sentinel is unpicklable, to prevent accidents.
Irit On Fri, May 14, 2021 at 8:38 PM Tal Einat <talei...@gmail.com> wrote: > > I'll try to organize my thoughts a bit here. This is a bit long, > welcome to skip to the final sentence for the "tl;dr". > > Features one may want for a sentinel: > 1. Unique from other objects > 2. Globally unique, i.e. unique from other such sentinels (no consensus > here) > 3. Clear repr (the original subject of this thread) - significant > since these often appear in function signatures > 4. Survives pickling round-trip (I brought this up since I was bitten > by this once, but others have mentioned that this is usually > irrelevant) > 5. Can be given a clear type signature (this was brought up on > twitter[1]) - significant since without this nobody can add full type > signatures even if they want to > > The common `SENTINEL = object()` idiom fails #3, #4 and #5. This is > what I've been using for years, and I now think that it isn't good > enough. This not having a nice repr is what started this thread. > > I'd also personally prefer something simple, ideally without a new > class or module. > > There are several simple idioms using existing features that seem like > good options, so let's review those: > > 1. Ellipsis, a.k.a. `...`. This has all of the features outlined above > except #2. My main issue with using Ellipsis for this is that it could > be surprising and confusing for devs first encountering such use, and > could be relatively awkward to figure out. > > 2. An instance of a one-off class. dataclasses.MISSING is an example > of this. It is defined thus: > > class _MISSING: > pass > MISSING = _MISSING() > > Besides failing #4 (surviving pickle round-trips), its repr isn't > great: <dataclasses._MISSING object at 0x7fe14b1e2e80>. That is easily > overcome by implementing __repr__. > > 3. A one-off class: > > class MISSING: pass > > This has all of the above features except #5: having a clear type > signature (since its type is type). Using a class as a value this way > could be surprising, though. It's repr also isn't great: <class > 'dataclasses._MISSING'>. > > 4. A value of an single-valued enum, for example (from [1]): > > class _UNSET(enum.Enum): > token = enum.auto() > > This has all of the features above and is simple, just requiring a > comment to explain what it is. It's repr is a bit awkward though: > > >>> repr(_UNSET.token) > '<_UNSET.token: 1>' > > > All of these are in use by some developers, though not necessarily in > the stdlib. None is perfect, though all are probably good enough. > Since pickling is likely not relevant in most cases, I'm currently in > favor of #2 making sure to implement a nice __repr__. > > - Tal > > [1] https://twitter.com/nolar/status/1392962447166877697 > _______________________________________________ > Python-Dev mailing list -- python-dev@python.org > To unsubscribe send an email to python-dev-le...@python.org > https://mail.python.org/mailman3/lists/python-dev.python.org/ > Message archived at > https://mail.python.org/archives/list/python-dev@python.org/message/BYLTDD72RZUUKVRJL6TTSWF35JD3FL47/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/7I7S22KEOZY2MDDIYCUPQWG6WXLFZZR5/ Code of Conduct: http://python.org/psf/codeofconduct/