On 2020-07-18 10:04, Steven D'Aprano wrote:
On Sat, Jul 18, 2020 at 12:18:38AM -0400, Ricky Teachey wrote:
On Fri, Jul 17, 2020 at 7:21 PM Steven D'Aprano <st...@pearwood.info> wrote:

> On Fri, Jul 17, 2020 at 11:11:17AM -0400, Ricky Teachey wrote:
>
> ...
>
> For backwards-compatibility, there will only ever be a single positional
> argument passed into the method. That's because comma-separated values
> in a subscript are already passed as a tuple:
>
>     # this calls __getitem__ with a single tuple argument
>     obj[a,b:c,d]  ==> (1, slice(2, 3), 4)
>
> So that's not going to change (at least not without a long and painful
> deprecation process). But adding support for keyword arguments requires
> no changes to any existing class or a new builtin "key object" type.
>

This strikes me as problematic for having a consistent mental model of how
stuff works in python. I think that for many the difference in the meaning
of the syntax between item-getting/setting and function-calling would be...
glaring.

Yes, but what are we going to do about it?

Break a million existing scripts, applications and libraries that rely
on `__getitem__` only receiving a single tuple argument when passed
comma-separated values? I don't think the core devs will accept that, I
think the numpy devs will object strongly, and I'm pretty sure that the
Steering Council will say no.

But if you disagree, then feel free to start writing a PEP.

The fact that multiple comma-separated subscripts are passed to the
method as a single tuple argument is a historical fact we (almost
certainly) cannot change now. But that is orthogonal to how we choose to
proceed with keyword arguments. We aren't obliged to repeat the same
design.

We have a few choices:

(1) There is a minor inconsistency between subscripts and function
calls, so let's just forget all about the whole idea. If we cannot agree
on a decision, this is the default. (Status quo wins a stalement.)

(2) Let the Perfect be the enemy of the Good. No compromises! Insist on
breaking the entire Python ecosystem for the sake of fixing this minor
inconsistency between subscripting and function calls.

(3) Reinforce that inconsistency, and continue to obfuscate the
similarities, by handling keyword arguments in the same fashion as
comma-separated subscripts. This will require a new builtin "key-object"
class, and it will require every class that cares about keyword
arguments in their subscripts to parse them themselves.

We'll also need to decide how to combine subscripts and keywords:

     obj[a, b:c, x=1]
     # is this a tuple argument (a, slice(b, c), key(x=1))
     # or key argument key(a, slice(b, c), x=1)

(4) Or keep the subscript processing as-is, for backwards-compatibility,
but pass keyword arguments as normal for functions.

Both (3) and (4) would get the job done, but (3) requires everyone who
needs keyword arguments to parse the tuple and/or key object by hand to
extract them. Having done something similiar in the past (emulating
keyword-only arguments in Python 2), I can tell you this is painful.

With (4), the interpreter automatically matches up passed keyword
arguments to my `__getitem__` parameters, filling in defaults if needed,
and I can concentrate on using the arguments, not parsing them.

[snip]
I haven't followed this thread for a while, but, to me, it seems that the simplest option would be to pass the keyword arguments as a dict:

    obj[a, b:c, x=1] does obj.__getitem__((a, slice(b, c)), dict(x=1))

If there are no keyword arguments, then there's no dict.

This does mean that __getitem__ could be called with 1 or 2 arguments and __setitem__ could be called with 2 or 3 arguments, so it would be advisable to make the additional argument optional:

    def __getitem__(self, args, kwargs=None):

Additionally, __setitem__ would look a little odd:

    def __setitem__(self, args, value, kwargs=None):

It would raise a TypeError if there were keyword arguments, but __getitem__, etc, didn't accept any.
_______________________________________________
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/6C4GJS5RJQ3I3E76CRIA2QDG4BXMS4AD/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to