Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-154002: Do not wrap a constructor TypeError in pickle._Unpickler - #154003

Merged
serhiy-storchaka merged 3 commits into
python:mainfrom
fedonman:fix-gh-154002-pickle-instantiate-chaining
Aug 16, 2026
Merged

gh-154002: Do not wrap a constructor TypeError in pickle._Unpickler#154003
serhiy-storchaka merged 3 commits into
python:mainfrom
fedonman:fix-gh-154002-pickle-instantiate-chaining

Conversation

@fedonman

@fedonman fedonman commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

_instantiate wrapped a constructor TypeError in a new one, passing the traceback as a second argument, so the traceback object ended up in args and there was no chaining.

The wrapper is now gone and the original error propagates. Its purpose (743d17e, 1998) was to name the class when __getinitargs__ returned something bogus, and the message already carries the class name in that case, so the prefix repeated it:

pure Python: ('in constructor for WrongArgCount: WrongArgCount.__init__() takes 2 positional arguments but 3 were given', <traceback object at 0x762b6376b400>)
pure Python  args types: ['str', 'traceback']  cause=NoneType

The C unpickler never wrapped the error, so this also removes the divergence between the two implementations. Both now give the same result for a bad argument count and for a TypeError raised inside the constructor body.

The test asserts the original error reaches the caller unchanged. It fails on the pure-Python unpickler without this change.

For the record, the traceback-in-args part is not from gh-102799 as the issue says. It comes from 26d95c3, where raise T, V, tb became raise T(V, tb) rather than raise T(V).with_traceback(tb). gh-102799 only changed sys.exc_info()[2] to err.__traceback__.

…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.
@fedonman

Copy link
Copy Markdown
Contributor Author

@zware part of EuroPython sprint.

The prefix repeats the class name that the constructor TypeError already
carries, and the C unpickler never wrapped the error, so letting the original
propagate removes the traceback-in-args bug and the divergence at once.
@fedonman fedonman changed the title gh-154002: Fix exception chaining in pickle _Unpickler._instantiate gh-154002: Do not wrap a constructor TypeError in pickle._Unpickler Aug 5, 2026

@serhiy-storchaka serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 👍

@github-project-automation github-project-automation Bot moved this from Todo to In Progress in Sprint Aug 16, 2026
@serhiy-storchaka
serhiy-storchaka merged commit 76ac2de into python:main Aug 16, 2026
54 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Sprint Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants