Merge remote-tracking branch 'origin/dev-3.x' into dev-3.x

This commit is contained in:
jrootjunior 2020-01-22 12:38:38 +02:00
commit cfd869b797
27 changed files with 602 additions and 111 deletions

View file

@ -10,10 +10,14 @@ on:
jobs:
build:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
max-parallel: 4
max-parallel: 6
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
python-version:
- 3.7
- 3.8
@ -21,7 +25,7 @@ jobs:
steps:
- uses: actions/checkout@master
- name: Set up Python ${{ matrix.python-version }}
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
@ -30,13 +34,12 @@ jobs:
run: |
python -m pip install --upgrade pip poetry==1.0
poetry install
mkdir -p reports
- name: Lint code
run: |
make flake8
make mypy
poetry run flake8 aiogram test
poetry run mypy aiogram tests
- name: Run tests
run: |
make test-coverage
poetry run pytest

View file

@ -1,4 +1,21 @@
from .base import BaseHandler, BaseHandlerMixin
from .callback_query import CallbackQueryHandler
from .chosen_inline_result import ChosenInlineResultHandler
from .inline_query import InlineQueryHandler
from .message import MessageHandler, MessageHandlerCommandMixin
from .poll import PollHandler
from .pre_checkout_query import PreCheckoutQueryHandler
from .shipping_query import ShippingQueryHandler
__all__ = ("BaseHandler", "BaseHandlerMixin", "MessageHandler", "MessageHandlerCommandMixin")
__all__ = (
"BaseHandler",
"BaseHandlerMixin",
"CallbackQueryHandler",
"ChosenInlineResultHandler",
"InlineQueryHandler",
"MessageHandler",
"MessageHandlerCommandMixin",
"PollHandler",
"PreCheckoutQueryHandler",
"ShippingQueryHandler",
)

View file

@ -1,23 +1,25 @@
from abc import ABC, abstractmethod
from typing import Any, Dict
from typing import TYPE_CHECKING, Any, Dict, Generic, TypeVar
from aiogram import Bot
from aiogram.api.types import TelegramObject
T = TypeVar("T")
class BaseHandlerMixin:
class BaseHandlerMixin(Generic[T]):
if TYPE_CHECKING: # pragma: no cover
event: T
data: Dict[str, Any]
class BaseHandler(BaseHandlerMixin[T], ABC):
"""
Typed mixin. Do nothing.
Base class for all class-based handlers
"""
event: TelegramObject
data: Dict[str, Any]
class _HandlerBotMixin(BaseHandlerMixin):
"""
Mixin adds bot attribute
"""
def __init__(self, event: T, **kwargs: Any) -> None:
self.event: T = event
self.data: Dict[str, Any] = kwargs
@property
def bot(self) -> Bot:
@ -25,16 +27,6 @@ class _HandlerBotMixin(BaseHandlerMixin):
return self.data["bot"]
return Bot.get_current()
class BaseHandler(_HandlerBotMixin, ABC):
"""
Base class for all class-based handlers
"""
def __init__(self, event: TelegramObject, **kwargs: Any) -> None:
self.event = event
self.data = kwargs
@abstractmethod
async def handle(self) -> Any: # pragma: no cover
pass

View file

@ -0,0 +1,23 @@
from abc import ABC
from typing import Optional
from aiogram.api.types import CallbackQuery, Message, User
from aiogram.dispatcher.handler import BaseHandler
class CallbackQueryHandler(BaseHandler[CallbackQuery], ABC):
"""
Base class for callback query handlers
"""
@property
def from_user(self) -> User:
return self.event.from_user
@property
def message(self) -> Optional[Message]:
return self.event.message
@property
def callback_data(self) -> Optional[str]:
return self.event.data

View file

@ -0,0 +1,18 @@
from abc import ABC
from aiogram.api.types import ChosenInlineResult, User
from aiogram.dispatcher.handler import BaseHandler
class ChosenInlineResultHandler(BaseHandler[ChosenInlineResult], ABC):
"""
Base class for chosen inline result handlers
"""
@property
def from_user(self) -> User:
return self.event.from_user
@property
def query(self) -> str:
return self.event.query

View file

@ -0,0 +1,18 @@
from abc import ABC
from aiogram.api.types import InlineQuery, User
from aiogram.dispatcher.handler import BaseHandler
class InlineQueryHandler(BaseHandler[InlineQuery], ABC):
"""
Base class for inline query handlers
"""
@property
def from_user(self) -> User:
return self.event.from_user
@property
def query(self) -> str:
return self.event.query

View file

@ -6,8 +6,10 @@ from aiogram.dispatcher.filters import CommandObject
from aiogram.dispatcher.handler.base import BaseHandler, BaseHandlerMixin
class MessageHandler(BaseHandler, ABC):
event: Message
class MessageHandler(BaseHandler[Message], ABC):
"""
Base class for message handlers
"""
@property
def from_user(self) -> Optional[User]:
@ -18,7 +20,7 @@ class MessageHandler(BaseHandler, ABC):
return self.event.chat
class MessageHandlerCommandMixin(BaseHandlerMixin):
class MessageHandlerCommandMixin(BaseHandlerMixin[Message]):
@property
def command(self) -> Optional[CommandObject]:
if "command" in self.data:

View file

@ -0,0 +1,19 @@
from abc import ABC
from typing import List
from aiogram.api.types import Poll, PollOption
from aiogram.dispatcher.handler import BaseHandler
class PollHandler(BaseHandler[Poll], ABC):
"""
Base class for poll handlers
"""
@property
def question(self) -> str:
return self.event.question
@property
def options(self) -> List[PollOption]:
return self.event.options

View file

@ -0,0 +1,14 @@
from abc import ABC
from aiogram.api.types import PreCheckoutQuery, User
from aiogram.dispatcher.handler import BaseHandler
class PreCheckoutQueryHandler(BaseHandler[PreCheckoutQuery], ABC):
"""
Base class for pre-checkout handlers
"""
@property
def from_user(self) -> User:
return self.event.from_user

View file

@ -0,0 +1,14 @@
from abc import ABC
from aiogram.api.types import ShippingQuery, User
from aiogram.dispatcher.handler import BaseHandler
class ShippingQueryHandler(BaseHandler[ShippingQuery], ABC):
"""
Base class for shipping query handlers
"""
@property
def from_user(self) -> User:
return self.event.from_user

View file

@ -7,11 +7,16 @@ There are some base class based handlers what you need to use in your own handle
- [BaseHandler](#basehandler)
- [MessageHandler](message.md)
- [CallbackQueryHandler](callback_query.md)
- [ChosenInlineResultHandler](chosen_inline_result.md)
- [InlineQueryHandler](inline_query.md)
- [PollHandler](poll.md)
- [PreCheckoutQueryHandler](pre_checkout_query.md)
- [ShippingQueryHandler](shipping_query.md)
## BaseHandler
Base handler is abstract class and should be used in all other class-based handlers.
Base handler is generic abstract class and should be used in all other class-based handlers.
Import: `#!python3 from aiogram.hanler import BaseHandler`
@ -21,3 +26,11 @@ This class is also have an default initializer and you don't need to change it.
Initializer accepts current event and all contextual data and which can be accessed from the handler through attributes: `event: TelegramEvent` and `data: Dict[Any, str]`
If instance of the bot is specified in context data or current context it can be accessed through `bot` class attribute.
### For example:
```python3
class MyHandler(BaseHandler[Message]):
async def handle(self) -> Any:
await self.event.answer("Hello!")
```

View file

@ -0,0 +1,29 @@
# CallbackQueryHandler
There is base class for callback query handlers.
## Simple usage:
```pyhton3
from aiogram.handlers import CallbackQueryHandler
...
@router.callback_query_handler()
class MyHandler(CallbackQueryHandler):
async def handle(self) -> Any: ...
```
## Extension
This base handler is subclass of [BaseHandler](basics.md#basehandler) with some extensions:
- `self.from_user` is alias for `self.event.from_user`
- `self.message` is alias for `self.event.message`
- `self.callback_data` is alias for `self.event.data`
## Related pages
- [BaseHandler](basics.md#basehandler)
- [CallbackQuery](../../api/types/callback_query.md)
- [Router.callback_query_handler](../router.md#callback-query)

View file

@ -0,0 +1,28 @@
# ChosenInlineResultHandler
There is base class for chosen inline result handlers.
## Simple usage:
```pyhton3
from aiogram.handlers import ChosenInlineResultHandler
...
@router.chosen_inline_result_handler()
class MyHandler(ChosenInlineResultHandler):
async def handle(self) -> Any: ...
```
## Extension
This base handler is subclass of [BaseHandler](basics.md#basehandler) with some extensions:
- `self.chat` is alias for `self.event.chat`
- `self.from_user` is alias for `self.event.from_user`
## Related pages
- [BaseHandler](basics.md#basehandler)
- [ChosenInlineResult](../../api/types/chosen_inline_result.md)
- [Router.chosen_inline_result_handler](../router.md#chosen-inline-query)

View file

@ -0,0 +1,27 @@
# InlineQueryHandler
There is base class for inline query handlers.
## Simple usage:
```pyhton3
from aiogram.handlers import InlineQueryHandler
...
@router.inline_query_handler()
class MyHandler(InlineQueryHandler):
async def handle(self) -> Any: ...
```
## Extension
This base handler is subclass of [BaseHandler](basics.md#basehandler) with some extensions:
- `self.chat` is alias for `self.event.chat`
- `self.query` is alias for `self.event.query`
## Related pages
- [BaseHandler](basics.md#basehandler)
- [InlineQuery](../../api/types/inline_query.md)
- [Router.inline_query_handler](../router.md#inline-query)

View file

@ -9,8 +9,8 @@ from aiogram.handlers import MessageHandler
...
@router.message_handler()
class MyTestMessageHandler(MessageHandler):
async def handle() -> Any:
class MyHandler(MessageHandler):
async def handle(self) -> Any:
return SendMessage(chat_id=self.chat.id, text="PASS")
```
@ -21,3 +21,12 @@ This base handler is subclass of [BaseHandler](basics.md#basehandler) with some
- `self.chat` is alias for `self.event.chat`
- `self.from_user` is alias for `self.event.from_user`
## Related pages
- [BaseHandler](basics.md#basehandler)
- [Message](../../api/types/message.md)
- [Router.message_handler](../router.md#message)
- [Router.edited_message_handler](../router.md#edited-message)
- [Router.channel_post_handler](../router.md#channel-post)
- [Router.edited_channel_post_handler](../router.md#edited-channel-post)

View file

@ -0,0 +1,28 @@
# PollHandler
There is base class for poll handlers.
## Simple usage:
```pyhton3
from aiogram.handlers import PollHandler
...
@router.poll_handler()
class MyHandler(PollHandler):
async def handle(self) -> Any: ...
```
## Extension
This base handler is subclass of [BaseHandler](basics.md#basehandler) with some extensions:
- `self.question` is alias for `self.event.question`
- `self.options` is alias for `self.event.options`
## Related pages
- [BaseHandler](basics.md#basehandler)
- [Poll](../../api/types/poll.md)
- [Router.poll_handler](../router.md#poll)

View file

@ -0,0 +1,27 @@
# PreCheckoutQueryHandler
There is base class for callback query handlers.
## Simple usage:
```pyhton3
from aiogram.handlers import PreCheckoutQueryHandler
...
@router.pre_checkout_query_handler()
class MyHandler(PreCheckoutQueryHandler):
async def handle(self) -> Any: ...
```
## Extension
This base handler is subclass of [BaseHandler](basics.md#basehandler) with some extensions:
- `self.from_user` is alias for `self.event.from_user`
## Related pages
- [BaseHandler](basics.md#basehandler)
- [PreCheckoutQuery](../../api/types/pre_checkout_query.md)
- [Router.pre_checkout_query_handler](../router.md#pre-checkout-query)

View file

@ -0,0 +1,27 @@
# ShippingQueryHandler
There is base class for callback query handlers.
## Simple usage:
```pyhton3
from aiogram.handlers import ShippingQueryHandler
...
@router.shipping_query_handler()
class MyHandler(ShippingQueryHandler):
async def handle(self) -> Any: ...
```
## Extension
This base handler is subclass of [BaseHandler](basics.md#basehandler) with some extensions:
- `self.from_user` is alias for `self.event.from_user`
## Related pages
- [BaseHandler](basics.md#basehandler)
- [ShippingQuery](../../api/types/shipping_query.md)
- [Router.shipping_query_handler](../router.md#shipping-query)

View file

@ -231,6 +231,12 @@ nav:
- Class based handlers:
- dispatcher/class_based_handlers/basics.md
- dispatcher/class_based_handlers/message.md
- dispatcher/class_based_handlers/callback_query.md
- dispatcher/class_based_handlers/chosen_inline_result.md
- dispatcher/class_based_handlers/inline_query.md
- dispatcher/class_based_handlers/poll.md
- dispatcher/class_based_handlers/pre_checkout_query.md
- dispatcher/class_based_handlers/shipping_query.md
- Build reports:
- reports.md
- Tests result: /reports/tests

139
poetry.lock generated
View file

@ -168,7 +168,7 @@ description = "Code coverage measurement for Python"
name = "coverage"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
version = "5.0.2"
version = "5.0.3"
[package.extras]
toml = ["toml"]
@ -524,7 +524,7 @@ marker = "sys_platform != \"win32\""
name = "pexpect"
optional = false
python-versions = "*"
version = "4.7.0"
version = "4.8.0"
[package.dependencies]
ptyprocess = ">=0.5"
@ -643,7 +643,7 @@ description = "pytest: simple powerful testing with Python"
name = "pytest"
optional = false
python-versions = ">=3.5"
version = "5.3.2"
version = "5.3.4"
[package.dependencies]
atomicwrites = ">=1.0"
@ -660,6 +660,7 @@ python = "<3.8"
version = ">=0.12"
[package.extras]
checkqa-mypy = ["mypy (v0.761)"]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[[package]]
@ -770,8 +771,8 @@ category = "dev"
description = "Python 2 and 3 compatibility utilities"
name = "six"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
version = "1.13.0"
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
version = "1.14.0"
[[package]]
category = "dev"
@ -811,7 +812,7 @@ description = "a fork of Python 2 and 3 ast modules with type comment support"
name = "typed-ast"
optional = false
python-versions = "*"
version = "1.4.0"
version = "1.4.1"
[[package]]
category = "dev"
@ -824,6 +825,7 @@ version = "3.7.4.1"
[[package]]
category = "main"
description = "Fast implementation of asyncio event loop on top of libuv"
marker = "sys_platform == \"darwin\" or sys_platform == \"linux\""
name = "uvloop"
optional = false
python-versions = "*"
@ -855,8 +857,8 @@ description = "Backport of pathlib-compatible object wrapper for zip files"
marker = "python_version >= \"3.5\" and python_version < \"3.8\" or python_version < \"3.8\""
name = "zipp"
optional = false
python-versions = ">=2.7"
version = "0.6.0"
python-versions = ">=3.6"
version = "2.0.0"
[package.dependencies]
more-itertools = "*"
@ -869,7 +871,7 @@ testing = ["pathlib2", "contextlib2", "unittest2"]
fast = ["uvloop"]
[metadata]
content-hash = "ab163ac1d239335c7e8d9cb1e9c02e878b17609ab3639fe3c2ad37c3fec5b462"
content-hash = "1789ff58bda6bf1d7166ba30607efae8c3bab2455ab165bba88bfdc77d5bedc7"
python-versions = "^3.7"
[metadata.files]
@ -947,37 +949,37 @@ colorama = [
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
]
coverage = [
{file = "coverage-5.0.2-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:511ec0c00840e12fb4e852e4db58fa6a01ca4da72f36a9766fae344c3d502033"},
{file = "coverage-5.0.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:d22b4297e7e4225ccf01f1aa55e7a96412ea0796b532dd614c3fcbafa341128e"},
{file = "coverage-5.0.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:593853aa1ac6dcc6405324d877544c596c9d948ef20d2e9512a0f5d2d3202356"},
{file = "coverage-5.0.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:e65a5aa1670db6263f19fdc03daee1d7dbbadb5cb67fd0a1f16033659db13c1d"},
{file = "coverage-5.0.2-cp27-cp27m-win32.whl", hash = "sha256:d4a2b578a7a70e0c71f662705262f87a456f1e6c1e40ada7ea699abaf070a76d"},
{file = "coverage-5.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:28f7f73b34a05e23758e860a89a7f649b85c6749e252eff60ebb05532d180e86"},
{file = "coverage-5.0.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7d1cc7acc9ce55179616cf72154f9e648136ea55987edf84addbcd9886ffeba2"},
{file = "coverage-5.0.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:2d0cb9b1fe6ad0d915d45ad3d87f03a38e979093a98597e755930db1f897afae"},
{file = "coverage-5.0.2-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:bfe102659e2ec13b86c7f3b1db6c9a4e7beea4255058d006351339e6b342d5d2"},
{file = "coverage-5.0.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:23688ff75adfa8bfa2a67254d889f9bdf9302c27241d746e17547c42c732d3f4"},
{file = "coverage-5.0.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1bf7ba2af1d373a1750888724f84cffdfc697738f29a353c98195f98fc011509"},
{file = "coverage-5.0.2-cp35-cp35m-win32.whl", hash = "sha256:569f9ee3025682afda6e9b0f5bb14897c0db03f1a1dc088b083dd36e743f92bb"},
{file = "coverage-5.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:cf908840896f7aa62d0ec693beb53264b154f972eb8226fb864ac38975590c4f"},
{file = "coverage-5.0.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:eaad65bd20955131bcdb3967a4dea66b4e4d4ca488efed7c00d91ee0173387e8"},
{file = "coverage-5.0.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:225e79a5d485bc1642cb7ba02281419c633c216cdc6b26c26494ba959f09e69f"},
{file = "coverage-5.0.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bd82b684bb498c60ef47bb1541a50e6d006dde8579934dcbdbc61d67d1ea70d9"},
{file = "coverage-5.0.2-cp36-cp36m-win32.whl", hash = "sha256:7ca3db38a61f3655a2613ee2c190d63639215a7a736d3c64cc7bbdb002ce6310"},
{file = "coverage-5.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:47874b4711c5aeb295c31b228a758ce3d096be83dc37bd56da48ed99efb8813b"},
{file = "coverage-5.0.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:955ec084f549128fa2702f0b2dc696392001d986b71acd8fd47424f28289a9c3"},
{file = "coverage-5.0.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1f4ee8e2e4243971618bc16fcc4478317405205f135e95226c2496e2a3b8dbbf"},
{file = "coverage-5.0.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f45fba420b94165c17896861bb0e8b27fb7abdcedfeb154895d8553df90b7b00"},
{file = "coverage-5.0.2-cp37-cp37m-win32.whl", hash = "sha256:cca38ded59105f7705ef6ffe1e960b8db6c7d8279c1e71654a4775ab4454ca15"},
{file = "coverage-5.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:cb2b74c123f65e8166f7e1265829a6c8ed755c3cd16d7f50e75a83456a5f3fd7"},
{file = "coverage-5.0.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:53e7438fef0c97bc248f88ba1edd10268cd94d5609970aaf87abbe493691af87"},
{file = "coverage-5.0.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1e4e39e43057396a5e9d069bfbb6ffeee892e40c5d2effbd8cd71f34ee66c4d"},
{file = "coverage-5.0.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b0a07158360d22492f9abd02a0f2ee7981b33f0646bf796598b7673f6bbab14"},
{file = "coverage-5.0.2-cp38-cp38m-win32.whl", hash = "sha256:88b51153657612aea68fa684a5b88037597925260392b7bb4509d4f9b0bdd889"},
{file = "coverage-5.0.2-cp38-cp38m-win_amd64.whl", hash = "sha256:189aac76d6e0d7af15572c51892e7326ee451c076c5a50a9d266406cd6c49708"},
{file = "coverage-5.0.2-cp39-cp39m-win32.whl", hash = "sha256:d095a7b473f8a95f7efe821f92058c8a2ecfb18f8db6677ae3819e15dc11aaae"},
{file = "coverage-5.0.2-cp39-cp39m-win_amd64.whl", hash = "sha256:ddeb42a3d5419434742bf4cc71c9eaa22df3b76808e23a82bd0b0bd360f1a9f1"},
{file = "coverage-5.0.2.tar.gz", hash = "sha256:b251c7092cbb6d789d62dc9c9e7c4fb448c9138b51285c36aeb72462cad3600e"},
{file = "coverage-5.0.3-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:cc1109f54a14d940b8512ee9f1c3975c181bbb200306c6d8b87d93376538782f"},
{file = "coverage-5.0.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:be18f4ae5a9e46edae3f329de2191747966a34a3d93046dbdf897319923923bc"},
{file = "coverage-5.0.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3230d1003eec018ad4a472d254991e34241e0bbd513e97a29727c7c2f637bd2a"},
{file = "coverage-5.0.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:e69215621707119c6baf99bda014a45b999d37602cb7043d943c76a59b05bf52"},
{file = "coverage-5.0.3-cp27-cp27m-win32.whl", hash = "sha256:1daa3eceed220f9fdb80d5ff950dd95112cd27f70d004c7918ca6dfc6c47054c"},
{file = "coverage-5.0.3-cp27-cp27m-win_amd64.whl", hash = "sha256:51bc7710b13a2ae0c726f69756cf7ffd4362f4ac36546e243136187cfcc8aa73"},
{file = "coverage-5.0.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:9bea19ac2f08672636350f203db89382121c9c2ade85d945953ef3c8cf9d2a68"},
{file = "coverage-5.0.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:5012d3b8d5a500834783689a5d2292fe06ec75dc86ee1ccdad04b6f5bf231691"},
{file = "coverage-5.0.3-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:d513cc3db248e566e07a0da99c230aca3556d9b09ed02f420664e2da97eac301"},
{file = "coverage-5.0.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3dbb72eaeea5763676a1a1efd9b427a048c97c39ed92e13336e726117d0b72bf"},
{file = "coverage-5.0.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:15cf13a6896048d6d947bf7d222f36e4809ab926894beb748fc9caa14605d9c3"},
{file = "coverage-5.0.3-cp35-cp35m-win32.whl", hash = "sha256:fca1669d464f0c9831fd10be2eef6b86f5ebd76c724d1e0706ebdff86bb4adf0"},
{file = "coverage-5.0.3-cp35-cp35m-win_amd64.whl", hash = "sha256:1e44a022500d944d42f94df76727ba3fc0a5c0b672c358b61067abb88caee7a0"},
{file = "coverage-5.0.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:b26aaf69713e5674efbde4d728fb7124e429c9466aeaf5f4a7e9e699b12c9fe2"},
{file = "coverage-5.0.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:722e4557c8039aad9592c6a4213db75da08c2cd9945320220634f637251c3894"},
{file = "coverage-5.0.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:7afad9835e7a651d3551eab18cbc0fdb888f0a6136169fbef0662d9cdc9987cf"},
{file = "coverage-5.0.3-cp36-cp36m-win32.whl", hash = "sha256:25dbf1110d70bab68a74b4b9d74f30e99b177cde3388e07cc7272f2168bd1477"},
{file = "coverage-5.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:c312e57847db2526bc92b9bfa78266bfbaabac3fdcd751df4d062cd4c23e46dc"},
{file = "coverage-5.0.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a8b8ac7876bc3598e43e2603f772d2353d9931709345ad6c1149009fd1bc81b8"},
{file = "coverage-5.0.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:527b4f316e6bf7755082a783726da20671a0cc388b786a64417780b90565b987"},
{file = "coverage-5.0.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d649dc0bcace6fcdb446ae02b98798a856593b19b637c1b9af8edadf2b150bea"},
{file = "coverage-5.0.3-cp37-cp37m-win32.whl", hash = "sha256:cd60f507c125ac0ad83f05803063bed27e50fa903b9c2cfee3f8a6867ca600fc"},
{file = "coverage-5.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c60097190fe9dc2b329a0eb03393e2e0829156a589bd732e70794c0dd804258e"},
{file = "coverage-5.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:d7008a6796095a79544f4da1ee49418901961c97ca9e9d44904205ff7d6aa8cb"},
{file = "coverage-5.0.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ea9525e0fef2de9208250d6c5aeeee0138921057cd67fcef90fbed49c4d62d37"},
{file = "coverage-5.0.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c62a2143e1313944bf4a5ab34fd3b4be15367a02e9478b0ce800cb510e3bbb9d"},
{file = "coverage-5.0.3-cp38-cp38m-win32.whl", hash = "sha256:b0840b45187699affd4c6588286d429cd79a99d509fe3de0f209594669bb0954"},
{file = "coverage-5.0.3-cp38-cp38m-win_amd64.whl", hash = "sha256:76e2057e8ffba5472fd28a3a010431fd9e928885ff480cb278877c6e9943cc2e"},
{file = "coverage-5.0.3-cp39-cp39m-win32.whl", hash = "sha256:b63dd43f455ba878e5e9f80ba4f748c0a2156dde6e0e6e690310e24d6e8caf40"},
{file = "coverage-5.0.3-cp39-cp39m-win_amd64.whl", hash = "sha256:da93027835164b8223e8e5af2cf902a4c80ed93cb0909417234f4a9df3bcd9af"},
{file = "coverage-5.0.3.tar.gz", hash = "sha256:77afca04240c40450c331fa796b3eab6f1e15c5ecf8bf2b8bee9706cd5452fef"},
]
decorator = [
{file = "decorator-4.4.1-py2.py3-none-any.whl", hash = "sha256:5d19b92a3c8f7f101c8dd86afd86b0f061a8ce4540ab8cd401fa2542756bce6d"},
@ -1170,8 +1172,8 @@ pep562 = [
{file = "pep562-1.0.tar.gz", hash = "sha256:58cb1cc9ee63d93e62b4905a50357618d526d289919814bea1f0da8f53b79395"},
]
pexpect = [
{file = "pexpect-4.7.0-py2.py3-none-any.whl", hash = "sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1"},
{file = "pexpect-4.7.0.tar.gz", hash = "sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb"},
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
{file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
]
pickleshare = [
{file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
@ -1230,8 +1232,8 @@ pyparsing = [
{file = "pyparsing-2.4.6.tar.gz", hash = "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f"},
]
pytest = [
{file = "pytest-5.3.2-py3-none-any.whl", hash = "sha256:e41d489ff43948babd0fad7ad5e49b8735d5d55e26628a58673c39ff61d95de4"},
{file = "pytest-5.3.2.tar.gz", hash = "sha256:6b571215b5a790f9b41f19f3531c53a45cf6bb8ef2988bc1ff9afb38270b25fa"},
{file = "pytest-5.3.4-py3-none-any.whl", hash = "sha256:c13d1943c63e599b98cf118fcb9703e4d7bde7caa9a432567bcdcae4bf512d20"},
{file = "pytest-5.3.4.tar.gz", hash = "sha256:1d122e8be54d1a709e56f82e2d85dcba3018313d64647f38a91aec88c239b600"},
]
pytest-asyncio = [
{file = "pytest-asyncio-0.10.0.tar.gz", hash = "sha256:9fac5100fd716cbecf6ef89233e8590a4ad61d729d1732e0a96b84182df1daaf"},
@ -1275,8 +1277,8 @@ pyyaml = [
{file = "PyYAML-5.3.tar.gz", hash = "sha256:e9f45bd5b92c7974e59bcd2dcc8631a6b6cc380a904725fce7bc08872e691615"},
]
six = [
{file = "six-1.13.0-py2.py3-none-any.whl", hash = "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd"},
{file = "six-1.13.0.tar.gz", hash = "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"},
{file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"},
{file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"},
]
toml = [
{file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"},
@ -1297,26 +1299,27 @@ traitlets = [
{file = "traitlets-4.3.3.tar.gz", hash = "sha256:d023ee369ddd2763310e4c3eae1ff649689440d4ae59d7485eb4cfbbe3e359f7"},
]
typed-ast = [
{file = "typed_ast-1.4.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e"},
{file = "typed_ast-1.4.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b"},
{file = "typed_ast-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4"},
{file = "typed_ast-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"},
{file = "typed_ast-1.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631"},
{file = "typed_ast-1.4.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233"},
{file = "typed_ast-1.4.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1"},
{file = "typed_ast-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a"},
{file = "typed_ast-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c"},
{file = "typed_ast-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a"},
{file = "typed_ast-1.4.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e"},
{file = "typed_ast-1.4.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d"},
{file = "typed_ast-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36"},
{file = "typed_ast-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0"},
{file = "typed_ast-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66"},
{file = "typed_ast-1.4.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2"},
{file = "typed_ast-1.4.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47"},
{file = "typed_ast-1.4.0-cp38-cp38-win32.whl", hash = "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161"},
{file = "typed_ast-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e"},
{file = "typed_ast-1.4.0.tar.gz", hash = "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34"},
{file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"},
{file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"},
{file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"},
{file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"},
{file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"},
{file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"},
{file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"},
{file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"},
{file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"},
{file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"},
{file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"},
{file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"},
{file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"},
{file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"},
{file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"},
{file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"},
{file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"},
{file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"},
{file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"},
{file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"},
{file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"},
]
typing-extensions = [
{file = "typing_extensions-3.7.4.1-py2-none-any.whl", hash = "sha256:910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d"},
@ -1358,6 +1361,6 @@ yarl = [
{file = "yarl-1.4.2.tar.gz", hash = "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b"},
]
zipp = [
{file = "zipp-0.6.0-py2.py3-none-any.whl", hash = "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"},
{file = "zipp-0.6.0.tar.gz", hash = "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e"},
{file = "zipp-2.0.0-py3-none-any.whl", hash = "sha256:57147f6b0403b59f33fd357f169f860e031303415aeb7d04ede4839d23905ab8"},
{file = "zipp-2.0.0.tar.gz", hash = "sha256:7ae5ccaca427bafa9760ac3cd8f8c244bfc259794b5b6bb9db4dda2241575d09"},
]

View file

@ -1,14 +1,21 @@
[tool.poetry]
name = "aiogram"
version = "3.0.0-alpha.1"
description = "modern and fully asynchronous framework for Telegram Bot API"
description = "Modern and fully asynchronous framework for Telegram Bot API"
authors = ["Alex Root Junior <jroot.junior@gmail.com>"]
license = "MIT"
readme = "README.md"
homepage = "https://aiogram.2038.io/"
documentation = "https://aiogram.2038.io/"
homepage = "https://aiogram.dev/"
documentation = "https://docs.aiogram.dev/"
repository = "https://github.com/aiogram/aiogram/"
keywords = []
keywords = [
"telegram",
"bot",
"api",
"framework",
"wrapper",
"asyncio",
]
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
@ -19,6 +26,8 @@ classifiers = [
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: Software Development :: Libraries :: Application Frameworks",
"Framework :: AsyncIO",
"Typing :: Typed",
]
[tool.poetry.dependencies]
@ -27,11 +36,11 @@ aiohttp = "^3.6"
pydantic = "^1.2"
Babel = "^2.7"
aiofiles = "^0.4.0"
uvloop = {version = "^0.14.0", optional = true}
uvloop = {version = "^0.14.0", markers = "sys_platform == 'darwin' or sys_platform == 'linux'", optional = true}
async_lru = "^1.0"
[tool.poetry.dev-dependencies]
uvloop = "^0.14.0"
uvloop = {version = "^0.14.0", markers = "sys_platform == 'darwin' or sys_platform == 'linux'"}
pytest = "^5.3"
pytest-html = "^2.0"
pytest-asyncio = "^0.10.0"

View file

@ -0,0 +1,26 @@
from typing import Any
import pytest
from aiogram.api.types import CallbackQuery, User
from aiogram.dispatcher.handler import CallbackQueryHandler
class TestCallbackQueryHandler:
@pytest.mark.asyncio
async def test_attributes_aliases(self):
event = CallbackQuery(
id="chosen",
from_user=User(id=42, is_bot=False, first_name="Test"),
data="test",
chat_instance="test",
)
class MyHandler(CallbackQueryHandler):
async def handle(self) -> Any:
assert self.event == event
assert self.from_user == self.event.from_user
assert self.callback_data == self.event.data
assert self.message == self.message
return True
assert await MyHandler(event)

View file

@ -0,0 +1,24 @@
from typing import Any
import pytest
from aiogram.api.types import CallbackQuery, ChosenInlineResult, User
from aiogram.dispatcher.handler import ChosenInlineResultHandler
class TestChosenInlineResultHandler:
@pytest.mark.asyncio
async def test_attributes_aliases(self):
event = ChosenInlineResult(
result_id="chosen",
from_user=User(id=42, is_bot=False, first_name="Test"),
query="test",
)
class MyHandler(ChosenInlineResultHandler):
async def handle(self) -> Any:
assert self.event == event
assert self.from_user == self.event.from_user
assert self.query == self.event.query
return True
assert await MyHandler(event)

View file

@ -0,0 +1,25 @@
from typing import Any
import pytest
from aiogram.api.types import CallbackQuery, InlineQuery, User
from aiogram.dispatcher.handler import InlineQueryHandler
class TestCallbackQueryHandler:
@pytest.mark.asyncio
async def test_attributes_aliases(self):
event = InlineQuery(
id="query",
from_user=User(id=42, is_bot=False, first_name="Test"),
query="query",
offset="0",
)
class MyHandler(InlineQueryHandler):
async def handle(self) -> Any:
assert self.event == event
assert self.from_user == self.event.from_user
assert self.query == self.event.query
return True
assert await MyHandler(event)

View file

@ -0,0 +1,34 @@
from typing import Any
import pytest
from aiogram.api.types import (
CallbackQuery,
InlineQuery,
Poll,
PollOption,
ShippingAddress,
ShippingQuery,
User,
)
from aiogram.dispatcher.handler import PollHandler
class TestShippingQueryHandler:
@pytest.mark.asyncio
async def test_attributes_aliases(self):
event = Poll(
id="query",
question="Q?",
options=[PollOption(text="A1", voter_count=1)],
is_closed=True,
)
class MyHandler(PollHandler):
async def handle(self) -> Any:
assert self.event == event
assert self.question == self.event.question
assert self.options == self.event.options
return True
assert await MyHandler(event)

View file

@ -0,0 +1,25 @@
from typing import Any
import pytest
from aiogram.api.types import PreCheckoutQuery, User
from aiogram.dispatcher.handler import PreCheckoutQueryHandler
class TestPreCheckoutQueryHandler:
@pytest.mark.asyncio
async def test_attributes_aliases(self):
event = PreCheckoutQuery(
id="query",
from_user=User(id=42, is_bot=False, first_name="Test"),
currency="BTC",
total_amount=7,
invoice_payload="payload",
)
class MyHandler(PreCheckoutQueryHandler):
async def handle(self) -> Any:
assert self.event == event
assert self.from_user == self.event.from_user
return True
assert await MyHandler(event)

View file

@ -0,0 +1,31 @@
from typing import Any
import pytest
from aiogram.api.types import CallbackQuery, InlineQuery, ShippingAddress, ShippingQuery, User
from aiogram.dispatcher.handler import ShippingQueryHandler
class TestShippingQueryHandler:
@pytest.mark.asyncio
async def test_attributes_aliases(self):
event = ShippingQuery(
id="query",
from_user=User(id=42, is_bot=False, first_name="Test"),
invoice_payload="payload",
shipping_address=ShippingAddress(
country_code="country_code",
state="state",
city="city",
street_line1="street_line1",
street_line2="street_line2",
post_code="post_code",
),
)
class MyHandler(ShippingQueryHandler):
async def handle(self) -> Any:
assert self.event == event
assert self.from_user == self.event.from_user
return True
assert await MyHandler(event)