Support pickling HTTPStatusError
This commit is contained in:
parent
37593c1952
commit
a46d033553
@ -34,6 +34,7 @@ Our exception hierarchy:
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import functools
|
||||
import typing
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
@ -267,6 +268,22 @@ class HTTPStatusError(HTTPError):
|
||||
self.request = request
|
||||
self.response = response
|
||||
|
||||
def __reduce__(self) -> tuple[typing.Any, ...]:
|
||||
# BaseException has a custom __reduce__ that can't handle subclasses with
|
||||
# required keyword-only arguments.
|
||||
return (
|
||||
functools.partial(
|
||||
self.__class__, request=self.request, response=self.response
|
||||
),
|
||||
self.args,
|
||||
# In case user code adds attributes to the exception instance.
|
||||
{
|
||||
k: v
|
||||
for k, v in self.__dict__.items()
|
||||
if k not in ("_request", "response")
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class InvalidURL(Exception):
|
||||
"""
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pickle
|
||||
import typing
|
||||
|
||||
import httpcore
|
||||
@ -61,3 +62,19 @@ def test_request_attribute() -> None:
|
||||
request = httpx.Request("GET", "https://www.example.com")
|
||||
exc = httpx.ReadTimeout("Read operation timed out", request=request)
|
||||
assert exc.request == request
|
||||
|
||||
|
||||
def test_pickle_error(server):
|
||||
with httpx.Client() as client:
|
||||
response = client.request("GET", server.url.copy_with(path="/status/404"))
|
||||
with pytest.raises(httpx.HTTPStatusError) as exc_info:
|
||||
response.raise_for_status()
|
||||
error = exc_info.value
|
||||
assert isinstance(error, httpx.HTTPStatusError)
|
||||
pickled_error = pickle.dumps(error)
|
||||
unpickled_error = pickle.loads(pickled_error)
|
||||
# Note that the unpickled error will not be equal to the original error
|
||||
# because requests and responses are compared by identity.
|
||||
assert str(unpickled_error) == str(error)
|
||||
assert unpickled_error.request is not None
|
||||
assert unpickled_error.response is not None
|
||||
|
||||
Loading…
Reference in New Issue
Block a user