Skip to content

Commit 726f52b

Browse files
Fixes for NEWS. Add setdefault test and fix
1 parent 3b5eace commit 726f52b

File tree

3 files changed

+17
-12
lines changed

3 files changed

+17
-12
lines changed

Lib/test/test_dict.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,20 +1602,25 @@ def __hash__(self):
16021602
d.get(key2)
16031603

16041604
def test_clear_at_lookup(self):
1605-
d = {}
1606-
16071605
class X(object):
16081606
def __hash__(self):
16091607
return 1
16101608
def __eq__(self, other):
16111609
nonlocal d
16121610
d.clear()
16131611

1612+
d = {}
16141613
for _ in range(10):
16151614
d[X()] = None
16161615

16171616
self.assertEqual(len(d), 1)
16181617

1618+
d = {}
1619+
for _ in range(10):
1620+
d.setdefault(X(), None)
1621+
1622+
self.assertEqual(len(d), 1)
1623+
16191624

16201625
class CAPITest(unittest.TestCase):
16211626

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Fixed crash in :class:`dict` if :meth:`clear` is called at the lookup stage. Patch by
2-
Mikhail Efimov.
1+
Fixed crash in :class:`dict` if :meth:`dict.clear` is called at the lookup
2+
stage. Patch by Mikhail Efimov.

Objects/dictobject.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,14 @@ static inline int
17751775
insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
17761776
Py_hash_t hash, PyObject *key, PyObject *value)
17771777
{
1778+
// gh-140551: If dict was cleaned in _Py_dict_lookup,
1779+
// we have to resize one more time to force general key kind.
1780+
if (DK_IS_UNICODE(mp->ma_keys) && !PyUnicode_CheckExact(key)) {
1781+
if (insertion_resize(mp, 0) < 0)
1782+
return -1;
1783+
assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL);
1784+
}
1785+
17781786
if (mp->ma_keys->dk_usable <= 0) {
17791787
/* Need to resize. */
17801788
if (insertion_resize(mp, 1) < 0) {
@@ -1899,14 +1907,6 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
18991907
if (ix == DKIX_ERROR)
19001908
goto Fail;
19011909

1902-
// gh-140551: If dict was cleaned in _Py_dict_lookup,
1903-
// we have to resize one more time to force general key kind.
1904-
if (DK_IS_UNICODE(mp->ma_keys) && !PyUnicode_CheckExact(key)) {
1905-
if (insertion_resize(mp, 0) < 0)
1906-
goto Fail;
1907-
assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL);
1908-
}
1909-
19101910
if (ix == DKIX_EMPTY) {
19111911
assert(!_PyDict_HasSplitTable(mp));
19121912
/* Insert into new slot. */

0 commit comments

Comments
 (0)