On Mon, May 25, 2020 at 02:19:57PM -0700, Christopher Barker wrote: > > It's an extremely common idiom right up until it doesn't > > work, and you need: > > > > _SENTINEL = object() > > def fun(..., option=_SENTINEL): > > if option is _SENTINEL: > > option = something_else > > > > I've thought to a while that there should be a more "standard" way to so > this: > > A NOT_SPECIFIED singleton in builtins would be pretty clear. > > (though I'd like to find a shorter spelling for that)
Guido's time machine strikes again! We already have that "not specified" singleton in the builtins, with a nice repr. It's spelled "None". The problem is that this is an infinite regression. No matter how many levels of "Not Specified" singletons you have, there's always going to be some context where they are all legitimate values so you need one more. Think about a function like `dir()` or `vars()`, which can operate on any object, or none at all: `dir()` is not the same as `dir(None)`, so we need a second sentinel MISSING to indicate the no argument case; but now we would like to say `dir(MISSING)`, so MISSING is likewise a legitimate value, and we need a third sentinel: since None is a legit value, we need MISSING; but MISSING is also a legit value, so we need UNDEFINED; but UNDEFINED is legit, so we need ... and so on through NOT_SPECIFIED, ABSENT, OMITTED and eventually we run out of synonyms. In the specific cases of `dir` and `vars`, it is easy enough to work around this with `*args`, but there can be functions with more complex signatures where you cannot do so conveniently. Fortunately, if you have a function that needs such a second level sentinel, you probably don't care that *other* functions like `dir` don't treat it as a special sentinel. It's only special to your library or application, not special everywhere, so the regression stops after one level. But that wouldn't be the case if it were a builtin. For the basic cases, using None is sufficient; if it's not, rolling your own is actually better than having a standard builtin, because: - it is specific to your library, you don't have to care about how other libraries might treat it (to them, it's just an arbitrary object, not a special sentinel); - you can choose whether or not to make it a public part of your library, and if so, what behaviour to give it; - and most importantly, you don't have to bike-shed the name and repr with the entire Python-Ideas mailing list *wink* -- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4TLBG5XJNRABFKXHJR4A2ARRSUVASXNF/ Code of Conduct: http://python.org/psf/codeofconduct/