Skip to content

[Bug]: macOS backend lacks several autorelease pools #31751

@iccir

Description

@iccir

Bug summary

I'm investigating #31106.

At the time show(PyObject* self) is called, the window in question has a -retainCount of 600+. This is due to AppKit and other macOS frameworks calling [[theWindow retain] autorelease] across several internal methods.

The window is retained and added to the autorelease pool at the top of the stack, which is either the one set up in wait_for_stdin() or in [NSApp run]. In any case, the pool has never been drained by the time show() is called. Even after the user closes the window, the pool has still not been drained.

Generally, if you are calling from non-Objective-C code to Objective-C code, you need to set up an autorelease pool before crossing the boundary and release it after returning. Using an @autoreleasepool block makes this easy; however, it involves touching a lot of C functions inside of _macosx.m.

I'm not experienced with Python extension modules. Is there a way to have Python automatically call a function before and after calling the C function assigned to each PyMethodDef?

Code for reproduction

import matplotlib.pyplot as plt

for i in range(0, 4):
    plt.subplots()

plt.show()

Actual outcome

Each NSWindow still has a retain count of 600+ after closing.

Expected outcome

Each NSWindow hits a retain count of 0 on close and -dealloc is called.

Additional information

No response

Operating system

No response

Matplotlib Version

0.2.0.dev54528+unknown.gf4cf12592.d20260526

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions