mirror of https://github.com/python/cpython
Issue #25406: Fixed a bug in C implementation of OrderedDict.move_to_end()
that caused segmentation fault or hang in iterating after moving several items to the start of ordered dict.
This commit is contained in:
parent
c1e98de7be
commit
992ec46acc
|
@ -1995,6 +1995,20 @@ class OrderedDictTests:
|
||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
od.move_to_end('x', 0)
|
od.move_to_end('x', 0)
|
||||||
|
|
||||||
|
def test_move_to_end_issue25406(self):
|
||||||
|
OrderedDict = self.module.OrderedDict
|
||||||
|
od = OrderedDict.fromkeys('abc')
|
||||||
|
od.move_to_end('c', last=False)
|
||||||
|
self.assertEqual(list(od), list('cab'))
|
||||||
|
od.move_to_end('a', last=False)
|
||||||
|
self.assertEqual(list(od), list('acb'))
|
||||||
|
|
||||||
|
od = OrderedDict.fromkeys('abc')
|
||||||
|
od.move_to_end('a')
|
||||||
|
self.assertEqual(list(od), list('bca'))
|
||||||
|
od.move_to_end('c')
|
||||||
|
self.assertEqual(list(od), list('bac'))
|
||||||
|
|
||||||
def test_sizeof(self):
|
def test_sizeof(self):
|
||||||
OrderedDict = self.module.OrderedDict
|
OrderedDict = self.module.OrderedDict
|
||||||
# Wimpy test: Just verify the reported size is larger than a regular dict
|
# Wimpy test: Just verify the reported size is larger than a regular dict
|
||||||
|
|
|
@ -45,6 +45,10 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #25406: Fixed a bug in C implementation of OrderedDict.move_to_end()
|
||||||
|
that caused segmentation fault or hang in iterating after moving several
|
||||||
|
items to the start of ordered dict.
|
||||||
|
|
||||||
- Issue #25364: zipfile now works in threads disabled builds.
|
- Issue #25364: zipfile now works in threads disabled builds.
|
||||||
|
|
||||||
- Issue #25328: smtpd's SMTPChannel now correctly raises a ValueError if both
|
- Issue #25328: smtpd's SMTPChannel now correctly raises a ValueError if both
|
||||||
|
|
|
@ -618,37 +618,26 @@ _odict_find_node(PyODictObject *od, PyObject *key)
|
||||||
static void
|
static void
|
||||||
_odict_add_head(PyODictObject *od, _ODictNode *node)
|
_odict_add_head(PyODictObject *od, _ODictNode *node)
|
||||||
{
|
{
|
||||||
if (_odict_FIRST(od) == NULL) {
|
_odictnode_PREV(node) = NULL;
|
||||||
_odictnode_PREV(node) = NULL;
|
_odictnode_NEXT(node) = _odict_FIRST(od);
|
||||||
_odictnode_NEXT(node) = NULL;
|
if (_odict_FIRST(od) == NULL)
|
||||||
_odict_FIRST(od) = node;
|
|
||||||
_odict_LAST(od) = node;
|
_odict_LAST(od) = node;
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
_odictnode_PREV(node) = NULL;
|
|
||||||
_odictnode_NEXT(node) = _odict_FIRST(od);
|
|
||||||
_odict_FIRST(od) = node;
|
|
||||||
_odictnode_PREV(_odict_FIRST(od)) = node;
|
_odictnode_PREV(_odict_FIRST(od)) = node;
|
||||||
}
|
_odict_FIRST(od) = node;
|
||||||
od->od_state++;
|
od->od_state++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_odict_add_tail(PyODictObject *od, _ODictNode *node)
|
_odict_add_tail(PyODictObject *od, _ODictNode *node)
|
||||||
{
|
{
|
||||||
if (_odict_LAST(od) == NULL) {
|
_odictnode_PREV(node) = _odict_LAST(od);
|
||||||
_odictnode_PREV(node) = NULL;
|
_odictnode_NEXT(node) = NULL;
|
||||||
_odictnode_NEXT(node) = NULL;
|
if (_odict_LAST(od) == NULL)
|
||||||
_odict_FIRST(od) = node;
|
_odict_FIRST(od) = node;
|
||||||
_odict_LAST(od) = node;
|
else
|
||||||
}
|
|
||||||
else {
|
|
||||||
_odictnode_PREV(node) = _odict_LAST(od);
|
|
||||||
_odictnode_NEXT(node) = NULL;
|
|
||||||
_odictnode_NEXT(_odict_LAST(od)) = node;
|
_odictnode_NEXT(_odict_LAST(od)) = node;
|
||||||
_odict_LAST(od) = node;
|
_odict_LAST(od) = node;
|
||||||
}
|
|
||||||
|
|
||||||
od->od_state++;
|
od->od_state++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue