Skip to content

Memory leak when accessing magicgui as a method #732

Description

@Antyos

Describe the bug
I found this while trying to hot-reload a widget (which is probably a bad idea), but this seems like a bug regardless.

Creating an object with a @magicgui decorated method and then accessing that method via .show (even without calling) or .native will prevent the object from being garbage collected.

For example,

from magicgui import magicgui

class F:
    def __init__(self, x: int):
        self.x = x

    @magicgui()
    def func_gui(self, a: int = 1):
        print(a + self.x)

To Reproduce

# /// script
# requires-python = ">=3.13"
# dependencies = [
#     "magicgui",
#     "pyqt6==6.9.1",
# ]
#
# [tool.uv.sources]
# magicgui = { git = "https://github.com/pyapp-kit/magicgui" }
# ///
import gc

from magicgui import magic_factory, magicgui, widgets

class F(widgets.Container):
    def __init__(self, x: int):
        self.x = x
        self.func = self.func_fact()
        super().__init__()

    @magic_factory()
    def func_fact(self, a=1):
        print(a + self.x)

    @magicgui()
    def func_gui(self, a=1):
        print(a + self.x)


def count_instances(cls) -> list:
    return len([obj for obj in gc.get_objects() if isinstance(obj, cls)])


f = F(x=5)
f.func.show  # This is fine
f.func_gui.show  # [BAD] We don't have to call .show() to get the bug, just access
f.func_gui.native  # [BAD] This also breaks it

print(get_instances(F))
### 1

# f.func_gui.native.deleteLater()  # Ironically, calling this also produces the issue
# del f.func_gui  # This raises an AttributeError. Not sure if that's intended.
del f
gc.collect()

print(count_instances(F))
### 1

Expected behavior

Commenting out the f.func_gui lines will print:

1
0

Screenshots
If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

  • OS: Windows, Python 3.13.9
  • backend: PyQt6==6.9.1
  • magicgui version: from main branch

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions