Skip to content

gh-154002: Fix exception chaining in pickle _Unpickler._instantiate#154003

Open
fedonman wants to merge 1 commit into
python:mainfrom
fedonman:fix-gh-154002-pickle-instantiate-chaining
Open

gh-154002: Fix exception chaining in pickle _Unpickler._instantiate#154003
fedonman wants to merge 1 commit into
python:mainfrom
fedonman:fix-gh-154002-pickle-instantiate-chaining

Conversation

@fedonman

@fedonman fedonman commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

When unpickling an old-style instance (the INST and OBJ opcodes) and the class constructor raises TypeError, the pure-Python pickle._Unpickler._instantiate did:

raise TypeError("in constructor for %s: %s" %
                (klass.__name__, str(err)), err.__traceback__)

Passing err.__traceback__ as a second positional argument put the traceback object into the exception's args, so it leaked into str() and there was no real chaining (__cause__ stayed None). This changes it to chain properly and drop the traceback argument:

raise TypeError("in constructor for %s: %s" %
                (klass.__name__, str(err))) from err

It is a leftover from the Python 2 way of carrying a traceback. It was sys.exc_info()[2] until gh-102799 mechanically turned it into err.__traceback__ without noticing the value was being passed as a constructor argument. The C _pickle unpickler does not wrap the error at all, so it is unaffected.

I added a regression test that loads an INST pickle whose constructor raises TypeError and checks that no traceback object ends up in args and that the original error is chained. It runs against both unpickler implementations and fails without the fix.

Fixes #154002.

…iate

When a class constructor raised TypeError during old-style (INST/OBJ)
unpickling, the pure-Python unpickler did
`raise TypeError(msg, err.__traceback__)`, which stored the traceback
object in the exception's args and performed no real chaining
(__cause__ stayed None). Use `raise TypeError(msg) from err` instead.
The C implementation is unaffected; it lets the original error propagate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pickle: pure-Python _Unpickler._instantiate mangles a constructor TypeError (traceback in args, no chaining)

1 participant