Tests on Python 3.11 (#1044)

* Try to use Python 3.11

* Remove `asynctest` dependency

* Fixed aiofiles tests

* Added changelog
This commit is contained in:
Alex Root Junior 2022-10-26 22:21:04 +03:00 committed by GitHub
parent c7a85de579
commit 6db3778c6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 36 additions and 88 deletions

View file

@ -41,7 +41,7 @@ jobs:
- '3.8' - '3.8'
- '3.9' - '3.9'
- '3.10' - '3.10'
#- '3.11' - '3.11'
- 'pypy3.8' - 'pypy3.8'
- 'pypy3.9' - 'pypy3.9'

1
CHANGES/1044.misc.rst Normal file
View file

@ -0,0 +1 @@
Enabled testing on Python 3.11

14
poetry.lock generated
View file

@ -78,14 +78,6 @@ category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
[[package]]
name = "asynctest"
version = "0.13.0"
description = "Enhance the standard unittest package with features for testing asyncio libraries"
category = "dev"
optional = false
python-versions = ">=3.5"
[[package]] [[package]]
name = "attrs" name = "attrs"
version = "22.1.0" version = "22.1.0"
@ -1203,7 +1195,7 @@ redis = ["redis"]
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.8" python-versions = "^3.8"
content-hash = "ee5c55fdf1dfa75f942e6a26c5a7d6111a2c8eb313ac9850097fb2b951e5aa64" content-hash = "96a502ce3830054d2b1f248f21b710d172b9c5c3bf8943e19f7478a0586dfcf5"
[metadata.files] [metadata.files]
aiofiles = [ aiofiles = [
@ -1319,10 +1311,6 @@ async-timeout = [
{file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"},
{file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"},
] ]
asynctest = [
{file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"},
{file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"},
]
attrs = [ attrs = [
{file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"},
{file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"},

View file

@ -85,7 +85,6 @@ pytest-mypy = "^0.10.0"
pytest-cov = "^4.0.0" pytest-cov = "^4.0.0"
pytest-aiohttp = "^1.0.4" pytest-aiohttp = "^1.0.4"
aresponses = "^2.1.6" aresponses = "^2.1.6"
asynctest = "^0.13.0"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]

View file

@ -1,6 +1,7 @@
import io import io
import os import os
from tempfile import mkstemp from tempfile import mkstemp
from unittest.mock import AsyncMock, MagicMock, patch
import aiofiles import aiofiles
import pytest import pytest
@ -13,12 +14,6 @@ from aiogram.methods import GetFile, GetMe
from aiogram.types import File, PhotoSize from aiogram.types import File, PhotoSize
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
try:
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio
@ -44,7 +39,7 @@ class TestBot:
with patch( with patch(
"aiogram.client.session.aiohttp.AiohttpSession.make_request", "aiogram.client.session.aiohttp.AiohttpSession.make_request",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_make_request: ) as mocked_make_request:
await bot(method) await bot(method)
mocked_make_request.assert_awaited_with(bot, method, timeout=None) mocked_make_request.assert_awaited_with(bot, method, timeout=None)
@ -55,7 +50,7 @@ class TestBot:
await session.create_session() await session.create_session()
with patch( with patch(
"aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=AsyncMock
) as mocked_close: ) as mocked_close:
await bot.session.close() await bot.session.close()
mocked_close.assert_awaited() mocked_close.assert_awaited()
@ -63,7 +58,7 @@ class TestBot:
@pytest.mark.parametrize("close", [True, False]) @pytest.mark.parametrize("close", [True, False])
async def test_context_manager(self, close: bool): async def test_context_manager(self, close: bool):
with patch( with patch(
"aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=AsyncMock
) as mocked_close: ) as mocked_close:
async with Bot("42:TEST", session=AiohttpSession()).context(auto_close=close) as bot: async with Bot("42:TEST", session=AiohttpSession()).context(auto_close=close) as bot:
assert isinstance(bot, Bot) assert isinstance(bot, Bot)
@ -78,11 +73,11 @@ class TestBot:
) )
# https://github.com/Tinche/aiofiles#writing-tests-for-aiofiles # https://github.com/Tinche/aiofiles#writing-tests-for-aiofiles
aiofiles.threadpool.wrap.register(CoroutineMock)( aiofiles.threadpool.wrap.register(MagicMock)(
lambda *args, **kwargs: aiofiles.threadpool.AsyncBufferedIOBase(*args, **kwargs) lambda *args, **kwargs: aiofiles.threadpool.binary.AsyncBufferedIOBase(*args, **kwargs)
) )
mock_file = CoroutineMock() mock_file = MagicMock()
bot = Bot("42:TEST") bot = Bot("42:TEST")
with patch("aiofiles.threadpool.sync_open", return_value=mock_file): with patch("aiofiles.threadpool.sync_open", return_value=mock_file):

View file

@ -1,5 +1,6 @@
import asyncio import asyncio
from typing import AsyncContextManager, AsyncGenerator from typing import AsyncContextManager, AsyncGenerator
from unittest.mock import AsyncMock, patch
import aiohttp_socks import aiohttp_socks
import pytest import pytest
@ -14,12 +15,6 @@ from aiogram.methods import Request, TelegramMethod
from aiogram.types import UNSET, InputFile from aiogram.types import UNSET, InputFile
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
try:
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio
@ -106,7 +101,7 @@ class TestAiohttpSession:
session = AiohttpSession() session = AiohttpSession()
await session.create_session() await session.create_session()
with patch("aiohttp.ClientSession.close", new=CoroutineMock()) as mocked_close: with patch("aiohttp.ClientSession.close", new=AsyncMock()) as mocked_close:
await session.close() await session.close()
mocked_close.assert_called_once() mocked_close.assert_called_once()
@ -184,7 +179,7 @@ class TestAiohttpSession:
with patch( with patch(
"aiohttp.client.ClientSession._request", "aiohttp.client.ClientSession._request",
new_callable=CoroutineMock, new_callable=AsyncMock,
side_effect=side_effect, side_effect=side_effect,
): ):
with pytest.raises(TelegramNetworkError): with pytest.raises(TelegramNetworkError):
@ -215,9 +210,9 @@ class TestAiohttpSession:
with patch( with patch(
"aiogram.client.session.aiohttp.AiohttpSession.create_session", "aiogram.client.session.aiohttp.AiohttpSession.create_session",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_create_session, patch( ) as mocked_create_session, patch(
"aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock "aiogram.client.session.aiohttp.AiohttpSession.close", new_callable=AsyncMock
) as mocked_close: ) as mocked_close:
async with session as ctx: async with session as ctx:
assert session == ctx assert session == ctx

View file

@ -1,6 +1,7 @@
import datetime import datetime
import json import json
from typing import AsyncContextManager, AsyncGenerator, Optional from typing import AsyncContextManager, AsyncGenerator, Optional
from unittest.mock import AsyncMock, patch
import pytest import pytest
@ -25,12 +26,6 @@ from aiogram.methods import DeleteMessage, GetMe, TelegramMethod
from aiogram.types import UNSET, User from aiogram.types import UNSET, User
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
try:
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio
@ -227,7 +222,7 @@ class TestBaseSession:
with patch( with patch(
"tests.test_api.test_client.test_session.test_base_session.CustomSession.close", "tests.test_api.test_client.test_session.test_base_session.CustomSession.close",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_close: ) as mocked_close:
async with session as ctx: async with session as ctx:
assert session == ctx assert session == ctx

View file

@ -4,6 +4,7 @@ import time
import warnings import warnings
from collections import Counter from collections import Counter
from typing import Any from typing import Any
from unittest.mock import AsyncMock, patch
import pytest import pytest
@ -33,12 +34,6 @@ from aiogram.types import (
from aiogram.types.error_event import ErrorEvent from aiogram.types.error_event import ErrorEvent
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
try:
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio
@ -176,7 +171,7 @@ class TestDispatcher:
bot.add_result_for(GetUpdates, ok=False, error_code=500, description="restarting") bot.add_result_for(GetUpdates, ok=False, error_code=500, description="restarting")
with patch( with patch(
"aiogram.utils.backoff.Backoff.asleep", "aiogram.utils.backoff.Backoff.asleep",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_asleep: ) as mocked_asleep:
assert isinstance(await anext(listen), Update) assert isinstance(await anext(listen), Update)
assert mocked_asleep.awaited assert mocked_asleep.awaited
@ -594,7 +589,7 @@ class TestDispatcher:
with patch( with patch(
"aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request", "aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_silent_call_request: ) as mocked_silent_call_request:
result = await dispatcher._process_update(bot=bot, update=Update(update_id=42)) result = await dispatcher._process_update(bot=bot, update=Update(update_id=42))
print(result) print(result)
@ -620,7 +615,7 @@ class TestDispatcher:
yield Update(update_id=42) yield Update(update_id=42)
with patch( with patch(
"aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=CoroutineMock "aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=AsyncMock
) as mocked_process_update, patch( ) as mocked_process_update, patch(
"aiogram.dispatcher.dispatcher.Dispatcher._listen_updates" "aiogram.dispatcher.dispatcher.Dispatcher._listen_updates"
) as patched_listen_updates: ) as patched_listen_updates:
@ -682,11 +677,11 @@ class TestDispatcher:
yield Update(update_id=42) yield Update(update_id=42)
with patch( with patch(
"aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=CoroutineMock "aiogram.dispatcher.dispatcher.Dispatcher._process_update", new_callable=AsyncMock
) as mocked_process_update, patch( ) as mocked_process_update, patch(
"aiogram.dispatcher.router.Router.emit_startup", new_callable=CoroutineMock "aiogram.dispatcher.router.Router.emit_startup", new_callable=AsyncMock
) as mocked_emit_startup, patch( ) as mocked_emit_startup, patch(
"aiogram.dispatcher.router.Router.emit_shutdown", new_callable=CoroutineMock "aiogram.dispatcher.router.Router.emit_shutdown", new_callable=AsyncMock
) as mocked_emit_shutdown, patch( ) as mocked_emit_shutdown, patch(
"aiogram.dispatcher.dispatcher.Dispatcher._listen_updates" "aiogram.dispatcher.dispatcher.Dispatcher._listen_updates"
) as patched_listen_updates: ) as patched_listen_updates:
@ -722,7 +717,7 @@ class TestDispatcher:
with patch( with patch(
"aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request", "aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_silent_call_request: ) as mocked_silent_call_request:
response = await dispatcher.feed_webhook_update(bot, RAW_UPDATE, _timeout=0.1) response = await dispatcher.feed_webhook_update(bot, RAW_UPDATE, _timeout=0.1)
assert response is None assert response is None

View file

@ -1,17 +1,12 @@
import functools import functools
from typing import Any from typing import Any
from unittest.mock import AsyncMock, patch
import pytest import pytest
from aiogram.dispatcher.event.event import EventObserver from aiogram.dispatcher.event.event import EventObserver
from aiogram.dispatcher.event.handler import HandlerObject from aiogram.dispatcher.event.handler import HandlerObject
try:
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio
@ -54,7 +49,7 @@ class TestEventObserver:
with patch( with patch(
"aiogram.dispatcher.event.handler.CallableMixin.call", "aiogram.dispatcher.event.handler.CallableMixin.call",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_my_handler: ) as mocked_my_handler:
results = await observer.trigger("test") results = await observer.trigger("test")
assert results is None assert results is None

View file

@ -1,15 +1,10 @@
from typing import Awaitable from typing import Awaitable
from unittest.mock import AsyncMock, patch
import pytest import pytest
from aiogram.filters import Filter from aiogram.filters import Filter
try:
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio
@ -26,7 +21,7 @@ class TestBaseFilter:
with patch( with patch(
"tests.test_filters.test_base.MyFilter.__call__", "tests.test_filters.test_base.MyFilter.__call__",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_call: ) as mocked_call:
call = my_filter(event="test") call = my_filter(event="test")
await call await call

View file

@ -1,6 +1,7 @@
import asyncio import asyncio
import time import time
from datetime import datetime from datetime import datetime
from unittest.mock import AsyncMock, patch
import pytest import pytest
@ -10,13 +11,7 @@ from aiogram.types import Chat, Message, User
from aiogram.utils.chat_action import ChatActionMiddleware, ChatActionSender from aiogram.utils.chat_action import ChatActionMiddleware, ChatActionSender
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
try: pytestmark = pytest.mark.asyncio
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmarm = pytest.mark.asyncio
class TestChatActionSender: class TestChatActionSender:
@ -55,7 +50,7 @@ class TestChatActionSender:
async def test_worker(self, bot: Bot): async def test_worker(self, bot: Bot):
with patch( with patch(
"aiogram.client.bot.Bot.send_chat_action", "aiogram.client.bot.Bot.send_chat_action",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_send_chat_action: ) as mocked_send_chat_action:
async with ChatActionSender.typing( async with ChatActionSender.typing(
bot=bot, chat_id=42, interval=0.01, initial_sleep=0 bot=bot, chat_id=42, interval=0.01, initial_sleep=0
@ -101,10 +96,10 @@ class TestChatActionMiddleware:
middleware = ChatActionMiddleware() middleware = ChatActionMiddleware()
with patch( with patch(
"aiogram.utils.chat_action.ChatActionSender._run", "aiogram.utils.chat_action.ChatActionSender._run",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_run, patch( ) as mocked_run, patch(
"aiogram.utils.chat_action.ChatActionSender._stop", "aiogram.utils.chat_action.ChatActionSender._stop",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_stop: ) as mocked_stop:
data = {"handler": HandlerObject(callback=handler1), "bot": bot} data = {"handler": HandlerObject(callback=handler1), "bot": bot}
message = Message( message = Message(

View file

@ -3,6 +3,7 @@ import time
from asyncio import Event from asyncio import Event
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Dict from typing import Any, Dict
from unittest.mock import AsyncMock, patch
import pytest import pytest
from aiohttp import web from aiohttp import web
@ -21,12 +22,6 @@ from aiogram.webhook.aiohttp_server import (
from aiogram.webhook.security import IPFilter from aiogram.webhook.security import IPFilter
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
try:
from asynctest import CoroutineMock, patch
except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
class TestAiohttpServer: class TestAiohttpServer:
def test_setup_application(self): def test_setup_application(self):
@ -110,7 +105,7 @@ class TestSimpleRequestHandler:
handler.handle_in_background = True handler.handle_in_background = True
with patch( with patch(
"aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request", "aiogram.dispatcher.dispatcher.Dispatcher.silent_call_request",
new_callable=CoroutineMock, new_callable=AsyncMock,
) as mocked_silent_call_request: ) as mocked_silent_call_request:
handler_event.clear() handler_event.clear()
resp = await self.make_reqest(client=client) resp = await self.make_reqest(client=client)