[Python-checkins] [3.12] gh-105736: Sync pure python version of OrderedDict with the C version (GH-108098) (#108200)
Yhg1s
webhook-mailer at python.org
Mon Aug 21 08:31:15 EDT 2023
https://github.com/python/cpython/commit/1ce8b92ce92e9a44ac804ea4e4c61d08d7e89a2e
commit: 1ce8b92ce92e9a44ac804ea4e4c61d08d7e89a2e
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Yhg1s <thomas at python.org>
date: 2023-08-21T14:31:11+02:00
summary:
[3.12] gh-105736: Sync pure python version of OrderedDict with the C version (GH-108098) (#108200)
gh-105736: Sync pure python version of OrderedDict with the C version (GH-108098)
(cherry picked from commit 20cc90c0df3e368fe7cb63d958f0b17a78fa9d0a)
Co-authored-by: Raymond Hettinger <rhettinger at users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2023-08-17-14-45-25.gh-issue-105736.NJsH7r.rst
M Lib/collections/__init__.py
M Lib/test/test_ordered_dict.py
diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py
index 03ca2d7e18f6f..8652dc8a4ec45 100644
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -95,17 +95,19 @@ class OrderedDict(dict):
# Individual links are kept alive by the hard reference in self.__map.
# Those hard references disappear when a key is deleted from an OrderedDict.
+ def __new__(cls, /, *args, **kwds):
+ "Create the ordered dict object and set up the underlying structures."
+ self = dict.__new__(cls)
+ self.__hardroot = _Link()
+ self.__root = root = _proxy(self.__hardroot)
+ root.prev = root.next = root
+ self.__map = {}
+ return self
+
def __init__(self, other=(), /, **kwds):
'''Initialize an ordered dictionary. The signature is the same as
regular dictionaries. Keyword argument order is preserved.
'''
- try:
- self.__root
- except AttributeError:
- self.__hardroot = _Link()
- self.__root = root = _proxy(self.__hardroot)
- root.prev = root.next = root
- self.__map = {}
self.__update(other, **kwds)
def __setitem__(self, key, value,
diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py
index decbcc2419c9f..4571b23dfe7c1 100644
--- a/Lib/test/test_ordered_dict.py
+++ b/Lib/test/test_ordered_dict.py
@@ -122,6 +122,17 @@ def items(self):
self.OrderedDict(Spam())
self.assertEqual(calls, ['keys'])
+ def test_overridden_init(self):
+ # Sync-up pure Python OD class with C class where
+ # a consistent internal state is created in __new__
+ # rather than __init__.
+ OrderedDict = self.OrderedDict
+ class ODNI(OrderedDict):
+ def __init__(*args, **kwargs):
+ pass
+ od = ODNI()
+ od['a'] = 1 # This used to fail because __init__ was bypassed
+
def test_fromkeys(self):
OrderedDict = self.OrderedDict
od = OrderedDict.fromkeys('abc')
diff --git a/Misc/NEWS.d/next/Library/2023-08-17-14-45-25.gh-issue-105736.NJsH7r.rst b/Misc/NEWS.d/next/Library/2023-08-17-14-45-25.gh-issue-105736.NJsH7r.rst
new file mode 100644
index 0000000000000..f051317d141ff
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-08-17-14-45-25.gh-issue-105736.NJsH7r.rst
@@ -0,0 +1,3 @@
+Harmonized the pure Python version of OrderedDict with the C version. Now,
+both versions set up their internal state in `__new__`. Formerly, the pure
+Python version did the set up in `__init__`.
More information about the Python-checkins
mailing list