Skip to content

Commit

Permalink
Make HttpStatusError and RequestError pickleable
Browse files Browse the repository at this point in the history
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)`
  • Loading branch information
hoodmane committed Feb 22, 2024
1 parent 326b943 commit a3c0cb3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
7 changes: 7 additions & 0 deletions httpx/_exceptions.py
Expand Up @@ -71,6 +71,13 @@ def request(self) -> Request:
def request(self, request: Request) -> None:
self._request = request

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__)


class RequestError(HTTPError):
"""
Expand Down
16 changes: 16 additions & 0 deletions tests/test_pickle.py
@@ -0,0 +1,16 @@
import pickle

from httpx import HTTPStatusError, RequestError


def test_pickle():
req_err = RequestError("hi!", request="request") # type:ignore[arg-type]
req_err_clone = pickle.loads(pickle.dumps(req_err))
assert req_err.args == req_err_clone.args
assert req_err.request == req_err_clone.request

status_err = HTTPStatusError("hi", request="request", response="response") # type:ignore[arg-type]
status_err_clone = pickle.loads(pickle.dumps(status_err))
assert status_err.args == status_err_clone.args
assert status_err.request == status_err_clone.request
assert status_err.response == status_err_clone.response

0 comments on commit a3c0cb3

Please sign in to comment.