You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
collections.UserDict.popitem currently uses the collections.abc.MutableMapping default implementation, which pops items in the order of iter(self.data) and is thus FIFO:
Given that UserDict is meant to "[simulate] a dictionary", it seems preferable for UserDict instances to pop LIFO as well. (This has already been the subject of confusion, per a recent Stack Overflow question.) This change could be a CPython implementation detail, but it could (in the long run) be a spec guarantee as well.
The spec has not historically guaranteed an order for UserDict.popitem, nor for MutableMapping.popitem (nor specified that UserDict is a subclass of MutableMapping), but this change might break programs that relied on the FIFO behavior anyways. That said, the whole point of UserDict is to emulate dict for subclassing purposes, so I think the consistency still outweighs the risk.
Neither UserDict, nor MutableMapping makes an ordering guarantee:
>>> help(UserDict.popitem)
Help on function popitem in module collections.abc:
popitem(self)
D.popitem() -> (k, v), remove and return **some** (key, value) pair
as a 2-tuple; but raise KeyError if D is empty.
@rhettinger The "some" note is based on the MutableMapping implementation. UserDict just doesn't have an implementation at all. However, dict makes the ordering guarantee; those using UserDict as an alternative to subclassing dict will likely expect that behavior.
This is an interesting question. UserDict inherits implementation from MutableMapping, but implements some methods by delegating to the underlying dict (because they are abstract in MutableMapping or for performance). What other methods are inherited from MutableMapping and not delegated to dict? What other methods are worth to delegate? The same questions for UserList and UserString.
@Andrew5057 The "some" note was mentioned not as a restriction, but as freedom to proceed with your change.
Since the underlying dict is assignable, it can be anything. So, the docstring for the new popitem should be worded to say that it accesses entries in the same order as the underlying dict. In the case of a real dict (the normal case), it would be LIFO.
Activity
pythongh-147957: pop items from UserDict in LIFO order
rhettinger commentedon Apr 1, 2026
Neither UserDict, nor MutableMapping makes an ordering guarantee:
Andrew5057 commentedon Apr 1, 2026
@rhettinger The "some" note is based on the
MutableMappingimplementation.UserDictjust doesn't have an implementation at all. However,dictmakes the ordering guarantee; those usingUserDictas an alternative to subclassingdictwill likely expect that behavior.Andrew5057 commentedon Apr 1, 2026
Is this a duplicate of gh-88913?
serhiy-storchaka commentedon Apr 1, 2026
This is an interesting question. UserDict inherits implementation from MutableMapping, but implements some methods by delegating to the underlying dict (because they are abstract in MutableMapping or for performance). What other methods are inherited from MutableMapping and not delegated to dict? What other methods are worth to delegate? The same questions for UserList and UserString.
rhettinger commentedon Apr 3, 2026
@Andrew5057 The "some" note was mentioned not as a restriction, but as freedom to proceed with your change.
Since the underlying dict is assignable, it can be anything. So, the docstring for the new
popitemshould be worded to say that it accesses entries in the same order as the underlying dict. In the case of a real dict (the normal case), it would be LIFO.pythongh-147957: pop items from UserDict in LIFO order
gh-147957: pop items from UserDict in LIFO order (gh-147958)
pythongh-147957: pop items from UserDict in LIFO order (pythongh-147958)