From 860406e2a37f4b99972800b36b8854f092193e53 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Sat, 15 Jul 2023 22:07:13 +0100 Subject: [PATCH] Fix garbage collection issue in ConfigManager Instances of the python configparser are not removed by the garbage collector unless some internal objects are deleted first. This is not an issue on the first run where we load the main Gramps ini file, but on subsequent runs there are uncollected objects after loading the view configuration files. This fix is not ideal because it accesses protected attributes of the configparser. --- gramps/gen/utils/configmanager.py | 10 ++++++++++ gramps/gui/widgets/grampletbar.py | 2 ++ gramps/gui/widgets/grampletpane.py | 2 ++ 3 files changed, 14 insertions(+) diff --git a/gramps/gen/utils/configmanager.py b/gramps/gen/utils/configmanager.py index 134771c6b..ac7a67dc9 100644 --- a/gramps/gen/utils/configmanager.py +++ b/gramps/gen/utils/configmanager.py @@ -47,6 +47,14 @@ from ..const import GRAMPS_LOCALE as glocale _ = glocale.translation.gettext +def clean_up(parser): + # Needed so that the parser can be removed by the garabge collection + for section in parser: + delattr(parser._proxies[section], 'getboolean') + delattr(parser._proxies[section], 'getint') + delattr(parser._proxies[section], 'getfloat') + del parser._proxies[section] + del parser._converters def safe_eval(exp): # restrict eval to empty environment @@ -287,6 +295,8 @@ class ConfigManager: self.data[name] = {} loader(section, parser) + clean_up(parser) + def _load_section(self, section, parser): """ Load a section of an .ini file into self.data diff --git a/gramps/gui/widgets/grampletbar.py b/gramps/gui/widgets/grampletbar.py index 5edefd495..c53362097 100644 --- a/gramps/gui/widgets/grampletbar.py +++ b/gramps/gui/widgets/grampletbar.py @@ -58,6 +58,7 @@ _ = glocale.translation.gettext from gramps.gen.const import URL_MANUAL_PAGE, URL_WIKISTRING, VERSION_DIR from gramps.gen.config import config from gramps.gen.constfunc import win +from gramps.gen.utils.configmanager import clean_up from ..managedwindow import ManagedWindow from ..display import display_help, display_url from .grampletpane import (AVAILABLE_GRAMPLETS, @@ -210,6 +211,7 @@ class GrampletBar(Gtk.Notebook): data["name"] = "Unnamed Gramplet" data["tname"] = _("Unnamed Gramplet") retval.append(data) + clean_up(cp) else: # give defaults as currently known for name in defaults: diff --git a/gramps/gui/widgets/grampletpane.py b/gramps/gui/widgets/grampletpane.py index 61dd7e7be..26e45585f 100644 --- a/gramps/gui/widgets/grampletpane.py +++ b/gramps/gui/widgets/grampletpane.py @@ -47,6 +47,7 @@ LOG = logging.getLogger(".") #------------------------------------------------------------------------- from gramps.gen.errors import WindowActiveError from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR, COLON +from gramps.gen.utils.configmanager import clean_up from ..editors import EditPerson, EditFamily from ..managedwindow import ManagedWindow from ..utils import is_right_click, match_primary_mask, get_link_color @@ -1194,6 +1195,7 @@ class GrampletPane(Gtk.ScrolledWindow): data["name"] = "Unnamed Gramplet" data["tname"] = _("Unnamed Gramplet") retval.append((data["name"], data)) # name, opts + clean_up(cp) else: # give defaults as currently known for name in self.default_gramplets: