From b52d53bfc5d8010d1a8bd4153b1ffe8e449954c2 Mon Sep 17 00:00:00 2001 From: Maximilian Haye Date: Mon, 13 Jan 2025 17:47:49 +0100 Subject: [PATCH] fix(ThreadWorker): don't unload modules without __loader__ DuckDB (and likely other packages) manually add their submodules (e.g. duckdb.duckdb.functional) during side-effects when the "parent" (e.g. duckdb.duckdb) is loaded. Since extension modules can't be reloaded, it is impossible to re-run these side-effects to recreate these modules. This commit preserves modules without the __loader__ attribute (which is added by Python's normal import machinery), sacrificing isolation for compatibility. --- questionpy_server/worker/impl/thread.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/questionpy_server/worker/impl/thread.py b/questionpy_server/worker/impl/thread.py index cf2c086..b541c98 100644 --- a/questionpy_server/worker/impl/thread.py +++ b/questionpy_server/worker/impl/thread.py @@ -51,6 +51,13 @@ def run(self) -> None: sys.path = original_path for module_name in sys.modules.keys() - original_module_names: + if getattr(sys.modules[module_name], "__loader__", None) is None: + log.debug( + "Not unloading '%s', as it doesn't have a '__loader__' attribute and was probably added " + "manually.", + sys.modules[module_name].__name__, + ) + continue # Having reset the path, this forces questionpy and any package modules to be reloaded upon next import. del sys.modules[module_name]