I have not fully thought this out yet, but while my first instinct was to agree with others to “just use the calling conventions we already have”, there is a wrinkle:
Current indexing behavior is an oddball now: ( you all know this, but I think it’s helpful to lay it out) The signature of __getitem__ is always: def __getitem__(self, index): If you pass a single item: an_object[thing] then that thing gets assigned to index, whatever it is. if you pass more than one item: an_object(thing1, thing2, thing3) then a tuple of those gets assigned to index, and the implementation of __getitem__ has to parse that out itself, which is different than the "usual" argument passing, where it would always be a tuple, whether is was a length-one or not. (and to get that tuple, you'd need to use *args, or specify a particular number of arguments. So: if we want to maintain backward compatibility, we *can't* use the regula rargument passing approach, it will have to be a slightly odd special case. Which brings us to (what I think is) Jonathan's idea: we keep the idea that __getitem__ always accepts a single argument. now it's either a single object or a tuple of objects. If we extend that, then it's either a single object, or a tuple of opjects, or a new "keywords" object that would hold both the positional and keyword "arguments", so any old code that did somethign like: def __getitem__(self, index): if isinstance(index, tuple): handle_the_tuple_of_indices(index) else: handle_a_single_index(index) would still work as it does now. and if something wanted to implement keywords, it could add a clause: elif isinstance(index, keywords_object): handle_all_the_args_and_keywords(index) and away we go. TL;DR: Indexing would now create one of: - a single item - a tuple of items - a keywords_object_of positional and keyword arguments. And just like we can now create a tuple of indices and pass them in as a single object, we could also create a keyword_object some other way and pass that in directly. If we did not do this, could we use: an_object[*args, **kwargs] and if *args was length-1, it would get extracted from the tuple? or would the seroth item of *args always get extracted from the tuple? So creating a new object to hold the arguments of an indexing operation is a bit awkward, yes, but more consistent with how it currently works. -CHB On Thu, Aug 20, 2020 at 9:55 AM Jonathan Fine <jfine2...@gmail.com> wrote: > Todd wrote: > > It has the same capabilities, the question is whether it has any >> additional abilities that would justify the added complexity. >> > > The most obvious additional ability is that always > >>> d[SOME_EXPRESSION] > is equivalent to > >>> d[key] > for a suitable key. > > This is a capability that we already have, which would sometimes be lost > under the scheme you support. Also lost would be the equivalence between > >>> val = d[key] > >>> getter = operator.itemgetter(key) > >>> val = getter(d) > > More exactly, sometimes it wouldn't be possible to find and use a key. > Docs would have to be changed. > See: https://docs.python.org/3/library/operator.html#operator.itemgetter > > As I understand it, xarray uses dimension names to slice data. Here's an > example from > > http://xarray.pydata.org/en/stable/indexing.html#indexing-with-dimension-names > >>> da[dict(space=0, time=slice(None, 2))] > > Presumably, this would be replaced by something like > >>> da[space=0, time=:2] > > Now, the commands > >>> da[space=0, time=:2] > >>> da[space=0, time=:2] = True > >>> del da[space=0, time=:2] > would at the begging of the call, presumably, do the same processing on > the keyword arguments. (Let this stand for a wide range of examples.) > > It is arguable that making it easier for the implementer of type(da) to do > all that processing in the same place would be a REDUCTION of complexity. > Allowing the processing to produce an intermediate object, say > >>> key = dict(space=0, time=slice(None, 2)) > would help here. > > Real world examples are required, I think, to ground any discussions of > complexity and simplicity. We want to optimise for what people do, for the > problems they face. And this is a new feature. > > We have a perfectly good way of handling keywords, so it is up to you to >> explain why we shouldn't use it. >> > > The scheme you support does not distinguish > >>> d[1, 2, x=3, y=4] > >>> d[(1, 2), x=3, y=4] > I don't regard that as being perfectly good. > > In addition, I would like > >>> d = dict() > >>> d[x=1, y=2] = 5 > to work. It works out-of-the-box for my scheme. It can be made to work > with a subclass of dict for the D'Aprano scheme. > > I think that is enough for now. > > I'd prefer to discuss this further by writing Python modules that contain > code that can be tested. The testing should cover both the technical > correctness and the user experience. To support this I intend not to focus > on the next version of kwkey. > https://pypi.org/project/kwkey/ > > -- > Jonathan > > > _______________________________________________ > > 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/3XRS7WVSFJAZJ6TODL62KZYEDRUV3CRI/ > > 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/P6Q5DYIAA5G3KWL55TVEGUAQFOO7TPEQ/ Code of Conduct: http://python.org/psf/codeofconduct/