add gc support to slice (closes #26659)
This commit is contained in:
parent
a07ab29a79
commit
2b601d3905
|
@ -1,11 +1,13 @@
|
|||
# tests for slice objects; in particular the indices method.
|
||||
|
||||
import unittest
|
||||
from pickle import loads, dumps
|
||||
|
||||
import itertools
|
||||
import operator
|
||||
import sys
|
||||
import unittest
|
||||
import weakref
|
||||
|
||||
from pickle import loads, dumps
|
||||
from test import support
|
||||
|
||||
|
||||
def evaluate_slice_index(arg):
|
||||
|
@ -240,5 +242,14 @@ class SliceTest(unittest.TestCase):
|
|||
self.assertEqual(s.indices(15), t.indices(15))
|
||||
self.assertNotEqual(id(s), id(t))
|
||||
|
||||
def test_cycle(self):
|
||||
class myobj(): pass
|
||||
o = myobj()
|
||||
o.s = slice(o)
|
||||
w = weakref.ref(o)
|
||||
o = None
|
||||
test_support.gc_collect()
|
||||
self.assertIsNone(w())
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -10,6 +10,8 @@ Release date: tba
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #26659: Make the builtin slice type support cycle collection.
|
||||
|
||||
- Issue #26718: super.__init__ no longer leaks memory if called multiple times.
|
||||
NOTE: A direct call of super.__init__ is not endorsed!
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
|
|||
slice_cache = NULL;
|
||||
_Py_NewReference((PyObject *)obj);
|
||||
} else {
|
||||
obj = PyObject_New(PySliceObject, &PySlice_Type);
|
||||
obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
|
|||
obj->start = start;
|
||||
obj->stop = stop;
|
||||
|
||||
_PyObject_GC_TRACK(obj);
|
||||
return (PyObject *) obj;
|
||||
}
|
||||
|
||||
|
@ -288,13 +289,14 @@ Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).");
|
|||
static void
|
||||
slice_dealloc(PySliceObject *r)
|
||||
{
|
||||
_PyObject_GC_UNTRACK(r);
|
||||
Py_DECREF(r->step);
|
||||
Py_DECREF(r->start);
|
||||
Py_DECREF(r->stop);
|
||||
if (slice_cache == NULL)
|
||||
slice_cache = r;
|
||||
else
|
||||
PyObject_Del(r);
|
||||
PyObject_GC_Del(r);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -586,6 +588,15 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
|
|||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
slice_traverse(PySliceObject *v, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(v->start);
|
||||
Py_VISIT(v->stop);
|
||||
Py_VISIT(v->step);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyTypeObject PySlice_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"slice", /* Name of this type */
|
||||
|
@ -606,9 +617,9 @@ PyTypeObject PySlice_Type = {
|
|||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||
slice_doc, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
(traverseproc)slice_traverse, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
slice_richcompare, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
|
|
Loading…
Reference in New Issue