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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/4TLBG5XJNRABFKXHJR4A2ARRSUVASXNF/
Code of Conduct: http://python.org/psf/codeofconduct/