Bump Telegram Bot API version

Change request timeout mechanism
Bump package version
This commit is contained in:
Alex Root Junior 2020-06-14 17:14:10 +03:00
parent b78f1cdb17
commit 7844a663a9
58 changed files with 526 additions and 369 deletions

View file

@ -1 +1 @@
4.8
4.9

View file

@ -28,5 +28,5 @@ __all__ = (
"handler",
)
__version__ = "3.0.0a4"
__api_version__ = "4.8"
__version__ = "3.0.0a5"
__api_version__ = "4.9"

File diff suppressed because it is too large Load diff

View file

@ -125,16 +125,16 @@ class AiohttpSession(BaseSession):
form.add_field(key, value, filename=value.filename or key)
return form
async def make_request(self, token: str, call: TelegramMethod[T]) -> T:
async def make_request(
self, token: str, call: TelegramMethod[T], timeout: Optional[int] = None
) -> T:
session = await self.create_session()
request = call.build_request()
url = self.api.api_url(token=token, method=request.method)
form = self.build_form_data(request)
async with session.post(
url, data=form, timeout=call.request_timeout or self.timeout
) as resp:
async with session.post(url, data=form, timeout=timeout or self.timeout) as resp:
raw_result = await resp.json(loads=self.json_loads)
response = call.build_response(raw_result)

View file

@ -10,6 +10,7 @@ from aiogram.utils.exceptions import TelegramAPIError
from ....utils.helper import Default
from ...methods import Response, TelegramMethod
from ...types import UNSET
from ..telegram import PRODUCTION, TelegramAPIServer
T = TypeVar("T")
@ -18,9 +19,7 @@ _JsonDumps = Callable[..., str]
class BaseSession(abc.ABC):
# global session timeout
default_timeout: ClassVar[float] = 60.0
api: Default[TelegramAPIServer] = Default(PRODUCTION)
json_loads: Default[_JsonLoads] = Default(json.loads)
json_dumps: Default[_JsonDumps] = Default(json.dumps)
@ -37,7 +36,9 @@ class BaseSession(abc.ABC):
pass
@abc.abstractmethod
async def make_request(self, token: str, method: TelegramMethod[T]) -> T: # pragma: no cover
async def make_request(
self, token: str, method: TelegramMethod[T], timeout: Optional[int] = UNSET
) -> T: # pragma: no cover
pass
@abc.abstractmethod

View file

@ -26,8 +26,8 @@ class AnswerInlineQuery(TelegramMethod[bool]):
query. By default, results may be returned to any user who sends the same query"""
next_offset: Optional[str] = None
"""Pass the offset that a client should send in the next query with the same text to receive
more results. Pass an empty string if there are no more results or if you dont support
pagination. Offset length cant exceed 64 bytes."""
more results. Pass an empty string if there are no more results or if you don't support
pagination. Offset length can't exceed 64 bytes."""
switch_pm_text: Optional[str] = None
"""If passed, clients will display a button with specified text that switches the user to a
private chat with the bot and sends the bot a start message with the parameter

View file

@ -69,13 +69,9 @@ class TelegramMethod(abc.ABC, BaseModel, Generic[T]):
def build_request(self) -> Request: # pragma: no cover
pass
request_timeout: Optional[float] = None
def dict(self, **kwargs: Any) -> Any:
# override dict of pydantic.BaseModel to overcome exporting request_timeout field
exclude = kwargs.pop("exclude", set())
if isinstance(exclude, set):
exclude.add("request_timeout")
return super().dict(exclude=exclude, **kwargs)

View file

@ -24,8 +24,7 @@ class EditMessageCaption(TelegramMethod[Union[Message, bool]]):
caption: Optional[str] = None
"""New caption of the message, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the message caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an inline keyboard."""

View file

@ -24,8 +24,7 @@ class EditMessageText(TelegramMethod[Union[Message, bool]]):
inline_message_id: Optional[str] = None
"""Required if chat_id and message_id are not specified. Identifier of the inline message"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in your bot's message."""
"""Mode for parsing entities in the message text. See formatting options for more details."""
disable_web_page_preview: Optional[bool] = None
"""Disables link previews for links in this message"""
reply_markup: Optional[InlineKeyboardMarkup] = None

View file

@ -6,8 +6,8 @@ from .base import Request, TelegramMethod
class PinChatMessage(TelegramMethod[bool]):
"""
Use this method to pin a message in a group, a supergroup, or a channel. The bot must be an
administrator in the chat for this to work and must have the can_pin_messages admin right in
the supergroup or can_edit_messages admin right in the channel. Returns True on success.
administrator in the chat for this to work and must have the 'can_pin_messages' admin right in
the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success.
Source: https://core.telegram.org/bots/api#pinchatmessage
"""

View file

@ -39,16 +39,16 @@ class SendAnimation(TelegramMethod[Message]):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
caption: Optional[str] = None
"""Animation caption (may also be used when resending animation by file_id), 0-1024 characters
after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the animation caption. See formatting options for more
details."""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None

View file

@ -35,8 +35,7 @@ class SendAudio(TelegramMethod[Message]):
caption: Optional[str] = None
"""Audio caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
duration: Optional[int] = None
"""Duration of the audio in seconds"""
performer: Optional[str] = None
@ -46,8 +45,8 @@ class SendAudio(TelegramMethod[Message]):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
disable_notification: Optional[bool] = None

View file

@ -12,9 +12,8 @@ from .base import Request, TelegramMethod
class SendDice(TelegramMethod[Message]):
"""
Use this method to send a dice, which will have a random value from 1 to 6. On success, the
sent Message is returned. (Yes, we're aware of the 'proper' singular of die. But it's awkward,
and we decided to help it change. One dice at a time!)
Use this method to send an animated emoji that will display a random value. On success, the
sent Message is returned.
Source: https://core.telegram.org/bots/api#senddice
"""
@ -25,8 +24,8 @@ class SendDice(TelegramMethod[Message]):
"""Unique identifier for the target chat or username of the target channel (in the format
@channelusername)"""
emoji: Optional[str] = None
"""Emoji on which the dice throw animation is based. Currently, must be one of '' or ''.
Defauts to ''"""
"""Emoji on which the dice throw animation is based. Currently, must be one of '', '', or ''.
Dice can have values 1-6 for '' and '', and values 1-5 for ''. Defaults to ''"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None

View file

@ -33,16 +33,15 @@ class SendDocument(TelegramMethod[Message]):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
caption: Optional[str] = None
"""Document caption (may also be used when resending documents by file_id), 0-1024 characters
after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the document caption. See formatting options for more details."""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None

View file

@ -23,7 +23,7 @@ class SendGame(TelegramMethod[Message]):
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an inline keyboard. If empty, one Play game_title button
"""A JSON-serialized object for an inline keyboard. If empty, one 'Play game_title' button
will be shown. If not empty, the first button must launch the game."""
def build_request(self) -> Request:

View file

@ -26,8 +26,7 @@ class SendMessage(TelegramMethod[Message]):
text: str
"""Text of the message to be sent, 1-4096 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in your bot's message."""
"""Mode for parsing entities in the message text. See formatting options for more details."""
disable_web_page_preview: Optional[bool] = None
"""Disables link previews for links in this message"""
disable_notification: Optional[bool] = None

View file

@ -32,8 +32,7 @@ class SendPhoto(TelegramMethod[Message]):
"""Photo caption (may also be used when resending photos by file_id), 0-1024 characters after
entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the photo caption. See formatting options for more details."""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None

View file

@ -39,16 +39,15 @@ class SendVideo(TelegramMethod[Message]):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
caption: Optional[str] = None
"""Video caption (may also be used when resending videos by file_id), 0-1024 characters after
entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the video caption. See formatting options for more details."""
supports_streaming: Optional[bool] = None
"""Pass True, if the uploaded video is suitable for streaming"""
disable_notification: Optional[bool] = None

View file

@ -35,8 +35,8 @@ class SendVideoNote(TelegramMethod[Message]):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
disable_notification: Optional[bool] = None

View file

@ -35,8 +35,8 @@ class SendVoice(TelegramMethod[Message]):
caption: Optional[str] = None
"""Voice message caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the voice message caption. See formatting options for more
details."""
duration: Optional[int] = None
"""Duration of the voice message in seconds"""
disable_notification: Optional[bool] = None

View file

@ -12,7 +12,7 @@ class SetWebhook(TelegramMethod[bool]):
after a reasonable amount of attempts. Returns True on success.
If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a
secret path in the URL, e.g. https://www.example.com/<token>. Since nobody else knows your
bots token, you can be pretty sure its us.
bot's token, you can be pretty sure it's us.
Notes
1. You will not be able to receive updates using getUpdates for as long as an outgoing webhook
is set up.
@ -34,8 +34,8 @@ class SetWebhook(TelegramMethod[bool]):
our self-signed guide for details."""
max_connections: Optional[int] = None
"""Maximum allowed number of simultaneous HTTPS connections to the webhook for update
delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bots server,
and higher values to increase your bots throughput."""
delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bot's server,
and higher values to increase your bot's throughput."""
allowed_updates: Optional[List[str]] = None
"""A JSON-serialized list of the update types you want your bot to receive. For example,
specify ['message', 'edited_channel_post', 'callback_query'] to only receive updates of

View file

@ -6,8 +6,8 @@ from .base import Request, TelegramMethod
class UnpinChatMessage(TelegramMethod[bool]):
"""
Use this method to unpin a message in a group, a supergroup, or a channel. The bot must be an
administrator in the chat for this to work and must have the can_pin_messages admin right in
the supergroup or can_edit_messages admin right in the channel. Returns True on success.
administrator in the chat for this to work and must have the 'can_pin_messages' admin right in
the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success.
Source: https://core.telegram.org/bots/api#unpinchatmessage
"""

View file

@ -24,4 +24,3 @@ class MutableTelegramObject(TelegramObject):
UNSET: Any = sentinel.UNSET # special sentinel object which used in sutuation when None might be a useful value
print(id(UNSET))

View file

@ -3,8 +3,8 @@ from __future__ import annotations
import datetime
from typing import TYPE_CHECKING, Optional, Union
from .base import TelegramObject
from ...utils import helper
from .base import TelegramObject
if TYPE_CHECKING: # pragma: no cover
from .user import User
@ -80,6 +80,7 @@ class ChatMemberStatus(helper.Helper):
"""
Chat member status
"""
mode = helper.HelperMode.lowercase
CREATOR = helper.Item() # creator

View file

@ -5,9 +5,7 @@ from .base import TelegramObject
class Dice(TelegramObject):
"""
This object represents a dice with a random value from 1 to 6 for currently supported base
emoji. (Yes, we're aware of the 'proper' singular of die. But it's awkward, and we decided to
help it change. One dice at a time!)
This object represents an animated emoji that displays a random value.
Source: https://core.telegram.org/bots/api#dice
"""
@ -15,7 +13,7 @@ class Dice(TelegramObject):
emoji: str
"""Emoji on which the dice throw animation is based"""
value: int
"""Value of the dice, 1-6 for currently supported base emoji"""
"""Value of the dice, 1-6 for '' and '' base emoji, 1-5 for '' base emoji"""
class DiceEmoji:

View file

@ -8,7 +8,7 @@ from .base import MutableTelegramObject
class ForceReply(MutableTelegramObject):
"""
Upon receiving a message with this object, Telegram clients will display a reply interface to
the user (act as if the user has selected the bots message and tapped Reply'). This can be
the user (act as if the user has selected the bot's message and tapped 'Reply'). This can be
extremely useful if you want to create user-friendly step-by-step interfaces without having to
sacrifice privacy mode.
Example: A poll bot for groups runs in privacy mode (only receives commands, replies to its
@ -16,19 +16,19 @@ class ForceReply(MutableTelegramObject):
Explain the user how to send a command with parameters (e.g. /newpoll question answer1
answer2). May be appealing for hardcore users but lacks modern day polish.
Guide the user through a step-by-step process. Please send me your question, Cool, now
lets add the first answer option, Great. Keep adding answer options, then send /done when
youre ready.
The last option is definitely more attractive. And if you use ForceReply in your bots
questions, it will receive the users answers even if it only receives replies, commands and
Guide the user through a step-by-step process. 'Please send me your question', 'Cool, now
let's add the first answer option', 'Great. Keep adding answer options, then send /done when
you're ready'.
The last option is definitely more attractive. And if you use ForceReply in your bot's
questions, it will receive the user's answers even if it only receives replies, commands and
mentions without any extra work for the user.
Source: https://core.telegram.org/bots/api#forcereply
"""
force_reply: bool
"""Shows reply interface to the user, as if they manually selected the bots message and
tapped Reply'"""
"""Shows reply interface to the user, as if they manually selected the bot's message and
tapped 'Reply'"""
selective: Optional[bool] = None
"""Use this parameter if you want to force reply from specific users only. Targets: 1) users
that are @mentioned in the text of the Message object; 2) if the bot's message is a reply

View file

@ -11,7 +11,7 @@ if TYPE_CHECKING: # pragma: no cover
class GameHighScore(TelegramObject):
"""
This object represents one row of the high scores table for a game.
And thats about all weve got for now.
And that's about all we've got for now.
If you've got any questions, please check out our Bot FAQ
Source: https://core.telegram.org/bots/api#gamehighscore

View file

@ -28,11 +28,11 @@ class InlineKeyboardButton(MutableTelegramObject):
"""Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes"""
switch_inline_query: Optional[str] = None
"""If set, pressing the button will prompt the user to select one of their chats, open that
chat and insert the bots username and the specified inline query in the input field. Can
be empty, in which case just the bots username will be inserted."""
chat and insert the bot's username and the specified inline query in the input field. Can
be empty, in which case just the bot's username will be inserted."""
switch_inline_query_current_chat: Optional[str] = None
"""If set, pressing the button will insert the bots username and the specified inline query
in the current chats input field. Can be empty, in which case only the bot's username will
"""If set, pressing the button will insert the bot's username and the specified inline query
in the current chat's input field. Can be empty, in which case only the bot's username will
be inserted."""
callback_game: Optional[CallbackGame] = None
"""Description of the game that will be launched when the user presses the button."""

View file

@ -34,8 +34,7 @@ class InlineQueryResultAudio(InlineQueryResult):
caption: Optional[str] = None
"""Caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
performer: Optional[str] = None
"""Performer"""
audio_duration: Optional[int] = None

View file

@ -32,8 +32,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
caption: Optional[str] = None
"""Caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -36,8 +36,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the document to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the document caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -32,8 +32,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the GIF file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -33,8 +33,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the MPEG-4 file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -34,8 +34,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the photo to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the photo caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -34,8 +34,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the video to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the video caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -34,8 +34,8 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
caption: Optional[str] = None
"""Caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the voice message caption. See formatting options for more
details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -37,8 +37,7 @@ class InlineQueryResultDocument(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the document to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the document caption. See formatting options for more details."""
description: Optional[str] = None
"""Short description of the result"""
reply_markup: Optional[InlineKeyboardMarkup] = None

View file

@ -28,20 +28,22 @@ class InlineQueryResultGif(InlineQueryResult):
gif_url: str
"""A valid URL for the GIF file. File size must not exceed 1MB"""
thumb_url: str
"""URL of the static thumbnail for the result (jpeg or gif)"""
"""URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result"""
gif_width: Optional[int] = None
"""Width of the GIF"""
gif_height: Optional[int] = None
"""Height of the GIF"""
gif_duration: Optional[int] = None
"""Duration of the GIF"""
thumb_mime_type: Optional[str] = None
"""MIME type of the thumbnail, must be one of 'image/jpeg', 'image/gif', or 'video/mp4'.
Defaults to 'image/jpeg'"""
title: Optional[str] = None
"""Title for the result"""
caption: Optional[str] = None
"""Caption of the GIF file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -29,20 +29,22 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
mpeg4_url: str
"""A valid URL for the MP4 file. File size must not exceed 1MB"""
thumb_url: str
"""URL of the static thumbnail (jpeg or gif) for the result"""
"""URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result"""
mpeg4_width: Optional[int] = None
"""Video width"""
mpeg4_height: Optional[int] = None
"""Video height"""
mpeg4_duration: Optional[int] = None
"""Video duration"""
thumb_mime_type: Optional[str] = None
"""MIME type of the thumbnail, must be one of 'image/jpeg', 'image/gif', or 'video/mp4'.
Defaults to 'image/jpeg'"""
title: Optional[str] = None
"""Title for the result"""
caption: Optional[str] = None
"""Caption of the MPEG-4 file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -40,8 +40,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the photo to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the photo caption. See formatting options for more details."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -38,8 +38,7 @@ class InlineQueryResultVideo(InlineQueryResult):
caption: Optional[str] = None
"""Caption of the video to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the video caption. See formatting options for more details."""
video_width: Optional[int] = None
"""Video width"""
video_height: Optional[int] = None

View file

@ -35,8 +35,8 @@ class InlineQueryResultVoice(InlineQueryResult):
caption: Optional[str] = None
"""Caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the voice message caption. See formatting options for more
details."""
voice_duration: Optional[int] = None
"""Recording duration in seconds"""
reply_markup: Optional[InlineKeyboardMarkup] = None

View file

@ -28,15 +28,15 @@ class InputMediaAnimation(InputMedia):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
caption: Optional[str] = None
"""Caption of the animation to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the animation caption. See formatting options for more
details."""
width: Optional[int] = None
"""Animation width"""
height: Optional[int] = None

View file

@ -28,15 +28,14 @@ class InputMediaAudio(InputMedia):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
caption: Optional[str] = None
"""Caption of the audio to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
duration: Optional[int] = None
"""Duration of the audio in seconds"""
performer: Optional[str] = None

View file

@ -28,12 +28,11 @@ class InputMediaDocument(InputMedia):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
caption: Optional[str] = None
"""Caption of the document to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the document caption. See formatting options for more details."""

View file

@ -28,5 +28,4 @@ class InputMediaPhoto(InputMedia):
caption: Optional[str] = None
"""Caption of the photo to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the photo caption. See formatting options for more details."""

View file

@ -28,15 +28,14 @@ class InputMediaVideo(InputMedia):
thumb: Optional[Union[InputFile, str]] = None
"""Thumbnail of the file sent; can be ignored if thumbnail generation for the file is
supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size.
A thumbnails width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails cant be reused and can be only uploaded as a new
A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded
using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new
file, so you can pass 'attach://<file_attach_name>' if the thumbnail was uploaded using
multipart/form-data under <file_attach_name>."""
caption: Optional[str] = None
"""Caption of the video to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in the media caption."""
"""Mode for parsing entities in the video caption. See formatting options for more details."""
width: Optional[int] = None
"""Video width"""
height: Optional[int] = None

View file

@ -16,7 +16,6 @@ class InputTextMessageContent(InputMessageContent):
message_text: str
"""Text of the message to be sent, 1-4096 characters"""
parse_mode: Optional[str] = UNSET
"""Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or
inline URLs in your bot's message."""
"""Mode for parsing entities in the message text. See formatting options for more details."""
disable_web_page_preview: Optional[bool] = None
"""Disables link previews for links in the sent message"""

View file

@ -90,6 +90,8 @@ class Message(TelegramObject):
reply_to_message: Optional[Message] = None
"""For replies, the original message. Note that the Message object in this field will not
contain further reply_to_message fields even if it itself is a reply."""
via_bot: Optional[User] = None
"""Bot through which the message was sent"""
edit_date: Optional[int] = None
"""Date the message was last edited in Unix time"""
media_group_id: Optional[str] = None
@ -101,40 +103,41 @@ class Message(TelegramObject):
entities: Optional[List[MessageEntity]] = None
"""For text messages, special entities like usernames, URLs, bot commands, etc. that appear in
the text"""
caption_entities: Optional[List[MessageEntity]] = None
"""For messages with a caption, special entities like usernames, URLs, bot commands, etc. that
appear in the caption"""
animation: Optional[Animation] = None
"""Message is an animation, information about the animation. For backward compatibility, when
this field is set, the document field will also be set"""
audio: Optional[Audio] = None
"""Message is an audio file, information about the file"""
document: Optional[Document] = None
"""Message is a general file, information about the file"""
animation: Optional[Animation] = None
"""Message is an animation, information about the animation. For backward compatibility, when
this field is set, the document field will also be set"""
game: Optional[Game] = None
"""Message is a game, information about the game."""
photo: Optional[List[PhotoSize]] = None
"""Message is a photo, available sizes of the photo"""
sticker: Optional[Sticker] = None
"""Message is a sticker, information about the sticker"""
video: Optional[Video] = None
"""Message is a video, information about the video"""
voice: Optional[Voice] = None
"""Message is a voice message, information about the file"""
video_note: Optional[VideoNote] = None
"""Message is a video note, information about the video message"""
voice: Optional[Voice] = None
"""Message is a voice message, information about the file"""
caption: Optional[str] = None
"""Caption for the animation, audio, document, photo, video or voice, 0-1024 characters"""
caption_entities: Optional[List[MessageEntity]] = None
"""For messages with a caption, special entities like usernames, URLs, bot commands, etc. that
appear in the caption"""
contact: Optional[Contact] = None
"""Message is a shared contact, information about the contact"""
location: Optional[Location] = None
"""Message is a shared location, information about the location"""
venue: Optional[Venue] = None
"""Message is a venue, information about the venue"""
poll: Optional[Poll] = None
"""Message is a native poll, information about the poll"""
dice: Optional[Dice] = None
"""Message is a dice with random value from 1 to 6"""
game: Optional[Game] = None
"""Message is a game, information about the game."""
poll: Optional[Poll] = None
"""Message is a native poll, information about the poll"""
venue: Optional[Venue] = None
"""Message is a venue, information about the venue. For backward compatibility, when this
field is set, the location field will also be set"""
location: Optional[Location] = None
"""Message is a shared location, information about the location"""
new_chat_members: Optional[List[User]] = None
"""New members that were added to the group or supergroup and information about them (the bot
itself may be one of these members)"""
@ -150,13 +153,13 @@ class Message(TelegramObject):
group_chat_created: Optional[bool] = None
"""Service message: the group has been created"""
supergroup_chat_created: Optional[bool] = None
"""Service message: the supergroup has been created. This field cant be received in a message
coming through updates, because bot cant be a member of a supergroup when it is created.
"""Service message: the supergroup has been created. This field can't be received in a message
coming through updates, because bot can't be a member of a supergroup when it is created.
It can only be found in reply_to_message if someone replies to a very first message in a
directly created supergroup."""
channel_chat_created: Optional[bool] = None
"""Service message: the channel has been created. This field cant be received in a message
coming through updates, because bot cant be a member of a channel when it is created. It
"""Service message: the channel has been created. This field can't be received in a message
coming through updates, because bot can't be a member of a channel when it is created. It
can only be found in reply_to_message if someone replies to a very first message in a
channel."""
migrate_to_chat_id: Optional[int] = None

View file

@ -24,8 +24,8 @@ class Update(TelegramObject):
"""
update_id: int
"""The updates unique identifier. Update identifiers start from a certain positive number and
increase sequentially. This ID becomes especially handy if youre using Webhooks, since it
"""The update's unique identifier. Update identifiers start from a certain positive number and
increase sequentially. This ID becomes especially handy if you're using Webhooks, since it
allows you to ignore repeated updates or to restore the correct update sequence, should
they get out of order. If there are no new updates for at least a week, then identifier of
the next update will be chosen randomly instead of sequentially."""

View file

@ -17,11 +17,11 @@ class User(TelegramObject):
is_bot: bool
"""True, if this user is a bot"""
first_name: str
"""Users or bots first name"""
"""User's or bot's first name"""
last_name: Optional[str] = None
"""Users or bots last name"""
"""User's or bot's last name"""
username: Optional[str] = None
"""Users or bots username"""
"""User's or bot's username"""
language_code: Optional[str] = None
"""IETF language tag of the user's language"""
can_join_groups: Optional[bool] = None

View file

@ -1 +1 @@
4.8
4.9

View file

@ -1 +1 @@
3.0.0a4
3.0.0a5

153
poetry.lock generated
View file

@ -130,7 +130,7 @@ description = "Specifications for callback functions passed in to an API"
name = "backcall"
optional = false
python-versions = "*"
version = "0.1.0"
version = "0.2.0"
[[package]]
category = "dev"
@ -191,7 +191,7 @@ description = "Python package for providing Mozilla's CA Bundle."
name = "certifi"
optional = false
python-versions = "*"
version = "2020.4.5.1"
version = "2020.4.5.2"
[[package]]
category = "dev"
@ -322,7 +322,7 @@ description = "the modular source code checker: pep8 pyflakes and co"
name = "flake8"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
version = "3.8.2"
version = "3.8.3"
[package.dependencies]
mccabe = ">=0.6.0,<0.7.0"
@ -380,7 +380,7 @@ description = "File identification library for Python"
name = "identify"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
version = "1.4.16"
version = "1.4.19"
[package.extras]
license = ["editdistance"]
@ -414,14 +414,14 @@ description = "Read metadata from Python packages"
name = "importlib-metadata"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
version = "1.6.0"
version = "1.6.1"
[package.dependencies]
zipp = ">=0.5"
[package.extras]
docs = ["sphinx", "rst.linker"]
testing = ["packaging", "importlib-resources"]
testing = ["packaging", "pep517", "importlib-resources (>=1.3)"]
[[package]]
category = "dev"
@ -429,7 +429,7 @@ description = "IPython: Productive Interactive Computing"
name = "ipython"
optional = false
python-versions = ">=3.6"
version = "7.14.0"
version = "7.15.0"
[package.dependencies]
appnope = "*"
@ -445,7 +445,7 @@ setuptools = ">=18.5"
traitlets = ">=4.2"
[package.extras]
all = ["nose (>=0.10.1)", "Sphinx (>=1.3)", "testpath", "nbformat", "ipywidgets", "qtconsole", "numpy (>=1.14)", "notebook", "ipyparallel", "ipykernel", "pygments", "requests", "nbconvert"]
all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.14)", "pygments", "qtconsole", "requests", "testpath"]
doc = ["Sphinx (>=1.3)"]
kernel = ["ipykernel"]
nbconvert = ["nbconvert"]
@ -576,11 +576,14 @@ description = "Python LiveReload is an awesome tool for web developers"
name = "livereload"
optional = false
python-versions = "*"
version = "2.6.1"
version = "2.6.2"
[package.dependencies]
six = "*"
tornado = "*"
[package.dependencies.tornado]
python = ">=2.8"
version = "*"
[[package]]
category = "dev"
@ -715,7 +718,7 @@ description = "More routines for operating on iterables, beyond itertools"
name = "more-itertools"
optional = false
python-versions = ">=3.5"
version = "8.3.0"
version = "8.4.0"
[[package]]
category = "dev"
@ -786,7 +789,7 @@ description = "Node.js virtual environment builder"
name = "nodeenv"
optional = false
python-versions = "*"
version = "1.3.5"
version = "1.4.0"
[[package]]
category = "dev"
@ -879,7 +882,7 @@ description = "Python dependency management and packaging made easy."
name = "poetry"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.0.5"
version = "1.0.9"
[package.dependencies]
cachy = ">=0.3.0,<0.4.0"
@ -914,7 +917,7 @@ description = "A framework for managing and maintaining multi-language pre-commi
name = "pre-commit"
optional = false
python-versions = ">=3.6.1"
version = "2.4.0"
version = "2.5.1"
[package.dependencies]
cfgv = ">=2.0.0"
@ -942,7 +945,6 @@ wcwidth = "*"
[[package]]
category = "dev"
description = "Run a subprocess in a pseudo terminal"
marker = "sys_platform != \"win32\""
name = "ptyprocess"
optional = false
python-versions = "*"
@ -1046,7 +1048,7 @@ description = "pytest: simple powerful testing with Python"
name = "pytest"
optional = false
python-versions = ">=3.5"
version = "5.4.2"
version = "5.4.3"
[package.dependencies]
atomicwrites = ">=1.0"
@ -1086,11 +1088,11 @@ description = "Pytest plugin for measuring coverage."
name = "pytest-cov"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "2.9.0"
version = "2.10.0"
[package.dependencies]
coverage = ">=4.4"
pytest = ">=3.6"
pytest = ">=4.6"
[package.extras]
testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"]
@ -1184,7 +1186,7 @@ description = "Alternative regular expression module, to replace re."
name = "regex"
optional = false
python-versions = "*"
version = "2020.5.14"
version = "2020.6.8"
[[package]]
category = "dev"
@ -1275,7 +1277,7 @@ marker = "python_version > \"2.7\""
name = "tqdm"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
version = "4.46.0"
version = "4.46.1"
[package.extras]
dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown"]
@ -1340,7 +1342,7 @@ description = "Virtual Python Environment builder"
name = "virtualenv"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
version = "20.0.21"
version = "20.0.23"
[package.dependencies]
appdirs = ">=1.4.3,<2"
@ -1354,15 +1356,15 @@ version = ">=0.12,<2"
[package.extras]
docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"]
testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "flaky (>=3)", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
[[package]]
category = "dev"
description = "Measures number of Terminal column cells of wide-character codes"
description = "Measures the displayed width of unicode strings in a terminal"
name = "wcwidth"
optional = false
python-versions = "*"
version = "0.1.9"
version = "0.2.4"
[[package]]
category = "dev"
@ -1463,8 +1465,8 @@ babel = [
{file = "Babel-2.8.0.tar.gz", hash = "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38"},
]
backcall = [
{file = "backcall-0.1.0.tar.gz", hash = "sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4"},
{file = "backcall-0.1.0.zip", hash = "sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2"},
{file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
{file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
]
black = [
{file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"},
@ -1479,8 +1481,8 @@ cachy = [
{file = "cachy-0.3.0.tar.gz", hash = "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1"},
]
certifi = [
{file = "certifi-2020.4.5.1-py2.py3-none-any.whl", hash = "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304"},
{file = "certifi-2020.4.5.1.tar.gz", hash = "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"},
{file = "certifi-2020.4.5.2-py2.py3-none-any.whl", hash = "sha256:9cd41137dc19af6a5e03b630eefe7d1f458d964d406342dd3edf625839b944cc"},
{file = "certifi-2020.4.5.2.tar.gz", hash = "sha256:5ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1"},
]
cffi = [
{file = "cffi-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1cae98a7054b5c9391eb3249b86e0e99ab1e02bb0cc0575da191aedadbdf4384"},
@ -1602,8 +1604,8 @@ filelock = [
{file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
]
flake8 = [
{file = "flake8-3.8.2-py2.py3-none-any.whl", hash = "sha256:ccaa799ef9893cebe69fdfefed76865aeaefbb94cb8545617b2298786a4de9a5"},
{file = "flake8-3.8.2.tar.gz", hash = "sha256:c69ac1668e434d37a2d2880b3ca9aafd54b3a10a3ac1ab101d22f29e29cf8634"},
{file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"},
{file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"},
]
flake8-html = [
{file = "flake8-html-0.4.1.tar.gz", hash = "sha256:2fb436cbfe1e109275bc8fb7fdd0cb00e67b3b48cfeb397309b6b2c61eeb4cb4"},
@ -1617,8 +1619,8 @@ html5lib = [
{file = "html5lib-1.0.1.tar.gz", hash = "sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736"},
]
identify = [
{file = "identify-1.4.16-py2.py3-none-any.whl", hash = "sha256:0f3c3aac62b51b86fea6ff52fe8ff9e06f57f10411502443809064d23e16f1c2"},
{file = "identify-1.4.16.tar.gz", hash = "sha256:f9ad3d41f01e98eb066b6e05c5b184fd1e925fadec48eb165b4e01c72a1ef3a7"},
{file = "identify-1.4.19-py2.py3-none-any.whl", hash = "sha256:781fd3401f5d2b17b22a8b18b493a48d5d948e3330634e82742e23f9c20234ef"},
{file = "identify-1.4.19.tar.gz", hash = "sha256:249ebc7e2066d6393d27c1b1be3b70433f824a120b1d8274d362f1eb419e3b52"},
]
idna = [
{file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"},
@ -1627,12 +1629,12 @@ idna = [
importlib-metadata = [
{file = "importlib_metadata-1.1.3-py2.py3-none-any.whl", hash = "sha256:7c7f8ac40673f507f349bef2eed21a0e5f01ddf5b2a7356a6c65eb2099b53764"},
{file = "importlib_metadata-1.1.3.tar.gz", hash = "sha256:7a99fb4084ffe6dae374961ba7a6521b79c1d07c658ab3a28aa264ee1d1b14e3"},
{file = "importlib_metadata-1.6.0-py2.py3-none-any.whl", hash = "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f"},
{file = "importlib_metadata-1.6.0.tar.gz", hash = "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"},
{file = "importlib_metadata-1.6.1-py2.py3-none-any.whl", hash = "sha256:15ec6c0fd909e893e3a08b3a7c76ecb149122fb14b7efe1199ddd4c7c57ea958"},
{file = "importlib_metadata-1.6.1.tar.gz", hash = "sha256:0505dd08068cfec00f53a74a0ad927676d7757da81b7436a6eefe4c7cf75c545"},
]
ipython = [
{file = "ipython-7.14.0-py3-none-any.whl", hash = "sha256:5b241b84bbf0eb085d43ae9d46adf38a13b45929ca7774a740990c2c242534bb"},
{file = "ipython-7.14.0.tar.gz", hash = "sha256:f0126781d0f959da852fb3089e170ed807388e986a8dd4e6ac44855845b0fb1c"},
{file = "ipython-7.15.0-py3-none-any.whl", hash = "sha256:1b85d65632211bf5d3e6f1406f3393c8c429a47d7b947b9a87812aa5bce6595c"},
{file = "ipython-7.15.0.tar.gz", hash = "sha256:0ef1433879816a960cd3ae1ae1dc82c64732ca75cec8dab5a4e29783fb571d0e"},
]
ipython-genutils = [
{file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"},
@ -1667,8 +1669,7 @@ keyring = [
{file = "keyring-20.0.1.tar.gz", hash = "sha256:963bfa7f090269d30bdc5e25589e5fd9dad2cf2a7c6f176a7f2386910e5d0d8d"},
]
livereload = [
{file = "livereload-2.6.1-py2.py3-none-any.whl", hash = "sha256:78d55f2c268a8823ba499305dcac64e28ddeb9a92571e12d543cd304faf5817b"},
{file = "livereload-2.6.1.tar.gz", hash = "sha256:89254f78d7529d7ea0a3417d224c34287ebfe266b05e67e51facaf82c27f0f66"},
{file = "livereload-2.6.2.tar.gz", hash = "sha256:d1eddcb5c5eb8d2ca1fa1f750e580da624c0f7fcb734aa5780dc81b7dcbd89be"},
]
lockfile = [
{file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"},
@ -1760,8 +1761,8 @@ mkdocs-material = [
{file = "mkdocs_material-4.6.3-py2.py3-none-any.whl", hash = "sha256:7f3afa0a09c07d0b89a6a9755fdb00513aee8f0cec3538bb903325c80f66f444"},
]
more-itertools = [
{file = "more-itertools-8.3.0.tar.gz", hash = "sha256:558bb897a2232f5e4f8e2399089e35aecb746e1f9191b6584a151647e89267be"},
{file = "more_itertools-8.3.0-py3-none-any.whl", hash = "sha256:7818f596b1e87be009031c7653d01acc46ed422e6656b394b0f765ce66ed4982"},
{file = "more-itertools-8.4.0.tar.gz", hash = "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5"},
{file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"},
]
msgpack = [
{file = "msgpack-1.0.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:cec8bf10981ed70998d98431cd814db0ecf3384e6b113366e7f36af71a0fca08"},
@ -1826,7 +1827,7 @@ nltk = [
{file = "nltk-3.5.zip", hash = "sha256:845365449cd8c5f9731f7cb9f8bd6fd0767553b9d53af9eb1b3abf7700936b35"},
]
nodeenv = [
{file = "nodeenv-1.3.5-py2.py3-none-any.whl", hash = "sha256:5b2438f2e42af54ca968dd1b374d14a1194848955187b0e5e4be1f73813a5212"},
{file = "nodeenv-1.4.0-py2.py3-none-any.whl", hash = "sha256:4b0b77afa3ba9b54f4b6396e60b0c83f59eaeb2d63dc3cc7a70f7f4af96c82bc"},
]
packaging = [
{file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"},
@ -1861,12 +1862,12 @@ pluggy = [
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
]
poetry = [
{file = "poetry-1.0.5-py2.py3-none-any.whl", hash = "sha256:81cdb3c708fe03cdef484ccd6c3becc74811dce2b15cb67444c2495b1240a278"},
{file = "poetry-1.0.5.tar.gz", hash = "sha256:8e195ea8a4bce4f418a23fd828aa2f9ce06be7655720efd1d95beb0ee641030a"},
{file = "poetry-1.0.9-py2.py3-none-any.whl", hash = "sha256:27e0c9c16f785156a8d8d0e98a73e239c8d2083306c180718825d11d5664aea0"},
{file = "poetry-1.0.9.tar.gz", hash = "sha256:0a4c56983546964b47cbbe0e1b49fef5662277bbf0673e3e350e1215560377ab"},
]
pre-commit = [
{file = "pre_commit-2.4.0-py2.py3-none-any.whl", hash = "sha256:5559e09afcac7808933951ffaf4ff9aac524f31efbc3f24d021540b6c579813c"},
{file = "pre_commit-2.4.0.tar.gz", hash = "sha256:703e2e34cbe0eedb0d319eff9f7b83e2022bb5a3ab5289a6a8841441076514d0"},
{file = "pre_commit-2.5.1-py2.py3-none-any.whl", hash = "sha256:c5c8fd4d0e1c363723aaf0a8f9cba0f434c160b48c4028f4bae6d219177945b3"},
{file = "pre_commit-2.5.1.tar.gz", hash = "sha256:da463cf8f0e257f9af49047ba514f6b90dbd9b4f92f4c8847a3ccd36834874c7"},
]
prompt-toolkit = [
{file = "prompt_toolkit-3.0.5-py3-none-any.whl", hash = "sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04"},
@ -1931,16 +1932,16 @@ pyrsistent = [
{file = "pyrsistent-0.14.11.tar.gz", hash = "sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"},
]
pytest = [
{file = "pytest-5.4.2-py3-none-any.whl", hash = "sha256:95c710d0a72d91c13fae35dce195633c929c3792f54125919847fdcdf7caa0d3"},
{file = "pytest-5.4.2.tar.gz", hash = "sha256:eb2b5e935f6a019317e455b6da83dd8650ac9ffd2ee73a7b657a30873d67a698"},
{file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"},
{file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"},
]
pytest-asyncio = [
{file = "pytest-asyncio-0.10.0.tar.gz", hash = "sha256:9fac5100fd716cbecf6ef89233e8590a4ad61d729d1732e0a96b84182df1daaf"},
{file = "pytest_asyncio-0.10.0-py3-none-any.whl", hash = "sha256:d734718e25cfc32d2bf78d346e99d33724deeba774cc4afdf491530c6184b63b"},
]
pytest-cov = [
{file = "pytest-cov-2.9.0.tar.gz", hash = "sha256:b6a814b8ed6247bd81ff47f038511b57fe1ce7f4cc25b9106f1a4b106f1d9322"},
{file = "pytest_cov-2.9.0-py2.py3-none-any.whl", hash = "sha256:c87dfd8465d865655a8213859f1b4749b43448b5fae465cb981e16d52a811424"},
{file = "pytest-cov-2.10.0.tar.gz", hash = "sha256:1a629dc9f48e53512fcbfda6b07de490c374b0c83c55ff7a1720b3fccff0ac87"},
{file = "pytest_cov-2.10.0-py2.py3-none-any.whl", hash = "sha256:6e6d18092dce6fad667cd7020deed816f858ad3b49d5b5e2b1cc1c97a4dba65c"},
]
pytest-html = [
{file = "pytest-html-2.1.1.tar.gz", hash = "sha256:6a4ac391e105e391208e3eb9bd294a60dd336447fd8e1acddff3a6de7f4e57c5"},
@ -1980,27 +1981,27 @@ pyyaml = [
{file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
]
regex = [
{file = "regex-2020.5.14-cp27-cp27m-win32.whl", hash = "sha256:e565569fc28e3ba3e475ec344d87ed3cd8ba2d575335359749298a0899fe122e"},
{file = "regex-2020.5.14-cp27-cp27m-win_amd64.whl", hash = "sha256:d466967ac8e45244b9dfe302bbe5e3337f8dc4dec8d7d10f5e950d83b140d33a"},
{file = "regex-2020.5.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:27ff7325b297fb6e5ebb70d10437592433601c423f5acf86e5bc1ee2919b9561"},
{file = "regex-2020.5.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ea55b80eb0d1c3f1d8d784264a6764f931e172480a2f1868f2536444c5f01e01"},
{file = "regex-2020.5.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c9bce6e006fbe771a02bda468ec40ffccbf954803b470a0345ad39c603402577"},
{file = "regex-2020.5.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:d881c2e657c51d89f02ae4c21d9adbef76b8325fe4d5cf0e9ad62f850f3a98fd"},
{file = "regex-2020.5.14-cp36-cp36m-win32.whl", hash = "sha256:99568f00f7bf820c620f01721485cad230f3fb28f57d8fbf4a7967ec2e446994"},
{file = "regex-2020.5.14-cp36-cp36m-win_amd64.whl", hash = "sha256:70c14743320a68c5dac7fc5a0f685be63bc2024b062fe2aaccc4acc3d01b14a1"},
{file = "regex-2020.5.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a7c37f048ec3920783abab99f8f4036561a174f1314302ccfa4e9ad31cb00eb4"},
{file = "regex-2020.5.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:89d76ce33d3266173f5be80bd4efcbd5196cafc34100fdab814f9b228dee0fa4"},
{file = "regex-2020.5.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:51f17abbe973c7673a61863516bdc9c0ef467407a940f39501e786a07406699c"},
{file = "regex-2020.5.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ce5cc53aa9fbbf6712e92c7cf268274eaff30f6bd12a0754e8133d85a8fb0f5f"},
{file = "regex-2020.5.14-cp37-cp37m-win32.whl", hash = "sha256:8044d1c085d49673aadb3d7dc20ef5cb5b030c7a4fa253a593dda2eab3059929"},
{file = "regex-2020.5.14-cp37-cp37m-win_amd64.whl", hash = "sha256:c2062c7d470751b648f1cacc3f54460aebfc261285f14bc6da49c6943bd48bdd"},
{file = "regex-2020.5.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:329ba35d711e3428db6b45a53b1b13a0a8ba07cbbcf10bbed291a7da45f106c3"},
{file = "regex-2020.5.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:579ea215c81d18da550b62ff97ee187b99f1b135fd894a13451e00986a080cad"},
{file = "regex-2020.5.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:3a9394197664e35566242686d84dfd264c07b20f93514e2e09d3c2b3ffdf78fe"},
{file = "regex-2020.5.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ce367d21f33e23a84fb83a641b3834dd7dd8e9318ad8ff677fbfae5915a239f7"},
{file = "regex-2020.5.14-cp38-cp38-win32.whl", hash = "sha256:1386e75c9d1574f6aa2e4eb5355374c8e55f9aac97e224a8a5a6abded0f9c927"},
{file = "regex-2020.5.14-cp38-cp38-win_amd64.whl", hash = "sha256:7e61be8a2900897803c293247ef87366d5df86bf701083b6c43119c7c6c99108"},
{file = "regex-2020.5.14.tar.gz", hash = "sha256:ce450ffbfec93821ab1fea94779a8440e10cf63819be6e176eb1973a6017aff5"},
{file = "regex-2020.6.8-cp27-cp27m-win32.whl", hash = "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c"},
{file = "regex-2020.6.8-cp27-cp27m-win_amd64.whl", hash = "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938"},
{file = "regex-2020.6.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89"},
{file = "regex-2020.6.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868"},
{file = "regex-2020.6.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f"},
{file = "regex-2020.6.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded"},
{file = "regex-2020.6.8-cp36-cp36m-win32.whl", hash = "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3"},
{file = "regex-2020.6.8-cp36-cp36m-win_amd64.whl", hash = "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd"},
{file = "regex-2020.6.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a"},
{file = "regex-2020.6.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae"},
{file = "regex-2020.6.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a"},
{file = "regex-2020.6.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3"},
{file = "regex-2020.6.8-cp37-cp37m-win32.whl", hash = "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9"},
{file = "regex-2020.6.8-cp37-cp37m-win_amd64.whl", hash = "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29"},
{file = "regex-2020.6.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610"},
{file = "regex-2020.6.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387"},
{file = "regex-2020.6.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910"},
{file = "regex-2020.6.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf"},
{file = "regex-2020.6.8-cp38-cp38-win32.whl", hash = "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754"},
{file = "regex-2020.6.8-cp38-cp38-win_amd64.whl", hash = "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5"},
{file = "regex-2020.6.8.tar.gz", hash = "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac"},
]
requests = [
{file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"},
@ -2042,8 +2043,8 @@ tornado = [
{file = "tornado-6.0.4.tar.gz", hash = "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc"},
]
tqdm = [
{file = "tqdm-4.46.0-py2.py3-none-any.whl", hash = "sha256:acdafb20f51637ca3954150d0405ff1a7edde0ff19e38fb99a80a66210d2a28f"},
{file = "tqdm-4.46.0.tar.gz", hash = "sha256:4733c4a10d0f2a4d098d801464bdaf5240c7dadd2a7fde4ee93b0a0efd9fb25e"},
{file = "tqdm-4.46.1-py2.py3-none-any.whl", hash = "sha256:07c06493f1403c1380b630ae3dcbe5ae62abcf369a93bbc052502279f189ab8c"},
{file = "tqdm-4.46.1.tar.gz", hash = "sha256:cd140979c2bebd2311dfb14781d8f19bd5a9debb92dcab9f6ef899c987fcf71f"},
]
traitlets = [
{file = "traitlets-4.3.3-py2.py3-none-any.whl", hash = "sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44"},
@ -2093,12 +2094,12 @@ uvloop = [
{file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"},
]
virtualenv = [
{file = "virtualenv-20.0.21-py2.py3-none-any.whl", hash = "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70"},
{file = "virtualenv-20.0.21.tar.gz", hash = "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf"},
{file = "virtualenv-20.0.23-py2.py3-none-any.whl", hash = "sha256:ccfb8e1e05a1174f7bd4c163700277ba730496094fe1a58bea9d4ac140a207c8"},
{file = "virtualenv-20.0.23.tar.gz", hash = "sha256:5102fbf1ec57e80671ef40ed98a84e980a71194cedf30c87c2b25c3a9e0b0107"},
]
wcwidth = [
{file = "wcwidth-0.1.9-py2.py3-none-any.whl", hash = "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1"},
{file = "wcwidth-0.1.9.tar.gz", hash = "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"},
{file = "wcwidth-0.2.4-py2.py3-none-any.whl", hash = "sha256:79375666b9954d4a1a10739315816324c3e73110af9d0e102d906fdb0aec009f"},
{file = "wcwidth-0.2.4.tar.gz", hash = "sha256:8c6b5b6ee1360b842645f336d9e5d68c55817c26d3050f46b235ef2bc650e48f"},
]
webencodings = [
{file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "aiogram"
version = "3.0.0-alpha.4"
version = "3.0.0-alpha.5"
description = "Modern and fully asynchronous framework for Telegram Bot API"
authors = ["Alex Root Junior <jroot.junior@gmail.com>"]
license = "MIT"

View file

@ -5,6 +5,7 @@ from aiogram import Bot
from aiogram.api.client.session.base import BaseSession
from aiogram.api.methods import TelegramMethod
from aiogram.api.methods.base import Request, Response, T
from aiogram.api.types import UNSET
class MockedSession(BaseSession):
@ -23,7 +24,9 @@ class MockedSession(BaseSession):
async def close(self):
pass
async def make_request(self, token: str, method: TelegramMethod[T]) -> T:
async def make_request(
self, token: str, method: TelegramMethod[T], timeout: Optional[int] = UNSET
) -> T:
self.requests.append(method.build_request())
response: Response[T] = self.responses.pop()
self.raise_for_status(response)

View file

@ -1,12 +1,13 @@
import datetime
import json
from typing import AsyncContextManager, AsyncGenerator
from typing import AsyncContextManager, AsyncGenerator, Optional
import pytest
from aiogram.api.client.session.base import BaseSession, T
from aiogram.api.client.telegram import PRODUCTION, TelegramAPIServer
from aiogram.api.methods import GetMe, Response, TelegramMethod
from aiogram.api.types import UNSET
try:
from asynctest import CoroutineMock, patch
@ -18,7 +19,7 @@ class CustomSession(BaseSession):
async def close(self):
pass
async def make_request(self, token: str, method: TelegramMethod[T]) -> None: # type: ignore
async def make_request(self, token: str, method: TelegramMethod[T], timeout: Optional[int] = UNSET) -> None: # type: ignore
assert isinstance(token, str)
assert isinstance(method, TelegramMethod)

View file

@ -7,12 +7,7 @@ user = User(id=42, is_bot=False, first_name="User", last_name=None)
class TestChatMember:
@pytest.mark.parametrize(
"status,result",
[
["administrator", True],
["creator", True],
["member", False]
]
"status,result", [["administrator", True], ["creator", True], ["member", False]]
)
def test_is_chat_admin(self, status: str, result: bool):
chat_member = ChatMember(user=user, status=status)
@ -26,8 +21,8 @@ class TestChatMember:
["member", True],
["restricted", True],
["kicked", False],
["left", False]
]
["left", False],
],
)
def test_is_chat_member(self, status: str, result: bool):
chat_member = ChatMember(user=user, status=status)