Skip to content

Commit

Permalink
Cope with Python 3.13 moving pathlib's implementation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
PeterJCLaw committed Jul 2, 2024
1 parent d543d1d commit 2551863
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion jedi/_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 2551863

Please sign in to comment.