From 1270774327372e64c85f219df98fea5971aa0cfc Mon Sep 17 00:00:00 2001 From: Joshua Coats Date: Thu, 10 Jan 2019 17:23:35 -0800 Subject: [PATCH 1/2] Permit empty reason strings on responses that use ClientResponse.raise_for_status() --- CHANGES/3532.bugfix | 2 ++ CONTRIBUTORS.txt | 1 + aiohttp/client_reqrep.py | 4 +++- tests/test_client_response.py | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 CHANGES/3532.bugfix diff --git a/CHANGES/3532.bugfix b/CHANGES/3532.bugfix new file mode 100644 index 00000000000..6ee7b3b3d18 --- /dev/null +++ b/CHANGES/3532.bugfix @@ -0,0 +1,2 @@ +Raise a ClientResponseError instead of an AssertionError for a blank +HTTP Reason Phrase. \ No newline at end of file diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1188ca1ccf1..5b7d89b81d5 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -120,6 +120,7 @@ Joel Watts Jon Nabozny Joongi Kim Josep Cugat +Joshu Coats Julia Tsemusheva Julien Duponchelle Jungkook Park diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index 846ce6f090c..c179333eee9 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -931,8 +931,10 @@ def release(self) -> Any: return noop() def raise_for_status(self) -> None: + # self.reason is only None if self.start() hasn't been called: + if self.reason is None: + raise TypeError("Expected a Reason-Phrase as a string") if 400 <= self.status: - assert self.reason # always not None for started response self.release() raise ClientResponseError( self.request_info, diff --git a/tests/test_client_response.py b/tests/test_client_response.py index cf203d844b2..f29f9e4d084 100644 --- a/tests/test_client_response.py +++ b/tests/test_client_response.py @@ -669,6 +669,24 @@ def test_raise_for_status_4xx() -> None: assert response.closed +def test_raise_for_status_4xx_without_reason() -> None: + response = ClientResponse('get', URL('http://def-cl-resp.org'), + request_info=mock.Mock(), + writer=mock.Mock(), + continue100=None, + timer=TimerNoop(), + traces=[], + loop=mock.Mock(), + session=mock.Mock()) + response.status = 404 + response.reason = '' + with pytest.raises(aiohttp.ClientResponseError) as cm: + response.raise_for_status() + assert str(cm.value.status) == '404' + assert str(cm.value.message) == '' + assert response.closed + + def test_resp_host() -> None: response = ClientResponse('get', URL('http://del-cl-resp.org'), request_info=mock.Mock(), From 3b9d0d3acd5794104d577a161768bafc816275a5 Mon Sep 17 00:00:00 2001 From: Joshua Coats Date: Sun, 13 Jan 2019 22:58:48 -0800 Subject: [PATCH 2/2] Change from raising a TypeError to asserting reason is not None --- aiohttp/client_reqrep.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index c179333eee9..8785605c708 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -931,10 +931,9 @@ def release(self) -> Any: return noop() def raise_for_status(self) -> None: - # self.reason is only None if self.start() hasn't been called: - if self.reason is None: - raise TypeError("Expected a Reason-Phrase as a string") if 400 <= self.status: + # reason should always be not None for a started response + assert self.reason is not None self.release() raise ClientResponseError( self.request_info,