-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-27015: Save kwargs given to exceptions constructor #11580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
remilapeyre
wants to merge
9
commits into
python:main
Choose a base branch
from
remilapeyre:BaseException-does-not-unpickle
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
6a00f21
Save kwargs given to exceptions constructor
12dc912
fix NEWS entry typo and formatting
gpshead 1d12d28
Move CalledProcessError pickling test to test_subprocess
88ba13e
Fix tuple size
9986e86
Create self.kwargs only if accessed
7794862
Fix coding style issues and use Python memory allocator
6c906da
Implement BaseException.__getnewargs_ex__
4657d7e
Use __reduce_ex__ and __getnewargs_ex__
2fc3366
Remove some Refleaks
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix coding style issues and use Python memory allocator
- Loading branch information
There are no files selected for viewing
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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reduce implementation concerns me, as it looks like it will make everything much slower, even for exception instances where
self->kwargs
isn't set.Instead, I'd recommend migrating
BaseException
away from implementing__reduce__
directly, and instead have it implement__getnewargs_ex__
: https://docs.python.org/3/library/pickle.html#object.__getnewargs_ex__That way the pickle machinery will take care of calling
__new__
with the correct arguments, and you wouldn't need to introduce a weird dependency from a core builtin into a standard library module.(That would have potential backwards compatibility implications for subclasses implementing reduce based on the parent class implementation, but the same would hold true for introduce a partial object in place of a direct reference to the class - either way, there'll need to be a note in the Porting section of the What's New guide, and switching to
__get_newargs_ex__
will at least have the virtue of simplifying the code rather than making it more complicated)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to do that, I removed
__reduce__
and added__getnewargs_ex__
to the methods as:but it brocke pickling. Did I miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, found my mistake, using
__getnewargs_ex__
broke pickling for protocols 0 and 1. Is this expected?I don't think this happened when using a partial reference on the the constructor of the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's ok to broke pickling support for protocols 0 and 1 since it was broken for keyword args anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defining
__reduce_ex__
would let you restore the old behaviour for those protocols, but I'm not sure__getnewargs_ex__
will still be called if you do that (we're reaching the limits of my ownpickle
knowledge).@pitrou Do you have any recommendations here? (Context: trying to get
BaseException
to pickle keyword args properly, wanting to use__getnewargs_ex__
for more recent pickle protocols, but wondering how to handle the older protocols that don't use that)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How should I call
object.__reduce_ex__
?It seems to me that calling the builtin super is not done anywhere in the source code but I don't find the right way to do it.
Do I need to call
object___reduce_ex__
directly?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ncoghlan Well, I'm not sure why you wouldn't implement the entire logic in
__reduce_ex__
, instead of also defining__getnewargs_ex__
?Or, rather, you could just define
__getnewargs_ex__
and stop caring about protocols 0 and 1 (which are extremely obsolete by now, so we want to maintain compatibility, but fixing bugs in them is not important).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pitrou I only suggested delegating to
__getnewargs_ex__
because I wasn't sure how to mimic that behaviour from inside a custom__reduce_ex__
implementation.But if
__reduce__
still gets called for protocols 0 and 1 even when__getnewargs_ex__
is defined, then that's even better.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @pitrou @ncoghlan, thanks for you input. I pushed a new commit that implement
__getnewargs_ex__
but it seems that__reduce_ex__
does not check it and call__reduce__
no matter what the protocol is:If I remove the
__reduce__
, then it breaks pickling for protocols 0 and 1:Do I need to define a custom
__reduce_ex__
as well?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dug further and it seems my issue comes from https://github.com/python/cpython/blob/master/Lib/copyreg.py#L66, I will look into the details tomorrow.