-
Notifications
You must be signed in to change notification settings - Fork 116
Update types for h11 v0.13 #526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7811c8b
6664449
4207b8b
3c46a89
ca728c2
4de236c
4347599
ce52141
71cc46d
1ed1413
668dce8
f42eab9
2a10a07
13b733b
e3c6335
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,7 +1,16 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import enum | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import time | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from types import TracebackType | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import AsyncIterable, AsyncIterator, List, Optional, Tuple, Type, Union | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
AsyncIterable, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
AsyncIterator, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
List, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Optional, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tuple, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Type, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Union, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cast, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import h11 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -17,15 +26,6 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from ..backends.base import AsyncNetworkStream | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from .interfaces import AsyncConnectionInterface | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
H11Event = Union[ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
h11.Request, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
h11.Response, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
h11.InformationalResponse, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
h11.Data, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
h11.EndOfMessage, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
h11.ConnectionClosed, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class HTTPConnectionState(enum.IntEnum): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NEW = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -127,14 +127,14 @@ async def _send_request_body(self, request: Request) -> None: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
event = h11.Data(data=chunk) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._send_event(event, timeout=timeout) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
event = h11.EndOfMessage() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._send_event(event, timeout=timeout) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._send_event(h11.EndOfMessage(), timeout=timeout) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def _send_event( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self, event: H11Event, timeout: Optional[float] = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self, event: h11.Event, timeout: Optional[float] = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes_to_send = self._h11_state.send(event) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._network_stream.write(bytes_to_send, timeout=timeout) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if bytes_to_send is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._network_stream.write(bytes_to_send, timeout=timeout) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Receiving the response... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -168,12 +168,18 @@ async def _receive_response_body(self, request: Request) -> AsyncIterator[bytes] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
break | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def _receive_event(self, timeout: Optional[float] = None) -> H11Event: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def _receive_event( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self, timeout: Optional[float] = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> Union[h11.Event, h11.PAUSED]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while True: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
event = self._h11_state.next_event() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# The h11 type signature uses a private return type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
event = cast( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Union[h11.Event, h11.NEED_DATA, h11.PAUSED], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self._h11_state.next_event(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if event is h11.NEED_DATA: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if isinstance(event, h11.NEED_DATA): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+177
to
+182
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I worry how much this cast and isinstance will slow stuff down - as this is a hot loop There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can hack around this by moving the cast outside the loop, but I'd want other maintainers to have a think on what's best here httpcore/httpcore/_async/http11.py Lines 30 to 49 in 627db6c
httpcore/httpcore/_async/http11.py Lines 195 to 207 in 627db6c
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data = await self._network_stream.read( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.READ_NUM_BYTES, timeout=timeout | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,7 +1,16 @@ | ||||||
import enum | ||||||
import time | ||||||
from types import TracebackType | ||||||
from typing import Iterable, Iterator, List, Optional, Tuple, Type, Union | ||||||
from typing import ( | ||||||
Iterable, | ||||||
Iterator, | ||||||
List, | ||||||
Optional, | ||||||
Tuple, | ||||||
Type, | ||||||
Union, | ||||||
cast, | ||||||
) | ||||||
|
||||||
import h11 | ||||||
|
||||||
|
@@ -17,15 +26,6 @@ | |||||
from ..backends.base import NetworkStream | ||||||
from .interfaces import ConnectionInterface | ||||||
|
||||||
H11Event = Union[ | ||||||
h11.Request, | ||||||
h11.Response, | ||||||
h11.InformationalResponse, | ||||||
h11.Data, | ||||||
h11.EndOfMessage, | ||||||
h11.ConnectionClosed, | ||||||
] | ||||||
|
||||||
|
||||||
class HTTPConnectionState(enum.IntEnum): | ||||||
NEW = 0 | ||||||
|
@@ -127,14 +127,14 @@ def _send_request_body(self, request: Request) -> None: | |||||
event = h11.Data(data=chunk) | ||||||
self._send_event(event, timeout=timeout) | ||||||
|
||||||
event = h11.EndOfMessage() | ||||||
self._send_event(event, timeout=timeout) | ||||||
self._send_event(h11.EndOfMessage(), timeout=timeout) | ||||||
|
||||||
def _send_event( | ||||||
self, event: H11Event, timeout: Optional[float] = None | ||||||
self, event: h11.Event, timeout: Optional[float] = None | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we still want our send_event to have a specific allowlist of events we send:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 makes sense to me. Seems like we would need this with the overload for correct typing. |
||||||
) -> None: | ||||||
bytes_to_send = self._h11_state.send(event) | ||||||
self._network_stream.write(bytes_to_send, timeout=timeout) | ||||||
if bytes_to_send is not None: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 I'll see if I can contribute that upstream There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oof, this would actually be a pretty big change upstream as the following is not a valid overload: @overload
def send(self, event: ConnectionClosed) -> None:
...
@overload
def send(self, event: Event) -> bytes:
...
def send(self, event: Event) -> Optional[bytes]:
We'd need to introduce a separate base type (like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm also exploring a generic SendType = TypeVar('SendType', None, bytes)
class Event(ABC, Generic[SendType]):
...
class Foo(Event[bytes]):
...
class ConnectionClosed(Event[None]):
... but this would break type-checks for any downstream library that uses
|
||||||
self._network_stream.write(bytes_to_send, timeout=timeout) | ||||||
|
||||||
# Receiving the response... | ||||||
|
||||||
|
@@ -168,12 +168,18 @@ def _receive_response_body(self, request: Request) -> Iterator[bytes]: | |||||
elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): | ||||||
break | ||||||
|
||||||
def _receive_event(self, timeout: Optional[float] = None) -> H11Event: | ||||||
def _receive_event( | ||||||
self, timeout: Optional[float] = None | ||||||
) -> Union[h11.Event, h11.PAUSED]: | ||||||
while True: | ||||||
with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): | ||||||
event = self._h11_state.next_event() | ||||||
# The h11 type signature uses a private return type | ||||||
event = cast( | ||||||
Union[h11.Event, h11.NEED_DATA, h11.PAUSED], | ||||||
self._h11_state.next_event(), | ||||||
) | ||||||
|
||||||
if event is h11.NEED_DATA: | ||||||
if isinstance(event, h11.NEED_DATA): | ||||||
data = self._network_stream.read( | ||||||
self.READ_NUM_BYTES, timeout=timeout | ||||||
) | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I need to do this on uvicorn as well? 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if you do following release of python-hyper/h11#144 which updates that function's signature with narrowed return types.