From 255186376e6fd1d3460a0d0541a3dceb436a52b1 Mon Sep 17 00:00:00 2001 From: Peter Law Date: Sat, 29 Jun 2024 16:38:27 +0100 Subject: [PATCH] Cope with Python 3.13 moving pathlib's implementation Jedi passes pickles to subprocesses which are running the target version of Python and thus may not be the same as the version under which Jedi itself is running. In Python 3.13, pathlib is being refactored to allow for easier extension and has thus moved most of its internal implementation to a submodule. Unfortunately this changes the paths of the symbols, causing pickles of those types to fail to load in earlier versions of Python. This commit introduces a custom unpickler which accounts for this move, allowing bi-directional passing of pickles to work. --- jedi/_compatibility.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/jedi/_compatibility.py b/jedi/_compatibility.py index 13a74b7b3..48563d00d 100644 --- a/jedi/_compatibility.py +++ b/jedi/_compatibility.py @@ -5,11 +5,24 @@ import errno import sys import pickle +from typing import Any + + +class Unpickler(pickle.Unpickler): + def find_class(self, module: str, name: str) -> Any: + # Python 3.13 moved pathlib implementation out of __init__.py as part of + # generalising its implementation. Ensure that we support loading + # pickles from 3.13 on older version of Python. Since 3.13 maintained a + # compatible API, pickles from older Python work natively on the newer + # version. + if module == 'pathlib._local': + module = 'pathlib' + return super().find_class(module, name) def pickle_load(file): try: - return pickle.load(file) + return Unpickler(file).load() # Python on Windows don't throw EOF errors for pipes. So reraise them with # the correct type, which is caught upwards. except OSError: