mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-12-28 07:20:17 +01:00
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com> Co-authored-by: Luca Bellanti <luca.bellanti@gmail.com> Co-authored-by: thefunkycat <104379699+thefunkycat@users.noreply.github.com> Co-authored-by: Aditya Yadav <69784758+clot27@users.noreply.github.com> Co-authored-by: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com>
This commit is contained in:
parent
58b89cf0e9
commit
fb86bb3417
78 changed files with 421 additions and 322 deletions
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
|||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11']
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
|
@ -98,7 +98,7 @@ jobs:
|
|||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: [3.11]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
|
|
|
@ -67,7 +67,7 @@ repos:
|
|||
- id: pyupgrade
|
||||
files: ^(telegram|examples|tests|docs)/.*\.py$
|
||||
args:
|
||||
- --py37-plus
|
||||
- --py38-plus
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
|
|
|
@ -24,6 +24,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
|||
- `Abshar <https://github.com/abxhr>`_
|
||||
- `Alateas <https://github.com/alateas>`_
|
||||
- `Ales Dokshanin <https://github.com/alesdokshanin>`_
|
||||
- `Alizia <https://github.com/thefunkycat>`_
|
||||
- `Ambro17 <https://github.com/Ambro17>`_
|
||||
- `Andrej Zhilenkov <https://github.com/Andrej730>`_
|
||||
- `Anton Tagunov <https://github.com/anton-tagunov>`_
|
||||
|
|
|
@ -77,7 +77,7 @@ Introduction
|
|||
|
||||
This library provides a pure Python, asynchronous interface for the
|
||||
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
|
||||
It's compatible with Python versions **3.7+**.
|
||||
It's compatible with Python versions **3.8+**.
|
||||
|
||||
In addition to the pure API implementation, this library features a number of high-level classes to
|
||||
make the development of bots easy and straightforward. These classes are contained in the
|
||||
|
|
|
@ -77,7 +77,7 @@ Introduction
|
|||
|
||||
This library provides a pure Python, asynchronous interface for the
|
||||
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
|
||||
It's compatible with Python versions **3.7+**.
|
||||
It's compatible with Python versions **3.8+**.
|
||||
|
||||
``python-telegram-bot-raw`` is part of the `python-telegram-bot <https://python-telegram-bot.org>`_ ecosystem and provides the pure API functionality extracted from PTB. It therefore does not have independent release schedules, changelogs or documentation.
|
||||
|
||||
|
|
|
@ -174,8 +174,7 @@ class AdmonitionInserter:
|
|||
break
|
||||
|
||||
for line in lines_with_attrs:
|
||||
line_match = attr_docstr_pattern.match(line)
|
||||
if not line_match:
|
||||
if not (line_match := attr_docstr_pattern.match(line)):
|
||||
continue
|
||||
|
||||
target_attr = line_match.group("attr_name")
|
||||
|
@ -529,7 +528,11 @@ class AdmonitionInserter:
|
|||
# For custom generics like telegram.ext._application.Application[~BT, ~CCT, ~UD...].
|
||||
# This must come before the check for isinstance(type) because GenericAlias can also be
|
||||
# recognized as type if it belongs to <class 'types.GenericAlias'>.
|
||||
elif str(type(arg)) in ("<class 'typing._GenericAlias'>", "<class 'types.GenericAlias'>"):
|
||||
elif str(type(arg)) in (
|
||||
"<class 'typing._GenericAlias'>",
|
||||
"<class 'types.GenericAlias'>",
|
||||
"<class 'typing._LiteralGenericAlias'>",
|
||||
):
|
||||
if "telegram" in str(arg):
|
||||
# get_origin() of telegram.ext._application.Application[~BT, ~CCT, ~UD...]
|
||||
# will produce <class 'telegram.ext._application.Application'>
|
||||
|
|
|
@ -189,8 +189,10 @@ def autodoc_process_bases(app, name, obj, option, bases: list):
|
|||
bases[idx] = f":class:`{base}`"
|
||||
|
||||
# Now convert `telegram._message.Message` to `telegram.Message` etc
|
||||
match = re.search(pattern=r"(telegram(\.ext|))\.[_\w\.]+", string=base)
|
||||
if not match or "_utils" in base:
|
||||
if (
|
||||
not (match := re.search(pattern=r"(telegram(\.ext|))\.[_\w\.]+", string=base))
|
||||
or "_utils" in base
|
||||
):
|
||||
continue
|
||||
|
||||
parts = match.group(0).split(".")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.black]
|
||||
line-length = 99
|
||||
target-version = ['py37', 'py38', 'py39', 'py310', 'py311']
|
||||
target-version = ['py38', 'py39', 'py310', 'py311']
|
||||
|
||||
[tool.isort] # black config
|
||||
profile = "black"
|
||||
|
@ -8,7 +8,7 @@ line_length = 99
|
|||
|
||||
[tool.ruff]
|
||||
line-length = 99
|
||||
target-version = "py37"
|
||||
target-version = "py38"
|
||||
show-fixes = true
|
||||
ignore = ["PLR2004", "PLR0911", "PLR0912", "PLR0913", "PLR0915"]
|
||||
select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET", "RSE",
|
||||
|
|
3
setup.py
3
setup.py
|
@ -105,13 +105,12 @@ def get_setup_kwargs(raw=False):
|
|||
"Topic :: Internet",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
],
|
||||
python_requires=">=3.7",
|
||||
python_requires=">=3.8",
|
||||
)
|
||||
|
||||
return kwargs
|
||||
|
|
|
@ -96,7 +96,14 @@ from telegram._utils.argumentparsing import parse_sequence_arg
|
|||
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||
from telegram._utils.files import is_local_file, parse_file_input
|
||||
from telegram._utils.logging import get_logger
|
||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||
from telegram._utils.types import (
|
||||
CorrectOptionID,
|
||||
DVInput,
|
||||
FileInput,
|
||||
JSONDict,
|
||||
ODVInput,
|
||||
ReplyMarkup,
|
||||
)
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._utils.warnings_transition import warn_about_thumb_return_thumbnail
|
||||
from telegram._webhookinfo import WebhookInfo
|
||||
|
@ -6602,7 +6609,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
|||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None, # pylint: disable=redefined-builtin
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
correct_option_id: Optional[int] = None,
|
||||
correct_option_id: Optional[CorrectOptionID] = None,
|
||||
is_closed: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Bot Command."""
|
||||
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -61,22 +61,22 @@ class BotCommand(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
MIN_COMMAND: ClassVar[int] = constants.BotCommandLimit.MIN_COMMAND
|
||||
MIN_COMMAND: Final[int] = constants.BotCommandLimit.MIN_COMMAND
|
||||
""":const:`telegram.constants.BotCommandLimit.MIN_COMMAND`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_COMMAND: ClassVar[int] = constants.BotCommandLimit.MAX_COMMAND
|
||||
MAX_COMMAND: Final[int] = constants.BotCommandLimit.MAX_COMMAND
|
||||
""":const:`telegram.constants.BotCommandLimit.MAX_COMMAND`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_DESCRIPTION: ClassVar[int] = constants.BotCommandLimit.MIN_DESCRIPTION
|
||||
MIN_DESCRIPTION: Final[int] = constants.BotCommandLimit.MIN_DESCRIPTION
|
||||
""":const:`telegram.constants.BotCommandLimit.MIN_DESCRIPTION`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_DESCRIPTION: ClassVar[int] = constants.BotCommandLimit.MAX_DESCRIPTION
|
||||
MAX_DESCRIPTION: Final[int] = constants.BotCommandLimit.MAX_DESCRIPTION
|
||||
""":const:`telegram.constants.BotCommandLimit.MAX_DESCRIPTION`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=redefined-builtin
|
||||
"""This module contains objects representing Telegram bot command scopes."""
|
||||
from typing import TYPE_CHECKING, ClassVar, Dict, Optional, Type, Union
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -60,19 +60,19 @@ class BotCommandScope(TelegramObject):
|
|||
|
||||
__slots__ = ("type",)
|
||||
|
||||
DEFAULT: ClassVar[str] = constants.BotCommandScopeType.DEFAULT
|
||||
DEFAULT: Final[str] = constants.BotCommandScopeType.DEFAULT
|
||||
""":const:`telegram.constants.BotCommandScopeType.DEFAULT`"""
|
||||
ALL_PRIVATE_CHATS: ClassVar[str] = constants.BotCommandScopeType.ALL_PRIVATE_CHATS
|
||||
ALL_PRIVATE_CHATS: Final[str] = constants.BotCommandScopeType.ALL_PRIVATE_CHATS
|
||||
""":const:`telegram.constants.BotCommandScopeType.ALL_PRIVATE_CHATS`"""
|
||||
ALL_GROUP_CHATS: ClassVar[str] = constants.BotCommandScopeType.ALL_GROUP_CHATS
|
||||
ALL_GROUP_CHATS: Final[str] = constants.BotCommandScopeType.ALL_GROUP_CHATS
|
||||
""":const:`telegram.constants.BotCommandScopeType.ALL_GROUP_CHATS`"""
|
||||
ALL_CHAT_ADMINISTRATORS: ClassVar[str] = constants.BotCommandScopeType.ALL_CHAT_ADMINISTRATORS
|
||||
ALL_CHAT_ADMINISTRATORS: Final[str] = constants.BotCommandScopeType.ALL_CHAT_ADMINISTRATORS
|
||||
""":const:`telegram.constants.BotCommandScopeType.ALL_CHAT_ADMINISTRATORS`"""
|
||||
CHAT: ClassVar[str] = constants.BotCommandScopeType.CHAT
|
||||
CHAT: Final[str] = constants.BotCommandScopeType.CHAT
|
||||
""":const:`telegram.constants.BotCommandScopeType.CHAT`"""
|
||||
CHAT_ADMINISTRATORS: ClassVar[str] = constants.BotCommandScopeType.CHAT_ADMINISTRATORS
|
||||
CHAT_ADMINISTRATORS: Final[str] = constants.BotCommandScopeType.CHAT_ADMINISTRATORS
|
||||
""":const:`telegram.constants.BotCommandScopeType.CHAT_ADMINISTRATORS`"""
|
||||
CHAT_MEMBER: ClassVar[str] = constants.BotCommandScopeType.CHAT_MEMBER
|
||||
CHAT_MEMBER: Final[str] = constants.BotCommandScopeType.CHAT_MEMBER
|
||||
""":const:`telegram.constants.BotCommandScopeType.CHAT_MEMBER`"""
|
||||
|
||||
def __init__(self, type: str, *, api_kwargs: Optional[JSONDict] = None):
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represent a Telegram bots name."""
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -50,5 +50,5 @@ class BotName(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
MAX_LENGTH: ClassVar[int] = constants.BotNameLimit.MAX_NAME_LENGTH
|
||||
MAX_LENGTH: Final[int] = constants.BotNameLimit.MAX_NAME_LENGTH
|
||||
""":const:`telegram.constants.BotNameLimit.MAX_NAME_LENGTH`"""
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=redefined-builtin
|
||||
"""This module contains an object that represents a Telegram CallbackQuery"""
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional, Sequence, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.location import Location
|
||||
|
@ -771,7 +771,7 @@ class CallbackQuery(TelegramObject):
|
|||
message_thread_id=message_thread_id,
|
||||
)
|
||||
|
||||
MAX_ANSWER_TEXT_LENGTH: ClassVar[
|
||||
MAX_ANSWER_TEXT_LENGTH: Final[
|
||||
int
|
||||
] = constants.CallbackQueryLimit.ANSWER_CALLBACK_QUERY_TEXT_LENGTH
|
||||
"""
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"""This module contains an object that represents a Telegram Chat."""
|
||||
from datetime import datetime
|
||||
from html import escape
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional, Sequence, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._chatlocation import ChatLocation
|
||||
|
@ -32,7 +32,14 @@ from telegram._telegramobject import TelegramObject
|
|||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||
from telegram._utils.types import (
|
||||
CorrectOptionID,
|
||||
DVInput,
|
||||
FileInput,
|
||||
JSONDict,
|
||||
ODVInput,
|
||||
ReplyMarkup,
|
||||
)
|
||||
from telegram.helpers import escape_markdown
|
||||
from telegram.helpers import mention_html as helpers_mention_html
|
||||
from telegram.helpers import mention_markdown as helpers_mention_markdown
|
||||
|
@ -303,18 +310,18 @@ class Chat(TelegramObject):
|
|||
"has_aggressive_anti_spam_enabled",
|
||||
)
|
||||
|
||||
SENDER: ClassVar[str] = constants.ChatType.SENDER
|
||||
SENDER: Final[str] = constants.ChatType.SENDER
|
||||
""":const:`telegram.constants.ChatType.SENDER`
|
||||
|
||||
.. versionadded:: 13.5
|
||||
"""
|
||||
PRIVATE: ClassVar[str] = constants.ChatType.PRIVATE
|
||||
PRIVATE: Final[str] = constants.ChatType.PRIVATE
|
||||
""":const:`telegram.constants.ChatType.PRIVATE`"""
|
||||
GROUP: ClassVar[str] = constants.ChatType.GROUP
|
||||
GROUP: Final[str] = constants.ChatType.GROUP
|
||||
""":const:`telegram.constants.ChatType.GROUP`"""
|
||||
SUPERGROUP: ClassVar[str] = constants.ChatType.SUPERGROUP
|
||||
SUPERGROUP: Final[str] = constants.ChatType.SUPERGROUP
|
||||
""":const:`telegram.constants.ChatType.SUPERGROUP`"""
|
||||
CHANNEL: ClassVar[str] = constants.ChatType.CHANNEL
|
||||
CHANNEL: Final[str] = constants.ChatType.CHANNEL
|
||||
""":const:`telegram.constants.ChatType.CHANNEL`"""
|
||||
|
||||
def __init__(
|
||||
|
@ -2201,7 +2208,7 @@ class Chat(TelegramObject):
|
|||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None,
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
correct_option_id: Optional[int] = None,
|
||||
correct_option_id: Optional[CorrectOptionID] = None,
|
||||
is_closed: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a location to which a chat is connected."""
|
||||
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.location import Location
|
||||
|
@ -79,12 +79,12 @@ class ChatLocation(TelegramObject):
|
|||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
MIN_ADDRESS: ClassVar[int] = constants.LocationLimit.MIN_CHAT_LOCATION_ADDRESS
|
||||
MIN_ADDRESS: Final[int] = constants.LocationLimit.MIN_CHAT_LOCATION_ADDRESS
|
||||
""":const:`telegram.constants.LocationLimit.MIN_CHAT_LOCATION_ADDRESS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_ADDRESS: ClassVar[int] = constants.LocationLimit.MAX_CHAT_LOCATION_ADDRESS
|
||||
MAX_ADDRESS: Final[int] = constants.LocationLimit.MAX_CHAT_LOCATION_ADDRESS
|
||||
""":const:`telegram.constants.LocationLimit.MAX_CHAT_LOCATION_ADDRESS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatMember."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, ClassVar, Dict, Optional, Type
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -74,17 +74,17 @@ class ChatMember(TelegramObject):
|
|||
|
||||
__slots__ = ("user", "status")
|
||||
|
||||
ADMINISTRATOR: ClassVar[str] = constants.ChatMemberStatus.ADMINISTRATOR
|
||||
ADMINISTRATOR: Final[str] = constants.ChatMemberStatus.ADMINISTRATOR
|
||||
""":const:`telegram.constants.ChatMemberStatus.ADMINISTRATOR`"""
|
||||
OWNER: ClassVar[str] = constants.ChatMemberStatus.OWNER
|
||||
OWNER: Final[str] = constants.ChatMemberStatus.OWNER
|
||||
""":const:`telegram.constants.ChatMemberStatus.OWNER`"""
|
||||
BANNED: ClassVar[str] = constants.ChatMemberStatus.BANNED
|
||||
BANNED: Final[str] = constants.ChatMemberStatus.BANNED
|
||||
""":const:`telegram.constants.ChatMemberStatus.BANNED`"""
|
||||
LEFT: ClassVar[str] = constants.ChatMemberStatus.LEFT
|
||||
LEFT: Final[str] = constants.ChatMemberStatus.LEFT
|
||||
""":const:`telegram.constants.ChatMemberStatus.LEFT`"""
|
||||
MEMBER: ClassVar[str] = constants.ChatMemberStatus.MEMBER
|
||||
MEMBER: Final[str] = constants.ChatMemberStatus.MEMBER
|
||||
""":const:`telegram.constants.ChatMemberStatus.MEMBER`"""
|
||||
RESTRICTED: ClassVar[str] = constants.ChatMemberStatus.RESTRICTED
|
||||
RESTRICTED: Final[str] = constants.ChatMemberStatus.RESTRICTED
|
||||
""":const:`telegram.constants.ChatMemberStatus.RESTRICTED`"""
|
||||
|
||||
def __init__(
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Dice."""
|
||||
from typing import ClassVar, List, Optional
|
||||
from typing import Final, List, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -98,62 +98,62 @@ class Dice(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
DICE: ClassVar[str] = constants.DiceEmoji.DICE # skipcq: PTC-W0052
|
||||
DICE: Final[str] = constants.DiceEmoji.DICE # skipcq: PTC-W0052
|
||||
""":const:`telegram.constants.DiceEmoji.DICE`"""
|
||||
DARTS: ClassVar[str] = constants.DiceEmoji.DARTS
|
||||
DARTS: Final[str] = constants.DiceEmoji.DARTS
|
||||
""":const:`telegram.constants.DiceEmoji.DARTS`"""
|
||||
BASKETBALL: ClassVar[str] = constants.DiceEmoji.BASKETBALL
|
||||
BASKETBALL: Final[str] = constants.DiceEmoji.BASKETBALL
|
||||
""":const:`telegram.constants.DiceEmoji.BASKETBALL`"""
|
||||
FOOTBALL: ClassVar[str] = constants.DiceEmoji.FOOTBALL
|
||||
FOOTBALL: Final[str] = constants.DiceEmoji.FOOTBALL
|
||||
""":const:`telegram.constants.DiceEmoji.FOOTBALL`"""
|
||||
SLOT_MACHINE: ClassVar[str] = constants.DiceEmoji.SLOT_MACHINE
|
||||
SLOT_MACHINE: Final[str] = constants.DiceEmoji.SLOT_MACHINE
|
||||
""":const:`telegram.constants.DiceEmoji.SLOT_MACHINE`"""
|
||||
BOWLING: ClassVar[str] = constants.DiceEmoji.BOWLING
|
||||
BOWLING: Final[str] = constants.DiceEmoji.BOWLING
|
||||
"""
|
||||
:const:`telegram.constants.DiceEmoji.BOWLING`
|
||||
|
||||
.. versionadded:: 13.4
|
||||
"""
|
||||
ALL_EMOJI: ClassVar[List[str]] = list(constants.DiceEmoji)
|
||||
ALL_EMOJI: Final[List[str]] = list(constants.DiceEmoji)
|
||||
"""List[:obj:`str`]: A list of all available dice emoji."""
|
||||
|
||||
MIN_VALUE: ClassVar[int] = constants.DiceLimit.MIN_VALUE
|
||||
MIN_VALUE: Final[int] = constants.DiceLimit.MIN_VALUE
|
||||
""":const:`telegram.constants.DiceLimit.MIN_VALUE`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
|
||||
MAX_VALUE_BOWLING: ClassVar[int] = constants.DiceLimit.MAX_VALUE_BOWLING
|
||||
MAX_VALUE_BOWLING: Final[int] = constants.DiceLimit.MAX_VALUE_BOWLING
|
||||
""":const:`telegram.constants.DiceLimit.MAX_VALUE_BOWLING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
|
||||
MAX_VALUE_DARTS: ClassVar[int] = constants.DiceLimit.MAX_VALUE_DARTS
|
||||
MAX_VALUE_DARTS: Final[int] = constants.DiceLimit.MAX_VALUE_DARTS
|
||||
""":const:`telegram.constants.DiceLimit.MAX_VALUE_DARTS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
|
||||
MAX_VALUE_DICE: ClassVar[int] = constants.DiceLimit.MAX_VALUE_DICE
|
||||
MAX_VALUE_DICE: Final[int] = constants.DiceLimit.MAX_VALUE_DICE
|
||||
""":const:`telegram.constants.DiceLimit.MAX_VALUE_DICE`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
|
||||
MAX_VALUE_BASKETBALL: ClassVar[int] = constants.DiceLimit.MAX_VALUE_BASKETBALL
|
||||
MAX_VALUE_BASKETBALL: Final[int] = constants.DiceLimit.MAX_VALUE_BASKETBALL
|
||||
""":const:`telegram.constants.DiceLimit.MAX_VALUE_BASKETBALL`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
|
||||
MAX_VALUE_FOOTBALL: ClassVar[int] = constants.DiceLimit.MAX_VALUE_FOOTBALL
|
||||
MAX_VALUE_FOOTBALL: Final[int] = constants.DiceLimit.MAX_VALUE_FOOTBALL
|
||||
""":const:`telegram.constants.DiceLimit.MAX_VALUE_FOOTBALL`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
|
||||
MAX_VALUE_SLOT_MACHINE: ClassVar[int] = constants.DiceLimit.MAX_VALUE_SLOT_MACHINE
|
||||
MAX_VALUE_SLOT_MACHINE: Final[int] = constants.DiceLimit.MAX_VALUE_SLOT_MACHINE
|
||||
""":const:`telegram.constants.DiceLimit.MAX_VALUE_SLOT_MACHINE`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatPhoto."""
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -164,12 +164,12 @@ class ChatPhoto(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
SIZE_SMALL: ClassVar[int] = constants.ChatPhotoSize.SMALL
|
||||
SIZE_SMALL: Final[int] = constants.ChatPhotoSize.SMALL
|
||||
""":const:`telegram.constants.ChatPhotoSize.SMALL`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
SIZE_BIG: ClassVar[int] = constants.ChatPhotoSize.BIG
|
||||
SIZE_BIG: Final[int] = constants.ChatPhotoSize.BIG
|
||||
""":const:`telegram.constants.ChatPhotoSize.BIG`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Location."""
|
||||
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -96,17 +96,17 @@ class Location(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
HORIZONTAL_ACCURACY: ClassVar[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
HORIZONTAL_ACCURACY: Final[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_HEADING: ClassVar[int] = constants.LocationLimit.MIN_HEADING
|
||||
MIN_HEADING: Final[int] = constants.LocationLimit.MIN_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MIN_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_HEADING: ClassVar[int] = constants.LocationLimit.MAX_HEADING
|
||||
MAX_HEADING: Final[int] = constants.LocationLimit.MAX_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MAX_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects that represent stickers."""
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional, Sequence, Tuple
|
||||
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
|
@ -192,11 +192,11 @@ class Sticker(_BaseThumbedMedium):
|
|||
self.custom_emoji_id: Optional[str] = custom_emoji_id
|
||||
self.needs_repainting: Optional[bool] = needs_repainting
|
||||
|
||||
REGULAR: ClassVar[str] = constants.StickerType.REGULAR
|
||||
REGULAR: Final[str] = constants.StickerType.REGULAR
|
||||
""":const:`telegram.constants.StickerType.REGULAR`"""
|
||||
MASK: ClassVar[str] = constants.StickerType.MASK
|
||||
MASK: Final[str] = constants.StickerType.MASK
|
||||
""":const:`telegram.constants.StickerType.MASK`"""
|
||||
CUSTOM_EMOJI: ClassVar[str] = constants.StickerType.CUSTOM_EMOJI
|
||||
CUSTOM_EMOJI: Final[str] = constants.StickerType.CUSTOM_EMOJI
|
||||
""":const:`telegram.constants.StickerType.CUSTOM_EMOJI`"""
|
||||
|
||||
@classmethod
|
||||
|
@ -390,13 +390,13 @@ class MaskPosition(TelegramObject):
|
|||
|
||||
__slots__ = ("point", "scale", "x_shift", "y_shift")
|
||||
|
||||
FOREHEAD: ClassVar[str] = constants.MaskPosition.FOREHEAD
|
||||
FOREHEAD: Final[str] = constants.MaskPosition.FOREHEAD
|
||||
""":const:`telegram.constants.MaskPosition.FOREHEAD`"""
|
||||
EYES: ClassVar[str] = constants.MaskPosition.EYES
|
||||
EYES: Final[str] = constants.MaskPosition.EYES
|
||||
""":const:`telegram.constants.MaskPosition.EYES`"""
|
||||
MOUTH: ClassVar[str] = constants.MaskPosition.MOUTH
|
||||
MOUTH: Final[str] = constants.MaskPosition.MOUTH
|
||||
""":const:`telegram.constants.MaskPosition.MOUTH`"""
|
||||
CHIN: ClassVar[str] = constants.MaskPosition.CHIN
|
||||
CHIN: Final[str] = constants.MaskPosition.CHIN
|
||||
""":const:`telegram.constants.MaskPosition.CHIN`"""
|
||||
|
||||
def __init__(
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ForceReply."""
|
||||
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -93,12 +93,12 @@ class ForceReply(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
MIN_INPUT_FIELD_PLACEHOLDER: ClassVar[int] = constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER
|
||||
MIN_INPUT_FIELD_PLACEHOLDER: Final[int] = constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER
|
||||
""":const:`telegram.constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_INPUT_FIELD_PLACEHOLDER: ClassVar[int] = constants.ReplyLimit.MAX_INPUT_FIELD_PLACEHOLDER
|
||||
MAX_INPUT_FIELD_PLACEHOLDER: Final[int] = constants.ReplyLimit.MAX_INPUT_FIELD_PLACEHOLDER
|
||||
""":const:`telegram.constants.ReplyLimit.MAX_INPUT_FIELD_PLACEHOLDER`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InlineKeyboardButton."""
|
||||
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional, Union
|
||||
from typing import TYPE_CHECKING, Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._games.callbackgame import CallbackGame
|
||||
|
@ -297,12 +297,12 @@ class InlineKeyboardButton(TelegramObject):
|
|||
self.callback_data = callback_data
|
||||
self._set_id_attrs()
|
||||
|
||||
MIN_CALLBACK_DATA: ClassVar[int] = constants.InlineKeyboardButtonLimit.MIN_CALLBACK_DATA
|
||||
MIN_CALLBACK_DATA: Final[int] = constants.InlineKeyboardButtonLimit.MIN_CALLBACK_DATA
|
||||
""":const:`telegram.constants.InlineKeyboardButtonLimit.MIN_CALLBACK_DATA`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_CALLBACK_DATA: ClassVar[int] = constants.InlineKeyboardButtonLimit.MAX_CALLBACK_DATA
|
||||
MAX_CALLBACK_DATA: Final[int] = constants.InlineKeyboardButtonLimit.MAX_CALLBACK_DATA
|
||||
""":const:`telegram.constants.InlineKeyboardButtonLimit.MAX_CALLBACK_DATA`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InlineQuery."""
|
||||
|
||||
from typing import TYPE_CHECKING, Callable, ClassVar, Optional, Sequence, Union
|
||||
from typing import TYPE_CHECKING, Callable, Final, Optional, Sequence, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.location import Location
|
||||
|
@ -202,27 +202,27 @@ class InlineQuery(TelegramObject):
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
MAX_RESULTS: ClassVar[int] = constants.InlineQueryLimit.RESULTS
|
||||
MAX_RESULTS: Final[int] = constants.InlineQueryLimit.RESULTS
|
||||
""":const:`telegram.constants.InlineQueryLimit.RESULTS`
|
||||
|
||||
.. versionadded:: 13.2
|
||||
"""
|
||||
MIN_SWITCH_PM_TEXT_LENGTH: ClassVar[int] = constants.InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH
|
||||
MIN_SWITCH_PM_TEXT_LENGTH: Final[int] = constants.InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_SWITCH_PM_TEXT_LENGTH: ClassVar[int] = constants.InlineQueryLimit.MAX_SWITCH_PM_TEXT_LENGTH
|
||||
MAX_SWITCH_PM_TEXT_LENGTH: Final[int] = constants.InlineQueryLimit.MAX_SWITCH_PM_TEXT_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryLimit.MAX_SWITCH_PM_TEXT_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_OFFSET_LENGTH: ClassVar[int] = constants.InlineQueryLimit.MAX_OFFSET_LENGTH
|
||||
MAX_OFFSET_LENGTH: Final[int] = constants.InlineQueryLimit.MAX_OFFSET_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryLimit.MAX_OFFSET_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_QUERY_LENGTH: ClassVar[int] = constants.InlineQueryLimit.MAX_QUERY_LENGTH
|
||||
MAX_QUERY_LENGTH: Final[int] = constants.InlineQueryLimit.MAX_QUERY_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryLimit.MAX_QUERY_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# pylint: disable=redefined-builtin
|
||||
"""This module contains the classes that represent Telegram InlineQueryResult."""
|
||||
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -66,12 +66,12 @@ class InlineQueryResult(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
MIN_ID_LENGTH: ClassVar[int] = constants.InlineQueryResultLimit.MIN_ID_LENGTH
|
||||
MIN_ID_LENGTH: Final[int] = constants.InlineQueryResultLimit.MIN_ID_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryResultLimit.MIN_ID_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_ID_LENGTH: ClassVar[int] = constants.InlineQueryResultLimit.MAX_ID_LENGTH
|
||||
MAX_ID_LENGTH: Final[int] = constants.InlineQueryResultLimit.MAX_ID_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryResultLimit.MAX_ID_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultLocation."""
|
||||
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
|
@ -244,37 +244,37 @@ class InlineQueryResultLocation(InlineQueryResult):
|
|||
)
|
||||
return self.thumbnail_height
|
||||
|
||||
HORIZONTAL_ACCURACY: ClassVar[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
HORIZONTAL_ACCURACY: Final[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_HEADING: ClassVar[int] = constants.LocationLimit.MIN_HEADING
|
||||
MIN_HEADING: Final[int] = constants.LocationLimit.MIN_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MIN_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_HEADING: ClassVar[int] = constants.LocationLimit.MAX_HEADING
|
||||
MAX_HEADING: Final[int] = constants.LocationLimit.MAX_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MAX_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_LIVE_PERIOD: ClassVar[int] = constants.LocationLimit.MIN_LIVE_PERIOD
|
||||
MIN_LIVE_PERIOD: Final[int] = constants.LocationLimit.MIN_LIVE_PERIOD
|
||||
""":const:`telegram.constants.LocationLimit.MIN_LIVE_PERIOD`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_LIVE_PERIOD: ClassVar[int] = constants.LocationLimit.MAX_LIVE_PERIOD
|
||||
MAX_LIVE_PERIOD: Final[int] = constants.LocationLimit.MAX_LIVE_PERIOD
|
||||
""":const:`telegram.constants.LocationLimit.MAX_LIVE_PERIOD`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_PROXIMITY_ALERT_RADIUS: ClassVar[int] = constants.LocationLimit.MIN_PROXIMITY_ALERT_RADIUS
|
||||
MIN_PROXIMITY_ALERT_RADIUS: Final[int] = constants.LocationLimit.MIN_PROXIMITY_ALERT_RADIUS
|
||||
""":const:`telegram.constants.LocationLimit.MIN_PROXIMITY_ALERT_RADIUS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_PROXIMITY_ALERT_RADIUS: ClassVar[int] = constants.LocationLimit.MAX_PROXIMITY_ALERT_RADIUS
|
||||
MAX_PROXIMITY_ALERT_RADIUS: Final[int] = constants.LocationLimit.MAX_PROXIMITY_ALERT_RADIUS
|
||||
""":const:`telegram.constants.LocationLimit.MAX_PROXIMITY_ALERT_RADIUS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# pylint: disable=redefined-builtin
|
||||
"""This module contains the class that represent a Telegram InlineQueryResultsButton."""
|
||||
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -107,11 +107,11 @@ class InlineQueryResultsButton(TelegramObject):
|
|||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
MIN_START_PARAMETER_LENGTH: ClassVar[
|
||||
MIN_START_PARAMETER_LENGTH: Final[
|
||||
int
|
||||
] = constants.InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH`"""
|
||||
MAX_START_PARAMETER_LENGTH: ClassVar[
|
||||
MAX_START_PARAMETER_LENGTH: Final[
|
||||
int
|
||||
] = constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`"""
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InputLocationMessageContent."""
|
||||
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._inline.inputmessagecontent import InputMessageContent
|
||||
|
@ -106,37 +106,37 @@ class InputLocationMessageContent(InputMessageContent):
|
|||
|
||||
self._id_attrs = (self.latitude, self.longitude)
|
||||
|
||||
HORIZONTAL_ACCURACY: ClassVar[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
HORIZONTAL_ACCURACY: Final[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_HEADING: ClassVar[int] = constants.LocationLimit.MIN_HEADING
|
||||
MIN_HEADING: Final[int] = constants.LocationLimit.MIN_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MIN_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_HEADING: ClassVar[int] = constants.LocationLimit.MAX_HEADING
|
||||
MAX_HEADING: Final[int] = constants.LocationLimit.MAX_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MAX_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_LIVE_PERIOD: ClassVar[int] = constants.LocationLimit.MIN_LIVE_PERIOD
|
||||
MIN_LIVE_PERIOD: Final[int] = constants.LocationLimit.MIN_LIVE_PERIOD
|
||||
""":const:`telegram.constants.LocationLimit.MIN_LIVE_PERIOD`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_LIVE_PERIOD: ClassVar[int] = constants.LocationLimit.MAX_LIVE_PERIOD
|
||||
MAX_LIVE_PERIOD: Final[int] = constants.LocationLimit.MAX_LIVE_PERIOD
|
||||
""":const:`telegram.constants.LocationLimit.MAX_LIVE_PERIOD`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_PROXIMITY_ALERT_RADIUS: ClassVar[int] = constants.LocationLimit.MIN_PROXIMITY_ALERT_RADIUS
|
||||
MIN_PROXIMITY_ALERT_RADIUS: Final[int] = constants.LocationLimit.MIN_PROXIMITY_ALERT_RADIUS
|
||||
""":const:`telegram.constants.LocationLimit.MIN_PROXIMITY_ALERT_RADIUS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_PROXIMITY_ALERT_RADIUS: ClassVar[int] = constants.LocationLimit.MAX_PROXIMITY_ALERT_RADIUS
|
||||
MAX_PROXIMITY_ALERT_RADIUS: Final[int] = constants.LocationLimit.MAX_PROXIMITY_ALERT_RADIUS
|
||||
""":const:`telegram.constants.LocationLimit.MAX_PROXIMITY_ALERT_RADIUS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects related to Telegram menu buttons."""
|
||||
from typing import TYPE_CHECKING, ClassVar, Dict, Optional, Type
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -95,11 +95,11 @@ class MenuButton(TelegramObject):
|
|||
return _class_mapping[data.pop("type")].de_json(data, bot=bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
COMMANDS: ClassVar[str] = constants.MenuButtonType.COMMANDS
|
||||
COMMANDS: Final[str] = constants.MenuButtonType.COMMANDS
|
||||
""":const:`telegram.constants.MenuButtonType.COMMANDS`"""
|
||||
WEB_APP: ClassVar[str] = constants.MenuButtonType.WEB_APP
|
||||
WEB_APP: Final[str] = constants.MenuButtonType.WEB_APP
|
||||
""":const:`telegram.constants.MenuButtonType.WEB_APP`"""
|
||||
DEFAULT: ClassVar[str] = constants.MenuButtonType.DEFAULT
|
||||
DEFAULT: Final[str] = constants.MenuButtonType.DEFAULT
|
||||
""":const:`telegram.constants.MenuButtonType.DEFAULT`"""
|
||||
|
||||
|
||||
|
|
|
@ -58,7 +58,15 @@ from telegram._user import User
|
|||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||
from telegram._utils.types import (
|
||||
CorrectOptionID,
|
||||
DVInput,
|
||||
FileInput,
|
||||
JSONDict,
|
||||
MarkdownVersion,
|
||||
ODVInput,
|
||||
ReplyMarkup,
|
||||
)
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._videochat import (
|
||||
VideoChatEnded,
|
||||
|
@ -2023,7 +2031,7 @@ class Message(TelegramObject):
|
|||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None, # pylint: disable=redefined-builtin
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
correct_option_id: Optional[int] = None,
|
||||
correct_option_id: Optional[CorrectOptionID] = None,
|
||||
is_closed: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
@ -3442,10 +3450,10 @@ class Message(TelegramObject):
|
|||
message_text: Optional[str],
|
||||
entities: Dict[MessageEntity, str],
|
||||
urled: bool = False,
|
||||
version: int = 1,
|
||||
version: MarkdownVersion = 1,
|
||||
offset: int = 0,
|
||||
) -> Optional[str]:
|
||||
version = int(version)
|
||||
version = int(version) # type: ignore
|
||||
|
||||
if message_text is None:
|
||||
return None
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram MessageEntity."""
|
||||
|
||||
from typing import TYPE_CHECKING, ClassVar, List, Optional
|
||||
from typing import TYPE_CHECKING, Final, List, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -130,45 +130,45 @@ class MessageEntity(TelegramObject):
|
|||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
MENTION: ClassVar[str] = constants.MessageEntityType.MENTION
|
||||
MENTION: Final[str] = constants.MessageEntityType.MENTION
|
||||
""":const:`telegram.constants.MessageEntityType.MENTION`"""
|
||||
HASHTAG: ClassVar[str] = constants.MessageEntityType.HASHTAG
|
||||
HASHTAG: Final[str] = constants.MessageEntityType.HASHTAG
|
||||
""":const:`telegram.constants.MessageEntityType.HASHTAG`"""
|
||||
CASHTAG: ClassVar[str] = constants.MessageEntityType.CASHTAG
|
||||
CASHTAG: Final[str] = constants.MessageEntityType.CASHTAG
|
||||
""":const:`telegram.constants.MessageEntityType.CASHTAG`"""
|
||||
PHONE_NUMBER: ClassVar[str] = constants.MessageEntityType.PHONE_NUMBER
|
||||
PHONE_NUMBER: Final[str] = constants.MessageEntityType.PHONE_NUMBER
|
||||
""":const:`telegram.constants.MessageEntityType.PHONE_NUMBER`"""
|
||||
BOT_COMMAND: ClassVar[str] = constants.MessageEntityType.BOT_COMMAND
|
||||
BOT_COMMAND: Final[str] = constants.MessageEntityType.BOT_COMMAND
|
||||
""":const:`telegram.constants.MessageEntityType.BOT_COMMAND`"""
|
||||
URL: ClassVar[str] = constants.MessageEntityType.URL
|
||||
URL: Final[str] = constants.MessageEntityType.URL
|
||||
""":const:`telegram.constants.MessageEntityType.URL`"""
|
||||
EMAIL: ClassVar[str] = constants.MessageEntityType.EMAIL
|
||||
EMAIL: Final[str] = constants.MessageEntityType.EMAIL
|
||||
""":const:`telegram.constants.MessageEntityType.EMAIL`"""
|
||||
BOLD: ClassVar[str] = constants.MessageEntityType.BOLD
|
||||
BOLD: Final[str] = constants.MessageEntityType.BOLD
|
||||
""":const:`telegram.constants.MessageEntityType.BOLD`"""
|
||||
ITALIC: ClassVar[str] = constants.MessageEntityType.ITALIC
|
||||
ITALIC: Final[str] = constants.MessageEntityType.ITALIC
|
||||
""":const:`telegram.constants.MessageEntityType.ITALIC`"""
|
||||
CODE: ClassVar[str] = constants.MessageEntityType.CODE
|
||||
CODE: Final[str] = constants.MessageEntityType.CODE
|
||||
""":const:`telegram.constants.MessageEntityType.CODE`"""
|
||||
PRE: ClassVar[str] = constants.MessageEntityType.PRE
|
||||
PRE: Final[str] = constants.MessageEntityType.PRE
|
||||
""":const:`telegram.constants.MessageEntityType.PRE`"""
|
||||
TEXT_LINK: ClassVar[str] = constants.MessageEntityType.TEXT_LINK
|
||||
TEXT_LINK: Final[str] = constants.MessageEntityType.TEXT_LINK
|
||||
""":const:`telegram.constants.MessageEntityType.TEXT_LINK`"""
|
||||
TEXT_MENTION: ClassVar[str] = constants.MessageEntityType.TEXT_MENTION
|
||||
TEXT_MENTION: Final[str] = constants.MessageEntityType.TEXT_MENTION
|
||||
""":const:`telegram.constants.MessageEntityType.TEXT_MENTION`"""
|
||||
UNDERLINE: ClassVar[str] = constants.MessageEntityType.UNDERLINE
|
||||
UNDERLINE: Final[str] = constants.MessageEntityType.UNDERLINE
|
||||
""":const:`telegram.constants.MessageEntityType.UNDERLINE`"""
|
||||
STRIKETHROUGH: ClassVar[str] = constants.MessageEntityType.STRIKETHROUGH
|
||||
STRIKETHROUGH: Final[str] = constants.MessageEntityType.STRIKETHROUGH
|
||||
""":const:`telegram.constants.MessageEntityType.STRIKETHROUGH`"""
|
||||
SPOILER: ClassVar[str] = constants.MessageEntityType.SPOILER
|
||||
SPOILER: Final[str] = constants.MessageEntityType.SPOILER
|
||||
""":const:`telegram.constants.MessageEntityType.SPOILER`
|
||||
|
||||
.. versionadded:: 13.10
|
||||
"""
|
||||
CUSTOM_EMOJI: ClassVar[str] = constants.MessageEntityType.CUSTOM_EMOJI
|
||||
CUSTOM_EMOJI: Final[str] = constants.MessageEntityType.CUSTOM_EMOJI
|
||||
""":const:`telegram.constants.MessageEntityType.CUSTOM_EMOJI`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
ALL_TYPES: ClassVar[List[str]] = list(constants.MessageEntityType)
|
||||
ALL_TYPES: Final[List[str]] = list(constants.MessageEntityType)
|
||||
"""List[:obj:`str`]: A list of all available message entity types."""
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Invoice."""
|
||||
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -95,37 +95,37 @@ class Invoice(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
MIN_TITLE_LENGTH: ClassVar[int] = constants.InvoiceLimit.MIN_TITLE_LENGTH
|
||||
MIN_TITLE_LENGTH: Final[int] = constants.InvoiceLimit.MIN_TITLE_LENGTH
|
||||
""":const:`telegram.constants.InvoiceLimit.MIN_TITLE_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_TITLE_LENGTH: ClassVar[int] = constants.InvoiceLimit.MAX_TITLE_LENGTH
|
||||
MAX_TITLE_LENGTH: Final[int] = constants.InvoiceLimit.MAX_TITLE_LENGTH
|
||||
""":const:`telegram.constants.InvoiceLimit.MAX_TITLE_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_DESCRIPTION_LENGTH: ClassVar[int] = constants.InvoiceLimit.MIN_DESCRIPTION_LENGTH
|
||||
MIN_DESCRIPTION_LENGTH: Final[int] = constants.InvoiceLimit.MIN_DESCRIPTION_LENGTH
|
||||
""":const:`telegram.constants.InvoiceLimit.MIN_DESCRIPTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_DESCRIPTION_LENGTH: ClassVar[int] = constants.InvoiceLimit.MAX_DESCRIPTION_LENGTH
|
||||
MAX_DESCRIPTION_LENGTH: Final[int] = constants.InvoiceLimit.MAX_DESCRIPTION_LENGTH
|
||||
""":const:`telegram.constants.InvoiceLimit.MAX_DESCRIPTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_PAYLOAD_LENGTH: ClassVar[int] = constants.InvoiceLimit.MIN_PAYLOAD_LENGTH
|
||||
MIN_PAYLOAD_LENGTH: Final[int] = constants.InvoiceLimit.MIN_PAYLOAD_LENGTH
|
||||
""":const:`telegram.constants.InvoiceLimit.MIN_PAYLOAD_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_PAYLOAD_LENGTH: ClassVar[int] = constants.InvoiceLimit.MAX_PAYLOAD_LENGTH
|
||||
MAX_PAYLOAD_LENGTH: Final[int] = constants.InvoiceLimit.MAX_PAYLOAD_LENGTH
|
||||
""":const:`telegram.constants.InvoiceLimit.MAX_PAYLOAD_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_TIP_AMOUNTS: ClassVar[int] = constants.InvoiceLimit.MAX_TIP_AMOUNTS
|
||||
MAX_TIP_AMOUNTS: Final[int] = constants.InvoiceLimit.MAX_TIP_AMOUNTS
|
||||
""":const:`telegram.constants.InvoiceLimit.MAX_TIP_AMOUNTS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Poll."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, ClassVar, Dict, List, Optional, Sequence, Tuple
|
||||
from typing import TYPE_CHECKING, Dict, Final, List, Optional, Sequence, Tuple
|
||||
|
||||
from telegram import constants
|
||||
from telegram._messageentity import MessageEntity
|
||||
|
@ -65,12 +65,12 @@ class PollOption(TelegramObject):
|
|||
|
||||
self._freeze()
|
||||
|
||||
MIN_LENGTH: ClassVar[int] = constants.PollLimit.MIN_OPTION_LENGTH
|
||||
MIN_LENGTH: Final[int] = constants.PollLimit.MIN_OPTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MIN_OPTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_LENGTH: ClassVar[int] = constants.PollLimit.MAX_OPTION_LENGTH
|
||||
MAX_LENGTH: Final[int] = constants.PollLimit.MAX_OPTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MAX_OPTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
@ -350,56 +350,56 @@ class Poll(TelegramObject):
|
|||
if entity.type in types
|
||||
}
|
||||
|
||||
REGULAR: ClassVar[str] = constants.PollType.REGULAR
|
||||
REGULAR: Final[str] = constants.PollType.REGULAR
|
||||
""":const:`telegram.constants.PollType.REGULAR`"""
|
||||
QUIZ: ClassVar[str] = constants.PollType.QUIZ
|
||||
QUIZ: Final[str] = constants.PollType.QUIZ
|
||||
""":const:`telegram.constants.PollType.QUIZ`"""
|
||||
MAX_EXPLANATION_LENGTH: ClassVar[int] = constants.PollLimit.MAX_EXPLANATION_LENGTH
|
||||
MAX_EXPLANATION_LENGTH: Final[int] = constants.PollLimit.MAX_EXPLANATION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MAX_EXPLANATION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_EXPLANATION_LINE_FEEDS: ClassVar[int] = constants.PollLimit.MAX_EXPLANATION_LINE_FEEDS
|
||||
MAX_EXPLANATION_LINE_FEEDS: Final[int] = constants.PollLimit.MAX_EXPLANATION_LINE_FEEDS
|
||||
""":const:`telegram.constants.PollLimit.MAX_EXPLANATION_LINE_FEEDS`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_OPEN_PERIOD: ClassVar[int] = constants.PollLimit.MIN_OPEN_PERIOD
|
||||
MIN_OPEN_PERIOD: Final[int] = constants.PollLimit.MIN_OPEN_PERIOD
|
||||
""":const:`telegram.constants.PollLimit.MIN_OPEN_PERIOD`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_OPEN_PERIOD: ClassVar[int] = constants.PollLimit.MAX_OPEN_PERIOD
|
||||
MAX_OPEN_PERIOD: Final[int] = constants.PollLimit.MAX_OPEN_PERIOD
|
||||
""":const:`telegram.constants.PollLimit.MAX_OPEN_PERIOD`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_QUESTION_LENGTH: ClassVar[int] = constants.PollLimit.MIN_QUESTION_LENGTH
|
||||
MIN_QUESTION_LENGTH: Final[int] = constants.PollLimit.MIN_QUESTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MIN_QUESTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_QUESTION_LENGTH: ClassVar[int] = constants.PollLimit.MAX_QUESTION_LENGTH
|
||||
MAX_QUESTION_LENGTH: Final[int] = constants.PollLimit.MAX_QUESTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MAX_QUESTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_OPTION_LENGTH: ClassVar[int] = constants.PollLimit.MIN_OPTION_LENGTH
|
||||
MIN_OPTION_LENGTH: Final[int] = constants.PollLimit.MIN_OPTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MIN_OPTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_OPTION_LENGTH: ClassVar[int] = constants.PollLimit.MAX_OPTION_LENGTH
|
||||
MAX_OPTION_LENGTH: Final[int] = constants.PollLimit.MAX_OPTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MAX_OPTION_LENGTH`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_OPTION_NUMBER: ClassVar[int] = constants.PollLimit.MIN_OPTION_NUMBER
|
||||
MIN_OPTION_NUMBER: Final[int] = constants.PollLimit.MIN_OPTION_NUMBER
|
||||
""":const:`telegram.constants.PollLimit.MIN_OPTION_NUMBER`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_OPTION_NUMBER: ClassVar[int] = constants.PollLimit.MAX_OPTION_NUMBER
|
||||
MAX_OPTION_NUMBER: Final[int] = constants.PollLimit.MAX_OPTION_NUMBER
|
||||
""":const:`telegram.constants.PollLimit.MAX_OPTION_NUMBER`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ReplyKeyboardMarkup."""
|
||||
|
||||
from typing import ClassVar, Optional, Sequence, Tuple, Union
|
||||
from typing import Final, Optional, Sequence, Tuple, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._keyboardbutton import KeyboardButton
|
||||
|
@ -346,12 +346,12 @@ class ReplyKeyboardMarkup(TelegramObject):
|
|||
**kwargs, # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
MIN_INPUT_FIELD_PLACEHOLDER: ClassVar[int] = constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER
|
||||
MIN_INPUT_FIELD_PLACEHOLDER: Final[int] = constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER
|
||||
""":const:`telegram.constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_INPUT_FIELD_PLACEHOLDER: ClassVar[int] = constants.ReplyLimit.MAX_INPUT_FIELD_PLACEHOLDER
|
||||
MAX_INPUT_FIELD_PLACEHOLDER: Final[int] = constants.ReplyLimit.MAX_INPUT_FIELD_PLACEHOLDER
|
||||
""":const:`telegram.constants.ReplyLimit.MAX_INPUT_FIELD_PLACEHOLDER`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Update."""
|
||||
|
||||
from typing import TYPE_CHECKING, ClassVar, List, Optional
|
||||
from typing import TYPE_CHECKING, Final, List, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._callbackquery import CallbackQuery
|
||||
|
@ -171,63 +171,63 @@ class Update(TelegramObject):
|
|||
"chat_join_request",
|
||||
)
|
||||
|
||||
MESSAGE: ClassVar[str] = constants.UpdateType.MESSAGE
|
||||
MESSAGE: Final[str] = constants.UpdateType.MESSAGE
|
||||
""":const:`telegram.constants.UpdateType.MESSAGE`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
EDITED_MESSAGE: ClassVar[str] = constants.UpdateType.EDITED_MESSAGE
|
||||
EDITED_MESSAGE: Final[str] = constants.UpdateType.EDITED_MESSAGE
|
||||
""":const:`telegram.constants.UpdateType.EDITED_MESSAGE`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
CHANNEL_POST: ClassVar[str] = constants.UpdateType.CHANNEL_POST
|
||||
CHANNEL_POST: Final[str] = constants.UpdateType.CHANNEL_POST
|
||||
""":const:`telegram.constants.UpdateType.CHANNEL_POST`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
EDITED_CHANNEL_POST: ClassVar[str] = constants.UpdateType.EDITED_CHANNEL_POST
|
||||
EDITED_CHANNEL_POST: Final[str] = constants.UpdateType.EDITED_CHANNEL_POST
|
||||
""":const:`telegram.constants.UpdateType.EDITED_CHANNEL_POST`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
INLINE_QUERY: ClassVar[str] = constants.UpdateType.INLINE_QUERY
|
||||
INLINE_QUERY: Final[str] = constants.UpdateType.INLINE_QUERY
|
||||
""":const:`telegram.constants.UpdateType.INLINE_QUERY`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
CHOSEN_INLINE_RESULT: ClassVar[str] = constants.UpdateType.CHOSEN_INLINE_RESULT
|
||||
CHOSEN_INLINE_RESULT: Final[str] = constants.UpdateType.CHOSEN_INLINE_RESULT
|
||||
""":const:`telegram.constants.UpdateType.CHOSEN_INLINE_RESULT`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
CALLBACK_QUERY: ClassVar[str] = constants.UpdateType.CALLBACK_QUERY
|
||||
CALLBACK_QUERY: Final[str] = constants.UpdateType.CALLBACK_QUERY
|
||||
""":const:`telegram.constants.UpdateType.CALLBACK_QUERY`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
SHIPPING_QUERY: ClassVar[str] = constants.UpdateType.SHIPPING_QUERY
|
||||
SHIPPING_QUERY: Final[str] = constants.UpdateType.SHIPPING_QUERY
|
||||
""":const:`telegram.constants.UpdateType.SHIPPING_QUERY`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
PRE_CHECKOUT_QUERY: ClassVar[str] = constants.UpdateType.PRE_CHECKOUT_QUERY
|
||||
PRE_CHECKOUT_QUERY: Final[str] = constants.UpdateType.PRE_CHECKOUT_QUERY
|
||||
""":const:`telegram.constants.UpdateType.PRE_CHECKOUT_QUERY`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
POLL: ClassVar[str] = constants.UpdateType.POLL
|
||||
POLL: Final[str] = constants.UpdateType.POLL
|
||||
""":const:`telegram.constants.UpdateType.POLL`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
POLL_ANSWER: ClassVar[str] = constants.UpdateType.POLL_ANSWER
|
||||
POLL_ANSWER: Final[str] = constants.UpdateType.POLL_ANSWER
|
||||
""":const:`telegram.constants.UpdateType.POLL_ANSWER`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
MY_CHAT_MEMBER: ClassVar[str] = constants.UpdateType.MY_CHAT_MEMBER
|
||||
MY_CHAT_MEMBER: Final[str] = constants.UpdateType.MY_CHAT_MEMBER
|
||||
""":const:`telegram.constants.UpdateType.MY_CHAT_MEMBER`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
CHAT_MEMBER: ClassVar[str] = constants.UpdateType.CHAT_MEMBER
|
||||
CHAT_MEMBER: Final[str] = constants.UpdateType.CHAT_MEMBER
|
||||
""":const:`telegram.constants.UpdateType.CHAT_MEMBER`
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
CHAT_JOIN_REQUEST = constants.UpdateType.CHAT_JOIN_REQUEST
|
||||
CHAT_JOIN_REQUEST: Final[str] = constants.UpdateType.CHAT_JOIN_REQUEST
|
||||
""":const:`telegram.constants.UpdateType.CHAT_JOIN_REQUEST`
|
||||
|
||||
.. versionadded:: 13.8"""
|
||||
ALL_TYPES: ClassVar[List[str]] = list(constants.UpdateType)
|
||||
ALL_TYPES: Final[List[str]] = list(constants.UpdateType)
|
||||
"""List[:obj:`str`]: A list of all available update types.
|
||||
|
||||
.. versionadded:: 13.5"""
|
||||
|
|
|
@ -25,7 +25,14 @@ from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton
|
|||
from telegram._menubutton import MenuButton
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||
from telegram._utils.types import (
|
||||
CorrectOptionID,
|
||||
DVInput,
|
||||
FileInput,
|
||||
JSONDict,
|
||||
ODVInput,
|
||||
ReplyMarkup,
|
||||
)
|
||||
from telegram.helpers import mention_html as helpers_mention_html
|
||||
from telegram.helpers import mention_markdown as helpers_mention_markdown
|
||||
|
||||
|
@ -1349,7 +1356,7 @@ class User(TelegramObject):
|
|||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None,
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
correct_option_id: Optional[int] = None,
|
||||
correct_option_id: Optional[CorrectOptionID] = None,
|
||||
is_closed: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
|
|
@ -24,7 +24,18 @@ Warning:
|
|||
the changelog.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from typing import IO, TYPE_CHECKING, Any, Collection, Dict, Optional, Tuple, TypeVar, Union
|
||||
from typing import (
|
||||
IO,
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Collection,
|
||||
Dict,
|
||||
Literal,
|
||||
Optional,
|
||||
Tuple,
|
||||
TypeVar,
|
||||
Union,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import (
|
||||
|
@ -75,3 +86,12 @@ FieldTuple = Tuple[str, bytes, str]
|
|||
"""Alias for return type of `InputFile.field_tuple`."""
|
||||
UploadFileDict = Dict[str, FieldTuple]
|
||||
"""Dictionary containing file data to be uploaded to the API."""
|
||||
|
||||
HTTPVersion = Literal["1.1", "2.0"]
|
||||
"""Allowed HTTP versions.
|
||||
|
||||
.. versionadded:: NEXT.VERSION"""
|
||||
|
||||
CorrectOptionID = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
MarkdownVersion = Literal[1, 2]
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=missing-module-docstring
|
||||
from typing import NamedTuple
|
||||
from typing import Final, NamedTuple
|
||||
|
||||
__all__ = ("__version__", "__version_info__", "__bot_api_version__", "__bot_api_version_info__")
|
||||
|
||||
|
@ -50,8 +50,10 @@ class Version(NamedTuple):
|
|||
return version
|
||||
|
||||
|
||||
__version_info__ = Version(major=20, minor=3, micro=0, releaselevel="final", serial=0)
|
||||
__version__ = str(__version_info__)
|
||||
__version_info__: Final[Version] = Version(
|
||||
major=20, minor=3, micro=0, releaselevel="final", serial=0
|
||||
)
|
||||
__version__: Final[str] = str(__version_info__)
|
||||
|
||||
# # SETUP.PY MARKER
|
||||
# Lines above this line will be `exec`-cuted in setup.py. Make sure that this only contains
|
||||
|
@ -59,5 +61,7 @@ __version__ = str(__version_info__)
|
|||
|
||||
from telegram import constants # noqa: E402 # pylint: disable=wrong-import-position
|
||||
|
||||
__bot_api_version__ = constants.BOT_API_VERSION
|
||||
__bot_api_version_info__ = constants.BOT_API_VERSION_INFO
|
||||
__bot_api_version__: Final[str] = constants.BOT_API_VERSION
|
||||
__bot_api_version_info__: Final[
|
||||
constants._BotAPIVersion
|
||||
] = constants.BOT_API_VERSION_INFO # pylint: disable=protected-access
|
||||
|
|
|
@ -86,7 +86,7 @@ __all__ = [
|
|||
]
|
||||
|
||||
import sys
|
||||
from typing import List, NamedTuple
|
||||
from typing import Final, List, NamedTuple
|
||||
|
||||
from telegram._utils.enum import IntEnum, StringEnum
|
||||
|
||||
|
@ -116,19 +116,19 @@ class _BotAPIVersion(NamedTuple):
|
|||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO = _BotAPIVersion(major=6, minor=7)
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=6, minor=7)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
#:
|
||||
#: .. versionadded:: 13.4
|
||||
BOT_API_VERSION = str(BOT_API_VERSION_INFO)
|
||||
BOT_API_VERSION: Final[str] = str(BOT_API_VERSION_INFO)
|
||||
|
||||
# constants above this line are tested
|
||||
|
||||
#: List[:obj:`int`]: Ports supported by
|
||||
#: :paramref:`telegram.Bot.set_webhook.url`.
|
||||
SUPPORTED_WEBHOOK_PORTS: List[int] = [443, 80, 88, 8443]
|
||||
SUPPORTED_WEBHOOK_PORTS: Final[List[int]] = [443, 80, 88, 8443]
|
||||
|
||||
|
||||
class BotCommandLimit(IntEnum):
|
||||
|
|
|
@ -568,9 +568,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
try:
|
||||
if self.persistence:
|
||||
self.__update_persistence_task = asyncio.create_task(
|
||||
self._persistence_updater()
|
||||
# TODO: Add this once we drop py3.7
|
||||
# name=f'Application:{self.bot.id}:persistence_updater'
|
||||
self._persistence_updater(),
|
||||
name=f"Application:{self.bot.id}:persistence_updater",
|
||||
)
|
||||
_LOGGER.debug("Loop for updating persistence started")
|
||||
|
||||
|
@ -579,9 +578,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
_LOGGER.debug("JobQueue started")
|
||||
|
||||
self.__update_fetcher_task = asyncio.create_task(
|
||||
self._update_fetcher(),
|
||||
# TODO: Add this once we drop py3.7
|
||||
# name=f'Application:{self.bot.id}:update_fetcher'
|
||||
self._update_fetcher(), name=f"Application:{self.bot.id}:update_fetcher"
|
||||
)
|
||||
_LOGGER.info("Application started")
|
||||
|
||||
|
@ -955,6 +952,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
self,
|
||||
coroutine: Union[Generator[Optional["asyncio.Future[object]"], None, RT], Awaitable[RT]],
|
||||
update: Optional[object] = None,
|
||||
*,
|
||||
name: Optional[str] = None,
|
||||
) -> "asyncio.Task[RT]":
|
||||
"""Thin wrapper around :func:`asyncio.create_task` that handles exceptions raised by
|
||||
the :paramref:`coroutine` with :meth:`process_error`.
|
||||
|
@ -977,16 +976,22 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
:attr:`chat_data` and :attr:`user_data` entries will be updated in the next run of
|
||||
:meth:`update_persistence` after the :paramref:`coroutine` is finished.
|
||||
|
||||
Keyword Args:
|
||||
name (:obj:`str`, optional): The name of the task.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Returns:
|
||||
:class:`asyncio.Task`: The created task.
|
||||
"""
|
||||
return self.__create_task(coroutine=coroutine, update=update)
|
||||
return self.__create_task(coroutine=coroutine, update=update, name=name)
|
||||
|
||||
def __create_task(
|
||||
self,
|
||||
coroutine: Union[Generator[Optional["asyncio.Future[object]"], None, RT], Awaitable[RT]],
|
||||
update: Optional[object] = None,
|
||||
is_error_handler: bool = False,
|
||||
name: Optional[str] = None,
|
||||
) -> "asyncio.Task[RT]":
|
||||
# Unfortunately, we can't know if `coroutine` runs one of the error handler functions
|
||||
# but by passing `is_error_handler=True` from `process_error`, we can make sure that we
|
||||
|
@ -995,7 +1000,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
task: "asyncio.Task[RT]" = asyncio.create_task(
|
||||
self.__create_task_callback(
|
||||
coroutine=coroutine, update=update, is_error_handler=is_error_handler
|
||||
)
|
||||
),
|
||||
name=name,
|
||||
)
|
||||
|
||||
if self.running:
|
||||
|
@ -1027,10 +1033,6 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
if isinstance(coroutine, Generator):
|
||||
return await asyncio.create_task(coroutine)
|
||||
return await coroutine
|
||||
except asyncio.CancelledError as cancel:
|
||||
# TODO: in py3.8+, CancelledError is a subclass of BaseException, so we can drop this
|
||||
# clause when we drop py3.7
|
||||
raise cancel
|
||||
except Exception as exception:
|
||||
if isinstance(exception, ApplicationHandlerStop):
|
||||
warn(
|
||||
|
@ -1080,6 +1082,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
self.create_task(
|
||||
self.__process_update_wrapper(update),
|
||||
update=update,
|
||||
name=f"Application:{self.bot.id}:process_concurrent_update",
|
||||
)
|
||||
else:
|
||||
await self.__process_update_wrapper(update)
|
||||
|
@ -1136,7 +1139,12 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
and self.bot.defaults
|
||||
and not self.bot.defaults.block
|
||||
):
|
||||
self.create_task(coroutine, update=update)
|
||||
self.create_task(
|
||||
coroutine,
|
||||
update=update,
|
||||
name=f"Application:{self.bot.id}:process_update_non_blocking"
|
||||
f":{handler}",
|
||||
)
|
||||
else:
|
||||
any_blocking = True
|
||||
await coroutine
|
||||
|
@ -1207,7 +1215,10 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
f"can not be persistent if application has no persistence"
|
||||
)
|
||||
if self._initialized:
|
||||
self.create_task(self._add_ch_to_persistence(handler))
|
||||
self.create_task(
|
||||
self._add_ch_to_persistence(handler),
|
||||
name=f"Application:{self.bot.id}:add_handler:conversation_handler_after_init",
|
||||
)
|
||||
warn(
|
||||
"A persistent `ConversationHandler` was passed to `add_handler`, "
|
||||
"after `Application.initialize` was called. This is discouraged."
|
||||
|
@ -1687,7 +1698,10 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
|||
and not self.bot.defaults.block
|
||||
):
|
||||
self.__create_task(
|
||||
callback(update, context), update=update, is_error_handler=True
|
||||
callback(update, context),
|
||||
update=update,
|
||||
is_error_handler=True,
|
||||
name=f"Application:{self.bot.id}:process_error:non_blocking",
|
||||
)
|
||||
else:
|
||||
try:
|
||||
|
|
|
@ -34,7 +34,7 @@ from typing import (
|
|||
|
||||
from telegram._bot import Bot
|
||||
from telegram._utils.defaultvalue import DEFAULT_FALSE, DEFAULT_NONE, DefaultValue
|
||||
from telegram._utils.types import DVInput, DVType, FilePathInput, ODVInput
|
||||
from telegram._utils.types import DVInput, DVType, FilePathInput, HTTPVersion, ODVInput
|
||||
from telegram.ext._application import Application
|
||||
from telegram.ext._baseupdateprocessor import BaseUpdateProcessor, SimpleUpdateProcessor
|
||||
from telegram.ext._contexttypes import ContextTypes
|
||||
|
@ -240,7 +240,7 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
|
|||
return HTTPXRequest(
|
||||
connection_pool_size=connection_pool_size,
|
||||
proxy_url=proxy_url,
|
||||
http_version=http_version,
|
||||
http_version=http_version, # type: ignore[arg-type]
|
||||
**effective_timeouts,
|
||||
)
|
||||
|
||||
|
@ -564,7 +564,7 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
|
|||
self._pool_timeout = pool_timeout
|
||||
return self
|
||||
|
||||
def http_version(self: BuilderType, http_version: str) -> BuilderType:
|
||||
def http_version(self: BuilderType, http_version: HTTPVersion) -> BuilderType:
|
||||
"""Sets the HTTP protocol version which is used for the
|
||||
:paramref:`~telegram.request.HTTPXRequest.http_version` parameter of
|
||||
:attr:`telegram.Bot.request`. By default, HTTP/1.1 is used.
|
||||
|
@ -723,7 +723,9 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
|
|||
self._get_updates_pool_timeout = get_updates_pool_timeout
|
||||
return self
|
||||
|
||||
def get_updates_http_version(self: BuilderType, get_updates_http_version: str) -> BuilderType:
|
||||
def get_updates_http_version(
|
||||
self: BuilderType, get_updates_http_version: HTTPVersion
|
||||
) -> BuilderType:
|
||||
"""Sets the HTTP protocol version which is used for the
|
||||
:paramref:`~telegram.request.HTTPXRequest.http_version` parameter which is used in the
|
||||
:meth:`telegram.Bot.get_updates` request. By default, HTTP/1.1 is used.
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from asyncio import BoundedSemaphore
|
||||
from types import TracebackType
|
||||
from typing import Any, Awaitable, Optional, Type
|
||||
from typing import Any, Awaitable, Optional, Type, final
|
||||
|
||||
|
||||
class BaseUpdateProcessor(ABC):
|
||||
|
@ -88,6 +88,7 @@ class BaseUpdateProcessor(ABC):
|
|||
:meth:`initialize`
|
||||
"""
|
||||
|
||||
@final
|
||||
async def process_update(
|
||||
self,
|
||||
update: object,
|
||||
|
|
|
@ -150,8 +150,7 @@ class CallbackQueryHandler(BaseHandler[Update, CCT]):
|
|||
return self.pattern(callback_data)
|
||||
if not isinstance(callback_data, str):
|
||||
return False
|
||||
match = re.match(self.pattern, callback_data)
|
||||
if match:
|
||||
if match := re.match(self.pattern, callback_data):
|
||||
return match
|
||||
else:
|
||||
return True
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the ChatMemberHandler class."""
|
||||
from typing import ClassVar, Optional, TypeVar
|
||||
from typing import Final, Optional, TypeVar
|
||||
|
||||
from telegram import Update
|
||||
from telegram._utils.defaultvalue import DEFAULT_TRUE
|
||||
|
@ -71,11 +71,11 @@ class ChatMemberHandler(BaseHandler[Update, CCT]):
|
|||
"""
|
||||
|
||||
__slots__ = ("chat_member_types",)
|
||||
MY_CHAT_MEMBER: ClassVar[int] = -1
|
||||
MY_CHAT_MEMBER: Final[int] = -1
|
||||
""":obj:`int`: Used as a constant to handle only :attr:`telegram.Update.my_chat_member`."""
|
||||
CHAT_MEMBER: ClassVar[int] = 0
|
||||
CHAT_MEMBER: Final[int] = 0
|
||||
""":obj:`int`: Used as a constant to handle only :attr:`telegram.Update.chat_member`."""
|
||||
ANY_CHAT_MEMBER: ClassVar[int] = 1
|
||||
ANY_CHAT_MEMBER: Final[int] = 1
|
||||
""":obj:`int`: Used as a constant to handle both :attr:`telegram.Update.my_chat_member`
|
||||
and :attr:`telegram.Update.chat_member`."""
|
||||
|
||||
|
|
|
@ -100,8 +100,7 @@ class ChosenInlineResultHandler(BaseHandler[Update, CCT]):
|
|||
"""
|
||||
if isinstance(update, Update) and update.chosen_inline_result:
|
||||
if self.pattern:
|
||||
match = re.match(self.pattern, update.chosen_inline_result.result_id)
|
||||
if match:
|
||||
if match := re.match(self.pattern, update.chosen_inline_result.result_id):
|
||||
return match
|
||||
else:
|
||||
return True
|
||||
|
|
|
@ -23,8 +23,8 @@ from dataclasses import dataclass
|
|||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
ClassVar,
|
||||
Dict,
|
||||
Final,
|
||||
Generic,
|
||||
List,
|
||||
NoReturn,
|
||||
|
@ -283,13 +283,13 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
|||
"timeout_jobs",
|
||||
)
|
||||
|
||||
END: ClassVar[int] = -1
|
||||
END: Final[int] = -1
|
||||
""":obj:`int`: Used as a constant to return when a conversation is ended."""
|
||||
TIMEOUT: ClassVar[int] = -2
|
||||
TIMEOUT: Final[int] = -2
|
||||
""":obj:`int`: Used as a constant to handle state when a conversation is timed out
|
||||
(exceeded :attr:`conversation_timeout`).
|
||||
"""
|
||||
WAITING: ClassVar[int] = -3
|
||||
WAITING: Final[int] = -3
|
||||
""":obj:`int`: Used as a constant to handle state when a conversation is still waiting on the
|
||||
previous :attr:`block=False <block>` handler to finish."""
|
||||
|
||||
|
@ -831,6 +831,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
|||
update, application, handler_check_result, context
|
||||
),
|
||||
update=update,
|
||||
name=f"ConversationHandler:{update.update_id}:handle_update:non_blocking_cb",
|
||||
)
|
||||
except ApplicationHandlerStop as exception:
|
||||
new_state = exception.state
|
||||
|
@ -856,6 +857,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
|||
new_state, application, update, context, conversation_key
|
||||
),
|
||||
update=update,
|
||||
name=f"ConversationHandler:{update.update_id}:handle_update:timeout_job",
|
||||
)
|
||||
else:
|
||||
self._schedule_job(new_state, application, update, context, conversation_key)
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the class Defaults, which allows passing default values to Application."""
|
||||
import datetime
|
||||
from typing import Any, Dict, NoReturn, Optional
|
||||
from typing import Any, Dict, NoReturn, Optional, final
|
||||
|
||||
from telegram._utils.datetime import UTC
|
||||
|
||||
|
||||
@final
|
||||
class Defaults:
|
||||
"""Convenience Class to gather all parameters with a (user defined) default value
|
||||
|
||||
|
|
|
@ -88,7 +88,14 @@ from telegram import (
|
|||
from telegram._utils.datetime import to_timestamp
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||
from telegram._utils.logging import get_logger
|
||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||
from telegram._utils.types import (
|
||||
CorrectOptionID,
|
||||
DVInput,
|
||||
FileInput,
|
||||
JSONDict,
|
||||
ODVInput,
|
||||
ReplyMarkup,
|
||||
)
|
||||
from telegram.ext._callbackdatacache import CallbackDataCache
|
||||
from telegram.ext._utils.types import RLARGS
|
||||
from telegram.request import BaseRequest
|
||||
|
@ -2705,7 +2712,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
|||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None, # pylint: disable=redefined-builtin
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
correct_option_id: Optional[int] = None,
|
||||
correct_option_id: Optional[CorrectOptionID] = None,
|
||||
is_closed: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
|
|
|
@ -117,12 +117,13 @@ class InlineQueryHandler(BaseHandler[Update, CCT]):
|
|||
update.inline_query.chat_type not in self.chat_types
|
||||
):
|
||||
return False
|
||||
if self.pattern:
|
||||
if update.inline_query.query:
|
||||
match = re.match(self.pattern, update.inline_query.query)
|
||||
if match:
|
||||
return match
|
||||
else:
|
||||
if (
|
||||
self.pattern
|
||||
and update.inline_query.query
|
||||
and (match := re.match(self.pattern, update.inline_query.query))
|
||||
):
|
||||
return match
|
||||
if not self.pattern:
|
||||
return True
|
||||
return None
|
||||
|
||||
|
|
|
@ -799,7 +799,10 @@ class Job(Generic[CCT]):
|
|||
await context.refresh_data()
|
||||
await self.callback(context)
|
||||
except Exception as exc:
|
||||
await application.create_task(application.process_error(None, exc, job=self))
|
||||
await application.create_task(
|
||||
application.process_error(None, exc, job=self),
|
||||
name=f"Job:{self.id}:run:process_error",
|
||||
)
|
||||
finally:
|
||||
# This is internal logic of application - let's keep it private for now
|
||||
application._mark_for_persistence_update(job=self) # pylint: disable=protected-access
|
||||
|
|
|
@ -17,11 +17,9 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the PicklePersistence class."""
|
||||
import copyreg
|
||||
import pickle
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
from sys import version_info as py_ver
|
||||
from typing import Any, Callable, Dict, Optional, Set, Tuple, Type, TypeVar, Union, cast, overload
|
||||
|
||||
from telegram import Bot, TelegramObject
|
||||
|
@ -74,18 +72,15 @@ class _BotPickler(pickle.Pickler):
|
|||
|
||||
def __init__(self, bot: Bot, *args: Any, **kwargs: Any):
|
||||
self._bot = bot
|
||||
if py_ver < (3, 8): # self.reducer_override is used above this version
|
||||
# Here we define a private dispatch_table, because we want to preserve the bot
|
||||
# attribute of objects so persistent_id works as intended. Otherwise, the bot attribute
|
||||
# is deleted in __getstate__, which is used during regular pickling (via pickle.dumps)
|
||||
self.dispatch_table = copyreg.dispatch_table.copy()
|
||||
for obj in _all_subclasses(TelegramObject):
|
||||
self.dispatch_table[obj] = _custom_reduction
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def reducer_override( # skipcq: PYL-R0201
|
||||
self, obj: TelegramObj
|
||||
) -> Tuple[Callable, Tuple[Type[TelegramObj], dict]]:
|
||||
"""
|
||||
This method is used for pickling. The bot attribute is preserved so
|
||||
_BotPickler().persistent_id works as intended.
|
||||
"""
|
||||
if not isinstance(obj, TelegramObject):
|
||||
return NotImplemented
|
||||
|
||||
|
|
|
@ -96,10 +96,8 @@ class StringRegexHandler(BaseHandler[str, CCT]):
|
|||
:obj:`None` | :obj:`re.match`
|
||||
|
||||
"""
|
||||
if isinstance(update, str):
|
||||
match = re.match(self.pattern, update)
|
||||
if match:
|
||||
return match
|
||||
if isinstance(update, str) and (match := re.match(self.pattern, update)):
|
||||
return match
|
||||
return None
|
||||
|
||||
def collect_additional_context(
|
||||
|
|
|
@ -326,10 +326,6 @@ class Updater(AsyncContextManager["Updater"]):
|
|||
pool_timeout=pool_timeout,
|
||||
allowed_updates=allowed_updates,
|
||||
)
|
||||
except asyncio.CancelledError as exc:
|
||||
# TODO: in py3.8+, CancelledError is a subclass of BaseException, so we can drop
|
||||
# this clause when we drop py3.7
|
||||
raise exc
|
||||
except TelegramError as exc:
|
||||
# TelegramErrors should be processed by the network retry loop
|
||||
raise exc
|
||||
|
@ -367,7 +363,8 @@ class Updater(AsyncContextManager["Updater"]):
|
|||
on_err_cb=error_callback or default_error_callback,
|
||||
description="getting Updates",
|
||||
interval=poll_interval,
|
||||
)
|
||||
),
|
||||
name="Updater:start_polling:polling_task",
|
||||
)
|
||||
|
||||
if ready is not None:
|
||||
|
|
|
@ -26,7 +26,7 @@ Warning:
|
|||
the changelog.
|
||||
"""
|
||||
from collections import UserDict
|
||||
from typing import ClassVar, Generic, List, Mapping, Optional, Set, Tuple, TypeVar, Union
|
||||
from typing import Final, Generic, List, Mapping, Optional, Set, Tuple, TypeVar, Union
|
||||
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||
|
||||
|
@ -45,7 +45,7 @@ class TrackingDict(UserDict, Generic[_KT, _VT]):
|
|||
* deleting values is considered writing
|
||||
"""
|
||||
|
||||
DELETED: ClassVar = object()
|
||||
DELETED: Final = object()
|
||||
"""Special marker indicating that an entry was deleted."""
|
||||
|
||||
__slots__ = ("_write_access_keys",)
|
||||
|
|
|
@ -599,10 +599,8 @@ class CaptionRegex(MessageFilter):
|
|||
super().__init__(name=f"filters.CaptionRegex({self.pattern})", data_filter=True)
|
||||
|
||||
def filter(self, message: Message) -> Optional[Dict[str, List[Match[str]]]]:
|
||||
if message.caption:
|
||||
match = self.pattern.search(message.caption)
|
||||
if match:
|
||||
return {"matches": [match]}
|
||||
if message.caption and (match := self.pattern.search(message.caption)):
|
||||
return {"matches": [match]}
|
||||
return {}
|
||||
|
||||
|
||||
|
@ -974,15 +972,15 @@ class _Dice(MessageFilter):
|
|||
self.name = "filters.Dice.ALL"
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
if not message.dice: # no dice
|
||||
if not (dice := message.dice): # no dice
|
||||
return False
|
||||
|
||||
if self.emoji:
|
||||
emoji_match = message.dice.emoji == self.emoji
|
||||
emoji_match = dice.emoji == self.emoji
|
||||
if self.values:
|
||||
return message.dice.value in self.values and emoji_match # emoji and value
|
||||
return dice.value in self.values and emoji_match # emoji and value
|
||||
return emoji_match # emoji, no value
|
||||
return message.dice.value in self.values if self.values else True # no emoji, only value
|
||||
return dice.value in self.values if self.values else True # no emoji, only value
|
||||
|
||||
|
||||
class Dice(_Dice):
|
||||
|
@ -1597,10 +1595,8 @@ class Regex(MessageFilter):
|
|||
super().__init__(name=f"filters.Regex({self.pattern})", data_filter=True)
|
||||
|
||||
def filter(self, message: Message) -> Optional[Dict[str, List[Match[str]]]]:
|
||||
if message.text:
|
||||
match = self.pattern.search(message.text)
|
||||
if match:
|
||||
return {"matches": [match]}
|
||||
if message.text and (match := self.pattern.search(message.text)):
|
||||
return {"matches": [match]}
|
||||
return {}
|
||||
|
||||
|
||||
|
|
|
@ -35,13 +35,16 @@ import re
|
|||
from html import escape
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from telegram._utils.types import MarkdownVersion
|
||||
from telegram.constants import MessageType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Message, Update
|
||||
|
||||
|
||||
def escape_markdown(text: str, version: int = 1, entity_type: Optional[str] = None) -> str:
|
||||
def escape_markdown(
|
||||
text: str, version: MarkdownVersion = 1, entity_type: Optional[str] = None
|
||||
) -> str:
|
||||
"""Helper function to escape telegram markup symbols.
|
||||
|
||||
.. versionchanged:: 20.3
|
||||
|
@ -88,7 +91,7 @@ def mention_html(user_id: Union[int, str], name: str) -> str:
|
|||
return f'<a href="tg://user?id={user_id}">{escape(name)}</a>'
|
||||
|
||||
|
||||
def mention_markdown(user_id: Union[int, str], name: str, version: int = 1) -> str:
|
||||
def mention_markdown(user_id: Union[int, str], name: str, version: MarkdownVersion = 1) -> str:
|
||||
"""
|
||||
Helper function to create a user mention in Markdown syntax.
|
||||
|
||||
|
|
|
@ -18,11 +18,10 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an abstract class to make POST and GET requests."""
|
||||
import abc
|
||||
import asyncio
|
||||
import json
|
||||
from http import HTTPStatus
|
||||
from types import TracebackType
|
||||
from typing import AsyncContextManager, ClassVar, List, Optional, Tuple, Type, TypeVar, Union
|
||||
from typing import AsyncContextManager, Final, List, Optional, Tuple, Type, TypeVar, Union, final
|
||||
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE as _DEFAULT_NONE
|
||||
from telegram._utils.defaultvalue import DefaultValue
|
||||
|
@ -84,10 +83,10 @@ class BaseRequest(
|
|||
|
||||
__slots__ = ()
|
||||
|
||||
USER_AGENT: ClassVar[str] = f"python-telegram-bot v{ptb_ver} (https://python-telegram-bot.org)"
|
||||
USER_AGENT: Final[str] = f"python-telegram-bot v{ptb_ver} (https://python-telegram-bot.org)"
|
||||
""":obj:`str`: A description that can be used as user agent for requests made to the Bot API.
|
||||
"""
|
||||
DEFAULT_NONE: ClassVar[DefaultValue[None]] = _DEFAULT_NONE
|
||||
DEFAULT_NONE: Final[DefaultValue[None]] = _DEFAULT_NONE
|
||||
""":class:`object`: A special object that indicates that an argument of a function was not
|
||||
explicitly passed. Used for the timeout parameters of :meth:`post` and :meth:`do_request`.
|
||||
|
||||
|
@ -125,6 +124,7 @@ class BaseRequest(
|
|||
async def shutdown(self) -> None:
|
||||
"""Stop & clear resources used by this class. Must be implemented by a subclass."""
|
||||
|
||||
@final
|
||||
async def post(
|
||||
self,
|
||||
url: str,
|
||||
|
@ -179,6 +179,7 @@ class BaseRequest(
|
|||
# see https://core.telegram.org/bots/api#making-requests
|
||||
return json_data["result"]
|
||||
|
||||
@final
|
||||
async def retrieve(
|
||||
self,
|
||||
url: str,
|
||||
|
@ -283,10 +284,6 @@ class BaseRequest(
|
|||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
)
|
||||
except asyncio.CancelledError as exc:
|
||||
# TODO: in py3.8+, CancelledError is a subclass of BaseException, so we can drop this
|
||||
# clause when we drop py3.7
|
||||
raise exc
|
||||
except TelegramError as exc:
|
||||
raise exc
|
||||
except Exception as exc:
|
||||
|
|
|
@ -23,7 +23,7 @@ import httpx
|
|||
|
||||
from telegram._utils.defaultvalue import DefaultValue
|
||||
from telegram._utils.logging import get_logger
|
||||
from telegram._utils.types import ODVInput
|
||||
from telegram._utils.types import HTTPVersion, ODVInput
|
||||
from telegram.error import NetworkError, TimedOut
|
||||
from telegram.request._baserequest import BaseRequest
|
||||
from telegram.request._requestdata import RequestData
|
||||
|
@ -101,7 +101,7 @@ class HTTPXRequest(BaseRequest):
|
|||
write_timeout: Optional[float] = 5.0,
|
||||
connect_timeout: Optional[float] = 5.0,
|
||||
pool_timeout: Optional[float] = 1.0,
|
||||
http_version: str = "1.1",
|
||||
http_version: HTTPVersion = "1.1",
|
||||
):
|
||||
self._http_version = http_version
|
||||
timeout = httpx.Timeout(
|
||||
|
|
|
@ -18,13 +18,14 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a class that holds the parameters of a request to the Bot API."""
|
||||
import json
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from typing import Any, Dict, List, Optional, Union, final
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from telegram._utils.types import UploadFileDict
|
||||
from telegram.request._requestparameter import RequestParameter
|
||||
|
||||
|
||||
@final
|
||||
class RequestData:
|
||||
"""Instances of this class collect the data needed for one request to the Bot API, including
|
||||
all parameters and files to be sent along with the request.
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import json
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import List, Optional, Sequence, Tuple
|
||||
from typing import List, Optional, Sequence, Tuple, final
|
||||
|
||||
from telegram._files.inputfile import InputFile
|
||||
from telegram._files.inputmedia import InputMedia
|
||||
|
@ -31,6 +31,7 @@ from telegram._utils.enum import StringEnum
|
|||
from telegram._utils.types import UploadFileDict
|
||||
|
||||
|
||||
@final
|
||||
@dataclass(repr=True, eq=False, order=False, frozen=True)
|
||||
class RequestParameter:
|
||||
"""Instances of this class represent a single parameter to be sent along with a request to
|
||||
|
|
|
@ -87,12 +87,8 @@ Bots used in tests
|
|||
|
||||
If you run the tests locally, the test setup will use one of the two public bots available. Which
|
||||
bot of the two gets chosen for the test session is random. Whereas when the tests on the
|
||||
Github Actions CI are run, the test setup allocates a different, but same bot for every combination of Python version and
|
||||
OS.
|
||||
|
||||
Thus, number of bots used for testing locally is 2 (called as fallback bots), and on the CI,
|
||||
its [3.7, 3.8, 3.9, 3.10, 3.11] x [ubuntu-latest, macos-latest, windows-latest] = 15. Bringing the
|
||||
total number of bots used for testing to 17.
|
||||
Github Actions CI are run, the test setup allocates a different, but same bot is for every combination of Python version and
|
||||
OS. The operating systems and Python versions the CI runs the tests on can be viewed in the `corresponding workflow`_.
|
||||
|
||||
|
||||
That's it! If you have any questions, feel free to ask them in the `PTB dev
|
||||
|
@ -100,4 +96,5 @@ group`_.
|
|||
|
||||
.. _pytest: https://docs.pytest.org/en/stable/
|
||||
.. _pytest-xdist: https://pypi.org/project/pytest-xdist/
|
||||
.. _PTB dev group: https://t.me/pythontelegrambotgroup
|
||||
.. _PTB dev group: https://t.me/pythontelegrambotgroup
|
||||
.. _corresponding workflow: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/workflows/test.yml
|
||||
|
|
|
@ -262,8 +262,7 @@ class TestAnimationWithRequest(TestAnimationBase):
|
|||
|
||||
async def test_get_and_download(self, bot, animation):
|
||||
path = Path("game.gif")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.get_file(animation.file_id)
|
||||
|
||||
|
|
|
@ -261,8 +261,7 @@ class TestAudioWithRequest(TestAudioBase):
|
|||
|
||||
async def test_get_and_download(self, bot, chat_id, audio):
|
||||
path = Path("telegram.mp3")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.get_file(audio.file_id)
|
||||
|
||||
|
|
|
@ -157,8 +157,7 @@ class TestChatPhotoWithoutRequest(TestChatPhotoBase):
|
|||
class TestChatPhotoWithRequest:
|
||||
async def test_get_and_download(self, bot, chat_photo):
|
||||
jpg_file = Path("telegram.jpg")
|
||||
if jpg_file.is_file():
|
||||
jpg_file.unlink()
|
||||
jpg_file.unlink(missing_ok=True)
|
||||
|
||||
tasks = {bot.get_file(chat_photo.small_file_id), bot.get_file(chat_photo.big_file_id)}
|
||||
asserts = []
|
||||
|
|
|
@ -231,8 +231,7 @@ class TestDocumentWithRequest(TestDocumentBase):
|
|||
|
||||
async def test_get_and_download(self, bot, document, chat_id):
|
||||
path = Path("telegram.png")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.get_file(document.file_id)
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ class TestFileWithoutRequest(TestFileBase):
|
|||
try:
|
||||
assert out_file.read_bytes() == self.file_content
|
||||
finally:
|
||||
out_file.unlink()
|
||||
out_file.unlink(missing_ok=True)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"]
|
||||
|
@ -179,7 +179,7 @@ class TestFileWithoutRequest(TestFileBase):
|
|||
assert out_file.read_bytes() == self.file_content
|
||||
finally:
|
||||
os.close(file_handle)
|
||||
custom_path.unlink()
|
||||
custom_path.unlink(missing_ok=True)
|
||||
|
||||
async def test_download_no_filename(self, monkeypatch, file):
|
||||
async def test(*args, **kwargs):
|
||||
|
@ -194,7 +194,7 @@ class TestFileWithoutRequest(TestFileBase):
|
|||
try:
|
||||
assert out_file.read_bytes() == self.file_content
|
||||
finally:
|
||||
out_file.unlink()
|
||||
out_file.unlink(missing_ok=True)
|
||||
|
||||
async def test_download_file_obj(self, monkeypatch, file):
|
||||
async def test(*args, **kwargs):
|
||||
|
@ -233,7 +233,7 @@ class TestFileWithoutRequest(TestFileBase):
|
|||
try:
|
||||
assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes()
|
||||
finally:
|
||||
out_file.unlink()
|
||||
out_file.unlink(missing_ok=True)
|
||||
|
||||
async def test_download_file_obj_encrypted(self, monkeypatch, encrypted_file):
|
||||
async def test(*args, **kwargs):
|
||||
|
@ -293,7 +293,7 @@ class TestFileWithRequest(TestFileBase):
|
|||
assert out_file.read_bytes() == self.file_content
|
||||
finally:
|
||||
os.close(file_handle)
|
||||
custom_path.unlink()
|
||||
custom_path.unlink(missing_ok=True)
|
||||
|
||||
async def test_download_file_obj_local_file(self, local_file):
|
||||
with TemporaryFile() as custom_fobj:
|
||||
|
@ -315,14 +315,14 @@ class TestFileWithRequest(TestFileBase):
|
|||
assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes()
|
||||
finally:
|
||||
os.close(file_handle)
|
||||
custom_path.unlink()
|
||||
custom_path.unlink(missing_ok=True)
|
||||
|
||||
async def test_download_local_file_encrypted(self, encrypted_local_file):
|
||||
out_file = await encrypted_local_file.download_to_drive()
|
||||
try:
|
||||
assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes()
|
||||
finally:
|
||||
out_file.unlink()
|
||||
out_file.unlink(missing_ok=True)
|
||||
|
||||
async def test_download_bytearray_local_file(self, local_file):
|
||||
# Check that a download to a newly allocated bytearray works.
|
||||
|
|
|
@ -362,8 +362,7 @@ class TestPhotoWithRequest(TestPhotoBase):
|
|||
|
||||
async def test_get_and_download(self, bot, photo):
|
||||
path = Path("telegram.jpg")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.getFile(photo.file_id)
|
||||
|
||||
|
|
|
@ -336,8 +336,7 @@ class TestStickerWithRequest(TestStickerBase):
|
|||
|
||||
async def test_get_and_download(self, bot, sticker):
|
||||
path = Path("telegram.webp")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.get_file(sticker.file_id)
|
||||
|
||||
|
|
|
@ -279,8 +279,7 @@ class TestVideoWithRequest(TestVideoBase):
|
|||
|
||||
async def test_get_and_download(self, bot, video, chat_id):
|
||||
path = Path("telegram.mp4")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.get_file(video.file_id)
|
||||
|
||||
|
|
|
@ -250,8 +250,7 @@ class TestVideoNoteWithRequest(TestVideoNoteBase):
|
|||
|
||||
async def test_get_and_download(self, bot, video_note, chat_id):
|
||||
path = Path("telegram2.mp4")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.get_file(video_note.file_id)
|
||||
|
||||
|
|
|
@ -201,8 +201,7 @@ class TestVoiceWithRequest(TestVoiceBase):
|
|||
|
||||
async def test_get_and_download(self, bot, voice, chat_id):
|
||||
path = Path("telegram.ogg")
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
new_file = await bot.get_file(voice.file_id)
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ def event_loop(request):
|
|||
# ever since ProactorEventLoop became the default in Win 3.8+, the app crashes after the loop
|
||||
# is closed. Hence, we use SelectorEventLoop on Windows to avoid this. See
|
||||
# https://github.com/python/cpython/issues/83413, https://github.com/encode/httpx/issues/914
|
||||
if sys.version_info[0] == 3 and sys.version_info[1] >= 8 and sys.platform.startswith("win"):
|
||||
if sys.platform.startswith("win"):
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
return asyncio.get_event_loop_policy().new_event_loop()
|
||||
# loop.close() # instead of closing here, do that at the every end of the test session
|
||||
|
|
|
@ -453,6 +453,8 @@ class TestApplication:
|
|||
async with app:
|
||||
await app.start()
|
||||
assert app.running
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any(":update_fetcher" in task.get_name() for task in tasks)
|
||||
if job_queue:
|
||||
assert app.job_queue.scheduler.running
|
||||
else:
|
||||
|
@ -551,7 +553,6 @@ class TestApplication:
|
|||
app.remove_handler(handler)
|
||||
app.remove_handler(handler, group=2)
|
||||
|
||||
#
|
||||
async def test_handler_order_in_group(self, app):
|
||||
app.add_handler(MessageHandler(filters.PHOTO, self.callback_set_count(1)))
|
||||
app.add_handler(MessageHandler(filters.ALL, self.callback_set_count(2)))
|
||||
|
@ -964,6 +965,8 @@ class TestApplication:
|
|||
await app.update_queue.put(1)
|
||||
task = asyncio.create_task(app.stop())
|
||||
await asyncio.sleep(0.05)
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any(":process_update_non_blocking" in t.get_name() for t in tasks)
|
||||
assert self.count == 1
|
||||
# Make sure that app stops only once all non blocking callbacks are done
|
||||
assert not task.done()
|
||||
|
@ -1029,6 +1032,8 @@ class TestApplication:
|
|||
await app.update_queue.put(self.message_update)
|
||||
task = asyncio.create_task(app.stop())
|
||||
await asyncio.sleep(0.05)
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any(":process_error:non_blocking" in t.get_name() for t in tasks)
|
||||
assert self.count == 42
|
||||
assert self.received is None
|
||||
event.set()
|
||||
|
@ -1196,7 +1201,8 @@ class TestApplication:
|
|||
self.count = 42
|
||||
return 43
|
||||
|
||||
task = app.create_task(callback())
|
||||
task = app.create_task(callback(), name="test_task")
|
||||
assert task.get_name() == "test_task"
|
||||
await asyncio.sleep(0.01)
|
||||
assert not task.done()
|
||||
out = await task
|
||||
|
@ -1377,6 +1383,8 @@ class TestApplication:
|
|||
assert not events[i].is_set()
|
||||
|
||||
await asyncio.sleep(0.9)
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any(":process_concurrent_update" in task.get_name() for task in tasks)
|
||||
for i in range(app.update_processor.max_concurrent_updates):
|
||||
assert events[i].is_set()
|
||||
for i in range(
|
||||
|
|
|
@ -552,6 +552,8 @@ class TestBasePersistence:
|
|||
papp.add_handler(conversation)
|
||||
|
||||
assert len(recwarn) >= 1
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any("conversation_handler_after_init" in t.get_name() for t in tasks)
|
||||
found = False
|
||||
for warning in recwarn:
|
||||
if "after `Application.initialize` was called" in str(warning.message):
|
||||
|
@ -584,6 +586,28 @@ class TestBasePersistence:
|
|||
with pytest.raises(ValueError, match="when handler is unnamed"):
|
||||
papp.add_handler(build_conversation_handler(name=None, persistent=True))
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"papp",
|
||||
[
|
||||
PappInput(update_interval=0.0),
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
async def test_update_persistence_called(self, papp: Application, monkeypatch):
|
||||
"""Tests if Application.update_persistence is called from app.start()"""
|
||||
called = asyncio.Event()
|
||||
|
||||
async def update_persistence(*args, **kwargs):
|
||||
called.set()
|
||||
|
||||
monkeypatch.setattr(papp, "update_persistence", update_persistence)
|
||||
async with papp:
|
||||
await papp.start()
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any(":persistence_updater" in task.get_name() for task in tasks)
|
||||
assert await called.wait()
|
||||
await papp.stop()
|
||||
|
||||
@pytest.mark.flaky(3, 1)
|
||||
@pytest.mark.parametrize(
|
||||
"papp",
|
||||
|
|
|
@ -2068,6 +2068,9 @@ class TestConversationHandler:
|
|||
assert conv_handler.check_update(Update(0, message=message))
|
||||
await app.process_update(Update(0, message=message))
|
||||
await asyncio.sleep(0.7)
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any(":handle_update:non_blocking_cb" in t.get_name() for t in tasks)
|
||||
assert any(":handle_update:timeout_job" in t.get_name() for t in tasks)
|
||||
assert not self.is_timeout
|
||||
event.set()
|
||||
await asyncio.sleep(0.7)
|
||||
|
|
|
@ -991,7 +991,7 @@ class TestPicklePersistence:
|
|||
await pickle_persistence.update_callback_data(callback_data)
|
||||
|
||||
assert pickle_persistence.filepath.is_file()
|
||||
pickle_persistence.filepath.unlink()
|
||||
pickle_persistence.filepath.unlink(missing_ok=True)
|
||||
assert not pickle_persistence.filepath.is_file()
|
||||
|
||||
await pickle_persistence.update_bot_data(bot_data)
|
||||
|
|
|
@ -248,6 +248,8 @@ class TestUpdater:
|
|||
# We call the same logic twice to make sure that restarting the updater works as well
|
||||
await updater.start_polling(drop_pending_updates=drop_pending_updates)
|
||||
assert updater.running
|
||||
tasks = asyncio.all_tasks()
|
||||
assert any("Updater:start_polling:polling_task" in t.get_name() for t in tasks)
|
||||
await updates.join()
|
||||
await updater.stop()
|
||||
assert not updater.running
|
||||
|
|
|
@ -137,9 +137,8 @@ class TestHelpers:
|
|||
assert helpers.effective_message_type(empty_update) is None
|
||||
|
||||
def test_effective_message_type_wrong_type(self):
|
||||
entity = {}
|
||||
with pytest.raises(
|
||||
TypeError, match=re.escape(f"neither Message nor Update (got: {type(entity)})")
|
||||
TypeError, match=re.escape(f"neither Message nor Update (got: {type(entity := {})})")
|
||||
):
|
||||
helpers.effective_message_type(entity)
|
||||
|
||||
|
|
Loading…
Reference in a new issue