From 4ae9e65e1d69100e585f783dfe8f2150388b49f4 Mon Sep 17 00:00:00 2001 From: Federico Caselli Date: Tue, 27 Aug 2024 19:20:44 +0200 Subject: [PATCH] Fix memory leak on top-level _ModuleMarker. Correctly cleanup the internal top-level module registry when no inner modules or classes are registered into it. Fixes: #11788 Change-Id: I489dd6394dd3f14458379368b8c8f18d5a0bb109 --- doc/build/changelog/unreleased_20/11788.rst | 6 ++++++ lib/sqlalchemy/orm/clsregistry.py | 5 +++-- test/orm/declarative/test_clsregistry.py | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 doc/build/changelog/unreleased_20/11788.rst diff --git a/doc/build/changelog/unreleased_20/11788.rst b/doc/build/changelog/unreleased_20/11788.rst new file mode 100644 index 0000000000..736cbd3370 --- /dev/null +++ b/doc/build/changelog/unreleased_20/11788.rst @@ -0,0 +1,6 @@ +.. change:: + :tags: bug, orm + :tickets: 11788 + + Correctly cleanup the internal top-level module registry when no + inner modules or classes are registered into it. diff --git a/lib/sqlalchemy/orm/clsregistry.py b/lib/sqlalchemy/orm/clsregistry.py index 26113d8b24..382d6aef9b 100644 --- a/lib/sqlalchemy/orm/clsregistry.py +++ b/lib/sqlalchemy/orm/clsregistry.py @@ -287,8 +287,9 @@ class _ModuleMarker(ClsRegistryToken): def _remove_item(self, name: str) -> None: self.contents.pop(name, None) - if not self.contents and self.parent is not None: - self.parent._remove_item(self.name) + if not self.contents: + if self.parent is not None: + self.parent._remove_item(self.name) _registries.discard(self) def resolve_attr(self, key: str) -> Union[_ModNS, Type[Any]]: diff --git a/test/orm/declarative/test_clsregistry.py b/test/orm/declarative/test_clsregistry.py index ffc8528125..0cf775e4d2 100644 --- a/test/orm/declarative/test_clsregistry.py +++ b/test/orm/declarative/test_clsregistry.py @@ -230,7 +230,7 @@ class ClsRegistryTest(fixtures.TestBase): del f2 gc_collect() - eq_(len(clsregistry._registries), 1) + eq_(len(clsregistry._registries), 0) def test_dupe_classes_name_race(self): """test the race condition that the class was garbage " -- 2.47.2