@@ -1039,42 +1039,6 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
1039
1039
return obj ;
1040
1040
}
1041
1041
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
-
1078
1042
PyObject *
1079
1043
PyType_GenericAlloc (PyTypeObject * type , Py_ssize_t nitems )
1080
1044
{
@@ -1164,11 +1128,16 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg)
1164
1128
Py_VISIT (* dictptr );
1165
1129
}
1166
1130
1167
- if (type -> tp_flags & Py_TPFLAGS_HEAPTYPE )
1131
+ if (type -> tp_flags & Py_TPFLAGS_HEAPTYPE
1132
+ && (!basetraverse || !(base -> tp_flags & Py_TPFLAGS_HEAPTYPE ))) {
1168
1133
/* For a heaptype, the instances count as references
1169
1134
to the type. Traverse the type so the collector
1170
- can find cycles involving this link. */
1135
+ can find cycles involving this link.
1136
+ Skip this visit if basetraverse belongs to a heap type: in that
1137
+ case, basetraverse will visit the type when we call it later.
1138
+ */
1171
1139
Py_VISIT (type );
1140
+ }
1172
1141
1173
1142
if (basetraverse )
1174
1143
return basetraverse (self , visit , arg );
@@ -2910,36 +2879,6 @@ static const short slotoffsets[] = {
2910
2879
#include "typeslots.inc"
2911
2880
};
2912
2881
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
-
2943
2882
PyObject *
2944
2883
PyType_FromSpecWithBases (PyType_Spec * spec , PyObject * bases )
2945
2884
{
@@ -2985,7 +2924,7 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
2985
2924
}
2986
2925
}
2987
2926
2988
- res = (PyHeapTypeObject * )PyType_FromSpec_Alloc (& PyType_Type , nmembers );
2927
+ res = (PyHeapTypeObject * )PyType_GenericAlloc (& PyType_Type , nmembers );
2989
2928
if (res == NULL )
2990
2929
return NULL ;
2991
2930
res_start = (char * )res ;
@@ -3093,30 +3032,6 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
3093
3032
memcpy (PyHeapType_GET_MEMBERS (res ), slot -> pfunc , len );
3094
3033
type -> tp_members = PyHeapType_GET_MEMBERS (res );
3095
3034
}
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
- }
3120
3035
else {
3121
3036
/* Copy other slots directly */
3122
3037
* (void * * )(res_start + slotoffsets [slot -> slot ]) = slot -> pfunc ;
0 commit comments