Thank you, Guido, for your interest in this discussion.

You wrote:

> So __keyfn__ has literally only two allowed values, None and True.
>

That's my proposal, for now. I'm happy for further allowed values to be
added via another PEP. In fact, that is my preference.

You also wrote:

> Could you just start over? And explain the name? And why it can't be
> False/True?


Consider
    >>> d[1, 2] = 'val'
    >>> d.__setitem__((1,2), 'val')

Here I call (1, 2) the key. As in
    def __setitem__(key, val):
        # set the value

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".

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))

    >>> a = A()
    >>> a[1, z=2] = 'hello'
    ('hello', 1, 0, 2)

[Above copied from
https://mail.python.org/archives/list/python-ideas@python.org/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/python-ideas@python.org/message/RNQFT4USRCTYTSLAUNPTWGMC6WLZEPKH/
]

I hope this helps.

-- 
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/IFW27K7ZYZ3I6LAANMZTO4MLI2E4LRWU/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to