bpo-38525: Fix a segmentation fault when using reverse iterators of empty dict (GH-16846)
The reverse iterator for empty dictionaries was not handling correctly shared-key dictionaries.
This commit is contained in:
parent
88eeda6311
commit
24dc2f8c56
|
@ -1312,6 +1312,31 @@ class DictTest(unittest.TestCase):
|
||||||
self.assertEqual(list(r), list('dcba'))
|
self.assertEqual(list(r), list('dcba'))
|
||||||
self.assertRaises(StopIteration, next, r)
|
self.assertRaises(StopIteration, next, r)
|
||||||
|
|
||||||
|
def test_reverse_iterator_for_empty_dict(self):
|
||||||
|
# bpo-38525: revered iterator should work properly
|
||||||
|
|
||||||
|
# empty dict is directly used for reference count test
|
||||||
|
self.assertEqual(list(reversed({})), [])
|
||||||
|
self.assertEqual(list(reversed({}.items())), [])
|
||||||
|
self.assertEqual(list(reversed({}.values())), [])
|
||||||
|
self.assertEqual(list(reversed({}.keys())), [])
|
||||||
|
|
||||||
|
# dict() and {} don't trigger the same code path
|
||||||
|
self.assertEqual(list(reversed(dict())), [])
|
||||||
|
self.assertEqual(list(reversed(dict().items())), [])
|
||||||
|
self.assertEqual(list(reversed(dict().values())), [])
|
||||||
|
self.assertEqual(list(reversed(dict().keys())), [])
|
||||||
|
|
||||||
|
def test_reverse_iterator_for_shared_shared_dicts(self):
|
||||||
|
class A:
|
||||||
|
def __init__(self, x, y):
|
||||||
|
if x: self.x = x
|
||||||
|
if y: self.y = y
|
||||||
|
|
||||||
|
self.assertEqual(list(reversed(A(1, 2).__dict__)), ['y', 'x'])
|
||||||
|
self.assertEqual(list(reversed(A(1, 0).__dict__)), ['x'])
|
||||||
|
self.assertEqual(list(reversed(A(0, 1).__dict__)), ['y'])
|
||||||
|
|
||||||
def test_dict_copy_order(self):
|
def test_dict_copy_order(self):
|
||||||
# bpo-34320
|
# bpo-34320
|
||||||
od = collections.OrderedDict([('a', 1), ('b', 2)])
|
od = collections.OrderedDict([('a', 1), ('b', 2)])
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix a segmentation fault when using reverse iterators of empty ``dict`` objects.
|
||||||
|
Patch by Dong-hee Na and Inada Naoki.
|
|
@ -3452,10 +3452,15 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
|
||||||
di->di_dict = dict;
|
di->di_dict = dict;
|
||||||
di->di_used = dict->ma_used;
|
di->di_used = dict->ma_used;
|
||||||
di->len = dict->ma_used;
|
di->len = dict->ma_used;
|
||||||
if ((itertype == &PyDictRevIterKey_Type ||
|
if (itertype == &PyDictRevIterKey_Type ||
|
||||||
itertype == &PyDictRevIterItem_Type ||
|
itertype == &PyDictRevIterItem_Type ||
|
||||||
itertype == &PyDictRevIterValue_Type) && dict->ma_used) {
|
itertype == &PyDictRevIterValue_Type) {
|
||||||
|
if (dict->ma_values) {
|
||||||
|
di->di_pos = dict->ma_used - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
di->di_pos = dict->ma_keys->dk_nentries - 1;
|
di->di_pos = dict->ma_keys->dk_nentries - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
di->di_pos = 0;
|
di->di_pos = 0;
|
||||||
|
|
Loading…
Reference in New Issue