Merge branch 'dev-3.x' into dev-3.x-remove-filters-factory

This commit is contained in:
Alex Root Junior 2022-08-30 01:56:34 +03:00
commit 2aa4a9fe31
No known key found for this signature in database
GPG key ID: 074C1D455EBEA4AC
5 changed files with 51 additions and 26 deletions

View file

@ -32,7 +32,6 @@ jobs:
build:
strategy:
fail-fast: false
max-parallel: 9
matrix:
os:
- ubuntu-latest
@ -42,6 +41,8 @@ jobs:
- '3.8'
- '3.9'
- '3.10'
- 'pypy3.8'
- 'pypy3.9'
defaults:
# Windows sucks. Force use bash instead of PowerShell
@ -50,8 +51,22 @@ jobs:
runs-on: ${{ matrix.os }}
env:
# We disable some features for PyPy by this environment variable such as:
# Installation of `fast` extras: `uvloop` on PyPy is useless and may be even slower
# than the default loop;
# Coverage reports: code introspection disables any optimizations, so tests with
# coverage enabled are very slow on PyPy.
# More: https://www.pypy.org/performance.html
IS_PYPY: ${{ startswith(matrix.python-version, 'pypy') }}
# Windows has also some limitations:
# Redis is not supported on GitHub Windows runners;
# Poetry installer doesn't work on Windows with PyPy.
IS_WINDOWS: ${{ startswith(matrix.os, 'windows') }}
steps:
- uses: actions/checkout@master
- name: Checkout code
uses: actions/checkout@master
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v4
@ -60,14 +75,24 @@ jobs:
- name: Install and configure Poetry
uses: snok/install-poetry@v1
if: "env.IS_PYPY == 'false' || env.IS_WINDOWS == 'false'"
with:
version: 1.1.11
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
- name: Install and configure Poetry (PyPy on Windows)
if: "env.IS_PYPY == 'true' && env.IS_WINDOWS == 'true'"
run: |
set -eu
pip install "poetry==1.1.11"
poetry config virtualenvs.create true
poetry config virtualenvs.in-project true
poetry config installer.parallel true
- name: Setup redis
if: ${{ matrix.os != 'windows-latest' }}
if: ${{ env.IS_WINDOWS == 'false' }}
uses: shogo82148/actions-setup-redis@v1
with:
redis-version: 6
@ -79,32 +104,29 @@ jobs:
path: .venv
key: venv-${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }}-${{ secrets.CACHE_VERSION }}
- name: Project dependencies
- name: Install project dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: |
poetry install --no-interaction -E fast -E redis -E proxy -E i18n -E docs
flags=""
[[ "$IS_PYPY" == "false" ]] && flags="$flags -E fast"
poetry install --no-interaction -E redis -E proxy -E i18n -E docs $flags
- name: Lint code
run: |
poetry run flake8 aiogram
poetry run mypy aiogram
- name: Check code-style (Black)
run: |
poetry run black --check --diff aiogram tests
- name: Run tests (with Redis)
if: ${{ matrix.os != 'windows-latest' }}
- name: Run tests
run: |
poetry run pytest --cov=aiogram --cov-config .coveragerc --cov-report=xml --redis redis://localhost:6379/0
flags=""
[[ "$IS_PYPY" == "false" ]] && flags="$flags --cov=aiogram --cov-config .coveragerc --cov-report=xml"
[[ "$IS_WINDOWS" == "false" ]] && flags="$flags --redis redis://localhost:6379/0"
poetry run pytest $flags
- name: Run tests (without Redis)
# Redis can't be used on GitHub Windows Runners
if: ${{ matrix.os == 'windows-latest' }}
run: |
poetry run pytest --cov=aiogram --cov-config .coveragerc --cov-report=xml
- uses: codecov/codecov-action@v1
- name: Upload coverage data
if: "env.IS_PYPY == 'false'"
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: coverage.xml

1
CHANGES/985.feature Normal file
View file

@ -0,0 +1 @@
Add PyPy support and run tests under PyPy

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

@ -0,0 +1 @@
Fixed polling crash when Telegram Bot API raises HTTP 429 status-code.

View file

@ -61,6 +61,7 @@ Features
- Asynchronous (`asyncio docs <https://docs.python.org/3/library/asyncio.html>`_, :pep:`492`)
- Has type hints (:pep:`484`) and can be used with `mypy <http://mypy-lang.org/>`_
- Supports `PyPy <https://www.pypy.org/>`_
- Supports `Telegram Bot API 5.3 <https://core.telegram.org/bots/api>`_
- Telegram Bot API integration code was `autogenerated <https://github.com/aiogram/tg-codegen>`_ and can be easily re-generated when API gets updated
- Updates router (Blueprints)

View file

@ -8,7 +8,7 @@ from typing import Any, AsyncGenerator, Dict, List, Optional, Union
from .. import loggers
from ..client.bot import Bot
from ..exceptions import TelegramAPIError, TelegramNetworkError, TelegramServerError
from ..exceptions import TelegramAPIError
from ..fsm.middleware import FSMContextMiddleware
from ..fsm.storage.base import BaseEventIsolation, BaseStorage
from ..fsm.storage.memory import DisabledEventIsolation, MemoryStorage
@ -183,15 +183,15 @@ class Dispatcher(Router):
get_updates = GetUpdates(timeout=polling_timeout, allowed_updates=allowed_updates)
kwargs = {}
if bot.session.timeout:
# Request timeout can be lower than session timeout ant that's OK.
# Request timeout can be lower than session timeout and that's OK.
# To prevent false-positive TimeoutError we should wait longer than polling timeout
kwargs["request_timeout"] = int(bot.session.timeout + polling_timeout)
while True:
try:
updates = await bot(get_updates, **kwargs)
except (TelegramNetworkError, TelegramServerError) as e:
# In cases when Telegram Bot API was inaccessible don't need to stop polling process
# because some of developers can't make auto-restarting of the script
except Exception as e:
# In cases when Telegram Bot API was inaccessible don't need to stop polling
# process because some developers can't make auto-restarting of the script
loggers.dispatcher.error("Failed to fetch updates - %s: %s", type(e).__name__, e)
# And also backoff timeout is best practice to retry any network activity
loggers.dispatcher.warning(
@ -211,8 +211,8 @@ class Dispatcher(Router):
yield update
# The getUpdates method returns the earliest 100 unconfirmed updates.
# To confirm an update, use the offset parameter when calling getUpdates
# All updates with update_id less than or equal to offset will be marked as confirmed on the server
# and will no longer be returned.
# All updates with update_id less than or equal to offset will be marked
# as confirmed on the server and will no longer be returned.
get_updates.offset = update.update_id + 1
async def _listen_update(self, update: Update, **kwargs: Any) -> Any:
@ -417,7 +417,7 @@ class Dispatcher(Router):
workflow_data = {"dispatcher": self, "bots": bots, "bot": bots[-1]}
workflow_data.update(kwargs)
await self.emit_startup(**workflow_data)
loggers.dispatcher.info("Start poling")
loggers.dispatcher.info("Start polling")
try:
coro_list = []
for bot in bots: