X Tutup
The Wayback Machine - https://web.archive.org/web/20250831022649/https://github.com/python/cpython/pull/138266
Skip to content

Conversation

picnixz
Copy link
Member

@picnixz picnixz commented Aug 30, 2025

AFAIU, tp_traverse will not be called if Py_TPFLAGS_HAVE_GC is not specified. Quoting the specs:

Instances of heap-allocated types hold a reference to their type. Their traversal function must therefore either visit Py_TYPE(self), or delegate this responsibility by calling tp_traverse of another heap-allocated type (such as a heap-allocated superclass). If they do not, the type object may not be garbage-collected.

As such, I believe that this is the correct fix (that is, we need tp_traverse to be called).

cc @vstinner

@@ -364,13 +364,16 @@ _bz2_BZ2Compressor_impl(PyTypeObject *type, int compresslevel)
return NULL;
}

// explicit fields initialization as PyObject_GC_New() does not change them
self->flushed = 0;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this to be explicitly initialized otherwise tests fail because flushed would be arbitrary.

@@ -673,10 +679,12 @@ _bz2_BZ2Decompressor_impl(PyTypeObject *type)
if (self->unused_data == NULL)
goto error;

self->bzs = (bz_stream){.opaque = NULL, .bzalloc = NULL, .bzfree = NULL};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this being set, we have a segmentation fault.

@@ -665,6 +669,8 @@ _bz2_BZ2Decompressor_impl(PyTypeObject *type)
return NULL;
}

// explicit fields initialization as PyObject_GC_New() does not change them
self->eof = 0;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this being set by default, tests fail as eof is most likely "true" by default (that's because of the call to PyObject_GC_New which initializes the memory but doesn't zero it).

@picnixz picnixz added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Aug 30, 2025
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @picnixz for commit a8e8501 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F138266%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Aug 30, 2025
@@ -352,7 +352,7 @@ _bz2_BZ2Compressor_impl(PyTypeObject *type, int compresslevel)
}

assert(type != NULL && type->tp_alloc != NULL);
self = (BZ2Compressor *)type->tp_alloc(type, 0);
self = PyObject_GC_New(BZ2Compressor, type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, this seems like introducing additional maintenance for no reason. If a type has Py_TPFLAGS_HAVE_GC set, then tp_alloc will act like PyObject_GC_New anyway, except the data will also be zero-ed (so we wouldn't need the additional change below).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
X Tutup