httpcore2 2.1.0__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {httpcore2-2.1.0 → httpcore2-2.3.0}/CHANGELOG.md +17 -4
  2. {httpcore2-2.1.0 → httpcore2-2.3.0}/PKG-INFO +24 -15
  3. {httpcore2-2.1.0 → httpcore2-2.3.0}/README.md +1 -5
  4. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/__init__.py +2 -2
  5. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/__init__.py +2 -2
  6. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/connection_pool.py +56 -43
  7. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/http11.py +2 -2
  8. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/http2.py +7 -7
  9. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/http_proxy.py +1 -1
  10. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/interfaces.py +8 -8
  11. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/socks_proxy.py +8 -8
  12. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_backends/anyio.py +5 -5
  13. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_backends/auto.py +2 -2
  14. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_backends/base.py +16 -16
  15. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_backends/sync.py +10 -8
  16. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_backends/trio.py +3 -3
  17. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_exceptions.py +1 -1
  18. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_models.py +12 -12
  19. httpcore2-2.3.0/httpcore2/_ssl.py +12 -0
  20. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/__init__.py +2 -2
  21. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/connection_pool.py +56 -43
  22. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/http11.py +2 -2
  23. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/http2.py +7 -7
  24. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/http_proxy.py +1 -1
  25. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/interfaces.py +8 -8
  26. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/socks_proxy.py +8 -8
  27. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_synchronization.py +10 -10
  28. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_utils.py +3 -3
  29. {httpcore2-2.1.0 → httpcore2-2.3.0}/pyproject.toml +7 -6
  30. httpcore2-2.1.0/httpcore2/_ssl.py +0 -9
  31. {httpcore2-2.1.0 → httpcore2-2.3.0}/.gitignore +0 -0
  32. {httpcore2-2.1.0 → httpcore2-2.3.0}/LICENSE.md +0 -0
  33. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_api.py +0 -0
  34. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_async/connection.py +0 -0
  35. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_backends/__init__.py +0 -0
  36. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_backends/mock.py +0 -0
  37. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_sync/connection.py +0 -0
  38. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/_trace.py +0 -0
  39. {httpcore2-2.1.0 → httpcore2-2.3.0}/httpcore2/py.typed +0 -0
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
6
 
7
+ ## 2.3.0 (June 1st, 2026)
8
+
9
+ ### Changed
10
+
11
+ * Use `truststore` instead of `certifi` for default SSL verification, loading the operating system's trust store. ([#1002](https://github.com/pydantic/httpx2/pull/1002))
12
+ * Rewrite `_assign_requests_to_connections` as a single-pass loop. ([#974](https://github.com/pydantic/httpx2/pull/974))
13
+ * Use `anyio`'s `fast_acquire` for `Lock` and `Semaphore`. ([#970](https://github.com/pydantic/httpx2/pull/970))
14
+ * Use `memoryview` in `write()` to avoid copies. ([#954](https://github.com/pydantic/httpx2/pull/954))
15
+
16
+ ## 2.2.0 (May 16th, 2026)
17
+
18
+ No changes since `2.1.0`. Version bumped to stay in lockstep with `httpx2`.
19
+
7
20
  ## 2.1.0 (May 15th, 2026)
8
21
 
9
22
  ### Removed
@@ -60,7 +73,7 @@ Historical entries below are from upstream `encode/httpcore`.
60
73
  ## 1.0.5 (March 27th, 2024)
61
74
 
62
75
  - Handle `EndOfStream` exception for anyio backend. (#899)
63
- - Allow trio `0.25.*` series in package dependancies. (#903)
76
+ - Allow trio `0.25.*` series in package dependencies. (#903)
64
77
 
65
78
  ## 1.0.4 (February 21st, 2024)
66
79
 
@@ -138,7 +151,7 @@ The project versioning policy is now explicitly governed by SEMVER. See https://
138
151
  - Allow `ws` and `wss` schemes. Allows us to properly support websocket upgrade connections. (#625)
139
152
  - Forwarding HTTP proxies use a connection-per-remote-host. Required by some proxy implementations. (#637)
140
153
  - Don't raise `RuntimeError` when closing a connection pool with active connections. Removes some error cases when cancellations are used. (#631)
141
- - Lazy import `anyio`, so that it's no longer a hard dependancy, and isn't imported if unused. (#639)
154
+ - Lazy import `anyio`, so that it's no longer a hard dependency, and isn't imported if unused. (#639)
142
155
 
143
156
  ## 0.16.2 (November 25th, 2022)
144
157
 
@@ -196,7 +209,7 @@ The project versioning policy is now explicitly governed by SEMVER. See https://
196
209
  ## 0.14.1 (November 12th, 2021)
197
210
 
198
211
  - `max_connections` becomes optional. (Pull #429)
199
- - `certifi` is now included in the install dependancies. (Pull #428)
212
+ - `certifi` is now included in the install dependencies. (Pull #428)
200
213
  - `h2` is now strictly optional. (Pull #428)
201
214
 
202
215
  ## 0.14.0 (November 11th, 2021)
@@ -261,7 +274,7 @@ Note that `curio` support is not currently available in 0.14.0. If you're using
261
274
 
262
275
  ### Fixed
263
276
 
264
- - More resiliant testing for closed connections. (Pull #311)
277
+ - More resilient testing for closed connections. (Pull #311)
265
278
  - Don't raise exceptions on ungraceful connection closes. (Pull #310)
266
279
 
267
280
  ## 0.13.0 (April 21st, 2021)
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpcore2
3
- Version: 2.1.0
3
+ Version: 2.3.0
4
4
  Summary: A minimal low-level HTTP client.
5
- Project-URL: Documentation, https://www.encode.io/httpcore
6
- Project-URL: Homepage, https://www.encode.io/httpcore/
7
- Project-URL: Source, https://github.com/encode/httpcore
5
+ Project-URL: Changelog, https://github.com/pydantic/httpx2/blob/main/src/httpcore2/CHANGELOG.md
6
+ Project-URL: Homepage, https://github.com/pydantic/httpx2
7
+ Project-URL: Source, https://github.com/pydantic/httpx2/blob/main/src/httpcore2
8
8
  Author-email: Tom Christie <tom@tomchristie.com>
9
9
  Maintainer-email: "Pydantic Services Inc." <engineering@pydantic.dev>
10
10
  License-Expression: BSD-3-Clause
@@ -25,10 +25,10 @@ Classifier: Programming Language :: Python :: 3.13
25
25
  Classifier: Programming Language :: Python :: 3.14
26
26
  Classifier: Topic :: Internet :: WWW/HTTP
27
27
  Requires-Python: >=3.10
28
- Requires-Dist: certifi
29
28
  Requires-Dist: h11>=0.16
29
+ Requires-Dist: truststore>=0.10
30
30
  Provides-Extra: asyncio
31
- Requires-Dist: anyio<5.0,>=4.0; extra == 'asyncio'
31
+ Requires-Dist: anyio<5.0,>=4.5.0; extra == 'asyncio'
32
32
  Provides-Extra: http2
33
33
  Requires-Dist: h2<5,>=3; extra == 'http2'
34
34
  Provides-Extra: socks
@@ -62,10 +62,6 @@ Some things HTTP Core does do:
62
62
  * Provides both sync and async interfaces.
63
63
  * Async backend support for `asyncio` and `trio`.
64
64
 
65
- ## Requirements
66
-
67
- Python 3.8+
68
-
69
65
  ## Installation
70
66
 
71
67
  For HTTP/1.1 only support, install with:
@@ -128,7 +124,7 @@ The motivation for `httpcore` is:
128
124
  The `httpcore` package has the following dependencies...
129
125
 
130
126
  * `h11`
131
- * `certifi`
127
+ * `truststore`
132
128
 
133
129
  And the following optional extras...
134
130
 
@@ -154,6 +150,19 @@ All notable changes to this project will be documented in this file.
154
150
 
155
151
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
156
152
 
153
+ ## 2.3.0 (June 1st, 2026)
154
+
155
+ ### Changed
156
+
157
+ * Use `truststore` instead of `certifi` for default SSL verification, loading the operating system's trust store. ([#1002](https://github.com/pydantic/httpx2/pull/1002))
158
+ * Rewrite `_assign_requests_to_connections` as a single-pass loop. ([#974](https://github.com/pydantic/httpx2/pull/974))
159
+ * Use `anyio`'s `fast_acquire` for `Lock` and `Semaphore`. ([#970](https://github.com/pydantic/httpx2/pull/970))
160
+ * Use `memoryview` in `write()` to avoid copies. ([#954](https://github.com/pydantic/httpx2/pull/954))
161
+
162
+ ## 2.2.0 (May 16th, 2026)
163
+
164
+ No changes since `2.1.0`. Version bumped to stay in lockstep with `httpx2`.
165
+
157
166
  ## 2.1.0 (May 15th, 2026)
158
167
 
159
168
  ### Removed
@@ -210,7 +219,7 @@ Historical entries below are from upstream `encode/httpcore`.
210
219
  ## 1.0.5 (March 27th, 2024)
211
220
 
212
221
  - Handle `EndOfStream` exception for anyio backend. (#899)
213
- - Allow trio `0.25.*` series in package dependancies. (#903)
222
+ - Allow trio `0.25.*` series in package dependencies. (#903)
214
223
 
215
224
  ## 1.0.4 (February 21st, 2024)
216
225
 
@@ -288,7 +297,7 @@ The project versioning policy is now explicitly governed by SEMVER. See https://
288
297
  - Allow `ws` and `wss` schemes. Allows us to properly support websocket upgrade connections. (#625)
289
298
  - Forwarding HTTP proxies use a connection-per-remote-host. Required by some proxy implementations. (#637)
290
299
  - Don't raise `RuntimeError` when closing a connection pool with active connections. Removes some error cases when cancellations are used. (#631)
291
- - Lazy import `anyio`, so that it's no longer a hard dependancy, and isn't imported if unused. (#639)
300
+ - Lazy import `anyio`, so that it's no longer a hard dependency, and isn't imported if unused. (#639)
292
301
 
293
302
  ## 0.16.2 (November 25th, 2022)
294
303
 
@@ -346,7 +355,7 @@ The project versioning policy is now explicitly governed by SEMVER. See https://
346
355
  ## 0.14.1 (November 12th, 2021)
347
356
 
348
357
  - `max_connections` becomes optional. (Pull #429)
349
- - `certifi` is now included in the install dependancies. (Pull #428)
358
+ - `certifi` is now included in the install dependencies. (Pull #428)
350
359
  - `h2` is now strictly optional. (Pull #428)
351
360
 
352
361
  ## 0.14.0 (November 11th, 2021)
@@ -411,7 +420,7 @@ Note that `curio` support is not currently available in 0.14.0. If you're using
411
420
 
412
421
  ### Fixed
413
422
 
414
- - More resiliant testing for closed connections. (Pull #311)
423
+ - More resilient testing for closed connections. (Pull #311)
415
424
  - Don't raise exceptions on ungraceful connection closes. (Pull #310)
416
425
 
417
426
  ## 0.13.0 (April 21st, 2021)
@@ -23,10 +23,6 @@ Some things HTTP Core does do:
23
23
  * Provides both sync and async interfaces.
24
24
  * Async backend support for `asyncio` and `trio`.
25
25
 
26
- ## Requirements
27
-
28
- Python 3.8+
29
-
30
26
  ## Installation
31
27
 
32
28
  For HTTP/1.1 only support, install with:
@@ -89,7 +85,7 @@ The motivation for `httpcore` is:
89
85
  The `httpcore` package has the following dependencies...
90
86
 
91
87
  * `h11`
92
- * `certifi`
88
+ * `truststore`
93
89
 
94
90
  And the following optional extras...
95
91
 
@@ -51,7 +51,7 @@ from ._sync import (
51
51
  # The 'httpcore2.AnyIOBackend' class is conditional on 'anyio' being installed.
52
52
  try:
53
53
  from ._backends.anyio import AnyIOBackend
54
- except ImportError: # pragma: nocover
54
+ except ImportError: # pragma: no cover
55
55
 
56
56
  class AnyIOBackend: # type: ignore
57
57
  def __init__(self, *args, **kwargs): # type: ignore
@@ -62,7 +62,7 @@ except ImportError: # pragma: nocover
62
62
  # The 'httpcore2.TrioBackend' class is conditional on 'trio' being installed.
63
63
  try:
64
64
  from ._backends.trio import TrioBackend
65
- except ImportError: # pragma: nocover
65
+ except ImportError: # pragma: no cover
66
66
 
67
67
  class TrioBackend: # type: ignore
68
68
  def __init__(self, *args, **kwargs): # type: ignore
@@ -6,7 +6,7 @@ from .interfaces import AsyncConnectionInterface
6
6
 
7
7
  try:
8
8
  from .http2 import AsyncHTTP2Connection
9
- except ImportError: # pragma: nocover
9
+ except ImportError: # pragma: no cover
10
10
 
11
11
  class AsyncHTTP2Connection: # type: ignore
12
12
  def __init__(self, *args, **kwargs) -> None: # type: ignore
@@ -18,7 +18,7 @@ except ImportError: # pragma: nocover
18
18
 
19
19
  try:
20
20
  from .socks_proxy import AsyncSOCKSProxy
21
- except ImportError: # pragma: nocover
21
+ except ImportError: # pragma: no cover
22
22
 
23
23
  class AsyncSOCKSProxy: # type: ignore
24
24
  def __init__(self, *args, **kwargs) -> None: # type: ignore
@@ -229,7 +229,7 @@ class AsyncConnectionPool(AsyncRequestInterface):
229
229
  # In this case we clear the connection and try again.
230
230
  pool_request.clear_connection()
231
231
  else:
232
- break # pragma: nocover
232
+ break # pragma: no cover
233
233
 
234
234
  except BaseException as exc:
235
235
  with self._optional_thread_lock:
@@ -259,38 +259,49 @@ class AsyncConnectionPool(AsyncRequestInterface):
259
259
  Called whenever a new request is added or removed from the pool.
260
260
 
261
261
  Any closing connections are returned, allowing the I/O for closing
262
- those connections to be handled seperately.
262
+ those connections to be handled separately.
263
263
  """
264
- closing_connections = []
264
+ closing_connections: list[AsyncConnectionInterface] = []
265
+ retained_connections: list[AsyncConnectionInterface] = []
265
266
 
266
- # First we handle cleaning up any connections that are closed,
267
- # have expired their keep-alive, or surplus idle connections.
268
- for connection in list(self._connections):
267
+ # First we handle cleaning up any connections that are closed
268
+ # or have expired their keep-alive, in a single pass.
269
+ for connection in self._connections:
269
270
  if connection.is_closed():
270
- # log: "removing closed connection"
271
- self._connections.remove(connection)
271
+ continue
272
272
  elif connection.has_expired():
273
- # log: "closing expired connection"
274
- self._connections.remove(connection)
275
- closing_connections.append(connection)
276
- elif (
277
- connection.is_idle()
278
- and sum(connection.is_idle() for connection in self._connections) > self._max_keepalive_connections
279
- ):
280
- # log: "closing idle connection"
281
- self._connections.remove(connection)
282
273
  closing_connections.append(connection)
274
+ else:
275
+ retained_connections.append(connection)
276
+
277
+ # Then we close any surplus idle connections, to enforce the
278
+ # max_keepalive_connections setting.
279
+ idle_surplus = (
280
+ sum(connection.is_idle() for connection in retained_connections) - self._max_keepalive_connections
281
+ )
282
+ if idle_surplus > 0:
283
+ kept: list[AsyncConnectionInterface] = []
284
+ for connection in retained_connections:
285
+ if idle_surplus > 0 and connection.is_idle():
286
+ closing_connections.append(connection)
287
+ idle_surplus -= 1
288
+ else:
289
+ kept.append(connection)
290
+ retained_connections = kept
291
+
292
+ self._connections = retained_connections
293
+
294
+ # Snapshot the set of reusable connections once, rather than rebuilding
295
+ # it per queued request — this is what brings the loop from O(N*M) to
296
+ # O(N+M) in the common case.
297
+ available_connections = [connection for connection in self._connections if connection.is_available()]
298
+ new_connection_budget = self._max_connections - len(self._connections)
283
299
 
284
300
  # Assign queued requests to connections.
285
- queued_requests = [request for request in self._requests if request.is_queued()]
286
- for pool_request in queued_requests:
301
+ for pool_request in self._requests:
302
+ if not pool_request.is_queued():
303
+ continue
287
304
  origin = pool_request.request.url.origin
288
- available_connections = [
289
- connection
290
- for connection in self._connections
291
- if connection.can_handle_request(origin) and connection.is_available()
292
- ]
293
- idle_connections = [connection for connection in self._connections if connection.is_idle()]
294
305
 
295
306
  # There are three cases for how we may be able to handle the request:
296
307
  #
@@ -298,24 +309,26 @@ class AsyncConnectionPool(AsyncRequestInterface):
298
309
  # 2. We can create a new connection to handle the request.
299
310
  # 3. We can close an idle connection and then create a new connection
300
311
  # to handle the request.
301
- if available_connections:
302
- # log: "reusing existing connection"
303
- connection = available_connections[0]
304
- pool_request.assign_to_connection(connection)
305
- elif len(self._connections) < self._max_connections:
306
- # log: "creating new connection"
307
- connection = self.create_connection(origin)
308
- self._connections.append(connection)
309
- pool_request.assign_to_connection(connection)
310
- elif idle_connections:
311
- # log: "closing idle connection"
312
- connection = idle_connections[0]
313
- self._connections.remove(connection)
314
- closing_connections.append(connection)
315
- # log: "creating new connection"
316
- connection = self.create_connection(origin)
317
- self._connections.append(connection)
318
- pool_request.assign_to_connection(connection)
312
+ for connection in available_connections:
313
+ if connection.can_handle_request(origin):
314
+ pool_request.assign_to_connection(connection)
315
+ break
316
+ else:
317
+ if new_connection_budget > 0:
318
+ connection = self.create_connection(origin)
319
+ self._connections.append(connection)
320
+ pool_request.assign_to_connection(connection)
321
+ new_connection_budget -= 1
322
+ continue
323
+ for idx, connection in enumerate(available_connections):
324
+ if connection.is_idle():
325
+ del available_connections[idx]
326
+ self._connections.remove(connection)
327
+ closing_connections.append(connection)
328
+ connection = self.create_connection(origin)
329
+ self._connections.append(connection)
330
+ pool_request.assign_to_connection(connection)
331
+ break
319
332
 
320
333
  return closing_connections
321
334
 
@@ -85,9 +85,9 @@ class AsyncHTTP11Connection(AsyncConnectionInterface):
85
85
  await self._send_request_body(**kwargs)
86
86
  except WriteError:
87
87
  # If we get a write error while we're writing the request,
88
- # then we supress this error and move on to attempting to
88
+ # then we suppress this error and move on to attempting to
89
89
  # read the response. Servers can sometimes close the request
90
- # pre-emptively and then respond with a well formed HTTP
90
+ # preemptively and then respond with a well formed HTTP
91
91
  # error response.
92
92
  pass
93
93
 
@@ -120,7 +120,7 @@ class AsyncHTTP2Connection(AsyncConnectionInterface):
120
120
  try:
121
121
  stream_id = self._h2_state.get_next_available_stream_id()
122
122
  self._events[stream_id] = []
123
- except h2.exceptions.NoAvailableStreamIDError: # pragma: nocover
123
+ except h2.exceptions.NoAvailableStreamIDError: # pragma: no cover
124
124
  self._used_all_stream_ids = True
125
125
  self._request_count -= 1
126
126
  raise ConnectionNotAvailable()
@@ -161,11 +161,11 @@ class AsyncHTTP2Connection(AsyncConnectionInterface):
161
161
  #
162
162
  # In this case we'll have stored the event, and should raise
163
163
  # it as a RemoteProtocolError.
164
- if self._connection_terminated: # pragma: nocover
164
+ if self._connection_terminated: # pragma: no cover
165
165
  raise RemoteProtocolError(self._connection_terminated)
166
166
  # If h2 raises a protocol error in some other state then we
167
167
  # must somehow have made a protocol violation.
168
- raise LocalProtocolError(exc) # pragma: nocover
168
+ raise LocalProtocolError(exc) # pragma: no cover
169
169
 
170
170
  raise exc
171
171
 
@@ -387,7 +387,7 @@ class AsyncHTTP2Connection(AsyncConnectionInterface):
387
387
  if self._keepalive_expiry is not None:
388
388
  now = time.monotonic()
389
389
  self._expire_at = now + self._keepalive_expiry
390
- if self._used_all_stream_ids: # pragma: nocover
390
+ if self._used_all_stream_ids: # pragma: no cover
391
391
  await self.aclose()
392
392
 
393
393
  async def aclose(self) -> None:
@@ -404,7 +404,7 @@ class AsyncHTTP2Connection(AsyncConnectionInterface):
404
404
  timeout = timeouts.get("read", None)
405
405
 
406
406
  if self._read_exception is not None:
407
- raise self._read_exception # pragma: nocover
407
+ raise self._read_exception # pragma: no cover
408
408
 
409
409
  try:
410
410
  data = await self._network_stream.read(self.READ_NUM_BYTES, timeout)
@@ -435,11 +435,11 @@ class AsyncHTTP2Connection(AsyncConnectionInterface):
435
435
  data_to_send = self._h2_state.data_to_send()
436
436
 
437
437
  if self._write_exception is not None:
438
- raise self._write_exception # pragma: nocover
438
+ raise self._write_exception # pragma: no cover
439
439
 
440
440
  try:
441
441
  await self._network_stream.write(data_to_send, timeout)
442
- except Exception as exc: # pragma: nocover
442
+ except Exception as exc: # pragma: no cover
443
443
  # If we get a network error we should:
444
444
  #
445
445
  # 1. Save the exception and just raise it immediately on any future write.
@@ -47,7 +47,7 @@ def merge_headers(
47
47
  return default_headers + override_headers
48
48
 
49
49
 
50
- class AsyncHTTPProxy(AsyncConnectionPool): # pragma: nocover
50
+ class AsyncHTTPProxy(AsyncConnectionPool): # pragma: no cover
51
51
  """
52
52
  A connection pool that sends requests via an HTTP proxy.
53
53
  """
@@ -82,18 +82,18 @@ class AsyncRequestInterface:
82
82
  await response.aclose()
83
83
 
84
84
  async def handle_async_request(self, request: Request) -> Response:
85
- raise NotImplementedError() # pragma: nocover
85
+ raise NotImplementedError() # pragma: no cover
86
86
 
87
87
 
88
88
  class AsyncConnectionInterface(AsyncRequestInterface):
89
89
  async def aclose(self) -> None:
90
- raise NotImplementedError() # pragma: nocover
90
+ raise NotImplementedError() # pragma: no cover
91
91
 
92
92
  def info(self) -> str:
93
- raise NotImplementedError() # pragma: nocover
93
+ raise NotImplementedError() # pragma: no cover
94
94
 
95
95
  def can_handle_request(self, origin: Origin) -> bool:
96
- raise NotImplementedError() # pragma: nocover
96
+ raise NotImplementedError() # pragma: no cover
97
97
 
98
98
  def is_available(self) -> bool:
99
99
  """
@@ -111,7 +111,7 @@ class AsyncConnectionInterface(AsyncRequestInterface):
111
111
  required exceptions if multiple requests are attempted over a connection
112
112
  that ends up being established as HTTP/1.1.
113
113
  """
114
- raise NotImplementedError() # pragma: nocover
114
+ raise NotImplementedError() # pragma: no cover
115
115
 
116
116
  def has_expired(self) -> bool:
117
117
  """
@@ -120,13 +120,13 @@ class AsyncConnectionInterface(AsyncRequestInterface):
120
120
  This either means that the connection is idle and it has passed the
121
121
  expiry time on its keep-alive, or that server has sent an EOF.
122
122
  """
123
- raise NotImplementedError() # pragma: nocover
123
+ raise NotImplementedError() # pragma: no cover
124
124
 
125
125
  def is_idle(self) -> bool:
126
126
  """
127
127
  Return `True` if the connection is currently idle.
128
128
  """
129
- raise NotImplementedError() # pragma: nocover
129
+ raise NotImplementedError() # pragma: no cover
130
130
 
131
131
  def is_closed(self) -> bool:
132
132
  """
@@ -135,4 +135,4 @@ class AsyncConnectionInterface(AsyncRequestInterface):
135
135
  Used when a response is closed to determine if the connection may be
136
136
  returned to the connection pool or not.
137
137
  """
138
- raise NotImplementedError() # pragma: nocover
138
+ raise NotImplementedError() # pragma: no cover
@@ -96,7 +96,7 @@ async def _init_socks5_connection(
96
96
  raise ProxyError(f"Proxy Server could not connect: {reply_code}.")
97
97
 
98
98
 
99
- class AsyncSOCKSProxy(AsyncConnectionPool): # pragma: nocover
99
+ class AsyncSOCKSProxy(AsyncConnectionPool): # pragma: no cover
100
100
  """
101
101
  A connection pool that sends requests via an HTTP proxy.
102
102
  """
@@ -254,7 +254,7 @@ class AsyncSocks5Connection(AsyncConnectionInterface):
254
254
  http2_negotiated = ssl_object is not None and ssl_object.selected_alpn_protocol() == "h2"
255
255
 
256
256
  # Create the HTTP/1.1 or HTTP/2 connection
257
- if http2_negotiated or (self._http2 and not self._http1): # pragma: nocover
257
+ if http2_negotiated or (self._http2 and not self._http1): # pragma: no cover
258
258
  from .http2 import AsyncHTTP2Connection
259
259
 
260
260
  self._connection = AsyncHTTP2Connection(
@@ -271,7 +271,7 @@ class AsyncSocks5Connection(AsyncConnectionInterface):
271
271
  except Exception as exc:
272
272
  self._connect_failed = True
273
273
  raise exc
274
- elif not self._connection.is_available(): # pragma: nocover
274
+ elif not self._connection.is_available(): # pragma: no cover
275
275
  raise ConnectionNotAvailable()
276
276
 
277
277
  return await self._connection.handle_async_request(request)
@@ -284,7 +284,7 @@ class AsyncSocks5Connection(AsyncConnectionInterface):
284
284
  await self._connection.aclose()
285
285
 
286
286
  def is_available(self) -> bool:
287
- if self._connection is None: # pragma: nocover
287
+ if self._connection is None: # pragma: no cover
288
288
  # If HTTP/2 support is enabled, and the resulting connection could
289
289
  # end up as HTTP/2 then we should indicate the connection as being
290
290
  # available to service multiple requests.
@@ -294,22 +294,22 @@ class AsyncSocks5Connection(AsyncConnectionInterface):
294
294
  return self._connection.is_available()
295
295
 
296
296
  def has_expired(self) -> bool:
297
- if self._connection is None: # pragma: nocover
297
+ if self._connection is None: # pragma: no cover
298
298
  return self._connect_failed
299
299
  return self._connection.has_expired()
300
300
 
301
301
  def is_idle(self) -> bool:
302
- if self._connection is None: # pragma: nocover
302
+ if self._connection is None: # pragma: no cover
303
303
  return self._connect_failed
304
304
  return self._connection.is_idle()
305
305
 
306
306
  def is_closed(self) -> bool:
307
- if self._connection is None: # pragma: nocover
307
+ if self._connection is None: # pragma: no cover
308
308
  return self._connect_failed
309
309
  return self._connection.is_closed()
310
310
 
311
311
  def info(self) -> str:
312
- if self._connection is None: # pragma: nocover
312
+ if self._connection is None: # pragma: no cover
313
313
  return "CONNECTION FAILED" if self._connect_failed else "CONNECTING"
314
314
  return self._connection.info()
315
315
 
@@ -33,7 +33,7 @@ class AnyIOStream(AsyncNetworkStream):
33
33
  with anyio.fail_after(timeout):
34
34
  try:
35
35
  return await self._stream.receive(max_bytes=max_bytes)
36
- except anyio.EndOfStream: # pragma: nocover
36
+ except anyio.EndOfStream: # pragma: no cover
37
37
  return b""
38
38
 
39
39
  async def write(self, buffer: bytes, timeout: float | None = None) -> None:
@@ -74,7 +74,7 @@ class AnyIOStream(AsyncNetworkStream):
74
74
  standard_compatible=False,
75
75
  server_side=False,
76
76
  )
77
- except Exception as exc: # pragma: nocover
77
+ except Exception as exc: # pragma: no cover
78
78
  await self.aclose()
79
79
  raise exc
80
80
  return AnyIOStream(ssl_stream)
@@ -102,7 +102,7 @@ class AnyIOBackend(AsyncNetworkBackend):
102
102
  timeout: float | None = None,
103
103
  local_address: str | None = None,
104
104
  socket_options: typing.Iterable[SOCKET_OPTION] | None = None,
105
- ) -> AsyncNetworkStream: # pragma: nocover
105
+ ) -> AsyncNetworkStream: # pragma: no cover
106
106
  if socket_options is None:
107
107
  socket_options = []
108
108
  exc_map = {
@@ -127,7 +127,7 @@ class AnyIOBackend(AsyncNetworkBackend):
127
127
  path: str,
128
128
  timeout: float | None = None,
129
129
  socket_options: typing.Iterable[SOCKET_OPTION] | None = None,
130
- ) -> AsyncNetworkStream: # pragma: nocover
130
+ ) -> AsyncNetworkStream: # pragma: no cover
131
131
  if socket_options is None:
132
132
  socket_options = []
133
133
  exc_map = {
@@ -143,4 +143,4 @@ class AnyIOBackend(AsyncNetworkBackend):
143
143
  return AnyIOStream(stream)
144
144
 
145
145
  async def sleep(self, seconds: float) -> None:
146
- await anyio.sleep(seconds) # pragma: nocover
146
+ await anyio.sleep(seconds) # pragma: no cover
@@ -41,10 +41,10 @@ class AutoBackend(AsyncNetworkBackend):
41
41
  path: str,
42
42
  timeout: float | None = None,
43
43
  socket_options: typing.Iterable[SOCKET_OPTION] | None = None,
44
- ) -> AsyncNetworkStream: # pragma: nocover
44
+ ) -> AsyncNetworkStream: # pragma: no cover
45
45
  await self._init_backend()
46
46
  return await self._backend.connect_unix_socket(path, timeout=timeout, socket_options=socket_options)
47
47
 
48
- async def sleep(self, seconds: float) -> None: # pragma: nocover
48
+ async def sleep(self, seconds: float) -> None: # pragma: no cover
49
49
  await self._init_backend()
50
50
  return await self._backend.sleep(seconds)