Hi Marc,

Yes, check out this from the 3.9 what's new document:

https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-c-api

Instances of heap-allocated types (such as those created with PyType_FromSpec() and similar APIs) hold a reference to their type object since Python 3.8. As indicated in the “Changes in the C API” of Python 3.8, for the vast majority of cases, there should be no side effect but for types that have a custom tp_traverse function, ensure that all custom tp_traverse functions of heap-allocated types visit the object’s type.

Example:

int
foo_traverse(foo_struct *self, visitproc visit, void *arg) {
// Rest of the traverse function
#if PY_VERSION_HEX >= 0x03090000
    // This was not needed before Python 3.9 (Python issue 35810 and 40217)
    Py_VISIT(Py_TYPE(self));
#endif
}
If your traverse function delegates to tp_traverse of its base class (or another type), ensure that Py_TYPE(self) is visited only once. Note that only heap types are expected to visit the type in tp_traverse.

For example, if your tp_traverse function includes:

base->tp_traverse(self, visit, arg)
then add:

#if PY_VERSION_HEX >= 0x03090000
    // This was not needed before Python 3.9 (Python issue 35810 and 40217)
    if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
        // a heap type's tp_traverse already visited Py_TYPE(self)
    } else {
        Py_VISIT(Py_TYPE(self));
    }
#else
(See bpo-35810 and bpo-40217 for more information.)

Regards from sunny London,
Pablo

On Thu, 27 May 2021, 16:36 Marc-Andre Lemburg, <mal@egenix.com> wrote:
Hi Pablo,

could you or Erlend please explain why types which don't reference
any other objects need to participate in GC for deallocation ?

Many PRs or checked in patches only do this:

+static int
+ucd_traverse(PreviousDBVersion *self, visitproc visit, void *arg)
+{
+    Py_VISIT(Py_TYPE(self));
+    return 0;
+}
+

AFAIK (but could be wrong, of course), the type object itself
does not reference any other objects related to the object
that is being GCed.

By having (nearly) all stdlib types participate in GC, even ones
which don't reference other objects and cannot be parts of reference
circles, instead of immediately deleting them, we will keep those
objects alive for much longer than necessary, potentially causing a
resource overhead regression.

--
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, May 27 2021)
>>> Python Projects, Coaching and Support ...    https://www.egenix.com/
>>> Python Product Development ...        https://consulting.egenix.com/
________________________________________________________________________

::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               https://www.egenix.com/company/contact/
                     https://www.malemburg.com/