punkreq 0.2.4__tar.gz → 0.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 (49) hide show
  1. {punkreq-0.2.4 → punkreq-0.3.0}/PKG-INFO +3 -4
  2. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_connect.py +11 -23
  3. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_pool.py +5 -5
  4. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_proxies.py +5 -3
  5. punkreq-0.3.0/punkreq/_version.py +1 -0
  6. {punkreq-0.2.4 → punkreq-0.3.0}/pyproject.toml +3 -4
  7. punkreq-0.2.4/punkreq/_version.py +0 -1
  8. {punkreq-0.2.4 → punkreq-0.3.0}/.gitignore +0 -0
  9. {punkreq-0.2.4 → punkreq-0.3.0}/LICENSE +0 -0
  10. {punkreq-0.2.4 → punkreq-0.3.0}/README.md +0 -0
  11. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/__init__.py +0 -0
  12. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_auth.py +0 -0
  13. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_client.py +0 -0
  14. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_config.py +0 -0
  15. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_content.py +0 -0
  16. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_cookies.py +0 -0
  17. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_decoders.py +0 -0
  18. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_exceptions.py +0 -0
  19. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_headers.py +0 -0
  20. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_models.py +0 -0
  21. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_multipart.py +0 -0
  22. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_redirects.py +0 -0
  23. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_transport.py +0 -0
  24. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_urls.py +0 -0
  25. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/asyncio.py +0 -0
  26. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/py.typed +0 -0
  27. {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/tonio.py +0 -0
  28. {punkreq-0.2.4 → punkreq-0.3.0}/tests/__init__.py +0 -0
  29. {punkreq-0.2.4 → punkreq-0.3.0}/tests/conftest.py +0 -0
  30. {punkreq-0.2.4 → punkreq-0.3.0}/tests/e2e.py +0 -0
  31. {punkreq-0.2.4 → punkreq-0.3.0}/tests/fakes.py +0 -0
  32. {punkreq-0.2.4 → punkreq-0.3.0}/tests/servers.py +0 -0
  33. {punkreq-0.2.4 → punkreq-0.3.0}/tests/servers_tonio.py +0 -0
  34. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_client.py +0 -0
  35. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_config.py +0 -0
  36. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_connect.py +0 -0
  37. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_content.py +0 -0
  38. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_cookies.py +0 -0
  39. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_decoders.py +0 -0
  40. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_e2e_asyncio.py +0 -0
  41. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_e2e_tonio.py +0 -0
  42. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_exceptions.py +0 -0
  43. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_headers.py +0 -0
  44. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_models.py +0 -0
  45. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_multipart.py +0 -0
  46. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_pool.py +0 -0
  47. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_redirects.py +0 -0
  48. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_transport.py +0 -0
  49. {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_urls.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: punkreq
3
- Version: 0.2.4
3
+ Version: 0.3.0
4
4
  Summary: An async HTTP client built on httpunk
5
5
  Project-URL: Homepage, https://github.com/gi0baro/punkreq
6
6
  Project-URL: Funding, https://github.com/sponsors/gi0baro
@@ -15,7 +15,6 @@ Classifier: Intended Audience :: Developers
15
15
  Classifier: License :: OSI Approved :: BSD License
16
16
  Classifier: Operating System :: OS Independent
17
17
  Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
@@ -23,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.14
23
22
  Classifier: Programming Language :: Python :: 3.15
24
23
  Classifier: Programming Language :: Python :: Free Threading :: 3 - Stable
25
24
  Classifier: Topic :: Internet :: WWW/HTTP
26
- Requires-Python: >=3.10
27
- Requires-Dist: httpunk~=0.4.4
25
+ Requires-Python: >=3.11
26
+ Requires-Dist: httpunk~=0.5.0
28
27
  Provides-Extra: brotli
29
28
  Requires-Dist: brotli~=1.2.0; extra == 'brotli'
30
29
  Provides-Extra: tonio
@@ -11,7 +11,7 @@ from httpunk.h2.client import H2Connection
11
11
  from ._exceptions import ConnectError, UnsupportedProtocol
12
12
 
13
13
 
14
- __all__ = ["Connector", "Origin", "connect_errors", "create_ssl_context", "enter_connection", "origin_for_url"]
14
+ __all__ = ["Connector", "Origin", "connect_errors", "create_ssl_context", "origin_for_url"]
15
15
 
16
16
  DEFAULT_PORTS = {"http": 80, "https": 443}
17
17
 
@@ -94,19 +94,6 @@ def connect_errors(backend: typing.Any) -> tuple[type[BaseException], ...]:
94
94
  return (OSError, ssl.SSLError, HTTPunkError, *backend.broken_transport_errors)
95
95
 
96
96
 
97
- async def enter_connection(conn: typing.Any, transport: typing.Any, backend: typing.Any) -> typing.Any:
98
- """Run `conn`'s HTTP handshake (`__aenter__`) and return it. Until that
99
- completes the transport we dialed is still ours to close: httpunk closes
100
- it on `__aexit__`, which a failed or interrupted `__aenter__` never
101
- reaches (h2 waits there for the peer's SETTINGS, pumps already running)."""
102
- try:
103
- await conn.__aenter__()
104
- except BaseException:
105
- backend.close_transport(transport)
106
- raise
107
- return conn
108
-
109
-
110
97
  class Connector:
111
98
  """The default connector: dial `origin` and return the protocol-matching
112
99
  httpunk connection, entered."""
@@ -142,14 +129,15 @@ class Connector:
142
129
  async def __call__(self, origin: Origin) -> H1Connection | H2Connection:
143
130
  try:
144
131
  if origin.scheme == "https":
145
- conn, stream = await self._connect_tls(origin)
132
+ conn = await self._connect_tls(origin)
146
133
  else:
147
- conn, stream = await self._connect_tcp(origin)
148
- return await enter_connection(conn, stream, self._backend)
134
+ conn = await self._connect_tcp(origin)
135
+ await conn.__aenter__()
136
+ return conn
149
137
  except connect_errors(self._backend) as exc:
150
138
  raise ConnectError(f"Failed to connect to {origin}: {exc}")
151
139
 
152
- async def _connect_tls(self, origin: Origin) -> tuple[H1Connection | H2Connection, typing.Any]:
140
+ async def _connect_tls(self, origin: Origin) -> H1Connection | H2Connection:
153
141
  # our context already carries the offer; a backend-created default one
154
142
  # (no context given) is configured per dial
155
143
  alpn = None if self._ssl_context is not None else self.alpn
@@ -157,12 +145,12 @@ class Connector:
157
145
  origin.host, origin.port, alpn=alpn, ssl_context=self._ssl_context
158
146
  )
159
147
  if selected == "h2" or not self._http1:
160
- return H2Connection(stream, authority=origin.authority, scheme="https", backend=self._backend), stream
161
- return H1Connection(stream, authority=origin.authority, backend=self._backend), stream
148
+ return H2Connection(stream, authority=origin.authority, scheme="https", backend=self._backend)
149
+ return H1Connection(stream, authority=origin.authority, backend=self._backend)
162
150
 
163
- async def _connect_tcp(self, origin: Origin) -> tuple[H1Connection | H2Connection, typing.Any]:
151
+ async def _connect_tcp(self, origin: Origin) -> H1Connection | H2Connection:
164
152
  stream = await self._backend.connect_tcp(origin.host, origin.port)
165
153
  if not self._http1:
166
154
  # h2 prior knowledge over cleartext (reqwest's http2_prior_knowledge)
167
- return H2Connection(stream, authority=origin.authority, scheme="http", backend=self._backend), stream
168
- return H1Connection(stream, authority=origin.authority, backend=self._backend), stream
155
+ return H2Connection(stream, authority=origin.authority, scheme="http", backend=self._backend)
156
+ return H1Connection(stream, authority=origin.authority, backend=self._backend)
@@ -11,14 +11,14 @@ Concept mapping (hyper-util `client/pool/*.rs` ≡ `httpunk.util.pool` ≡ here)
11
11
  ≡ `_HostState.shared` + `.dialing` + `.mode`. Waiters re-attempt internally
12
12
  instead of surfacing `Canceled` — the same retry-by-calling-again
13
13
  semantics. A closed shared conn is ditched and redialed at checkout
14
- (`Singled::poll_ready` reset; httpunk F35).
14
+ (`Singled::poll_ready` reset, as httpunk's `Singleton` does).
15
15
  * `Cache` (idle set, drop-returns-to-cache) ≡ `_HostState.idle` + `release()`.
16
16
  The park check (`discard or closed or busy`) matches httpunk's `_Lease`:
17
17
  `closed` mirrors `Cached::poll_ready`-sets-`is_closed` + `Drop` skipping
18
- the put; `busy` is the runtime-forced extra (httpunk D3); closing on a
19
- failed exchange instead of re-parking is httpunk's F51 choice. Like
20
- httpunk's `Cache` (F50), there is no checkout-vs-connect race: an empty
21
- idle set dials directly.
18
+ the put; `busy` is the runtime-forced extra httpunk also adds; closing on
19
+ a failed exchange instead of re-parking is httpunk's choice too. Like
20
+ httpunk's `Cache`, there is no checkout-vs-connect race: an empty idle
21
+ set dials directly.
22
22
 
23
23
  Policy layered on top (owner-owned, per the modern pool's design — its only
24
24
  culling surface is `Cache::retain(predicate)`, everything else is the
@@ -10,7 +10,7 @@ from httpunk.h2.client import H2Connection
10
10
  from httpunk.util.proxy import Matcher
11
11
 
12
12
  from ._config import Proxy
13
- from ._connect import Connector, Origin, connect_errors, enter_connection
13
+ from ._connect import Connector, Origin, connect_errors
14
14
  from ._exceptions import ConnectError, ProxyError
15
15
  from ._headers import Headers
16
16
  from ._urls import URL
@@ -112,7 +112,8 @@ class ProxyConnector:
112
112
  transport = await self._dial_proxy(intercept)
113
113
  conn = H1Connection(transport, authority=origin.authority, backend=self._backend)
114
114
  setattr(conn, PROXY_ATTR, ProxyInfo(auth=intercept.basic_auth(), headers=self._config.headers))
115
- return await enter_connection(conn, transport, self._backend)
115
+ await conn.__aenter__()
116
+ return conn
116
117
 
117
118
  async def _tunnel(self, origin: Origin, intercept: typing.Any) -> typing.Any:
118
119
  transport = await self._dial_proxy(intercept)
@@ -152,4 +153,5 @@ class ProxyConnector:
152
153
  conn = H2Connection(tls, authority=origin.authority, scheme="https", backend=self._backend)
153
154
  else:
154
155
  conn = H1Connection(tls, authority=origin.authority, backend=self._backend)
155
- return await enter_connection(conn, tls, self._backend)
156
+ await conn.__aenter__()
157
+ return conn
@@ -0,0 +1 @@
1
+ __version__ = "0.3.0"
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "punkreq"
7
- version = "0.2.4"
7
+ version = "0.3.0"
8
8
  description = "An async HTTP client built on httpunk"
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
11
- requires-python = ">=3.10"
11
+ requires-python = ">=3.11"
12
12
 
13
13
  authors = [
14
14
  { name = "Giovanni Barillari", email = "g@baro.dev" }
@@ -22,7 +22,6 @@ classifiers = [
22
22
  "Operating System :: OS Independent",
23
23
  "Programming Language :: Python :: Free Threading :: 3 - Stable",
24
24
  "Programming Language :: Python :: 3",
25
- "Programming Language :: Python :: 3.10",
26
25
  "Programming Language :: Python :: 3.11",
27
26
  "Programming Language :: Python :: 3.12",
28
27
  "Programming Language :: Python :: 3.13",
@@ -32,7 +31,7 @@ classifiers = [
32
31
  ]
33
32
 
34
33
  dependencies = [
35
- "httpunk~=0.4.4",
34
+ "httpunk~=0.5.0",
36
35
  ]
37
36
 
38
37
  [project.optional-dependencies]
@@ -1 +0,0 @@
1
- __version__ = "0.2.4"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes