On 2020-12-29 12:44, Christopher Barker wrote:
On Tue, Dec 29, 2020 at 11:18 AM Brendan Barnwell <firstname.lastname@example.org mailto:email@example.com> 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:
No offense to anyone here, but I don't really see that as a valid excuse. Documentation can evolve too. It's fine if the protocols and so on overlap, but the nature of that overlap needs to be documented.
To my mind, every time a change is made to Python behavior there must be a corresponding change to the main documentation describing the change. I would go so far as to say that the lack of such documentation updates should be a blocker on the release of the feature. Features without complete documentation in a straightforward place on python.org/docs (not the PEPs!) should not be shipped.
I can understand really old stuff like dict having undocumented innards, when it was just Guido tinkering on his own, but stuff that dates from the era of a wider development team and widespread use of Python (like the iterator protocol) faces a higher standard. Is there any ongoing project to bring the official documentation up to date with regard to the kinds of issues you describe?
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."
Even that isn't sufficiently explicit, to my mind. It needs to be something more like:
When an object is unpacked with ** unpacking, its .keys() method is called to get the available keys, and its __getitem__ is called to obtain the value for each key.
That should be somewhere where it describes the unpacking syntax and semantics. If dict.update internally uses .keys() and that's relevant for stuff like subclassing dict, that should be in the dict documentation.
In other words, every operation that uses .keys() needs to be defined to use .keys() where that operation it is defined. Or, if there is a "dict protocol" (like maybe the Mapping ABC) then there should be a separate doc page about that protocol, which gives a COMPLETE list of all methods that are part of the protocol along with a COMPLETE list of the language features that make use of that protocol.
Otherwise, the Mapping ABC is clearly defined, but not, in fact, required in most of the contexts that expect a Mapping.
Again, to my mind, the Mapping ABC (and most of the other ABCs there) are not clearly defined, because the semantics of the methods and when they are invoked by other parts of Python's machinery (e.g., syntax) are not defined. In other words, it's not enough to say that .keys() "is part of the Mapping ABC"; you have to actually give a complete list of situations when it's going to be implicitly called, and update that list if needed as the language evolves.