On Fri, Aug 07, 2020 at 12:09:28PM -0400, Ricky Teachey wrote:

> I was actually trying to help the kwd arg case here. As illustrated by the
> quote I included from Greg Ewing, there seems to be not even close to a
> consensus over what the semantic meaning of this should be:
> 
> m[1, 2, a=3, b=2]

This is Python-Ideas. If we asked for a consensus on what the print 
function should do, I'm sure we would find at least one person 
seriously insist that it ought to erase your hard drive *wink*

But seriously, getting consensus is difficult, especially when people 
seem to be unwilling or unable to articulate why they prefer one 
behaviour over another, or the advantages vs disadvantages of a 
proposal.


> Which could be made to mean one of the following things, or another thing I
> haven't considered:
> 
> 1.    m.__get__((1, 2), a=3, b=4)  # handling of positional arguments
> unchanged from current behavior


By the way, I assume you meant `__getitem__` in each of your examples, 
since `__get__` is part of the descriptor protocol.


Advantages: 

(1) Existing positional only subscripting does not change (backwards 
compatible).

(2) Easy to handle keyword arguments.

(3) Those who want to bundle all their keywords into a single object can 
just define a single `**kw` parameter.

(4) Probably requires little special handling in the interpreter?

(5) Probably requires the minimum amount of implementation effort?

(6) Requires no extra effort for developers who don't need or want 
keyword parameters in their subscript methods. Just do nothing.

Disadvantages: none that I can see. (Assuming we agree that this is a 
useful feature.)


> 2.    m.__get__(1, 2, a=3, b=4)  # change positional argument handling from
> current behavior

Advantages:

1. Consistency with other methods and functions.

Disadvantages:

1. Breaks backwards compatibility.

2. Will require a long and painful transition period during which time 
libraries will have to somehow support both calling conventions.


> 3.    m.__get__((1, 2), {'a': 3, 'b': 4})  #  handling of positional
> arguments unchanged from current behavior

I assume that if there are no keyword arguments given, only the 
first argument is passed to the method (as opposed to passing an 
empty dict). If not, the advantages listed below disappear.

Advantages:

(1) Existing positional only subscripting does not change (backwards 
compatible).

(2) Requires no extra effort for developers who don't need or want 
keyword parameters in their subscript methods. Just do nothing.

Disadvantages:

(1) Forces people to do their own parsing of keyword arguments to local 
variables inside the method, instead of allowing the interpreter to do 
it.

(2) Compounds the "Special case breaks the rules" of subscript methods 
to keyword arguments as well as positional arguments.

(3) It's not really clear to me that anyone actually wants this, apart 
from just suggesting it as an option. What's the concrete use-case for 
this?


> 4.    m.__get__(KeyObject( (1, 2), {'a': 3, 'b': 4} ))   # change
> positional argument handling from current behavior only in the case that
> kwd args are provided

Use-case: you want to wrap an arbitrary number of positional arguments, 
plus an arbitrary set of keyword arguments, into a single hashable "key 
object", for some unstated reason, and be able to store that key object 
into a dict.

Advantage (double-edged, possible):

(1) Requires no change to the method signature to support keyword 
parameters (whether you want them or not, you will get them).

Disadvantages:

(1) If you don't want keyword parameters in your subscript methods, you 
can't just *do nothing* and have them be a TypeError, you have to 
explicitly check for a KeyObject argument and raise:

    def __getitem__(self, index):
        if isinstance(item, KeyObject):
            raise TypeError('MyClass index takes no keyword arguments')

(2) Seems to be a completely artificial and useless use-case to me. If 
there is a concrete use-case for this, either I have missed it, (in 
which case my apologies) or Jonathan seems to be unwilling or unable to 
give it. But if you really wanted it, you could get it with this 
signature and a single line in the body:

    def __getitem__(self, *args, **kw):
        key = KeyObject(*args, **kw)

(3) Forces those who want named keyword parameters to parse them from 
the KeyObject value themselves.

Since named keyword parameters are surely going to be the most common 
use-case (just as they are for other functions), this makes the common 
case difficult and the rare and unusual case easy.

(4) KeyObject doesn't exist. We would need a new builtin type to support 
this, as well as the new syntax. This increases the complexity and 
maintenance burden of this new feature.

(5) Compounds the "kind of screwy" (Greg's words) nature of subscripting 
by extending it to keyword arguments as well as positional arguments.



-- 
Steven
_______________________________________________
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/DAND7BJXUAVPGQU4EDHX2YIZ7HUNDASJ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to