From f749902260ee27028f13a17223c2dad096dfde8e Mon Sep 17 00:00:00 2001 From: dalthviz <16781833+dalthviz@users.noreply.github.com> Date: Tue, 24 Oct 2023 18:06:19 -0500 Subject: [PATCH 1/2] Config: Prevent errors when removing nested options values --- spyder/config/manager.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/spyder/config/manager.py b/spyder/config/manager.py index b2ce0c70af4..8cc024c3419 100644 --- a/spyder/config/manager.py +++ b/spyder/config/manager.py @@ -560,17 +560,28 @@ def remove_option(self, section, option): """Remove `option` from `section`.""" config = self.get_active_conf(section) if isinstance(option, tuple): + # The actual option saved in the config base_option = option[0] + # Keys of the nested dicts where the option to remove is contained intermediate_options = option[1:-1] + # Key of the option to remove last_option = option[-1] + # Get config value (which is a dictionary) base_conf = self.get(section, base_option) + # Get reference to the actual dictionary containing the option + # that needs to be removed conf_ptr = base_conf for opt in intermediate_options: conf_ptr = conf_ptr[opt] - conf_ptr.pop(last_option) - self.set(section, base_option) - self.notify_observers(section, base_option) + # Remove option and set updated config values for the actual option + # while checking that the option to be removed is actually a value + # available in the config. + # See spyder-ide/spyder#21161 + if last_option in conf_ptr: + conf_ptr.pop(last_option) + self.set(section, base_option, base_conf) + self.notify_observers(section, base_option) else: config.remove_option(section, option) From 13d92ae0f2678f2e491c781b71a35738c01cc174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Althviz=20Mor=C3=A9?= <16781833+dalthviz@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:50:35 -0500 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Carlos Cordoba --- spyder/config/manager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spyder/config/manager.py b/spyder/config/manager.py index 8cc024c3419..38df31149a5 100644 --- a/spyder/config/manager.py +++ b/spyder/config/manager.py @@ -562,18 +562,22 @@ def remove_option(self, section, option): if isinstance(option, tuple): # The actual option saved in the config base_option = option[0] + # Keys of the nested dicts where the option to remove is contained intermediate_options = option[1:-1] + # Key of the option to remove last_option = option[-1] # Get config value (which is a dictionary) base_conf = self.get(section, base_option) + # Get reference to the actual dictionary containing the option # that needs to be removed conf_ptr = base_conf for opt in intermediate_options: conf_ptr = conf_ptr[opt] + # Remove option and set updated config values for the actual option # while checking that the option to be removed is actually a value # available in the config.