Skip to content

Commit 8658faa

Browse files
Correct type of ClientRequest.body (#11011)
Co-authored-by: J. Nick Koston <[email protected]>
1 parent 1c01726 commit 8658faa

File tree

5 files changed

+21
-21
lines changed

5 files changed

+21
-21
lines changed

aiohttp/client_middleware_digest_auth.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ def __init__(
193193
self._nonce_count = 0
194194
self._challenge: DigestAuthChallenge = {}
195195

196-
async def _encode(self, method: str, url: URL, body: Union[bytes, Payload]) -> str:
196+
async def _encode(
197+
self, method: str, url: URL, body: Union[Payload, Literal[b""]]
198+
) -> str:
197199
"""
198200
Build digest authorization header for the current challenge.
199201
@@ -274,10 +276,10 @@ def KD(s: bytes, d: bytes) -> bytes:
274276
A1 = b":".join((self._login_bytes, realm_bytes, self._password_bytes))
275277
A2 = f"{method.upper()}:{path}".encode()
276278
if qop == "auth-int":
277-
if isinstance(body, bytes): # will always be empty bytes unless Payload
278-
entity_bytes = body
279-
else:
279+
if isinstance(body, Payload): # will always be empty bytes unless Payload
280280
entity_bytes = await body.as_bytes() # Get bytes from Payload
281+
else:
282+
entity_bytes = body
281283
entity_hash = H(entity_bytes)
282284
A2 = b":".join((A2, entity_hash))
283285

aiohttp/client_reqrep.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
Dict,
1818
Iterable,
1919
List,
20+
Literal,
2021
Mapping,
2122
NamedTuple,
2223
Optional,
@@ -393,7 +394,7 @@ def port(self) -> Optional[int]:
393394
return self.url.port
394395

395396
@property
396-
def body(self) -> Union[bytes, payload.Payload]:
397+
def body(self) -> Union[payload.Payload, Literal[b""]]:
397398
"""Request body."""
398399
# empty body is represented as bytes for backwards compatibility
399400
return self._body or b""

docs/client_reference.rst

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,12 +1866,9 @@ ClientRequest
18661866
For more information about using middleware, see :ref:`aiohttp-client-middleware`.
18671867

18681868
.. attribute:: body
1869-
:type: Payload | FormData
1869+
:type: Payload | Literal[b""]
18701870

1871-
The request body payload. This can be:
1872-
1873-
- A :class:`Payload` object for raw data (default is empty bytes ``b""``)
1874-
- A :class:`FormData` object for form submissions
1871+
The request body payload (defaults to ``b""`` if no body passed).
18751872

18761873
.. danger::
18771874

tests/test_client_middleware_digest_auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import io
44
from hashlib import md5, sha1
5-
from typing import Generator, Union
5+
from typing import Generator, Literal, Union
66
from unittest import mock
77

88
import pytest
@@ -270,7 +270,7 @@ def KD(secret: str, data: str) -> str:
270270
@pytest.mark.parametrize(
271271
("body", "body_str"),
272272
[
273-
(b"this is a body", "this is a body"), # Bytes case
273+
(b"", ""), # Bytes case
274274
(
275275
BytesIOPayload(io.BytesIO(b"this is a body")),
276276
"this is a body",
@@ -280,7 +280,7 @@ def KD(secret: str, data: str) -> str:
280280
async def test_digest_response_exact_match(
281281
qop: str,
282282
algorithm: str,
283-
body: Union[bytes, BytesIOPayload],
283+
body: Union[Literal[b""], BytesIOPayload],
284284
body_str: str,
285285
mock_sha1_digest: mock.MagicMock,
286286
) -> None:

tests/test_client_request.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,7 +1320,7 @@ async def test_oserror_on_write_bytes(
13201320
loop: asyncio.AbstractEventLoop, conn: mock.Mock
13211321
) -> None:
13221322
req = ClientRequest("POST", URL("http://python.org/"), loop=loop)
1323-
req.body = b"test data"
1323+
req.body = b"test data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
13241324

13251325
writer = WriterMock()
13261326
writer.write.side_effect = OSError
@@ -1668,7 +1668,7 @@ async def test_write_bytes_with_content_length_limit(
16681668
data = b"Hello World"
16691669
req = ClientRequest("post", URL("http://python.org/"), loop=loop)
16701670

1671-
req.body = data
1671+
req.body = data # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
16721672

16731673
writer = StreamWriter(protocol=conn.protocol, loop=loop)
16741674
# Use content_length=5 to truncate data
@@ -1705,7 +1705,7 @@ async def gen() -> AsyncIterator[bytes]:
17051705

17061706
req.body = gen() # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
17071707
else:
1708-
req.body = data
1708+
req.body = data # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
17091709

17101710
writer = StreamWriter(protocol=conn.protocol, loop=loop)
17111711
# Use content_length=7 to truncate at the middle of Part2
@@ -1755,7 +1755,7 @@ async def test_warn_if_unclosed_payload_via_body_setter(
17551755
ResourceWarning,
17561756
match="The previous request body contains unclosed resources",
17571757
):
1758-
req.body = b"new data"
1758+
req.body = b"new data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
17591759

17601760
await req.close()
17611761

@@ -1773,7 +1773,7 @@ async def test_no_warn_for_autoclose_payload_via_body_setter(
17731773
# Setting body again should not trigger warning since previous payload has autoclose=True
17741774
with warnings.catch_warnings(record=True) as warning_list:
17751775
warnings.simplefilter("always")
1776-
req.body = b"new data"
1776+
req.body = b"new data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
17771777

17781778
# Filter out any non-ResourceWarning warnings
17791779
resource_warnings = [
@@ -1803,7 +1803,7 @@ async def test_no_warn_for_consumed_payload_via_body_setter(
18031803
# Setting body again should not trigger warning since previous payload is consumed
18041804
with warnings.catch_warnings(record=True) as warning_list:
18051805
warnings.simplefilter("always")
1806-
req.body = b"new data"
1806+
req.body = b"new data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
18071807

18081808
# Filter out any non-ResourceWarning warnings
18091809
resource_warnings = [
@@ -1922,7 +1922,7 @@ async def test_body_setter_closes_previous_payload(
19221922
req._body = mock_payload
19231923

19241924
# Update body with new data using setter
1925-
req.body = b"new body data"
1925+
req.body = b"new body data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
19261926

19271927
# Verify the previous payload was closed using _close
19281928
mock_payload._close.assert_called_once()
@@ -2051,7 +2051,7 @@ async def test_warn_stacklevel_points_to_user_code(
20512051
with warnings.catch_warnings(record=True) as warning_list:
20522052
warnings.simplefilter("always", ResourceWarning)
20532053
# This line should be reported as the warning source
2054-
req.body = b"new data" # LINE TO BE REPORTED
2054+
req.body = b"new data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892 # LINE TO BE REPORTED
20552055

20562056
# Find the ResourceWarning
20572057
resource_warnings = [

0 commit comments

Comments
 (0)