Hi Ricky

Thank you for your very helpful comment, which Paul has usefully amplified. You wrote:

This is confusing to me because `my_mapping[1,2,3]` is already valid syntax equivalent to `my_mapping.__setitem__(my_mapping, (1,2,3))`. Wouldn't a change to translate the tuple into this K object lead to big problems for a lot of existing code...?
 
Yes it would, if we don't take care to maintain backwards compatibility. At present we have:
    >>> class Dummy:
    ...         def __getitem__(self, *argv, **kwargs):
    ...             return argv, kwargs
    >>> d = Dummy()
    >>> d[1, 2, 3]
    (((1, 2, 3),), {})

This behaviour must be preserved. Only when the new syntax is used should d.__getitem__ get an instance of the new class K. Otherwise, it should as before get a tuple, exactly as before. (Therefore, it might be good that K(1, 2, 3) returns the tuple (1, 2, 3), rather than an instance of K. As I recall, this can be done by using a suitable K.__new__ method.)

And this would include the use of colon to obtain slices.:
    >>> d[0:1,2:3,4:5]
    (((slice(0, 1, None), slice(2, 3, None), slice(4, 5, None)),), {})

This solution to backwards compatibility is another reason for using a K.adjust_get decorator, when defining the __getitem__ for a map that relies on the new syntax. That way, if the programmer wants the new feature, the appropriate marshalling of positional (and keyword) arguments is done by a dedicated piece of code.

I hope this helps, and thank you again for your query (and Paul for his constructive critical interest).
--
Jonathan