Description: Backport the resource tracker message decoding from CPython
 Python 3.14+ sends resource tracker messages as JSON; decode both formats.
Author: Maximiliano Curia <maxy@debian.org>
Bug-Debian: https://bugs.debian.org/1146528
Forwarded: no
Last-Update: 2026-11-06
Index: joblib/joblib/externals/loky/backend/resource_tracker.py
===================================================================
--- joblib.orig/joblib/externals/loky/backend/resource_tracker.py
+++ joblib/joblib/externals/loky/backend/resource_tracker.py
@@ -38,6 +38,8 @@
 # resources once all processes connected to the resource tracker have exited.
 
 
+import base64
+import json
 import os
 import shutil
 import sys
@@ -254,6 +256,30 @@ unregister = _resource_tracker.unregiste
 getfd = _resource_tracker.getfd
 
 
+def _decode_message(line):
+    if line.startswith(b'{'):
+        try:
+            obj = json.loads(line.decode('ascii'))
+        except Exception as e:
+            raise ValueError("malformed resource_tracker message: %r" % (line,)) from e
+
+        cmd = obj["cmd"]
+        rtype = obj["rtype"]
+        b64  = obj.get("base64_name", "")
+
+        if not isinstance(cmd, str) or not isinstance(rtype, str) or not isinstance(b64, str):
+            raise ValueError("malformed resource_tracker fields: %r" % (obj,))
+
+        try:
+            name = base64.urlsafe_b64decode(b64).decode('utf-8', 'surrogateescape')
+        except ValueError as e:
+            raise ValueError("malformed resource_tracker base64_name: %r" % (b64,)) from e
+    else:
+        cmd, rest = line.strip().decode('ascii').split(':', maxsplit=1)
+        name, rtype = rest.rsplit(':', maxsplit=1)
+    return cmd, rtype, name
+
+
 def main(fd, verbose=0):
     """Run resource tracker."""
     if verbose:
@@ -284,14 +310,7 @@ def main(fd, verbose=0):
         with open(fd, "rb") as f:
             for line in f:
                 try:
-                    splitted = line.strip().decode("ascii").split(":")
-                    # name can potentially contain separator symbols (for
-                    # instance folders on Windows)
-                    cmd, name, rtype = (
-                        splitted[0],
-                        ":".join(splitted[1:-1]),
-                        splitted[-1],
-                    )
+                    cmd, rtype, name = _decode_message(line)
 
                     if rtype not in _CLEANUP_FUNCS:
                         raise ValueError(
