This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: .popitem() is inconsistent in collections and collections.abc
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: AlexWaygood, rhettinger, stutzbach
Priority: normal Keywords:

Created on 2021-07-27 17:35 by AlexWaygood, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
collections popitem weirdness.py AlexWaygood, 2021-07-27 17:35 Short script demonstrating unexpected behaviour of `.popitem()` in `collections` and `collections.abc` modules
Messages (3)
msg398310 - (view) Author: Alex Waygood (AlexWaygood) * (Python triager) Date: 2021-07-27 17:35
In a Python dictionary, `.popitem()` returns (key, value) pairs from the dictionary in a LIFO order. `collections.OrderedDict` and `collections.Counter` both do the same. However, a class inheriting from `collections.abc.MutableMapping` (which includes, in the standard library, `collections.UserDict`), will inherit a `.popitem()` method that returns (key, value) pairs in a FIFO order.

In my opinion, this seems like unexpected behaviour, given that these classes are designed to emulate the API of a standard Python dict.

The documentation for ordinary dictionaries states that `.popitem()` uses LIFO (https://docs.python.org/3/library/stdtypes.html#typesmapping), as does `collections.OrderedDict` (https://docs.python.org/3/library/collections.html#collections.OrderedDict). However, I can't find anything in the documentation for the collections.abc module (https://docs.python.org/3/library/collections.abc.html) or the docstring for `collections.abc.MutableMapping.popitem()` (https://github.com/python/cpython/blob/ae0a2b756255629140efcbe57fc2e714f0267aa3/Lib/_collections_abc.py#L964) that states that collections.abc.MutableMapping will use FIFO. Ditto for the collections.UserDict documentation/docstring: https://docs.python.org/3/library/collections.html#collections.UserDict, https://github.com/python/cpython/blob/6948964ecf94e858448dd28eea634317226d2913/Lib/collections/__init__.py#L1084.

Is this expected/intended behaviour? I found it highly confusing when attempting to implement a custom data structure just now. I think a note in the docstring/documentation, noting that this is the behaviour, would certainly be useful.

I have attached a minimal demonstration of this behaviour. Tests only done on Python 3.9.
msg398317 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-07-27 20:43
Alex, thank for noticing this, but it is not a bug.

MutableMapping is meant to describe all mapping classes including those that don't remember insertion order.

The builtin dict() type implements MutableMapping but also adds ordering guarantees.  It is common and normal for concrete classes to implement additional behaviors and guarantees beyond those specified in the abstract base class.
msg398319 - (view) Author: Alex Waygood (AlexWaygood) * (Python triager) Date: 2021-07-27 21:19
Thanks, Raymond -- that makes sense, and seems very fair. I still think a note somewhere in the documentation stating this might be helpful -- as a user, it wasn't what I was expecting. I would argue this is especially true for UserDict, a class which the name implies will be extremely `dict`-like in behaviour. Just my two cents, though.
History
Date User Action Args
2022-04-11 14:59:47adminsetgithub: 88913
2021-07-27 21:20:00AlexWaygoodsetmessages: + msg398319
2021-07-27 20:43:16rhettingersetstatus: open -> closed
messages: + msg398317

assignee: rhettinger
resolution: not a bug
stage: resolved
2021-07-27 17:56:17AlexWaygoodsetnosy: + rhettinger, stutzbach
2021-07-27 17:35:28AlexWaygoodcreate