From: Federico Caselli Date: Tue, 27 Aug 2024 17:20:44 +0000 (+0200) Subject: Fix memory leak on top-level _ModuleMarker. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ae9e65e1d69100e585f783dfe8f2150388b49f4;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git 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 --- 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 "