11import logging
22import typing
3- from typing import List , Optional
43
54import pytest
65import trio as concurrency
76
8- from httpcore import (
9- SOCKET_OPTION ,
10- AsyncConnectionPool ,
11- AsyncMockBackend ,
12- AsyncNetworkStream ,
13- ConnectError ,
14- PoolTimeout ,
15- ReadError ,
16- UnsupportedProtocol ,
17- )
7+ import httpcore
188
199
2010@pytest .mark .anyio
2111async def test_connection_pool_with_keepalive ():
2212 """
2313 By default HTTP/1.1 requests should be returned to the connection pool.
2414 """
25- network_backend = AsyncMockBackend (
15+ network_backend = httpcore . AsyncMockBackend (
2616 [
2717 b"HTTP/1.1 200 OK\r \n " ,
2818 b"Content-Type: plain/text\r \n " ,
@@ -37,7 +27,7 @@ async def test_connection_pool_with_keepalive():
3727 ]
3828 )
3929
40- async with AsyncConnectionPool (
30+ async with httpcore . AsyncConnectionPool (
4131 network_backend = network_backend ,
4232 ) as pool :
4333 # Sending an intial request, which once complete will return to the pool, IDLE.
@@ -94,7 +84,7 @@ async def test_connection_pool_with_close():
9484 HTTP/1.1 requests that include a 'Connection: Close' header should
9585 not be returned to the connection pool.
9686 """
97- network_backend = AsyncMockBackend (
87+ network_backend = httpcore . AsyncMockBackend (
9888 [
9989 b"HTTP/1.1 200 OK\r \n " ,
10090 b"Content-Type: plain/text\r \n " ,
@@ -104,7 +94,7 @@ async def test_connection_pool_with_close():
10494 ]
10595 )
10696
107- async with AsyncConnectionPool (network_backend = network_backend ) as pool :
97+ async with httpcore . AsyncConnectionPool (network_backend = network_backend ) as pool :
10898 # Sending an intial request, which once complete will not return to the pool.
10999 async with pool .stream (
110100 "GET" , "https://example.com/" , headers = {"Connection" : "close" }
@@ -127,7 +117,7 @@ async def test_trace_request():
127117 The 'trace' request extension allows for a callback function to inspect the
128118 internal events that occur while sending a request.
129119 """
130- network_backend = AsyncMockBackend (
120+ network_backend = httpcore . AsyncMockBackend (
131121 [
132122 b"HTTP/1.1 200 OK\r \n " ,
133123 b"Content-Type: plain/text\r \n " ,
@@ -142,7 +132,7 @@ async def test_trace_request():
142132 async def trace (name , kwargs ):
143133 called .append (name )
144134
145- async with AsyncConnectionPool (network_backend = network_backend ) as pool :
135+ async with httpcore . AsyncConnectionPool (network_backend = network_backend ) as pool :
146136 await pool .request ("GET" , "https://example.com/" , extensions = {"trace" : trace })
147137
148138 assert called == [
@@ -171,7 +161,7 @@ async def test_debug_request(caplog):
171161 """
172162 caplog .set_level (logging .DEBUG )
173163
174- network_backend = AsyncMockBackend (
164+ network_backend = httpcore . AsyncMockBackend (
175165 [
176166 b"HTTP/1.1 200 OK\r \n " ,
177167 b"Content-Type: plain/text\r \n " ,
@@ -181,7 +171,7 @@ async def test_debug_request(caplog):
181171 ]
182172 )
183173
184- async with AsyncConnectionPool (network_backend = network_backend ) as pool :
174+ async with httpcore . AsyncConnectionPool (network_backend = network_backend ) as pool :
185175 await pool .request ("GET" , "http://example.com/" )
186176
187177 assert caplog .record_tuples == [
@@ -237,14 +227,14 @@ async def test_connection_pool_with_http_exception():
237227 HTTP/1.1 requests that result in an exception during the connection should
238228 not be returned to the connection pool.
239229 """
240- network_backend = AsyncMockBackend ([b"Wait, this isn't valid HTTP!" ])
230+ network_backend = httpcore . AsyncMockBackend ([b"Wait, this isn't valid HTTP!" ])
241231
242232 called = []
243233
244234 async def trace (name , kwargs ):
245235 called .append (name )
246236
247- async with AsyncConnectionPool (network_backend = network_backend ) as pool :
237+ async with httpcore . AsyncConnectionPool (network_backend = network_backend ) as pool :
248238 # Sending an initial request, which once complete will not return to the pool.
249239 with pytest .raises (Exception ):
250240 await pool .request (
@@ -277,16 +267,18 @@ async def test_connection_pool_with_connect_exception():
277267 be returned to the connection pool.
278268 """
279269
280- class FailedConnectBackend (AsyncMockBackend ):
270+ class FailedConnectBackend (httpcore . AsyncMockBackend ):
281271 async def connect_tcp (
282272 self ,
283273 host : str ,
284274 port : int ,
285- timeout : Optional [float ] = None ,
286- local_address : Optional [str ] = None ,
287- socket_options : typing .Optional [typing .Iterable [SOCKET_OPTION ]] = None ,
288- ) -> AsyncNetworkStream :
289- raise ConnectError ("Could not connect" )
275+ timeout : typing .Optional [float ] = None ,
276+ local_address : typing .Optional [str ] = None ,
277+ socket_options : typing .Optional [
278+ typing .Iterable [httpcore .SOCKET_OPTION ]
279+ ] = None ,
280+ ) -> httpcore .AsyncNetworkStream :
281+ raise httpcore .ConnectError ("Could not connect" )
290282
291283 network_backend = FailedConnectBackend ([])
292284
@@ -295,7 +287,7 @@ async def connect_tcp(
295287 async def trace (name , kwargs ):
296288 called .append (name )
297289
298- async with AsyncConnectionPool (network_backend = network_backend ) as pool :
290+ async with httpcore . AsyncConnectionPool (network_backend = network_backend ) as pool :
299291 # Sending an initial request, which once complete will not return to the pool.
300292 with pytest .raises (Exception ):
301293 await pool .request (
@@ -317,7 +309,7 @@ async def test_connection_pool_with_immediate_expiry():
317309 Connection pools with keepalive_expiry=0.0 should immediately expire
318310 keep alive connections.
319311 """
320- network_backend = AsyncMockBackend (
312+ network_backend = httpcore . AsyncMockBackend (
321313 [
322314 b"HTTP/1.1 200 OK\r \n " ,
323315 b"Content-Type: plain/text\r \n " ,
@@ -327,7 +319,7 @@ async def test_connection_pool_with_immediate_expiry():
327319 ]
328320 )
329321
330- async with AsyncConnectionPool (
322+ async with httpcore . AsyncConnectionPool (
331323 keepalive_expiry = 0.0 ,
332324 network_backend = network_backend ,
333325 ) as pool :
@@ -351,7 +343,7 @@ async def test_connection_pool_with_no_keepalive_connections_allowed():
351343 When 'max_keepalive_connections=0' is used, IDLE connections should not
352344 be returned to the pool.
353345 """
354- network_backend = AsyncMockBackend (
346+ network_backend = httpcore . AsyncMockBackend (
355347 [
356348 b"HTTP/1.1 200 OK\r \n " ,
357349 b"Content-Type: plain/text\r \n " ,
@@ -361,7 +353,7 @@ async def test_connection_pool_with_no_keepalive_connections_allowed():
361353 ]
362354 )
363355
364- async with AsyncConnectionPool (
356+ async with httpcore . AsyncConnectionPool (
365357 max_keepalive_connections = 0 , network_backend = network_backend
366358 ) as pool :
367359 # Sending an intial request, which once complete will not return to the pool.
@@ -384,7 +376,7 @@ async def test_connection_pool_concurrency():
384376 HTTP/1.1 requests made in concurrency must not ever exceed the maximum number
385377 of allowable connection in the pool.
386378 """
387- network_backend = AsyncMockBackend (
379+ network_backend = httpcore . AsyncMockBackend (
388380 [
389381 b"HTTP/1.1 200 OK\r \n " ,
390382 b"Content-Type: plain/text\r \n " ,
@@ -400,10 +392,10 @@ async def fetch(pool, domain, info_list):
400392 info_list .append (info )
401393 await response .aread ()
402394
403- async with AsyncConnectionPool (
395+ async with httpcore . AsyncConnectionPool (
404396 max_connections = 1 , network_backend = network_backend
405397 ) as pool :
406- info_list : List [str ] = []
398+ info_list : typing . List [str ] = []
407399 async with concurrency .open_nursery () as nursery :
408400 for domain in ["a.com" , "b.com" , "c.com" , "d.com" , "e.com" ]:
409401 nursery .start_soon (fetch , pool , domain , info_list )
@@ -429,7 +421,7 @@ async def test_connection_pool_concurrency_same_domain_closing():
429421 HTTP/1.1 requests made in concurrency must not ever exceed the maximum number
430422 of allowable connection in the pool.
431423 """
432- network_backend = AsyncMockBackend (
424+ network_backend = httpcore . AsyncMockBackend (
433425 [
434426 b"HTTP/1.1 200 OK\r \n " ,
435427 b"Content-Type: plain/text\r \n " ,
@@ -446,10 +438,10 @@ async def fetch(pool, domain, info_list):
446438 info_list .append (info )
447439 await response .aread ()
448440
449- async with AsyncConnectionPool (
441+ async with httpcore . AsyncConnectionPool (
450442 max_connections = 1 , network_backend = network_backend , http2 = True
451443 ) as pool :
452- info_list : List [str ] = []
444+ info_list : typing . List [str ] = []
453445 async with concurrency .open_nursery () as nursery :
454446 for domain in ["a.com" , "a.com" , "a.com" , "a.com" , "a.com" ]:
455447 nursery .start_soon (fetch , pool , domain , info_list )
@@ -471,7 +463,7 @@ async def test_connection_pool_concurrency_same_domain_keepalive():
471463 HTTP/1.1 requests made in concurrency must not ever exceed the maximum number
472464 of allowable connection in the pool.
473465 """
474- network_backend = AsyncMockBackend (
466+ network_backend = httpcore . AsyncMockBackend (
475467 [
476468 b"HTTP/1.1 200 OK\r \n " ,
477469 b"Content-Type: plain/text\r \n " ,
@@ -488,10 +480,10 @@ async def fetch(pool, domain, info_list):
488480 info_list .append (info )
489481 await response .aread ()
490482
491- async with AsyncConnectionPool (
483+ async with httpcore . AsyncConnectionPool (
492484 max_connections = 1 , network_backend = network_backend , http2 = True
493485 ) as pool :
494- info_list : List [str ] = []
486+ info_list : typing . List [str ] = []
495487 async with concurrency .open_nursery () as nursery :
496488 for domain in ["a.com" , "a.com" , "a.com" , "a.com" , "a.com" ]:
497489 nursery .start_soon (fetch , pool , domain , info_list )
@@ -512,11 +504,11 @@ async def fetch(pool, domain, info_list):
512504
513505@pytest .mark .anyio
514506async def test_unsupported_protocol ():
515- async with AsyncConnectionPool () as pool :
516- with pytest .raises (UnsupportedProtocol ):
507+ async with httpcore . AsyncConnectionPool () as pool :
508+ with pytest .raises (httpcore . UnsupportedProtocol ):
517509 await pool .request ("GET" , "ftp://www.example.com/" )
518510
519- with pytest .raises (UnsupportedProtocol ):
511+ with pytest .raises (httpcore . UnsupportedProtocol ):
520512 await pool .request ("GET" , "://www.example.com/" )
521513
522514
@@ -526,7 +518,7 @@ async def test_connection_pool_closed_while_request_in_flight():
526518 Closing a connection pool while a request/response is still in-flight
527519 should raise an error.
528520 """
529- network_backend = AsyncMockBackend (
521+ network_backend = httpcore . AsyncMockBackend (
530522 [
531523 b"HTTP/1.1 200 OK\r \n " ,
532524 b"Content-Type: plain/text\r \n " ,
@@ -536,14 +528,14 @@ async def test_connection_pool_closed_while_request_in_flight():
536528 ]
537529 )
538530
539- async with AsyncConnectionPool (
531+ async with httpcore . AsyncConnectionPool (
540532 network_backend = network_backend ,
541533 ) as pool :
542534 # Send a request, and then close the connection pool while the
543535 # response has not yet been streamed.
544536 async with pool .stream ("GET" , "https://example.com/" ) as response :
545537 await pool .aclose ()
546- with pytest .raises (ReadError ):
538+ with pytest .raises (httpcore . ReadError ):
547539 await response .aread ()
548540
549541
@@ -552,7 +544,7 @@ async def test_connection_pool_timeout():
552544 """
553545 Ensure that exceeding max_connections can cause a request to timeout.
554546 """
555- network_backend = AsyncMockBackend (
547+ network_backend = httpcore . AsyncMockBackend (
556548 [
557549 b"HTTP/1.1 200 OK\r \n " ,
558550 b"Content-Type: plain/text\r \n " ,
@@ -562,14 +554,14 @@ async def test_connection_pool_timeout():
562554 ]
563555 )
564556
565- async with AsyncConnectionPool (
557+ async with httpcore . AsyncConnectionPool (
566558 network_backend = network_backend , max_connections = 1
567559 ) as pool :
568560 # Send a request to a pool that is configured to only support a single
569561 # connection, and then ensure that a second concurrent request
570562 # fails with a timeout.
571563 async with pool .stream ("GET" , "https://example.com/" ):
572- with pytest .raises (PoolTimeout ):
564+ with pytest .raises (httpcore . PoolTimeout ):
573565 extensions = {"timeout" : {"pool" : 0.0001 }}
574566 await pool .request ("GET" , "https://example.com/" , extensions = extensions )
575567
@@ -580,7 +572,7 @@ async def test_connection_pool_timeout_zero():
580572 A pool timeout of 0 shouldn't raise a PoolTimeout if there's
581573 no need to wait on a new connection.
582574 """
583- network_backend = AsyncMockBackend (
575+ network_backend = httpcore . AsyncMockBackend (
584576 [
585577 b"HTTP/1.1 200 OK\r \n " ,
586578 b"Content-Type: plain/text\r \n " ,
@@ -599,7 +591,7 @@ async def test_connection_pool_timeout_zero():
599591 extensions = {"timeout" : {"pool" : 0 }}
600592
601593 # A connection pool configured to allow only one connection at a time.
602- async with AsyncConnectionPool (
594+ async with httpcore . AsyncConnectionPool (
603595 network_backend = network_backend , max_connections = 1
604596 ) as pool :
605597 # Two consecutive requests with a pool timeout of zero.
@@ -617,7 +609,7 @@ async def test_connection_pool_timeout_zero():
617609 assert response .content == b"Hello, world!"
618610
619611 # A connection pool configured to allow only one connection at a time.
620- async with AsyncConnectionPool (
612+ async with httpcore . AsyncConnectionPool (
621613 network_backend = network_backend , max_connections = 1
622614 ) as pool :
623615 # Two concurrent requests with a pool timeout of zero.
@@ -626,7 +618,7 @@ async def test_connection_pool_timeout_zero():
626618 "GET" , "https://example.com/" , extensions = extensions
627619 ) as response :
628620 # The first response hasn't yet completed.
629- with pytest .raises (PoolTimeout ):
621+ with pytest .raises (httpcore . PoolTimeout ):
630622 # So a pool timeout occurs.
631623 await pool .request ("GET" , "https://example.com/" , extensions = extensions )
632624 # The first response now completes.
@@ -647,7 +639,7 @@ async def test_http11_upgrade_connection():
647639 https://httpwg.org/specs/rfc9110.html#status.101
648640 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101
649641 """
650- network_backend = AsyncMockBackend (
642+ network_backend = httpcore . AsyncMockBackend (
651643 [
652644 b"HTTP/1.1 101 Switching Protocols\r \n " ,
653645 b"Connection: upgrade\r \n " ,
@@ -656,7 +648,7 @@ async def test_http11_upgrade_connection():
656648 b"..." ,
657649 ]
658650 )
659- async with AsyncConnectionPool (
651+ async with httpcore . AsyncConnectionPool (
660652 network_backend = network_backend , max_connections = 1
661653 ) as pool :
662654 async with pool .stream (
0 commit comments