I am going to put everything in the new PEP tonight.
On Sun, 30 Aug 2020, 08:47 Guido van Rossum,
On Sat, Aug 29, 2020 at 10:29 PM Guido van Rossum
wrote: FYI, Jonathan's post (once I "got" it) led me to a new way of reasoning about the various proposals (__keyfn__, __subscript__ and what I will keep calling "Steven's proposal") based on what the compiler and interpreter need to do to support this corner case. My tentative conclusion is that Steven's proposal is superior. But I have been reviewing my reasoning and pseudo-code a few times and I'm still not happy with it, so posting it will have to wait.
I've spent some more thinking about this, focused on two things: absolute backwards compatibility for d[1] vs. d[1,], and what should happen at the C level. There are both the type slots and API functions like PyObject_{Get,Set}Item to consider.
Interestingly, it seems Jonathan's proposal and __subscript__ seem inspired by the desire to keep both type slots and PyObject{Get,Set}Item unchanged, but have the disadvantage that it's hard to keep d[1] vs. d[1,] straight, and add a lot of complexity to the bytecode interpreter.
At this point my recommendation is to go with Steven's proposal, constructing a "key" from the positional args, taking d[1] vs. d[1,] into account for backwards compatibility, and passing keywords as a dict to new C API functions PyObject_GetItemEx and PyObject_SetItemEx. These functions then call the mp_subscript and mp_ass_subscript slots. There will have to be a flag in the type object to declare whether the slot functions take a dict of keywords. This flag is off by default (for backwards compatibility) but on for type objects wrapping Python classes -- the dict of keywords will then be passed as **kwargs to __getitem__ or __setitem__ (the call will fail if the Python __getitem__ or __setitem__ doesn't take the specific keywords in the dict).
If the flag in the type slot says "doesn't take dict of keywords" then passing a non-empty dict causes a type error. Ditto if there are keywords but the type slots are in tp_as_sequence rather than in tp_as_mapping. (The sequence slots only take a single int and seem to be mostly a legacy for sequences -- even slices go through tp_as_mapping.)
There is one final case -- PyObject_GetItem on a type object may call __class_getitem__. This is used for PEP 585 (list[int] etc.). In this case we should pass keywords along. This should be relatively straightforward (it's not a slot).
A quick summary of the proposal at the pure Python level:
``` d[1] -> d.__getitem__(1) d[1,] -> d.__getitem__((1,)) d[1, 2] -> d.__getitem__((1, 2)) d[a=3] -> d.__getitem__((), a=3) d[1, a=3] -> d.__getitem__((1,), a=3) d[1, 2, a=3] -> d.__getitem__((1, 2), a=3)
d[1] = val -> d.__setitem__(1, val) d[1,] = val -> d.__setitem__((1,), val) d[1, 2] = val -> d.__setitem__((1, 2), val) d[a=3] = val -> d.__setitem__((), val, a=3) d[1, a=3] = val -> d.__setitem__((1,), val, a=3) d[1, 2, a=3] = val -> d.__setitem__((1, 2), val, a=3) ```
Do we want to support d[**kwargs]? It can be done, alternatively we could just ask the user to write the __getitem__/__setitem__ call explicitly.
I think we should say no to d[*args], because that will just become d[(*args)], with awkward questions around what if args == (1,). Maybe then for consistency we needn't bother with **kwargs, though the case for that is definitely stronger.
Sorry for telegraphing this -- I am way past my bedtime but looking at this from the C API POV definitely made some things clear to me. I'm probably posting this in the wrong thread -- I can't keep up (and GMail splits threads after 100 messages, which doesn't help).
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c... _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@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/ZQWSIJ... Code of Conduct: http://python.org/psf/codeofconduct/