From 618f930d0c5223a08b0ea1138d8d2cc5eceecb14 Mon Sep 17 00:00:00 2001 From: Anerdw Date: Wed, 1 Apr 2026 01:45:05 -0500 Subject: [PATCH 1/8] gh-147957: pop items from UserDict in LIFO order `UserDict.popitem` used to pop first-in, first-out since that's the `MutableMapping` implementation. It now pops first-in, last-out since that's the behavior guaranteed for `dict` starting in Python 3.7. --- Lib/collections/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index febab521629228..d07a9481d1dc22 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1253,6 +1253,13 @@ def copy(self): c.update(self) return c + + # This method has a default implementation in MutableMapping, but dict's + # equivalent is first-in, first-out. + def popitem(self): + return self.data.popitem() + + @classmethod def fromkeys(cls, iterable, value=None): d = cls() From 15acd1fe9498f005b262cc513fd1387036d86d1b Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 07:10:50 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst diff --git a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst new file mode 100644 index 00000000000000..a40162374cae58 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst @@ -0,0 +1 @@ +Causes the `popitem` method for `collections.UserDict` to pop in last-in, first-out order rather than first-in, first-out. The former has been the default for `dict` instances since Python 3.7, so this change will make subclasses of `UserDict` behave more similarly to `dict`. From a460fbeaab1a496f24cdead10a3681824749202a Mon Sep 17 00:00:00 2001 From: Anerdw Date: Wed, 1 Apr 2026 02:14:06 -0500 Subject: [PATCH 3/8] Clarify LIFO vs FIFO The last commit used the wrong verbiage in a comment. This fixes it and clarifies that MutableMapping uses FIFO. --- Lib/collections/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index d07a9481d1dc22..f03397ff407c73 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1255,7 +1255,7 @@ def copy(self): # This method has a default implementation in MutableMapping, but dict's - # equivalent is first-in, first-out. + # equivalent is last-in, first-out instead of first-in, first-out. def popitem(self): return self.data.popitem() From 41660d6f2a106680f648c30529f90af57427e867 Mon Sep 17 00:00:00 2001 From: Anerdw <84680088+Andrew5057@users.noreply.github.com> Date: Wed, 1 Apr 2026 02:21:32 -0500 Subject: [PATCH 4/8] Fix inline code in NEWS entry Switch from single to double backticks for inline code. --- .../next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst index a40162374cae58..532887a0d049a1 100644 --- a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst +++ b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst @@ -1 +1 @@ -Causes the `popitem` method for `collections.UserDict` to pop in last-in, first-out order rather than first-in, first-out. The former has been the default for `dict` instances since Python 3.7, so this change will make subclasses of `UserDict` behave more similarly to `dict`. +Causes the ``popitem`` method for ``collections.UserDict`` to pop in last-in, first-out order rather than first-in, first-out. The former has been the default for ``dict`` instances since Python 3.7, so this change will make subclasses of `UserDict` behave more like ``dict``. From ea8e2969f43dc431eb6cb49eed84907e0fecc91a Mon Sep 17 00:00:00 2001 From: Anerdw Date: Wed, 1 Apr 2026 02:25:11 -0500 Subject: [PATCH 5/8] Fix one last single backtick --- .../next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst index 532887a0d049a1..208b47fc312a3f 100644 --- a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst +++ b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst @@ -1 +1 @@ -Causes the ``popitem`` method for ``collections.UserDict`` to pop in last-in, first-out order rather than first-in, first-out. The former has been the default for ``dict`` instances since Python 3.7, so this change will make subclasses of `UserDict` behave more like ``dict``. +Causes the ``popitem`` method for ``collections.UserDict`` to pop in last-in, first-out order rather than first-in, first-out. The former has been the default for ``dict`` instances since Python 3.7, so this change will make subclasses of ``UserDict`` behave more like ``dict``. From 1e29fbaa06699e736194b9330240d5870fc5605c Mon Sep 17 00:00:00 2001 From: Anerdw Date: Fri, 3 Apr 2026 18:23:01 -0500 Subject: [PATCH 6/8] Document the UserDict.popitem() override Provide documentation for the ordering guarantees in UserDict.popitem() in the method's docstring and in the Python docs. --- Doc/library/collections.rst | 7 +++++++ Lib/collections/__init__.py | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index c8dcaef80188cd..8e94fc92999544 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -1346,7 +1346,14 @@ attribute. A real dictionary used to store the contents of the :class:`UserDict` class. + :class:`!UserDict` instances also override the following method: + .. method:: popitem + + Remove and return a ``(key, value)`` pair from the wrapped dictionary. Pairs are + returned in in the same order as :func:`.data.popitem`. (For the default + :meth:`dict.popitem`, this order is :abbr:`LIFO (last-in, first-out)`.) If the + dictionary is empty, raises a :exc:`KeyError`. :class:`UserList` objects ------------------------- diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index f03397ff407c73..20f1e728733fec 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1257,6 +1257,13 @@ def copy(self): # This method has a default implementation in MutableMapping, but dict's # equivalent is last-in, first-out instead of first-in, first-out. def popitem(self): + """Remove and return a (key, value) pair as a 2-tuple. + + Removes pairs in the same order as the wrapped mapping's popitem() + method. For dict objects (the default), that order is last-in, + first-out (LIFO). + Raises KeyError if the UserDict is empty. + """ return self.data.popitem() From 9f4625ca19908174131f18d25d9c464a02d26de2 Mon Sep 17 00:00:00 2001 From: Anerdw Date: Fri, 3 Apr 2026 18:24:41 -0500 Subject: [PATCH 7/8] Improve the NEWS entry for UserDict.popitem() Makes better use of reST constructs and uses better language. --- .../Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst index 208b47fc312a3f..25b6108fc8602d 100644 --- a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst +++ b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst @@ -1 +1,2 @@ -Causes the ``popitem`` method for ``collections.UserDict`` to pop in last-in, first-out order rather than first-in, first-out. The former has been the default for ``dict`` instances since Python 3.7, so this change will make subclasses of ``UserDict`` behave more like ``dict``. +Guarantees that the CPython implementation of :meth:`collections.UserDict.popitem` will pop in the same order as the wrapped dictionary rather than an arbitrary order. +This change will make :class:`UserDict` instances behave more similarly to :class:`dict` (or whichever mapping type the instance is customized to use). From 4aeef152fac07b1def866aabc517fdec08ead629 Mon Sep 17 00:00:00 2001 From: Anerdw Date: Fri, 3 Apr 2026 18:32:47 -0500 Subject: [PATCH 8/8] Fix missing references in reST documents The Python documentation and NEWS entry for the override had missing references; this fixes them. --- Doc/library/collections.rst | 2 +- .../Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 8e94fc92999544..fb4f8da503fde8 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -1351,7 +1351,7 @@ attribute. .. method:: popitem Remove and return a ``(key, value)`` pair from the wrapped dictionary. Pairs are - returned in in the same order as :func:`.data.popitem`. (For the default + returned in in the same order as ``data.popitem()``. (For the default :meth:`dict.popitem`, this order is :abbr:`LIFO (last-in, first-out)`.) If the dictionary is empty, raises a :exc:`KeyError`. diff --git a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst index 25b6108fc8602d..4a0e15d01c72b6 100644 --- a/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst +++ b/Misc/NEWS.d/next/Library/2026-04-01-07-10-49.gh-issue-147957.QXf5Xx.rst @@ -1,2 +1 @@ -Guarantees that the CPython implementation of :meth:`collections.UserDict.popitem` will pop in the same order as the wrapped dictionary rather than an arbitrary order. -This change will make :class:`UserDict` instances behave more similarly to :class:`dict` (or whichever mapping type the instance is customized to use). +Guarantees that :meth:`collections.UserDict.popitem` will pop in the same order as the wrapped dictionary rather than an arbitrary order.