Skip to content

Commit 6d13ccc

Browse files
patchback[bot]Dreamsorcererbdraco
authored
[PR #11011/8658faad backport][3.12] Correct type of ClientRequest.body (#11023)
Co-authored-by: Sam Bull <[email protected]> Co-authored-by: J. Nick Koston <[email protected]>
1 parent ee8f1c4 commit 6d13ccc

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,
@@ -459,7 +460,7 @@ def port(self) -> Optional[int]:
459460
return self.url.port
460461

461462
@property
462-
def body(self) -> Union[bytes, payload.Payload]:
463+
def body(self) -> Union[payload.Payload, Literal[b""]]:
463464
"""Request body."""
464465
# empty body is represented as bytes for backwards compatibility
465466
return self._body or b""

docs/client_reference.rst

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

18841884
.. attribute:: body
1885-
:type: Payload | FormData
1885+
:type: Payload | Literal[b""]
18861886

1887-
The request body payload. This can be:
1888-
1889-
- A :class:`Payload` object for raw data (default is empty bytes ``b""``)
1890-
- A :class:`FormData` object for form submissions
1887+
The request body payload (defaults to ``b""`` if no body passed).
18911888

18921889
.. danger::
18931890

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
@@ -1261,7 +1261,7 @@ def read(self, decode=False):
12611261

12621262
async def test_oserror_on_write_bytes(loop, conn) -> None:
12631263
req = ClientRequest("POST", URL("http://python.org/"), loop=loop)
1264-
req.body = b"test data"
1264+
req.body = b"test data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
12651265

12661266
writer = WriterMock()
12671267
writer.write.side_effect = OSError
@@ -1618,7 +1618,7 @@ async def test_write_bytes_with_content_length_limit(
16181618
data = b"Hello World"
16191619
req = ClientRequest("post", URL("http://python.org/"), loop=loop)
16201620

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

16231623
writer = StreamWriter(protocol=conn.protocol, loop=loop)
16241624
# Use content_length=5 to truncate data
@@ -1655,7 +1655,7 @@ async def gen() -> AsyncIterator[bytes]:
16551655

16561656
req.body = gen() # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
16571657
else:
1658-
req.body = data
1658+
req.body = data # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
16591659

16601660
writer = StreamWriter(protocol=conn.protocol, loop=loop)
16611661
# Use content_length=7 to truncate at the middle of Part2
@@ -1705,7 +1705,7 @@ async def test_warn_if_unclosed_payload_via_body_setter(
17051705
ResourceWarning,
17061706
match="The previous request body contains unclosed resources",
17071707
):
1708-
req.body = b"new data"
1708+
req.body = b"new data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
17091709

17101710
await req.close()
17111711

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

17281728
# Filter out any non-ResourceWarning warnings
17291729
resource_warnings = [
@@ -1753,7 +1753,7 @@ async def test_no_warn_for_consumed_payload_via_body_setter(
17531753
# Setting body again should not trigger warning since previous payload is consumed
17541754
with warnings.catch_warnings(record=True) as warning_list:
17551755
warnings.simplefilter("always")
1756-
req.body = b"new data"
1756+
req.body = b"new data" # type: ignore[assignment] # https://github.com/python/mypy/issues/12892
17571757

17581758
# Filter out any non-ResourceWarning warnings
17591759
resource_warnings = [
@@ -1872,7 +1872,7 @@ async def test_body_setter_closes_previous_payload(
18721872
req._body = mock_payload
18731873

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

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

20062006
# Find the ResourceWarning
20072007
resource_warnings = [

0 commit comments

Comments
 (0)