[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 20cc90c0df)

Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2023-08-21 05:31:11 -07:00 committed by GitHub
parent f798a6360b
commit 1ce8b92ce9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 7 deletions

View file

@ -95,17 +95,19 @@ class OrderedDict(dict):
# Individual links are kept alive by the hard reference in self.__map. # Individual links are kept alive by the hard reference in self.__map.
# Those hard references disappear when a key is deleted from an OrderedDict. # 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): def __init__(self, other=(), /, **kwds):
'''Initialize an ordered dictionary. The signature is the same as '''Initialize an ordered dictionary. The signature is the same as
regular dictionaries. Keyword argument order is preserved. 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) self.__update(other, **kwds)
def __setitem__(self, key, value, def __setitem__(self, key, value,

View file

@ -122,6 +122,17 @@ class OrderedDictTests:
self.OrderedDict(Spam()) self.OrderedDict(Spam())
self.assertEqual(calls, ['keys']) 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): def test_fromkeys(self):
OrderedDict = self.OrderedDict OrderedDict = self.OrderedDict
od = OrderedDict.fromkeys('abc') od = OrderedDict.fromkeys('abc')

View file

@ -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__`.