[Python-checkins] cpython (2.7): add gc support to slice (closes #26659)

benjamin.peterson python-checkins at python.org
Sat Apr 16 17:54:37 EDT 2016


https://hg.python.org/cpython/rev/879da9400529
changeset:   101020:879da9400529
branch:      2.7
user:        Benjamin Peterson <benjamin at python.org>
date:        Sat Apr 16 14:47:12 2016 -0700
summary:
  add gc support to slice (closes #26659)

files:
  Lib/test/test_slice.py |  13 ++++++++++++-
  Misc/NEWS              |   2 ++
  Objects/sliceobject.c  |  19 +++++++++++++++----
  3 files changed, 29 insertions(+), 5 deletions(-)


diff --git a/Lib/test/test_slice.py b/Lib/test/test_slice.py
--- a/Lib/test/test_slice.py
+++ b/Lib/test/test_slice.py
@@ -1,8 +1,10 @@
 # tests for slice objects; in particular the indices method.
 
 import unittest
+import weakref
+
+from cPickle import loads, dumps
 from test import test_support
-from cPickle import loads, dumps
 
 import sys
 
@@ -128,6 +130,15 @@
             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())
+
 def test_main():
     test_support.run_unittest(SliceTest)
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
 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!
 
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -60,7 +60,7 @@
 PyObject *
 PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
 {
-    PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type);
+    PySliceObject *obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
 
     if (obj == NULL)
         return NULL;
@@ -76,6 +76,7 @@
     obj->start = start;
     obj->stop = stop;
 
+    _PyObject_GC_TRACK(obj);
     return (PyObject *) obj;
 }
 
@@ -219,10 +220,11 @@
 static void
 slice_dealloc(PySliceObject *r)
 {
+    _PyObject_GC_UNTRACK(r);
     Py_DECREF(r->step);
     Py_DECREF(r->start);
     Py_DECREF(r->stop);
-    PyObject_Del(r);
+    PyObject_GC_Del(r);
 }
 
 static PyObject *
@@ -320,6 +322,15 @@
     return -1L;
 }
 
+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 */
@@ -340,9 +351,9 @@
     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 */
     0,                                          /* tp_richcompare */
     0,                                          /* tp_weaklistoffset */

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list