Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2b601d3

Browse files
committed
add gc support to slice (closes #26659)
1 parent a07ab29 commit 2b601d3

3 files changed

Lines changed: 31 additions & 7 deletions

File tree

Lib/test/test_slice.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# tests for slice objects; in particular the indices method.
22

3-
import unittest
4-
from pickle import loads, dumps
5-
63
import itertools
74
import operator
85
import sys
6+
import unittest
7+
import weakref
8+
9+
from pickle import loads, dumps
10+
from test import support
911

1012

1113
def evaluate_slice_index(arg):
@@ -240,5 +242,14 @@ def test_pickle(self):
240242
self.assertEqual(s.indices(15), t.indices(15))
241243
self.assertNotEqual(id(s), id(t))
242244

245+
def test_cycle(self):
246+
class myobj(): pass
247+
o = myobj()
248+
o.s = slice(o)
249+
w = weakref.ref(o)
250+
o = None
251+
test_support.gc_collect()
252+
self.assertIsNone(w())
253+
243254
if __name__ == "__main__":
244255
unittest.main()

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Release date: tba
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #26659: Make the builtin slice type support cycle collection.
14+
1315
- Issue #26718: super.__init__ no longer leaks memory if called multiple times.
1416
NOTE: A direct call of super.__init__ is not endorsed!
1517

Objects/sliceobject.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
119119
slice_cache = NULL;
120120
_Py_NewReference((PyObject *)obj);
121121
} else {
122-
obj = PyObject_New(PySliceObject, &PySlice_Type);
122+
obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
123123
if (obj == NULL)
124124
return NULL;
125125
}
@@ -135,6 +135,7 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
135135
obj->start = start;
136136
obj->stop = stop;
137137

138+
_PyObject_GC_TRACK(obj);
138139
return (PyObject *) obj;
139140
}
140141

@@ -288,13 +289,14 @@ Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).");
288289
static void
289290
slice_dealloc(PySliceObject *r)
290291
{
292+
_PyObject_GC_UNTRACK(r);
291293
Py_DECREF(r->step);
292294
Py_DECREF(r->start);
293295
Py_DECREF(r->stop);
294296
if (slice_cache == NULL)
295297
slice_cache = r;
296298
else
297-
PyObject_Del(r);
299+
PyObject_GC_Del(r);
298300
}
299301

300302
static PyObject *
@@ -586,6 +588,15 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
586588
return res;
587589
}
588590

591+
static int
592+
slice_traverse(PySliceObject *v, visitproc visit, void *arg)
593+
{
594+
Py_VISIT(v->start);
595+
Py_VISIT(v->stop);
596+
Py_VISIT(v->step);
597+
return 0;
598+
}
599+
589600
PyTypeObject PySlice_Type = {
590601
PyVarObject_HEAD_INIT(&PyType_Type, 0)
591602
"slice", /* Name of this type */
@@ -606,9 +617,9 @@ PyTypeObject PySlice_Type = {
606617
PyObject_GenericGetAttr, /* tp_getattro */
607618
0, /* tp_setattro */
608619
0, /* tp_as_buffer */
609-
Py_TPFLAGS_DEFAULT, /* tp_flags */
620+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
610621
slice_doc, /* tp_doc */
611-
0, /* tp_traverse */
622+
(traverseproc)slice_traverse, /* tp_traverse */
612623
0, /* tp_clear */
613624
slice_richcompare, /* tp_richcompare */
614625
0, /* tp_weaklistoffset */

0 commit comments

Comments
 (0)