]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-138342: Use a common utility for visiting an object's type (GH-138343)
authorPeter Bierma <zintensitydev@gmail.com>
Mon, 1 Sep 2025 16:20:33 +0000 (12:20 -0400)
committerGitHub <noreply@github.com>
Mon, 1 Sep 2025 16:20:33 +0000 (16:20 +0000)
Add `_PyObject_VisitType` in place of `tp_traverse` functions that only visit the object's type.

24 files changed:
Include/cpython/object.h
Modules/_dbmmodule.c
Modules/_decimal/_decimal.c
Modules/_functoolsmodule.c
Modules/_gdbmmodule.c
Modules/_multiprocessing/semaphore.c
Modules/_pickle.c
Modules/_sqlite/prepare_protocol.c
Modules/_sqlite/statement.c
Modules/_ssl.c
Modules/_threadmodule.c
Modules/arraymodule.c
Modules/blake2module.c
Modules/hmacmodule.c
Modules/md5module.c
Modules/mmapmodule.c
Modules/sha1module.c
Modules/sha2module.c
Modules/sha3module.c
Modules/socketmodule.c
Modules/unicodedata.c
Objects/object.c
Objects/typevarobject.c
PC/winreg.c

index 973d358ed8e4ec7c66c578d06869a00b73883a6f..b244c062c7679e7f13c92b1bff690fbca1c58c01 100644 (file)
@@ -491,3 +491,7 @@ PyAPI_FUNC(int) PyUnstable_TryIncRef(PyObject *);
 PyAPI_FUNC(void) PyUnstable_EnableTryIncRef(PyObject *);
 
 PyAPI_FUNC(int) PyUnstable_Object_IsUniquelyReferenced(PyObject *);
+
+/* Utility for the tp_traverse slot of mutable heap types that have no other
+ * references. */
+PyAPI_FUNC(int) _PyObject_VisitType(PyObject *op, visitproc visit, void *arg);
index 0cd0f043de453d66cd67d1d93f784bcab9600b09..17aca2f00a13c0232e4878ebab6441857d276286 100644 (file)
@@ -96,12 +96,6 @@ newdbmobject(_dbm_state *state, const char *file, int flags, int mode)
 }
 
 /* Methods */
-static int
-dbm_traverse(PyObject *dp, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(dp));
-    return 0;
-}
 
 static void
 dbm_dealloc(PyObject *self)
@@ -540,7 +534,7 @@ static PyMethodDef dbm_methods[] = {
 
 static PyType_Slot dbmtype_spec_slots[] = {
     {Py_tp_dealloc, dbm_dealloc},
-    {Py_tp_traverse, dbm_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_methods, dbm_methods},
     {Py_sq_contains, dbm_contains},
     {Py_mp_length, dbm_length},
index de7200af8c158b1812777f105379336c3056c6e1..50994be2968d35b6b72ec2bdbe935fda2f9b5380 100644 (file)
@@ -746,13 +746,6 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
     return 0;
 }
 
-static int
-signaldict_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static void
 signaldict_dealloc(PyObject *self)
 {
@@ -845,7 +838,7 @@ static PyMethodDef signaldict_methods[] = {
 
 static PyType_Slot signaldict_slots[] = {
     {Py_tp_dealloc, signaldict_dealloc},
-    {Py_tp_traverse, signaldict_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_repr, signaldict_repr},
     {Py_tp_hash, PyObject_HashNotImplemented},
     {Py_tp_getattro, PyObject_GenericGetAttr},
@@ -2194,13 +2187,6 @@ PyDecType_New(decimal_state *state, PyTypeObject *type)
 }
 #define dec_alloc(st) PyDecType_New(st, (st)->PyDec_Type)
 
-static int
-dec_traverse(PyObject *dec, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(dec));
-    return 0;
-}
-
 static void
 dec_dealloc(PyObject *dec)
 {
@@ -6032,7 +6018,7 @@ static PyType_Slot dec_slots[] = {
     {Py_tp_token, Py_TP_USE_SPEC},
     {Py_tp_dealloc, dec_dealloc},
     {Py_tp_getattro, PyObject_GenericGetAttr},
-    {Py_tp_traverse, dec_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_repr, dec_repr},
     {Py_tp_hash, dec_hash},
     {Py_tp_str, dec_str},
index f077a0ed329516152fa756f6a2e60813fb64de2b..257d5c6d53611c16d90ca578176b52b99b9879d5 100644 (file)
@@ -108,20 +108,13 @@ placeholder_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     return placeholder;
 }
 
-static int
-placeholder_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static PyType_Slot placeholder_type_slots[] = {
     {Py_tp_dealloc, placeholder_dealloc},
     {Py_tp_repr, placeholder_repr},
     {Py_tp_doc, (void *)placeholder_doc},
     {Py_tp_methods, placeholder_methods},
     {Py_tp_new, placeholder_new},
-    {Py_tp_traverse, placeholder_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0, 0}
 };
 
index 76072ca60cf6cd853f37b56173ff4e5ed3911062..7bef6ae7f0c43eceda56f238da8e4c73f8781019 100644 (file)
@@ -122,13 +122,6 @@ newgdbmobject(_gdbm_state *state, const char *file, int flags, int mode)
 }
 
 /* Methods */
-static int
-gdbm_traverse(PyObject *op, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(op));
-    return 0;
-}
-
 static void
 gdbm_dealloc(PyObject *op)
 {
@@ -714,7 +707,7 @@ static PyMethodDef gdbm_methods[] = {
 
 static PyType_Slot gdbmtype_spec_slots[] = {
     {Py_tp_dealloc, gdbm_dealloc},
-    {Py_tp_traverse, gdbm_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_methods, gdbm_methods},
     {Py_sq_contains, gdbm_contains},
     {Py_mp_length, gdbm_length},
index a4a2a866ccbfceb2c286a640463a6d3568176e0b..d5a1f27e9ff4ff780e6d9ec5bb212b9ae1ed7168 100644 (file)
@@ -720,13 +720,6 @@ _multiprocessing_SemLock___exit___impl(SemLockObject *self,
     return _multiprocessing_SemLock_release_impl(self);
 }
 
-static int
-semlock_traverse(PyObject *s, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(s));
-    return 0;
-}
-
 /*
  * Semaphore methods
  */
@@ -773,7 +766,7 @@ static PyType_Slot _PyMp_SemLockType_slots[] = {
     {Py_tp_members, semlock_members},
     {Py_tp_alloc, PyType_GenericAlloc},
     {Py_tp_new, _multiprocessing_SemLock},
-    {Py_tp_traverse, semlock_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_free, PyObject_GC_Del},
     {Py_tp_doc, (void *)PyDoc_STR("Semaphore/Mutex type")},
     {0, 0},
index bc06478799345a50951c64ef614aeb5fd306fa24..0774e91039ec41ed6760adc83ab07cb63a7db081 100644 (file)
@@ -413,13 +413,6 @@ typedef struct {
 
 #define Pdata_CAST(op)  ((Pdata *)(op))
 
-static int
-Pdata_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static void
 Pdata_dealloc(PyObject *op)
 {
@@ -437,7 +430,7 @@ Pdata_dealloc(PyObject *op)
 
 static PyType_Slot pdata_slots[] = {
     {Py_tp_dealloc, Pdata_dealloc},
-    {Py_tp_traverse, Pdata_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0, NULL},
 };
 
index 31092417cb480d2a60e11e19dba79bd13ee2f0d1..d7ac09e3947a77ab4b42074155e7024586148bce 100644 (file)
@@ -29,13 +29,6 @@ pysqlite_prepare_protocol_init(PyObject *self, PyObject *args, PyObject *kwargs)
     return 0;
 }
 
-static int
-pysqlite_prepare_protocol_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static void
 pysqlite_prepare_protocol_dealloc(PyObject *self)
 {
@@ -50,7 +43,7 @@ PyDoc_STRVAR(doc, "PEP 246 style object adaption protocol type.");
 static PyType_Slot type_slots[] = {
     {Py_tp_dealloc, pysqlite_prepare_protocol_dealloc},
     {Py_tp_init, pysqlite_prepare_protocol_init},
-    {Py_tp_traverse, pysqlite_prepare_protocol_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_doc, (void *)doc},
     {0, NULL},
 };
index 736e60fd7782876289802fc8c80692d65e31da33..77181104eda10b8bca705559fa968136e72af73b 100644 (file)
@@ -116,13 +116,6 @@ stmt_dealloc(PyObject *op)
     Py_DECREF(tp);
 }
 
-static int
-stmt_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 /*
  * Strip leading whitespace and comments from incoming SQL (null terminated C
  * string) and return a pointer to the first non-whitespace, non-comment
@@ -183,7 +176,7 @@ lstrip_sql(const char *sql)
 
 static PyType_Slot stmt_slots[] = {
     {Py_tp_dealloc, stmt_dealloc},
-    {Py_tp_traverse, stmt_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0, NULL},
 };
 
index 2388bbb3bae631a5ed08951cb881a3d04e7ebbbe..048e640283638b5a6524c903bd4c52824fbb5a75 100644 (file)
@@ -5692,13 +5692,6 @@ _ssl_MemoryBIO_impl(PyTypeObject *type)
     return (PyObject *) self;
 }
 
-static int
-memory_bio_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static void
 memory_bio_dealloc(PyObject *op)
 {
@@ -5869,7 +5862,7 @@ static PyType_Slot PySSLMemoryBIO_slots[] = {
     {Py_tp_getset, memory_bio_getsetlist},
     {Py_tp_new, _ssl_MemoryBIO},
     {Py_tp_dealloc, memory_bio_dealloc},
-    {Py_tp_traverse, memory_bio_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0, 0},
 };
 
index 0a22907375b0dd2d6a5cf67af47a8a65aaaa2501..1a64289ea01fdbe7f4e3d6ffa77b6c9c1cc2fd8a 100644 (file)
@@ -655,13 +655,6 @@ PyThreadHandleObject_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     return (PyObject *)PyThreadHandleObject_new(type);
 }
 
-static int
-PyThreadHandleObject_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static void
 PyThreadHandleObject_dealloc(PyObject *op)
 {
@@ -751,7 +744,7 @@ static PyType_Slot ThreadHandle_Type_slots[] = {
     {Py_tp_dealloc, PyThreadHandleObject_dealloc},
     {Py_tp_repr, PyThreadHandleObject_repr},
     {Py_tp_getset, ThreadHandle_getsetlist},
-    {Py_tp_traverse, PyThreadHandleObject_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_methods, ThreadHandle_methods},
     {Py_tp_new, PyThreadHandleObject_tp_new},
     {0, 0}
@@ -767,13 +760,6 @@ static PyType_Spec ThreadHandle_Type_spec = {
 
 /* Lock objects */
 
-static int
-lock_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static void
 lock_dealloc(PyObject *self)
 {
@@ -1045,7 +1031,7 @@ static PyType_Slot lock_type_slots[] = {
     {Py_tp_repr, lock_repr},
     {Py_tp_doc, (void *)lock_doc},
     {Py_tp_methods, lock_methods},
-    {Py_tp_traverse, lock_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_new, lock_new},
     {0, 0}
 };
@@ -1060,13 +1046,6 @@ static PyType_Spec lock_type_spec = {
 
 /* Recursive lock objects */
 
-static int
-rlock_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static int
 rlock_locked_impl(rlockobject *self)
 {
@@ -1359,7 +1338,7 @@ static PyType_Slot rlock_type_slots[] = {
     {Py_tp_methods, rlock_methods},
     {Py_tp_alloc, PyType_GenericAlloc},
     {Py_tp_new, rlock_new},
-    {Py_tp_traverse, rlock_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0, 0},
 };
 
index 654e9445985d8449ea15b06ee78831f4ee7a76b2..d9ac5b97f8258f6d5eb300945e6224b87e98ea0c 100644 (file)
@@ -714,14 +714,6 @@ ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
 }
 
 /* Methods */
-
-static int
-array_tp_traverse(PyObject *op, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(op));
-    return 0;
-}
-
 static void
 array_dealloc(PyObject *op)
 {
@@ -2968,7 +2960,7 @@ static PyType_Slot array_slots[] = {
     {Py_tp_getset, array_getsets},
     {Py_tp_alloc, PyType_GenericAlloc},
     {Py_tp_new, array_new},
-    {Py_tp_traverse, array_tp_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
 
     /* as sequence */
     {Py_sq_length, array_length},
index 163f238a4268d0cec57dbb59255314775684a8af..4921e8f945ef3794e87b34e9fd5e631da9c6da33 100644 (file)
@@ -1008,17 +1008,10 @@ py_blake2_dealloc(PyObject *self)
     Py_DECREF(type);
 }
 
-static int
-py_blake2_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static PyType_Slot blake2b_type_slots[] = {
     {Py_tp_clear, py_blake2_clear},
     {Py_tp_dealloc, py_blake2_dealloc},
-    {Py_tp_traverse, py_blake2_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_doc, (char *)py_blake2b_new__doc__},
     {Py_tp_methods, py_blake2b_methods},
     {Py_tp_getset, py_blake2b_getsetters},
@@ -1029,7 +1022,7 @@ static PyType_Slot blake2b_type_slots[] = {
 static PyType_Slot blake2s_type_slots[] = {
     {Py_tp_clear, py_blake2_clear},
     {Py_tp_dealloc, py_blake2_dealloc},
-    {Py_tp_traverse, py_blake2_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_doc, (char *)py_blake2s_new__doc__},
     {Py_tp_methods, py_blake2b_methods},
     {Py_tp_getset, py_blake2b_getsetters},
index 680c93a04cac17e308f965e5075028a73e8cec41..b30dda501a0716c0c46d0a57190bf7df704574e9 100644 (file)
@@ -1032,13 +1032,6 @@ HMACObject_dealloc(PyObject *op)
     Py_DECREF(type);
 }
 
-static int
-HMACObject_traverse(PyObject *op, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(op));
-    return 0;
-}
-
 static PyMethodDef HMACObject_methods[] = {
     _HMAC_HMAC_COPY_METHODDEF
     _HMAC_HMAC_UPDATE_METHODDEF
@@ -1060,7 +1053,7 @@ static PyType_Slot HMACObject_Type_slots[] = {
     {Py_tp_getset, HMACObject_getsets},
     {Py_tp_clear, HMACObject_clear},
     {Py_tp_dealloc, HMACObject_dealloc},
-    {Py_tp_traverse, HMACObject_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0, NULL} /* sentinel */
 };
 
index 8b6dd4a8195dfb597c6b9155a3c40b2994cb304c..6b6457427b6b5ea1a1f0e8c4d7abfd20df6686a2 100644 (file)
@@ -82,13 +82,6 @@ newMD5object(MD5State * st)
 }
 
 /* Internal methods for a hash object */
-static int
-MD5_traverse(PyObject *ptr, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(ptr));
-    return 0;
-}
-
 static void
 MD5_dealloc(PyObject *op)
 {
@@ -246,7 +239,7 @@ static PyType_Slot md5_type_slots[] = {
     {Py_tp_dealloc, MD5_dealloc},
     {Py_tp_methods, MD5_methods},
     {Py_tp_getset, MD5_getseters},
-    {Py_tp_traverse, MD5_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0,0}
 };
 
index 0cb4b62d7345505d51779cceea9a3fe529761909..8413ebe668dffe9d438f689bbfd29d3df105e719 100644 (file)
@@ -128,13 +128,6 @@ typedef struct {
 
 #define mmap_object_CAST(op)    ((mmap_object *)(op))
 
-static int
-mmap_object_traverse(PyObject *op, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(op));
-    return 0;
-}
-
 static void
 mmap_object_dealloc(PyObject *op)
 {
@@ -1499,7 +1492,7 @@ static PyType_Slot mmap_object_slots[] = {
     {Py_tp_members, mmap_object_members},
     {Py_tp_getset, mmap_object_getset},
     {Py_tp_getattro, PyObject_GenericGetAttr},
-    {Py_tp_traverse, mmap_object_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
 
     /* as sequence */
     {Py_sq_length, mmap_length},
index faa9dcccc5755bc9f0b487215e7dbe53f46dfabc..d64eb91458cae819b2307790ace3bc52b42ad4d7 100644 (file)
@@ -81,13 +81,6 @@ newSHA1object(SHA1State *st)
 
 
 /* Internal methods for a hash object */
-static int
-SHA1_traverse(PyObject *ptr, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(ptr));
-    return 0;
-}
-
 static void
 SHA1_dealloc(PyObject *op)
 {
@@ -247,7 +240,7 @@ static PyType_Slot sha1_type_slots[] = {
     {Py_tp_dealloc, SHA1_dealloc},
     {Py_tp_methods, SHA1_methods},
     {Py_tp_getset, SHA1_getseters},
-    {Py_tp_traverse, SHA1_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0,0}
 };
 
index 36300ba899fd4444e6647bf5e186a299443e3eb0..66259fe47a0fd35c9a76bd1b050a2b9b7c0f62e7 100644 (file)
@@ -164,14 +164,6 @@ newSHA512object(sha2_state *state)
 }
 
 /* Internal methods for our hash objects. */
-
-static int
-SHA2_traverse(PyObject *ptr, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(ptr));
-    return 0;
-}
-
 static void
 SHA256_dealloc(PyObject *op)
 {
@@ -519,7 +511,7 @@ static PyType_Slot sha256_types_slots[] = {
     {Py_tp_dealloc, SHA256_dealloc},
     {Py_tp_methods, SHA256_methods},
     {Py_tp_getset, SHA256_getseters},
-    {Py_tp_traverse, SHA2_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0,0}
 };
 
@@ -527,7 +519,7 @@ static PyType_Slot sha512_type_slots[] = {
     {Py_tp_dealloc, SHA512_dealloc},
     {Py_tp_methods, SHA512_methods},
     {Py_tp_getset, SHA512_getseters},
-    {Py_tp_traverse, SHA2_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0,0}
 };
 
index 5764556bb680f358bc7a6d6d4d5166e56e7dadc9..de4bf09b8e7e0b6640fbf5c7eb68cb3932f1aefb 100644 (file)
@@ -226,13 +226,6 @@ SHA3_dealloc(PyObject *self)
     Py_DECREF(tp);
 }
 
-static int
-SHA3_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 /* External methods for a hash object */
 
 
@@ -424,7 +417,7 @@ static PyGetSetDef SHA3_getseters[] = {
     static PyType_Slot type_slots_obj[] = { \
         {Py_tp_clear, SHA3_clear}, \
         {Py_tp_dealloc, SHA3_dealloc}, \
-        {Py_tp_traverse, SHA3_traverse}, \
+        {Py_tp_traverse, _PyObject_VisitType}, \
         {Py_tp_doc, (char*)type_doc}, \
         {Py_tp_methods, type_methods}, \
         {Py_tp_getset, type_getseters}, \
index c5b16dc4fe4c5f023f3ad2365fe45b10a30cd681..dc8e08ac3e522eba7dab7fbcac8a4c233edecc88 100644 (file)
@@ -5538,13 +5538,6 @@ sock_finalize(PyObject *self)
     PyErr_SetRaisedException(exc);
 }
 
-static int
-sock_traverse(PyObject *s, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(s));
-    return 0;
-}
-
 static void
 sock_dealloc(PyObject *s)
 {
@@ -5843,7 +5836,7 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
 
 static PyType_Slot sock_slots[] = {
     {Py_tp_dealloc, sock_dealloc},
-    {Py_tp_traverse, sock_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_repr, sock_repr},
     {Py_tp_doc, (void *)sock_doc},
     {Py_tp_methods, sock_methods},
index 2a30030a2a1153e804cdb2622f2bb7b96c00fbd3..41725e5aec16417af23caf7312d67152b99c649e 100644 (file)
@@ -1594,13 +1594,6 @@ static PyMethodDef unicodedata_functions[] = {
     {NULL, NULL}                /* sentinel */
 };
 
-static int
-ucd_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static void
 ucd_dealloc(PyObject *self)
 {
@@ -1612,7 +1605,7 @@ ucd_dealloc(PyObject *self)
 
 static PyType_Slot ucd_type_slots[] = {
     {Py_tp_dealloc, ucd_dealloc},
-    {Py_tp_traverse, ucd_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_getattro, PyObject_GenericGetAttr},
     {Py_tp_methods, unicodedata_functions},
     {Py_tp_members, DB_members},
index fba86e63cd4a11f5c334529a366bb62bcdcd944e..bd3ba02f8eb25543f6e15f10a772e8ebc7b5f9e4 100644 (file)
@@ -3384,3 +3384,13 @@ PyUnstable_Object_IsUniquelyReferenced(PyObject *op)
     assert(op != NULL);
     return _PyObject_IsUniquelyReferenced(op);
 }
+
+int
+_PyObject_VisitType(PyObject *op, visitproc visit, void *arg)
+{
+    assert(op != NULL);
+    PyTypeObject *tp = Py_TYPE(op);
+    _PyObject_ASSERT((PyObject *)tp, PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE));
+    Py_VISIT(tp);
+    return 0;
+}
index cead6e69af545188f10026e5e6f976863277f6f8..522e9fd9c955afea8915543c281b231e09a499e0 100644 (file)
@@ -2304,20 +2304,13 @@ generic_dealloc(PyObject *self)
     Py_DECREF(tp);
 }
 
-static int
-generic_traverse(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static PyType_Slot generic_slots[] = {
     {Py_tp_doc, (void *)generic_doc},
     {Py_tp_methods, generic_methods},
     {Py_tp_dealloc, generic_dealloc},
     {Py_tp_alloc, PyType_GenericAlloc},
     {Py_tp_free, PyObject_GC_Del},
-    {Py_tp_traverse, generic_traverse},
+    {Py_tp_traverse, _PyObject_VisitType},
     {0, NULL},
 };
 
index 05a33006c323269376cc7c04a3e31224b1f0e1bf..9bbacb0f50bd63c88544d147163bb94c50c2d907 100644 (file)
@@ -161,13 +161,6 @@ PyHKEY_deallocFunc(PyObject *ob)
     Py_DECREF(tp);
 }
 
-static int
-PyHKEY_traverseFunc(PyObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(Py_TYPE(self));
-    return 0;
-}
-
 static int
 PyHKEY_boolFunc(PyObject *ob)
 {
@@ -369,7 +362,7 @@ static PyType_Slot pyhkey_type_slots[] = {
     {Py_tp_members, PyHKEY_memberlist},
     {Py_tp_methods, PyHKEY_methods},
     {Py_tp_doc, (char *)PyHKEY_doc},
-    {Py_tp_traverse, PyHKEY_traverseFunc},
+    {Py_tp_traverse, _PyObject_VisitType},
     {Py_tp_hash, PyHKEY_hashFunc},
     {Py_tp_str, PyHKEY_strFunc},