On Fri, Jul 17, 2020, 6:17 AM Jonathan Fine <jfine2358@gmail.com> wrote:
Guido wrote:
I think it’s a reasonable idea and encourage you to start working on a design for the API and then a PRP. 

In this post, I explore how the new API might interact with dict objects. (I think PRP is a typo for PEP.)

 ...

To summarize and slightly extend the above. If
    >>> d = dict()
    >>> d[x=1, y=2] = 3
executes without error, then there is an object 'k' such that
    >>> d[x=1, y=2] = 5
    >>> d[k] = 5
are equivalent. (This object 'k' is the key in the collection of (key, value) pairs that are the entries in the dict.)

Aside: The key object, if it exists, has a type. Whether this type is a new type or an existing type is an implementation question. This message is focussed on the user experience.

It seems to me that the validity of this key-object paradigm is directly tied to the decision of whether or not to change the get/set item dunder signatures.

If it turns out the desired way forward is to not change the signature for __getitem__ and __setitem__, only then does a key object exists. If not, I suggest it means the key-object does not exist.

On the other hand, if it were determined we'd rather have **kwargs become part of these signatures, there is no "key object". There is more of an unpacked kwargs, or unpacked namespace, object.

So it isn't obvious to me that this object must be some key object. It certainly CAN be. But the syntax looks so much like kwargs being supplied to a function, a (currently ephemeral) namespace object, or unpacked kwargs object, might be more of a valid way to think about it: 

>>> x = dict(a="foo", b="bar")
>>> d[**x]  # unpack kwargs here, rather than d[x]
>>> d[a="foo", b="bar"]

If one approaches it this way, then just as there isn't some namespace object that you can supply to a function that becomes kwd args in all situations, like:

>>> f(x) == f(a="foo", b="bar")  # this obviously doesn't make sense, since a and b are kwargs

...I'd be more than a little surprised if this worked:

>>> d[x] == d[a="foo", b="bar"]  # a and b certainly LOOK LIKE kwargs, don't they?

But! On the other hand, the huge difference here is that currently, the signature of the get/set item dunders only accepts a single key argument. This is a very big difference from arbitrary function signatures, which CAN accept kwd args. So maybe this key object paradigm does make sense, but what that REALLY means is we are committing ourselves to maintaining the __getitem__ and __setitem__ signatures and not, for example, letting them accept **kwargs. 

On Fri, Jul 17, 2020, 6:49 AM Steven D'Aprano <steve@pearwood.info> wrote:
On Fri, Jul 17, 2020 at 11:14:21AM +0100, Jonathan Fine wrote:

> So what should be the new behaviour of:
>     >>> d = dict()
>     >>> d[x=1, y=2] = 3

TypeError: dict subscripting takes no keyword arguments



Just because something is syntactically allowed doesn't mean it has to be given a meaning in all circumstances.

Another way forward could be to expand the syntax, but delay the decision on what it means. It would be a multi-step process:
  1. allow usage of Dict[x=str, y=int] (including a TypeError on assignment, and TypeError for dictionaries, and TypeError for all other mappings)
  2. delay the decision of which paradigm (key-object, or unpacked/namespace) makes sense (a TypeError everywhere else  in the meantime)   
  3. once it is seen the new syntax is allowed but produces TypeError in all situations other than on `type` objects, let the people tell the steering council what they want the syntax to do in other situations 
So INITIALLY you only teach`type` objects-- and NOT regular dicts or mappings-- how to interpret this syntax:

>>> Dict[x=str, y=int]  # k, cool
>>> d[a="foo", b="bar"]  # TypeError

If people later demand that you be able to do this (with real world code examples):

>>> xy = dict(x=str, y=int)
>>> Dict[**xy] == Dict[x=str, y=int]

...that tells you people want the namespace/unpacked paradigm. On the other hand, if people start asking (with real world code examples) for some kind of key object so they can do this:

>>> d[x] == d[a="foo", b="bar"]

...that tells you people are thinking about it more as a key-object paradigm.

Rick.