From 1d90b366b4ca4d71ac5b65868021f5bb399f3f24 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 7 Jun 2023 13:38:36 +0100 Subject: [PATCH] Refactor test import style (#713) --- tests/_async/test_connection.py | 7 +- tests/_async/test_connection_pool.py | 104 +++++++++++++-------------- tests/_async/test_http11.py | 89 +++++++++++------------ tests/_async/test_http2.py | 80 ++++++++++----------- tests/_async/test_http_proxy.py | 9 ++- tests/_async/test_integration.py | 8 +-- tests/_async/test_socks_proxy.py | 36 +++++----- tests/_sync/test_connection.py | 7 +- tests/_sync/test_connection_pool.py | 104 +++++++++++++-------------- tests/_sync/test_http11.py | 89 +++++++++++------------ tests/_sync/test_http2.py | 80 ++++++++++----------- tests/_sync/test_http_proxy.py | 9 ++- tests/_sync/test_integration.py | 8 +-- tests/_sync/test_socks_proxy.py | 36 +++++----- tests/test_models.py | 10 +-- 15 files changed, 315 insertions(+), 361 deletions(-) diff --git a/tests/_async/test_connection.py b/tests/_async/test_connection.py index a1011c05..8b29942c 100644 --- a/tests/_async/test_connection.py +++ b/tests/_async/test_connection.py @@ -1,6 +1,5 @@ import ssl import typing -from typing import List, Optional import hpack import hyperframe.frame @@ -134,7 +133,7 @@ async def test_request_to_incorrect_origin(): class NeedsRetryBackend(AsyncMockBackend): def __init__( self, - buffer: List[bytes], + buffer: typing.List[bytes], http2: bool = False, connect_tcp_failures: int = 2, start_tls_failures: int = 0, @@ -147,8 +146,8 @@ async def connect_tcp( self, host: str, port: int, - timeout: Optional[float] = None, - local_address: Optional[str] = None, + timeout: typing.Optional[float] = None, + local_address: typing.Optional[str] = None, socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> AsyncNetworkStream: if self._connect_tcp_failures > 0: diff --git a/tests/_async/test_connection_pool.py b/tests/_async/test_connection_pool.py index 2ccfaf8c..df0199ab 100644 --- a/tests/_async/test_connection_pool.py +++ b/tests/_async/test_connection_pool.py @@ -1,20 +1,10 @@ import logging import typing -from typing import List, Optional import pytest import trio as concurrency -from httpcore import ( - SOCKET_OPTION, - AsyncConnectionPool, - AsyncMockBackend, - AsyncNetworkStream, - ConnectError, - PoolTimeout, - ReadError, - UnsupportedProtocol, -) +import httpcore @pytest.mark.anyio @@ -22,7 +12,7 @@ async def test_connection_pool_with_keepalive(): """ By default HTTP/1.1 requests should be returned to the connection pool. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -37,7 +27,7 @@ async def test_connection_pool_with_keepalive(): ] ) - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( network_backend=network_backend, ) as pool: # Sending an intial request, which once complete will return to the pool, IDLE. @@ -94,7 +84,7 @@ async def test_connection_pool_with_close(): HTTP/1.1 requests that include a 'Connection: Close' header should not be returned to the connection pool. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -104,7 +94,7 @@ async def test_connection_pool_with_close(): ] ) - async with AsyncConnectionPool(network_backend=network_backend) as pool: + async with httpcore.AsyncConnectionPool(network_backend=network_backend) as pool: # Sending an intial request, which once complete will not return to the pool. async with pool.stream( "GET", "https://example.com/", headers={"Connection": "close"} @@ -127,7 +117,7 @@ async def test_trace_request(): The 'trace' request extension allows for a callback function to inspect the internal events that occur while sending a request. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -142,7 +132,7 @@ async def test_trace_request(): async def trace(name, kwargs): called.append(name) - async with AsyncConnectionPool(network_backend=network_backend) as pool: + async with httpcore.AsyncConnectionPool(network_backend=network_backend) as pool: await pool.request("GET", "https://example.com/", extensions={"trace": trace}) assert called == [ @@ -171,7 +161,7 @@ async def test_debug_request(caplog): """ caplog.set_level(logging.DEBUG) - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -181,7 +171,7 @@ async def test_debug_request(caplog): ] ) - async with AsyncConnectionPool(network_backend=network_backend) as pool: + async with httpcore.AsyncConnectionPool(network_backend=network_backend) as pool: await pool.request("GET", "http://example.com/") assert caplog.record_tuples == [ @@ -237,14 +227,14 @@ async def test_connection_pool_with_http_exception(): HTTP/1.1 requests that result in an exception during the connection should not be returned to the connection pool. """ - network_backend = AsyncMockBackend([b"Wait, this isn't valid HTTP!"]) + network_backend = httpcore.AsyncMockBackend([b"Wait, this isn't valid HTTP!"]) called = [] async def trace(name, kwargs): called.append(name) - async with AsyncConnectionPool(network_backend=network_backend) as pool: + async with httpcore.AsyncConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(Exception): await pool.request( @@ -277,16 +267,18 @@ async def test_connection_pool_with_connect_exception(): be returned to the connection pool. """ - class FailedConnectBackend(AsyncMockBackend): + class FailedConnectBackend(httpcore.AsyncMockBackend): async def connect_tcp( self, host: str, port: int, - timeout: Optional[float] = None, - local_address: Optional[str] = None, - socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, - ) -> AsyncNetworkStream: - raise ConnectError("Could not connect") + timeout: typing.Optional[float] = None, + local_address: typing.Optional[str] = None, + socket_options: typing.Optional[ + typing.Iterable[httpcore.SOCKET_OPTION] + ] = None, + ) -> httpcore.AsyncNetworkStream: + raise httpcore.ConnectError("Could not connect") network_backend = FailedConnectBackend([]) @@ -295,7 +287,7 @@ async def connect_tcp( async def trace(name, kwargs): called.append(name) - async with AsyncConnectionPool(network_backend=network_backend) as pool: + async with httpcore.AsyncConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(Exception): await pool.request( @@ -317,7 +309,7 @@ async def test_connection_pool_with_immediate_expiry(): Connection pools with keepalive_expiry=0.0 should immediately expire keep alive connections. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -327,7 +319,7 @@ async def test_connection_pool_with_immediate_expiry(): ] ) - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( keepalive_expiry=0.0, network_backend=network_backend, ) as pool: @@ -351,7 +343,7 @@ async def test_connection_pool_with_no_keepalive_connections_allowed(): When 'max_keepalive_connections=0' is used, IDLE connections should not be returned to the pool. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -361,7 +353,7 @@ async def test_connection_pool_with_no_keepalive_connections_allowed(): ] ) - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( max_keepalive_connections=0, network_backend=network_backend ) as pool: # Sending an intial request, which once complete will not return to the pool. @@ -384,7 +376,7 @@ async def test_connection_pool_concurrency(): HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -400,10 +392,10 @@ async def fetch(pool, domain, info_list): info_list.append(info) await response.aread() - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( max_connections=1, network_backend=network_backend ) as pool: - info_list: List[str] = [] + info_list: typing.List[str] = [] async with concurrency.open_nursery() as nursery: for domain in ["a.com", "b.com", "c.com", "d.com", "e.com"]: nursery.start_soon(fetch, pool, domain, info_list) @@ -429,7 +421,7 @@ async def test_connection_pool_concurrency_same_domain_closing(): HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -446,10 +438,10 @@ async def fetch(pool, domain, info_list): info_list.append(info) await response.aread() - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( max_connections=1, network_backend=network_backend, http2=True ) as pool: - info_list: List[str] = [] + info_list: typing.List[str] = [] async with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) @@ -471,7 +463,7 @@ async def test_connection_pool_concurrency_same_domain_keepalive(): HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -488,10 +480,10 @@ async def fetch(pool, domain, info_list): info_list.append(info) await response.aread() - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( max_connections=1, network_backend=network_backend, http2=True ) as pool: - info_list: List[str] = [] + info_list: typing.List[str] = [] async with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) @@ -512,11 +504,11 @@ async def fetch(pool, domain, info_list): @pytest.mark.anyio async def test_unsupported_protocol(): - async with AsyncConnectionPool() as pool: - with pytest.raises(UnsupportedProtocol): + async with httpcore.AsyncConnectionPool() as pool: + with pytest.raises(httpcore.UnsupportedProtocol): await pool.request("GET", "ftp://www.example.com/") - with pytest.raises(UnsupportedProtocol): + with pytest.raises(httpcore.UnsupportedProtocol): await pool.request("GET", "://www.example.com/") @@ -526,7 +518,7 @@ async def test_connection_pool_closed_while_request_in_flight(): Closing a connection pool while a request/response is still in-flight should raise an error. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -536,14 +528,14 @@ async def test_connection_pool_closed_while_request_in_flight(): ] ) - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( network_backend=network_backend, ) as pool: # Send a request, and then close the connection pool while the # response has not yet been streamed. async with pool.stream("GET", "https://example.com/") as response: await pool.aclose() - with pytest.raises(ReadError): + with pytest.raises(httpcore.ReadError): await response.aread() @@ -552,7 +544,7 @@ async def test_connection_pool_timeout(): """ Ensure that exceeding max_connections can cause a request to timeout. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -562,14 +554,14 @@ async def test_connection_pool_timeout(): ] ) - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: # Send a request to a pool that is configured to only support a single # connection, and then ensure that a second concurrent request # fails with a timeout. async with pool.stream("GET", "https://example.com/"): - with pytest.raises(PoolTimeout): + with pytest.raises(httpcore.PoolTimeout): extensions = {"timeout": {"pool": 0.0001}} await pool.request("GET", "https://example.com/", extensions=extensions) @@ -580,7 +572,7 @@ async def test_connection_pool_timeout_zero(): A pool timeout of 0 shouldn't raise a PoolTimeout if there's no need to wait on a new connection. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -599,7 +591,7 @@ async def test_connection_pool_timeout_zero(): extensions = {"timeout": {"pool": 0}} # A connection pool configured to allow only one connection at a time. - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: # Two consecutive requests with a pool timeout of zero. @@ -617,7 +609,7 @@ async def test_connection_pool_timeout_zero(): assert response.content == b"Hello, world!" # A connection pool configured to allow only one connection at a time. - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: # Two concurrent requests with a pool timeout of zero. @@ -626,7 +618,7 @@ async def test_connection_pool_timeout_zero(): "GET", "https://example.com/", extensions=extensions ) as response: # The first response hasn't yet completed. - with pytest.raises(PoolTimeout): + with pytest.raises(httpcore.PoolTimeout): # So a pool timeout occurs. await pool.request("GET", "https://example.com/", extensions=extensions) # The first response now completes. @@ -647,7 +639,7 @@ async def test_http11_upgrade_connection(): https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", @@ -656,7 +648,7 @@ async def test_http11_upgrade_connection(): b"...", ] ) - async with AsyncConnectionPool( + async with httpcore.AsyncConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: async with pool.stream( diff --git a/tests/_async/test_http11.py b/tests/_async/test_http11.py index f1cc1e25..489d68b4 100644 --- a/tests/_async/test_http11.py +++ b/tests/_async/test_http11.py @@ -1,19 +1,12 @@ import pytest -from httpcore import ( - AsyncHTTP11Connection, - AsyncMockStream, - ConnectionNotAvailable, - LocalProtocolError, - Origin, - RemoteProtocolError, -) +import httpcore @pytest.mark.anyio async def test_http11_connection(): - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -22,7 +15,7 @@ async def test_http11_connection(): b"Hello, world!", ] ) - async with AsyncHTTP11Connection( + async with httpcore.AsyncHTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = await conn.request("GET", "https://example.com/") @@ -45,8 +38,8 @@ async def test_http11_connection_unread_response(): If the client releases the response without reading it to termination, then the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -55,7 +48,7 @@ async def test_http11_connection_unread_response(): b"Hello, world!", ] ) - async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn: + async with httpcore.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: assert response.status == 200 @@ -75,10 +68,10 @@ async def test_http11_connection_with_remote_protocol_error(): If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream([b"Wait, this isn't valid HTTP!", b""]) - async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream([b"Wait, this isn't valid HTTP!", b""]) + async with httpcore.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): await conn.request("GET", "https://example.com/") assert not conn.is_idle() @@ -96,8 +89,8 @@ async def test_http11_connection_with_incomplete_response(): """ We should be gracefully handling the case where the connection ends prematurely. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -106,8 +99,8 @@ async def test_http11_connection_with_incomplete_response(): b"Hello, wor", ] ) - async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + async with httpcore.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): await conn.request("GET", "https://example.com/") assert not conn.is_idle() @@ -126,8 +119,8 @@ async def test_http11_connection_with_local_protocol_error(): If a local protocol error occurs, then no response will be returned, and the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -136,8 +129,8 @@ async def test_http11_connection_with_local_protocol_error(): b"Hello, world!", ] ) - async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn: - with pytest.raises(LocalProtocolError) as exc_info: + async with httpcore.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.LocalProtocolError) as exc_info: await conn.request("GET", "https://example.com/", headers={"Host": "\0"}) assert str(exc_info.value) == "Illegal header value b'\\x00'" @@ -158,8 +151,8 @@ async def test_http11_connection_handles_one_active_request(): Attempting to send a request while one is already in-flight will raise a ConnectionNotAvailable exception. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -168,9 +161,9 @@ async def test_http11_connection_handles_one_active_request(): b"Hello, world!", ] ) - async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn: + async with httpcore.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/"): - with pytest.raises(ConnectionNotAvailable): + with pytest.raises(httpcore.ConnectionNotAvailable): await conn.request("GET", "https://example.com/") @@ -179,8 +172,8 @@ async def test_http11_connection_attempt_close(): """ A connection can only be closed when it is idle. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -189,7 +182,7 @@ async def test_http11_connection_attempt_close(): b"Hello, world!", ] ) - async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn: + async with httpcore.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: await response.aread() assert response.status == 200 @@ -201,9 +194,9 @@ async def test_http11_request_to_incorrect_origin(): """ A connection can only send requests to whichever origin it is connected to. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream([]) - async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn: + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream([]) + async with httpcore.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): await conn.request("GET", "https://other.com/") @@ -217,8 +210,8 @@ async def test_http11_expect_continue(): https://httpwg.org/specs/rfc9110.html#status.100 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100 """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 100 Continue\r\n", b"\r\n", @@ -229,7 +222,7 @@ async def test_http11_expect_continue(): b"Hello, world!", ] ) - async with AsyncHTTP11Connection( + async with httpcore.AsyncHTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = await conn.request( @@ -252,8 +245,8 @@ async def test_http11_upgrade_connection(): https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ - origin = Origin(b"wss", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"wss", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", @@ -262,7 +255,7 @@ async def test_http11_upgrade_connection(): b"...", ] ) - async with AsyncHTTP11Connection( + async with httpcore.AsyncHTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: async with conn.stream( @@ -284,8 +277,8 @@ async def test_http11_early_hints(): https://datatracker.ietf.org/doc/rfc8297/ """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 103 Early Hints\r\n", b"Link: ; rel=preload; as=style\r\n", @@ -300,7 +293,7 @@ async def test_http11_early_hints(): b"Hello, world! ...", ] ) - async with AsyncHTTP11Connection( + async with httpcore.AsyncHTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = await conn.request( @@ -317,8 +310,8 @@ async def test_http11_header_sub_100kb(): """ A connection should be able to handle a http header size up to 100kB. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", # 17 b"Content-Type: plain/text\r\n", # 43 @@ -328,7 +321,7 @@ async def test_http11_header_sub_100kb(): b"", ] ) - async with AsyncHTTP11Connection( + async with httpcore.AsyncHTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = await conn.request("GET", "https://example.com/") diff --git a/tests/_async/test_http2.py b/tests/_async/test_http2.py index 92ac7efd..59ba158e 100644 --- a/tests/_async/test_http2.py +++ b/tests/_async/test_http2.py @@ -2,19 +2,13 @@ import hyperframe.frame import pytest -from httpcore import ( - AsyncHTTP2Connection, - AsyncMockStream, - ConnectionNotAvailable, - Origin, - RemoteProtocolError, -) +import httpcore @pytest.mark.anyio async def test_http2_connection(): - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -32,7 +26,7 @@ async def test_http2_connection(): ).serialize(), ] ) - async with AsyncHTTP2Connection( + async with httpcore.AsyncHTTP2Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = await conn.request("GET", "https://example.com/") @@ -54,8 +48,8 @@ async def test_http2_connection(): @pytest.mark.anyio async def test_http2_connection_closed(): - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -75,12 +69,12 @@ async def test_http2_connection_closed(): hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0).serialize(), ] ) - async with AsyncHTTP2Connection( + async with httpcore.AsyncHTTP2Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: await conn.request("GET", "https://example.com/") - with pytest.raises(RemoteProtocolError): + with pytest.raises(httpcore.RemoteProtocolError): await conn.request("GET", "https://example.com/") assert not conn.is_available() @@ -88,8 +82,8 @@ async def test_http2_connection_closed(): @pytest.mark.anyio async def test_http2_connection_post_request(): - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -107,7 +101,7 @@ async def test_http2_connection_post_request(): ).serialize(), ] ) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: response = await conn.request( "POST", "https://example.com/", @@ -124,10 +118,10 @@ async def test_http2_connection_with_remote_protocol_error(): If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream([b"Wait, this isn't valid HTTP!", b""]) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream([b"Wait, this isn't valid HTTP!", b""]) + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): await conn.request("GET", "https://example.com/") @@ -137,8 +131,8 @@ async def test_http2_connection_with_rst_stream(): If a stream reset occurs, then no response will be returned, but the connection will remain reusable for other requests. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -170,8 +164,8 @@ async def test_http2_connection_with_rst_stream(): b"", ] ) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): await conn.request("GET", "https://example.com/") response = await conn.request("GET", "https://example.com/") assert response.status == 200 @@ -183,8 +177,8 @@ async def test_http2_connection_with_goaway(): If a GoAway frame occurs, then no response will be returned, and the connection will not be reusable for other requests. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -216,17 +210,17 @@ async def test_http2_connection_with_goaway(): b"", ] ) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): await conn.request("GET", "https://example.com/") - with pytest.raises(RemoteProtocolError): + with pytest.raises(httpcore.RemoteProtocolError): await conn.request("GET", "https://example.com/") @pytest.mark.anyio async def test_http2_connection_with_flow_control(): - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), # Available flow: 65,535 @@ -273,7 +267,7 @@ async def test_http2_connection_with_flow_control(): ).serialize(), ] ) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: response = await conn.request( "POST", "https://example.com/", @@ -288,8 +282,8 @@ async def test_http2_connection_attempt_close(): """ A connection can only be closed when it is idle. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -307,14 +301,14 @@ async def test_http2_connection_attempt_close(): ).serialize(), ] ) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" await conn.aclose() - with pytest.raises(ConnectionNotAvailable): + with pytest.raises(httpcore.ConnectionNotAvailable): await conn.request("GET", "https://example.com/") @@ -323,9 +317,9 @@ async def test_http2_request_to_incorrect_origin(): """ A connection can only send requests to whichever origin it is connected to. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream([]) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream([]) + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): await conn.request("GET", "https://other.com/") @@ -336,8 +330,8 @@ async def test_http2_remote_max_streams_update(): If the remote server updates the maximum concurrent streams value, we should be adjusting how many streams we will allow. """ - origin = Origin(b"https", b"example.com", 443) - stream = AsyncMockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.AsyncMockStream( [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1000} @@ -361,7 +355,7 @@ async def test_http2_remote_max_streams_update(): ).serialize(), ] ) - async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn: + async with httpcore.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: i = 0 async for chunk in response.aiter_stream(): diff --git a/tests/_async/test_http_proxy.py b/tests/_async/test_http_proxy.py index b60915e6..b35fc289 100644 --- a/tests/_async/test_http_proxy.py +++ b/tests/_async/test_http_proxy.py @@ -1,6 +1,5 @@ import ssl import typing -from typing import Optional import hpack import hyperframe.frame @@ -133,8 +132,8 @@ class HTTP1ThenHTTP2Stream(AsyncMockStream): async def start_tls( self, ssl_context: ssl.SSLContext, - server_hostname: Optional[str] = None, - timeout: Optional[float] = None, + server_hostname: typing.Optional[str] = None, + timeout: typing.Optional[float] = None, ) -> AsyncNetworkStream: self._http2 = True return self @@ -145,8 +144,8 @@ async def connect_tcp( self, host: str, port: int, - timeout: Optional[float] = None, - local_address: Optional[str] = None, + timeout: typing.Optional[float] = None, + local_address: typing.Optional[str] = None, socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> AsyncNetworkStream: return HTTP1ThenHTTP2Stream(list(self._buffer)) diff --git a/tests/_async/test_integration.py b/tests/_async/test_integration.py index ec7cb61b..1970531d 100644 --- a/tests/_async/test_integration.py +++ b/tests/_async/test_integration.py @@ -2,12 +2,12 @@ import pytest -from httpcore import AsyncConnectionPool +import httpcore @pytest.mark.anyio async def test_request(httpbin): - async with AsyncConnectionPool() as pool: + async with httpcore.AsyncConnectionPool() as pool: response = await pool.request("GET", httpbin.url) assert response.status == 200 @@ -17,7 +17,7 @@ async def test_ssl_request(httpbin_secure): ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE - async with AsyncConnectionPool(ssl_context=ssl_context) as pool: + async with httpcore.AsyncConnectionPool(ssl_context=ssl_context) as pool: response = await pool.request("GET", httpbin_secure.url) assert response.status == 200 @@ -27,7 +27,7 @@ async def test_extra_info(httpbin_secure): ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE - async with AsyncConnectionPool(ssl_context=ssl_context) as pool: + async with httpcore.AsyncConnectionPool(ssl_context=ssl_context) as pool: async with pool.stream("GET", httpbin_secure.url) as response: assert response.status == 200 stream = response.extensions["network_stream"] diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 033c3259..3f5dd1cc 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -1,6 +1,6 @@ import pytest -from httpcore import AsyncMockBackend, AsyncSOCKSProxy, Origin, ProxyError +import httpcore @pytest.mark.anyio @@ -8,7 +8,7 @@ async def test_socks5_request(): """ Send an HTTP request via a SOCKS proxy. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ # The initial socks CONNECT # v5 NOAUTH @@ -24,7 +24,7 @@ async def test_socks5_request(): ] ) - async with AsyncSOCKSProxy( + async with httpcore.AsyncSOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, ) as proxy: @@ -48,16 +48,16 @@ async def test_socks5_request(): # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request( - Origin(b"http", b"example.com", 80) + httpcore.Origin(b"http", b"example.com", 80) ) assert not proxy.connections[0].can_handle_request( - Origin(b"http", b"other.com", 80) + httpcore.Origin(b"http", b"other.com", 80) ) assert proxy.connections[0].can_handle_request( - Origin(b"https", b"example.com", 443) + httpcore.Origin(b"https", b"example.com", 443) ) assert not proxy.connections[0].can_handle_request( - Origin(b"https", b"other.com", 443) + httpcore.Origin(b"https", b"other.com", 443) ) @@ -66,7 +66,7 @@ async def test_authenticated_socks5_request(): """ Send an HTTP request via a SOCKS proxy. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ # The initial socks CONNECT # v5 USERNAME/PASSWORD @@ -84,7 +84,7 @@ async def test_authenticated_socks5_request(): ] ) - async with AsyncSOCKSProxy( + async with httpcore.AsyncSOCKSProxy( proxy_url="socks5://localhost:8080/", proxy_auth=(b"username", b"password"), network_backend=network_backend, @@ -113,7 +113,7 @@ async def test_socks5_request_connect_failed(): """ Attempt to send an HTTP request via a SOCKS proxy, resulting in a connect failure. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ # The initial socks CONNECT # v5 NOAUTH @@ -123,12 +123,12 @@ async def test_socks5_request_connect_failed(): ] ) - async with AsyncSOCKSProxy( + async with httpcore.AsyncSOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects - with pytest.raises(ProxyError) as exc_info: + with pytest.raises(httpcore.ProxyError) as exc_info: await proxy.request("GET", "https://example.com/") assert ( str(exc_info.value) == "Proxy Server could not connect: Connection refused." @@ -143,19 +143,19 @@ async def test_socks5_request_failed_to_provide_auth(): Attempt to send an HTTP request via an authenticated SOCKS proxy, without providing authentication credentials. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", ] ) - async with AsyncSOCKSProxy( + async with httpcore.AsyncSOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects - with pytest.raises(ProxyError) as exc_info: + with pytest.raises(httpcore.ProxyError) as exc_info: await proxy.request("GET", "https://example.com/") assert ( str(exc_info.value) @@ -171,7 +171,7 @@ async def test_socks5_request_incorrect_auth(): Attempt to send an HTTP request via an authenticated SOCKS proxy, wit incorrect authentication credentials. """ - network_backend = AsyncMockBackend( + network_backend = httpcore.AsyncMockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", @@ -180,13 +180,13 @@ async def test_socks5_request_incorrect_auth(): ] ) - async with AsyncSOCKSProxy( + async with httpcore.AsyncSOCKSProxy( proxy_url="socks5://localhost:8080/", proxy_auth=(b"invalid", b"invalid"), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects - with pytest.raises(ProxyError) as exc_info: + with pytest.raises(httpcore.ProxyError) as exc_info: await proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "Invalid username/password" diff --git a/tests/_sync/test_connection.py b/tests/_sync/test_connection.py index ad989ee2..9e0c4035 100644 --- a/tests/_sync/test_connection.py +++ b/tests/_sync/test_connection.py @@ -1,6 +1,5 @@ import ssl import typing -from typing import List, Optional import hpack import hyperframe.frame @@ -134,7 +133,7 @@ def test_request_to_incorrect_origin(): class NeedsRetryBackend(MockBackend): def __init__( self, - buffer: List[bytes], + buffer: typing.List[bytes], http2: bool = False, connect_tcp_failures: int = 2, start_tls_failures: int = 0, @@ -147,8 +146,8 @@ def connect_tcp( self, host: str, port: int, - timeout: Optional[float] = None, - local_address: Optional[str] = None, + timeout: typing.Optional[float] = None, + local_address: typing.Optional[str] = None, socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> NetworkStream: if self._connect_tcp_failures > 0: diff --git a/tests/_sync/test_connection_pool.py b/tests/_sync/test_connection_pool.py index b0fc9704..aafa68aa 100644 --- a/tests/_sync/test_connection_pool.py +++ b/tests/_sync/test_connection_pool.py @@ -1,20 +1,10 @@ import logging import typing -from typing import List, Optional import pytest from tests import concurrency -from httpcore import ( - SOCKET_OPTION, - ConnectionPool, - MockBackend, - NetworkStream, - ConnectError, - PoolTimeout, - ReadError, - UnsupportedProtocol, -) +import httpcore @@ -22,7 +12,7 @@ def test_connection_pool_with_keepalive(): """ By default HTTP/1.1 requests should be returned to the connection pool. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -37,7 +27,7 @@ def test_connection_pool_with_keepalive(): ] ) - with ConnectionPool( + with httpcore.ConnectionPool( network_backend=network_backend, ) as pool: # Sending an intial request, which once complete will return to the pool, IDLE. @@ -94,7 +84,7 @@ def test_connection_pool_with_close(): HTTP/1.1 requests that include a 'Connection: Close' header should not be returned to the connection pool. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -104,7 +94,7 @@ def test_connection_pool_with_close(): ] ) - with ConnectionPool(network_backend=network_backend) as pool: + with httpcore.ConnectionPool(network_backend=network_backend) as pool: # Sending an intial request, which once complete will not return to the pool. with pool.stream( "GET", "https://example.com/", headers={"Connection": "close"} @@ -127,7 +117,7 @@ def test_trace_request(): The 'trace' request extension allows for a callback function to inspect the internal events that occur while sending a request. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -142,7 +132,7 @@ def test_trace_request(): def trace(name, kwargs): called.append(name) - with ConnectionPool(network_backend=network_backend) as pool: + with httpcore.ConnectionPool(network_backend=network_backend) as pool: pool.request("GET", "https://example.com/", extensions={"trace": trace}) assert called == [ @@ -171,7 +161,7 @@ def test_debug_request(caplog): """ caplog.set_level(logging.DEBUG) - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -181,7 +171,7 @@ def test_debug_request(caplog): ] ) - with ConnectionPool(network_backend=network_backend) as pool: + with httpcore.ConnectionPool(network_backend=network_backend) as pool: pool.request("GET", "http://example.com/") assert caplog.record_tuples == [ @@ -237,14 +227,14 @@ def test_connection_pool_with_http_exception(): HTTP/1.1 requests that result in an exception during the connection should not be returned to the connection pool. """ - network_backend = MockBackend([b"Wait, this isn't valid HTTP!"]) + network_backend = httpcore.MockBackend([b"Wait, this isn't valid HTTP!"]) called = [] def trace(name, kwargs): called.append(name) - with ConnectionPool(network_backend=network_backend) as pool: + with httpcore.ConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(Exception): pool.request( @@ -277,16 +267,18 @@ def test_connection_pool_with_connect_exception(): be returned to the connection pool. """ - class FailedConnectBackend(MockBackend): + class FailedConnectBackend(httpcore.MockBackend): def connect_tcp( self, host: str, port: int, - timeout: Optional[float] = None, - local_address: Optional[str] = None, - socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, - ) -> NetworkStream: - raise ConnectError("Could not connect") + timeout: typing.Optional[float] = None, + local_address: typing.Optional[str] = None, + socket_options: typing.Optional[ + typing.Iterable[httpcore.SOCKET_OPTION] + ] = None, + ) -> httpcore.NetworkStream: + raise httpcore.ConnectError("Could not connect") network_backend = FailedConnectBackend([]) @@ -295,7 +287,7 @@ def connect_tcp( def trace(name, kwargs): called.append(name) - with ConnectionPool(network_backend=network_backend) as pool: + with httpcore.ConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(Exception): pool.request( @@ -317,7 +309,7 @@ def test_connection_pool_with_immediate_expiry(): Connection pools with keepalive_expiry=0.0 should immediately expire keep alive connections. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -327,7 +319,7 @@ def test_connection_pool_with_immediate_expiry(): ] ) - with ConnectionPool( + with httpcore.ConnectionPool( keepalive_expiry=0.0, network_backend=network_backend, ) as pool: @@ -351,7 +343,7 @@ def test_connection_pool_with_no_keepalive_connections_allowed(): When 'max_keepalive_connections=0' is used, IDLE connections should not be returned to the pool. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -361,7 +353,7 @@ def test_connection_pool_with_no_keepalive_connections_allowed(): ] ) - with ConnectionPool( + with httpcore.ConnectionPool( max_keepalive_connections=0, network_backend=network_backend ) as pool: # Sending an intial request, which once complete will not return to the pool. @@ -384,7 +376,7 @@ def test_connection_pool_concurrency(): HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -400,10 +392,10 @@ def fetch(pool, domain, info_list): info_list.append(info) response.read() - with ConnectionPool( + with httpcore.ConnectionPool( max_connections=1, network_backend=network_backend ) as pool: - info_list: List[str] = [] + info_list: typing.List[str] = [] with concurrency.open_nursery() as nursery: for domain in ["a.com", "b.com", "c.com", "d.com", "e.com"]: nursery.start_soon(fetch, pool, domain, info_list) @@ -429,7 +421,7 @@ def test_connection_pool_concurrency_same_domain_closing(): HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -446,10 +438,10 @@ def fetch(pool, domain, info_list): info_list.append(info) response.read() - with ConnectionPool( + with httpcore.ConnectionPool( max_connections=1, network_backend=network_backend, http2=True ) as pool: - info_list: List[str] = [] + info_list: typing.List[str] = [] with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) @@ -471,7 +463,7 @@ def test_connection_pool_concurrency_same_domain_keepalive(): HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -488,10 +480,10 @@ def fetch(pool, domain, info_list): info_list.append(info) response.read() - with ConnectionPool( + with httpcore.ConnectionPool( max_connections=1, network_backend=network_backend, http2=True ) as pool: - info_list: List[str] = [] + info_list: typing.List[str] = [] with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) @@ -512,11 +504,11 @@ def fetch(pool, domain, info_list): def test_unsupported_protocol(): - with ConnectionPool() as pool: - with pytest.raises(UnsupportedProtocol): + with httpcore.ConnectionPool() as pool: + with pytest.raises(httpcore.UnsupportedProtocol): pool.request("GET", "ftp://www.example.com/") - with pytest.raises(UnsupportedProtocol): + with pytest.raises(httpcore.UnsupportedProtocol): pool.request("GET", "://www.example.com/") @@ -526,7 +518,7 @@ def test_connection_pool_closed_while_request_in_flight(): Closing a connection pool while a request/response is still in-flight should raise an error. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -536,14 +528,14 @@ def test_connection_pool_closed_while_request_in_flight(): ] ) - with ConnectionPool( + with httpcore.ConnectionPool( network_backend=network_backend, ) as pool: # Send a request, and then close the connection pool while the # response has not yet been streamed. with pool.stream("GET", "https://example.com/") as response: pool.close() - with pytest.raises(ReadError): + with pytest.raises(httpcore.ReadError): response.read() @@ -552,7 +544,7 @@ def test_connection_pool_timeout(): """ Ensure that exceeding max_connections can cause a request to timeout. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -562,14 +554,14 @@ def test_connection_pool_timeout(): ] ) - with ConnectionPool( + with httpcore.ConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: # Send a request to a pool that is configured to only support a single # connection, and then ensure that a second concurrent request # fails with a timeout. with pool.stream("GET", "https://example.com/"): - with pytest.raises(PoolTimeout): + with pytest.raises(httpcore.PoolTimeout): extensions = {"timeout": {"pool": 0.0001}} pool.request("GET", "https://example.com/", extensions=extensions) @@ -580,7 +572,7 @@ def test_connection_pool_timeout_zero(): A pool timeout of 0 shouldn't raise a PoolTimeout if there's no need to wait on a new connection. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -599,7 +591,7 @@ def test_connection_pool_timeout_zero(): extensions = {"timeout": {"pool": 0}} # A connection pool configured to allow only one connection at a time. - with ConnectionPool( + with httpcore.ConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: # Two consecutive requests with a pool timeout of zero. @@ -617,7 +609,7 @@ def test_connection_pool_timeout_zero(): assert response.content == b"Hello, world!" # A connection pool configured to allow only one connection at a time. - with ConnectionPool( + with httpcore.ConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: # Two concurrent requests with a pool timeout of zero. @@ -626,7 +618,7 @@ def test_connection_pool_timeout_zero(): "GET", "https://example.com/", extensions=extensions ) as response: # The first response hasn't yet completed. - with pytest.raises(PoolTimeout): + with pytest.raises(httpcore.PoolTimeout): # So a pool timeout occurs. pool.request("GET", "https://example.com/", extensions=extensions) # The first response now completes. @@ -647,7 +639,7 @@ def test_http11_upgrade_connection(): https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", @@ -656,7 +648,7 @@ def test_http11_upgrade_connection(): b"...", ] ) - with ConnectionPool( + with httpcore.ConnectionPool( network_backend=network_backend, max_connections=1 ) as pool: with pool.stream( diff --git a/tests/_sync/test_http11.py b/tests/_sync/test_http11.py index b4842f19..dcd80e84 100644 --- a/tests/_sync/test_http11.py +++ b/tests/_sync/test_http11.py @@ -1,19 +1,12 @@ import pytest -from httpcore import ( - HTTP11Connection, - MockStream, - ConnectionNotAvailable, - LocalProtocolError, - Origin, - RemoteProtocolError, -) +import httpcore def test_http11_connection(): - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -22,7 +15,7 @@ def test_http11_connection(): b"Hello, world!", ] ) - with HTTP11Connection( + with httpcore.HTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = conn.request("GET", "https://example.com/") @@ -45,8 +38,8 @@ def test_http11_connection_unread_response(): If the client releases the response without reading it to termination, then the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -55,7 +48,7 @@ def test_http11_connection_unread_response(): b"Hello, world!", ] ) - with HTTP11Connection(origin=origin, stream=stream) as conn: + with httpcore.HTTP11Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: assert response.status == 200 @@ -75,10 +68,10 @@ def test_http11_connection_with_remote_protocol_error(): If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream([b"Wait, this isn't valid HTTP!", b""]) - with HTTP11Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream([b"Wait, this isn't valid HTTP!", b""]) + with httpcore.HTTP11Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): conn.request("GET", "https://example.com/") assert not conn.is_idle() @@ -96,8 +89,8 @@ def test_http11_connection_with_incomplete_response(): """ We should be gracefully handling the case where the connection ends prematurely. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -106,8 +99,8 @@ def test_http11_connection_with_incomplete_response(): b"Hello, wor", ] ) - with HTTP11Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + with httpcore.HTTP11Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): conn.request("GET", "https://example.com/") assert not conn.is_idle() @@ -126,8 +119,8 @@ def test_http11_connection_with_local_protocol_error(): If a local protocol error occurs, then no response will be returned, and the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -136,8 +129,8 @@ def test_http11_connection_with_local_protocol_error(): b"Hello, world!", ] ) - with HTTP11Connection(origin=origin, stream=stream) as conn: - with pytest.raises(LocalProtocolError) as exc_info: + with httpcore.HTTP11Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.LocalProtocolError) as exc_info: conn.request("GET", "https://example.com/", headers={"Host": "\0"}) assert str(exc_info.value) == "Illegal header value b'\\x00'" @@ -158,8 +151,8 @@ def test_http11_connection_handles_one_active_request(): Attempting to send a request while one is already in-flight will raise a ConnectionNotAvailable exception. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -168,9 +161,9 @@ def test_http11_connection_handles_one_active_request(): b"Hello, world!", ] ) - with HTTP11Connection(origin=origin, stream=stream) as conn: + with httpcore.HTTP11Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/"): - with pytest.raises(ConnectionNotAvailable): + with pytest.raises(httpcore.ConnectionNotAvailable): conn.request("GET", "https://example.com/") @@ -179,8 +172,8 @@ def test_http11_connection_attempt_close(): """ A connection can only be closed when it is idle. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", @@ -189,7 +182,7 @@ def test_http11_connection_attempt_close(): b"Hello, world!", ] ) - with HTTP11Connection(origin=origin, stream=stream) as conn: + with httpcore.HTTP11Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: response.read() assert response.status == 200 @@ -201,9 +194,9 @@ def test_http11_request_to_incorrect_origin(): """ A connection can only send requests to whichever origin it is connected to. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream([]) - with HTTP11Connection(origin=origin, stream=stream) as conn: + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream([]) + with httpcore.HTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): conn.request("GET", "https://other.com/") @@ -217,8 +210,8 @@ def test_http11_expect_continue(): https://httpwg.org/specs/rfc9110.html#status.100 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100 """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 100 Continue\r\n", b"\r\n", @@ -229,7 +222,7 @@ def test_http11_expect_continue(): b"Hello, world!", ] ) - with HTTP11Connection( + with httpcore.HTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = conn.request( @@ -252,8 +245,8 @@ def test_http11_upgrade_connection(): https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ - origin = Origin(b"wss", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"wss", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", @@ -262,7 +255,7 @@ def test_http11_upgrade_connection(): b"...", ] ) - with HTTP11Connection( + with httpcore.HTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: with conn.stream( @@ -284,8 +277,8 @@ def test_http11_early_hints(): https://datatracker.ietf.org/doc/rfc8297/ """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 103 Early Hints\r\n", b"Link: ; rel=preload; as=style\r\n", @@ -300,7 +293,7 @@ def test_http11_early_hints(): b"Hello, world! ...", ] ) - with HTTP11Connection( + with httpcore.HTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = conn.request( @@ -317,8 +310,8 @@ def test_http11_header_sub_100kb(): """ A connection should be able to handle a http header size up to 100kB. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ b"HTTP/1.1 200 OK\r\n", # 17 b"Content-Type: plain/text\r\n", # 43 @@ -328,7 +321,7 @@ def test_http11_header_sub_100kb(): b"", ] ) - with HTTP11Connection( + with httpcore.HTTP11Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = conn.request("GET", "https://example.com/") diff --git a/tests/_sync/test_http2.py b/tests/_sync/test_http2.py index f83a3be8..2cb353e1 100644 --- a/tests/_sync/test_http2.py +++ b/tests/_sync/test_http2.py @@ -2,19 +2,13 @@ import hyperframe.frame import pytest -from httpcore import ( - HTTP2Connection, - MockStream, - ConnectionNotAvailable, - Origin, - RemoteProtocolError, -) +import httpcore def test_http2_connection(): - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -32,7 +26,7 @@ def test_http2_connection(): ).serialize(), ] ) - with HTTP2Connection( + with httpcore.HTTP2Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: response = conn.request("GET", "https://example.com/") @@ -54,8 +48,8 @@ def test_http2_connection(): def test_http2_connection_closed(): - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -75,12 +69,12 @@ def test_http2_connection_closed(): hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0).serialize(), ] ) - with HTTP2Connection( + with httpcore.HTTP2Connection( origin=origin, stream=stream, keepalive_expiry=5.0 ) as conn: conn.request("GET", "https://example.com/") - with pytest.raises(RemoteProtocolError): + with pytest.raises(httpcore.RemoteProtocolError): conn.request("GET", "https://example.com/") assert not conn.is_available() @@ -88,8 +82,8 @@ def test_http2_connection_closed(): def test_http2_connection_post_request(): - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -107,7 +101,7 @@ def test_http2_connection_post_request(): ).serialize(), ] ) - with HTTP2Connection(origin=origin, stream=stream) as conn: + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: response = conn.request( "POST", "https://example.com/", @@ -124,10 +118,10 @@ def test_http2_connection_with_remote_protocol_error(): If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream([b"Wait, this isn't valid HTTP!", b""]) - with HTTP2Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream([b"Wait, this isn't valid HTTP!", b""]) + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): conn.request("GET", "https://example.com/") @@ -137,8 +131,8 @@ def test_http2_connection_with_rst_stream(): If a stream reset occurs, then no response will be returned, but the connection will remain reusable for other requests. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -170,8 +164,8 @@ def test_http2_connection_with_rst_stream(): b"", ] ) - with HTTP2Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): conn.request("GET", "https://example.com/") response = conn.request("GET", "https://example.com/") assert response.status == 200 @@ -183,8 +177,8 @@ def test_http2_connection_with_goaway(): If a GoAway frame occurs, then no response will be returned, and the connection will not be reusable for other requests. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -216,17 +210,17 @@ def test_http2_connection_with_goaway(): b"", ] ) - with HTTP2Connection(origin=origin, stream=stream) as conn: - with pytest.raises(RemoteProtocolError): + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: + with pytest.raises(httpcore.RemoteProtocolError): conn.request("GET", "https://example.com/") - with pytest.raises(RemoteProtocolError): + with pytest.raises(httpcore.RemoteProtocolError): conn.request("GET", "https://example.com/") def test_http2_connection_with_flow_control(): - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), # Available flow: 65,535 @@ -273,7 +267,7 @@ def test_http2_connection_with_flow_control(): ).serialize(), ] ) - with HTTP2Connection(origin=origin, stream=stream) as conn: + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: response = conn.request( "POST", "https://example.com/", @@ -288,8 +282,8 @@ def test_http2_connection_attempt_close(): """ A connection can only be closed when it is idle. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( @@ -307,14 +301,14 @@ def test_http2_connection_attempt_close(): ).serialize(), ] ) - with HTTP2Connection(origin=origin, stream=stream) as conn: + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: response.read() assert response.status == 200 assert response.content == b"Hello, world!" conn.close() - with pytest.raises(ConnectionNotAvailable): + with pytest.raises(httpcore.ConnectionNotAvailable): conn.request("GET", "https://example.com/") @@ -323,9 +317,9 @@ def test_http2_request_to_incorrect_origin(): """ A connection can only send requests to whichever origin it is connected to. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream([]) - with HTTP2Connection(origin=origin, stream=stream) as conn: + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream([]) + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): conn.request("GET", "https://other.com/") @@ -336,8 +330,8 @@ def test_http2_remote_max_streams_update(): If the remote server updates the maximum concurrent streams value, we should be adjusting how many streams we will allow. """ - origin = Origin(b"https", b"example.com", 443) - stream = MockStream( + origin = httpcore.Origin(b"https", b"example.com", 443) + stream = httpcore.MockStream( [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1000} @@ -361,7 +355,7 @@ def test_http2_remote_max_streams_update(): ).serialize(), ] ) - with HTTP2Connection(origin=origin, stream=stream) as conn: + with httpcore.HTTP2Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: i = 0 for chunk in response.iter_stream(): diff --git a/tests/_sync/test_http_proxy.py b/tests/_sync/test_http_proxy.py index 98d07e69..2d66578e 100644 --- a/tests/_sync/test_http_proxy.py +++ b/tests/_sync/test_http_proxy.py @@ -1,6 +1,5 @@ import ssl import typing -from typing import Optional import hpack import hyperframe.frame @@ -133,8 +132,8 @@ class HTTP1ThenHTTP2Stream(MockStream): def start_tls( self, ssl_context: ssl.SSLContext, - server_hostname: Optional[str] = None, - timeout: Optional[float] = None, + server_hostname: typing.Optional[str] = None, + timeout: typing.Optional[float] = None, ) -> NetworkStream: self._http2 = True return self @@ -145,8 +144,8 @@ def connect_tcp( self, host: str, port: int, - timeout: Optional[float] = None, - local_address: Optional[str] = None, + timeout: typing.Optional[float] = None, + local_address: typing.Optional[str] = None, socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> NetworkStream: return HTTP1ThenHTTP2Stream(list(self._buffer)) diff --git a/tests/_sync/test_integration.py b/tests/_sync/test_integration.py index 42bf70b0..e3327e69 100644 --- a/tests/_sync/test_integration.py +++ b/tests/_sync/test_integration.py @@ -2,12 +2,12 @@ import pytest -from httpcore import ConnectionPool +import httpcore def test_request(httpbin): - with ConnectionPool() as pool: + with httpcore.ConnectionPool() as pool: response = pool.request("GET", httpbin.url) assert response.status == 200 @@ -17,7 +17,7 @@ def test_ssl_request(httpbin_secure): ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE - with ConnectionPool(ssl_context=ssl_context) as pool: + with httpcore.ConnectionPool(ssl_context=ssl_context) as pool: response = pool.request("GET", httpbin_secure.url) assert response.status == 200 @@ -27,7 +27,7 @@ def test_extra_info(httpbin_secure): ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE - with ConnectionPool(ssl_context=ssl_context) as pool: + with httpcore.ConnectionPool(ssl_context=ssl_context) as pool: with pool.stream("GET", httpbin_secure.url) as response: assert response.status == 200 stream = response.extensions["network_stream"] diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 4c701b0d..2d39bb97 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -1,6 +1,6 @@ import pytest -from httpcore import MockBackend, SOCKSProxy, Origin, ProxyError +import httpcore @@ -8,7 +8,7 @@ def test_socks5_request(): """ Send an HTTP request via a SOCKS proxy. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ # The initial socks CONNECT # v5 NOAUTH @@ -24,7 +24,7 @@ def test_socks5_request(): ] ) - with SOCKSProxy( + with httpcore.SOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, ) as proxy: @@ -48,16 +48,16 @@ def test_socks5_request(): # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request( - Origin(b"http", b"example.com", 80) + httpcore.Origin(b"http", b"example.com", 80) ) assert not proxy.connections[0].can_handle_request( - Origin(b"http", b"other.com", 80) + httpcore.Origin(b"http", b"other.com", 80) ) assert proxy.connections[0].can_handle_request( - Origin(b"https", b"example.com", 443) + httpcore.Origin(b"https", b"example.com", 443) ) assert not proxy.connections[0].can_handle_request( - Origin(b"https", b"other.com", 443) + httpcore.Origin(b"https", b"other.com", 443) ) @@ -66,7 +66,7 @@ def test_authenticated_socks5_request(): """ Send an HTTP request via a SOCKS proxy. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ # The initial socks CONNECT # v5 USERNAME/PASSWORD @@ -84,7 +84,7 @@ def test_authenticated_socks5_request(): ] ) - with SOCKSProxy( + with httpcore.SOCKSProxy( proxy_url="socks5://localhost:8080/", proxy_auth=(b"username", b"password"), network_backend=network_backend, @@ -113,7 +113,7 @@ def test_socks5_request_connect_failed(): """ Attempt to send an HTTP request via a SOCKS proxy, resulting in a connect failure. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ # The initial socks CONNECT # v5 NOAUTH @@ -123,12 +123,12 @@ def test_socks5_request_connect_failed(): ] ) - with SOCKSProxy( + with httpcore.SOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects - with pytest.raises(ProxyError) as exc_info: + with pytest.raises(httpcore.ProxyError) as exc_info: proxy.request("GET", "https://example.com/") assert ( str(exc_info.value) == "Proxy Server could not connect: Connection refused." @@ -143,19 +143,19 @@ def test_socks5_request_failed_to_provide_auth(): Attempt to send an HTTP request via an authenticated SOCKS proxy, without providing authentication credentials. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", ] ) - with SOCKSProxy( + with httpcore.SOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects - with pytest.raises(ProxyError) as exc_info: + with pytest.raises(httpcore.ProxyError) as exc_info: proxy.request("GET", "https://example.com/") assert ( str(exc_info.value) @@ -171,7 +171,7 @@ def test_socks5_request_incorrect_auth(): Attempt to send an HTTP request via an authenticated SOCKS proxy, wit incorrect authentication credentials. """ - network_backend = MockBackend( + network_backend = httpcore.MockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", @@ -180,13 +180,13 @@ def test_socks5_request_incorrect_auth(): ] ) - with SOCKSProxy( + with httpcore.SOCKSProxy( proxy_url="socks5://localhost:8080/", proxy_auth=(b"invalid", b"invalid"), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects - with pytest.raises(ProxyError) as exc_info: + with pytest.raises(httpcore.ProxyError) as exc_info: proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "Invalid username/password" diff --git a/tests/test_models.py b/tests/test_models.py index 05619754..104da310 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,4 +1,4 @@ -from typing import AsyncIterator, Iterator, List +import typing import pytest @@ -95,10 +95,10 @@ def test_response(): class ByteIterator: - def __init__(self, chunks: List[bytes]) -> None: + def __init__(self, chunks: typing.List[bytes]) -> None: self._chunks = chunks - def __iter__(self) -> Iterator[bytes]: + def __iter__(self) -> typing.Iterator[bytes]: for chunk in self._chunks: yield chunk @@ -130,10 +130,10 @@ def test_response_sync_streaming(): class AsyncByteIterator: - def __init__(self, chunks: List[bytes]) -> None: + def __init__(self, chunks: typing.List[bytes]) -> None: self._chunks = chunks - async def __aiter__(self) -> AsyncIterator[bytes]: + async def __aiter__(self) -> typing.AsyncIterator[bytes]: for chunk in self._chunks: yield chunk