From 0d23ada8a44b65a1da2eec204d246d87196d58f6 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 26 Mar 2025 07:30:44 +0000 Subject: [PATCH 1/4] use ruff check --- scripts/lint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/lint b/scripts/lint index e40524f52..fc02e475a 100755 --- a/scripts/lint +++ b/scripts/lint @@ -8,7 +8,7 @@ export SOURCE_FILES="httpcore tests" set -x -${PREFIX}ruff --fix $SOURCE_FILES +${PREFIX}ruff check --fix $SOURCE_FILES ${PREFIX}ruff format $SOURCE_FILES # Run unasync last because its `--check` mode is not aware of code formatters. From 67c6f70014ee6ffe0e6d26b52cf20f893840e6d2 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 26 Mar 2025 07:43:49 +0000 Subject: [PATCH 2/4] fix mypy --- httpcore/_async/http2.py | 31 ++++++++++++++++++++++--------- httpcore/_sync/http2.py | 31 ++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/httpcore/_async/http2.py b/httpcore/_async/http2.py index c6434a049..39ac89c4c 100644 --- a/httpcore/_async/http2.py +++ b/httpcore/_async/http2.py @@ -67,10 +67,12 @@ def __init__( # Mapping from stream ID to response stream events. self._events: dict[ int, - h2.events.ResponseReceived - | h2.events.DataReceived - | h2.events.StreamEnded - | h2.events.StreamReset, + list[ + h2.events.ResponseReceived + | h2.events.DataReceived + | h2.events.StreamEnded + | h2.events.StreamReset, + ], ] = {} # Connection terminated events are stored as state since @@ -102,9 +104,11 @@ async def handle_async_request(self, request: Request) -> Response: async with self._init_lock: if not self._sent_connection_init: try: - kwargs = {"request": request} - async with Trace("send_connection_init", logger, request, kwargs): - await self._send_connection_init(**kwargs) + sci_kwargs = {"request": request} + async with Trace( + "send_connection_init", logger, request, sci_kwargs + ): + await self._send_connection_init(**sci_kwargs) except BaseException as exc: with AsyncShieldCancellation(): await self.aclose() @@ -291,6 +295,9 @@ async def _receive_response( if isinstance(event, h2.events.ResponseReceived): break + if event.headers is None: + return (200, []) + status_code = 200 headers = [] for k, v in event.headers: @@ -309,7 +316,11 @@ async def _receive_response_body( """ while True: event = await self._receive_stream_event(request, stream_id) - if isinstance(event, h2.events.DataReceived): + if ( + isinstance(event, h2.events.DataReceived) + and event.flow_controlled_length is not None + and event.data is not None + ): amount = event.flow_controlled_length self._h2_state.acknowledge_received_data(amount, stream_id) await self._write_outgoing_data(request) @@ -380,7 +391,9 @@ async def _receive_events( await self._write_outgoing_data(request) - async def _receive_remote_settings_change(self, event: h2.events.Event) -> None: + async def _receive_remote_settings_change( + self, event: h2.events.RemoteSettingsChanged + ) -> None: max_concurrent_streams = event.changed_settings.get( h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS ) diff --git a/httpcore/_sync/http2.py b/httpcore/_sync/http2.py index ca4dd7243..f9897d3ef 100644 --- a/httpcore/_sync/http2.py +++ b/httpcore/_sync/http2.py @@ -67,10 +67,12 @@ def __init__( # Mapping from stream ID to response stream events. self._events: dict[ int, - h2.events.ResponseReceived - | h2.events.DataReceived - | h2.events.StreamEnded - | h2.events.StreamReset, + list[ + h2.events.ResponseReceived + | h2.events.DataReceived + | h2.events.StreamEnded + | h2.events.StreamReset, + ], ] = {} # Connection terminated events are stored as state since @@ -102,9 +104,11 @@ def handle_request(self, request: Request) -> Response: with self._init_lock: if not self._sent_connection_init: try: - kwargs = {"request": request} - with Trace("send_connection_init", logger, request, kwargs): - self._send_connection_init(**kwargs) + sci_kwargs = {"request": request} + with Trace( + "send_connection_init", logger, request, sci_kwargs + ): + self._send_connection_init(**sci_kwargs) except BaseException as exc: with ShieldCancellation(): self.close() @@ -291,6 +295,9 @@ def _receive_response( if isinstance(event, h2.events.ResponseReceived): break + if event.headers is None: + return (200, []) + status_code = 200 headers = [] for k, v in event.headers: @@ -309,7 +316,11 @@ def _receive_response_body( """ while True: event = self._receive_stream_event(request, stream_id) - if isinstance(event, h2.events.DataReceived): + if ( + isinstance(event, h2.events.DataReceived) + and event.flow_controlled_length is not None + and event.data is not None + ): amount = event.flow_controlled_length self._h2_state.acknowledge_received_data(amount, stream_id) self._write_outgoing_data(request) @@ -380,7 +391,9 @@ def _receive_events( self._write_outgoing_data(request) - def _receive_remote_settings_change(self, event: h2.events.Event) -> None: + def _receive_remote_settings_change( + self, event: h2.events.RemoteSettingsChanged + ) -> None: max_concurrent_streams = event.changed_settings.get( h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS ) From cd452314360c66a1f8928bee8931165f3874c2d9 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 26 Mar 2025 07:46:32 +0000 Subject: [PATCH 3/4] upgrade twine and build --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index ba9471708..880330c6f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,8 +9,8 @@ mkdocstrings[python-legacy]==0.25.1 jinja2==3.1.4 # Packaging -build==1.2.1 -twine==5.1.1 +build==1.2.2.post1 +twine==6.1.0 # Tests & Linting coverage[toml]==7.5.4 From e9785c81dd29a3264f2257eb8ff22cfb9e3f0800 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 26 Mar 2025 07:49:00 +0000 Subject: [PATCH 4/4] use an assert for mypy None, rather than an if (for coverage) --- httpcore/_async/http2.py | 12 ++++-------- httpcore/_sync/http2.py | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/httpcore/_async/http2.py b/httpcore/_async/http2.py index 39ac89c4c..dbd0beeb4 100644 --- a/httpcore/_async/http2.py +++ b/httpcore/_async/http2.py @@ -295,11 +295,9 @@ async def _receive_response( if isinstance(event, h2.events.ResponseReceived): break - if event.headers is None: - return (200, []) - status_code = 200 headers = [] + assert event.headers is not None for k, v in event.headers: if k == b":status": status_code = int(v.decode("ascii", errors="ignore")) @@ -316,11 +314,9 @@ async def _receive_response_body( """ while True: event = await self._receive_stream_event(request, stream_id) - if ( - isinstance(event, h2.events.DataReceived) - and event.flow_controlled_length is not None - and event.data is not None - ): + if isinstance(event, h2.events.DataReceived): + assert event.flow_controlled_length is not None + assert event.data is not None amount = event.flow_controlled_length self._h2_state.acknowledge_received_data(amount, stream_id) await self._write_outgoing_data(request) diff --git a/httpcore/_sync/http2.py b/httpcore/_sync/http2.py index f9897d3ef..ddcc18900 100644 --- a/httpcore/_sync/http2.py +++ b/httpcore/_sync/http2.py @@ -295,11 +295,9 @@ def _receive_response( if isinstance(event, h2.events.ResponseReceived): break - if event.headers is None: - return (200, []) - status_code = 200 headers = [] + assert event.headers is not None for k, v in event.headers: if k == b":status": status_code = int(v.decode("ascii", errors="ignore")) @@ -316,11 +314,9 @@ def _receive_response_body( """ while True: event = self._receive_stream_event(request, stream_id) - if ( - isinstance(event, h2.events.DataReceived) - and event.flow_controlled_length is not None - and event.data is not None - ): + if isinstance(event, h2.events.DataReceived): + assert event.flow_controlled_length is not None + assert event.data is not None amount = event.flow_controlled_length self._h2_state.acknowledge_received_data(amount, stream_id) self._write_outgoing_data(request)