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/