Generate __reduce__ for auto_exc classes so kw_only exceptions pickle#1595
Open
Jayashanker-Padishala wants to merge 2 commits into
Open
Generate __reduce__ for auto_exc classes so kw_only exceptions pickle#1595Jayashanker-Padishala wants to merge 2 commits into
Jayashanker-Padishala wants to merge 2 commits into
Conversation
BaseException.__reduce__ re-creates an exception by calling cls(*self.args), which fails when __init__ cannot accept the args positionally (e.g. kw_only fields) and loses state __init__ does not reproduce. Generate a dedicated __reduce__ for exceptions that re-creates the instance with BaseException.__new__ (setting args without calling __init__) and restores attribute state: slots classes go through their generated frozen-safe __setstate__, dict classes apply state inside the reconstructor because default state application can go through setattr, which frozen classes reject. Fixes python-attrs#734
ada33-arch
approved these changes
Jul 24, 2026
ada33-arch
approved these changes
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #734
Summary
BaseException.__reduce__re-creates an exception by callingcls(*self.args)— that fails when__init__can't accept the args positionally (kw_onlyfields) and silently loses any state__init__doesn't reproduce.Following the direction in the issue (a dedicated
__reduce__when we detect an exception), but addressing @meshy's counterexample —(cls, (), state)breaks for subclasses with required fields becausecls()still calls__init__:BaseException.__new__(cls, *args)via a module-level reconstructor:argsis set without__init__ever running, so signatures don't matter and validators/converters don't re-run on unpickle.__setstate__(frozen-safe viaobject.__setattr__); the generated__reduce__tolerates attributes that were never set (init=False, no default).__dict__state inside the reconstructor, because the default pickle state application can go throughsetattr, which frozen classes reject; this also preserves non-attrs instance attributes, matching classic exception pickling.__reduce__on the class is respected (not overwritten).Tests
New tests in
tests/test_functional.py: kw_only round-trip across dict/slots × plain/frozen and all pickle protocols ≥2; subclass-with-required-positional round-trip; unset-attribute (init=False) pickling + deepcopy; user__reduce__respected. Full suite: 1412 passed.Changelog fragment included (named
1567.change.md— happy to rename to the actual PR number).