Dev 3.x flat package (#961)

* Move packages

* Added changelog

* Update examples/echo_bot.py

Co-authored-by: Oleg A. <t0rr@mail.ru>

* Rename `handler` -> `handlers`

* Update __init__.py

Co-authored-by: Oleg A. <t0rr@mail.ru>
This commit is contained in:
Alex Root Junior 2022-08-14 01:07:52 +03:00 committed by GitHub
parent 5e7932ca20
commit 4315ecf1a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
111 changed files with 376 additions and 390 deletions

9
CHANGES/938.misc.rst Normal file
View file

@ -0,0 +1,9 @@
**Breaking!** More flat project structure
These packages was moved, imports in your code should be fixed:
- :code:`aiogram.dispatcher.filters` -> :code:`aiogram.filters`
- :code:`aiogram.dispatcher.fsm` -> :code:`aiogram.fsm`
- :code:`aiogram.dispatcher.handler` -> :code:`aiogram.handler`
- :code:`aiogram.dispatcher.webhook` -> :code:`aiogram.webhook`
- :code:`aiogram.dispatcher.flags/*` -> :code:`aiogram.dispatcher.flags` (single module instead of package)

View file

@ -105,10 +105,22 @@ test-coverage-view:
# Docs # Docs
# ================================================================================================= # =================================================================================================
.PHONY: docs-serve locales := en uk_UA ru
locale_targets := $(addprefix docs-serve-, $(locales))
docs-gettext:
cd docs && make gettext
cd docs && sphinx-intl update -p _build/gettext $(addprefix -l , $(locales))
.PHONY: docs-gettext
docs-serve: docs-serve:
rm -rf docs/_build rm -rf docs/_build
$(py) sphinx-autobuild --watch aiogram/ docs/ docs/_build/ $(py) sphinx-autobuild --watch aiogram/ docs/ docs/_build/ $(OPTS)
.PHONY: docs-serve
$(locale_targets): docs-serve-%:
$(MAKE) docs-serve OPTS="-D language=$(subst docs-serve-,,$@)"
.PHONY: $(locale_targets)
# ================================================================================================= # =================================================================================================
# Project # Project

View file

@ -1,13 +1,13 @@
from aiogram.dispatcher.flags import FlagGenerator
from .client import session from .client import session
from .client.bot import Bot from .client.bot import Bot
from .dispatcher import filters, handler
from .dispatcher.dispatcher import Dispatcher from .dispatcher.dispatcher import Dispatcher
from .dispatcher.flags.flag import FlagGenerator
from .dispatcher.middlewares.base import BaseMiddleware from .dispatcher.middlewares.base import BaseMiddleware
from .dispatcher.router import Router from .dispatcher.router import Router
from .utils.magic_filter import MagicFilter from .utils.magic_filter import MagicFilter
from .utils.text_decorations import html_decoration as _html_decoration from .utils.text_decorations import html_decoration as html
from .utils.text_decorations import markdown_decoration as _markdown_decoration from .utils.text_decorations import markdown_decoration as md
try: try:
import uvloop as _uvloop import uvloop as _uvloop
@ -17,8 +17,6 @@ except ImportError: # pragma: no cover
pass pass
F = MagicFilter() F = MagicFilter()
html = _html_decoration
md = _markdown_decoration
flags = FlagGenerator() flags = FlagGenerator()
__all__ = ( __all__ = (
@ -31,8 +29,6 @@ __all__ = (
"Dispatcher", "Dispatcher",
"Router", "Router",
"BaseMiddleware", "BaseMiddleware",
"filters",
"handler",
"F", "F",
"html", "html",
"md", "md",

View file

@ -165,6 +165,10 @@ T = TypeVar("T")
class Bot(ContextInstanceMixin["Bot"]): class Bot(ContextInstanceMixin["Bot"]):
"""
Bot class
"""
def __init__( def __init__(
self, self,
token: str, token: str,
@ -172,8 +176,6 @@ class Bot(ContextInstanceMixin["Bot"]):
parse_mode: Optional[str] = None, parse_mode: Optional[str] = None,
) -> None: ) -> None:
""" """
Bot class
:param token: Telegram Bot token `Obtained from @BotFather <https://t.me/BotFather>`_ :param token: Telegram Bot token `Obtained from @BotFather <https://t.me/BotFather>`_
:param session: HTTP Client session (For example AiohttpSession). :param session: HTTP Client session (For example AiohttpSession).
If not specified it will be automatically created. If not specified it will be automatically created.

View file

@ -9,16 +9,16 @@ from typing import Any, AsyncGenerator, Dict, List, Optional, Union
from .. import loggers from .. import loggers
from ..client.bot import Bot from ..client.bot import Bot
from ..exceptions import TelegramAPIError, TelegramNetworkError, TelegramServerError from ..exceptions import TelegramAPIError, TelegramNetworkError, TelegramServerError
from ..fsm.middleware import FSMContextMiddleware
from ..fsm.storage.base import BaseEventIsolation, BaseStorage
from ..fsm.storage.memory import DisabledEventIsolation, MemoryStorage
from ..fsm.strategy import FSMStrategy
from ..methods import GetUpdates, TelegramMethod from ..methods import GetUpdates, TelegramMethod
from ..types import Update, User from ..types import Update, User
from ..types.update import UpdateTypeLookupError from ..types.update import UpdateTypeLookupError
from ..utils.backoff import Backoff, BackoffConfig from ..utils.backoff import Backoff, BackoffConfig
from .event.bases import UNHANDLED, SkipHandler from .event.bases import UNHANDLED, SkipHandler
from .event.telegram import TelegramEventObserver from .event.telegram import TelegramEventObserver
from .fsm.middleware import FSMContextMiddleware
from .fsm.storage.base import BaseEventIsolation, BaseStorage
from .fsm.storage.memory import DisabledEventIsolation, MemoryStorage
from .fsm.strategy import FSMStrategy
from .middlewares.error import ErrorsMiddleware from .middlewares.error import ErrorsMiddleware
from .middlewares.user_context import UserContextMiddleware from .middlewares.user_context import UserContextMiddleware
from .router import Router from .router import Router

View file

@ -7,8 +7,8 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
from magic_filter import MagicFilter from magic_filter import MagicFilter
from aiogram.dispatcher.flags.getter import extract_flags_from_object from aiogram.dispatcher.flags import extract_flags_from_object
from aiogram.dispatcher.handler.base import BaseHandler from aiogram.handlers import BaseHandler
CallbackType = Callable[..., Any] CallbackType = Callable[..., Any]

View file

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import warnings
from inspect import isclass from inspect import isclass
from itertools import chain from itertools import chain
from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, List, Optional, Tuple, Type from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, List, Optional, Tuple, Type
@ -7,10 +8,10 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, List, Optional
from pydantic import ValidationError from pydantic import ValidationError
from aiogram.dispatcher.middlewares.manager import MiddlewareManager from aiogram.dispatcher.middlewares.manager import MiddlewareManager
from aiogram.filters.base import BaseFilter
from ...exceptions import FiltersResolveError from ...exceptions import FiltersResolveError
from ...types import TelegramObject from ...types import TelegramObject
from ..filters.base import BaseFilter
from .bases import REJECTED, UNHANDLED, MiddlewareType, SkipHandler from .bases import REJECTED, UNHANDLED, MiddlewareType, SkipHandler
from .handler import CallbackType, FilterObject, HandlerObject from .handler import CallbackType, FilterObject, HandlerObject
@ -160,6 +161,15 @@ class TelegramEventObserver:
unresolved_fields=set(full_config.keys()), possible_cases=possible_cases unresolved_fields=set(full_config.keys()), possible_cases=possible_cases
) )
if bound_filters:
warnings.warn(
category=DeprecationWarning,
message="Filters factory deprecated and will be removed in Beta 5. "
"Use filters directly, for example instead of "
"`@router.message(commands=['help']')` "
"use `@router.message(Command(commands=['help'])`",
stacklevel=3,
)
return bound_filters return bound_filters
def register( def register(

View file

@ -1,12 +1,10 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Callable, Optional, Union, cast, overload from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union, cast, overload
from magic_filter import AttrDict from magic_filter import AttrDict, MagicFilter
from aiogram.dispatcher.flags.getter import extract_flags_from_object
if TYPE_CHECKING: if TYPE_CHECKING:
pass from aiogram.dispatcher.event.handler import HandlerObject
@dataclass(frozen=True) @dataclass(frozen=True)
@ -77,3 +75,53 @@ class FlagGenerator:
if TYPE_CHECKING: if TYPE_CHECKING:
chat_action: _ChatActionFlagProtocol chat_action: _ChatActionFlagProtocol
def extract_flags_from_object(obj: Any) -> Dict[str, Any]:
if not hasattr(obj, "aiogram_flag"):
return {}
return cast(Dict[str, Any], obj.aiogram_flag)
def extract_flags(handler: Union["HandlerObject", Dict[str, Any]]) -> Dict[str, Any]:
"""
Extract flags from handler or middleware context data
:param handler: handler object or data
:return: dictionary with all handler flags
"""
if isinstance(handler, dict) and "handler" in handler:
handler = handler["handler"]
if not hasattr(handler, "flags"):
return {}
return handler.flags # type: ignore
def get_flag(
handler: Union["HandlerObject", Dict[str, Any]],
name: str,
*,
default: Optional[Any] = None,
) -> Any:
"""
Get flag by name
:param handler: handler object or data
:param name: name of the flag
:param default: default value (None)
:return: value of the flag or default
"""
flags = extract_flags(handler)
return flags.get(name, default)
def check_flags(handler: Union["HandlerObject", Dict[str, Any]], magic: MagicFilter) -> Any:
"""
Check flags via magic filter
:param handler: handler object or data
:param magic: instance of the magic
:return: the result of magic filter check
"""
flags = extract_flags(handler)
return magic.resolve(AttrDict(flags))

View file

@ -1,56 +0,0 @@
from typing import TYPE_CHECKING, Any, Dict, Optional, Union, cast
from magic_filter import AttrDict, MagicFilter
if TYPE_CHECKING:
from aiogram.dispatcher.event.handler import HandlerObject
def extract_flags_from_object(obj: Any) -> Dict[str, Any]:
if not hasattr(obj, "aiogram_flag"):
return {}
return cast(Dict[str, Any], obj.aiogram_flag)
def extract_flags(handler: Union["HandlerObject", Dict[str, Any]]) -> Dict[str, Any]:
"""
Extract flags from handler or middleware context data
:param handler: handler object or data
:return: dictionary with all handler flags
"""
if isinstance(handler, dict) and "handler" in handler:
handler = handler["handler"]
if not hasattr(handler, "flags"):
return {}
return handler.flags # type: ignore
def get_flag(
handler: Union["HandlerObject", Dict[str, Any]],
name: str,
*,
default: Optional[Any] = None,
) -> Any:
"""
Get flag by name
:param handler: handler object or data
:param name: name of the flag
:param default: default value (None)
:return: value of the flag or default
"""
flags = extract_flags(handler)
return flags.get(name, default)
def check_flags(handler: Union["HandlerObject", Dict[str, Any]], magic: MagicFilter) -> Any:
"""
Check flags via magic filter
:param handler: handler object or data
:param magic: instance of the magic
:return: the result of magic filter check
"""
flags = extract_flags(handler)
return magic.resolve(AttrDict(flags))

View file

@ -3,12 +3,13 @@ from __future__ import annotations
import warnings import warnings
from typing import Any, Dict, Final, Generator, List, Optional, Set, Union from typing import Any, Dict, Final, Generator, List, Optional, Set, Union
from aiogram.filters import BUILTIN_FILTERS
from ..types import TelegramObject from ..types import TelegramObject
from ..utils.warnings import CodeHasNoEffect from ..utils.warnings import CodeHasNoEffect
from .event.bases import REJECTED, UNHANDLED from .event.bases import REJECTED, UNHANDLED
from .event.event import EventObserver from .event.event import EventObserver
from .event.telegram import TelegramEventObserver from .event.telegram import TelegramEventObserver
from .filters import BUILTIN_FILTERS
INTERNAL_UPDATE_TYPES: Final[frozenset[str]] = frozenset({"update", "error"}) INTERNAL_UPDATE_TYPES: Final[frozenset[str]] = frozenset({"update", "error"})

View file

@ -16,7 +16,7 @@ from .chat_member_updated import (
RESTRICTED, RESTRICTED,
ChatMemberUpdatedFilter, ChatMemberUpdatedFilter,
) )
from .command import Command, CommandObject from .command import Command, CommandObject, CommandStart
from .content_types import ContentTypesFilter from .content_types import ContentTypesFilter
from .exception import ExceptionMessageFilter, ExceptionTypeFilter from .exception import ExceptionMessageFilter, ExceptionTypeFilter
from .logic import and_f, invert_f, or_f from .logic import and_f, invert_f, or_f
@ -30,6 +30,7 @@ __all__ = (
"Text", "Text",
"Command", "Command",
"CommandObject", "CommandObject",
"CommandStart",
"ContentTypesFilter", "ContentTypesFilter",
"ExceptionMessageFilter", "ExceptionMessageFilter",
"ExceptionTypeFilter", "ExceptionTypeFilter",

View file

@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Union
from pydantic import BaseModel from pydantic import BaseModel
from aiogram.dispatcher.filters.logic import _LogicFilter from aiogram.filters.logic import _LogicFilter
class BaseFilter(BaseModel, ABC, _LogicFilter): class BaseFilter(BaseModel, ABC, _LogicFilter):

View file

@ -9,7 +9,7 @@ from uuid import UUID
from magic_filter import MagicFilter from magic_filter import MagicFilter
from pydantic import BaseModel from pydantic import BaseModel
from aiogram.dispatcher.filters import BaseFilter from aiogram.filters import BaseFilter
from aiogram.types import CallbackQuery from aiogram.types import CallbackQuery
T = TypeVar("T", bound="CallbackData") T = TypeVar("T", bound="CallbackData")

View file

@ -1,6 +1,6 @@
from typing import Any, Dict, Optional, TypeVar, Union from typing import Any, Dict, Optional, TypeVar, Union
from aiogram.dispatcher.filters import BaseFilter from aiogram.filters import BaseFilter
from aiogram.types import ChatMember, ChatMemberUpdated from aiogram.types import ChatMember, ChatMemberUpdated
MarkerT = TypeVar("MarkerT", bound="_MemberStatusMarker") MarkerT = TypeVar("MarkerT", bound="_MemberStatusMarker")

View file

@ -2,16 +2,18 @@ from __future__ import annotations
import re import re
from dataclasses import dataclass, field, replace from dataclasses import dataclass, field, replace
from typing import Any, Dict, Match, Optional, Pattern, Sequence, Tuple, Union, cast from typing import TYPE_CHECKING, Any, Dict, Match, Optional, Pattern, Sequence, Tuple, Union, cast
from magic_filter import MagicFilter from magic_filter import MagicFilter
from pydantic import Field, validator from pydantic import Field, validator
from aiogram import Bot from aiogram.filters import BaseFilter
from aiogram.dispatcher.filters import BaseFilter
from aiogram.types import Message from aiogram.types import Message
from aiogram.utils.deep_linking import decode_payload from aiogram.utils.deep_linking import decode_payload
if TYPE_CHECKING:
from aiogram import Bot
CommandPatternType = Union[str, re.Pattern] CommandPatternType = Union[str, re.Pattern]

View file

@ -2,9 +2,9 @@ from typing import Any, Dict, Optional, Sequence, Union
from pydantic import validator from pydantic import validator
from aiogram.types import Message
from aiogram.types.message import ContentType from aiogram.types.message import ContentType
from ...types import Message
from .base import BaseFilter from .base import BaseFilter

View file

@ -3,7 +3,7 @@ from typing import Any, Dict, Pattern, Tuple, Type, Union, cast
from pydantic import validator from pydantic import validator
from aiogram.dispatcher.filters import BaseFilter from aiogram.filters import BaseFilter
from aiogram.types import TelegramObject from aiogram.types import TelegramObject

View file

@ -2,7 +2,7 @@ from typing import Any
from magic_filter import AttrDict, MagicFilter from magic_filter import AttrDict, MagicFilter
from aiogram.dispatcher.filters import BaseFilter from aiogram.filters import BaseFilter
from aiogram.types import TelegramObject from aiogram.types import TelegramObject

View file

@ -3,8 +3,8 @@ from typing import Any, Dict, Optional, Sequence, Type, Union, cast, no_type_che
from pydantic import Field, validator from pydantic import Field, validator
from aiogram.dispatcher.filters import BaseFilter from aiogram.filters import BaseFilter
from aiogram.dispatcher.fsm.state import State, StatesGroup from aiogram.fsm.state import State, StatesGroup
from aiogram.types import TelegramObject from aiogram.types import TelegramObject
StateType = Union[str, None, State, StatesGroup, Type[StatesGroup]] StateType = Union[str, None, State, StatesGroup, Type[StatesGroup]]

View file

@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Union
from pydantic import root_validator from pydantic import root_validator
from aiogram.dispatcher.filters import BaseFilter from aiogram.filters import BaseFilter
from aiogram.types import CallbackQuery, InlineQuery, Message, Poll from aiogram.types import CallbackQuery, InlineQuery, Message, Poll
if TYPE_CHECKING: if TYPE_CHECKING:

View file

@ -1,7 +1,7 @@
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from aiogram import Bot from aiogram import Bot
from aiogram.dispatcher.fsm.storage.base import BaseStorage, StateType, StorageKey from aiogram.fsm.storage.base import BaseStorage, StateType, StorageKey
class FSMContext: class FSMContext:

View file

@ -1,15 +1,10 @@
from typing import Any, Awaitable, Callable, Dict, Optional, cast from typing import Any, Awaitable, Callable, Dict, Optional, cast
from aiogram import Bot from aiogram import Bot
from aiogram.dispatcher.fsm.context import FSMContext
from aiogram.dispatcher.fsm.storage.base import (
DEFAULT_DESTINY,
BaseEventIsolation,
BaseStorage,
StorageKey,
)
from aiogram.dispatcher.fsm.strategy import FSMStrategy, apply_strategy
from aiogram.dispatcher.middlewares.base import BaseMiddleware from aiogram.dispatcher.middlewares.base import BaseMiddleware
from aiogram.fsm.context import FSMContext
from aiogram.fsm.storage.base import DEFAULT_DESTINY, BaseEventIsolation, BaseStorage, StorageKey
from aiogram.fsm.strategy import FSMStrategy, apply_strategy
from aiogram.types import TelegramObject from aiogram.types import TelegramObject

View file

@ -1,7 +1,7 @@
import inspect import inspect
from typing import Any, Iterator, Optional, Tuple, Type, no_type_check from typing import Any, Iterator, Optional, Tuple, Type, no_type_check
from ...types import TelegramObject from aiogram.types import TelegramObject
class State: class State:

View file

@ -4,7 +4,7 @@ from dataclasses import dataclass
from typing import Any, AsyncGenerator, Dict, Optional, Union from typing import Any, AsyncGenerator, Dict, Optional, Union
from aiogram import Bot from aiogram import Bot
from aiogram.dispatcher.fsm.state import State from aiogram.fsm.state import State
StateType = Optional[Union[str, State]] StateType = Optional[Union[str, State]]

View file

@ -5,13 +5,8 @@ from dataclasses import dataclass, field
from typing import Any, AsyncGenerator, DefaultDict, Dict, Hashable, Optional from typing import Any, AsyncGenerator, DefaultDict, Dict, Hashable, Optional
from aiogram import Bot from aiogram import Bot
from aiogram.dispatcher.fsm.state import State from aiogram.fsm.state import State
from aiogram.dispatcher.fsm.storage.base import ( from aiogram.fsm.storage.base import BaseEventIsolation, BaseStorage, StateType, StorageKey
BaseEventIsolation,
BaseStorage,
StateType,
StorageKey,
)
@dataclass @dataclass

View file

@ -8,8 +8,8 @@ from redis.asyncio.lock import Lock
from redis.typing import ExpiryT from redis.typing import ExpiryT
from aiogram import Bot from aiogram import Bot
from aiogram.dispatcher.fsm.state import State from aiogram.fsm.state import State
from aiogram.dispatcher.fsm.storage.base import ( from aiogram.fsm.storage.base import (
DEFAULT_DESTINY, DEFAULT_DESTINY,
BaseEventIsolation, BaseEventIsolation,
BaseStorage, BaseStorage,

View file

@ -1,9 +1,13 @@
from __future__ import annotations
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Dict, Generic, TypeVar, cast from typing import TYPE_CHECKING, Any, Dict, Generic, TypeVar, cast
from aiogram import Bot
from aiogram.types import Update from aiogram.types import Update
if TYPE_CHECKING:
from aiogram import Bot
T = TypeVar("T") T = TypeVar("T")
@ -24,6 +28,8 @@ class BaseHandler(BaseHandlerMixin[T], ABC):
@property @property
def bot(self) -> Bot: def bot(self) -> Bot:
from aiogram import Bot
if "bot" in self.data: if "bot" in self.data:
return cast(Bot, self.data["bot"]) return cast(Bot, self.data["bot"])
return Bot.get_current(no_error=False) return Bot.get_current(no_error=False)

View file

@ -1,7 +1,7 @@
from abc import ABC from abc import ABC
from typing import Optional from typing import Optional
from aiogram.dispatcher.handler import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import CallbackQuery, Message, User from aiogram.types import CallbackQuery, Message, User

View file

@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from aiogram.dispatcher.handler import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import ChatMemberUpdated, User from aiogram.types import ChatMemberUpdated, User

View file

@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from aiogram.dispatcher.handler import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import ChosenInlineResult, User from aiogram.types import ChosenInlineResult, User

View file

@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from aiogram.dispatcher.handler.base import BaseHandler from aiogram.handlers.base import BaseHandler
class ErrorHandler(BaseHandler[Exception], ABC): class ErrorHandler(BaseHandler[Exception], ABC):

View file

@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from aiogram.dispatcher.handler import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import InlineQuery, User from aiogram.types import InlineQuery, User

View file

@ -1,8 +1,8 @@
from abc import ABC from abc import ABC
from typing import Optional, cast from typing import Optional, cast
from aiogram.dispatcher.filters import CommandObject from aiogram.filters import CommandObject
from aiogram.dispatcher.handler.base import BaseHandler, BaseHandlerMixin from aiogram.handlers.base import BaseHandler, BaseHandlerMixin
from aiogram.types import Chat, Message, User from aiogram.types import Chat, Message, User

View file

@ -1,7 +1,7 @@
from abc import ABC from abc import ABC
from typing import List from typing import List
from aiogram.dispatcher.handler import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import Poll, PollOption from aiogram.types import Poll, PollOption

View file

@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from aiogram.dispatcher.handler import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import PreCheckoutQuery, User from aiogram.types import PreCheckoutQuery, User

View file

@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from aiogram.dispatcher.handler import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import ShippingQuery, User from aiogram.types import ShippingQuery, User

View file

@ -7,7 +7,7 @@ from types import TracebackType
from typing import Any, Awaitable, Callable, Dict, Optional, Type, Union from typing import Any, Awaitable, Callable, Dict, Optional, Type, Union
from aiogram import BaseMiddleware, Bot from aiogram import BaseMiddleware, Bot
from aiogram.dispatcher.flags.getter import get_flag from aiogram.dispatcher.flags import get_flag
from aiogram.types import Message, TelegramObject from aiogram.types import Message, TelegramObject
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View file

@ -42,13 +42,17 @@ Decode it back example:
await message.answer(f"Your payload: {payload}") await message.answer(f"Your payload: {payload}")
""" """
from __future__ import annotations
import re import re
from base64 import urlsafe_b64decode, urlsafe_b64encode from base64 import urlsafe_b64decode, urlsafe_b64encode
from typing import Literal, cast from typing import TYPE_CHECKING, Literal, cast
from aiogram import Bot
from aiogram.utils.link import create_telegram_link from aiogram.utils.link import create_telegram_link
if TYPE_CHECKING:
from aiogram import Bot
BAD_PATTERN = re.compile(r"[^_A-z0-9-]") BAD_PATTERN = re.compile(r"[^_A-z0-9-]")

View file

@ -11,7 +11,7 @@ except ImportError: # pragma: no cover
from aiogram import BaseMiddleware, Router from aiogram import BaseMiddleware, Router
from aiogram.dispatcher.fsm.context import FSMContext from aiogram.fsm.context import FSMContext
from aiogram.types import TelegramObject, User from aiogram.types import TelegramObject, User
from aiogram.utils.i18n.core import I18n from aiogram.utils.i18n.core import I18n

View file

@ -17,7 +17,7 @@ from typing import (
no_type_check, no_type_check,
) )
from aiogram.dispatcher.filters.callback_data import CallbackData from aiogram.filters.callback_data import CallbackData
from aiogram.types import ( from aiogram.types import (
CallbackGame, CallbackGame,
InlineKeyboardButton, InlineKeyboardButton,

View file

@ -14,6 +14,8 @@ __all__ = (
"TextDecoration", "TextDecoration",
"html_decoration", "html_decoration",
"markdown_decoration", "markdown_decoration",
"add_surrogates",
"remove_surrogates",
) )

View file

@ -117,7 +117,7 @@ def safe_parse_webapp_init_data(
""" """
Validate raw WebApp init data and return it as WebAppInitData object Validate raw WebApp init data and return it as WebAppInitData object
Raise :type:`ValueError` when data is invalid Raise :obj:`ValueError` when data is invalid
:param token: bot token :param token: bot token
:param init_data: data from frontend to be parsed and validated :param init_data: data from frontend to be parsed and validated

View file

@ -9,8 +9,8 @@ from aiohttp.typedefs import Handler
from aiohttp.web_middlewares import middleware from aiohttp.web_middlewares import middleware
from aiogram import Bot, Dispatcher, loggers from aiogram import Bot, Dispatcher, loggers
from aiogram.dispatcher.webhook.security import IPFilter
from aiogram.methods import TelegramMethod from aiogram.methods import TelegramMethod
from aiogram.webhook.security import IPFilter
def setup_application(app: Application, dispatcher: Dispatcher, /, **kwargs: Any) -> None: def setup_application(app: Application, dispatcher: Dispatcher, /, **kwargs: Any) -> None:

View file

@ -39,8 +39,9 @@ rst_prolog = f"""
:language: python3 :language: python3
""" """
language = None # language = None
locale_dirs = ["locales"] locale_dirs = ["locale/"]
gettext_compact = False
exclude_patterns = [] exclude_patterns = []
source_suffix = ".rst" source_suffix = ".rst"

View file

@ -3,7 +3,7 @@ CallbackQueryHandler
#################### ####################
.. automodule:: aiogram.dispatcher.handler.callback_query .. automodule:: aiogram.handler.callback_query
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: True :undoc-members: True

View file

@ -2,7 +2,7 @@
Callback Data Factory & Filter Callback Data Factory & Filter
============================== ==============================
.. autoclass:: aiogram.dispatcher.filters.callback_data.CallbackData .. autoclass:: aiogram.filters.callback_data.CallbackData
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False

View file

@ -2,12 +2,12 @@
ChatMemberUpdated ChatMemberUpdated
================= =================
.. autoclass:: aiogram.dispatcher.filters.chat_member_updated.ChatMemberUpdatedFilter .. autoclass:: aiogram.filters.chat_member_updated.ChatMemberUpdatedFilter
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False
You can import from :code:`aiogram.dispatcher.filters` all available You can import from :code:`aiogram.filters` all available
variants of `statuses`_, `status groups`_ or `transitions`_: variants of `statuses`_, `status groups`_ or `transitions`_:
Statuses Statuses
@ -84,7 +84,7 @@ Handle user leave or join events
.. code-block:: python .. code-block:: python
from aiogram.dispatcher.filters import IS_MEMBER, IS_NOT_MEMBER from aiogram.filters import IS_MEMBER, IS_NOT_MEMBER
@router.chat_member(member_status_changed=IS_MEMBER >> IS_NOT_MEMBER) @router.chat_member(member_status_changed=IS_MEMBER >> IS_NOT_MEMBER)
async def on_user_leave(event: ChatMemberUpdated): ... async def on_user_leave(event: ChatMemberUpdated): ...

View file

@ -2,14 +2,14 @@
Command Command
======= =======
.. autoclass:: aiogram.dispatcher.filters.command.Command .. autoclass:: aiogram.filters.command.Command
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False
When filter is passed the :class:`aiogram.dispatcher.filters.command.CommandObject` will be passed to the handler argument :code:`command` When filter is passed the :class:`aiogram.filters.command.CommandObject` will be passed to the handler argument :code:`command`
.. autoclass:: aiogram.dispatcher.filters.command.CommandObject .. autoclass:: aiogram.filters.command.CommandObject
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False

View file

@ -2,15 +2,14 @@
ContentTypesFilter ContentTypesFilter
================== ==================
.. autoclass:: aiogram.dispatcher.filters.content_types.ContentTypesFilter .. autoclass:: aiogram.filters.content_types.ContentTypesFilter
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False
Can be imported: Can be imported:
- :code:`from aiogram.dispatcher.filters.content_types import ContentTypesFilter` - :code:`from aiogram.filters.content_types import ContentTypesFilter`
- :code:`from aiogram.dispatcher.filters import ContentTypesFilter`
- :code:`from aiogram.filters import ContentTypesFilter` - :code:`from aiogram.filters import ContentTypesFilter`
Or used from filters factory by passing corresponding arguments to handler registration line Or used from filters factory by passing corresponding arguments to handler registration line

View file

@ -4,12 +4,12 @@ Exceptions
This filters can be helpful for handling errors from the text messages. This filters can be helpful for handling errors from the text messages.
.. autoclass:: aiogram.dispatcher.filters.exception.ExceptionTypeFilter .. autoclass:: aiogram.filters.exception.ExceptionTypeFilter
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False
.. autoclass:: aiogram.dispatcher.filters.exception.ExceptionMessageFilter .. autoclass:: aiogram.filters.exception.ExceptionMessageFilter
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False

View file

@ -37,7 +37,7 @@ Filters can be:
- Any awaitable object - Any awaitable object
- Subclass of :class:`aiogram.dispatcher.filters.base.BaseFilter` - Subclass of :class:`aiogram.filters.base.BaseFilter`
- Instances of :ref:`MagicFilter <magic-filters>` - Instances of :ref:`MagicFilter <magic-filters>`
@ -48,7 +48,7 @@ filters and handler as keywords arguments.
Writing bound filters Writing bound filters
===================== =====================
.. autoclass:: aiogram.dispatcher.filters.base.BaseFilter .. autoclass:: aiogram.filters.base.BaseFilter
:members: __call__ :members: __call__
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False
@ -57,7 +57,7 @@ For example if you need to make simple text filter:
.. code-block:: python .. code-block:: python
from aiogram.dispatcher.filters import BaseFilter from aiogram.filters import BaseFilter
class MyText(BaseFilter): class MyText(BaseFilter):

View file

@ -2,15 +2,14 @@
MagicData MagicData
==== ====
.. autoclass:: aiogram.dispatcher.filters.magic_data.MagicData .. autoclass:: aiogram.filters.magic_data.MagicData
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False
Can be imported: Can be imported:
- :code:`from aiogram.dispatcher.filters.magic_data import MagicData` - :code:`from aiogram.filters.magic_data import MagicData`
- :code:`from aiogram.dispatcher.filters import MagicData`
- :code:`from aiogram.filters import MagicData` - :code:`from aiogram.filters import MagicData`
Or used from filters factory by passing corresponding arguments to handler registration line Or used from filters factory by passing corresponding arguments to handler registration line

View file

@ -2,16 +2,16 @@
Text Text
==== ====
.. autoclass:: aiogram.dispatcher.filters.text.Text .. autoclass:: aiogram.filters.text.Text
:members: :members:
:member-order: bysource :member-order: bysource
:undoc-members: False :undoc-members: False
Can be imported: Can be imported:
- :code:`from aiogram.dispatcher.filters.text import Text` - :code:`from aiogram.filters.text import Text`
- :code:`from aiogram.dispatcher.filters import Text`
- :code:`from aiogram.filters import Text` - :code:`from aiogram.filters import Text`
- :code:`from.filters import Text`
Or used from filters factory by passing corresponding arguments to handler registration line Or used from filters factory by passing corresponding arguments to handler registration line

View file

@ -8,24 +8,24 @@ Storages out of the box
MemoryStorage MemoryStorage
------------- -------------
.. autoclass:: aiogram.dispatcher.fsm.storage.memory.MemoryStorage .. autoclass:: aiogram.fsm.storage.memory.MemoryStorage
:members: __init__ :members: __init__
:member-order: bysource :member-order: bysource
RedisStorage RedisStorage
------------ ------------
.. autoclass:: aiogram.dispatcher.fsm.storage.redis.RedisStorage .. autoclass:: aiogram.fsm.storage.redis.RedisStorage
:members: __init__, from_url :members: __init__, from_url
:member-order: bysource :member-order: bysource
Keys inside storage can be customized via key builders: Keys inside storage can be customized via key builders:
.. autoclass:: aiogram.dispatcher.fsm.storage.redis.KeyBuilder .. autoclass:: aiogram.fsm.storage.redis.KeyBuilder
:members: :members:
:member-order: bysource :member-order: bysource
.. autoclass:: aiogram.dispatcher.fsm.storage.redis.DefaultKeyBuilder .. autoclass:: aiogram.fsm.storage.redis.DefaultKeyBuilder
:members: :members:
:member-order: bysource :member-order: bysource
@ -33,6 +33,6 @@ Keys inside storage can be customized via key builders:
Writing own storages Writing own storages
==================== ====================
.. autoclass:: aiogram.dispatcher.fsm.storage.base.BaseStorage .. autoclass:: aiogram.fsm.storage.base.BaseStorage
:members: :members:
:member-order: bysource :member-order: bysource

View file

@ -54,7 +54,7 @@ Via filters
Use in middlewares Use in middlewares
================== ==================
.. automodule:: aiogram.dispatcher.flags.getter .. automodule:: aiogram.flags.getter
:members: :members:
Example in middlewares Example in middlewares

View file

@ -45,7 +45,7 @@ Message
(For example text, sticker and document are always of different content types of message) (For example text, sticker and document are always of different content types of message)
Recommended way to check field availability before usage or use Recommended way to check field availability before usage or use
:class:`aiogram.dispatcher.filters.content_types.ContentTypesFilter` :class:`aiogram.filters.content_types.ContentTypesFilter`
.. code-block:: python .. code-block:: python

View file

@ -14,10 +14,11 @@ async def command_start_handler(message: Message) -> None:
""" """
This handler receive messages with `/start` command This handler receive messages with `/start` command
""" """
# Most of event objects has an aliases for API methods to be called in event context # Most event objects have aliases for API methods that can be called in events' context
# For example if you want to answer to incoming message you can use `message.answer(...)` alias # For example if you want to answer to incoming message you can use `message.answer(...)` alias
# and the target chat will be passed to :ref:`aiogram.methods.send_message.SendMessage` method automatically # and the target chat will be passed to :ref:`aiogram.methods.send_message.SendMessage`
# or call API method directly via Bot instance: `bot.send_message(chat_id=message.chat.id, ...)` # method automatically or call API method directly via
# Bot instance: `bot.send_message(chat_id=message.chat.id, ...)`
await message.answer(f"Hello, <b>{message.from_user.full_name}!</b>") await message.answer(f"Hello, <b>{message.from_user.full_name}!</b>")
@ -26,7 +27,7 @@ async def echo_handler(message: types.Message) -> None:
""" """
Handler will forward received message back to the sender Handler will forward received message back to the sender
By default message handler will handle all message types (like text, photo, sticker and etc.) By default, message handler will handle all message types (like text, photo, sticker and etc.)
""" """
try: try:
# Send copy of the received message # Send copy of the received message

View file

@ -5,8 +5,8 @@ from os import getenv
from typing import Any, Dict from typing import Any, Dict
from aiogram import Bot, Dispatcher, F, Router, html from aiogram import Bot, Dispatcher, F, Router, html
from aiogram.dispatcher.fsm.context import FSMContext from aiogram.fsm.context import FSMContext
from aiogram.dispatcher.fsm.state import State, StatesGroup from aiogram.fsm.state import State, StatesGroup
from aiogram.types import KeyboardButton, Message, ReplyKeyboardMarkup, ReplyKeyboardRemove from aiogram.types import KeyboardButton, Message, ReplyKeyboardMarkup, ReplyKeyboardRemove
form_router = Router() form_router = Router()

View file

@ -6,16 +6,16 @@ from finite_state_machine import form_router
from aiogram import Bot, Dispatcher, F, Router from aiogram import Bot, Dispatcher, F, Router
from aiogram.client.session.aiohttp import AiohttpSession from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.dispatcher.filters import Command, CommandObject from aiogram.exceptions import TelegramUnauthorizedError
from aiogram.dispatcher.fsm.storage.redis import DefaultKeyBuilder, RedisStorage from aiogram.filters import Command, CommandObject
from aiogram.dispatcher.webhook.aiohttp_server import ( from aiogram.fsm.storage.redis import DefaultKeyBuilder, RedisStorage
from aiogram.types import Message
from aiogram.utils.token import TokenValidationError, validate_token
from aiogram.webhook.aiohttp_server import (
SimpleRequestHandler, SimpleRequestHandler,
TokenBasedRequestHandler, TokenBasedRequestHandler,
setup_application, setup_application,
) )
from aiogram.exceptions import TelegramUnauthorizedError
from aiogram.types import Message
from aiogram.utils.token import TokenValidationError, validate_token
main_router = Router() main_router = Router()

View file

@ -1,10 +1,13 @@
import logging import logging
from aiogram import Bot, Dispatcher from aiogram import Bot, Dispatcher, Router
from aiogram.dispatcher.router import Router from aiogram.types import (
from aiogram.types import CallbackQuery, ChatMemberUpdated, Message CallbackQuery,
from aiogram.types.inline_keyboard_button import InlineKeyboardButton ChatMemberUpdated,
from aiogram.types.inline_keyboard_markup import InlineKeyboardMarkup InlineKeyboardButton,
InlineKeyboardMarkup,
Message,
)
TOKEN = "6wo" TOKEN = "6wo"
dp = Dispatcher() dp = Dispatcher()

View file

@ -1,5 +1,5 @@
from aiogram import Bot, F, Router from aiogram import Bot, F, Router
from aiogram.dispatcher.filters import Command from aiogram.filters import Command
from aiogram.types import ( from aiogram.types import (
InlineKeyboardButton, InlineKeyboardButton,
InlineKeyboardMarkup, InlineKeyboardMarkup,

View file

@ -7,8 +7,8 @@ from handlers import my_router
from routes import check_data_handler, demo_handler, send_message_handler from routes import check_data_handler, demo_handler, send_message_handler
from aiogram import Bot, Dispatcher from aiogram import Bot, Dispatcher
from aiogram.dispatcher.webhook.aiohttp_server import SimpleRequestHandler, setup_application
from aiogram.types import MenuButtonWebApp, WebAppInfo from aiogram.types import MenuButtonWebApp, WebAppInfo
from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application
TELEGRAM_TOKEN = getenv("TELEGRAM_TOKEN") TELEGRAM_TOKEN = getenv("TELEGRAM_TOKEN")
APP_BASE_URL = getenv("APP_BASE_URL") APP_BASE_URL = getenv("APP_BASE_URL")

261
poetry.lock generated
View file

@ -110,11 +110,11 @@ tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>
[[package]] [[package]]
name = "babel" name = "babel"
version = "2.9.1" version = "2.10.3"
description = "Internationalization utilities" description = "Internationalization utilities"
category = "main" category = "main"
optional = true optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" python-versions = ">=3.6"
[package.dependencies] [package.dependencies]
pytz = ">=2015.7" pytz = ">=2015.7"
@ -156,14 +156,6 @@ d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"] uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "certifi"
version = "2021.10.8"
description = "Python package for providing Mozilla's CA Bundle."
category = "main"
optional = true
python-versions = "*"
[[package]] [[package]]
name = "cfgv" name = "cfgv"
version = "3.3.1" version = "3.3.1"
@ -174,18 +166,18 @@ python-versions = ">=3.6.1"
[[package]] [[package]]
name = "charset-normalizer" name = "charset-normalizer"
version = "2.0.12" version = "2.1.0"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.5.0" python-versions = ">=3.6.0"
[package.extras] [package.extras]
unicode_backport = ["unicodedata2"] unicode_backport = ["unicodedata2"]
[[package]] [[package]]
name = "click" name = "click"
version = "8.1.2" version = "8.1.3"
description = "Composable command line interface toolkit" description = "Composable command line interface toolkit"
category = "main" category = "main"
optional = false optional = false
@ -207,7 +199,7 @@ click = "*"
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.4" version = "0.4.5"
description = "Cross-platform colored terminal text." description = "Cross-platform colored terminal text."
category = "main" category = "main"
optional = false optional = false
@ -259,7 +251,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]] [[package]]
name = "filelock" name = "filelock"
version = "3.6.0" version = "3.7.1"
description = "A platform independent file lock." description = "A platform independent file lock."
category = "dev" category = "dev"
optional = false optional = false
@ -306,7 +298,7 @@ sphinx-basic-ng = "*"
[[package]] [[package]]
name = "identify" name = "identify"
version = "2.4.12" version = "2.5.1"
description = "File identification library for Python" description = "File identification library for Python"
category = "dev" category = "dev"
optional = false optional = false
@ -333,7 +325,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]] [[package]]
name = "importlib-metadata" name = "importlib-metadata"
version = "4.11.3" version = "4.11.4"
description = "Read metadata from Python packages" description = "Read metadata from Python packages"
category = "main" category = "main"
optional = true optional = true
@ -382,7 +374,7 @@ plugins = ["setuptools"]
[[package]] [[package]]
name = "jinja2" name = "jinja2"
version = "3.1.1" version = "3.1.2"
description = "A very fast and expressive template engine." description = "A very fast and expressive template engine."
category = "main" category = "main"
optional = true optional = true
@ -416,7 +408,7 @@ python-versions = ">=3.6.2,<4.0.0"
[[package]] [[package]]
name = "markdown" name = "markdown"
version = "3.3.6" version = "3.3.7"
description = "Python implementation of Markdown." description = "Python implementation of Markdown."
category = "main" category = "main"
optional = true optional = true
@ -518,15 +510,15 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]] [[package]]
name = "platformdirs" name = "platformdirs"
version = "2.5.1" version = "2.5.2"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
[package.extras] [package.extras]
docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
[[package]] [[package]]
name = "pluggy" name = "pluggy"
@ -616,7 +608,7 @@ markdown = ">=3.2"
[[package]] [[package]]
name = "pyparsing" name = "pyparsing"
version = "3.0.8" version = "3.0.9"
description = "pyparsing module - Classes and methods to define and execute parsing grammars" description = "pyparsing module - Classes and methods to define and execute parsing grammars"
category = "main" category = "main"
optional = false optional = false
@ -811,21 +803,15 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"
[[package]] [[package]]
name = "requests" name = "requests"
version = "2.27.1" version = "2.15.1"
description = "Python HTTP for Humans." description = "Python HTTP for Humans."
category = "main" category = "main"
optional = true optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" python-versions = "*"
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
urllib3 = ">=1.21.1,<1.27"
[package.extras] [package.extras]
security = ["cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)"]
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
[[package]] [[package]]
name = "six" name = "six"
@ -845,7 +831,7 @@ python-versions = "*"
[[package]] [[package]]
name = "soupsieve" name = "soupsieve"
version = "2.3.2" version = "2.3.2.post1"
description = "A modern CSS selector implementation for Beautiful Soup." description = "A modern CSS selector implementation for Beautiful Soup."
category = "main" category = "main"
optional = true optional = true
@ -1094,19 +1080,6 @@ category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
[[package]]
name = "urllib3"
version = "1.26.9"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
[package.extras]
brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]] [[package]]
name = "uvloop" name = "uvloop"
version = "0.16.0" version = "0.16.0"
@ -1122,7 +1095,7 @@ test = ["aiohttp", "flake8 (>=3.9.2,<3.10.0)", "psutil", "pycodestyle (>=2.7.0,<
[[package]] [[package]]
name = "virtualenv" name = "virtualenv"
version = "20.14.0" version = "20.14.1"
description = "Virtual Python Environment builder" description = "Virtual Python Environment builder"
category = "dev" category = "dev"
optional = false optional = false
@ -1140,7 +1113,7 @@ testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)",
[[package]] [[package]]
name = "wrapt" name = "wrapt"
version = "1.14.0" version = "1.14.1"
description = "Module for decorators, wrappers and monkey patching." description = "Module for decorators, wrappers and monkey patching."
category = "main" category = "main"
optional = true optional = true
@ -1294,8 +1267,8 @@ attrs = [
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
] ]
babel = [ babel = [
{file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"},
{file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"},
] ]
beautifulsoup4 = [ beautifulsoup4 = [
{file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"},
@ -1326,28 +1299,24 @@ black = [
{file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
] ]
certifi = [
{file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
{file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
]
cfgv = [ cfgv = [
{file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
{file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
] ]
charset-normalizer = [ charset-normalizer = [
{file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"},
{file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"},
] ]
click = [ click = [
{file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"}, {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"}, {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
] ]
click-default-group = [ click-default-group = [
{file = "click-default-group-1.2.2.tar.gz", hash = "sha256:d9560e8e8dfa44b3562fbc9425042a0fd6d21956fcc2db0077f63f34253ab904"}, {file = "click-default-group-1.2.2.tar.gz", hash = "sha256:d9560e8e8dfa44b3562fbc9425042a0fd6d21956fcc2db0077f63f34253ab904"},
] ]
colorama = [ colorama = [
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
] ]
coverage = [ coverage = [
{file = "coverage-6.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b"}, {file = "coverage-6.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b"},
@ -1405,8 +1374,8 @@ docutils = [
{file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"},
] ]
filelock = [ filelock = [
{file = "filelock-3.6.0-py3-none-any.whl", hash = "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0"}, {file = "filelock-3.7.1-py3-none-any.whl", hash = "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404"},
{file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, {file = "filelock-3.7.1.tar.gz", hash = "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04"},
] ]
flake8 = [ flake8 = [
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
@ -1478,8 +1447,8 @@ furo = [
{file = "furo-2022.6.21.tar.gz", hash = "sha256:9aa983b7488a4601d13113884bfb7254502c8729942e073a0acb87a5512af223"}, {file = "furo-2022.6.21.tar.gz", hash = "sha256:9aa983b7488a4601d13113884bfb7254502c8729942e073a0acb87a5512af223"},
] ]
identify = [ identify = [
{file = "identify-2.4.12-py2.py3-none-any.whl", hash = "sha256:5f06b14366bd1facb88b00540a1de05b69b310cbc2654db3c7e07fa3a4339323"}, {file = "identify-2.5.1-py2.py3-none-any.whl", hash = "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa"},
{file = "identify-2.4.12.tar.gz", hash = "sha256:3f3244a559290e7d3deb9e9adc7b33594c1bc85a9dd82e0f1be519bf12a1ec17"}, {file = "identify-2.5.1.tar.gz", hash = "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82"},
] ]
idna = [ idna = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
@ -1490,8 +1459,8 @@ imagesize = [
{file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"},
] ]
importlib-metadata = [ importlib-metadata = [
{file = "importlib_metadata-4.11.3-py3-none-any.whl", hash = "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6"}, {file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"},
{file = "importlib_metadata-4.11.3.tar.gz", hash = "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"}, {file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"},
] ]
incremental = [ incremental = [
{file = "incremental-21.3.0-py2.py3-none-any.whl", hash = "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321"}, {file = "incremental-21.3.0-py2.py3-none-any.whl", hash = "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321"},
@ -1506,8 +1475,8 @@ isort = [
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
] ]
jinja2 = [ jinja2 = [
{file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"}, {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
{file = "Jinja2-3.1.1.tar.gz", hash = "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
] ]
livereload = [ livereload = [
{file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"},
@ -1517,8 +1486,8 @@ magic-filter = [
{file = "magic_filter-1.0.7-py3-none-any.whl", hash = "sha256:cf591b7f8c4a5037e162fb054ff84e6a7f6db05eb36f312f60b8bfefddc12294"}, {file = "magic_filter-1.0.7-py3-none-any.whl", hash = "sha256:cf591b7f8c4a5037e162fb054ff84e6a7f6db05eb36f312f60b8bfefddc12294"},
] ]
markdown = [ markdown = [
{file = "Markdown-3.3.6-py3-none-any.whl", hash = "sha256:9923332318f843411e9932237530df53162e29dc7a4e2b91e35764583c46c9a3"}, {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"},
{file = "Markdown-3.3.6.tar.gz", hash = "sha256:76df8ae32294ec39dcf89340382882dfa12975f87f45c3ed1ecdb1e8cefc7006"}, {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"},
] ]
markdown-include = [ markdown-include = [
{file = "markdown-include-0.6.0.tar.gz", hash = "sha256:6f5d680e36f7780c7f0f61dca53ca581bd50d1b56137ddcd6353efafa0c3e4a2"}, {file = "markdown-include-0.6.0.tar.gz", hash = "sha256:6f5d680e36f7780c7f0f61dca53ca581bd50d1b56137ddcd6353efafa0c3e4a2"},
@ -1672,8 +1641,8 @@ pathspec = [
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
] ]
platformdirs = [ platformdirs = [
{file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"}, {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
{file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"}, {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"},
] ]
pluggy = [ pluggy = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
@ -1741,8 +1710,8 @@ pymdown-extensions = [
{file = "pymdown_extensions-9.5.tar.gz", hash = "sha256:3ef2d998c0d5fa7eb09291926d90d69391283561cf6306f85cd588a5eb5befa0"}, {file = "pymdown_extensions-9.5.tar.gz", hash = "sha256:3ef2d998c0d5fa7eb09291926d90d69391283561cf6306f85cd588a5eb5befa0"},
] ]
pyparsing = [ pyparsing = [
{file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
{file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
] ]
pytest = [ pytest = [
{file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"}, {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"},
@ -1829,8 +1798,8 @@ redis = [
{file = "redis-4.3.3.tar.gz", hash = "sha256:2f7a57cf4af15cd543c4394bcbe2b9148db2606a37edba755368836e3a1d053e"}, {file = "redis-4.3.3.tar.gz", hash = "sha256:2f7a57cf4af15cd543c4394bcbe2b9148db2606a37edba755368836e3a1d053e"},
] ]
requests = [ requests = [
{file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, {file = "requests-2.15.1-py2.py3-none-any.whl", hash = "sha256:ff753b2196cd18b1bbeddc9dcd5c864056599f7a7d9a4fb5677e723efa2b7fb9"},
{file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, {file = "requests-2.15.1.tar.gz", hash = "sha256:e5659b9315a0610505e050bb7190bf6fa2ccee1ac295f2b760ef9d8a03ebbb2e"},
] ]
six = [ six = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
@ -1841,8 +1810,8 @@ snowballstemmer = [
{file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
] ]
soupsieve = [ soupsieve = [
{file = "soupsieve-2.3.2-py3-none-any.whl", hash = "sha256:a714129d3021ec17ce5be346b1007300558b378332c289a1a20e7d4de6ff18a5"}, {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"},
{file = "soupsieve-2.3.2.tar.gz", hash = "sha256:0bcc6d7432153063e3df09c3ac9442af3eba488715bfcad6a4c38ccb2a523124"}, {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"},
] ]
sphinx = [ sphinx = [
{file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"},
@ -1954,10 +1923,6 @@ typing-extensions = [
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
{file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"},
] ]
urllib3 = [
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
]
uvloop = [ uvloop = [
{file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"}, {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"},
{file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c"}, {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c"},
@ -1977,74 +1942,74 @@ uvloop = [
{file = "uvloop-0.16.0.tar.gz", hash = "sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228"}, {file = "uvloop-0.16.0.tar.gz", hash = "sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228"},
] ]
virtualenv = [ virtualenv = [
{file = "virtualenv-20.14.0-py2.py3-none-any.whl", hash = "sha256:1e8588f35e8b42c6ec6841a13c5e88239de1e6e4e4cedfd3916b306dc826ec66"}, {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"},
{file = "virtualenv-20.14.0.tar.gz", hash = "sha256:8e5b402037287126e81ccde9432b95a8be5b19d36584f64957060a3488c11ca8"}, {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"},
] ]
wrapt = [ wrapt = [
{file = "wrapt-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:5a9a1889cc01ed2ed5f34574c90745fab1dd06ec2eee663e8ebeefe363e8efd7"}, {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
{file = "wrapt-1.14.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:9a3ff5fb015f6feb78340143584d9f8a0b91b6293d6b5cf4295b3e95d179b88c"}, {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"},
{file = "wrapt-1.14.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4b847029e2d5e11fd536c9ac3136ddc3f54bc9488a75ef7d040a3900406a91eb"}, {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"},
{file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9a5a544861b21e0e7575b6023adebe7a8c6321127bb1d238eb40d99803a0e8bd"}, {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"},
{file = "wrapt-1.14.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:88236b90dda77f0394f878324cfbae05ae6fde8a84d548cfe73a75278d760291"}, {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"},
{file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f0408e2dbad9e82b4c960274214af533f856a199c9274bd4aff55d4634dedc33"}, {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"},
{file = "wrapt-1.14.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9d8c68c4145041b4eeae96239802cfdfd9ef927754a5be3f50505f09f309d8c6"}, {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"},
{file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:22626dca56fd7f55a0733e604f1027277eb0f4f3d95ff28f15d27ac25a45f71b"}, {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"},
{file = "wrapt-1.14.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:65bf3eb34721bf18b5a021a1ad7aa05947a1767d1aa272b725728014475ea7d5"}, {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"},
{file = "wrapt-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09d16ae7a13cff43660155383a2372b4aa09109c7127aa3f24c3cf99b891c330"}, {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"},
{file = "wrapt-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:debaf04f813ada978d7d16c7dfa16f3c9c2ec9adf4656efdc4defdf841fc2f0c"}, {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"},
{file = "wrapt-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748df39ed634851350efa87690c2237a678ed794fe9ede3f0d79f071ee042561"}, {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"},
{file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1807054aa7b61ad8d8103b3b30c9764de2e9d0c0978e9d3fc337e4e74bf25faa"}, {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"},
{file = "wrapt-1.14.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763a73ab377390e2af26042f685a26787c402390f682443727b847e9496e4a2a"}, {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"},
{file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8529b07b49b2d89d6917cfa157d3ea1dfb4d319d51e23030664a827fe5fd2131"}, {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"},
{file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:68aeefac31c1f73949662ba8affaf9950b9938b712fb9d428fa2a07e40ee57f8"}, {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"},
{file = "wrapt-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59d7d92cee84a547d91267f0fea381c363121d70fe90b12cd88241bd9b0e1763"}, {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"},
{file = "wrapt-1.14.0-cp310-cp310-win32.whl", hash = "sha256:3a88254881e8a8c4784ecc9cb2249ff757fd94b911d5df9a5984961b96113fff"}, {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"},
{file = "wrapt-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:9a242871b3d8eecc56d350e5e03ea1854de47b17f040446da0e47dc3e0b9ad4d"}, {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"},
{file = "wrapt-1.14.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a65bffd24409454b889af33b6c49d0d9bcd1a219b972fba975ac935f17bdf627"}, {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"},
{file = "wrapt-1.14.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9d9fcd06c952efa4b6b95f3d788a819b7f33d11bea377be6b8980c95e7d10775"}, {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"},
{file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:db6a0ddc1282ceb9032e41853e659c9b638789be38e5b8ad7498caac00231c23"}, {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"},
{file = "wrapt-1.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:14e7e2c5f5fca67e9a6d5f753d21f138398cad2b1159913ec9e9a67745f09ba3"}, {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"},
{file = "wrapt-1.14.0-cp35-cp35m-win32.whl", hash = "sha256:6d9810d4f697d58fd66039ab959e6d37e63ab377008ef1d63904df25956c7db0"}, {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"},
{file = "wrapt-1.14.0-cp35-cp35m-win_amd64.whl", hash = "sha256:d808a5a5411982a09fef6b49aac62986274ab050e9d3e9817ad65b2791ed1425"}, {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"},
{file = "wrapt-1.14.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b77159d9862374da213f741af0c361720200ab7ad21b9f12556e0eb95912cd48"}, {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"},
{file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36a76a7527df8583112b24adc01748cd51a2d14e905b337a6fefa8b96fc708fb"}, {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"},
{file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0057b5435a65b933cbf5d859cd4956624df37b8bf0917c71756e4b3d9958b9e"}, {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"},
{file = "wrapt-1.14.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0a4ca02752ced5f37498827e49c414d694ad7cf451ee850e3ff160f2bee9d3"}, {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"},
{file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8c6be72eac3c14baa473620e04f74186c5d8f45d80f8f2b4eda6e1d18af808e8"}, {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"},
{file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:21b1106bff6ece8cb203ef45b4f5778d7226c941c83aaaa1e1f0f4f32cc148cd"}, {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"},
{file = "wrapt-1.14.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:493da1f8b1bb8a623c16552fb4a1e164c0200447eb83d3f68b44315ead3f9036"}, {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"},
{file = "wrapt-1.14.0-cp36-cp36m-win32.whl", hash = "sha256:89ba3d548ee1e6291a20f3c7380c92f71e358ce8b9e48161401e087e0bc740f8"}, {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"},
{file = "wrapt-1.14.0-cp36-cp36m-win_amd64.whl", hash = "sha256:729d5e96566f44fccac6c4447ec2332636b4fe273f03da128fff8d5559782b06"}, {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"},
{file = "wrapt-1.14.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:891c353e95bb11abb548ca95c8b98050f3620a7378332eb90d6acdef35b401d4"}, {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"},
{file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23f96134a3aa24cc50614920cc087e22f87439053d886e474638c68c8d15dc80"}, {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"},
{file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6807bcee549a8cb2f38f73f469703a1d8d5d990815c3004f21ddb68a567385ce"}, {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"},
{file = "wrapt-1.14.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6915682f9a9bc4cf2908e83caf5895a685da1fbd20b6d485dafb8e218a338279"}, {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"},
{file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f2f3bc7cd9c9fcd39143f11342eb5963317bd54ecc98e3650ca22704b69d9653"}, {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"},
{file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3a71dbd792cc7a3d772ef8cd08d3048593f13d6f40a11f3427c000cf0a5b36a0"}, {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"},
{file = "wrapt-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5a0898a640559dec00f3614ffb11d97a2666ee9a2a6bad1259c9facd01a1d4d9"}, {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"},
{file = "wrapt-1.14.0-cp37-cp37m-win32.whl", hash = "sha256:167e4793dc987f77fd476862d32fa404d42b71f6a85d3b38cbce711dba5e6b68"}, {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"},
{file = "wrapt-1.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d066ffc5ed0be00cd0352c95800a519cf9e4b5dd34a028d301bdc7177c72daf3"}, {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"},
{file = "wrapt-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d9bdfa74d369256e4218000a629978590fd7cb6cf6893251dad13d051090436d"}, {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"},
{file = "wrapt-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2498762814dd7dd2a1d0248eda2afbc3dd9c11537bc8200a4b21789b6df6cd38"}, {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"},
{file = "wrapt-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f24ca7953f2643d59a9c87d6e272d8adddd4a53bb62b9208f36db408d7aafc7"}, {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"},
{file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b835b86bd5a1bdbe257d610eecab07bf685b1af2a7563093e0e69180c1d4af1"}, {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"},
{file = "wrapt-1.14.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b21650fa6907e523869e0396c5bd591cc326e5c1dd594dcdccac089561cacfb8"}, {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"},
{file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:354d9fc6b1e44750e2a67b4b108841f5f5ea08853453ecbf44c81fdc2e0d50bd"}, {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"},
{file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1f83e9c21cd5275991076b2ba1cd35418af3504667affb4745b48937e214bafe"}, {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"},
{file = "wrapt-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61e1a064906ccba038aa3c4a5a82f6199749efbbb3cef0804ae5c37f550eded0"}, {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"},
{file = "wrapt-1.14.0-cp38-cp38-win32.whl", hash = "sha256:28c659878f684365d53cf59dc9a1929ea2eecd7ac65da762be8b1ba193f7e84f"}, {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"},
{file = "wrapt-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:b0ed6ad6c9640671689c2dbe6244680fe8b897c08fd1fab2228429b66c518e5e"}, {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"},
{file = "wrapt-1.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3f7e671fb19734c872566e57ce7fc235fa953d7c181bb4ef138e17d607dc8a1"}, {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"},
{file = "wrapt-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87fa943e8bbe40c8c1ba4086971a6fefbf75e9991217c55ed1bcb2f1985bd3d4"}, {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"},
{file = "wrapt-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4775a574e9d84e0212f5b18886cace049a42e13e12009bb0491562a48bb2b758"}, {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"},
{file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d57677238a0c5411c76097b8b93bdebb02eb845814c90f0b01727527a179e4d"}, {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"},
{file = "wrapt-1.14.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00108411e0f34c52ce16f81f1d308a571df7784932cc7491d1e94be2ee93374b"}, {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"},
{file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d332eecf307fca852d02b63f35a7872de32d5ba8b4ec32da82f45df986b39ff6"}, {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"},
{file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:01f799def9b96a8ec1ef6b9c1bbaf2bbc859b87545efbecc4a78faea13d0e3a0"}, {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"},
{file = "wrapt-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47045ed35481e857918ae78b54891fac0c1d197f22c95778e66302668309336c"}, {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"},
{file = "wrapt-1.14.0-cp39-cp39-win32.whl", hash = "sha256:2eca15d6b947cfff51ed76b2d60fd172c6ecd418ddab1c5126032d27f74bc350"}, {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"},
{file = "wrapt-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb36fbb48b22985d13a6b496ea5fb9bb2a076fea943831643836c9f6febbcfdc"}, {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"},
{file = "wrapt-1.14.0.tar.gz", hash = "sha256:8323a43bd9c91f62bb7d4be74cc9ff10090e7ef820e27bfe8815c57e68261311"}, {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"},
] ]
yarl = [ yarl = [
{file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"}, {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"},

View file

@ -5,12 +5,8 @@ from _pytest.config import UsageError
from redis.asyncio.connection import parse_url as parse_redis_url from redis.asyncio.connection import parse_url as parse_redis_url
from aiogram import Bot, Dispatcher from aiogram import Bot, Dispatcher
from aiogram.dispatcher.fsm.storage.memory import ( from aiogram.fsm.storage.memory import DisabledEventIsolation, MemoryStorage, SimpleEventIsolation
DisabledEventIsolation, from aiogram.fsm.storage.redis import RedisEventIsolation, RedisStorage
MemoryStorage,
SimpleEventIsolation,
)
from aiogram.dispatcher.fsm.storage.redis import RedisEventIsolation, RedisStorage
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
DATA_DIR = Path(__file__).parent / "data" DATA_DIR = Path(__file__).parent / "data"

View file

@ -5,8 +5,8 @@ import pytest
from aiogram import F from aiogram import F
from aiogram.dispatcher.event.handler import CallableMixin, FilterObject, HandlerObject from aiogram.dispatcher.event.handler import CallableMixin, FilterObject, HandlerObject
from aiogram.dispatcher.filters.base import BaseFilter from aiogram.filters import BaseFilter
from aiogram.dispatcher.handler.base import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import Update from aiogram.types import Update
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -7,9 +7,9 @@ import pytest
from aiogram.dispatcher.event.bases import REJECTED, SkipHandler from aiogram.dispatcher.event.bases import REJECTED, SkipHandler
from aiogram.dispatcher.event.handler import HandlerObject from aiogram.dispatcher.event.handler import HandlerObject
from aiogram.dispatcher.event.telegram import TelegramEventObserver from aiogram.dispatcher.event.telegram import TelegramEventObserver
from aiogram.dispatcher.filters.base import BaseFilter
from aiogram.dispatcher.router import Router from aiogram.dispatcher.router import Router
from aiogram.exceptions import FiltersResolveError from aiogram.exceptions import FiltersResolveError
from aiogram.filters import BaseFilter
from aiogram.types import Chat, Message, User from aiogram.types import Chat, Message, User
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -2,7 +2,7 @@ from typing import Awaitable
import pytest import pytest
from aiogram.dispatcher.filters.base import BaseFilter from aiogram.filters import BaseFilter
try: try:
from asynctest import CoroutineMock, patch from asynctest import CoroutineMock, patch
@ -27,7 +27,7 @@ class TestBaseFilter:
assert isinstance(my_filter, Awaitable) assert isinstance(my_filter, Awaitable)
with patch( with patch(
"tests.test_dispatcher.test_filters.test_base.MyFilter.__call__", "tests.test_filters.test_base.MyFilter.__call__",
new_callable=CoroutineMock, new_callable=CoroutineMock,
) as mocked_call: ) as mocked_call:
call = my_filter(event="test") call = my_filter(event="test")

View file

@ -9,7 +9,7 @@ from magic_filter import MagicFilter
from pydantic import ValidationError from pydantic import ValidationError
from aiogram import F from aiogram import F
from aiogram.dispatcher.filters.callback_data import CallbackData from aiogram.filters.callback_data import CallbackData
from aiogram.types import CallbackQuery, User from aiogram.types import CallbackQuery, User
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -2,7 +2,7 @@ from datetime import datetime
import pytest import pytest
from aiogram.dispatcher.filters.chat_member_updated import ( from aiogram.filters.chat_member_updated import (
ADMINISTRATOR, ADMINISTRATOR,
IS_MEMBER, IS_MEMBER,
JOIN_TRANSITION, JOIN_TRANSITION,

View file

@ -4,8 +4,8 @@ import re
import pytest import pytest
from aiogram import F from aiogram import F
from aiogram.dispatcher.filters import Command, CommandObject from aiogram.filters import Command, CommandObject
from aiogram.dispatcher.filters.command import CommandStart from aiogram.filters.command import CommandStart
from aiogram.types import Chat, Message, User from aiogram.types import Chat, Message, User
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot

View file

@ -4,7 +4,7 @@ from typing import cast
import pytest import pytest
from pydantic import ValidationError from pydantic import ValidationError
from aiogram.dispatcher.filters import ContentTypesFilter from aiogram.filters import ContentTypesFilter
from aiogram.types import ContentType, Message from aiogram.types import ContentType, Message
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -3,7 +3,7 @@ import re
import pytest import pytest
from aiogram import Dispatcher from aiogram import Dispatcher
from aiogram.dispatcher.filters import ExceptionMessageFilter, ExceptionTypeFilter from aiogram.filters import ExceptionMessageFilter, ExceptionTypeFilter
from aiogram.types import Update from aiogram.types import Update
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -1,7 +1,7 @@
import pytest import pytest
from aiogram.dispatcher.filters import Text, and_f, invert_f, or_f from aiogram.filters import Text, and_f, invert_f, or_f
from aiogram.dispatcher.filters.logic import _AndFilter, _InvertFilter, _OrFilter from aiogram.filters.logic import _AndFilter, _InvertFilter, _OrFilter
class TestLogic: class TestLogic:

View file

@ -2,7 +2,7 @@ import pytest
from magic_filter import AttrDict from magic_filter import AttrDict
from aiogram import F from aiogram import F
from aiogram.dispatcher.filters import MagicData from aiogram.filters import MagicData
from aiogram.types import Update from aiogram.types import Update

View file

@ -4,8 +4,8 @@ from inspect import isclass
import pytest import pytest
from aiogram.dispatcher.event.handler import FilterObject from aiogram.dispatcher.event.handler import FilterObject
from aiogram.dispatcher.filters import StateFilter from aiogram.filters import StateFilter
from aiogram.dispatcher.fsm.state import State, StatesGroup from aiogram.fsm.state import State, StatesGroup
from aiogram.types import Update from aiogram.types import Update
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -5,8 +5,7 @@ from typing import Sequence, Type
import pytest import pytest
from pydantic import ValidationError from pydantic import ValidationError
from aiogram.dispatcher.filters import BUILTIN_FILTERS from aiogram.filters import BUILTIN_FILTERS, Text
from aiogram.dispatcher.filters.text import Text
from aiogram.types import CallbackQuery, Chat, InlineQuery, Message, Poll, PollOption, User from aiogram.types import CallbackQuery, Chat, InlineQuery, Message, Poll, PollOption, User
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -1,6 +1,6 @@
import pytest import pytest
from aiogram.dispatcher.flags.flag import Flag, FlagDecorator, FlagGenerator from aiogram.dispatcher.flags import Flag, FlagDecorator, FlagGenerator
@pytest.fixture(name="flag") @pytest.fixture(name="flag")

View file

@ -4,7 +4,7 @@ import pytest
from aiogram import F from aiogram import F
from aiogram.dispatcher.event.handler import HandlerObject from aiogram.dispatcher.event.handler import HandlerObject
from aiogram.dispatcher.flags.getter import ( from aiogram.dispatcher.flags import (
check_flags, check_flags,
extract_flags, extract_flags,
extract_flags_from_object, extract_flags_from_object,
@ -60,5 +60,5 @@ class TestGetters:
], ],
) )
def test_check_flag(self, flags, magic, result): def test_check_flag(self, flags, magic, result):
with patch("aiogram.dispatcher.flags.getter.extract_flags", return_value=flags): with patch("aiogram.dispatcher.flags.extract_flags", return_value=flags):
assert check_flags(object(), magic) == result assert check_flags(object(), magic) == result

View file

@ -1,6 +1,6 @@
import pytest import pytest
from aiogram.dispatcher.fsm.storage.base import BaseEventIsolation, StorageKey from aiogram.fsm.storage.base import BaseEventIsolation, StorageKey
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -1,11 +1,7 @@
import pytest import pytest
from aiogram.dispatcher.fsm.storage.base import DEFAULT_DESTINY, StorageKey from aiogram.fsm.storage.base import DEFAULT_DESTINY, StorageKey
from aiogram.dispatcher.fsm.storage.redis import ( from aiogram.fsm.storage.redis import DefaultKeyBuilder, RedisEventIsolation, RedisStorage
DefaultKeyBuilder,
RedisEventIsolation,
RedisStorage,
)
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -1,6 +1,6 @@
import pytest import pytest
from aiogram.dispatcher.fsm.storage.base import BaseStorage, StorageKey from aiogram.fsm.storage.base import BaseStorage, StorageKey
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -1,8 +1,8 @@
import pytest import pytest
from aiogram.dispatcher.fsm.context import FSMContext from aiogram.fsm.context import FSMContext
from aiogram.dispatcher.fsm.storage.base import StorageKey from aiogram.fsm.storage.base import StorageKey
from aiogram.dispatcher.fsm.storage.memory import MemoryStorage from aiogram.fsm.storage.memory import MemoryStorage
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -1,6 +1,6 @@
import pytest import pytest
from aiogram.dispatcher.fsm.state import State, StatesGroup, any_state from aiogram.fsm.state import State, StatesGroup, any_state
class TestState: class TestState:

View file

@ -1,6 +1,6 @@
import pytest import pytest
from aiogram.dispatcher.fsm.strategy import FSMStrategy, apply_strategy from aiogram.fsm.strategy import FSMStrategy, apply_strategy
class TestStrategy: class TestStrategy:

View file

@ -7,7 +7,7 @@ import pytest
from aiogram import Bot from aiogram import Bot
from aiogram.dispatcher.event.handler import HandlerObject from aiogram.dispatcher.event.handler import HandlerObject
from aiogram.dispatcher.handler.base import BaseHandler from aiogram.handlers import BaseHandler
from aiogram.types import Chat, Message, Update from aiogram.types import Chat, Message, Update
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -2,7 +2,7 @@ from typing import Any
import pytest import pytest
from aiogram.dispatcher.handler import CallbackQueryHandler from aiogram.handlers import CallbackQueryHandler
from aiogram.types import CallbackQuery, User from aiogram.types import CallbackQuery, User
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -3,7 +3,7 @@ from typing import Any
import pytest import pytest
from aiogram.dispatcher.handler.chat_member import ChatMemberHandler from aiogram.handlers import ChatMemberHandler
from aiogram.types import Chat, ChatMemberMember, ChatMemberUpdated, User from aiogram.types import Chat, ChatMemberMember, ChatMemberUpdated, User
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

View file

@ -2,7 +2,7 @@ from typing import Any
import pytest import pytest
from aiogram.dispatcher.handler import ChosenInlineResultHandler from aiogram.handlers import ChosenInlineResultHandler
from aiogram.types import ChosenInlineResult, User from aiogram.types import ChosenInlineResult, User
pytestmark = pytest.mark.asyncio pytestmark = pytest.mark.asyncio

Some files were not shown because too many files have changed in this diff Show more