[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.
# 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,

View file

@ -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')

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