Skip to content

Commit

Permalink
Update types for h11 v0.14 (#579)
Browse files Browse the repository at this point in the history
* Update setup.py

Allow for h11 V. 013. Facilitates installation alongside latest version of Uvicorn.

* Bump h11 pin to 0.14

* Remove reassignment of `event` to prevent type failure

* Add an explicit check for `None` in `_send_event`

This also reverted commit f9a9847
which was dropped during rebase with the `master` branch.

We probably do not want to suggest that passing `None` to
the `write` function is proper. The short circuit there (return on
empty buffer) should be targeted to an empty byte array.

* Replace h11 event with new base class type; add stubs for PAUSED handling

* Lint; add cast for return type

* apply unasync

* do not attempt to handle paused in _receive_event

* Bump h11 upper bound to 0.15

* Update types to support h11 0.14.0

* Bump minimum h11 requirement to 0.13

0.12 does not define `h11.Event`

* Update `_send_event` to narrow accepted types

* Lint

Co-authored-by: Francis Secada <francis.secada@gmail.com>
Co-authored-by: Tom Christie <tom@tomchristie.com>
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
  • Loading branch information
5 people committed Sep 27, 2022
1 parent 809f168 commit 4cf288e
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 23 deletions.
32 changes: 21 additions & 11 deletions httpcore/_async/http11.py
@@ -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

Expand All @@ -17,13 +26,11 @@
from ..backends.base import AsyncNetworkStream
from .interfaces import AsyncConnectionInterface

H11Event = Union[
# A subset of `h11.Event` types supported by `_send_event`
H11SendEvent = Union[
h11.Request,
h11.Response,
h11.InformationalResponse,
h11.Data,
h11.EndOfMessage,
h11.ConnectionClosed,
]


Expand Down Expand Up @@ -127,14 +134,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...

Expand Down Expand Up @@ -168,7 +175,9 @@ 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, Type[h11.PAUSED]]:
while True:
with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}):
event = self._h11_state.next_event()
Expand All @@ -192,7 +201,8 @@ async def _receive_event(self, timeout: Optional[float] = None) -> H11Event:

self._h11_state.receive_data(data)
else:
return event
# mypy fails to narrow the type in the above if statement above
return cast(Union[h11.Event, Type[h11.PAUSED]], event)

async def _response_closed(self) -> None:
async with self._state_lock:
Expand Down
32 changes: 21 additions & 11 deletions httpcore/_sync/http11.py
@@ -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

Expand All @@ -17,13 +26,11 @@
from ..backends.base import NetworkStream
from .interfaces import ConnectionInterface

H11Event = Union[
# A subset of `h11.Event` types supported by `_send_event`
H11SendEvent = Union[
h11.Request,
h11.Response,
h11.InformationalResponse,
h11.Data,
h11.EndOfMessage,
h11.ConnectionClosed,
]


Expand Down Expand Up @@ -127,14 +134,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
) -> 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:
self._network_stream.write(bytes_to_send, timeout=timeout)

# Receiving the response...

Expand Down Expand Up @@ -168,7 +175,9 @@ 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, Type[h11.PAUSED]]:
while True:
with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}):
event = self._h11_state.next_event()
Expand All @@ -192,7 +201,8 @@ def _receive_event(self, timeout: Optional[float] = None) -> H11Event:

self._h11_state.receive_data(data)
else:
return event
# mypy fails to narrow the type in the above if statement above
return cast(Union[h11.Event, Type[h11.PAUSED]], event)

def _response_closed(self) -> None:
with self._state_lock:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -54,7 +54,7 @@ def get_packages(package):
include_package_data=True,
zip_safe=False,
install_requires=[
"h11>=0.11,<0.13",
"h11>=0.13,<0.15",
"sniffio==1.*",
"anyio==3.*",
"certifi",
Expand Down

0 comments on commit 4cf288e

Please sign in to comment.