[Python-ideas] __iter__(), keys(), and the mapping protocol

Michael Selik mike at selik.org
Thu Sep 13 01:55:55 EDT 2018

The dict keys method has other benefits beyond iteration. For example, it
provides a set-like interface.

On Wed, Sep 12, 2018, 10:50 PM Elias Tarhini <eltrhn at gmail.com> wrote:

> On Wed, Sep 12, 2018 at 4:42 PM Michael Selik <mike at selik.org> wrote:
>> You want to have a Mapping that does not supply a keys method? What use
>> case motivated your proposal?
> Yes, my proposal was to consider allowing __iter__() to subsume keys()
> entirely, for the reasons outlined in my second email -- which I'm just
> realizing was an accidental "reply one" to Alex Walters rather than a
> "reply all", yikes! Here it is, duplicated:
> Ahh, no, I phrased my question a bit badly -- I'm not proposing that the
>> keys() method be *removed* from what it exists on currently, but rather
>> that this:
>> > To be treated like a mapping everywhere, python requires that you
>> define* a keys() method, so why not use it?
>> be changed, such that only __iter__() and __getitem__() indicate a
>> mapping rather than keys() and the same. The latter method would then be
>> optional, but not necessarily removed from the front-facing API.
>> Granted, my only strong argument is that the ** unpacking operator
>> depends on this method to do its job, and it's currently alone amongst
>> Python's operators in depending on a non-dunder to do so; that, combined
>> with the point heading the below paragraph, is also why I'm only going
>> after keys() — not items() or sequences' index() or any of the other
>> normally-named-but-important methods.
>> And given that __iter__() is already recommended to iterate over a
>> mapping's keys, it doesn't seem illogical to me to just let it take that
>> job officially (and in turn, I guess, to make keys() on stdlib/built-in
>> types just return __iter__()). I don't believe there would be another
>> expected use for it in a mapping, anyway, correct? (I haven't done the
>> research here, but there could be third-party authors who use it to iterate
>> over items(), given that “why does it iterate over just keys” a
>> somewhat-recognizable discussion topic on such beginner forums as
>> /r/learnpython... if so, this could be a good opportunity to
>> force-standardize that behavior as well.)
>> Does this clarify my intent? ...I don't doubt that there are roadblocks
>> I'm still ignoring, though.
>> Eli
> However, Serihy's example of {**[0, 2, 1]} is so-plainly irreconcilable
> -- somewhat embarrassing for me to have missed it -- that I'm now
> reluctantly no longer in favor. (Well, really, I'm tempted to say *why
> not?*, but I do see that it wouldn't be a good thing overall.)
> And I still kind of feel that there should be a dunder involved somewhere
> in this, but nowhere near strongly enough to dispute that *"[t]he dunder
> methods are dunder methods because they are not generally directly useful.
> [There doesn't seem to be] a major problem with having the mapping api call
> keys() [...]"*, as it's reasonable and rationalizes the current system
> well enough. Thank you for bearing with ;)
> Eli
> On Wed, Sep 12, 2018 at 4:42 PM, Michael Selik <mike at selik.org> wrote:
>> Elias,
>> I'm a little confused about what you're suggesting. You want to have a
>> Mapping that does not supply a keys method? What use case motivated your
>> proposal?
>> On Mon, Sep 10, 2018, 7:04 PM Elias Tarhini <eltrhn at gmail.com> wrote:
>>> This has been bouncing around in my head for a while regarding the
>>> requisite keys() method on mappings:
>>> How come the ** unpacking operator, a built-in language feature, relies
>>> on a non-dunder to operate?
>>> To me, I mean to say, requiring that classes implement keys() – a
>>> method whose name is totally undistinguished – in order to conform to the
>>> mapping protocol feels like a design running counter to Python's norm of
>>> using dunders for everything "hidden". I am not sure if it feels dirty to
>>> anybody else, however. Interestingly, the docs already say
>>> <https://docs.python.org/3/reference/datamodel.html#object.__iter__>
>>> that *[f]or mappings, [__iter__()] should iterate over the keys of the
>>> container*, but it of course is not enforced in any way at present.
>>> So, then — how about enforcing it? Should __iter__(), for the reasons
>>> above, replace the current purpose of keys() in mappings?
>>> I'm not properly equipped at the moment to mess around with CPython
>>> (sorry), but I assume at a minimum this would entail either replacing all
>>> instances of PyMapping_Keys() with PyObject_GetIter() or alternatively
>>> changing  PyMapping_Keys() to call the latter.
>>> Does it sound like a reasonable change overall?
>>> Eli
>>> _______________________________________________
>>> Python-ideas mailing list
>>> Python-ideas at python.org
>>> https://mail.python.org/mailman/listinfo/python-ideas
>>> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180912/b6bbc172/attachment.html>

More information about the Python-ideas mailing list