On Fri, Aug 14, 2020, at 06:03, Jonathan Fine wrote:
I'd like to sound out consensus regarding mapping access, where none of the keys are positional. In particular, I suggest that PEP 472 allow syntax and semantics such as >>> d[x=1, y=2] = 42 >>> d[x=1, y=2] 42 and ask whether the class >>> X = type(d) should be part of standard Python.
I have an implementation proposal that I believe is distinct from any of the ones mentioned in the PEP currently.
Pass keyword arguments as ordinary keyword arguments [which any particular __getitem__ implementation is free to handle as **kwargs, specific keywords, or simple named arguments]. When a single positional argument is passed, it's used directly; when zero or two or more are passed, they are bundled into a tuple and passed as a single positional argument. Having zero arguments result in an empty tuple allows for easy conceptual compatibility with numpy.
d: d.__getitem__(()) d : d.__getitem__(0) d[0,1] : d.__getitem__((0, 1)) d[x=0]: d.__getitem__((), x=0) d[0, y=1]: d.__getitem__(0, y=1) d[0, 1, z=2]: d.__getitem__((0, 1), z=2)
if an implementation wishes to support a more conventional style of argument handling, the tuple can be deparsed easily in python code:
def __getitem__(self, arg, **kwargs): return self._getitem(*(arg if isinstance(arg, tuple) else (arg,)))
def _getitem(self, x=slice(), y=slice(), z=slice()): ...
but an implementation could also define __getitem__ with any other signature that accepts the arguments outlined above, for example def __getitem__(self, arg, option) would effectively treat option as a keyword-only argument, and __getitem__(self, arg) would, as currently, not accept any keyword arguments.
and if __getitem__ itself defines named keyword args instead of **kwargs, or does not define anything at all, it will result in a TypeError in exactly the same way as if the calls outlined above were made directly, with only positional arguments being accepted and handled in the same way as they are currently.