Issue #25935: Garbage collector now breaks reference loops with OrderedDict.
This commit is contained in:
commit
4918b47c64
|
@ -1,10 +1,12 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import copy
|
import copy
|
||||||
|
import gc
|
||||||
import pickle
|
import pickle
|
||||||
from random import randrange, shuffle
|
from random import randrange, shuffle
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
import weakref
|
||||||
from collections.abc import MutableMapping
|
from collections.abc import MutableMapping
|
||||||
from test import mapping_tests, support
|
from test import mapping_tests, support
|
||||||
|
|
||||||
|
@ -593,6 +595,17 @@ class OrderedDictTests:
|
||||||
dict.update(od, [('spam', 1)])
|
dict.update(od, [('spam', 1)])
|
||||||
self.assertNotIn('NULL', repr(od))
|
self.assertNotIn('NULL', repr(od))
|
||||||
|
|
||||||
|
def test_reference_loop(self):
|
||||||
|
# Issue 25935
|
||||||
|
OrderedDict = self.OrderedDict
|
||||||
|
class A:
|
||||||
|
od = OrderedDict()
|
||||||
|
A.od[A] = None
|
||||||
|
r = weakref.ref(A)
|
||||||
|
del A
|
||||||
|
gc.collect()
|
||||||
|
self.assertIsNone(r())
|
||||||
|
|
||||||
|
|
||||||
class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
|
class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #25935: Garbage collector now breaks reference loops with OrderedDict.
|
||||||
|
|
||||||
- Issue #16620: Fixed AttributeError in msilib.Directory.glob().
|
- Issue #16620: Fixed AttributeError in msilib.Directory.glob().
|
||||||
|
|
||||||
- Issue #26013: Added compatibility with broken protocol 2 pickles created
|
- Issue #26013: Added compatibility with broken protocol 2 pickles created
|
||||||
|
|
|
@ -772,19 +772,17 @@ _odict_clear_nodes(PyODictObject *od)
|
||||||
{
|
{
|
||||||
_ODictNode *node, *next;
|
_ODictNode *node, *next;
|
||||||
|
|
||||||
if (!_odict_EMPTY(od)) {
|
|
||||||
node = _odict_FIRST(od);
|
|
||||||
while (node != NULL) {
|
|
||||||
next = _odictnode_NEXT(node);
|
|
||||||
_odictnode_DEALLOC(node);
|
|
||||||
node = next;
|
|
||||||
}
|
|
||||||
_odict_FIRST(od) = NULL;
|
|
||||||
_odict_LAST(od) = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_odict_free_fast_nodes(od);
|
_odict_free_fast_nodes(od);
|
||||||
od->od_fast_nodes = NULL;
|
od->od_fast_nodes = NULL;
|
||||||
|
|
||||||
|
node = _odict_FIRST(od);
|
||||||
|
_odict_FIRST(od) = NULL;
|
||||||
|
_odict_LAST(od) = NULL;
|
||||||
|
while (node != NULL) {
|
||||||
|
next = _odictnode_NEXT(node);
|
||||||
|
_odictnode_DEALLOC(node);
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There isn't any memory management of nodes past this point. */
|
/* There isn't any memory management of nodes past this point. */
|
||||||
|
@ -1233,8 +1231,6 @@ odict_clear(register PyODictObject *od)
|
||||||
{
|
{
|
||||||
PyDict_Clear((PyObject *)od);
|
PyDict_Clear((PyObject *)od);
|
||||||
_odict_clear_nodes(od);
|
_odict_clear_nodes(od);
|
||||||
_odict_FIRST(od) = NULL;
|
|
||||||
_odict_LAST(od) = NULL;
|
|
||||||
if (_odict_resize(od) < 0)
|
if (_odict_resize(od) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -1556,8 +1552,13 @@ PyDoc_STRVAR(odict_doc,
|
||||||
static int
|
static int
|
||||||
odict_traverse(PyODictObject *od, visitproc visit, void *arg)
|
odict_traverse(PyODictObject *od, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
_ODictNode *node;
|
||||||
|
|
||||||
Py_VISIT(od->od_inst_dict);
|
Py_VISIT(od->od_inst_dict);
|
||||||
Py_VISIT(od->od_weakreflist);
|
Py_VISIT(od->od_weakreflist);
|
||||||
|
_odict_FOREACH(od, node) {
|
||||||
|
Py_VISIT(_odictnode_KEY(node));
|
||||||
|
}
|
||||||
return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
|
return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue