-
-
Notifications
You must be signed in to change notification settings - Fork 858
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
Make HttpStatusError and RequestError pickleable #3108
base: master
Are you sure you want to change the base?
Conversation
0eef52c
to
5f81a85
Compare
If an error has keyword-only arguments, it needs this extra `__reduce__` method to ensure that unpickling doesn't raise `TypeError: missing (n) required keyword-only argument(s)`
5f81a85
to
a3c0cb3
Compare
def __reduce__( | ||
self, | ||
) -> typing.Tuple[ | ||
typing.Callable[..., Exception], typing.Tuple[typing.Any], dict[str, typing.Any] | ||
]: | ||
return (Exception.__new__, (type(self),) + self.args, self.__dict__) | ||
|
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.
Are we able to be consistent with how pickle is supported on Request
/Response
here?
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.
All of the key word only arguments of Request
have default values so that's why it's pickleable. Our choices here are:
- Give all kwonly arguments defaults. Classes where all kwonly arguments have defaults mostly have the correct pickle behavior without any special support.
- Do something like what I have here.
As an aside, this is a bit of a Python wart, ideally simple classes with required kwonly constructor args should be pickleable out of the box. I wonder if there is any discussion on discuss.python.org about it...
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.
Okay sure thing.
Thanks for the fix.
Worth adding a |
Okay updated changelog. |
The root issue is that BaseException has a custom reduce that can't handle subclasses with required keyword-only arguments. Overriding reduce is the right fix (barring a fix in Python), but I think it only needs to be in HttpStatusError. RequestError can already be pickled because its keyword argument has a default. More importantly, I'd like to see this merged! |
Okay, I'll rephrase my reservations and let's see if we can get this unblocked. I'd prefer to accept a See https://docs.python.org/3/library/pickle.html#object.__setstate__
|
I see, I didn't understand from what you said previously that this PR was waiting on me. I'll look into it. |
No it is not possible to implement this with static PyObject *
BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
{
if (self->args && self->dict)
return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
else
return PyTuple_Pack(2, Py_TYPE(self), self->args);
} So in order to fix the behavior we'll have to override The ordinary Anyways none of this happens if |
As @camillol said:
|
@tomchristie can you read my explanation above about why need to override |
If an error has keyword-only arguments, it needs this extra
__reduce__
method to ensure that unpickling doesn't raiseTypeError: missing (n) required keyword-only argument(s)
.Checklist