-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
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
Closed
remilapeyre
wants to merge
9
commits into
python:main
from
remilapeyre:BaseException-does-not-unpickle
Closed
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->kwargsisn't set.Instead, I'd recommend migrating
BaseExceptionaway 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 ownpickleknowledge).@pitrou Do you have any recommendations here? (Context: trying to get
BaseExceptionto 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.