summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Viktorin <encukou@gmail.com>2019-06-03 01:31:12 +0200
committerGitHub <noreply@github.com>2019-06-03 01:31:12 +0200
commit7f4ae1b2cc60cb69938e7c88793b9e9a2dd36d93 (patch)
treefdbae6e040276df94d9febafd9e1a02ca512ffda
parent0d70227e419ab78c44d81b4ea6ae8aaf769470e6 (diff)
downloadcpython-git-7f4ae1b2cc60cb69938e7c88793b9e9a2dd36d93.tar.gz
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
-rw-r--r--Objects/typeobject.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 76e06aa31d..beb0ddd824 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.