[Python-checkins] bpo-37012: Clean up special cases in PyType_FromSpecWithBases slot assignments (GH-13496)

Petr Viktorin webhook-mailer at python.org
Sun Jun 2 19:31:16 EDT 2019


https://github.com/python/cpython/commit/7f4ae1b2cc60cb69938e7c88793b9e9a2dd36d93
commit: 7f4ae1b2cc60cb69938e7c88793b9e9a2dd36d93
branch: master
author: Petr Viktorin <encukou at gmail.com>
committer: GitHub <noreply at github.com>
date: 2019-06-03T01:31:12+02:00
summary:

bpo-37012: Clean up special cases in PyType_FromSpecWithBases slot assignments (GH-13496)

The main slot assignment loop is now if-else if ladder, making the
control flow clearer.

Based on suggestion by Victor Stinner in:
https://github.com/python/cpython/pull/10304/#issuecomment-491123026

files:
M Objects/typeobject.c

diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 76e06aa31d64..beb0ddd82400 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2941,14 +2941,13 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
             PyErr_SetString(PyExc_RuntimeError, "invalid slot offset");
             goto fail;
         }
-        if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases)
+        else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) {
             /* Processed above */
             continue;
-        *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc;
-
-        /* need to make a copy of the docstring slot, which usually
-           points to a static string literal */
-        if (slot->slot == Py_tp_doc) {
+        }
+        else if (slot->slot == Py_tp_doc) {
+            /* For the docstring slot, which usually points to a static string
+               literal, we need to make a copy */
             const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc);
             size_t len = strlen(old_doc)+1;
             char *tp_doc = PyObject_MALLOC(len);
@@ -2960,13 +2959,16 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
             memcpy(tp_doc, old_doc, len);
             type->tp_doc = tp_doc;
         }
-
-        /* Move the slots to the heap type itself */
-        if (slot->slot == Py_tp_members) {
+        else if (slot->slot == Py_tp_members) {
+            /* Move the slots to the heap type itself */
             size_t len = Py_TYPE(type)->tp_itemsize * nmembers;
             memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len);
             type->tp_members = PyHeapType_GET_MEMBERS(res);
         }
+        else {
+            /* Copy other slots directly */
+            *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc;
+        }
     }
     if (type->tp_dealloc == NULL) {
         /* It's a heap type, so needs the heap types' dealloc.



More information about the Python-checkins mailing list