[Python-checkins] cpython: Issue #23726: Don't enable GC for user subclasses of non-GC types that don't

antoine.pitrou python-checkins at python.org
Mon Apr 13 20:10:12 CEST 2015


https://hg.python.org/cpython/rev/a60b7945ef87
changeset:   95592:a60b7945ef87
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Mon Apr 13 20:10:06 2015 +0200
summary:
  Issue #23726: Don't enable GC for user subclasses of non-GC types that don't add any new fields.
Patch by Eugene Toder.

files:
  Lib/test/test_descr.py |   2 --
  Lib/test/test_gc.py    |  20 ++++++++++++++++++++
  Misc/NEWS              |   3 +++
  Objects/typeobject.c   |   7 ++++---
  4 files changed, 27 insertions(+), 5 deletions(-)


diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -3020,8 +3020,6 @@
         cant(object(), list)
         cant(list(), object)
         class Int(int): __slots__ = []
-        cant(2, Int)
-        cant(Int(), int)
         cant(True, int)
         cant(2, bool)
         o = object()
diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -546,11 +546,31 @@
 
         class UserClass:
             pass
+
+        class UserInt(int):
+            pass
+
+        # Base class is object; no extra fields.
+        class UserClassSlots:
+            __slots__ = ()
+
+        # Base class is fixed size larger than object; no extra fields.
+        class UserFloatSlots(float):
+            __slots__ = ()
+
+        # Base class is variable size; no extra fields.
+        class UserIntSlots(int):
+            __slots__ = ()
+
         self.assertTrue(gc.is_tracked(gc))
         self.assertTrue(gc.is_tracked(UserClass))
         self.assertTrue(gc.is_tracked(UserClass()))
+        self.assertTrue(gc.is_tracked(UserInt()))
         self.assertTrue(gc.is_tracked([]))
         self.assertTrue(gc.is_tracked(set()))
+        self.assertFalse(gc.is_tracked(UserClassSlots()))
+        self.assertFalse(gc.is_tracked(UserFloatSlots()))
+        self.assertFalse(gc.is_tracked(UserIntSlots()))
 
     def test_bug1055820b(self):
         # Corresponds to temp2b.py in the bug report.
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #23726: Don't enable GC for user subclasses of non-GC types that
+  don't add any new fields.  Patch by Eugene Toder.
+
 - Issue #23309: Avoid a deadlock at shutdown if a daemon thread is aborted
   while it is holding a lock to a buffered I/O object, and the main thread
   tries to use the same I/O object (typically stdout or stderr).  A fatal
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2645,9 +2645,10 @@
     }
     type->tp_dealloc = subtype_dealloc;
 
-    /* Enable GC unless there are really no instance variables possible */
-    if (!(type->tp_basicsize == sizeof(PyObject) &&
-          type->tp_itemsize == 0))
+    /* Enable GC unless this class is not adding new instance variables and
+       the base class did not use GC. */
+    if ((base->tp_flags & Py_TPFLAGS_HAVE_GC) ||
+        type->tp_basicsize > base->tp_basicsize)
         type->tp_flags |= Py_TPFLAGS_HAVE_GC;
 
     /* Always override allocation strategy to use regular heap */

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


More information about the Python-checkins mailing list