On Sat, Sep 26, 2020 at 03:48:42PM -0700, Christopher Barker wrote:
> On Fri, Sep 25, 2020 at 11:50 PM Steven D'Aprano <[email protected]>
> wrote:
> >>
> >> 1. We have to pass a sentinel to the setitem dunder if there is no
> >> positional index passed.
>
>
> I still don't follow this logic -- why can't nothing be passed? The dunders
> either require an index or they don't, would that be just like function
> calling? So (adapting the example in the PEP:
>
> obj[spam=1, eggs=2]
> # calls type(obj).__getitem__(obj, spam=1, eggs=2)
>
> This sure seems like the obvious way to handle it.
Christopher, with the greatest respect, it is really demoralising for me
to explain this issue something like three, four, maybe five times now
(I'm not going to go back and count), including this thread which is
specifically about this issue, and then have people seemingly not even
read it before writing back to disagree :-(
The problem isn't with the `__getindex__` dunder. It's the
`__setindex__` dunder. I said it right there in the comment you quoted.
Okay, I was lazy and dropped the underscores, but still, **set**index is
right there. Then I spent a lot of time explaining why setindex is a
problem.
The problem is, how does the interpreter pass the second positional
argument without passing something as the first positional argument?
This isn't a problem for subscripting alone. It's a problem for any
function call:
def function(first=None, second=None, /):
print(first, second)
I've explicitly flagged the arguments as "positional only" to avoid
(non-)solutions that rely on the interpreter knowing the names of the
parameters at runtime. You can only pass arguments by position, they
have to be filled left-to-right, and the aim is to successfully pass a
value for `second` but no value for `first`.
You can't rely on the author of the function to do the argument
processing like this:
def function(*args):
if len(args) == 1:
second = args[0]
first = None # default
elif len(args) == 2:
first, second = args
else:
raise TypeError('wrong number of arguments')
That's why there are so few functions in the Python ecosystem with a
signature similar to range:
range( [start,] end [, step] )
and that's the problem that we solve here by auto-filling some sentinel
for the index when the subscript is keyword-only.
If the constraints are:
* the right hand side assignment value gets bound to the second
positional argument (not counting "self"), as expected;
* there are no changes to way the interpreter binds arguments to
parameters;
* there is no requirement that all `__setitem__` methods use the
same fixed parameter name for the value argument so that it can
be passed by a standard name (even "self" is just a convention);
* and no runtime introspection by the interpreter to find out what
the parameter name is (too slow);
then it is hard to see any other solution than to pass a special
sentinel to setitem to represent the missing index.
If you have any other solutions, or if you have a persuasive argument in
favour of relaxing one or more of those constraints, I'd love to hear
it.
--
Steve
_______________________________________________
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/EQRPHQL4HKGUPC7DFUIZU5SDCHDL2RBI/
Code of Conduct: http://python.org/psf/codeofconduct/