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/

Reply via email to