diff --git a/Lib/pickle.py b/Lib/pickle.py index 3e7cf25cb05337..bb4e002a746432 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -1349,12 +1349,19 @@ def load(self): if not key: raise EOFError assert isinstance(key, bytes_types) - dispatch[key[0]](self) + try: + func = dispatch[key[0]] + except KeyError: + raise UnpicklingError( + f"invalid load key, '\\x{key[0]:02x}'.") + func(self) except _Stop as stopinst: return stopinst.value # Return a list of items pushed in the stack after last MARK instruction. def pop_mark(self): + if not self.metastack: + raise UnpicklingError("could not find MARK") items = self.stack self.stack = self.metastack.pop() self.append = self.stack.append diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 48375cf459ea0b..c21a27c8473c2a 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -55,7 +55,7 @@ class PyPickleTests(AbstractPickleModuleTests, unittest.TestCase): class PyUnpicklerTests(AbstractUnpickleTests, unittest.TestCase): unpickler = pickle._Unpickler - bad_stack_errors = (IndexError,) + bad_stack_errors = (pickle.UnpicklingError, IndexError) truncated_errors = (pickle.UnpicklingError, EOFError, AttributeError, ValueError, struct.error, IndexError, ImportError) diff --git a/Misc/NEWS.d/next/Library/2025-11-19-15-23-30.gh-issue-141749.QRBf7O.rst b/Misc/NEWS.d/next/Library/2025-11-19-15-23-30.gh-issue-141749.QRBf7O.rst new file mode 100644 index 00000000000000..44dbb087dd8777 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-11-19-15-23-30.gh-issue-141749.QRBf7O.rst @@ -0,0 +1,3 @@ +:mod:`pickle`: align exceptions raised by the pure Python implementation of :func:`pickle.load` +with the C implementation. Previous cases raising :exc:`KeyError` or :exc:`IndexError` +now raise :exc:`~pickle.UnpicklingError`. Patch by Djoume Salvetti.