Skip to content

Commit

Permalink
pythongh-105736: Sync pure python version of OrderedDict with the C v…
Browse files Browse the repository at this point in the history
…ersion (pythonGH-108098)

(cherry picked from commit 20cc90c)

Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
  • Loading branch information
rhettinger authored and miss-islington committed Aug 21, 2023
1 parent d4c66bd commit 5699bd8
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
16 changes: 9 additions & 7 deletions Lib/collections/__init__.py
Expand Up @@ -90,17 +90,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,
Expand Down
11 changes: 11 additions & 0 deletions Lib/test/test_ordered_dict.py
Expand Up @@ -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')
Expand Down
@@ -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__`.

0 comments on commit 5699bd8

Please sign in to comment.