8000 Merge branch 'master' into add-connection-documentation · encode/httpcore@167b1e3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 167b1e3

Browse files
authored
Merge branch 'master' into add-connection-documentation
2 parents 1dd04a4 + 9c818e9 commit 167b1e3

File tree

7 files changed

+43
-75
lines changed

7 files changed

+43
-75
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

7-
## Unreleased
7+
## 1.0.1 (November 3rd, 2023)
88

99
- Fix pool timeout to account for the total time spent retrying. (#823)
10+
- Raise a neater RuntimeError when the correct async deps are not installed. (#826)
11+
- Add support for synchronous TLS-in-TLS streams. (#840)
1012

11-
## 1.0.0 (November 6th, 2023)
13+
## 1.0.0 (October 6th, 2023)
1214

1315
From version 1.0 our async support is now optional, as the package has minimal dependencies by default.
1416

httpcore/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def __init__(self, *args, **kwargs): # type: ignore
130130
"WriteError",
131131
]
132132

133-
__version__ = "1.0.0"
133+
__version__ = "1.0.1"
134134

135135

136136
__locals = locals()

httpcore/_async/connection_pool.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,10 @@ async def aclose(self) -> None:
326326
self._requests = []
327327

328328
async def __aenter__(self) -> "AsyncConnectionPool":
329+
# Acquiring the pool lock here ensures that we have the
E7F5 330+
# correct dependencies installed as early as possible.
331+
async with self._pool_lock:
332+
pass
329333
return self
330334

331335
async def __aexit__(

httpcore/_backends/sync.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,6 @@ def start_tls(
145145
server_hostname: typing.Optional[str] = None,
146146
timeout: typing.Optional[float] = None,
147147
) -> NetworkStream:
148-
if isinstance(self._sock, ssl.SSLSocket): # pragma: no cover
149-
raise RuntimeError(
150-
"Attempted to add a TLS layer on top of the existing "
151-
"TLS stream, which is not supported by httpcore package"
152-
)
153-
154148
exc_map: ExceptionMapping = {
155149
socket.timeout: ConnectTimeout,
156150
OSError: ConnectError,

httpcore/_sync/connection_pool.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,10 @@ def close(self) -> None:
326326
self._requests = []
327327

328328
def __enter__(self) -> "ConnectionPool":
329+
# Acquiring the pool lock here ensures that we have the
330+
# correct dependencies installed as early as possible.
331+
with self._pool_lock:
332+
pass
329333
return self
330334

331335
def __exit__(

httpcore/_synchronization.py

Lines changed: 25 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,23 @@ def current_async_library() -> str:
2424
try:
2525
import sniffio
2626
except ImportError: # pragma: nocover
27-
return "asyncio"
28-
29-
environment = sniffio.current_async_library()
27+
environment = "asyncio"
28+
else:
29+
environment = sniffio.current_async_library()
3030

3131
if environment not in ("asyncio", "trio"): # pragma: nocover
3232
raise RuntimeError("Running under an unsupported async environment.")
3333

34+
if environment == "asyncio" and anyio is None: # pragma: nocover
35+
raise RuntimeError(
36+
"Running with asyncio requires installation of 'httpcore[asyncio]'."
37+
)
38+
39+
if environment == "trio" and trio is None: # pragma: nocover
40+
raise RuntimeError(
41+
"Running with trio requires installation of 'httpcore[trio]'."
42+
)
43+
3444
return environment
3545

3646

@@ -45,16 +55,8 @@ def setup(self) -> None:
4555
"""
4656
self._backend = current_async_library()
4757
if self._backend == "trio":
48-
if trio is None: # pragma: nocover
49-
raise RuntimeError(
50-
"Running with trio requires installation of 'httpcore[trio]'."
51-
)
5258
self._trio_lock = trio.Lock()
53-
else:
54-
if anyio is None: # pragma: nocover
55-
raise RuntimeError(
56-
"Running with asyncio requires installation of 'httpcore[asyncio]'."
57-
)
59+
elif self._backend == "asyncio":
5860
self._anyio_lock = anyio.Lock()
5961

6062
async def __aenter__(self) -> "AsyncLock":
@@ -63,7 +65,7 @@ async def __aenter__(self) -> "AsyncLock":
6365

6466
if self._backend == "trio":
6567
await self._trio_lock.acquire()
66-
else:
68+
elif self._backend == "asyncio":
6769
await self._anyio_lock.acquire()
6870

6971
return self
@@ -76,7 +78,7 @@ async def __aexit__(
7678
) -> None:
7779
if self._backend == "trio":
7880
self._trio_lock.release()
79-
else:
81+
elif self._backend == "asyncio":
8082
self._anyio_lock.release()
8183

8284

@@ -91,16 +93,8 @@ def setup(self) -> None:
9193
"""
9294
self._backend = current_async_library()
9395
if self._backend == "trio":
94-
if trio is None: # pragma: nocover
95-
raise RuntimeError(
96-
"Running with trio requires installation of 'httpcore[trio]'."
97-
)
9896
self._trio_event = trio.Event()
99-
else:
100-
if anyio is None: # pragma: nocover
101-
raise RuntimeError(
102-
"Running with asyncio requires installation of 'httpcore[asyncio]'."
103-
)
97+
elif self._backend == "asyncio":
10498
self._anyio_event = anyio.Event()
10599

106100
def set(self) -> None:
@@ -109,30 +103,20 @@ def set(self) -> None:
109103

110104
if self._backend == "trio":
111105
self._trio_event.set()
112-
else:
106+
elif self._backend == "asyncio":
113107
self._anyio_event.set()
114108

115109
async def wait(self, timeout: Optional[float] = None) -> None:
116110
if not self._backend:
117111
self.setup()
118112

119113
if self._backend == "trio":
120-
if trio is None: # pragma: nocover
121-
raise RuntimeError(
122-
"Running with trio requires installation of 'httpcore[trio]'."
123-
)
124-
125114
trio_exc_map: ExceptionMapping = {trio.TooSlowError: PoolTimeout}
126115
timeout_or_inf = float("inf") if timeout is None else timeout
127116
with map_exceptions(trio_exc_map):
128117
with trio.fail_after(timeout_or_inf):
129118
await self._trio_event.wait()
130-
else:
131-
if anyio is None: # pragma: nocover
132-
raise RuntimeError(
133-
"Running with asyncio requires installation of 'httpcore[asyncio]'."
134-
)
135-
119+
elif self._backend == "asyncio":
136120
anyio_exc_map: ExceptionMapping = {TimeoutError: PoolTimeout}
137121
with map_exceptions(anyio_exc_map):
138122
with anyio.fail_after(timeout):
@@ -151,20 +135,10 @@ def setup(self) -> None:
151135
"""
152136
self._backend = current_async_library()
153137
if self._backend == "trio":
154-
if trio is None: # pragma: nocover
155-
raise RuntimeError(
156-
"Running with trio requires installation of 'httpcore[trio]'."
157-
)
158-
159138
self._trio_semaphore = trio.Semaphore(
160139
initial_value=self._bound, max_value=self._bound
161140
)
162-
else:
163-
if anyio is None: # pragma: nocover
164-
raise RuntimeError(
165-
"Running with asyncio requires installation of 'httpcore[asyncio]'."
166-
)
167-
141+
elif self._backend == "asyncio":
168142
self._anyio_semaphore = anyio.Semaphore(
169143
initial_value=self._bound, max_value=self._bound
170144
)
@@ -175,13 +149,13 @@ async def acquire(self) -> None:
175149

176150
if self._backend == "trio":
177151
await self._trio_semaphore.acquire()
178-
else:
152+
elif self._backend == "asyncio":
179153
await self._anyio_semaphore.acquire()
180154

181155
async def release(self) -> None:
182156
if self._backend == "trio":
183157
self._trio_semaphore.release()
184-
else:
158+
elif self._backend == "asyncio":
185159
self._anyio_semaphore.release()
186160

187161

@@ -201,24 +175,14 @@ def __init__(self) -> None:
201175
self._backend = current_async_library()
202176

203177
if self._backend == "trio":
204-
if trio is None: # pragma: nocover
205-
raise RuntimeError(
206-
"Running with trio requires installation of 'httpcore[trio]'."
207-
)
208-
209178
self._trio_shield = trio.CancelScope(shield=True)
210-
else:
211-
if anyio is None: # pragma: nocover
212-
raise RuntimeError(
213-
"Running with asyncio requires installation of 'httpcore[asyncio]'."
214-
)
215-
179+
elif self._backend == "asyncio":
216180
self._anyio_shield = anyio.CancelScope(shield=True)
217181

218182
def __enter__(self) -> "AsyncShieldCancellation":
219183
if self._backend == "trio":
220184
self._trio_shield.__enter__()
221-
else:
185+
elif self._backend == "asyncio":
222186
self._anyio_shield.__enter__()
223187
return self
224188

@@ -230,7 +194,7 @@ def __exit__(
230194
) -> None:
231195
if self._backend == "trio":
232196
self._trio_shield.__exit__(exc_type, exc_value, traceback)
233-
else:
197+
elif self._backend == "asyncio":
234198
self._anyio_shield.__exit__(exc_type, exc_value, traceback)
235199

236200

requirements.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# Docs
44
mkdocs==1.5.3
55
mkdocs-autorefs==0.5.0
6-
mkdocs-material==9.4.2
7-
mkdocs-material-extensions==1.2
6+
mkdocs-material==9.4.7
7+
mkdocs-material-extensions==1.3
88
mkdocstrings[python-legacy]==0.22.0
99
jinja2==3.1.2
1010

@@ -13,13 +13,13 @@ build==1.0.3
1313
twine
1414

1515
# Tests & Linting
16-
black==23.7.0
16+
black==23.10.1
1717
coverage[toml]==7.3.0
1818
ruff==0.0.291
1919
mypy==1.5.1
20-
trio-typing==0.8.0
20+
trio-typing==0.9.0
2121
types-certifi==2021.10.8.3
22-
pytest==7.4.0
22+
pytest==7.4.3
2323
pytest-httpbin==2.0.0
2424
pytest-trio==0.7.0
2525
werkzeug<2.1 # See: https://github.com/postmanlabs/httpbin/issues/673

0 commit comments

Comments
 (0)
0