From d0b2f06964a9a7485cb0aa0eae6eed7b459fc8b0 Mon Sep 17 00:00:00 2001 From: Maor Hamami Date: Thu, 26 Mar 2026 16:47:46 +0200 Subject: [PATCH] [windows] fix multiprocess dill issue --- btest | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/btest b/btest index 717bdad..58b94dd 100755 --- a/btest +++ b/btest @@ -65,6 +65,12 @@ DEFAULT_CONFIG_NAME = "btest.cfg" ConfigDefault = os.environ.get("BTEST_CFG", DEFAULT_CONFIG_NAME) +# These regexes have fixed patterns and are used in child processes, so they +# must be module-level constants to survive multiprocess spawn on Windows. +RE_INPUT = re.compile(r"%INPUT") +RE_DIR = re.compile(r"%DIR") +RE_ENV = re.compile(r"\$\{(\w+)}") + def normalize_path(path): """Ensures that paths on Windows convert backslashes to forward slashes, to @@ -440,9 +446,6 @@ class TestManager(mp_managers.SyncManager): mgr_data["Options"] = Options mgr_data["TestBase"] = TestBase mgr_data["TmpDir"] = TmpDir - mgr_data["RE_INPUT"] = RE_INPUT - mgr_data["RE_DIR"] = RE_DIR - mgr_data["RE_ENV"] = RE_ENV output_handler.prepare(self) self._output_handler = output_handler @@ -567,6 +570,15 @@ class TestManager(mp_managers.SyncManager): for global_key, global_value in mgr_data.items(): globals()[global_key] = global_value + # multiprocess/dill may reconstruct this method with its own globals + # dict, separate from the module-level globals used by functions like + # replaceEnvs. Also set globals in __mp_main__, which is where + # multiprocess imports the script in spawned child processes. + mp_main = sys.modules.get("__mp_main__") + if mp_main is not None: + for global_key, global_value in mgr_data.items(): + setattr(mp_main, global_key, global_value) + while True: # Pull the next test from the list that was built at startup. This may # be more than one test if there were alternatives requested in the @@ -3275,9 +3287,6 @@ if __name__ == "__main__": CommandPrefix = getOption("CommandPrefix", "@TEST-") - RE_INPUT = re.compile(r"%INPUT") - RE_DIR = re.compile(r"%DIR") - RE_ENV = re.compile(r"\$\{(\w+)}") RE_PART = re.compile(r"^(.*)#([0-9]+)$") RE_IGNORE = re.compile(CommandPrefix + "IGNORE") RE_START_NEXT_TEST = re.compile(CommandPrefix + "START-NEXT")