Drop .next()/.anext() in favour of response.next_request (#1339)

* Drop response.next()/response.anext() in favour of response.next_request

* Drop NotRedirectResponse
This commit is contained in:
Tom Christie 2020-10-06 14:53:07 +01:00 committed by GitHub
parent 2a2bbe58a6
commit 0eed6a3734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 16 additions and 113 deletions

View File

@ -76,7 +76,6 @@ except httpx.HTTPStatusError as exc:
* TooManyRedirects
* HTTPStatusError
* InvalidURL
* NotRedirectResponse
* CookieConflict
* StreamError
* StreamConsumed
@ -154,9 +153,6 @@ except httpx.HTTPStatusError as exc:
::: httpx.InvalidURL
:docstring:
::: httpx.NotRedirectResponse
:docstring:
::: httpx.CookieConflict
:docstring:

View File

@ -14,7 +14,6 @@ from ._exceptions import (
InvalidURL,
LocalProtocolError,
NetworkError,
NotRedirectResponse,
PoolTimeout,
ProtocolError,
ProxyError,
@ -67,7 +66,6 @@ __all__ = [
"Limits",
"LocalProtocolError",
"NetworkError",
"NotRedirectResponse",
"options",
"patch",
"PoolTimeout",

View File

@ -1,6 +1,5 @@
import datetime
import enum
import functools
import typing
import warnings
from types import TracebackType
@ -848,13 +847,6 @@ class Client(BaseClient):
if not allow_redirects:
response.next_request = request
response.call_next = functools.partial(
self._send_handling_redirects,
request=request,
timeout=timeout,
allow_redirects=False,
history=history,
)
return response
def _send_single_request(self, request: Request, timeout: Timeout) -> Response:
@ -1494,13 +1486,6 @@ class AsyncClient(BaseClient):
if not allow_redirects:
response.next_request = request
response.call_next = functools.partial(
self._send_handling_redirects,
request=request,
timeout=timeout,
allow_redirects=False,
history=history,
)
return response
async def _send_single_request(

View File

@ -24,7 +24,6 @@ Our exception hierarchy:
+ RequestBodyUnavailable
x HTTPStatusError
* InvalidURL
* NotRedirectResponse
* CookieConflict
* StreamError
x StreamConsumed
@ -233,18 +232,6 @@ class InvalidURL(Exception):
super().__init__(message)
class NotRedirectResponse(Exception):
"""
Response was not a redirect response.
May be raised if `response.next()` is called without first
properly checking `response.is_redirect`.
"""
def __init__(self, message: str) -> None:
super().__init__(message)
class CookieConflict(Exception):
"""
Attempted to lookup a cookie by name, but multiple cookies existed.

View File

@ -27,7 +27,6 @@ from ._exceptions import (
DecodingError,
HTTPStatusError,
InvalidURL,
NotRedirectResponse,
RequestNotRead,
ResponseClosed,
ResponseNotRead,
@ -1183,19 +1182,6 @@ class Response:
yield part
self.close()
def next(self) -> "Response":
"""
Get the next response from a redirect response.
"""
if not self.is_redirect:
message = (
"Called .next(), but the response was not a redirect. "
"Calling code should check `response.is_redirect` first."
)
raise NotRedirectResponse(message)
assert self.call_next is not None
return self.call_next()
def close(self) -> None:
"""
Close the response and release the connection.
@ -1268,18 +1254,6 @@ class Response:
yield part
await self.aclose()
async def anext(self) -> "Response":
"""
Get the next response from a redirect response.
"""
if not self.is_redirect:
raise NotRedirectResponse(
"Called .anext(), but the response was not a redirect. "
"Calling code should check `response.is_redirect` first."
)
assert self.call_next is not None
return await self.call_next()
async def aclose(self) -> None:
"""
Close the response and release the connection.

View File

@ -19,9 +19,6 @@ async def test_get(server):
assert repr(response) == "<Response [200 OK]>"
assert response.elapsed > timedelta(seconds=0)
with pytest.raises(httpx.NotRedirectResponse):
await response.anext()
@pytest.mark.parametrize(
"url",

View File

@ -23,9 +23,6 @@ def test_get(server):
assert repr(response) == "<Response [200 OK]>"
assert response.elapsed > timedelta(0)
with pytest.raises(httpx.NotRedirectResponse):
response.next()
@pytest.mark.parametrize(
"url",

View File

@ -11,10 +11,7 @@ def redirects(request: httpx.Request) -> httpx.Response:
f"Scheme {request.url.scheme!r} not supported."
)
if request.url.path == "/no_redirect":
return httpx.Response(200)
elif request.url.path == "/redirect_301":
if request.url.path == "/redirect_301":
status_code = httpx.codes.MOVED_PERMANENTLY
content = b"<a href='https://example.org/'>here</a>"
headers = {"location": "https://example.org/"}
@ -118,15 +115,6 @@ def redirects(request: httpx.Request) -> httpx.Response:
return httpx.Response(200, html="<html><body>Hello, world!</body></html>")
def test_no_redirect():
client = httpx.Client(transport=MockTransport(redirects))
url = "https://example.com/no_redirect"
response = client.get(url)
assert response.status_code == 200
with pytest.raises(httpx.NotRedirectResponse):
response.next()
def test_redirect_301():
client = httpx.Client(transport=MockTransport(redirects))
response = client.post("https://example.org/redirect_301")
@ -151,21 +139,6 @@ def test_redirect_303():
assert len(response.history) == 1
def test_disallow_redirects():
client = httpx.Client(transport=MockTransport(redirects))
response = client.post("https://example.org/redirect_303", allow_redirects=False)
assert response.status_code == httpx.codes.SEE_OTHER
assert response.url == "https://example.org/redirect_303"
assert response.is_redirect is True
assert len(response.history) == 0
response = response.next()
assert response.status_code == httpx.codes.OK
assert response.url == "https://example.org/"
assert response.is_redirect is False
assert len(response.history) == 1
def test_next_request():
client = httpx.Client(transport=MockTransport(redirects))
request = client.build_request("POST", "https://example.org/redirect_303")
@ -180,6 +153,21 @@ def test_next_request():
assert response.next_request is None
@pytest.mark.usefixtures("async_environment")
async def test_async_next_request():
client = httpx.AsyncClient(transport=MockTransport(redirects))
request = client.build_request("POST", "https://example.org/redirect_303")
response = await client.send(request, allow_redirects=False)
assert response.status_code == httpx.codes.SEE_OTHER
assert response.url == "https://example.org/redirect_303"
assert response.next_request is not None
response = await client.send(response.next_request, allow_redirects=False)
assert response.status_code == httpx.codes.OK
assert response.url == "https://example.org/"
assert response.next_request is None
def test_head_redirect():
"""
Contrary to Requests, redirects remain enabled by default for HEAD requests.
@ -251,31 +239,12 @@ async def test_async_too_many_redirects():
await client.get("https://example.org/multiple_redirects?count=21")
@pytest.mark.usefixtures("async_environment")
async def test_async_too_many_redirects_calling_next():
async with httpx.AsyncClient(transport=MockTransport(redirects)) as client:
url = "https://example.org/multiple_redirects?count=21"
response = await client.get(url, allow_redirects=False)
with pytest.raises(httpx.TooManyRedirects):
while response.is_redirect:
response = await response.anext()
def test_sync_too_many_redirects():
client = httpx.Client(transport=MockTransport(redirects))
with pytest.raises(httpx.TooManyRedirects):
client.get("https://example.org/multiple_redirects?count=21")
def test_sync_too_many_redirects_calling_next():
client = httpx.Client(transport=MockTransport(redirects))
url = "https://example.org/multiple_redirects?count=21"
response = client.get(url, allow_redirects=False)
with pytest.raises(httpx.TooManyRedirects):
while response.is_redirect:
response = response.next()
def test_redirect_loop():
client = httpx.Client(transport=MockTransport(redirects))
with pytest.raises(httpx.TooManyRedirects):