On Wed, Sep 2, 2020 at 4:23 AM Steven D'Aprano <st...@pearwood.info> wrote:

> On Wed, Sep 02, 2020 at 12:55:43PM +1200, Greg Ewing wrote:
> > On 2/09/20 3:44 am, Steven D'Aprano wrote:
> > >(9) Keyword-only subscripts are permitted:
> > >
> > >     obj[spam=1, eggs=2]
> > >     # calls type(obj).__getitem__(spam=1, eggs=2)
> > >
> > >     del obj[spam=1, eggs=2]
> > >     # calls type(obj).__delitem__(spam=1, eggs=2)
> >
> > An alternative is to pass an empty tuple as the index when there
> > are no positional args. That would make the following less of a
> > special case:
>
> I think that will interfere with people who need to choose their own
> default for the index.
>
> Unifying the behaviour of the getter and the setter only makes sense if
> you have both; for immutable objects (hence no setter) that need only
> keyword subscripts, why bother declaring an index you're never going to
> use when you actually want this signature?
>
>     __getitem__(self, *, keyword=default)
>
> Having to declare a positional index parameter I don't want, simply for
> consistency with a setitem I'm not even using, might be a tad annoying.
>

The whole backwards compatibility thing is more than a bit annoying, isn't
it?

So maybe accepting that you'll always get a key, and it may be `()`, isn't
the worst part.

OTOH, maybe we can cook up a scheme where we have two API families,
`__getitem__/__setitem__` and `__getindex__/__setindex__`. The signature of
`__setindex__` has the value first (after `self`).

The rules could be something like

- If keywords are present, always use `__getindex__/__setindex__` (fail if
they aren't present); if multiple positional indices are present, these
become multiple arguments.

- Otherwise, if only `__getindex__/__setindex__` are present, call those,
and lose the distinction between `d[1]` and `d[1,]`; `d[1, 2]` becomes two
positional arguments.

- Otherwise, if only `__getitem__/__setitem__` are present, call those in a
100% backwards compatible way.

- Otherwise, if both are present, call `__getitem__/__setitem__` if no
outer-level comma is present (so for `d[1]` as well as for `d[(1, 2)]`),
and call `__getindex__/__setindex__` if an outer-level comma is present (so
for `d[1,]` as well as for `d[1, 2]`).

This can be done relatively cleanly with changes at both the bytecode level
and the C API level.

I'm not sure I like this better than the "pure `__getitem__/__setitem__`
scheme, because the API duplication is troublesome,

-- 
--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-change-the-world/>
_______________________________________________
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/KJG7Q5Q74TDFV3GFQTREULJZERHTPGYR/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to