On Tue, Aug 25, 2020 at 4:26 PM Stefano Borini <stefano.bor...@gmail.com> wrote:
> In any case, I think that Ricky Teachey might be onto something. > Well when it comes to python ideas, that actually might be a first for me. ;) > Imagine we start from zero. There's no __getitem__. How would you > envision it to work? > > The answer is probably going to be "like a function". that is, if you pass > > a[1, 2] > > it will receive two arguments as if it were __new_getitem__(self, v1, > v2), with only a couple of magic stuff for slices and Ellipsis. From > this, everything would behave rather naturally: a[v1=1, v2=2] would be > automatic. and so the flipped one a[v2=2, v1=1] would return the same > value. > Actually I think this *may not* be true. Consider, if we were starting at zero ,and we agreed we wanted dict literal behavior to work like the following: >>> idx1 = 1,2,3 >>> idx2 = 1,2 >>> idx3 = 1 >>> d = {idx1: "foo", idx2: "bar", idx2: "baz"} This is what we have today, and I think most agree this is all a Good Thing. Then, we might reason, if I want to be able to do a lookup using tuple literals, I'd do this, just as we do today: >>> d[1,2,3] 'foo' >>> d[1,2] 'bar' >>> d[1] 'baz' No tuple brackets required. I think it is REALLY NICE not to have to do THIS, which is what we'd have to do if things behaved the function-call-way inside square brackets: >>> d[(1,2,3)] 'foo' >>> d[(1,2)] 'bar' >>> d[1] 'baz' Of course all of these DO work today-- it just isn't required to use the tuple brackets. They're optional. Could it be that the convenience of not needing to give the tuple brackets, if we were starting at zero, might win out over the function-call syntax even today? I don't know. I wonder. --- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler > Now, my question is, would it _really_ be a major issue to introduce > this __new_getitem__ to be used if available, like we have done > already in the past for similar enhanced protocols? > Because to me, this solution seems the most rational, flexible, and > clear compared to any other option, which in the end are mostly > workarounds fraught with either manual work or odd syntax. It would > solve the ambiguity of the API, it would allow for the parser to > handle the assignment of named arguments to the correct arguments, > with the only problem of potentially allowing a[] as valid syntax if > __new_getitem__(self, *args, **kwargs) is used. > > > > > > > > > On Sat, 8 Aug 2020 at 03:49, Steven D'Aprano <st...@pearwood.info> wrote: > > > > 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/ > > > > -- > Kind regards, > > Stefano Borini > _______________________________________________ > 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/FK3LOXO66WELOOBRXUCCEKP4QKFUIMTU/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ 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/OZEI3ASZ2275JWS4UJXIPWP7KZ6X4BH3/ Code of Conduct: http://python.org/psf/codeofconduct/