
On Thu, Aug 06, 2020 at 02:46:01PM +0100, MRAB wrote:
On 2020-08-06 14:16, Stestagg wrote:
In the "New syntax", wouldn't these examples map to:
d[1, 2, a=3] => d.__getitem__((1, 2), a=3) and d[(1, 2), a=3] => d.__getitem__((1, 2), a=3)
That is certainly what I would expect. All positional arguments are packed into a single positional parameter, and any keyword arguments passed separately. Any current subscript dunder is likely to look like this: def __getitem__(self, index): # or key, whatever i.e. it will only have a single positional argument. (Aside from self of course.)
Not quite. The second should be:
d[(1, 2), a=3] => d.__getitem__(((1, 2),), a=3)
Aside from the keyword argument, which is a syntax error, that's not what happens now. py> class Demo: ... def __getitem__(self, index): ... print(index, type(index)) ... py> d = Demo() py> d[(1, 2)] # Tuple single arg. (1, 2) <class 'tuple'> py> d[1, 2] # Still a tuple. (1, 2) <class 'tuple'> Adding a keyword arg should not change this. [Stestagg]
I.e. My understanding was that the existing conversion of all positional parameters in a subscript would be packed into a tuple (strictly for consistency with legacy behaviour) while any keywords would be passed as kwargs?
To be clear, a single argument is not packed into a tuple. I think that what is actually going on is a matter of precedence. Commas do double duty, separating arguments in calls and creating tuples. Inside a function call, the argument separate takes priority: func(1, 2, 3) is interpreted as three arguments separated by commas. If you want a tuple, you need to change the priority by using round brackets: func((1, 2, 3)) But inside a subscript, there is currently no concept of multiple arguments. There's always only one item, and commas just have their normal meaning of creating a tuple. I think that's how it works, but I'm not quite good enough at reading the grammar specs to be sure. https://docs.python.org/3/reference/grammar.html -- Steven