]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-37012: Clean up special cases in PyType_FromSpecWithBases slot assignments (GH...
authorPetr Viktorin <encukou@gmail.com>
Sun, 2 Jun 2019 23:31:12 +0000 (01:31 +0200)
committerGitHub <noreply@github.com>
Sun, 2 Jun 2019 23:31:12 +0000 (01:31 +0200)
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

Objects/typeobject.c

index 76e06aa31d641a95844dd5c9053648fa9d786fe4..beb0ddd82400145f171b7a963caa7ae7b512d180 100644 (file)
@@ -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.