Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion h11/_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ def trailing_data(self) -> Tuple[bytes, bool]:
"""
return (bytes(self._receive_buffer), self._receive_buffer_closed)

def receive_data(self, data: bytes) -> None:
def receive_data(self, data: Union[bytes, bytearray, memoryview]) -> None:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to use collections.abc.Buffer for Python >= 3.12, as introduced in PEP 688. Alternatively, you can use if typing.TYPE_CHECKING: from typing_extensions import Buffer, which avoids a runtime dependency on typing_extensions.

"""Add data to our internal receive buffer.
This does not actually do any processing on the data, just stores
Expand Down
4 changes: 3 additions & 1 deletion h11/_receivebuffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ def __init__(self) -> None:
self._next_line_search = 0
self._multiple_lines_search = 0

def __iadd__(self, byteslike: Union[bytes, bytearray]) -> "ReceiveBuffer":
def __iadd__(
self, byteslike: Union[bytes, bytearray, memoryview]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

) -> "ReceiveBuffer":
self._data += byteslike
return self

Expand Down
16 changes: 16 additions & 0 deletions h11/tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,22 @@ def test_chunk_boundaries() -> None:
assert conn.next_event() == EndOfMessage()


@pytest.mark.parametrize("data_wrapper", [bytearray, memoryview])
def test_receive_data_accepts_byteslike_objects(data_wrapper: Any) -> None:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this parameter need to be Any?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. This is just statistically generated spam. This account is brand new and spamming tonnes of projects

conn = Connection(our_role=SERVER)

conn.receive_data(
data_wrapper(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
)

assert conn.next_event() == Request(
method="GET",
target="/",
headers=[("Host", "example.com")],
)
assert conn.next_event() == EndOfMessage()


def test_client_talking_to_http10_server() -> None:
c = Connection(CLIENT)
c.send(Request(method="GET", target="/", headers=[("Host", "example.com")]))
Expand Down
2 changes: 2 additions & 0 deletions newsfragments/186.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Allow ``Connection.receive_data()`` to accept ``bytearray`` and
``memoryview`` inputs in its public type hints.