8000 C API: `PyGC_Disable()` not respected · Issue #116604 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content
C API: PyGC_Disable() not respected #116604
Closed
@wjakob

Description

@wjakob

Bug report

Bug description:

The Python C API provides the function PyGC_Disable() to temporarily disable garbage collection. Calling it causes PyGC_Collect() to become a no-op. So far so good.

Unfortunately, CPython >= 3.12 no longer respects this flag beyond direct calls to PyGC_Collect(). Let's consider, for example, the operation PyErr_CheckSignals() at line 1773. This calls _Py_RunGC, which ignores the GC enabled flag. And this indeed happens! In fact, I just spent quite a bit of time debugging an issue where the GC was supposed to be disabled for a brief moment, and yet it runs on Python 3.12. (Whether disabling the GC for a brief period of time is a good design pattern is another discussion. I would like to steer the discussion away from this and focus on documented API behavior.)

The PyErr_CheckSignals() function is called from 135 locations in the CPython codebase including very common ones like PyObject_Str(), so making any fixes in callers of this API does not look feasible.

The flag-ignoring _Py_RunGC() function is only called by two places: besides the mentioned PyErr_CheckSignals(), there is also _Py_HandlePending() in Python/ceval_gil.c.

To restore the documented behavior, I see three options:

  • _Py_RunGC() could be modified to exit immediately if the enabled flag is set to zero.
  • The implementation of _Py_HandlePending() and PyErr_CheckSignals() could be modified to check PyGC_IsEnabled() before calling _Py_RunGC().
  • Something is setting _PY_GC_SCHEDULED_BIT, and that causes the implementation to enter _Py_RunGC(). I'm not really sure about how that works, but perhaps this flag could be cleared in PyGC_Disable(), and Python could then avoid setting the flag.

(Tagging @pablogsal and @swtaarrs, who commited changes to the relevant code.)

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0