Skip to content

Commit 3bc77ee

Browse files
committed
Revert "bpo-40217: Ensure Py_VISIT(Py_TYPE(self)) is always called for PyType_FromSpec types (GH-19414)"
This reverts commit 0169d30.
1 parent 6fad3e6 commit 3bc77ee

File tree

1 file changed

+1
-91
lines changed

1 file changed

+1
-91
lines changed

Objects/typeobject.c

Lines changed: 1 addition & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,42 +1039,6 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
10391039
return obj;
10401040
}
10411041

1042-
PyObject *
1043-
PyType_FromSpec_Alloc(PyTypeObject *type, Py_ssize_t nitems)
1044-
{
1045-
PyObject *obj;
1046-
const size_t size = _Py_SIZE_ROUND_UP(
1047-
_PyObject_VAR_SIZE(type, nitems+1) + sizeof(traverseproc),
1048-
SIZEOF_VOID_P);
1049-
/* note that we need to add one, for the sentinel and space for the
1050-
provided tp-traverse: See bpo-40217 for more details */
1051-
1052-
if (PyType_IS_GC(type)) {
1053-
obj = _PyObject_GC_Malloc(size);
1054-
}
1055-
else {
1056-
obj = (PyObject *)PyObject_MALLOC(size);
1057-
}
1058-
1059-
if (obj == NULL) {
1060-
return PyErr_NoMemory();
1061-
}
1062-
1063-
memset(obj, '\0', size);
1064-
1065-
if (type->tp_itemsize == 0) {
1066-
(void)PyObject_INIT(obj, type);
1067-
}
1068-
else {
1069-
(void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
1070-
}
1071-
1072-
if (PyType_IS_GC(type)) {
1073-
_PyObject_GC_TRACK(obj);
1074-
}
1075-
return obj;
1076-
}
1077-
10781042
PyObject *
10791043
PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
10801044
{
@@ -2910,36 +2874,6 @@ static const short slotoffsets[] = {
29102874
#include "typeslots.inc"
29112875
};
29122876

2913-
static int
2914-
PyType_FromSpec_tp_traverse(PyObject *self, visitproc visit, void *arg)
2915-
{
2916-
PyTypeObject *parent = Py_TYPE(self);
2917-
2918-
// Only a instance of a type that is directly created by
2919-
// PyType_FromSpec (not subclasses) must visit its parent.
2920-
if (parent->tp_traverse == PyType_FromSpec_tp_traverse) {
2921-
Py_VISIT(parent);
2922-
}
2923-
2924-
// Search for the original type that was created using PyType_FromSpec
2925-
PyTypeObject *base;
2926-
base = parent;
2927-
while (base->tp_traverse != PyType_FromSpec_tp_traverse) {
2928-
base = base->tp_base;
2929-
assert(base);
2930-
}
2931-
2932-
// Extract the user defined traverse function that we placed at the end
2933-
// of the type and call it.
2934-
size_t size = Py_SIZE(base);
2935-
size_t _offset = _PyObject_VAR_SIZE(&PyType_Type, size+1);
2936-
traverseproc fun = *(traverseproc*)((char*)base + _offset);
2937-
if (fun == NULL) {
2938-
return 0;
2939-
}
2940-
return fun(self, visit, arg);
2941-
}
2942-
29432877
PyObject *
29442878
PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
29452879
{
@@ -2985,7 +2919,7 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
29852919
}
29862920
}
29872921

2988-
res = (PyHeapTypeObject*)PyType_FromSpec_Alloc(&PyType_Type, nmembers);
2922+
res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, nmembers);
29892923
if (res == NULL)
29902924
return NULL;
29912925
res_start = (char*)res;
@@ -3093,30 +3027,6 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
30933027
memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len);
30943028
type->tp_members = PyHeapType_GET_MEMBERS(res);
30953029
}
3096-
else if (slot->slot == Py_tp_traverse) {
3097-
3098-
/* Types created by PyType_FromSpec own a strong reference to their
3099-
* type, but this was added in Python 3.8. The tp_traverse function
3100-
* needs to call Py_VISIT on the type but all existing traverse
3101-
* functions cannot be updated (especially the ones from existing user
3102-
* functions) so we need to provide a tp_traverse that manually calls
3103-
* Py_VISIT(Py_TYPE(self)) and then call the provided tp_traverse. In
3104-
* this way, user functions do not need to be updated, preserve
3105-
* backwards compatibility.
3106-
*
3107-
* We store the user-provided traverse function at the end of the type
3108-
* (we have allocated space for it) so we can call it from our
3109-
* PyType_FromSpec_tp_traverse wrapper.
3110-
*
3111-
* Check bpo-40217 for more information and rationale about this issue.
3112-
*
3113-
* */
3114-
3115-
type->tp_traverse = PyType_FromSpec_tp_traverse;
3116-
size_t _offset = _PyObject_VAR_SIZE(&PyType_Type, nmembers+1);
3117-
traverseproc *user_traverse = (traverseproc*)((char*)type + _offset);
3118-
*user_traverse = slot->pfunc;
3119-
}
31203030
else {
31213031
/* Copy other slots directly */
31223032
*(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc;

0 commit comments

Comments
 (0)