On Tue, Dec 29, 2020 at 11:18 AM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
On 2020-12-29 10:30, Guido van Rossum wrote:
>  Long ago we decided that the distinctive
> feature is that mappings have a `keys()` method whereas sequences don't

        It seems the real issue here is one of documentation.

Exactly. The challenge here is that Python is dynamic and has evolved (a lot!) over the years. So there are dunders, and protocols, and ABCs, and they all overlap a bit in purpose. And "protocols" seem to be the least clearly specified. Indeed, the "iteration protocol" is well known and talked about, but not well documented in the standard docs:

The only actual reference to it I could find is in the C API docs.

__iter__ and __next__ are referred to a lot, but I don't see the protocol described anywhere.

And there are various protocols described in the C API docs, including the Mapping protocol:

https://docs.python.org/3/c-api/mapping.html

But I *think* that's really about the C API -- not what we are talking about here. Also interestingly, it says:
"Note that it returns 1 for Python classes with a __getitem__() method" -- so it's not checking for keys() here.

There IS a discussion of the iterator protocol (without using that word) here:

https://docs.python.org/3/library/stdtypes.html#iterator-types

Under "Iterator Types" -- which is a bit odd, as strictly speaking, it's not a type, but where else would it go? 

So maybe we could add some text to the Mapping Type section on that page:

https://docs.python.org/3/library/stdtypes.html#mapping-types-dict

Maybe something along the lines of:

"When a Mapping type is required in python (e.g. dict.update, ** unpacking),  .keys() and __getitem__ are the minimum required to meet the Mapping protocol."

Otherwise, the Mapping ABC is clearly defined, but not, in fact, required in most of the contexts that expect a Mapping.

The other place we could perhaps improve the docs is in the error message for **:

"TypeError: 'str' object is not a mapping"

perhaps it could say something like:

"TypeError: 'str' object is not a mapping. An object must have a .keys() method to be used in this context"

or some such.

 As far as I can
see, on python.org/docs all we have is that the Mapping abc lists keys()
as a mixin method, but nowhere actually says that those methods are also
what is used to implement syntactic things like **-unpacking.

Indeed, and it also lists .items() among others, but it would be good to specify that it is keys() that is used to determine if an object "is* a Mapping. I see this as a fundamental clash between the concept of an "ABC" and duck typing -- an ABC defines everything that *could* be needed, whereas duck typing requires only what is actually needed in a given context. But if that's the case, it should be documented.
 
-CHB


--
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython