Skip to content

Commit 5213e2b

Browse files
authored
Fix Type Annotations & Tests for AiohttpRequest (#132)
* Fix Type Annotations in `AiohttpRequest.do_request` * try fixing tests on 3.9+ * try harder * try skipping aiohttp tests on python3.8
1 parent e6f27cd commit 5213e2b

File tree

4 files changed

+52
-35
lines changed

4 files changed

+52
-35
lines changed

ptbcontrib/aiohttp_request/aiohttprequest.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,10 @@ async def do_request( # pylint: disable=too-many-arguments,too-many-positional-
150150
url: str,
151151
method: str,
152152
request_data: Optional[RequestData] = None,
153-
read_timeout: Optional[Union[BaseRequest.DEFAULT_NONE, float]] = BaseRequest.DEFAULT_NONE,
154-
write_timeout: Optional[Union[BaseRequest.DEFAULT_NONE, float]] = BaseRequest.DEFAULT_NONE,
155-
connect_timeout: Optional[
156-
Union[BaseRequest.DEFAULT_NONE, float]
157-
] = BaseRequest.DEFAULT_NONE,
158-
pool_timeout: Optional[Union[BaseRequest.DEFAULT_NONE, float]] = BaseRequest.DEFAULT_NONE,
153+
read_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
154+
write_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
155+
connect_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
156+
pool_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
159157
) -> tuple[int, bytes]:
160158
"""See :meth:`BaseRequest.do_request`.
161159
@@ -215,7 +213,8 @@ async def do_request( # pylint: disable=too-many-arguments,too-many-positional-
215213
timeout=timeout,
216214
data=data,
217215
)
218-
except TimeoutError as err:
216+
# asyncio.TimeoutError is an alias of TimeoutError only starting with Python 3.11.
217+
except asyncio.TimeoutError as err:
219218
if isinstance(err, aiohttp.ConnectionTimeoutError):
220219
raise TimedOut(
221220
message=(

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# cryptography is an optional dependency, but running the tests properly requires it
22
cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3
3-
pygit2==1.9.1
3+
pygit2~=1.9
44

55
pre-commit
66

run_tests.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,28 @@ def run_tests(changed: bool, names: List[str]) -> int:
7575
exit_code = 0
7676
for name in names:
7777
try:
78-
subprocess.check_call( # nosec
78+
result = subprocess.run( # pylint: disable=subprocess-run-check # nosec
7979
[
8080
sys.executable,
8181
"-m",
8282
"pip",
8383
"install",
8484
"-r",
8585
str(ptbcontrib_path / name / "requirements.txt"),
86-
]
86+
],
87+
capture_output=True,
88+
text=True,
8789
)
90+
if (
91+
result.stderr
92+
and "No matching distribution found for python-telegram-bot" in result.stderr
93+
):
94+
print(
95+
f"Ignoring contribution {name}, as this PTB version is not "
96+
f"supported on Python {sys.version}. "
97+
)
98+
continue
99+
result.check_returncode()
88100

89101
result = subprocess.run( # nosec
90102
[sys.executable, "-m", "telegram"],

tests/test_aiohttp_request.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,12 @@
2525
from collections.abc import Coroutine
2626
from http import HTTPStatus
2727
from typing import Any, Callable, Optional
28+
from unittest.mock import MagicMock
2829

2930
import aiohttp
3031
import multidict
3132
import pytest
3233
import yarl
33-
from telegram import InputFile
34-
from telegram._utils.defaultvalue import DEFAULT_NONE
35-
from telegram._utils.strings import TextEncoding
36-
from telegram._utils.types import ODVInput
3734
from telegram.error import (
3835
BadRequest,
3936
ChatMigrated,
@@ -45,8 +42,7 @@
4542
TelegramError,
4643
TimedOut,
4744
)
48-
from telegram.request import RequestData
49-
from telegram.request._requestparameter import RequestParameter
45+
from telegram.request import BaseRequest, RequestData
5046

5147
from ptbcontrib.aiohttp_request import AiohttpRequest
5248

@@ -70,10 +66,10 @@ async def _request_wrapper(
7066
method: str,
7167
url: str,
7268
request_data: Optional[RequestData] = None,
73-
read_timeout: ODVInput[float] = DEFAULT_NONE,
74-
connect_timeout: ODVInput[float] = DEFAULT_NONE,
75-
write_timeout: ODVInput[float] = DEFAULT_NONE,
76-
pool_timeout: ODVInput[float] = DEFAULT_NONE,
69+
read_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
70+
connect_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
71+
write_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
72+
pool_timeout: Optional[float] = BaseRequest.DEFAULT_NONE,
7773
) -> bytes:
7874
try:
7975
return await super()._request_wrapper(
@@ -203,10 +199,15 @@ async def test_illegal_json_response(
203199

204200
await aiohttp_request.shutdown()
205201

206-
assert len(caplog.records) == 1
207-
record = caplog.records[0]
208-
assert record.name == "telegram.request.BaseRequest"
209-
assert record.getMessage().endswith(f'invalid JSON data: "{server_response.decode()}"')
202+
assert len(caplog.records) >= 1
203+
found = False
204+
for record in caplog.records:
205+
if record.name == "telegram.request.BaseRequest":
206+
assert record.getMessage().endswith(
207+
f'invalid JSON data: "{server_response.decode()}"'
208+
)
209+
found = True
210+
assert found, "Expected log message not found"
210211

211212
async def test_chat_migrated(self, monkeypatch, aiohttp_request: AiohttpRequest):
212213
server_response = b'{"ok": "False", "parameters": {"migrate_to_chat_id": 123}}'
@@ -222,17 +223,19 @@ async def test_chat_migrated(self, monkeypatch, aiohttp_request: AiohttpRequest)
222223

223224
assert exc_info.value.new_chat_id == 123
224225

225-
async def test_retry_after(self, monkeypatch, aiohttp_request: AiohttpRequest):
226+
async def test_retry_after(self, monkeypatch):
226227
server_response = b'{"ok": "False", "parameters": {"retry_after": 42}}'
228+
aiohttp_request = AiohttpRequest()
227229

228230
monkeypatch.setattr(
229231
aiohttp_request,
230232
"do_request",
231233
mocker_factory(response=server_response, return_code=HTTPStatus.BAD_REQUEST),
232234
)
233235

234-
with pytest.raises(RetryAfter, match="Retry in 42") as exc_info:
235-
await aiohttp_request.post(None, None, None)
236+
async with aiohttp_request:
237+
with pytest.raises(RetryAfter, match="Retry in 42") as exc_info:
238+
await aiohttp_request.post(None, None, None)
236239

237240
assert exc_info.value.retry_after == 42
238241

@@ -262,7 +265,7 @@ async def test_error_description(
262265
else:
263266
match = "Unknown HTTPError"
264267

265-
server_response = json.dumps(response_data).encode(TextEncoding.UTF_8)
268+
server_response = json.dumps(response_data).encode("utf-8")
266269

267270
monkeypatch.setattr(
268271
aiohttp_request,
@@ -364,7 +367,12 @@ async def make_assertion(*args, **kwargs):
364367
monkeypatch.setattr(aiohttp_request, "do_request", make_assertion)
365368

366369
await aiohttp_request.post("url", None)
367-
assert self.test_flag == (DEFAULT_NONE, DEFAULT_NONE, DEFAULT_NONE, DEFAULT_NONE)
370+
assert self.test_flag == (
371+
BaseRequest.DEFAULT_NONE,
372+
BaseRequest.DEFAULT_NONE,
373+
BaseRequest.DEFAULT_NONE,
374+
BaseRequest.DEFAULT_NONE,
375+
)
368376

369377
await aiohttp_request.post(
370378
"url", None, read_timeout=1, connect_timeout=2, write_timeout=3, pool_timeout=4
@@ -527,12 +535,10 @@ async def make_assertion(self, **kwargs):
527535
assert code == HTTPStatus.OK
528536

529537
async def test_do_request_params_with_data(self, monkeypatch, aiohttp_request):
530-
mixed_rqs = RequestData(
531-
[
532-
RequestParameter("name", "value", [InputFile(obj="data", attach=True)]),
533-
RequestParameter("second_name", "second_value", []),
534-
]
535-
)
538+
mixed_rqs = MagicMock()
539+
mixed_rqs.contains_files = True
540+
mixed_rqs.json_parameters = {"name": "value", "second_name": "second_value"}
541+
mixed_rqs.multipart_data = {"attachment": ("data", b"content", "application/octet-stream")}
536542

537543
async def make_assertion(self, **kwargs):
538544
method_assertion = kwargs.get("method") == "method"

0 commit comments

Comments
 (0)