Control: severity -1 minor Control: retitle -1 Improve resolution of conflicting plugins Control: tags -1 patch upstream
I have investigated this more. I feel I understand more what the code in PluginManager was trying to do. I discovered that I had a gsettings setting, as follows: $ gsettings get org.blueman.general plugin-list ['!TransferService', '!PPPSupport', '!GameControllerWakelock', 'AuthAgent', 'DhcpClient', 'Networking', 'NetUsage', 'SerialManager'] $ This was the root cause of the problem. I didn't set that explicitly. Presumably it was set by some previous version. (My home directory has survived many different Debian releases.) Using `gsettings reset` caused the symptoms to go away in my installation. In my testing I also found that the DhcpClient plugin actually doesn't work when I try to do bluetooth tethering with my Android phone. I didn't investigate the cause any further. The NMPANSupport plugin does work. In the default configuration, the builtin priority mechanism would prefer NMPANSupport, which is good. However, I found the logic in PluginManager confusing and a bit unprincipled. I attach a patch to rationalise it. It may print more warnings now, but it will not crash unless it actually needs to, and the logic is now the same (and, I hope, reasonable) in all cases. Ian.
>From 95e85dfbe10deb90dde98101566886ebd50cc410 Mon Sep 17 00:00:00 2001 From: Ian Jackson <ijack...@chiark.greenend.org.uk> Date: Mon, 3 Feb 2025 12:33:35 +0000 Subject: [PATCH] PluginManager: Rationalise plugin priority/enable/disable Previously, ad-hoc code was used in the two situations in the conflict-checking loop, leading to divergent behaviour. Centralise the calculation of which plugins to prefer. Only throw an exception if conflicting plugins are explicitly enabled. Closes: #1082668 --- blueman/main/PluginManager.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/blueman/main/PluginManager.py b/blueman/main/PluginManager.py index 8b2d1a76..024d8a71 100644 --- a/blueman/main/PluginManager.py +++ b/blueman/main/PluginManager.py @@ -145,16 +145,18 @@ class PluginManager(GObject.GObject, Generic[_T]): for cfl in self.__cfls[cls.__name__]: if cfl in self.__classes: - if self.__classes[cfl].__priority__ > cls.__priority__ and not self.disable_plugin(cfl) \ - and not self.enable_plugin(cls.__name__): - logging.warning(f"Not loading {cls.__name__} because its conflict has higher priority") + prefer_cfl = self.prefer_plugin(self.__classes[cfl], cls) + if prefer_cfl: + logging.warning(f"{prefer_cfl}; not loading {cls.__name__}") return if cfl in self.__loaded: - if cls.__priority__ > self.__classes[cfl].__priority__ and not self.enable_plugin(cfl): - self.unload_plugin(cfl) + prefer_cfl = self.prefer_plugin(self.__classes[cfl], cls) + if prefer_cfl: + logging.warning(f"{prefer_cfl}; not unloading {cfl}") + return else: - raise LoadException(f"Not loading conflicting plugin {cls.__name__} due to lower priority") + self.unload_plugin(cfl) logging.info(f"loading {cls}") inst = cls(self.parent) @@ -173,6 +175,27 @@ class PluginManager(GObject.GObject, Generic[_T]): self.__loaded.append(cls.__name__) self.emit("plugin-loaded", cls.__name__) + def prefer_plugin(self, a, b): + ''' + Returns a string (for the log) explaining why we prefer A to B, or None if we don't + ''' + if self.enable_plugin(a.__name__): + if self.enable_plugin(b.__name__): + raise LoadException(f"Plugins {a.__name__} and {b.__name__} both explicitly enabled, but they conflict") + else: + return f"Preferring {a.__name__} over conflicting {b.__name__} because {a.__name__} is explicitly enabled" + else: + if self.enable_plugin(b.__name__): + return None + + if self.disable_plugin(b.__name__): + return f"Preferring {a.__name__} over conflicting {b.__name__} because {b.__name__} is explicitly disabled" + + if a.__priority__ > b.__priority__: + return f"Preferring {a.__name__} (priority {a.__priority__}) over conflicting {b.__name__} (priority {b.__priority__})" + + return None + def __getattr__(self, key: str) -> object: try: return self._plugins[key] -- 2.47.2
-- Ian Jackson <ijack...@chiark.greenend.org.uk> These opinions are my own. Pronouns: they/he. If I emailed you from @fyvzl.net or @evade.org.uk, that is a private address which bypasses my fierce spamfilter.