On Sat, Aug 29, 2020 at 11:04 AM Jonathan Fine <[email protected]> wrote:
[snip]
> The passage
> >>> d[1, 2] = 'val'
> >>> d.__setitem__((1,2), 'val')
> goes via tuple. If tuple didn't already exist, we'd have to invent it. And
> so here tuple is what I call "the key function".
>
IIUC in order to get these semantics under your proposed system, I should
either leave __keyfn__ unset (for backward compatible behavior) or set it
explicitly to True. Is that correct?
The key function is the function that is the intermediary between
> >>> d[EXPRESSION]
> >>> d.__getitem__(key)
>
> When there is a key function, the signatures are
> __getitem__(key)
> __delitem__(key)
> __setitem__(key, val)
>
> So we're allowed to have
> class A:
> __keyfn__ = None
> def __setitem__(self, val, a, b, c d):
> # set the value
>
> Recall that dict has, implicitly, a way of getting a key from permitted
> arguments. The meaning of
> class B:
> __keyfn__ = True
> def __getitem__(key):
> # Get the value
> is that the key is produced by exactly the same method as in dict.
>
> The meaning of
> __keyfunc__ = True
> is "produce a key from the arguments, in exactly the same way as in dict".
> Or in other words, "Yes, it's True. We do have a keyfn. Use the default,
> dict, keyfn."
>
> I think (None, True) works better than (False, True). This is because a
> further PEP might allow the user to supply a custom keyfn. So while it is
> at this time a binary choice, there might be further choices in future.
>
>
>> Can you explain (in words or with examples) what happens in each case?
>> You were so excited to show off one case that you never showed how the
>> other case would work
>>
>
> How about:
>
> class A:
> __keyfn__ = None
> def __setitem__(self, val, x=0, y=0, z=0):
> print((val, x, y, z))
>
Okay, I am beginning to understand your proposal (despite vehemently
disagreeing). You propose that setting __keyfn__ = None should change the
signature of __setitem__ so that
1. the value is placed first (before the "key" values)
2. the rest of the arguments (whether positional or keywords) are passed
the same way as for a function
> >>> a = A()
> >>> a[1, z=2] = 'hello'
> ('hello', 1, 0, 2)
>
> [Above copied from
> https://mail.python.org/archives/list/[email protected]/message/P3AW6GNIYDDOTVQ2FKWYD7XYNZ5P5QBS/
> ]
>
>
> And also
>
> class C:
> __keyfn__ = True
> def __setitem__(self, *argv, **kwargs):
> print(f'argv={argv} | kwargs={kwargs}')
>
> >>> c = C()
>
> >>> c[1] = 'val'
> argv=(1, 'val') | kwargs={}
> >>> c[1, 2] = 'val'
> argv=((1, 2), 'val') | kwargs={}
>
> >>> c[a=1] = 'val'
> TypeError: __keyfn__ got unexpected keyword argument 'a'
>
> [Above copied from
> https://mail.python.org/archives/list/[email protected]/message/RNQFT4USRCTYTSLAUNPTWGMC6WLZEPKH/
> ]
>
> I hope this helps.
>
Yes. I find it a big flaw that the signature of __setitem__ is so strongly
influenced by the value of __keyfunc__. For example, a static type checker
(since PEP 484 I care deeply about those and they're popping up like
mushrooms :-) would have to hard-code a special case for this, because
there really is nothing else in Python where the signature of a dunder
depends on the value of another dunder.
And in case you don't care about static type checkers, I think it's the
same for human readers. Whenever I see a __setitem__ function I must look
everywhere else in the class (and in all its base classes) for a __keyfn__
before I can understand how the __setitem__ function's signature is mapped
from the d[...] notation.
Finally, I am unsure how you would deal with the difference between d[1]
and d[1,], which must be preserved (for __keyfn__ = True or absent, for
backwards compatibility). The bytecode compiler cannot assume to know the
value of __keyfn__ (because d could be defined in another module or could
be an instance of one of several classes defined in the current module). (I
think this problem is also present in the __subscript__ version.)
--
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/T7FGW7ZRZGM5NYNKBFCNKEWGGCUBGP5K/
Code of Conduct: http://python.org/psf/codeofconduct/