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.
|
# tests for slice objects; in particular the indices method.
|
||||||
|
|
||||||
import unittest
|
|
||||||
from pickle import loads, dumps
|
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import operator
|
import operator
|
||||||
import sys
|
import sys
|
||||||
|
import unittest
|
||||||
|
import weakref
|
||||||
|
|
||||||
|
from pickle import loads, dumps
|
||||||
|
from test import support
|
||||||
|
|
||||||
|
|
||||||
def evaluate_slice_index(arg):
|
def evaluate_slice_index(arg):
|
||||||
@ -240,5 +242,14 @@ class SliceTest(unittest.TestCase):
|
|||||||
self.assertEqual(s.indices(15), t.indices(15))
|
self.assertEqual(s.indices(15), t.indices(15))
|
||||||
self.assertNotEqual(id(s), id(t))
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -10,6 +10,8 @@ Release date: tba
|
|||||||
Core and Builtins
|
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.
|
- Issue #26718: super.__init__ no longer leaks memory if called multiple times.
|
||||||
NOTE: A direct call of super.__init__ is not endorsed!
|
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;
|
slice_cache = NULL;
|
||||||
_Py_NewReference((PyObject *)obj);
|
_Py_NewReference((PyObject *)obj);
|
||||||
} else {
|
} else {
|
||||||
obj = PyObject_New(PySliceObject, &PySlice_Type);
|
obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -135,6 +135,7 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
|
|||||||
obj->start = start;
|
obj->start = start;
|
||||||
obj->stop = stop;
|
obj->stop = stop;
|
||||||
|
|
||||||
|
_PyObject_GC_TRACK(obj);
|
||||||
return (PyObject *) 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
|
static void
|
||||||
slice_dealloc(PySliceObject *r)
|
slice_dealloc(PySliceObject *r)
|
||||||
{
|
{
|
||||||
|
_PyObject_GC_UNTRACK(r);
|
||||||
Py_DECREF(r->step);
|
Py_DECREF(r->step);
|
||||||
Py_DECREF(r->start);
|
Py_DECREF(r->start);
|
||||||
Py_DECREF(r->stop);
|
Py_DECREF(r->stop);
|
||||||
if (slice_cache == NULL)
|
if (slice_cache == NULL)
|
||||||
slice_cache = r;
|
slice_cache = r;
|
||||||
else
|
else
|
||||||
PyObject_Del(r);
|
PyObject_GC_Del(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
@ -586,6 +588,15 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
|
|||||||
return res;
|
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 = {
|
PyTypeObject PySlice_Type = {
|
||||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||||
"slice", /* Name of this type */
|
"slice", /* Name of this type */
|
||||||
@ -606,9 +617,9 @@ PyTypeObject PySlice_Type = {
|
|||||||
PyObject_GenericGetAttr, /* tp_getattro */
|
PyObject_GenericGetAttr, /* tp_getattro */
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||||
slice_doc, /* tp_doc */
|
slice_doc, /* tp_doc */
|
||||||
0, /* tp_traverse */
|
(traverseproc)slice_traverse, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
slice_richcompare, /* tp_richcompare */
|
slice_richcompare, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user