8000 [3.12] gh-105736: Sync pure python version of OrderedDict with the C … · python/cpython@1ce8b92 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1ce8b92

Browse files
[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 20cc90c) Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
1 parent f798a63 commit 1ce8b92

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

Lib/collections/__init__.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,19 @@ class OrderedDict(dict):
9595
# Individual links are kept alive by the hard reference in self.__map.
9696
# Those hard references disappear when a key is deleted from an OrderedDict.
9797

98+
def __new__(cls, /, *args, **kwds):
99+
"Create the ordered dict object and set up the underlying structures."
100+
self = dict.__new__(cls)
101+
self.__hardroot = _Link()
102+
self.__root = root = _proxy(self.__hardroot)
103+
root.prev = root.next = root
104+
self.__map = {}
105+
return self
106+
98107
def __init__(self, other=(), /, **kwds):
99108
'''Initialize an ordered dictionary. The signature is the same as
100109
regular dictionaries. Keyword argument order is preserved.
101110
'''
102-
try:
103-
self.__root
104-
except AttributeError:
105-
self.__hardroot = _Link()
106-
self.__root = root = _proxy(self.__hardroot)
107-
root.prev = root.next = root
108-
self.__map = {}
109111
self.__update(other, **kwds)
110112

111113
def __setitem__(self, key, value,

Lib/test/test_ordered_dict.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ def items(self):
122122
self.OrderedDict(Spam())
123123
self.assertEqual(calls, ['keys'])
124124

125+
def test_overridden_init(self):
126+
# Sync-up pure Python OD class with C class where
127+
# a consistent internal state is created in __new__
128+
# rather than __init__.
129+
OrderedDict = self.OrderedDict
130+
class ODNI(OrderedDict):
131+
def __init__(*args, **kwargs):
132+
pass
133+
od = ODNI()
134+
od['a'] = 1 # This used to fail because __init__ was bypassed
135+
125136
def test_fromkeys(self):
126137
OrderedDict = self.OrderedDict
127138
od = OrderedDict.fromkeys('abc')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Harmonized the pure Python version of OrderedDict with the C version. Now,
2+
both versions set up their internal state in `__new__`. Formerly, the pure
3+
Python version did the set up in `__init__`.

0 commit comments

Comments
 (0)
0