Drop Support for Python 3.8 (#4398)

Co-authored-by: poolitzer <github@poolitzer.eu>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
This commit is contained in:
Pablo Martínez 2024-10-24 20:48:49 +02:00 committed by GitHub
parent 847b97f86e
commit 5ab82a9c2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
133 changed files with 894 additions and 950 deletions

View file

@ -20,7 +20,7 @@ jobs:
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
strategy: strategy:
matrix: matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
os: [ubuntu-latest, windows-latest, macos-latest] os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: False fail-fast: False
steps: steps:

View file

@ -72,7 +72,7 @@ repos:
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: args:
- --py38-plus - --py39-plus
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 5.13.2 rev: 5.13.2
hooks: hooks:

View file

@ -70,7 +70,7 @@ Introduction
This library provides a pure Python, asynchronous interface for the This library provides a pure Python, asynchronous interface for the
`Telegram Bot API <https://core.telegram.org/bots/api>`_. `Telegram Bot API <https://core.telegram.org/bots/api>`_.
It's compatible with Python versions **3.8+**. It's compatible with Python versions **3.9+**.
In addition to the pure API implementation, this library features several convenience methods and shortcuts as well as a number of high-level classes to In addition to the pure API implementation, this library features several convenience methods and shortcuts as well as a number of high-level classes to
make the development of bots easy and straightforward. These classes are contained in the make the development of bots easy and straightforward. These classes are contained in the

View file

@ -20,7 +20,8 @@ import inspect
import re import re
import typing import typing
from collections import defaultdict from collections import defaultdict
from typing import Any, Iterator, Union from collections.abc import Iterator
from typing import Any, Union
import telegram import telegram
import telegram.ext import telegram.ext

View file

@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
import inspect import inspect
from typing import List
keyword_args = [ keyword_args = [
"Keyword Arguments:", "Keyword Arguments:",
@ -85,7 +84,7 @@ get_updates_read_timeout_addition = [
] ]
def find_insert_pos_for_kwargs(lines: List[str]) -> int: def find_insert_pos_for_kwargs(lines: list[str]) -> int:
"""Finds the correct position to insert the keyword arguments and returns the index.""" """Finds the correct position to insert the keyword arguments and returns the index."""
for idx, value in reversed(list(enumerate(lines))): # reversed since :returns: is at the end for idx, value in reversed(list(enumerate(lines))): # reversed since :returns: is at the end
if value.startswith("Returns"): if value.startswith("Returns"):

View file

@ -21,7 +21,6 @@ https://github.com/sphinx-doc/sphinx/issues/1556 is closed
""" """
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from typing import Dict, Tuple
from sphinx.util import logging from sphinx.util import logging
@ -32,7 +31,7 @@ sphinx_logger = logging.getLogger(__name__)
# must be a module-level variable so that it can be written to by the `autodoc-process-docstring` # must be a module-level variable so that it can be written to by the `autodoc-process-docstring`
# event handler in `sphinx_hooks.py` # event handler in `sphinx_hooks.py`
LINE_NUMBERS: Dict[str, Tuple[Path, int, int]] = {} LINE_NUMBERS: dict[str, tuple[Path, int, int]] = {}
def _git_branch() -> str: def _git_branch() -> str:

View file

@ -12,7 +12,7 @@ To use arbitrary callback data, you must install PTB via
`pip install "python-telegram-bot[callback-data]"` `pip install "python-telegram-bot[callback-data]"`
""" """
import logging import logging
from typing import List, Tuple, cast from typing import cast
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import ( from telegram.ext import (
@ -36,7 +36,7 @@ logger = logging.getLogger(__name__)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Sends a message with 5 inline buttons attached.""" """Sends a message with 5 inline buttons attached."""
number_list: List[int] = [] number_list: list[int] = []
await update.message.reply_text("Please choose:", reply_markup=build_keyboard(number_list)) await update.message.reply_text("Please choose:", reply_markup=build_keyboard(number_list))
@ -55,7 +55,7 @@ async def clear(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.effective_message.reply_text("All clear!") await update.effective_message.reply_text("All clear!")
def build_keyboard(current_list: List[int]) -> InlineKeyboardMarkup: def build_keyboard(current_list: list[int]) -> InlineKeyboardMarkup:
"""Helper function to build the next inline keyboard.""" """Helper function to build the next inline keyboard."""
return InlineKeyboardMarkup.from_column( return InlineKeyboardMarkup.from_column(
[InlineKeyboardButton(str(i), callback_data=(i, current_list)) for i in range(1, 6)] [InlineKeyboardButton(str(i), callback_data=(i, current_list)) for i in range(1, 6)]
@ -69,7 +69,7 @@ async def list_button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> Non
# Get the data from the callback_data. # Get the data from the callback_data.
# If you're using a type checker like MyPy, you'll have to use typing.cast # If you're using a type checker like MyPy, you'll have to use typing.cast
# to make the checker get the expected type of the callback_data # to make the checker get the expected type of the callback_data
number, number_list = cast(Tuple[int, List[int]], query.data) number, number_list = cast(tuple[int, list[int]], query.data)
# append the number to the list # append the number to the list
number_list.append(number) number_list.append(number)

View file

@ -12,7 +12,7 @@ bot.
""" """
import logging import logging
from typing import Optional, Tuple from typing import Optional
from telegram import Chat, ChatMember, ChatMemberUpdated, Update from telegram import Chat, ChatMember, ChatMemberUpdated, Update
from telegram.constants import ParseMode from telegram.constants import ParseMode
@ -37,7 +37,7 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def extract_status_change(chat_member_update: ChatMemberUpdated) -> Optional[Tuple[bool, bool]]: def extract_status_change(chat_member_update: ChatMemberUpdated) -> Optional[tuple[bool, bool]]:
"""Takes a ChatMemberUpdated instance and extracts whether the 'old_chat_member' was a member """Takes a ChatMemberUpdated instance and extracts whether the 'old_chat_member' was a member
of the chat and whether the 'new_chat_member' is a member of the chat. Returns None, if of the chat and whether the 'new_chat_member' is a member of the chat. Returns None, if
the status didn't change. the status didn't change.

View file

@ -12,7 +12,7 @@ bot.
import logging import logging
from collections import defaultdict from collections import defaultdict
from typing import DefaultDict, Optional, Set from typing import Optional
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.constants import ParseMode from telegram.constants import ParseMode
@ -40,7 +40,7 @@ class ChatData:
"""Custom class for chat_data. Here we store data per message.""" """Custom class for chat_data. Here we store data per message."""
def __init__(self) -> None: def __init__(self) -> None:
self.clicks_per_message: DefaultDict[int, int] = defaultdict(int) self.clicks_per_message: defaultdict[int, int] = defaultdict(int)
# The [ExtBot, dict, ChatData, dict] is for type checkers like mypy # The [ExtBot, dict, ChatData, dict] is for type checkers like mypy
@ -57,7 +57,7 @@ class CustomContext(CallbackContext[ExtBot, dict, ChatData, dict]):
self._message_id: Optional[int] = None self._message_id: Optional[int] = None
@property @property
def bot_user_ids(self) -> Set[int]: def bot_user_ids(self) -> set[int]:
"""Custom shortcut to access a value stored in the bot_data dict""" """Custom shortcut to access a value stored in the bot_data dict"""
return self.bot_data.setdefault("user_ids", set()) return self.bot_data.setdefault("user_ids", set())

View file

@ -15,7 +15,6 @@ bot.
""" """
import logging import logging
from typing import Dict
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
from telegram.ext import ( from telegram.ext import (
@ -46,7 +45,7 @@ reply_keyboard = [
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True) markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
def facts_to_str(user_data: Dict[str, str]) -> str: def facts_to_str(user_data: dict[str, str]) -> str:
"""Helper function for formatting the gathered user info.""" """Helper function for formatting the gathered user info."""
facts = [f"{key} - {value}" for key, value in user_data.items()] facts = [f"{key} - {value}" for key, value in user_data.items()]
return "\n".join(facts).join(["\n", "\n"]) return "\n".join(facts).join(["\n", "\n"])

View file

@ -15,7 +15,7 @@ bot.
""" """
import logging import logging
from typing import Any, Dict, Tuple from typing import Any
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import ( from telegram.ext import (
@ -66,7 +66,7 @@ END = ConversationHandler.END
# Helper # Helper
def _name_switcher(level: str) -> Tuple[str, str]: def _name_switcher(level: str) -> tuple[str, str]:
if level == PARENTS: if level == PARENTS:
return "Father", "Mother" return "Father", "Mother"
return "Brother", "Sister" return "Brother", "Sister"
@ -122,7 +122,7 @@ async def adding_self(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str
async def show_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str: async def show_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
"""Pretty print gathered data.""" """Pretty print gathered data."""
def pretty_print(data: Dict[str, Any], level: str) -> str: def pretty_print(data: dict[str, Any], level: str) -> str:
people = data.get(level) people = data.get(level)
if not people: if not people:
return "\nNo information yet." return "\nNo information yet."

View file

@ -15,7 +15,6 @@ bot.
""" """
import logging import logging
from typing import Dict
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
from telegram.ext import ( from telegram.ext import (
@ -47,7 +46,7 @@ reply_keyboard = [
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True) markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
def facts_to_str(user_data: Dict[str, str]) -> str: def facts_to_str(user_data: dict[str, str]) -> str:
"""Helper function for formatting the gathered user info.""" """Helper function for formatting the gathered user info."""
facts = [f"{key} - {value}" for key, value in user_data.items()] facts = [f"{key} - {value}" for key, value in user_data.items()]
return "\n".join(facts).join(["\n", "\n"]) return "\n".join(facts).join(["\n", "\n"])

View file

@ -8,7 +8,7 @@ dynamic = ["version"]
name = "python-telegram-bot" name = "python-telegram-bot"
description = "We have made you a wrapper you can't refuse" description = "We have made you a wrapper you can't refuse"
readme = "README.rst" readme = "README.rst"
requires-python = ">=3.8" requires-python = ">=3.9"
license = "LGPL-3.0-only" license = "LGPL-3.0-only"
license-files = { paths = ["LICENSE", "LICENSE.dual", "LICENSE.lesser"] } license-files = { paths = ["LICENSE", "LICENSE.dual", "LICENSE.lesser"] }
authors = [ authors = [
@ -31,7 +31,6 @@ classifiers = [
"Topic :: Internet", "Topic :: Internet",
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.11",
@ -192,7 +191,7 @@ disallow_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true
disallow_untyped_decorators = true disallow_untyped_decorators = true
show_error_codes = true show_error_codes = true
python_version = "3.8" python_version = "3.9"
# For some files, it's easier to just disable strict-optional all together instead of # For some files, it's easier to just disable strict-optional all together instead of
# cluttering the code with `# type: ignore`s or stuff like # cluttering the code with `# type: ignore`s or stuff like

View file

@ -23,21 +23,15 @@ import asyncio
import contextlib import contextlib
import copy import copy
import pickle import pickle
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from types import TracebackType from types import TracebackType
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
AsyncContextManager,
Callable, Callable,
Dict,
List,
NoReturn, NoReturn,
Optional, Optional,
Sequence,
Set,
Tuple,
Type,
TypeVar, TypeVar,
Union, Union,
cast, cast,
@ -130,7 +124,7 @@ if TYPE_CHECKING:
BT = TypeVar("BT", bound="Bot") BT = TypeVar("BT", bound="Bot")
class Bot(TelegramObject, AsyncContextManager["Bot"]): class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
"""This object represents a Telegram Bot. """This object represents a Telegram Bot.
Instances of this class can be used as asyncio context managers, where Instances of this class can be used as asyncio context managers, where
@ -263,7 +257,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
self._private_key: Optional[bytes] = None self._private_key: Optional[bytes] = None
self._initialized: bool = False self._initialized: bool = False
self._request: Tuple[BaseRequest, BaseRequest] = ( self._request: tuple[BaseRequest, BaseRequest] = (
HTTPXRequest() if get_updates_request is None else get_updates_request, HTTPXRequest() if get_updates_request is None else get_updates_request,
HTTPXRequest() if request is None else request, HTTPXRequest() if request is None else request,
) )
@ -332,7 +326,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
async def __aexit__( async def __aexit__(
self, self,
exc_type: Optional[Type[BaseException]], exc_type: Optional[type[BaseException]],
exc_val: Optional[BaseException], exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType], exc_tb: Optional[TracebackType],
) -> None: ) -> None:
@ -352,7 +346,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
""" """
raise pickle.PicklingError("Bot objects cannot be pickled!") raise pickle.PicklingError("Bot objects cannot be pickled!")
def __deepcopy__(self, memodict: Dict[int, object]) -> NoReturn: def __deepcopy__(self, memodict: dict[int, object]) -> NoReturn:
"""Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not """Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not
be deepcopied and this method will always raise an exception. be deepcopied and this method will always raise an exception.
@ -528,7 +522,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
def _warn( def _warn(
cls, cls,
message: Union[str, PTBUserWarning], message: Union[str, PTBUserWarning],
category: Type[Warning] = PTBUserWarning, category: type[Warning] = PTBUserWarning,
stacklevel: int = 0, stacklevel: int = 0,
) -> None: ) -> None:
"""Convenience method to issue a warning. This method is here mostly to make it easier """Convenience method to issue a warning. This method is here mostly to make it easier
@ -539,7 +533,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
def _parse_file_input( def _parse_file_input(
self, self,
file_input: Union[FileInput, "TelegramObject"], file_input: Union[FileInput, "TelegramObject"],
tg_type: Optional[Type["TelegramObject"]] = None, tg_type: Optional[type["TelegramObject"]] = None,
filename: Optional[str] = None, filename: Optional[str] = None,
attach: bool = False, attach: bool = False,
) -> Union[str, "InputFile", Any]: ) -> Union[str, "InputFile", Any]:
@ -551,7 +545,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
local_mode=self._local_mode, local_mode=self._local_mode,
) )
def _insert_defaults(self, data: Dict[str, object]) -> None: def _insert_defaults(self, data: dict[str, object]) -> None:
"""This method is here to make ext.Defaults work. Because we need to be able to tell """This method is here to make ext.Defaults work. Because we need to be able to tell
e.g. `send_message(chat_id, text)` from `send_message(chat_id, text, parse_mode=None)`, the e.g. `send_message(chat_id, text)` from `send_message(chat_id, text, parse_mode=None)`, the
default values for `parse_mode` etc are not `None` but `DEFAULT_NONE`. While this *could* default values for `parse_mode` etc are not `None` but `DEFAULT_NONE`. While this *could*
@ -605,7 +599,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Any: ) -> Any:
# We know that the return type is Union[bool, JSONDict, List[JSONDict]], but it's hard # We know that the return type is Union[bool, JSONDict, list[JSONDict]], but it's hard
# to tell mypy which methods expects which of these return values and `Any` saves us a # to tell mypy which methods expects which of these return values and `Any` saves us a
# lot of `type: ignore` comments # lot of `type: ignore` comments
if data is None: if data is None:
@ -638,7 +632,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
) -> Union[bool, JSONDict, List[JSONDict]]: ) -> Union[bool, JSONDict, list[JSONDict]]:
# This also converts datetimes into timestamps. # This also converts datetimes into timestamps.
# We don't do this earlier so that _insert_defaults (see above) has a chance to convert # We don't do this earlier so that _insert_defaults (see above) has a chance to convert
# to the default timezone in case this is called by ExtBot # to the default timezone in case this is called by ExtBot
@ -798,7 +792,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
self, self,
endpoint: str, endpoint: str,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
return_type: Optional[Type[TelegramObject]] = None, return_type: Optional[type[TelegramObject]] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -1226,7 +1220,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[MessageId, ...]: ) -> tuple[MessageId, ...]:
""" """
Use this method to forward messages of any kind. If some of the specified messages can't be Use this method to forward messages of any kind. If some of the specified messages can't be
found or forwarded, they are skipped. Service messages and messages with protected content found or forwarded, they are skipped. Service messages and messages with protected content
@ -1248,7 +1242,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
message_thread_id (:obj:`int`, optional): |message_thread_id_arg| message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
Returns: Returns:
Tuple[:class:`telegram.Message`]: On success, a tuple of ``MessageId`` of sent messages tuple[:class:`telegram.Message`]: On success, a tuple of ``MessageId`` of sent messages
is returned. is returned.
Raises: Raises:
@ -2499,7 +2493,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
caption: Optional[str] = None, caption: Optional[str] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE, parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None, caption_entities: Optional[Sequence["MessageEntity"]] = None,
) -> Tuple[Message, ...]: ) -> tuple[Message, ...]:
"""Use this method to send a group of photos, videos, documents or audios as an album. """Use this method to send a group of photos, videos, documents or audios as an album.
Documents and audio files can be only grouped in an album with messages of the same type. Documents and audio files can be only grouped in an album with messages of the same type.
@ -2581,7 +2575,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
.. versionadded:: 20.0 .. versionadded:: 20.0
Returns: Returns:
Tuple[:class:`telegram.Message`]: An array of the sent Messages. tuple[:class:`telegram.Message`]: An array of the sent Messages.
Raises: Raises:
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
@ -3403,7 +3397,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
], ],
next_offset: Optional[str] = None, next_offset: Optional[str] = None,
current_offset: Optional[str] = None, current_offset: Optional[str] = None,
) -> Tuple[Sequence["InlineQueryResult"], Optional[str]]: ) -> tuple[Sequence["InlineQueryResult"], Optional[str]]:
""" """
Builds the effective results from the results input. Builds the effective results from the results input.
We make this a stand-alone method so tg.ext.ExtBot can wrap it. We make this a stand-alone method so tg.ext.ExtBot can wrap it.
@ -3526,7 +3520,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
Args: Args:
inline_query_id (:obj:`str`): Unique identifier for the answered query. inline_query_id (:obj:`str`): Unique identifier for the answered query.
results (List[:class:`telegram.InlineQueryResult`] | Callable): A list of results for results (list[:class:`telegram.InlineQueryResult`] | Callable): A list of results for
the inline query. In case :paramref:`current_offset` is passed, the inline query. In case :paramref:`current_offset` is passed,
:paramref:`results` may also be :paramref:`results` may also be
a callable that accepts the current page index starting from 0. It must return a callable that accepts the current page index starting from 0. It must return
@ -4280,7 +4274,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[Update, ...]: ) -> tuple[Update, ...]:
"""Use this method to receive incoming updates using long polling. """Use this method to receive incoming updates using long polling.
Note: Note:
@ -4325,7 +4319,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|sequenceargs| |sequenceargs|
Returns: Returns:
Tuple[:class:`telegram.Update`] tuple[:class:`telegram.Update`]
Raises: Raises:
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
@ -4362,7 +4356,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
# waiting for the server to return and there's no way of knowing the connection had been # waiting for the server to return and there's no way of knowing the connection had been
# dropped in real time. # dropped in real time.
result = cast( result = cast(
List[JSONDict], list[JSONDict],
await self._post( await self._post(
"getUpdates", "getUpdates",
data, data,
@ -4626,7 +4620,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[ChatMember, ...]: ) -> tuple[ChatMember, ...]:
""" """
Use this method to get a list of administrators in a chat. Use this method to get a list of administrators in a chat.
@ -4637,7 +4631,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
Returns: Returns:
Tuple[:class:`telegram.ChatMember`]: On success, returns a tuple of ``ChatMember`` tuple[:class:`telegram.ChatMember`]: On success, returns a tuple of ``ChatMember``
objects that contains information about all chat administrators except objects that contains information about all chat administrators except
other bots. If the chat is a group or a supergroup and no administrators were other bots. If the chat is a group or a supergroup and no administrators were
appointed, only the creator will be returned. appointed, only the creator will be returned.
@ -4901,7 +4895,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[GameHighScore, ...]: ) -> tuple[GameHighScore, ...]:
""" """
Use this method to get data for high score tables. Will return the score of the specified Use this method to get data for high score tables. Will return the score of the specified
user and several of their neighbors in a game. user and several of their neighbors in a game.
@ -4924,7 +4918,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
:paramref:`message_id` are not specified. Identifier of the inline message. :paramref:`message_id` are not specified. Identifier of the inline message.
Returns: Returns:
Tuple[:class:`telegram.GameHighScore`] tuple[:class:`telegram.GameHighScore`]
Raises: Raises:
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
@ -6304,7 +6298,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[Sticker, ...]: ) -> tuple[Sticker, ...]:
""" """
Use this method to get information about emoji stickers by their identifiers. Use this method to get information about emoji stickers by their identifiers.
@ -6320,7 +6314,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|sequenceargs| |sequenceargs|
Returns: Returns:
Tuple[:class:`telegram.Sticker`] tuple[:class:`telegram.Sticker`]
Raises: Raises:
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
@ -7427,7 +7421,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[BotCommand, ...]: ) -> tuple[BotCommand, ...]:
""" """
Use this method to get the current list of the bot's commands for the given scope and user Use this method to get the current list of the bot's commands for the given scope and user
language. language.
@ -7449,7 +7443,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
.. versionadded:: 13.7 .. versionadded:: 13.7
Returns: Returns:
Tuple[:class:`telegram.BotCommand`]: On success, the commands set for the bot. An empty tuple[:class:`telegram.BotCommand`]: On success, the commands set for the bot. An empty
tuple is returned if commands are not set. tuple is returned if commands are not set.
Raises: Raises:
@ -7472,7 +7466,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
async def set_my_commands( async def set_my_commands(
self, self,
commands: Sequence[Union[BotCommand, Tuple[str, str]]], commands: Sequence[Union[BotCommand, tuple[str, str]]],
scope: Optional[BotCommandScope] = None, scope: Optional[BotCommandScope] = None,
language_code: Optional[str] = None, language_code: Optional[str] = None,
*, *,
@ -7791,7 +7785,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
""" """
Use this method to copy messages of any kind. If some of the specified messages can't be Use this method to copy messages of any kind. If some of the specified messages can't be
found or copied, they are skipped. Service messages, paid media messages, giveaway found or copied, they are skipped. Service messages, paid media messages, giveaway
@ -7819,7 +7813,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
their captions. their captions.
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of the sent messages is returned. of the sent messages is returned.
Raises: Raises:
@ -8072,14 +8066,14 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[Sticker, ...]: ) -> tuple[Sticker, ...]:
"""Use this method to get custom emoji stickers, which can be used as a forum topic """Use this method to get custom emoji stickers, which can be used as a forum topic
icon by any user. Requires no parameters. icon by any user. Requires no parameters.
.. versionadded:: 20.0 .. versionadded:: 20.0
Returns: Returns:
Tuple[:class:`telegram.Sticker`] tuple[:class:`telegram.Sticker`]
Raises: Raises:
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
@ -8968,7 +8962,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
Raises: Raises:
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
""" """
allowed_reactions: Set[str] = set(ReactionEmoji) allowed_reactions: set[str] = set(ReactionEmoji)
parsed_reaction = ( parsed_reaction = (
[ [
( (

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=redefined-builtin # pylint: disable=redefined-builtin
"""This module contains objects representing Telegram bot command scopes.""" """This module contains objects representing Telegram bot command scopes."""
from typing import TYPE_CHECKING, Dict, Final, Optional, Type, Union from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -91,7 +91,7 @@ class BotCommandScope(TelegramObject):
care of selecting the correct subclass. care of selecting the correct subclass.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to
:obj:`None`, in which case shortcut methods will not be available. :obj:`None`, in which case shortcut methods will not be available.
@ -107,7 +107,7 @@ class BotCommandScope(TelegramObject):
if not data: if not data:
return None return None
_class_mapping: Dict[str, Type[BotCommandScope]] = { _class_mapping: dict[str, type[BotCommandScope]] = {
cls.DEFAULT: BotCommandScopeDefault, cls.DEFAULT: BotCommandScopeDefault,
cls.ALL_PRIVATE_CHATS: BotCommandScopeAllPrivateChats, cls.ALL_PRIVATE_CHATS: BotCommandScopeAllPrivateChats,
cls.ALL_GROUP_CHATS: BotCommandScopeAllGroupChats, cls.ALL_GROUP_CHATS: BotCommandScopeAllGroupChats,

View file

@ -19,8 +19,9 @@
# along with this program. If not, see [http://www.gnu.org/licenses/] # along with this program. If not, see [http://www.gnu.org/licenses/]
"""This module contains the Telegram Business related classes.""" """This module contains the Telegram Business related classes."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from typing import TYPE_CHECKING, Optional
from telegram._chat import Chat from telegram._chat import Chat
from telegram._files.location import Location from telegram._files.location import Location
@ -145,7 +146,7 @@ class BusinessMessagesDeleted(TelegramObject):
business_connection_id (:obj:`str`): Unique identifier of the business connection. business_connection_id (:obj:`str`): Unique identifier of the business connection.
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
may not have access to the chat or the corresponding user. may not have access to the chat or the corresponding user.
message_ids (Tuple[:obj:`int`]): A list of identifiers of the deleted messages in the message_ids (tuple[:obj:`int`]): A list of identifiers of the deleted messages in the
chat of the business account. chat of the business account.
""" """
@ -166,7 +167,7 @@ class BusinessMessagesDeleted(TelegramObject):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.business_connection_id: str = business_connection_id self.business_connection_id: str = business_connection_id
self.chat: Chat = chat self.chat: Chat = chat
self.message_ids: Tuple[int, ...] = parse_sequence_arg(message_ids) self.message_ids: tuple[int, ...] = parse_sequence_arg(message_ids)
self._id_attrs = ( self._id_attrs = (
self.business_connection_id, self.business_connection_id,
@ -359,37 +360,37 @@ class BusinessOpeningHoursInterval(TelegramObject):
self.opening_minute: int = opening_minute self.opening_minute: int = opening_minute
self.closing_minute: int = closing_minute self.closing_minute: int = closing_minute
self._opening_time: Optional[Tuple[int, int, int]] = None self._opening_time: Optional[tuple[int, int, int]] = None
self._closing_time: Optional[Tuple[int, int, int]] = None self._closing_time: Optional[tuple[int, int, int]] = None
self._id_attrs = (self.opening_minute, self.closing_minute) self._id_attrs = (self.opening_minute, self.closing_minute)
self._freeze() self._freeze()
def _parse_minute(self, minute: int) -> Tuple[int, int, int]: def _parse_minute(self, minute: int) -> tuple[int, int, int]:
return (minute // 1440, minute % 1440 // 60, minute % 1440 % 60) return (minute // 1440, minute % 1440 // 60, minute % 1440 % 60)
@property @property
def opening_time(self) -> Tuple[int, int, int]: def opening_time(self) -> tuple[int, int, int]:
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`opening_minute`. It contains """Convenience attribute. A :obj:`tuple` parsed from :attr:`opening_minute`. It contains
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`, the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute` :attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
Returns: Returns:
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]: tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
""" """
if self._opening_time is None: if self._opening_time is None:
self._opening_time = self._parse_minute(self.opening_minute) self._opening_time = self._parse_minute(self.opening_minute)
return self._opening_time return self._opening_time
@property @property
def closing_time(self) -> Tuple[int, int, int]: def closing_time(self) -> tuple[int, int, int]:
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`closing_minute`. It contains """Convenience attribute. A :obj:`tuple` parsed from :attr:`closing_minute`. It contains
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`, the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute` :attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
Returns: Returns:
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]: tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
""" """
if self._closing_time is None: if self._closing_time is None:
self._closing_time = self._parse_minute(self.closing_minute) self._closing_time = self._parse_minute(self.closing_minute)

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=redefined-builtin # pylint: disable=redefined-builtin
"""This module contains an object that represents a Telegram CallbackQuery""" """This module contains an object that represents a Telegram CallbackQuery"""
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple, Union from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._files.location import Location from telegram._files.location import Location
@ -676,7 +677,7 @@ class CallbackQuery(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["GameHighScore", ...]: ) -> tuple["GameHighScore", ...]:
"""Shortcut for either:: """Shortcut for either::
await update.callback_query.message.get_game_high_score(*args, **kwargs) await update.callback_query.message.get_game_high_score(*args, **kwargs)
@ -695,7 +696,7 @@ class CallbackQuery(TelegramObject):
Raises :exc:`TypeError` if :attr:`message` is not accessible. Raises :exc:`TypeError` if :attr:`message` is not accessible.
Returns: Returns:
Tuple[:class:`telegram.GameHighScore`] tuple[:class:`telegram.GameHighScore`]
Raises: Raises:
:exc:`TypeError` if :attr:`message` is not accessible. :exc:`TypeError` if :attr:`message` is not accessible.

View file

@ -18,9 +18,10 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Chat.""" """This module contains an object that represents a Telegram Chat."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from html import escape from html import escape
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple, Union from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._chatpermissions import ChatPermissions from telegram._chatpermissions import ChatPermissions
@ -296,7 +297,7 @@ class _ChatBase(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["ChatMember", ...]: ) -> tuple["ChatMember", ...]:
"""Shortcut for:: """Shortcut for::
await bot.get_chat_administrators(update.effective_chat.id, *args, **kwargs) await bot.get_chat_administrators(update.effective_chat.id, *args, **kwargs)
@ -305,7 +306,7 @@ class _ChatBase(TelegramObject):
:meth:`telegram.Bot.get_chat_administrators`. :meth:`telegram.Bot.get_chat_administrators`.
Returns: Returns:
Tuple[:class:`telegram.ChatMember`]: A tuple of administrators in a chat. An Array of tuple[:class:`telegram.ChatMember`]: A tuple of administrators in a chat. An Array of
:class:`telegram.ChatMember` objects that contains information about all :class:`telegram.ChatMember` objects that contains information about all
chat administrators except other bots. If the chat is a group or a supergroup chat administrators except other bots. If the chat is a group or a supergroup
and no administrators were appointed, only the creator will be returned. and no administrators were appointed, only the creator will be returned.
@ -1140,7 +1141,7 @@ class _ChatBase(TelegramObject):
caption: Optional[str] = None, caption: Optional[str] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE, parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None, caption_entities: Optional[Sequence["MessageEntity"]] = None,
) -> Tuple["Message", ...]: ) -> tuple["Message", ...]:
"""Shortcut for:: """Shortcut for::
await bot.send_media_group(update.effective_chat.id, *args, **kwargs) await bot.send_media_group(update.effective_chat.id, *args, **kwargs)
@ -1148,7 +1149,7 @@ class _ChatBase(TelegramObject):
For the documentation of the arguments, please see :meth:`telegram.Bot.send_media_group`. For the documentation of the arguments, please see :meth:`telegram.Bot.send_media_group`.
Returns: Returns:
Tuple[:class:`telegram.Message`]: On success, a tuple of :class:`~telegram.Message` tuple[:class:`telegram.Message`]: On success, a tuple of :class:`~telegram.Message`
instances that were sent is returned. instances that were sent is returned.
""" """
@ -2268,7 +2269,7 @@ class _ChatBase(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.copy_messages(chat_id=update.effective_chat.id, *args, **kwargs) await bot.copy_messages(chat_id=update.effective_chat.id, *args, **kwargs)
@ -2280,7 +2281,7 @@ class _ChatBase(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of the sent messages is returned. of the sent messages is returned.
""" """
@ -2313,7 +2314,7 @@ class _ChatBase(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.copy_messages(from_chat_id=update.effective_chat.id, *args, **kwargs) await bot.copy_messages(from_chat_id=update.effective_chat.id, *args, **kwargs)
@ -2325,7 +2326,7 @@ class _ChatBase(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of the sent messages is returned. of the sent messages is returned.
""" """
@ -2442,7 +2443,7 @@ class _ChatBase(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.forward_messages(chat_id=update.effective_chat.id, *args, **kwargs) await bot.forward_messages(chat_id=update.effective_chat.id, *args, **kwargs)
@ -2454,7 +2455,7 @@ class _ChatBase(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of sent messages is returned. of sent messages is returned.
""" """
@ -2485,7 +2486,7 @@ class _ChatBase(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.forward_messages(from_chat_id=update.effective_chat.id, *args, **kwargs) await bot.forward_messages(from_chat_id=update.effective_chat.id, *args, **kwargs)
@ -2497,7 +2498,7 @@ class _ChatBase(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of sent messages is returned. of sent messages is returned.
""" """

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains objects related to chat backgrounds.""" """This module contains objects related to chat backgrounds."""
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._files.document import Document from telegram._files.document import Document
@ -87,7 +88,7 @@ class BackgroundFill(TelegramObject):
if not data: if not data:
return None return None
_class_mapping: Dict[str, Type[BackgroundFill]] = { _class_mapping: dict[str, type[BackgroundFill]] = {
cls.SOLID: BackgroundFillSolid, cls.SOLID: BackgroundFillSolid,
cls.GRADIENT: BackgroundFillGradient, cls.GRADIENT: BackgroundFillGradient,
cls.FREEFORM_GRADIENT: BackgroundFillFreeformGradient, cls.FREEFORM_GRADIENT: BackgroundFillFreeformGradient,
@ -212,7 +213,7 @@ class BackgroundFillFreeformGradient(BackgroundFill):
super().__init__(type=self.FREEFORM_GRADIENT, api_kwargs=api_kwargs) super().__init__(type=self.FREEFORM_GRADIENT, api_kwargs=api_kwargs)
with self._unfrozen(): with self._unfrozen():
self.colors: Tuple[int, ...] = parse_sequence_arg(colors) self.colors: tuple[int, ...] = parse_sequence_arg(colors)
self._id_attrs = (self.colors,) self._id_attrs = (self.colors,)
@ -278,7 +279,7 @@ class BackgroundType(TelegramObject):
if not data: if not data:
return None return None
_class_mapping: Dict[str, Type[BackgroundType]] = { _class_mapping: dict[str, type[BackgroundType]] = {
cls.FILL: BackgroundTypeFill, cls.FILL: BackgroundTypeFill,
cls.WALLPAPER: BackgroundTypeWallpaper, cls.WALLPAPER: BackgroundTypeWallpaper,
cls.PATTERN: BackgroundTypePattern, cls.PATTERN: BackgroundTypePattern,

View file

@ -18,8 +18,9 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram ChatBoosts.""" """This module contains the classes that represent Telegram ChatBoosts."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._chat import Chat from telegram._chat import Chat
@ -119,7 +120,7 @@ class ChatBoostSource(TelegramObject):
if not data: if not data:
return None return None
_class_mapping: Dict[str, Type[ChatBoostSource]] = { _class_mapping: dict[str, type[ChatBoostSource]] = {
cls.PREMIUM: ChatBoostSourcePremium, cls.PREMIUM: ChatBoostSourcePremium,
cls.GIFT_CODE: ChatBoostSourceGiftCode, cls.GIFT_CODE: ChatBoostSourceGiftCode,
cls.GIVEAWAY: ChatBoostSourceGiveaway, cls.GIVEAWAY: ChatBoostSourceGiveaway,
@ -431,7 +432,7 @@ class UserChatBoosts(TelegramObject):
user. user.
Attributes: Attributes:
boosts (Tuple[:class:`telegram.ChatBoost`]): List of boosts added to the chat by the user. boosts (tuple[:class:`telegram.ChatBoost`]): List of boosts added to the chat by the user.
""" """
__slots__ = ("boosts",) __slots__ = ("boosts",)
@ -444,7 +445,7 @@ class UserChatBoosts(TelegramObject):
): ):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.boosts: Tuple[ChatBoost, ...] = parse_sequence_arg(boosts) self.boosts: tuple[ChatBoost, ...] = parse_sequence_arg(boosts)
self._id_attrs = (self.boosts,) self._id_attrs = (self.boosts,)
self._freeze() self._freeze()

View file

@ -18,8 +18,9 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram ChatFullInfo.""" """This module contains an object that represents a Telegram ChatFullInfo."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from typing import TYPE_CHECKING, Optional
from telegram._birthdate import Birthdate from telegram._birthdate import Birthdate
from telegram._chat import Chat, _ChatBase from telegram._chat import Chat, _ChatBase
@ -224,7 +225,7 @@ class ChatFullInfo(_ChatBase):
.. versionadded:: 20.0 .. versionadded:: 20.0
photo (:class:`telegram.ChatPhoto`): Optional. Chat photo. photo (:class:`telegram.ChatPhoto`): Optional. Chat photo.
active_usernames (Tuple[:obj:`str`]): Optional. If set, the list of all `active chat active_usernames (tuple[:obj:`str`]): Optional. If set, the list of all `active chat
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\ usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
#collectible-usernames>`_; for private chats, supergroups and channels. #collectible-usernames>`_; for private chats, supergroups and channels.
@ -252,7 +253,7 @@ class ChatFullInfo(_ChatBase):
of the user. of the user.
.. versionadded:: 21.1 .. versionadded:: 21.1
available_reactions (Tuple[:class:`telegram.ReactionType`]): Optional. List of available available_reactions (tuple[:class:`telegram.ReactionType`]): Optional. List of available
reactions allowed in the chat. If omitted, then all of reactions allowed in the chat. If omitted, then all of
:const:`telegram.constants.ReactionEmoji` are allowed. :const:`telegram.constants.ReactionEmoji` are allowed.
@ -483,14 +484,14 @@ class ChatFullInfo(_ChatBase):
self.has_restricted_voice_and_video_messages: Optional[bool] = ( self.has_restricted_voice_and_video_messages: Optional[bool] = (
has_restricted_voice_and_video_messages has_restricted_voice_and_video_messages
) )
self.active_usernames: Tuple[str, ...] = parse_sequence_arg(active_usernames) self.active_usernames: tuple[str, ...] = parse_sequence_arg(active_usernames)
self.emoji_status_custom_emoji_id: Optional[str] = emoji_status_custom_emoji_id self.emoji_status_custom_emoji_id: Optional[str] = emoji_status_custom_emoji_id
self.emoji_status_expiration_date: Optional[datetime] = emoji_status_expiration_date self.emoji_status_expiration_date: Optional[datetime] = emoji_status_expiration_date
self.has_aggressive_anti_spam_enabled: Optional[bool] = ( self.has_aggressive_anti_spam_enabled: Optional[bool] = (
has_aggressive_anti_spam_enabled has_aggressive_anti_spam_enabled
) )
self.has_hidden_members: Optional[bool] = has_hidden_members self.has_hidden_members: Optional[bool] = has_hidden_members
self.available_reactions: Optional[Tuple[ReactionType, ...]] = parse_sequence_arg( self.available_reactions: Optional[tuple[ReactionType, ...]] = parse_sequence_arg(
available_reactions available_reactions
) )
self.accent_color_id: Optional[int] = accent_color_id self.accent_color_id: Optional[int] = accent_color_id

View file

@ -19,7 +19,7 @@
"""This module contains an object that represents a Telegram ChatMember.""" """This module contains an object that represents a Telegram ChatMember."""
import datetime import datetime
from typing import TYPE_CHECKING, Dict, Final, Optional, Type from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -114,7 +114,7 @@ class ChatMember(TelegramObject):
if not data: if not data:
return None return None
_class_mapping: Dict[str, Type[ChatMember]] = { _class_mapping: dict[str, type[ChatMember]] = {
cls.OWNER: ChatMemberOwner, cls.OWNER: ChatMemberOwner,
cls.ADMINISTRATOR: ChatMemberAdministrator, cls.ADMINISTRATOR: ChatMemberAdministrator,
cls.MEMBER: ChatMemberMember, cls.MEMBER: ChatMemberMember,

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram ChatMemberUpdated.""" """This module contains an object that represents a Telegram ChatMemberUpdated."""
import datetime import datetime
from typing import TYPE_CHECKING, Dict, Optional, Tuple, Union from typing import TYPE_CHECKING, Optional, Union
from telegram._chat import Chat from telegram._chat import Chat
from telegram._chatinvitelink import ChatInviteLink from telegram._chatinvitelink import ChatInviteLink
@ -162,7 +162,7 @@ class ChatMemberUpdated(TelegramObject):
return super().de_json(data=data, bot=bot) return super().de_json(data=data, bot=bot)
def _get_attribute_difference(self, attribute: str) -> Tuple[object, object]: def _get_attribute_difference(self, attribute: str) -> tuple[object, object]:
try: try:
old = self.old_chat_member[attribute] old = self.old_chat_member[attribute]
except KeyError: except KeyError:
@ -177,9 +177,9 @@ class ChatMemberUpdated(TelegramObject):
def difference( def difference(
self, self,
) -> Dict[ ) -> dict[
str, str,
Tuple[ tuple[
Union[str, bool, datetime.datetime, User], Union[str, bool, datetime.datetime, User] Union[str, bool, datetime.datetime, User], Union[str, bool, datetime.datetime, User]
], ],
]: ]:
@ -198,7 +198,7 @@ class ChatMemberUpdated(TelegramObject):
.. versionadded:: 13.5 .. versionadded:: 13.5
Returns: Returns:
Dict[:obj:`str`, Tuple[:class:`object`, :class:`object`]]: A dictionary mapping dict[:obj:`str`, tuple[:class:`object`, :class:`object`]]: A dictionary mapping
attribute names to tuples of the form ``(old_value, new_value)`` attribute names to tuples of the form ``(old_value, new_value)``
""" """
# we first get the names of the attributes that have changed # we first get the names of the attributes that have changed

View file

@ -17,7 +17,7 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Dice.""" """This module contains an object that represents a Telegram Dice."""
from typing import Final, List, Optional from typing import Final, Optional
from telegram import constants from telegram import constants
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -114,8 +114,8 @@ class Dice(TelegramObject):
.. versionadded:: 13.4 .. versionadded:: 13.4
""" """
ALL_EMOJI: Final[List[str]] = list(constants.DiceEmoji) ALL_EMOJI: Final[list[str]] = list(constants.DiceEmoji)
"""List[:obj:`str`]: A list of all available dice emoji.""" """list[:obj:`str`]: A list of all available dice emoji."""
MIN_VALUE: Final[int] = constants.DiceLimit.MIN_VALUE MIN_VALUE: Final[int] = constants.DiceLimit.MIN_VALUE
""":const:`telegram.constants.DiceLimit.MIN_VALUE` """:const:`telegram.constants.DiceLimit.MIN_VALUE`

View file

@ -17,7 +17,7 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""Common base class for media objects with thumbnails""" """Common base class for media objects with thumbnails"""
from typing import TYPE_CHECKING, Optional, Type, TypeVar from typing import TYPE_CHECKING, Optional, TypeVar
from telegram._files._basemedium import _BaseMedium from telegram._files._basemedium import _BaseMedium
from telegram._files.photosize import PhotoSize from telegram._files.photosize import PhotoSize
@ -82,7 +82,7 @@ class _BaseThumbedMedium(_BaseMedium):
@classmethod @classmethod
def de_json( def de_json(
cls: Type[ThumbedMT_co], data: Optional[JSONDict], bot: Optional["Bot"] = None cls: type[ThumbedMT_co], data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional[ThumbedMT_co]: ) -> Optional[ThumbedMT_co]:
"""See :meth:`telegram.TelegramObject.de_json`.""" """See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data) data = cls._parse_data(data)

View file

@ -130,7 +130,7 @@ class InputFile:
Content may now be a file handle. Content may now be a file handle.
Returns: Returns:
Tuple[:obj:`str`, :obj:`bytes` | :class:`IO`, :obj:`str`]: tuple[:obj:`str`, :obj:`bytes` | :class:`IO`, :obj:`str`]:
""" """
return self.filename, self.input_file_content, self.mimetype return self.filename, self.input_file_content, self.mimetype

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""Base class for Telegram InputMedia Objects.""" """Base class for Telegram InputMedia Objects."""
from typing import Final, Optional, Sequence, Tuple, Union from collections.abc import Sequence
from typing import Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._files.animation import Animation from telegram._files.animation import Animation
@ -74,7 +75,7 @@ class InputMedia(TelegramObject):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing. parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -99,7 +100,7 @@ class InputMedia(TelegramObject):
self.type: str = enum.get_member(constants.InputMediaType, media_type, media_type) self.type: str = enum.get_member(constants.InputMediaType, media_type, media_type)
self.media: Union[str, InputFile, Animation, Audio, Document, PhotoSize, Video] = media self.media: Union[str, InputFile, Animation, Audio, Document, PhotoSize, Video] = media
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self._freeze() self._freeze()
@ -321,7 +322,7 @@ class InputMediaAnimation(InputMedia):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting. parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -436,7 +437,7 @@ class InputMediaPhoto(InputMedia):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -546,7 +547,7 @@ class InputMediaVideo(InputMedia):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -676,7 +677,7 @@ class InputMediaAudio(InputMedia):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -779,7 +780,7 @@ class InputMediaDocument(InputMedia):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram InputSticker.""" """This module contains an object that represents a Telegram InputSticker."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, Union from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional, Union
from telegram._files.sticker import MaskPosition from telegram._files.sticker import MaskPosition
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -67,13 +68,13 @@ class InputSticker(TelegramObject):
Attributes: Attributes:
sticker (:obj:`str` | :class:`telegram.InputFile`): The added sticker. sticker (:obj:`str` | :class:`telegram.InputFile`): The added sticker.
emoji_list (Tuple[:obj:`str`]): Tuple of emoji_list (tuple[:obj:`str`]): Tuple of
:tg-const:`telegram.constants.StickerLimit.MIN_STICKER_EMOJI` - :tg-const:`telegram.constants.StickerLimit.MIN_STICKER_EMOJI` -
:tg-const:`telegram.constants.StickerLimit.MAX_STICKER_EMOJI` emoji associated with the :tg-const:`telegram.constants.StickerLimit.MAX_STICKER_EMOJI` emoji associated with the
sticker. sticker.
mask_position (:class:`telegram.MaskPosition`): Optional. Position where the mask should be mask_position (:class:`telegram.MaskPosition`): Optional. Position where the mask should be
placed on faces. For ":tg-const:`telegram.constants.StickerType.MASK`" stickers only. placed on faces. For ":tg-const:`telegram.constants.StickerType.MASK`" stickers only.
keywords (Tuple[:obj:`str`]): Optional. Tuple of keywords (tuple[:obj:`str`]): Optional. Tuple of
0-:tg-const:`telegram.constants.StickerLimit.MAX_SEARCH_KEYWORDS` search keywords 0-:tg-const:`telegram.constants.StickerLimit.MAX_SEARCH_KEYWORDS` search keywords
for the sticker with the total length of up to for the sticker with the total length of up to
:tg-const:`telegram.constants.StickerLimit.MAX_KEYWORD_LENGTH` characters. For :tg-const:`telegram.constants.StickerLimit.MAX_KEYWORD_LENGTH` characters. For
@ -110,9 +111,9 @@ class InputSticker(TelegramObject):
local_mode=True, local_mode=True,
attach=True, attach=True,
) )
self.emoji_list: Tuple[str, ...] = parse_sequence_arg(emoji_list) self.emoji_list: tuple[str, ...] = parse_sequence_arg(emoji_list)
self.format: str = format self.format: str = format
self.mask_position: Optional[MaskPosition] = mask_position self.mask_position: Optional[MaskPosition] = mask_position
self.keywords: Tuple[str, ...] = parse_sequence_arg(keywords) self.keywords: tuple[str, ...] = parse_sequence_arg(keywords)
self._freeze() self._freeze()

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains objects that represent stickers.""" """This module contains objects that represent stickers."""
from typing import TYPE_CHECKING, Final, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._files._basethumbedmedium import _BaseThumbedMedium from telegram._files._basethumbedmedium import _BaseThumbedMedium
@ -259,7 +260,7 @@ class StickerSet(TelegramObject):
Attributes: Attributes:
name (:obj:`str`): Sticker set name. name (:obj:`str`): Sticker set name.
title (:obj:`str`): Sticker set title. title (:obj:`str`): Sticker set title.
stickers (Tuple[:class:`telegram.Sticker`]): List of all set stickers. stickers (tuple[:class:`telegram.Sticker`]): List of all set stickers.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
|tupleclassattrs| |tupleclassattrs|
@ -296,7 +297,7 @@ class StickerSet(TelegramObject):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.name: str = name self.name: str = name
self.title: str = title self.title: str = title
self.stickers: Tuple[Sticker, ...] = parse_sequence_arg(stickers) self.stickers: tuple[Sticker, ...] = parse_sequence_arg(stickers)
self.sticker_type: str = sticker_type self.sticker_type: str = sticker_type
# Optional # Optional
self.thumbnail: Optional[PhotoSize] = thumbnail self.thumbnail: Optional[PhotoSize] = thumbnail

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Game.""" """This module contains an object that represents a Telegram Game."""
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._files.animation import Animation from telegram._files.animation import Animation
from telegram._files.photosize import PhotoSize from telegram._files.photosize import PhotoSize
@ -65,7 +66,7 @@ class Game(TelegramObject):
Attributes: Attributes:
title (:obj:`str`): Title of the game. title (:obj:`str`): Title of the game.
description (:obj:`str`): Description of the game. description (:obj:`str`): Description of the game.
photo (Tuple[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game photo (tuple[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game
message in chats. message in chats.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -76,7 +77,7 @@ class Game(TelegramObject):
when the bot calls :meth:`telegram.Bot.set_game_score`, or manually edited when the bot calls :meth:`telegram.Bot.set_game_score`, or manually edited
using :meth:`telegram.Bot.edit_message_text`. using :meth:`telegram.Bot.edit_message_text`.
0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters. 0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters.
text_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. Special entities that text_entities (tuple[:class:`telegram.MessageEntity`]): Optional. Special entities that
appear in text, such as usernames, URLs, bot commands, etc. appear in text, such as usernames, URLs, bot commands, etc.
This tuple is empty if the message does not contain text entities. This tuple is empty if the message does not contain text entities.
@ -112,10 +113,10 @@ class Game(TelegramObject):
# Required # Required
self.title: str = title self.title: str = title
self.description: str = description self.description: str = description
self.photo: Tuple[PhotoSize, ...] = parse_sequence_arg(photo) self.photo: tuple[PhotoSize, ...] = parse_sequence_arg(photo)
# Optionals # Optionals
self.text: Optional[str] = text self.text: Optional[str] = text
self.text_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(text_entities) self.text_entities: tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
self.animation: Optional[Animation] = animation self.animation: Optional[Animation] = animation
self._id_attrs = (self.title, self.description, self.photo) self._id_attrs = (self.title, self.description, self.photo)
@ -163,7 +164,7 @@ class Game(TelegramObject):
return entity_text.decode(TextEncoding.UTF_16_LE) return entity_text.decode(TextEncoding.UTF_16_LE)
def parse_text_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]: def parse_text_entities(self, types: Optional[list[str]] = None) -> dict[MessageEntity, str]:
""" """
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`. Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
It contains entities from this message filtered by their It contains entities from this message filtered by their
@ -176,13 +177,13 @@ class Game(TelegramObject):
See :attr:`parse_text_entity` for more info. See :attr:`parse_text_entity` for more info.
Args: Args:
types (List[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as types (list[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
strings. If the :attr:`~telegram.MessageEntity.type` attribute of an entity is strings. If the :attr:`~telegram.MessageEntity.type` attribute of an entity is
contained in this list, it will be returned. Defaults to contained in this list, it will be returned. Defaults to
:attr:`telegram.MessageEntity.ALL_TYPES`. :attr:`telegram.MessageEntity.ALL_TYPES`.
Returns: Returns:
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
the text that belongs to them, calculated based on UTF-16 codepoints. the text that belongs to them, calculated based on UTF-16 codepoints.
""" """

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an objects that are related to Telegram giveaways.""" """This module contains an objects that are related to Telegram giveaways."""
import datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._chat import Chat from telegram._chat import Chat
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -41,7 +42,7 @@ class Giveaway(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Args: Args:
chats (Tuple[:class:`telegram.Chat`]): The list of chats which the user must join to chats (tuple[:class:`telegram.Chat`]): The list of chats which the user must join to
participate in the giveaway. participate in the giveaway.
winners_selection_date (:class:`datetime.datetime`): The date when the giveaway winner will winners_selection_date (:class:`datetime.datetime`): The date when the giveaway winner will
be selected. |datetime_localization| be selected. |datetime_localization|
@ -76,7 +77,7 @@ class Giveaway(TelegramObject):
has_public_winners (:obj:`True`): Optional. :obj:`True`, if the list of giveaway winners has_public_winners (:obj:`True`): Optional. :obj:`True`, if the list of giveaway winners
will be visible to everyone will be visible to everyone
prize_description (:obj:`str`): Optional. Description of additional giveaway prize prize_description (:obj:`str`): Optional. Description of additional giveaway prize
country_codes (Tuple[:obj:`str`]): Optional. A tuple of two-letter ISO 3166-1 alpha-2 country_codes (tuple[:obj:`str`]): Optional. A tuple of two-letter ISO 3166-1 alpha-2
country codes indicating the countries from which eligible users for the giveaway must country codes indicating the countries from which eligible users for the giveaway must
come. If empty, then all users can participate in the giveaway. Users with a phone come. If empty, then all users can participate in the giveaway. Users with a phone
number that was bought on Fragment can always participate in giveaways. number that was bought on Fragment can always participate in giveaways.
@ -117,13 +118,13 @@ class Giveaway(TelegramObject):
): ):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.chats: Tuple[Chat, ...] = tuple(chats) self.chats: tuple[Chat, ...] = tuple(chats)
self.winners_selection_date: datetime.datetime = winners_selection_date self.winners_selection_date: datetime.datetime = winners_selection_date
self.winner_count: int = winner_count self.winner_count: int = winner_count
self.only_new_members: Optional[bool] = only_new_members self.only_new_members: Optional[bool] = only_new_members
self.has_public_winners: Optional[bool] = has_public_winners self.has_public_winners: Optional[bool] = has_public_winners
self.prize_description: Optional[str] = prize_description self.prize_description: Optional[str] = prize_description
self.country_codes: Tuple[str, ...] = parse_sequence_arg(country_codes) self.country_codes: tuple[str, ...] = parse_sequence_arg(country_codes)
self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count
self.prize_star_count: Optional[int] = prize_star_count self.prize_star_count: Optional[int] = prize_star_count
@ -222,7 +223,7 @@ class GiveawayWinners(TelegramObject):
winners_selection_date (:class:`datetime.datetime`): Point in time when winners of the winners_selection_date (:class:`datetime.datetime`): Point in time when winners of the
giveaway were selected. |datetime_localization| giveaway were selected. |datetime_localization|
winner_count (:obj:`int`): Total number of winners in the giveaway winner_count (:obj:`int`): Total number of winners in the giveaway
winners (Tuple[:class:`telegram.User`]): tuple of up to winners (tuple[:class:`telegram.User`]): tuple of up to
:tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway :tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway
additional_chat_count (:obj:`int`): Optional. The number of other chats the user had to additional_chat_count (:obj:`int`): Optional. The number of other chats the user had to
join in order to be eligible for the giveaway join in order to be eligible for the giveaway
@ -278,7 +279,7 @@ class GiveawayWinners(TelegramObject):
self.giveaway_message_id: int = giveaway_message_id self.giveaway_message_id: int = giveaway_message_id
self.winners_selection_date: datetime.datetime = winners_selection_date self.winners_selection_date: datetime.datetime = winners_selection_date
self.winner_count: int = winner_count self.winner_count: int = winner_count
self.winners: Tuple[User, ...] = tuple(winners) self.winners: tuple[User, ...] = tuple(winners)
self.additional_chat_count: Optional[int] = additional_chat_count self.additional_chat_count: Optional[int] = additional_chat_count
self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count
self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram InlineKeyboardMarkup.""" """This module contains an object that represents a Telegram InlineKeyboardMarkup."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -57,7 +58,7 @@ class InlineKeyboardMarkup(TelegramObject):
|sequenceclassargs| |sequenceclassargs|
Attributes: Attributes:
inline_keyboard (Tuple[Tuple[:class:`telegram.InlineKeyboardButton`]]): Tuple of inline_keyboard (tuple[tuple[:class:`telegram.InlineKeyboardButton`]]): Tuple of
button rows, each represented by a tuple of :class:`~telegram.InlineKeyboardButton` button rows, each represented by a tuple of :class:`~telegram.InlineKeyboardButton`
objects. objects.
@ -81,7 +82,7 @@ class InlineKeyboardMarkup(TelegramObject):
"InlineKeyboardButtons" "InlineKeyboardButtons"
) )
# Required # Required
self.inline_keyboard: Tuple[Tuple[InlineKeyboardButton, ...], ...] = tuple( self.inline_keyboard: tuple[tuple[InlineKeyboardButton, ...], ...] = tuple(
tuple(row) for row in inline_keyboard tuple(row) for row in inline_keyboard
) )

View file

@ -19,7 +19,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram InlineQuery.""" """This module contains an object that represents a Telegram InlineQuery."""
from typing import TYPE_CHECKING, Callable, Final, Optional, Sequence, Union from collections.abc import Sequence
from typing import TYPE_CHECKING, Callable, Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._files.location import Location from telegram._files.location import Location

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultAudio.""" """This module contains the classes that represent Telegram InlineQueryResultAudio."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -73,7 +74,7 @@ class InlineQueryResultAudio(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing. parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -124,6 +125,6 @@ class InlineQueryResultAudio(InlineQueryResult):
self.audio_duration: Optional[int] = audio_duration self.audio_duration: Optional[int] = audio_duration
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultCachedAudio.""" """This module contains the classes that represent Telegram InlineQueryResultCachedAudio."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -68,7 +69,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing. parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -110,6 +111,6 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
# Optionals # Optionals
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultCachedDocument.""" """This module contains the classes that represent Telegram InlineQueryResultCachedDocument."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -72,7 +73,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -120,6 +121,6 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
self.description: Optional[str] = description self.description: Optional[str] = description
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultCachedGif.""" """This module contains the classes that represent Telegram InlineQueryResultCachedGif."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -74,7 +75,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -124,7 +125,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
self.title: Optional[str] = title self.title: Optional[str] = title
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content
self.show_caption_above_media: Optional[bool] = show_caption_above_media self.show_caption_above_media: Optional[bool] = show_caption_above_media

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif.""" """This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -74,7 +75,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -124,7 +125,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
self.title: Optional[str] = title self.title: Optional[str] = title
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content
self.show_caption_above_media: Optional[bool] = show_caption_above_media self.show_caption_above_media: Optional[bool] = show_caption_above_media

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultPhoto""" """This module contains the classes that represent Telegram InlineQueryResultPhoto"""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -76,7 +77,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
entities parsing. entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -129,7 +130,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
self.description: Optional[str] = description self.description: Optional[str] = description
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content
self.show_caption_above_media: Optional[bool] = show_caption_above_media self.show_caption_above_media: Optional[bool] = show_caption_above_media

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultCachedVideo.""" """This module contains the classes that represent Telegram InlineQueryResultCachedVideo."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -72,7 +73,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
entities parsing. entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -125,7 +126,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
self.description: Optional[str] = description self.description: Optional[str] = description
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content
self.show_caption_above_media: Optional[bool] = show_caption_above_media self.show_caption_above_media: Optional[bool] = show_caption_above_media

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultCachedVoice.""" """This module contains the classes that represent Telegram InlineQueryResultCachedVoice."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -70,7 +71,7 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing. parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -115,6 +116,6 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
# Optionals # Optionals
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultDocument""" """This module contains the classes that represent Telegram InlineQueryResultDocument"""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -86,7 +87,7 @@ class InlineQueryResultDocument(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -155,7 +156,7 @@ class InlineQueryResultDocument(InlineQueryResult):
# Optionals # Optionals
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.description: Optional[str] = description self.description: Optional[str] = description
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultGif.""" """This module contains the classes that represent Telegram InlineQueryResultGif."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -102,7 +103,7 @@ class InlineQueryResultGif(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -166,7 +167,7 @@ class InlineQueryResultGif(InlineQueryResult):
self.title: Optional[str] = title self.title: Optional[str] = title
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif.""" """This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -104,7 +105,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing. after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -168,7 +169,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
self.title: Optional[str] = title self.title: Optional[str] = title
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultPhoto.""" """This module contains the classes that represent Telegram InlineQueryResultPhoto."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -92,7 +93,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
entities parsing. entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -154,7 +155,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
self.description: Optional[str] = description self.description: Optional[str] = description
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content
self.show_caption_above_media: Optional[bool] = show_caption_above_media self.show_caption_above_media: Optional[bool] = show_caption_above_media

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultVideo.""" """This module contains the classes that represent Telegram InlineQueryResultVideo."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -99,7 +100,7 @@ class InlineQueryResultVideo(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing. parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional.
|captionentitiesattr| |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -171,7 +172,7 @@ class InlineQueryResultVideo(InlineQueryResult):
# Optional # Optional
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.video_width: Optional[int] = video_width self.video_width: Optional[int] = video_width
self.video_height: Optional[int] = video_height self.video_height: Optional[int] = video_height
self.video_duration: Optional[int] = video_duration self.video_duration: Optional[int] = video_duration

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InlineQueryResultVoice.""" """This module contains the classes that represent Telegram InlineQueryResultVoice."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
from telegram._inline.inlinequeryresult import InlineQueryResult from telegram._inline.inlinequeryresult import InlineQueryResult
@ -72,7 +73,7 @@ class InlineQueryResultVoice(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing. parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -121,6 +122,6 @@ class InlineQueryResultVoice(InlineQueryResult):
self.voice_duration: Optional[int] = voice_duration self.voice_duration: Optional[int] = voice_duration
self.caption: Optional[str] = caption self.caption: Optional[str] = caption
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
self.input_message_content: Optional[InputMessageContent] = input_message_content self.input_message_content: Optional[InputMessageContent] = input_message_content

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a class that represents a Telegram InputInvoiceMessageContent.""" """This module contains a class that represents a Telegram InputInvoiceMessageContent."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inputmessagecontent import InputMessageContent from telegram._inline.inputmessagecontent import InputMessageContent
from telegram._payment.labeledprice import LabeledPrice from telegram._payment.labeledprice import LabeledPrice
@ -122,7 +123,7 @@ class InputInvoiceMessageContent(InputMessageContent):
currency (:obj:`str`): Three-letter ISO 4217 currency code, see more on currency (:obj:`str`): Three-letter ISO 4217 currency code, see more on
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_. `currencies <https://core.telegram.org/bots/payments#supported-currencies>`_.
Pass ``XTR`` for payments in |tg_stars|. Pass ``XTR`` for payments in |tg_stars|.
prices (Tuple[:class:`telegram.LabeledPrice`]): Price breakdown, a list of prices (tuple[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus,
etc.). Must contain exactly one item for payments in |tg_stars|. etc.). Must contain exactly one item for payments in |tg_stars|.
@ -135,7 +136,7 @@ class InputInvoiceMessageContent(InputMessageContent):
`currencies.json <https://core.telegram.org/bots/payments/currencies.json>`_, it `currencies.json <https://core.telegram.org/bots/payments/currencies.json>`_, it
shows the number of digits past the decimal point for each currency (2 for the majority shows the number of digits past the decimal point for each currency (2 for the majority
of currencies). Defaults to ``0``. Not supported for payments in |tg_stars|. of currencies). Defaults to ``0``. Not supported for payments in |tg_stars|.
suggested_tip_amounts (Tuple[:obj:`int`]): Optional. An array of suggested suggested_tip_amounts (tuple[:obj:`int`]): Optional. An array of suggested
amounts of tip in the *smallest units* of the currency (integer, **not** float/double). amounts of tip in the *smallest units* of the currency (integer, **not** float/double).
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be At most 4 suggested tip amounts can be specified. The suggested tip amounts must be
positive, passed in a strictly increased order and must not exceed positive, passed in a strictly increased order and must not exceed
@ -226,10 +227,10 @@ class InputInvoiceMessageContent(InputMessageContent):
self.payload: str = payload self.payload: str = payload
self.provider_token: Optional[str] = provider_token self.provider_token: Optional[str] = provider_token
self.currency: str = currency self.currency: str = currency
self.prices: Tuple[LabeledPrice, ...] = parse_sequence_arg(prices) self.prices: tuple[LabeledPrice, ...] = parse_sequence_arg(prices)
# Optionals # Optionals
self.max_tip_amount: Optional[int] = max_tip_amount self.max_tip_amount: Optional[int] = max_tip_amount
self.suggested_tip_amounts: Tuple[int, ...] = parse_sequence_arg(suggested_tip_amounts) self.suggested_tip_amounts: tuple[int, ...] = parse_sequence_arg(suggested_tip_amounts)
self.provider_data: Optional[str] = provider_data self.provider_data: Optional[str] = provider_data
self.photo_url: Optional[str] = photo_url self.photo_url: Optional[str] = photo_url
self.photo_size: Optional[int] = photo_size self.photo_size: Optional[int] = photo_size

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram InputTextMessageContent.""" """This module contains the classes that represent Telegram InputTextMessageContent."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._inline.inputmessagecontent import InputMessageContent from telegram._inline.inputmessagecontent import InputMessageContent
from telegram._messageentity import MessageEntity from telegram._messageentity import MessageEntity
@ -75,7 +76,7 @@ class InputTextMessageContent(InputMessageContent):
:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters after entities :tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters after entities
parsing. parsing.
parse_mode (:obj:`str`): Optional. |parse_mode| parse_mode (:obj:`str`): Optional. |parse_mode|
entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr| entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -107,7 +108,7 @@ class InputTextMessageContent(InputMessageContent):
self.message_text: str = message_text self.message_text: str = message_text
# Optionals # Optionals
self.parse_mode: ODVInput[str] = parse_mode self.parse_mode: ODVInput[str] = parse_mode
self.entities: Tuple[MessageEntity, ...] = parse_sequence_arg(entities) self.entities: tuple[MessageEntity, ...] = parse_sequence_arg(entities)
self.link_preview_options: ODVInput[LinkPreviewOptions] = parse_lpo_and_dwpp( self.link_preview_options: ODVInput[LinkPreviewOptions] = parse_lpo_and_dwpp(
disable_web_page_preview, link_preview_options disable_web_page_preview, link_preview_options
) )

View file

@ -17,7 +17,7 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains objects related to Telegram menu buttons.""" """This module contains objects related to Telegram menu buttons."""
from typing import TYPE_CHECKING, Dict, Final, Optional, Type from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -76,7 +76,7 @@ class MenuButton(TelegramObject):
care of selecting the correct subclass. care of selecting the correct subclass.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to
:obj:`None`, in which case shortcut methods will not be available. :obj:`None`, in which case shortcut methods will not be available.
@ -95,7 +95,7 @@ class MenuButton(TelegramObject):
if not data and cls is MenuButton: if not data and cls is MenuButton:
return None return None
_class_mapping: Dict[str, Type[MenuButton]] = { _class_mapping: dict[str, type[MenuButton]] = {
cls.COMMANDS: MenuButtonCommands, cls.COMMANDS: MenuButtonCommands,
cls.WEB_APP: MenuButtonWebApp, cls.WEB_APP: MenuButtonWebApp,
cls.DEFAULT: MenuButtonDefault, cls.DEFAULT: MenuButtonDefault,

View file

@ -21,8 +21,9 @@
import datetime import datetime
import re import re
from collections.abc import Sequence
from html import escape from html import escape
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Tuple, TypedDict, Union from typing import TYPE_CHECKING, Optional, TypedDict, Union
from telegram._chat import Chat from telegram._chat import Chat
from telegram._chatbackground import ChatBackground from telegram._chatbackground import ChatBackground
@ -629,7 +630,7 @@ class Message(MaybeInaccessibleMessage):
message belongs to. message belongs to.
text (:obj:`str`): Optional. For text messages, the actual UTF-8 text of the message, text (:obj:`str`): Optional. For text messages, the actual UTF-8 text of the message,
0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters. 0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters.
entities (Tuple[:class:`telegram.MessageEntity`]): Optional. For text messages, special entities (tuple[:class:`telegram.MessageEntity`]): Optional. For text messages, special
entities like usernames, URLs, bot commands, etc. that appear in the text. See entities like usernames, URLs, bot commands, etc. that appear in the text. See
:attr:`parse_entity` and :attr:`parse_entities` methods for how to use properly. :attr:`parse_entity` and :attr:`parse_entities` methods for how to use properly.
This list is empty if the message does not contain entities. This list is empty if the message does not contain entities.
@ -648,7 +649,7 @@ class Message(MaybeInaccessibleMessage):
..versionadded:: 21.3 ..versionadded:: 21.3
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. For messages with a caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. For messages with a
Caption. Special entities like usernames, URLs, bot commands, etc. that appear in the Caption. Special entities like usernames, URLs, bot commands, etc. that appear in the
caption. See :attr:`Message.parse_caption_entity` and :attr:`parse_caption_entities` caption. See :attr:`Message.parse_caption_entity` and :attr:`parse_caption_entities`
methods for how to use properly. This list is empty if the message does not contain methods for how to use properly. This list is empty if the message does not contain
@ -675,7 +676,7 @@ class Message(MaybeInaccessibleMessage):
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>` .. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
game (:class:`telegram.Game`): Optional. Message is a game, information about the game. game (:class:`telegram.Game`): Optional. Message is a game, information about the game.
:ref:`More about games >> <games-tree>`. :ref:`More about games >> <games-tree>`.
photo (Tuple[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available photo (tuple[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available
sizes of the photo. This list is empty if the message does not contain a photo. sizes of the photo. This list is empty if the message does not contain a photo.
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>` .. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
@ -703,7 +704,7 @@ class Message(MaybeInaccessibleMessage):
about the video message. about the video message.
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>` .. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
new_chat_members (Tuple[:class:`telegram.User`]): Optional. New members that were added new_chat_members (tuple[:class:`telegram.User`]): Optional. New members that were added
to the group or supergroup and information about them (the bot itself may be one of to the group or supergroup and information about them (the bot itself may be one of
these members). This list is empty if the message does not contain new chat members. these members). This list is empty if the message does not contain new chat members.
@ -722,7 +723,7 @@ class Message(MaybeInaccessibleMessage):
left_chat_member (:class:`telegram.User`): Optional. A member was removed from the group, left_chat_member (:class:`telegram.User`): Optional. A member was removed from the group,
information about them (this member may be the bot itself). information about them (this member may be the bot itself).
new_chat_title (:obj:`str`): Optional. A chat title was changed to this value. new_chat_title (:obj:`str`): Optional. A chat title was changed to this value.
new_chat_photo (Tuple[:class:`telegram.PhotoSize`]): A chat photo was changed to new_chat_photo (tuple[:class:`telegram.PhotoSize`]): A chat photo was changed to
this value. This list is empty if the message does not contain a new chat photo. this value. This list is empty if the message does not contain a new chat photo.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -1118,12 +1119,12 @@ class Message(MaybeInaccessibleMessage):
self.edit_date: Optional[datetime.datetime] = edit_date self.edit_date: Optional[datetime.datetime] = edit_date
self.has_protected_content: Optional[bool] = has_protected_content self.has_protected_content: Optional[bool] = has_protected_content
self.text: Optional[str] = text self.text: Optional[str] = text
self.entities: Tuple[MessageEntity, ...] = parse_sequence_arg(entities) self.entities: tuple[MessageEntity, ...] = parse_sequence_arg(entities)
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities) self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
self.audio: Optional[Audio] = audio self.audio: Optional[Audio] = audio
self.game: Optional[Game] = game self.game: Optional[Game] = game
self.document: Optional[Document] = document self.document: Optional[Document] = document
self.photo: Tuple[PhotoSize, ...] = parse_sequence_arg(photo) self.photo: tuple[PhotoSize, ...] = parse_sequence_arg(photo)
self.sticker: Optional[Sticker] = sticker self.sticker: Optional[Sticker] = sticker
self.video: Optional[Video] = video self.video: Optional[Video] = video
self.voice: Optional[Voice] = voice self.voice: Optional[Voice] = voice
@ -1132,10 +1133,10 @@ class Message(MaybeInaccessibleMessage):
self.contact: Optional[Contact] = contact self.contact: Optional[Contact] = contact
self.location: Optional[Location] = location self.location: Optional[Location] = location
self.venue: Optional[Venue] = venue self.venue: Optional[Venue] = venue
self.new_chat_members: Tuple[User, ...] = parse_sequence_arg(new_chat_members) self.new_chat_members: tuple[User, ...] = parse_sequence_arg(new_chat_members)
self.left_chat_member: Optional[User] = left_chat_member self.left_chat_member: Optional[User] = left_chat_member
self.new_chat_title: Optional[str] = new_chat_title self.new_chat_title: Optional[str] = new_chat_title
self.new_chat_photo: Tuple[PhotoSize, ...] = parse_sequence_arg(new_chat_photo) self.new_chat_photo: tuple[PhotoSize, ...] = parse_sequence_arg(new_chat_photo)
self.delete_chat_photo: Optional[bool] = bool(delete_chat_photo) self.delete_chat_photo: Optional[bool] = bool(delete_chat_photo)
self.group_chat_created: Optional[bool] = bool(group_chat_created) self.group_chat_created: Optional[bool] = bool(group_chat_created)
self.supergroup_chat_created: Optional[bool] = bool(supergroup_chat_created) self.supergroup_chat_created: Optional[bool] = bool(supergroup_chat_created)
@ -1406,7 +1407,7 @@ class Message(MaybeInaccessibleMessage):
* :class:`telegram.Invoice` * :class:`telegram.Invoice`
* :class:`telegram.Location` * :class:`telegram.Location`
* :class:`telegram.PassportData` * :class:`telegram.PassportData`
* List[:class:`telegram.PhotoSize`] * list[:class:`telegram.PhotoSize`]
* :class:`telegram.PaidMediaInfo` * :class:`telegram.PaidMediaInfo`
* :class:`telegram.Poll` * :class:`telegram.Poll`
* :class:`telegram.Sticker` * :class:`telegram.Sticker`
@ -1478,7 +1479,7 @@ class Message(MaybeInaccessibleMessage):
def compute_quote_position_and_entities( def compute_quote_position_and_entities(
self, quote: str, index: Optional[int] = None self, quote: str, index: Optional[int] = None
) -> Tuple[int, Optional[Tuple[MessageEntity, ...]]]: ) -> tuple[int, Optional[tuple[MessageEntity, ...]]]:
""" """
Use this function to compute position and entities of a quote in the message text or Use this function to compute position and entities of a quote in the message text or
caption. Useful for filling the parameters caption. Useful for filling the parameters
@ -1504,7 +1505,7 @@ class Message(MaybeInaccessibleMessage):
message. If not specified, the first occurrence is used. message. If not specified, the first occurrence is used.
Returns: Returns:
Tuple[:obj:`int`, :obj:`None` | Tuple[:class:`~telegram.MessageEntity`, ...]]: On tuple[:obj:`int`, :obj:`None` | tuple[:class:`~telegram.MessageEntity`, ...]]: On
success, a tuple containing information about quote position and entities is returned. success, a tuple containing information about quote position and entities is returned.
Raises: Raises:
@ -1647,7 +1648,7 @@ class Message(MaybeInaccessibleMessage):
quote: Optional[bool], quote: Optional[bool],
reply_to_message_id: Optional[int], reply_to_message_id: Optional[int],
reply_parameters: Optional["ReplyParameters"], reply_parameters: Optional["ReplyParameters"],
) -> Tuple[Union[str, int], ReplyParameters]: ) -> tuple[Union[str, int], ReplyParameters]:
if quote and do_quote: if quote and do_quote:
raise ValueError("The arguments `quote` and `do_quote` are mutually exclusive") raise ValueError("The arguments `quote` and `do_quote` are mutually exclusive")
@ -2048,7 +2049,7 @@ class Message(MaybeInaccessibleMessage):
caption: Optional[str] = None, caption: Optional[str] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE, parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None, caption_entities: Optional[Sequence["MessageEntity"]] = None,
) -> Tuple["Message", ...]: ) -> tuple["Message", ...]:
"""Shortcut for:: """Shortcut for::
await bot.send_media_group( await bot.send_media_group(
@ -2075,7 +2076,7 @@ class Message(MaybeInaccessibleMessage):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.Message`]: An array of the sent Messages. tuple[:class:`telegram.Message`]: An array of the sent Messages.
Raises: Raises:
:class:`telegram.error.TelegramError` :class:`telegram.error.TelegramError`
@ -3989,7 +3990,7 @@ class Message(MaybeInaccessibleMessage):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["GameHighScore", ...]: ) -> tuple["GameHighScore", ...]:
"""Shortcut for:: """Shortcut for::
await bot.get_game_high_scores( await bot.get_game_high_scores(
@ -4005,7 +4006,7 @@ class Message(MaybeInaccessibleMessage):
behaviour is undocumented and might be changed by Telegram. behaviour is undocumented and might be changed by Telegram.
Returns: Returns:
Tuple[:class:`telegram.GameHighScore`] tuple[:class:`telegram.GameHighScore`]
""" """
return await self.get_bot().get_game_high_scores( return await self.get_bot().get_game_high_scores(
chat_id=self.chat_id, chat_id=self.chat_id,
@ -4431,7 +4432,7 @@ class Message(MaybeInaccessibleMessage):
return parse_message_entity(self.caption, entity) return parse_message_entity(self.caption, entity)
def parse_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]: def parse_entities(self, types: Optional[list[str]] = None) -> dict[MessageEntity, str]:
""" """
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`. Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
It contains entities from this message filtered by their It contains entities from this message filtered by their
@ -4444,21 +4445,21 @@ class Message(MaybeInaccessibleMessage):
See :attr:`parse_entity` for more info. See :attr:`parse_entity` for more info.
Args: Args:
types (List[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as types (list[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
strings. If the ``type`` attribute of an entity is contained in this list, it will strings. If the ``type`` attribute of an entity is contained in this list, it will
be returned. Defaults to a list of all types. All types can be found as constants be returned. Defaults to a list of all types. All types can be found as constants
in :class:`telegram.MessageEntity`. in :class:`telegram.MessageEntity`.
Returns: Returns:
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
the text that belongs to them, calculated based on UTF-16 codepoints. the text that belongs to them, calculated based on UTF-16 codepoints.
""" """
return parse_message_entities(self.text, self.entities, types=types) return parse_message_entities(self.text, self.entities, types=types)
def parse_caption_entities( def parse_caption_entities(
self, types: Optional[List[str]] = None self, types: Optional[list[str]] = None
) -> Dict[MessageEntity, str]: ) -> dict[MessageEntity, str]:
""" """
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`. Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
It contains entities from this message's caption filtered by their It contains entities from this message's caption filtered by their
@ -4471,13 +4472,13 @@ class Message(MaybeInaccessibleMessage):
codepoints. See :attr:`parse_entity` for more info. codepoints. See :attr:`parse_entity` for more info.
Args: Args:
types (List[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as types (list[:obj:`str`], optional): List of :class:`telegram.MessageEntity` types as
strings. If the ``type`` attribute of an entity is contained in this list, it will strings. If the ``type`` attribute of an entity is contained in this list, it will
be returned. Defaults to a list of all types. All types can be found as constants be returned. Defaults to a list of all types. All types can be found as constants
in :class:`telegram.MessageEntity`. in :class:`telegram.MessageEntity`.
Returns: Returns:
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
the text that belongs to them, calculated based on UTF-16 codepoints. the text that belongs to them, calculated based on UTF-16 codepoints.
""" """
@ -4487,7 +4488,7 @@ class Message(MaybeInaccessibleMessage):
def _parse_html( def _parse_html(
cls, cls,
message_text: Optional[str], message_text: Optional[str],
entities: Dict[MessageEntity, str], entities: dict[MessageEntity, str],
urled: bool = False, urled: bool = False,
offset: int = 0, offset: int = 0,
) -> Optional[str]: ) -> Optional[str]:
@ -4676,7 +4677,7 @@ class Message(MaybeInaccessibleMessage):
def _parse_markdown( def _parse_markdown(
cls, cls,
message_text: Optional[str], message_text: Optional[str],
entities: Dict[MessageEntity, str], entities: dict[MessageEntity, str],
urled: bool = False, urled: bool = False,
version: MarkdownVersion = 1, version: MarkdownVersion = 1,
offset: int = 0, offset: int = 0,

View file

@ -20,7 +20,8 @@
import copy import copy
import itertools import itertools
from typing import TYPE_CHECKING, Dict, Final, List, Optional, Sequence, Tuple, Union from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -200,7 +201,7 @@ class MessageEntity(TelegramObject):
accumulated_length = 0 accumulated_length = 0
# calculate the length of each slice text[:position] in utf-16 accordingly, # calculate the length of each slice text[:position] in utf-16 accordingly,
# store the position translations # store the position translations
position_translation: Dict[int, int] = {} position_translation: dict[int, int] = {}
for i, position in enumerate(positions): for i, position in enumerate(positions):
last_position = positions[i - 1] if i > 0 else 0 last_position = positions[i - 1] if i > 0 else 0
text_slice = text[last_position:position] text_slice = text[last_position:position]
@ -286,8 +287,8 @@ class MessageEntity(TelegramObject):
@classmethod @classmethod
def concatenate( def concatenate(
cls, cls,
*args: Union[Tuple[str, _SEM], Tuple[str, _SEM, bool]], *args: Union[tuple[str, _SEM], tuple[str, _SEM, bool]],
) -> Tuple[str, _SEM]: ) -> tuple[str, _SEM]:
"""Utility functionality for concatenating two text along with their formatting entities. """Utility functionality for concatenating two text along with their formatting entities.
Tip: Tip:
@ -332,8 +333,8 @@ class MessageEntity(TelegramObject):
.. versionadded:: 21.5 .. versionadded:: 21.5
Args: Args:
*args (Tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]] | \ *args (tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]] | \
Tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`], :obj:`bool`]): tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`], :obj:`bool`]):
Arbitrary number of tuples containing the text and its entities to concatenate. Arbitrary number of tuples containing the text and its entities to concatenate.
If the last element of the tuple is a :obj:`bool`, it is used to determine whether If the last element of the tuple is a :obj:`bool`, it is used to determine whether
to adjust the entities to UTF-16 via to adjust the entities to UTF-16 via
@ -341,11 +342,11 @@ class MessageEntity(TelegramObject):
default. default.
Returns: Returns:
Tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]]: The concatenated text tuple[:obj:`str`, Sequence[:class:`telegram.MessageEntity`]]: The concatenated text
and its entities and its entities
""" """
output_text = "" output_text = ""
output_entities: List[MessageEntity] = [] output_entities: list[MessageEntity] = []
for arg in args: for arg in args:
text, entities = arg[0], arg[1] text, entities = arg[0], arg[1]
@ -357,8 +358,8 @@ class MessageEntity(TelegramObject):
return output_text, output_entities return output_text, output_entities
ALL_TYPES: Final[List[str]] = list(constants.MessageEntityType) ALL_TYPES: Final[list[str]] = list(constants.MessageEntityType)
"""List[:obj:`str`]: A list of all available message entity types.""" """list[:obj:`str`]: A list of all available message entity types."""
BLOCKQUOTE: Final[str] = constants.MessageEntityType.BLOCKQUOTE BLOCKQUOTE: Final[str] = constants.MessageEntityType.BLOCKQUOTE
""":const:`telegram.constants.MessageEntityType.BLOCKQUOTE` """:const:`telegram.constants.MessageEntityType.BLOCKQUOTE`

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the classes that represent Telegram MessageOigin.""" """This module contains the classes that represent Telegram MessageOigin."""
import datetime import datetime
from typing import TYPE_CHECKING, Dict, Final, Optional, Type from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._chat import Chat from telegram._chat import Chat
@ -105,7 +105,7 @@ class MessageOrigin(TelegramObject):
if not data: if not data:
return None return None
_class_mapping: Dict[str, Type[MessageOrigin]] = { _class_mapping: dict[str, type[MessageOrigin]] = {
cls.USER: MessageOriginUser, cls.USER: MessageOriginUser,
cls.HIDDEN_USER: MessageOriginHiddenUser, cls.HIDDEN_USER: MessageOriginHiddenUser,
cls.CHAT: MessageOriginChat, cls.CHAT: MessageOriginChat,

View file

@ -17,8 +17,9 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram MessageReaction Update.""" """This module contains an object that represents a Telegram MessageReaction Update."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from typing import TYPE_CHECKING, Optional
from telegram._chat import Chat from telegram._chat import Chat
from telegram._reaction import ReactionCount, ReactionType from telegram._reaction import ReactionCount, ReactionType
@ -54,7 +55,7 @@ class MessageReactionCountUpdated(TelegramObject):
message_id (:obj:`int`): Unique message identifier inside the chat. message_id (:obj:`int`): Unique message identifier inside the chat.
date (:class:`datetime.datetime`): Date of the change in Unix time date (:class:`datetime.datetime`): Date of the change in Unix time
|datetime_localization| |datetime_localization|
reactions (Tuple[:class:`telegram.ReactionCount`]): List of reactions that are present on reactions (tuple[:class:`telegram.ReactionCount`]): List of reactions that are present on
the message the message
""" """
@ -79,7 +80,7 @@ class MessageReactionCountUpdated(TelegramObject):
self.chat: Chat = chat self.chat: Chat = chat
self.message_id: int = message_id self.message_id: int = message_id
self.date: datetime = date self.date: datetime = date
self.reactions: Tuple[ReactionCount, ...] = parse_sequence_arg(reactions) self.reactions: tuple[ReactionCount, ...] = parse_sequence_arg(reactions)
self._id_attrs = (self.chat, self.message_id, self.date, self.reactions) self._id_attrs = (self.chat, self.message_id, self.date, self.reactions)
self._freeze() self._freeze()
@ -132,9 +133,9 @@ class MessageReactionUpdated(TelegramObject):
message_id (:obj:`int`): Unique message identifier inside the chat. message_id (:obj:`int`): Unique message identifier inside the chat.
date (:class:`datetime.datetime`): Date of the change in Unix time. date (:class:`datetime.datetime`): Date of the change in Unix time.
|datetime_localization| |datetime_localization|
old_reaction (Tuple[:class:`telegram.ReactionType`]): Previous list of reaction types old_reaction (tuple[:class:`telegram.ReactionType`]): Previous list of reaction types
that were set by the user. that were set by the user.
new_reaction (Tuple[:class:`telegram.ReactionType`]): New list of reaction types that new_reaction (tuple[:class:`telegram.ReactionType`]): New list of reaction types that
were set by the user. were set by the user.
user (:class:`telegram.User`): Optional. The user that changed the reaction, if the user user (:class:`telegram.User`): Optional. The user that changed the reaction, if the user
isn't anonymous. isn't anonymous.
@ -169,8 +170,8 @@ class MessageReactionUpdated(TelegramObject):
self.chat: Chat = chat self.chat: Chat = chat
self.message_id: int = message_id self.message_id: int = message_id
self.date: datetime = date self.date: datetime = date
self.old_reaction: Tuple[ReactionType, ...] = parse_sequence_arg(old_reaction) self.old_reaction: tuple[ReactionType, ...] = parse_sequence_arg(old_reaction)
self.new_reaction: Tuple[ReactionType, ...] = parse_sequence_arg(new_reaction) self.new_reaction: tuple[ReactionType, ...] = parse_sequence_arg(new_reaction)
# Optional # Optional
self.user: Optional[User] = user self.user: Optional[User] = user

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains objects that represent paid media in Telegram.""" """This module contains objects that represent paid media in Telegram."""
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._files.photosize import PhotoSize from telegram._files.photosize import PhotoSize
@ -81,7 +82,7 @@ class PaidMedia(TelegramObject):
care of selecting the correct subclass. care of selecting the correct subclass.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`, optional): The bot associated with this object. bot (:class:`telegram.Bot`, optional): The bot associated with this object.
Returns: Returns:
@ -96,7 +97,7 @@ class PaidMedia(TelegramObject):
if not data and cls is PaidMedia: if not data and cls is PaidMedia:
return None return None
_class_mapping: Dict[str, Type[PaidMedia]] = { _class_mapping: dict[str, type[PaidMedia]] = {
cls.PREVIEW: PaidMediaPreview, cls.PREVIEW: PaidMediaPreview,
cls.PHOTO: PaidMediaPhoto, cls.PHOTO: PaidMediaPhoto,
cls.VIDEO: PaidMediaVideo, cls.VIDEO: PaidMediaVideo,
@ -165,7 +166,7 @@ class PaidMediaPhoto(PaidMedia):
Attributes: Attributes:
type (:obj:`str`): Type of the paid media, always :tg-const:`telegram.PaidMedia.PHOTO`. type (:obj:`str`): Type of the paid media, always :tg-const:`telegram.PaidMedia.PHOTO`.
photo (Tuple[:class:`telegram.PhotoSize`]): The photo. photo (tuple[:class:`telegram.PhotoSize`]): The photo.
""" """
__slots__ = ("photo",) __slots__ = ("photo",)
@ -179,7 +180,7 @@ class PaidMediaPhoto(PaidMedia):
super().__init__(type=PaidMedia.PHOTO, api_kwargs=api_kwargs) super().__init__(type=PaidMedia.PHOTO, api_kwargs=api_kwargs)
with self._unfrozen(): with self._unfrozen():
self.photo: Tuple[PhotoSize, ...] = parse_sequence_arg(photo) self.photo: tuple[PhotoSize, ...] = parse_sequence_arg(photo)
self._id_attrs = (self.type, self.photo) self._id_attrs = (self.type, self.photo)
@ -259,7 +260,7 @@ class PaidMediaInfo(TelegramObject):
Attributes: Attributes:
star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access to star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access to
the media. the media.
paid_media (Tuple[:class:`telegram.PaidMedia`]): Information about the paid media. paid_media (tuple[:class:`telegram.PaidMedia`]): Information about the paid media.
""" """
__slots__ = ("paid_media", "star_count") __slots__ = ("paid_media", "star_count")
@ -273,7 +274,7 @@ class PaidMediaInfo(TelegramObject):
) -> None: ) -> None:
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.star_count: int = star_count self.star_count: int = star_count
self.paid_media: Tuple[PaidMedia, ...] = parse_sequence_arg(paid_media) self.paid_media: tuple[PaidMedia, ...] = parse_sequence_arg(paid_media)
self._id_attrs = (self.star_count, self.paid_media) self._id_attrs = (self.star_count, self.paid_media)
self._freeze() self._freeze()

View file

@ -19,7 +19,8 @@
# pylint: disable=missing-module-docstring, redefined-builtin # pylint: disable=missing-module-docstring, redefined-builtin
import json import json
from base64 import b64decode from base64 import b64decode
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, no_type_check from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional, no_type_check
try: try:
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
@ -390,11 +391,11 @@ class SecureValue(TelegramObject):
selfie (:class:`telegram.FileCredentials`, optional): Credentials for encrypted selfie selfie (:class:`telegram.FileCredentials`, optional): Credentials for encrypted selfie
of the user with a document. Can be available for "passport", "driver_license", of the user with a document. Can be available for "passport", "driver_license",
"identity_card" and "internal_passport". "identity_card" and "internal_passport".
translation (List[:class:`telegram.FileCredentials`], optional): Credentials for an translation (list[:class:`telegram.FileCredentials`], optional): Credentials for an
encrypted translation of the document. Available for "passport", "driver_license", encrypted translation of the document. Available for "passport", "driver_license",
"identity_card", "internal_passport", "utility_bill", "bank_statement", "identity_card", "internal_passport", "utility_bill", "bank_statement",
"rental_agreement", "passport_registration" and "temporary_registration". "rental_agreement", "passport_registration" and "temporary_registration".
files (List[:class:`telegram.FileCredentials`], optional): Credentials for encrypted files (list[:class:`telegram.FileCredentials`], optional): Credentials for encrypted
files. Available for "utility_bill", "bank_statement", "rental_agreement", files. Available for "utility_bill", "bank_statement", "rental_agreement",
"passport_registration" and "temporary_registration" types. "passport_registration" and "temporary_registration" types.
@ -410,7 +411,7 @@ class SecureValue(TelegramObject):
selfie (:class:`telegram.FileCredentials`): Optional. Credentials for encrypted selfie selfie (:class:`telegram.FileCredentials`): Optional. Credentials for encrypted selfie
of the user with a document. Can be available for "passport", "driver_license", of the user with a document. Can be available for "passport", "driver_license",
"identity_card" and "internal_passport". "identity_card" and "internal_passport".
translation (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for an translation (tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for an
encrypted translation of the document. Available for "passport", "driver_license", encrypted translation of the document. Available for "passport", "driver_license",
"identity_card", "internal_passport", "utility_bill", "bank_statement", "identity_card", "internal_passport", "utility_bill", "bank_statement",
"rental_agreement", "passport_registration" and "temporary_registration". "rental_agreement", "passport_registration" and "temporary_registration".
@ -418,7 +419,7 @@ class SecureValue(TelegramObject):
.. versionchanged:: 20.0 .. versionchanged:: 20.0
|tupleclassattrs| |tupleclassattrs|
files (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for encrypted files (tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for encrypted
files. Available for "utility_bill", "bank_statement", "rental_agreement", files. Available for "utility_bill", "bank_statement", "rental_agreement",
"passport_registration" and "temporary_registration" types. "passport_registration" and "temporary_registration" types.
@ -447,8 +448,8 @@ class SecureValue(TelegramObject):
self.front_side: Optional[FileCredentials] = front_side self.front_side: Optional[FileCredentials] = front_side
self.reverse_side: Optional[FileCredentials] = reverse_side self.reverse_side: Optional[FileCredentials] = reverse_side
self.selfie: Optional[FileCredentials] = selfie self.selfie: Optional[FileCredentials] = selfie
self.files: Tuple[FileCredentials, ...] = parse_sequence_arg(files) self.files: tuple[FileCredentials, ...] = parse_sequence_arg(files)
self.translation: Tuple[FileCredentials, ...] = parse_sequence_arg(translation) self.translation: tuple[FileCredentials, ...] = parse_sequence_arg(translation)
self._freeze() self._freeze()

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram EncryptedPassportElement.""" """This module contains an object that represents a Telegram EncryptedPassportElement."""
from base64 import b64decode from base64 import b64decode
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, Union from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional, Union
from telegram._passport.credentials import decrypt_json from telegram._passport.credentials import decrypt_json
from telegram._passport.data import IdDocumentData, PersonalDetails, ResidentialAddress from telegram._passport.data import IdDocumentData, PersonalDetails, ResidentialAddress
@ -100,7 +101,7 @@ class EncryptedPassportElement(TelegramObject):
"phone_number" type. "phone_number" type.
email (:obj:`str`): Optional. User's verified email address; available only for "email" email (:obj:`str`): Optional. User's verified email address; available only for "email"
type. type.
files (Tuple[:class:`telegram.PassportFile`]): Optional. Array of encrypted/decrypted files (tuple[:class:`telegram.PassportFile`]): Optional. Array of encrypted/decrypted
files with documents provided by the user; available only for "utility_bill", files with documents provided by the user; available only for "utility_bill",
"bank_statement", "rental_agreement", "passport_registration" and "bank_statement", "rental_agreement", "passport_registration" and
"temporary_registration" types. "temporary_registration" types.
@ -119,7 +120,7 @@ class EncryptedPassportElement(TelegramObject):
selfie (:class:`telegram.PassportFile`): Optional. Encrypted/decrypted file with the selfie (:class:`telegram.PassportFile`): Optional. Encrypted/decrypted file with the
selfie of the user holding a document, provided by the user; available if requested for selfie of the user holding a document, provided by the user; available if requested for
"passport", "driver_license", "identity_card" and "internal_passport". "passport", "driver_license", "identity_card" and "internal_passport".
translation (Tuple[:class:`telegram.PassportFile`]): Optional. Array of translation (tuple[:class:`telegram.PassportFile`]): Optional. Array of
encrypted/decrypted files with translated versions of documents provided by the user; encrypted/decrypted files with translated versions of documents provided by the user;
available if requested for "passport", "driver_license", "identity_card", available if requested for "passport", "driver_license", "identity_card",
"internal_passport", "utility_bill", "bank_statement", "rental_agreement", "internal_passport", "utility_bill", "bank_statement", "rental_agreement",
@ -172,11 +173,11 @@ class EncryptedPassportElement(TelegramObject):
self.data: Optional[Union[PersonalDetails, IdDocumentData, ResidentialAddress]] = data self.data: Optional[Union[PersonalDetails, IdDocumentData, ResidentialAddress]] = data
self.phone_number: Optional[str] = phone_number self.phone_number: Optional[str] = phone_number
self.email: Optional[str] = email self.email: Optional[str] = email
self.files: Tuple[PassportFile, ...] = parse_sequence_arg(files) self.files: tuple[PassportFile, ...] = parse_sequence_arg(files)
self.front_side: Optional[PassportFile] = front_side self.front_side: Optional[PassportFile] = front_side
self.reverse_side: Optional[PassportFile] = reverse_side self.reverse_side: Optional[PassportFile] = reverse_side
self.selfie: Optional[PassportFile] = selfie self.selfie: Optional[PassportFile] = selfie
self.translation: Tuple[PassportFile, ...] = parse_sequence_arg(translation) self.translation: tuple[PassportFile, ...] = parse_sequence_arg(translation)
self.hash: str = hash self.hash: str = hash
self._id_attrs = ( self._id_attrs = (
@ -218,7 +219,7 @@ class EncryptedPassportElement(TelegramObject):
passport credentials. passport credentials.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot` | :obj:`None`): The bot associated with these object. bot (:class:`telegram.Bot` | :obj:`None`): The bot associated with these object.
May be :obj:`None`, in which case shortcut methods will not be available. May be :obj:`None`, in which case shortcut methods will not be available.

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""Contains information about Telegram Passport data shared with the bot by the user.""" """Contains information about Telegram Passport data shared with the bot by the user."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._passport.credentials import EncryptedCredentials from telegram._passport.credentials import EncryptedCredentials
from telegram._passport.encryptedpassportelement import EncryptedPassportElement from telegram._passport.encryptedpassportelement import EncryptedPassportElement
@ -49,7 +50,7 @@ class PassportData(TelegramObject):
credentials (:class:`telegram.EncryptedCredentials`)): Encrypted credentials. credentials (:class:`telegram.EncryptedCredentials`)): Encrypted credentials.
Attributes: Attributes:
data (Tuple[:class:`telegram.EncryptedPassportElement`]): Array with encrypted data (tuple[:class:`telegram.EncryptedPassportElement`]): Array with encrypted
information about documents and other Telegram Passport elements that was shared with information about documents and other Telegram Passport elements that was shared with
the bot. the bot.
@ -72,10 +73,10 @@ class PassportData(TelegramObject):
): ):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.data: Tuple[EncryptedPassportElement, ...] = parse_sequence_arg(data) self.data: tuple[EncryptedPassportElement, ...] = parse_sequence_arg(data)
self.credentials: EncryptedCredentials = credentials self.credentials: EncryptedCredentials = credentials
self._decrypted_data: Optional[Tuple[EncryptedPassportElement]] = None self._decrypted_data: Optional[tuple[EncryptedPassportElement]] = None
self._id_attrs = tuple([x.type for x in data] + [credentials.hash]) self._id_attrs = tuple([x.type for x in data] + [credentials.hash])
self._freeze() self._freeze()
@ -96,9 +97,9 @@ class PassportData(TelegramObject):
return super().de_json(data=data, bot=bot) return super().de_json(data=data, bot=bot)
@property @property
def decrypted_data(self) -> Tuple[EncryptedPassportElement, ...]: def decrypted_data(self) -> tuple[EncryptedPassportElement, ...]:
""" """
Tuple[:class:`telegram.EncryptedPassportElement`]: Lazily decrypt and return information tuple[:class:`telegram.EncryptedPassportElement`]: Lazily decrypt and return information
about documents and other Telegram Passport elements which were shared with the bot. about documents and other Telegram Passport elements which were shared with the bot.
.. versionchanged:: 20.0 .. versionchanged:: 20.0

View file

@ -19,7 +19,7 @@
# pylint: disable=redefined-builtin # pylint: disable=redefined-builtin
"""This module contains the classes that represent Telegram PassportElementError.""" """This module contains the classes that represent Telegram PassportElementError."""
from typing import List, Optional from typing import Optional
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict from telegram._utils.types import JSONDict
@ -168,7 +168,7 @@ class PassportElementErrorFiles(PassportElementError):
type (:obj:`str`): The section of the user's Telegram Passport which has the issue, one of type (:obj:`str`): The section of the user's Telegram Passport which has the issue, one of
``"utility_bill"``, ``"bank_statement"``, ``"rental_agreement"``, ``"utility_bill"``, ``"bank_statement"``, ``"rental_agreement"``,
``"passport_registration"``, ``"temporary_registration"``. ``"passport_registration"``, ``"temporary_registration"``.
file_hashes (List[:obj:`str`]): List of base64-encoded file hashes. file_hashes (list[:obj:`str`]): List of base64-encoded file hashes.
message (:obj:`str`): Error message. message (:obj:`str`): Error message.
Attributes: Attributes:
@ -184,7 +184,7 @@ class PassportElementErrorFiles(PassportElementError):
def __init__( def __init__(
self, self,
type: str, type: str,
file_hashes: List[str], file_hashes: list[str],
message: str, message: str,
*, *,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
@ -192,7 +192,7 @@ class PassportElementErrorFiles(PassportElementError):
# Required # Required
super().__init__("files", type, message, api_kwargs=api_kwargs) super().__init__("files", type, message, api_kwargs=api_kwargs)
with self._unfrozen(): with self._unfrozen():
self._file_hashes: List[str] = file_hashes self._file_hashes: list[str] = file_hashes
self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes)) self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes))
@ -203,7 +203,7 @@ class PassportElementErrorFiles(PassportElementError):
return data return data
@property @property
def file_hashes(self) -> List[str]: def file_hashes(self) -> list[str]:
"""List of base64-encoded file hashes. """List of base64-encoded file hashes.
.. deprecated:: 20.6 .. deprecated:: 20.6
@ -386,7 +386,7 @@ class PassportElementErrorTranslationFiles(PassportElementError):
one of ``"passport"``, ``"driver_license"``, ``"identity_card"``, one of ``"passport"``, ``"driver_license"``, ``"identity_card"``,
``"internal_passport"``, ``"utility_bill"``, ``"bank_statement"``, ``"internal_passport"``, ``"utility_bill"``, ``"bank_statement"``,
``"rental_agreement"``, ``"passport_registration"``, ``"temporary_registration"``. ``"rental_agreement"``, ``"passport_registration"``, ``"temporary_registration"``.
file_hashes (List[:obj:`str`]): List of base64-encoded file hashes. file_hashes (list[:obj:`str`]): List of base64-encoded file hashes.
message (:obj:`str`): Error message. message (:obj:`str`): Error message.
Attributes: Attributes:
@ -403,7 +403,7 @@ class PassportElementErrorTranslationFiles(PassportElementError):
def __init__( def __init__(
self, self,
type: str, type: str,
file_hashes: List[str], file_hashes: list[str],
message: str, message: str,
*, *,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
@ -411,7 +411,7 @@ class PassportElementErrorTranslationFiles(PassportElementError):
# Required # Required
super().__init__("translation_files", type, message, api_kwargs=api_kwargs) super().__init__("translation_files", type, message, api_kwargs=api_kwargs)
with self._unfrozen(): with self._unfrozen():
self._file_hashes: List[str] = file_hashes self._file_hashes: list[str] = file_hashes
self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes)) self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes))
@ -422,7 +422,7 @@ class PassportElementErrorTranslationFiles(PassportElementError):
return data return data
@property @property
def file_hashes(self) -> List[str]: def file_hashes(self) -> list[str]:
"""List of base64-encoded file hashes. """List of base64-encoded file hashes.
.. deprecated:: 20.6 .. deprecated:: 20.6

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Encrypted PassportFile.""" """This module contains an object that represents a Encrypted PassportFile."""
from typing import TYPE_CHECKING, List, Optional, Tuple from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
from telegram._utils.defaultvalue import DEFAULT_NONE from telegram._utils.defaultvalue import DEFAULT_NONE
@ -124,7 +124,7 @@ class PassportFile(TelegramObject):
passport credentials. passport credentials.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot` | :obj:`None`): The bot associated with these object. bot (:class:`telegram.Bot` | :obj:`None`): The bot associated with these object.
May be :obj:`None`, in which case shortcut methods will not be available. May be :obj:`None`, in which case shortcut methods will not be available.
@ -151,10 +151,10 @@ class PassportFile(TelegramObject):
@classmethod @classmethod
def de_list_decrypted( def de_list_decrypted(
cls, cls,
data: Optional[List[JSONDict]], data: Optional[list[JSONDict]],
bot: Optional["Bot"], bot: Optional["Bot"],
credentials: List["FileCredentials"], credentials: list["FileCredentials"],
) -> Tuple[Optional["PassportFile"], ...]: ) -> tuple[Optional["PassportFile"], ...]:
"""Variant of :meth:`telegram.TelegramObject.de_list` that also takes into account """Variant of :meth:`telegram.TelegramObject.de_list` that also takes into account
passport credentials. passport credentials.
@ -164,7 +164,7 @@ class PassportFile(TelegramObject):
* Filters out any :obj:`None` values * Filters out any :obj:`None` values
Args: Args:
data (List[Dict[:obj:`str`, ...]]): The JSON data. data (list[dict[:obj:`str`, ...]]): The JSON data.
bot (:class:`telegram.Bot` | :obj:`None`): The bot associated with these object. bot (:class:`telegram.Bot` | :obj:`None`): The bot associated with these object.
May be :obj:`None`, in which case shortcut methods will not be available. May be :obj:`None`, in which case shortcut methods will not be available.
@ -176,7 +176,7 @@ class PassportFile(TelegramObject):
credentials (:class:`telegram.FileCredentials`): The credentials credentials (:class:`telegram.FileCredentials`): The credentials
Returns: Returns:
Tuple[:class:`telegram.PassportFile`]: tuple[:class:`telegram.PassportFile`]:
""" """
if not data: if not data:

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram ShippingOption.""" """This module contains an object that represents a Telegram ShippingOption."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
from telegram._utils.argumentparsing import parse_sequence_arg from telegram._utils.argumentparsing import parse_sequence_arg
@ -47,7 +48,7 @@ class ShippingOption(TelegramObject):
Attributes: Attributes:
id (:obj:`str`): Shipping option identifier. id (:obj:`str`): Shipping option identifier.
title (:obj:`str`): Option title. title (:obj:`str`): Option title.
prices (Tuple[:class:`telegram.LabeledPrice`]): List of price portions. prices (tuple[:class:`telegram.LabeledPrice`]): List of price portions.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
|tupleclassattrs| |tupleclassattrs|
@ -68,7 +69,7 @@ class ShippingOption(TelegramObject):
self.id: str = id self.id: str = id
self.title: str = title self.title: str = title
self.prices: Tuple[LabeledPrice, ...] = parse_sequence_arg(prices) self.prices: tuple[LabeledPrice, ...] = parse_sequence_arg(prices)
self._id_attrs = (self.id,) self._id_attrs = (self.id,)

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram ShippingQuery.""" """This module contains an object that represents a Telegram ShippingQuery."""
from typing import TYPE_CHECKING, Optional, Sequence from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._payment.shippingaddress import ShippingAddress from telegram._payment.shippingaddress import ShippingAddress
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject

View file

@ -19,8 +19,9 @@
# pylint: disable=redefined-builtin # pylint: disable=redefined-builtin
"""This module contains the classes for Telegram Stars transactions.""" """This module contains the classes for Telegram Stars transactions."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._paidmedia import PaidMedia from telegram._paidmedia import PaidMedia
@ -79,7 +80,7 @@ class RevenueWithdrawalState(TelegramObject):
care of selecting the correct subclass. care of selecting the correct subclass.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`): The bot associated with this object. bot (:class:`telegram.Bot`): The bot associated with this object.
Returns: Returns:
@ -91,7 +92,7 @@ class RevenueWithdrawalState(TelegramObject):
if not data: if not data:
return None return None
_class_mapping: Dict[str, Type[RevenueWithdrawalState]] = { _class_mapping: dict[str, type[RevenueWithdrawalState]] = {
cls.PENDING: RevenueWithdrawalStatePending, cls.PENDING: RevenueWithdrawalStatePending,
cls.SUCCEEDED: RevenueWithdrawalStateSucceeded, cls.SUCCEEDED: RevenueWithdrawalStateSucceeded,
cls.FAILED: RevenueWithdrawalStateFailed, cls.FAILED: RevenueWithdrawalStateFailed,
@ -239,7 +240,7 @@ class TransactionPartner(TelegramObject):
care of selecting the correct subclass. care of selecting the correct subclass.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`): The bot associated with this object. bot (:class:`telegram.Bot`): The bot associated with this object.
Returns: Returns:
@ -254,7 +255,7 @@ class TransactionPartner(TelegramObject):
if not data and cls is TransactionPartner: if not data and cls is TransactionPartner:
return None return None
_class_mapping: Dict[str, Type[TransactionPartner]] = { _class_mapping: dict[str, type[TransactionPartner]] = {
cls.FRAGMENT: TransactionPartnerFragment, cls.FRAGMENT: TransactionPartnerFragment,
cls.USER: TransactionPartnerUser, cls.USER: TransactionPartnerUser,
cls.OTHER: TransactionPartnerOther, cls.OTHER: TransactionPartnerOther,
@ -337,7 +338,7 @@ class TransactionPartnerUser(TransactionPartner):
always :tg-const:`telegram.TransactionPartner.USER`. always :tg-const:`telegram.TransactionPartner.USER`.
user (:class:`telegram.User`): Information about the user. user (:class:`telegram.User`): Information about the user.
invoice_payload (:obj:`str`): Optional. Bot-specified invoice payload. invoice_payload (:obj:`str`): Optional. Bot-specified invoice payload.
paid_media (Tuple[:class:`telegram.PaidMedia`]): Optional. Information about the paid paid_media (tuple[:class:`telegram.PaidMedia`]): Optional. Information about the paid
media bought by the user. media bought by the user.
.. versionadded:: 21.5 .. versionadded:: 21.5
@ -363,7 +364,7 @@ class TransactionPartnerUser(TransactionPartner):
with self._unfrozen(): with self._unfrozen():
self.user: User = user self.user: User = user
self.invoice_payload: Optional[str] = invoice_payload self.invoice_payload: Optional[str] = invoice_payload
self.paid_media: Optional[Tuple[PaidMedia, ...]] = parse_sequence_arg(paid_media) self.paid_media: Optional[tuple[PaidMedia, ...]] = parse_sequence_arg(paid_media)
self.paid_media_payload: Optional[str] = paid_media_payload self.paid_media_payload: Optional[str] = paid_media_payload
self._id_attrs = ( self._id_attrs = (
self.type, self.type,
@ -516,7 +517,7 @@ class StarTransactions(TelegramObject):
transactions (Sequence[:class:`telegram.StarTransaction`]): The list of transactions. transactions (Sequence[:class:`telegram.StarTransaction`]): The list of transactions.
Attributes: Attributes:
transactions (Tuple[:class:`telegram.StarTransaction`]): The list of transactions. transactions (tuple[:class:`telegram.StarTransaction`]): The list of transactions.
""" """
__slots__ = ("transactions",) __slots__ = ("transactions",)
@ -525,7 +526,7 @@ class StarTransactions(TelegramObject):
self, transactions: Sequence[StarTransaction], *, api_kwargs: Optional[JSONDict] = None self, transactions: Sequence[StarTransaction], *, api_kwargs: Optional[JSONDict] = None
): ):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.transactions: Tuple[StarTransaction, ...] = parse_sequence_arg(transactions) self.transactions: tuple[StarTransaction, ...] = parse_sequence_arg(transactions)
self._id_attrs = (self.transactions,) self._id_attrs = (self.transactions,)
self._freeze() self._freeze()

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Poll.""" """This module contains an object that represents a Telegram Poll."""
import datetime import datetime
from typing import TYPE_CHECKING, Dict, Final, List, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional
from telegram import constants from telegram import constants
from telegram._chat import Chat from telegram._chat import Chat
@ -83,7 +84,7 @@ class InputPollOption(TelegramObject):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.text: str = text self.text: str = text
self.text_parse_mode: ODVInput[str] = text_parse_mode self.text_parse_mode: ODVInput[str] = text_parse_mode
self.text_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(text_entities) self.text_entities: tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
self._id_attrs = (self.text,) self._id_attrs = (self.text,)
@ -127,7 +128,7 @@ class PollOption(TelegramObject):
:tg-const:`telegram.PollOption.MIN_LENGTH`-:tg-const:`telegram.PollOption.MAX_LENGTH` :tg-const:`telegram.PollOption.MIN_LENGTH`-:tg-const:`telegram.PollOption.MAX_LENGTH`
characters. characters.
voter_count (:obj:`int`): Number of users that voted for this option. voter_count (:obj:`int`): Number of users that voted for this option.
text_entities (Tuple[:class:`telegram.MessageEntity`]): Special entities text_entities (tuple[:class:`telegram.MessageEntity`]): Special entities
that appear in the option text. Currently, only custom emoji entities are allowed in that appear in the option text. Currently, only custom emoji entities are allowed in
poll option texts. poll option texts.
This list is empty if the question does not contain entities. This list is empty if the question does not contain entities.
@ -149,7 +150,7 @@ class PollOption(TelegramObject):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.text: str = text self.text: str = text
self.voter_count: int = voter_count self.voter_count: int = voter_count
self.text_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(text_entities) self.text_entities: tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
self._id_attrs = (self.text, self.voter_count) self._id_attrs = (self.text, self.voter_count)
@ -189,7 +190,7 @@ class PollOption(TelegramObject):
""" """
return parse_message_entity(self.text, entity) return parse_message_entity(self.text, entity)
def parse_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]: def parse_entities(self, types: Optional[list[str]] = None) -> dict[MessageEntity, str]:
""" """
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`. Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
It contains entities from this polls question filtered by their ``type`` attribute as It contains entities from this polls question filtered by their ``type`` attribute as
@ -203,12 +204,12 @@ class PollOption(TelegramObject):
.. versionadded:: 21.2 .. versionadded:: 21.2
Args: Args:
types (List[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the types (list[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the
``type`` attribute of an entity is contained in this list, it will be returned. ``type`` attribute of an entity is contained in this list, it will be returned.
Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`. Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`.
Returns: Returns:
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
the text that belongs to them, calculated based on UTF-16 codepoints. the text that belongs to them, calculated based on UTF-16 codepoints.
""" """
return parse_message_entities(self.text, self.text_entities, types) return parse_message_entities(self.text, self.text_entities, types)
@ -260,7 +261,7 @@ class PollAnswer(TelegramObject):
Attributes: Attributes:
poll_id (:obj:`str`): Unique poll identifier. poll_id (:obj:`str`): Unique poll identifier.
option_ids (Tuple[:obj:`int`]): Identifiers of answer options, chosen by the user. May option_ids (tuple[:obj:`int`]): Identifiers of answer options, chosen by the user. May
be empty if the user retracted their vote. be empty if the user retracted their vote.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -292,7 +293,7 @@ class PollAnswer(TelegramObject):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.poll_id: str = poll_id self.poll_id: str = poll_id
self.voter_chat: Optional[Chat] = voter_chat self.voter_chat: Optional[Chat] = voter_chat
self.option_ids: Tuple[int, ...] = parse_sequence_arg(option_ids) self.option_ids: tuple[int, ...] = parse_sequence_arg(option_ids)
self.user: Optional[User] = user self.user: Optional[User] = user
self._id_attrs = ( self._id_attrs = (
@ -374,7 +375,7 @@ class Poll(TelegramObject):
id (:obj:`str`): Unique poll identifier. id (:obj:`str`): Unique poll identifier.
question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`- question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`-
:tg-const:`telegram.Poll.MAX_QUESTION_LENGTH` characters. :tg-const:`telegram.Poll.MAX_QUESTION_LENGTH` characters.
options (Tuple[:class:`~telegram.PollOption`]): List of poll options. options (tuple[:class:`~telegram.PollOption`]): List of poll options.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
|tupleclassattrs| |tupleclassattrs|
@ -389,7 +390,7 @@ class Poll(TelegramObject):
explanation (:obj:`str`): Optional. Text that is shown when a user chooses an incorrect explanation (:obj:`str`): Optional. Text that is shown when a user chooses an incorrect
answer or taps on the lamp icon in a quiz-style poll, answer or taps on the lamp icon in a quiz-style poll,
0-:tg-const:`telegram.Poll.MAX_EXPLANATION_LENGTH` characters. 0-:tg-const:`telegram.Poll.MAX_EXPLANATION_LENGTH` characters.
explanation_entities (Tuple[:class:`telegram.MessageEntity`]): Special entities explanation_entities (tuple[:class:`telegram.MessageEntity`]): Special entities
like usernames, URLs, bot commands, etc. that appear in the :attr:`explanation`. like usernames, URLs, bot commands, etc. that appear in the :attr:`explanation`.
This list is empty if the message does not contain explanation entities. This list is empty if the message does not contain explanation entities.
@ -405,7 +406,7 @@ class Poll(TelegramObject):
.. versionchanged:: 20.3 .. versionchanged:: 20.3
|datetime_localization| |datetime_localization|
question_entities (Tuple[:class:`telegram.MessageEntity`]): Special entities question_entities (tuple[:class:`telegram.MessageEntity`]): Special entities
that appear in the :attr:`question`. Currently, only custom emoji entities are allowed that appear in the :attr:`question`. Currently, only custom emoji entities are allowed
in poll questions. in poll questions.
This list is empty if the question does not contain entities. This list is empty if the question does not contain entities.
@ -453,7 +454,7 @@ class Poll(TelegramObject):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.id: str = id self.id: str = id
self.question: str = question self.question: str = question
self.options: Tuple[PollOption, ...] = parse_sequence_arg(options) self.options: tuple[PollOption, ...] = parse_sequence_arg(options)
self.total_voter_count: int = total_voter_count self.total_voter_count: int = total_voter_count
self.is_closed: bool = is_closed self.is_closed: bool = is_closed
self.is_anonymous: bool = is_anonymous self.is_anonymous: bool = is_anonymous
@ -461,12 +462,12 @@ class Poll(TelegramObject):
self.allows_multiple_answers: bool = allows_multiple_answers self.allows_multiple_answers: bool = allows_multiple_answers
self.correct_option_id: Optional[int] = correct_option_id self.correct_option_id: Optional[int] = correct_option_id
self.explanation: Optional[str] = explanation self.explanation: Optional[str] = explanation
self.explanation_entities: Tuple[MessageEntity, ...] = parse_sequence_arg( self.explanation_entities: tuple[MessageEntity, ...] = parse_sequence_arg(
explanation_entities explanation_entities
) )
self.open_period: Optional[int] = open_period self.open_period: Optional[int] = open_period
self.close_date: Optional[datetime.datetime] = close_date self.close_date: Optional[datetime.datetime] = close_date
self.question_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(question_entities) self.question_entities: tuple[MessageEntity, ...] = parse_sequence_arg(question_entities)
self._id_attrs = (self.id,) self._id_attrs = (self.id,)
@ -516,8 +517,8 @@ class Poll(TelegramObject):
return parse_message_entity(self.explanation, entity) return parse_message_entity(self.explanation, entity)
def parse_explanation_entities( def parse_explanation_entities(
self, types: Optional[List[str]] = None self, types: Optional[list[str]] = None
) -> Dict[MessageEntity, str]: ) -> dict[MessageEntity, str]:
""" """
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`. Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
It contains entities from this polls explanation filtered by their ``type`` attribute as It contains entities from this polls explanation filtered by their ``type`` attribute as
@ -529,12 +530,12 @@ class Poll(TelegramObject):
UTF-16 codepoints. See :attr:`parse_explanation_entity` for more info. UTF-16 codepoints. See :attr:`parse_explanation_entity` for more info.
Args: Args:
types (List[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the types (list[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the
``type`` attribute of an entity is contained in this list, it will be returned. ``type`` attribute of an entity is contained in this list, it will be returned.
Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`. Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`.
Returns: Returns:
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
the text that belongs to them, calculated based on UTF-16 codepoints. the text that belongs to them, calculated based on UTF-16 codepoints.
Raises: Raises:
@ -567,8 +568,8 @@ class Poll(TelegramObject):
return parse_message_entity(self.question, entity) return parse_message_entity(self.question, entity)
def parse_question_entities( def parse_question_entities(
self, types: Optional[List[str]] = None self, types: Optional[list[str]] = None
) -> Dict[MessageEntity, str]: ) -> dict[MessageEntity, str]:
""" """
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`. Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
It contains entities from this polls question filtered by their ``type`` attribute as It contains entities from this polls question filtered by their ``type`` attribute as
@ -582,12 +583,12 @@ class Poll(TelegramObject):
UTF-16 codepoints. See :attr:`parse_question_entity` for more info. UTF-16 codepoints. See :attr:`parse_question_entity` for more info.
Args: Args:
types (List[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the types (list[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the
``type`` attribute of an entity is contained in this list, it will be returned. ``type`` attribute of an entity is contained in this list, it will be returned.
Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`. Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`.
Returns: Returns:
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
the text that belongs to them, calculated based on UTF-16 codepoints. the text that belongs to them, calculated based on UTF-16 codepoints.
""" """

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains objects that represents a Telegram ReactionType.""" """This module contains objects that represents a Telegram ReactionType."""
from typing import TYPE_CHECKING, Dict, Final, Literal, Optional, Type, Union from typing import TYPE_CHECKING, Final, Literal, Optional, Union
from telegram import constants from telegram import constants
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -89,7 +89,7 @@ class ReactionType(TelegramObject):
if not data and cls is ReactionType: if not data and cls is ReactionType:
return None return None
_class_mapping: Dict[str, Type[ReactionType]] = { _class_mapping: dict[str, type[ReactionType]] = {
cls.EMOJI: ReactionTypeEmoji, cls.EMOJI: ReactionTypeEmoji,
cls.CUSTOM_EMOJI: ReactionTypeCustomEmoji, cls.CUSTOM_EMOJI: ReactionTypeCustomEmoji,
cls.PAID: ReactionTypePaid, cls.PAID: ReactionTypePaid,

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This modules contains objects that represents Telegram Replies""" """This modules contains objects that represents Telegram Replies"""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, Union from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional, Union
from telegram._chat import Chat from telegram._chat import Chat
from telegram._dice import Dice from telegram._dice import Dice
@ -124,7 +125,7 @@ class ExternalReplyInfo(TelegramObject):
file. file.
document (:class:`telegram.Document`): Optional. Message is a general file, information document (:class:`telegram.Document`): Optional. Message is a general file, information
about the file. about the file.
photo (Tuple[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available sizes photo (tuple[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available sizes
of the photo. of the photo.
sticker (:class:`telegram.Sticker`): Optional. Message is a sticker, information about the sticker (:class:`telegram.Sticker`): Optional. Message is a sticker, information about the
sticker. sticker.
@ -224,7 +225,7 @@ class ExternalReplyInfo(TelegramObject):
self.animation: Optional[Animation] = animation self.animation: Optional[Animation] = animation
self.audio: Optional[Audio] = audio self.audio: Optional[Audio] = audio
self.document: Optional[Document] = document self.document: Optional[Document] = document
self.photo: Optional[Tuple[PhotoSize, ...]] = parse_sequence_arg(photo) self.photo: Optional[tuple[PhotoSize, ...]] = parse_sequence_arg(photo)
self.sticker: Optional[Sticker] = sticker self.sticker: Optional[Sticker] = sticker
self.story: Optional[Story] = story self.story: Optional[Story] = story
self.video: Optional[Video] = video self.video: Optional[Video] = video
@ -311,7 +312,7 @@ class TextQuote(TelegramObject):
message. message.
position (:obj:`int`): Approximate quote position in the original message in UTF-16 code position (:obj:`int`): Approximate quote position in the original message in UTF-16 code
units as specified by the sender. units as specified by the sender.
entities (Tuple[:class:`telegram.MessageEntity`]): Optional. Special entities that appear entities (tuple[:class:`telegram.MessageEntity`]): Optional. Special entities that appear
in the quote. Currently, only bold, italic, underline, strikethrough, spoiler, and in the quote. Currently, only bold, italic, underline, strikethrough, spoiler, and
custom_emoji entities are kept in quotes. custom_emoji entities are kept in quotes.
is_manual (:obj:`bool`): Optional. :obj:`True`, if the quote was chosen manually by the is_manual (:obj:`bool`): Optional. :obj:`True`, if the quote was chosen manually by the
@ -338,7 +339,7 @@ class TextQuote(TelegramObject):
self.text: str = text self.text: str = text
self.position: int = position self.position: int = position
self.entities: Optional[Tuple[MessageEntity, ...]] = parse_sequence_arg(entities) self.entities: Optional[tuple[MessageEntity, ...]] = parse_sequence_arg(entities)
self.is_manual: Optional[bool] = is_manual self.is_manual: Optional[bool] = is_manual
self._id_attrs = ( self._id_attrs = (
@ -411,7 +412,7 @@ class ReplyParameters(TelegramObject):
quote_parse_mode (:obj:`str`): Optional. Mode for parsing entities in the quote. See quote_parse_mode (:obj:`str`): Optional. Mode for parsing entities in the quote. See
:wiki:`formatting options <Code-snippets#message-formatting-bold-italic-code->` for :wiki:`formatting options <Code-snippets#message-formatting-bold-italic-code->` for
more details. more details.
quote_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. A JSON-serialized list quote_entities (tuple[:class:`telegram.MessageEntity`]): Optional. A JSON-serialized list
of special entities that appear in the quote. It can be specified instead of of special entities that appear in the quote. It can be specified instead of
:paramref:`quote_parse_mode`. :paramref:`quote_parse_mode`.
quote_position (:obj:`int`): Optional. Position of the quote in the original message in quote_position (:obj:`int`): Optional. Position of the quote in the original message in
@ -447,7 +448,7 @@ class ReplyParameters(TelegramObject):
self.allow_sending_without_reply: ODVInput[bool] = allow_sending_without_reply self.allow_sending_without_reply: ODVInput[bool] = allow_sending_without_reply
self.quote: Optional[str] = quote self.quote: Optional[str] = quote
self.quote_parse_mode: ODVInput[str] = quote_parse_mode self.quote_parse_mode: ODVInput[str] = quote_parse_mode
self.quote_entities: Optional[Tuple[MessageEntity, ...]] = parse_sequence_arg( self.quote_entities: Optional[tuple[MessageEntity, ...]] = parse_sequence_arg(
quote_entities quote_entities
) )
self.quote_position: Optional[int] = quote_position self.quote_position: Optional[int] = quote_position

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram ReplyKeyboardMarkup.""" """This module contains an object that represents a Telegram ReplyKeyboardMarkup."""
from typing import Final, Optional, Sequence, Tuple, Union from collections.abc import Sequence
from typing import Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._keyboardbutton import KeyboardButton from telegram._keyboardbutton import KeyboardButton
@ -85,7 +86,7 @@ class ReplyKeyboardMarkup(TelegramObject):
.. versionadded:: 20.0 .. versionadded:: 20.0
Attributes: Attributes:
keyboard (Tuple[Tuple[:class:`telegram.KeyboardButton`]]): Array of button rows, keyboard (tuple[tuple[:class:`telegram.KeyboardButton`]]): Array of button rows,
each represented by an Array of :class:`telegram.KeyboardButton` objects. each represented by an Array of :class:`telegram.KeyboardButton` objects.
resize_keyboard (:obj:`bool`): Optional. Requests clients to resize the keyboard vertically resize_keyboard (:obj:`bool`): Optional. Requests clients to resize the keyboard vertically
for optimal fit (e.g., make the keyboard smaller if there are just two rows of for optimal fit (e.g., make the keyboard smaller if there are just two rows of
@ -148,7 +149,7 @@ class ReplyKeyboardMarkup(TelegramObject):
) )
# Required # Required
self.keyboard: Tuple[Tuple[KeyboardButton, ...], ...] = tuple( self.keyboard: tuple[tuple[KeyboardButton, ...], ...] = tuple(
tuple(KeyboardButton(button) if isinstance(button, str) else button for button in row) tuple(KeyboardButton(button) if isinstance(button, str) else button for button in row)
for row in keyboard for row in keyboard
) )

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains two objects used for request chats/users service messages.""" """This module contains two objects used for request chats/users service messages."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._files.photosize import PhotoSize from telegram._files.photosize import PhotoSize
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -59,7 +60,7 @@ class UsersShared(TelegramObject):
Attributes: Attributes:
request_id (:obj:`int`): Identifier of the request. request_id (:obj:`int`): Identifier of the request.
users (Tuple[:class:`telegram.SharedUser`]): Information about users shared with the users (tuple[:class:`telegram.SharedUser`]): Information about users shared with the
bot. bot.
.. versionadded:: 21.1 .. versionadded:: 21.1
@ -76,7 +77,7 @@ class UsersShared(TelegramObject):
): ):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.request_id: int = request_id self.request_id: int = request_id
self.users: Tuple[SharedUser, ...] = parse_sequence_arg(users) self.users: tuple[SharedUser, ...] = parse_sequence_arg(users)
self._id_attrs = (self.request_id, self.users) self._id_attrs = (self.request_id, self.users)
@ -144,7 +145,7 @@ class ChatShared(TelegramObject):
the bot and available. the bot and available.
.. versionadded:: 21.1 .. versionadded:: 21.1
photo (Tuple[:class:`telegram.PhotoSize`]): Optional. Available sizes of the chat photo, photo (tuple[:class:`telegram.PhotoSize`]): Optional. Available sizes of the chat photo,
if the photo was requested by the bot if the photo was requested by the bot
.. versionadded:: 21.1 .. versionadded:: 21.1
@ -167,7 +168,7 @@ class ChatShared(TelegramObject):
self.chat_id: int = chat_id self.chat_id: int = chat_id
self.title: Optional[str] = title self.title: Optional[str] = title
self.username: Optional[str] = username self.username: Optional[str] = username
self.photo: Optional[Tuple[PhotoSize, ...]] = parse_sequence_arg(photo) self.photo: Optional[tuple[PhotoSize, ...]] = parse_sequence_arg(photo)
self._id_attrs = (self.request_id, self.chat_id) self._id_attrs = (self.request_id, self.chat_id)
@ -226,7 +227,7 @@ class SharedUser(TelegramObject):
bot. bot.
username (:obj:`str`): Optional. Username of the user, if the username was requested by the username (:obj:`str`): Optional. Username of the user, if the username was requested by the
bot. bot.
photo (Tuple[:class:`telegram.PhotoSize`]): Available sizes of the chat photo, if photo (tuple[:class:`telegram.PhotoSize`]): Available sizes of the chat photo, if
the photo was requested by the bot. This list is empty if the photo was not requsted. the photo was requested by the bot. This list is empty if the photo was not requsted.
""" """
@ -247,7 +248,7 @@ class SharedUser(TelegramObject):
self.first_name: Optional[str] = first_name self.first_name: Optional[str] = first_name
self.last_name: Optional[str] = last_name self.last_name: Optional[str] = last_name
self.username: Optional[str] = username self.username: Optional[str] = username
self.photo: Optional[Tuple[PhotoSize, ...]] = parse_sequence_arg(photo) self.photo: Optional[tuple[PhotoSize, ...]] = parse_sequence_arg(photo)
self._id_attrs = (self.user_id,) self._id_attrs = (self.user_id,)

View file

@ -21,27 +21,12 @@ import contextlib
import datetime import datetime
import inspect import inspect
import json import json
from collections.abc import Sized from collections.abc import Iterator, Mapping, Sized
from contextlib import contextmanager from contextlib import contextmanager
from copy import deepcopy from copy import deepcopy
from itertools import chain from itertools import chain
from types import MappingProxyType from types import MappingProxyType
from typing import ( from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypeVar, Union, cast
TYPE_CHECKING,
Any,
ClassVar,
Dict,
Iterator,
List,
Mapping,
Optional,
Set,
Tuple,
Type,
TypeVar,
Union,
cast,
)
from telegram._utils.datetime import to_timestamp from telegram._utils.datetime import to_timestamp
from telegram._utils.defaultvalue import DefaultValue from telegram._utils.defaultvalue import DefaultValue
@ -80,7 +65,7 @@ class TelegramObject:
:obj:`list` are now of type :obj:`tuple`. :obj:`list` are now of type :obj:`tuple`.
Arguments: Arguments:
api_kwargs (Dict[:obj:`str`, any], optional): |toapikwargsarg| api_kwargs (dict[:obj:`str`, any], optional): |toapikwargsarg|
.. versionadded:: 20.0 .. versionadded:: 20.0
@ -95,11 +80,11 @@ class TelegramObject:
# Used to cache the names of the parameters of the __init__ method of the class # Used to cache the names of the parameters of the __init__ method of the class
# Must be a private attribute to avoid name clashes between subclasses # Must be a private attribute to avoid name clashes between subclasses
__INIT_PARAMS: ClassVar[Set[str]] = set() __INIT_PARAMS: ClassVar[set[str]] = set()
# Used to check if __INIT_PARAMS has been set for the current class. Unfortunately, we can't # Used to check if __INIT_PARAMS has been set for the current class. Unfortunately, we can't
# just check if `__INIT_PARAMS is None`, since subclasses use the parent class' __INIT_PARAMS # just check if `__INIT_PARAMS is None`, since subclasses use the parent class' __INIT_PARAMS
# unless it's overridden # unless it's overridden
__INIT_PARAMS_CHECK: Optional[Type["TelegramObject"]] = None __INIT_PARAMS_CHECK: Optional[type["TelegramObject"]] = None
def __init__(self, *, api_kwargs: Optional[JSONDict] = None) -> None: def __init__(self, *, api_kwargs: Optional[JSONDict] = None) -> None:
# Setting _frozen to `False` here means that classes without arguments still need to # Setting _frozen to `False` here means that classes without arguments still need to
@ -107,7 +92,7 @@ class TelegramObject:
# `with self._unfrozen()` in the `__init__` of subclasses and we have fewer empty # `with self._unfrozen()` in the `__init__` of subclasses and we have fewer empty
# classes than classes with arguments. # classes than classes with arguments.
self._frozen: bool = False self._frozen: bool = False
self._id_attrs: Tuple[object, ...] = () self._id_attrs: tuple[object, ...] = ()
self._bot: Optional[Bot] = None self._bot: Optional[Bot] = None
# We don't do anything with api_kwargs here - see docstring of _apply_api_kwargs # We don't do anything with api_kwargs here - see docstring of _apply_api_kwargs
self.api_kwargs: Mapping[str, Any] = MappingProxyType(api_kwargs or {}) self.api_kwargs: Mapping[str, Any] = MappingProxyType(api_kwargs or {})
@ -263,7 +248,7 @@ class TelegramObject:
f"`{item}`." f"`{item}`."
) from exc ) from exc
def __getstate__(self) -> Dict[str, Union[str, object]]: def __getstate__(self) -> dict[str, Union[str, object]]:
""" """
Overrides :meth:`object.__getstate__` to customize the pickling process of objects of this Overrides :meth:`object.__getstate__` to customize the pickling process of objects of this
type. type.
@ -271,7 +256,7 @@ class TelegramObject:
:meth:`set_bot` (if any), as it can't be pickled. :meth:`set_bot` (if any), as it can't be pickled.
Returns: Returns:
state (Dict[:obj:`str`, :obj:`object`]): The state of the object. state (dict[:obj:`str`, :obj:`object`]): The state of the object.
""" """
out = self._get_attrs( out = self._get_attrs(
include_private=True, recursive=False, remove_bot=True, convert_default_vault=False include_private=True, recursive=False, remove_bot=True, convert_default_vault=False
@ -281,7 +266,7 @@ class TelegramObject:
out["api_kwargs"] = dict(self.api_kwargs) out["api_kwargs"] = dict(self.api_kwargs)
return out return out
def __setstate__(self, state: Dict[str, object]) -> None: def __setstate__(self, state: dict[str, object]) -> None:
""" """
Overrides :meth:`object.__setstate__` to customize the unpickling process of objects of Overrides :meth:`object.__setstate__` to customize the unpickling process of objects of
this type. Modifies the object in-place. this type. Modifies the object in-place.
@ -305,7 +290,7 @@ class TelegramObject:
self._bot = None self._bot = None
# get api_kwargs first because we may need to add entries to it (see try-except below) # get api_kwargs first because we may need to add entries to it (see try-except below)
api_kwargs = cast(Dict[str, object], state.pop("api_kwargs", {})) api_kwargs = cast(dict[str, object], state.pop("api_kwargs", {}))
# get _frozen before the loop to avoid setting it to True in the loop # get _frozen before the loop to avoid setting it to True in the loop
frozen = state.pop("_frozen", False) frozen = state.pop("_frozen", False)
@ -341,7 +326,7 @@ class TelegramObject:
if frozen: if frozen:
self._freeze() self._freeze()
def __deepcopy__(self: Tele_co, memodict: Dict[int, object]) -> Tele_co: def __deepcopy__(self: Tele_co, memodict: dict[int, object]) -> Tele_co:
""" """
Customizes how :func:`copy.deepcopy` processes objects of this type. Customizes how :func:`copy.deepcopy` processes objects of this type.
The only difference to the default implementation is that the :class:`telegram.Bot` The only difference to the default implementation is that the :class:`telegram.Bot`
@ -401,7 +386,7 @@ class TelegramObject:
@classmethod @classmethod
def _de_json( def _de_json(
cls: Type[Tele_co], cls: type[Tele_co],
data: Optional[JSONDict], data: Optional[JSONDict],
bot: Optional["Bot"], bot: Optional["Bot"],
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
@ -433,12 +418,12 @@ class TelegramObject:
@classmethod @classmethod
def de_json( def de_json(
cls: Type[Tele_co], data: Optional[JSONDict], bot: Optional["Bot"] = None cls: type[Tele_co], data: Optional[JSONDict], bot: Optional["Bot"] = None
) -> Optional[Tele_co]: ) -> Optional[Tele_co]:
"""Converts JSON data to a Telegram object. """Converts JSON data to a Telegram object.
Args: Args:
data (Dict[:obj:`str`, ...]): The JSON data. data (dict[:obj:`str`, ...]): The JSON data.
bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to
:obj:`None`, in which case shortcut methods will not be available. :obj:`None`, in which case shortcut methods will not be available.
@ -453,8 +438,8 @@ class TelegramObject:
@classmethod @classmethod
def de_list( def de_list(
cls: Type[Tele_co], data: Optional[List[JSONDict]], bot: Optional["Bot"] = None cls: type[Tele_co], data: Optional[list[JSONDict]], bot: Optional["Bot"] = None
) -> Tuple[Tele_co, ...]: ) -> tuple[Tele_co, ...]:
"""Converts a list of JSON objects to a tuple of Telegram objects. """Converts a list of JSON objects to a tuple of Telegram objects.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -463,7 +448,7 @@ class TelegramObject:
* Filters out any :obj:`None` values. * Filters out any :obj:`None` values.
Args: Args:
data (List[Dict[:obj:`str`, ...]]): The JSON data. data (list[dict[:obj:`str`, ...]]): The JSON data.
bot (:class:`telegram.Bot`, optional): The bot associated with these object. Defaults bot (:class:`telegram.Bot`, optional): The bot associated with these object. Defaults
to :obj:`None`, in which case shortcut methods will not be available. to :obj:`None`, in which case shortcut methods will not be available.
@ -552,7 +537,7 @@ class TelegramObject:
recursive: bool = False, recursive: bool = False,
remove_bot: bool = False, remove_bot: bool = False,
convert_default_vault: bool = True, convert_default_vault: bool = True,
) -> Dict[str, Union[str, object]]: ) -> dict[str, Union[str, object]]:
"""This method is used for obtaining the attributes of the object. """This method is used for obtaining the attributes of the object.
Args: Args:
@ -625,7 +610,7 @@ class TelegramObject:
# Now we should convert TGObjects to dicts inside objects such as sequences, and convert # Now we should convert TGObjects to dicts inside objects such as sequences, and convert
# datetimes to timestamps. This mostly eliminates the need for subclasses to override # datetimes to timestamps. This mostly eliminates the need for subclasses to override
# `to_dict` # `to_dict`
pop_keys: Set[str] = set() pop_keys: set[str] = set()
for key, value in out.items(): for key, value in out.items():
if isinstance(value, (tuple, list)): if isinstance(value, (tuple, list)):
if not value: if not value:
@ -637,7 +622,7 @@ class TelegramObject:
for item in value: for item in value:
if hasattr(item, "to_dict"): if hasattr(item, "to_dict"):
val.append(item.to_dict(recursive=recursive)) val.append(item.to_dict(recursive=recursive))
# This branch is useful for e.g. Tuple[Tuple[PhotoSize|KeyboardButton]] # This branch is useful for e.g. tuple[tuple[PhotoSize|KeyboardButton]]
elif isinstance(item, (tuple, list)): elif isinstance(item, (tuple, list)):
val.append( val.append(
[ [

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Update.""" """This module contains an object that represents a Telegram Update."""
from typing import TYPE_CHECKING, Final, List, Optional, Union from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants from telegram import constants
from telegram._business import BusinessConnection, BusinessMessagesDeleted from telegram._business import BusinessConnection, BusinessMessagesDeleted
@ -402,8 +402,8 @@ class Update(TelegramObject):
.. versionadded:: 21.6 .. versionadded:: 21.6
""" """
ALL_TYPES: Final[List[str]] = list(constants.UpdateType) ALL_TYPES: Final[list[str]] = list(constants.UpdateType)
"""List[:obj:`str`]: A list of all available update types. """list[:obj:`str`]: A list of all available update types.
.. versionadded:: 13.5""" .. versionadded:: 13.5"""

View file

@ -18,8 +18,9 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram User.""" """This module contains an object that represents a Telegram User."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, Union from typing import TYPE_CHECKING, Optional, Union
from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton
from telegram._menubutton import MenuButton from telegram._menubutton import MenuButton
@ -621,7 +622,7 @@ class User(TelegramObject):
caption: Optional[str] = None, caption: Optional[str] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE, parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None, caption_entities: Optional[Sequence["MessageEntity"]] = None,
) -> Tuple["Message", ...]: ) -> tuple["Message", ...]:
"""Shortcut for:: """Shortcut for::
await bot.send_media_group(update.effective_user.id, *args, **kwargs) await bot.send_media_group(update.effective_user.id, *args, **kwargs)
@ -632,7 +633,7 @@ class User(TelegramObject):
|user_chat_id_note| |user_chat_id_note|
Returns: Returns:
Tuple[:class:`telegram.Message`:] On success, a tuple of :class:`~telegram.Message` tuple[:class:`telegram.Message`:] On success, a tuple of :class:`~telegram.Message`
instances that were sent is returned. instances that were sent is returned.
""" """
@ -1739,7 +1740,7 @@ class User(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.copy_messages(chat_id=update.effective_user.id, *argss, **kwargs) await bot.copy_messages(chat_id=update.effective_user.id, *argss, **kwargs)
@ -1751,7 +1752,7 @@ class User(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of the sent messages is returned. of the sent messages is returned.
""" """
@ -1784,7 +1785,7 @@ class User(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.copy_messages(from_chat_id=update.effective_user.id, *argss, **kwargs) await bot.copy_messages(from_chat_id=update.effective_user.id, *argss, **kwargs)
@ -1796,7 +1797,7 @@ class User(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of the sent messages is returned. of the sent messages is returned.
""" """
@ -1913,7 +1914,7 @@ class User(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.forward_messages(chat_id=update.effective_user.id, *argss, **kwargs) await bot.forward_messages(chat_id=update.effective_user.id, *argss, **kwargs)
@ -1925,7 +1926,7 @@ class User(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of sent messages is returned. of sent messages is returned.
""" """
@ -1956,7 +1957,7 @@ class User(TelegramObject):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
"""Shortcut for:: """Shortcut for::
await bot.forward_messages(from_chat_id=update.effective_user.id, *argss, **kwargs) await bot.forward_messages(from_chat_id=update.effective_user.id, *argss, **kwargs)
@ -1968,7 +1969,7 @@ class User(TelegramObject):
.. versionadded:: 20.8 .. versionadded:: 20.8
Returns: Returns:
Tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId` tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
of sent messages is returned. of sent messages is returned.
""" """

View file

@ -17,7 +17,8 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram UserProfilePhotos.""" """This module contains an object that represents a Telegram UserProfilePhotos."""
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._files.photosize import PhotoSize from telegram._files.photosize import PhotoSize
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
@ -43,7 +44,7 @@ class UserProfilePhotos(TelegramObject):
Attributes: Attributes:
total_count (:obj:`int`): Total number of profile pictures. total_count (:obj:`int`): Total number of profile pictures.
photos (Tuple[Tuple[:class:`telegram.PhotoSize`]]): Requested profile pictures (in up to 4 photos (tuple[tuple[:class:`telegram.PhotoSize`]]): Requested profile pictures (in up to 4
sizes each). sizes each).
.. versionchanged:: 20.0 .. versionchanged:: 20.0
@ -63,7 +64,7 @@ class UserProfilePhotos(TelegramObject):
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
# Required # Required
self.total_count: int = total_count self.total_count: int = total_count
self.photos: Tuple[Tuple[PhotoSize, ...], ...] = tuple(tuple(sizes) for sizes in photos) self.photos: tuple[tuple[PhotoSize, ...], ...] = tuple(tuple(sizes) for sizes in photos)
self._id_attrs = (self.total_count, self.photos) self._id_attrs = (self.total_count, self.photos)

View file

@ -23,7 +23,8 @@ Warning:
user. Changes to this module are not considered breaking changes and may not be documented in user. Changes to this module are not considered breaking changes and may not be documented in
the changelog. the changelog.
""" """
from typing import Optional, Sequence, Tuple, TypeVar from collections.abc import Sequence
from typing import Optional, TypeVar
from telegram._linkpreviewoptions import LinkPreviewOptions from telegram._linkpreviewoptions import LinkPreviewOptions
from telegram._utils.types import ODVInput from telegram._utils.types import ODVInput
@ -31,7 +32,7 @@ from telegram._utils.types import ODVInput
T = TypeVar("T") T = TypeVar("T")
def parse_sequence_arg(arg: Optional[Sequence[T]]) -> Tuple[T, ...]: def parse_sequence_arg(arg: Optional[Sequence[T]]) -> tuple[T, ...]:
"""Parses an optional sequence into a tuple """Parses an optional sequence into a tuple
Args: Args:

View file

@ -23,7 +23,8 @@ Warning:
user. Changes to this module are not considered breaking changes and may not be documented in user. Changes to this module are not considered breaking changes and may not be documented in
the changelog. the changelog.
""" """
from typing import Dict, Optional, Sequence from collections.abc import Sequence
from typing import Optional
from telegram._messageentity import MessageEntity from telegram._messageentity import MessageEntity
from telegram._utils.strings import TextEncoding from telegram._utils.strings import TextEncoding
@ -47,7 +48,7 @@ def parse_message_entity(text: str, entity: MessageEntity) -> str:
def parse_message_entities( def parse_message_entities(
text: str, entities: Sequence[MessageEntity], types: Optional[Sequence[str]] = None text: str, entities: Sequence[MessageEntity], types: Optional[Sequence[str]] = None
) -> Dict[MessageEntity, str]: ) -> dict[MessageEntity, str]:
""" """
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`. Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
It contains entities filtered by their ``type`` attribute as It contains entities filtered by their ``type`` attribute as
@ -55,13 +56,13 @@ def parse_message_entities(
Args: Args:
text (:obj:`str`): The text to extract the entity from. text (:obj:`str`): The text to extract the entity from.
entities (List[:class:`telegram.MessageEntity`]): The entities to extract the text from. entities (list[:class:`telegram.MessageEntity`]): The entities to extract the text from.
types (List[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the types (list[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the
``type`` attribute of an entity is contained in this list, it will be returned. ``type`` attribute of an entity is contained in this list, it will be returned.
Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`. Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`.
Returns: Returns:
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
the text that belongs to them, calculated based on UTF-16 codepoints. the text that belongs to them, calculated based on UTF-16 codepoints.
""" """
if types is None: if types is None:

View file

@ -25,14 +25,14 @@ Warning:
""" """
import enum as _enum import enum as _enum
import sys import sys
from typing import Type, TypeVar, Union from typing import TypeVar, Union
_A = TypeVar("_A") _A = TypeVar("_A")
_B = TypeVar("_B") _B = TypeVar("_B")
_Enum = TypeVar("_Enum", bound=_enum.Enum) _Enum = TypeVar("_Enum", bound=_enum.Enum)
def get_member(enum_cls: Type[_Enum], value: _A, default: _B) -> Union[_Enum, _A, _B]: def get_member(enum_cls: type[_Enum], value: _A, default: _B) -> Union[_Enum, _A, _B]:
"""Tries to call ``enum_cls(value)`` to convert the value into an enumeration member. """Tries to call ``enum_cls(value)`` to convert the value into an enumeration member.
If that fails, the ``default`` is returned. If that fails, the ``default`` is returned.
""" """

View file

@ -29,7 +29,7 @@ Warning:
""" """
from pathlib import Path from pathlib import Path
from typing import IO, TYPE_CHECKING, Any, Optional, Tuple, Type, TypeVar, Union, cast, overload from typing import IO, TYPE_CHECKING, Any, Optional, TypeVar, Union, cast, overload
from telegram._utils.types import FileInput, FilePathInput from telegram._utils.types import FileInput, FilePathInput
@ -40,16 +40,16 @@ _T = TypeVar("_T", bound=Union[bytes, "InputFile", str, Path, None])
@overload @overload
def load_file(obj: IO[bytes]) -> Tuple[Optional[str], bytes]: ... def load_file(obj: IO[bytes]) -> tuple[Optional[str], bytes]: ...
@overload @overload
def load_file(obj: _T) -> Tuple[None, _T]: ... def load_file(obj: _T) -> tuple[None, _T]: ...
def load_file( def load_file(
obj: Optional[FileInput], obj: Optional[FileInput],
) -> Tuple[Optional[str], Union[bytes, "InputFile", str, Path, None]]: ) -> tuple[Optional[str], Union[bytes, "InputFile", str, Path, None]]:
"""If the input is a file handle, read the data and name and return it. Otherwise, return """If the input is a file handle, read the data and name and return it. Otherwise, return
the input unchanged. the input unchanged.
""" """
@ -95,7 +95,7 @@ def is_local_file(obj: Optional[FilePathInput]) -> bool:
def parse_file_input( # pylint: disable=too-many-return-statements def parse_file_input( # pylint: disable=too-many-return-statements
file_input: Union[FileInput, "TelegramObject"], file_input: Union[FileInput, "TelegramObject"],
tg_type: Optional[Type["TelegramObject"]] = None, tg_type: Optional[type["TelegramObject"]] = None,
filename: Optional[str] = None, filename: Optional[str] = None,
attach: bool = False, attach: bool = False,
local_mode: bool = False, local_mode: bool = False,

View file

@ -23,19 +23,9 @@ Warning:
user. Changes to this module are not considered breaking changes and may not be documented in user. Changes to this module are not considered breaking changes and may not be documented in
the changelog. the changelog.
""" """
from collections.abc import Collection
from pathlib import Path from pathlib import Path
from typing import ( from typing import IO, TYPE_CHECKING, Any, Literal, Optional, TypeVar, Union
IO,
TYPE_CHECKING,
Any,
Collection,
Dict,
Literal,
Optional,
Tuple,
TypeVar,
Union,
)
if TYPE_CHECKING: if TYPE_CHECKING:
from telegram import ( from telegram import (
@ -57,7 +47,7 @@ FileInput = Union[FilePathInput, FileLike, bytes, str]
"""Valid input for passing files to Telegram. Either a file id as string, a file like object, """Valid input for passing files to Telegram. Either a file id as string, a file like object,
a local file path as string, :class:`pathlib.Path` or the file contents as :obj:`bytes`.""" a local file path as string, :class:`pathlib.Path` or the file contents as :obj:`bytes`."""
JSONDict = Dict[str, Any] JSONDict = dict[str, Any]
"""Dictionary containing response from Telegram or data to send to the API.""" """Dictionary containing response from Telegram or data to send to the API."""
DVValueType = TypeVar("DVValueType") # pylint: disable=invalid-name DVValueType = TypeVar("DVValueType") # pylint: disable=invalid-name
@ -82,9 +72,9 @@ ReplyMarkup = Union[
.. versionadded:: 20.0 .. versionadded:: 20.0
""" """
FieldTuple = Tuple[str, Union[bytes, IO[bytes]], str] FieldTuple = tuple[str, Union[bytes, IO[bytes]], str]
"""Alias for return type of `InputFile.field_tuple`.""" """Alias for return type of `InputFile.field_tuple`."""
UploadFileDict = Dict[str, FieldTuple] UploadFileDict = dict[str, FieldTuple]
"""Dictionary containing file data to be uploaded to the API.""" """Dictionary containing file data to be uploaded to the API."""
HTTPVersion = Literal["1.1", "2.0", "2"] HTTPVersion = Literal["1.1", "2.0", "2"]
@ -97,7 +87,7 @@ CorrectOptionID = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
MarkdownVersion = Literal[1, 2] MarkdownVersion = Literal[1, 2]
SocketOpt = Union[ SocketOpt = Union[
Tuple[int, int, int], tuple[int, int, int],
Tuple[int, int, Union[bytes, bytearray]], tuple[int, int, Union[bytes, bytearray]],
Tuple[int, int, None, int], tuple[int, int, None, int],
] ]

View file

@ -26,14 +26,14 @@ Warning:
the changelog. the changelog.
""" """
import warnings import warnings
from typing import Type, Union from typing import Union
from telegram.warnings import PTBUserWarning from telegram.warnings import PTBUserWarning
def warn( def warn(
message: Union[str, PTBUserWarning], message: Union[str, PTBUserWarning],
category: Type[Warning] = PTBUserWarning, category: type[Warning] = PTBUserWarning,
stacklevel: int = 0, stacklevel: int = 0,
) -> None: ) -> None:
""" """
@ -48,7 +48,7 @@ def warn(
.. versionchanged:: 21.2 .. versionchanged:: 21.2
Now also accepts a :obj:`PTBUserWarning` instance. Now also accepts a :obj:`PTBUserWarning` instance.
category (:obj:`Type[Warning]`, optional): Specify the Warning class to pass to category (:obj:`type[Warning]`, optional): Specify the Warning class to pass to
``warnings.warn()``. Defaults to :class:`telegram.warnings.PTBUserWarning`. ``warnings.warn()``. Defaults to :class:`telegram.warnings.PTBUserWarning`.
stacklevel (:obj:`int`, optional): Specify the stacklevel to pass to ``warnings.warn()``. stacklevel (:obj:`int`, optional): Specify the stacklevel to pass to ``warnings.warn()``.
Pass the same value as you'd pass directly to ``warnings.warn()``. Defaults to ``0``. Pass the same value as you'd pass directly to ``warnings.warn()``. Defaults to ``0``.

View file

@ -23,7 +23,7 @@ inside warnings.py.
.. versionadded:: 20.2 .. versionadded:: 20.2
""" """
from typing import Any, Callable, Type, Union from typing import Any, Callable, Union
from telegram._utils.warnings import warn from telegram._utils.warnings import warn
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
@ -56,7 +56,7 @@ def warn_about_deprecated_arg_return_new_arg(
bot_api_version: str, bot_api_version: str,
ptb_version: str, ptb_version: str,
stacklevel: int = 2, stacklevel: int = 2,
warn_callback: Callable[[Union[str, PTBUserWarning], Type[Warning], int], None] = warn, warn_callback: Callable[[Union[str, PTBUserWarning], type[Warning], int], None] = warn,
) -> Any: ) -> Any:
"""A helper function for the transition in API when argument is renamed. """A helper function for the transition in API when argument is renamed.

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains objects related to Telegram video chats.""" """This module contains objects related to Telegram video chats."""
import datetime as dtm import datetime as dtm
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
from telegram._user import User from telegram._user import User
@ -102,7 +103,7 @@ class VideoChatParticipantsInvited(TelegramObject):
|sequenceclassargs| |sequenceclassargs|
Attributes: Attributes:
users (Tuple[:class:`telegram.User`]): New members that were invited to the video chat. users (tuple[:class:`telegram.User`]): New members that were invited to the video chat.
.. versionchanged:: 20.0 .. versionchanged:: 20.0
|tupleclassattrs| |tupleclassattrs|
@ -118,7 +119,7 @@ class VideoChatParticipantsInvited(TelegramObject):
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> None: ) -> None:
super().__init__(api_kwargs=api_kwargs) super().__init__(api_kwargs=api_kwargs)
self.users: Tuple[User, ...] = parse_sequence_arg(users) self.users: tuple[User, ...] = parse_sequence_arg(users)
self._id_attrs = (self.users,) self._id_attrs = (self.users,)
self._freeze() self._freeze()

View file

@ -17,8 +17,9 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram WebhookInfo.""" """This module contains an object that represents a Telegram WebhookInfo."""
from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Optional, Sequence, Tuple from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject from telegram._telegramobject import TelegramObject
from telegram._utils.argumentparsing import parse_sequence_arg from telegram._utils.argumentparsing import parse_sequence_arg
@ -89,7 +90,7 @@ class WebhookInfo(TelegramObject):
most recent error that happened when trying to deliver an update via webhook. most recent error that happened when trying to deliver an update via webhook.
max_connections (:obj:`int`): Optional. Maximum allowed number of simultaneous HTTPS max_connections (:obj:`int`): Optional. Maximum allowed number of simultaneous HTTPS
connections to the webhook for update delivery. connections to the webhook for update delivery.
allowed_updates (Tuple[:obj:`str`]): Optional. A list of update types the bot is allowed_updates (tuple[:obj:`str`]): Optional. A list of update types the bot is
subscribed to. Defaults to all update types, except subscribed to. Defaults to all update types, except
:attr:`telegram.Update.chat_member`. :attr:`telegram.Update.chat_member`.
@ -144,7 +145,7 @@ class WebhookInfo(TelegramObject):
self.last_error_date: Optional[datetime] = last_error_date self.last_error_date: Optional[datetime] = last_error_date
self.last_error_message: Optional[str] = last_error_message self.last_error_message: Optional[str] = last_error_message
self.max_connections: Optional[int] = max_connections self.max_connections: Optional[int] = max_connections
self.allowed_updates: Tuple[str, ...] = parse_sequence_arg(allowed_updates) self.allowed_updates: tuple[str, ...] = parse_sequence_arg(allowed_updates)
self.last_synchronization_error_date: Optional[datetime] = last_synchronization_error_date self.last_synchronization_error_date: Optional[datetime] = last_synchronization_error_date
self._id_attrs = ( self._id_attrs = (

View file

@ -108,7 +108,7 @@ __all__ = [
import datetime import datetime
import sys import sys
from enum import Enum from enum import Enum
from typing import Final, List, NamedTuple, Optional, Tuple from typing import Final, NamedTuple, Optional
from telegram._utils.datetime import UTC from telegram._utils.datetime import UTC
from telegram._utils.enum import IntEnum, StringEnum from telegram._utils.enum import IntEnum, StringEnum
@ -141,8 +141,8 @@ class _AccentColor(NamedTuple):
identifier: int identifier: int
name: Optional[str] = None name: Optional[str] = None
light_colors: Tuple[int, ...] = () light_colors: tuple[int, ...] = ()
dark_colors: Tuple[int, ...] = () dark_colors: tuple[int, ...] = ()
#: :class:`typing.NamedTuple`: A tuple containing the two components of the version number: #: :class:`typing.NamedTuple`: A tuple containing the two components of the version number:
@ -162,9 +162,9 @@ BOT_API_VERSION: Final[str] = str(BOT_API_VERSION_INFO)
# constants above this line are tested # constants above this line are tested
#: List[:obj:`int`]: Ports supported by #: list[:obj:`int`]: Ports supported by
#: :paramref:`telegram.Bot.set_webhook.url`. #: :paramref:`telegram.Bot.set_webhook.url`.
SUPPORTED_WEBHOOK_PORTS: Final[List[int]] = [443, 80, 88, 8443] SUPPORTED_WEBHOOK_PORTS: Final[list[int]] = [443, 80, 88, 8443]
#: :obj:`datetime.datetime`, value of unix 0. #: :obj:`datetime.datetime`, value of unix 0.
#: This date literal is used in :class:`telegram.InaccessibleMessage` #: This date literal is used in :class:`telegram.InaccessibleMessage`
@ -180,9 +180,9 @@ class AccentColor(Enum):
- ``identifier`` (:obj:`int`): The identifier of the accent color. - ``identifier`` (:obj:`int`): The identifier of the accent color.
- ``name`` (:obj:`str`): Optional. The name of the accent color. - ``name`` (:obj:`str`): Optional. The name of the accent color.
- ``light_colors`` (Tuple[:obj:`str`]): Optional. The light colors of the accent color as HEX - ``light_colors`` (tuple[:obj:`str`]): Optional. The light colors of the accent color as HEX
value. value.
- ``dark_colors`` (Tuple[:obj:`str`]): Optional. The dark colors of the accent color as HEX - ``dark_colors`` (tuple[:obj:`str`]): Optional. The dark colors of the accent color as HEX
value. value.
Since Telegram gives no exact specification for the accent colors, future accent colors might Since Telegram gives no exact specification for the accent colors, future accent colors might
@ -2083,9 +2083,9 @@ class ProfileAccentColor(Enum):
- ``identifier`` (:obj:`int`): The identifier of the accent color. - ``identifier`` (:obj:`int`): The identifier of the accent color.
- ``name`` (:obj:`str`): Optional. The name of the accent color. - ``name`` (:obj:`str`): Optional. The name of the accent color.
- ``light_colors`` (Tuple[:obj:`str`]): Optional. The light colors of the accent color as HEX - ``light_colors`` (tuple[:obj:`str`]): Optional. The light colors of the accent color as HEX
value. value.
- ``dark_colors`` (Tuple[:obj:`str`]): Optional. The dark colors of the accent color as HEX - ``dark_colors`` (tuple[:obj:`str`]): Optional. The dark colors of the accent color as HEX
value. value.
Since Telegram gives no exact specification for the accent colors, future accent colors might Since Telegram gives no exact specification for the accent colors, future accent colors might

View file

@ -36,20 +36,7 @@ __all__ = (
"TimedOut", "TimedOut",
) )
from typing import Optional, Tuple, Union from typing import Optional, Union
def _lstrip_str(in_s: str, lstr: str) -> str:
"""
Args:
in_s (:obj:`str`): in string
lstr (:obj:`str`): substr to strip from left side
Returns:
:obj:`str`: The stripped string.
"""
return in_s[len(lstr) :] if in_s.startswith(lstr) else in_s
class TelegramError(Exception): class TelegramError(Exception):
@ -70,9 +57,9 @@ class TelegramError(Exception):
def __init__(self, message: str): def __init__(self, message: str):
super().__init__() super().__init__()
msg = _lstrip_str(message, "Error: ") msg = message.removeprefix("Error: ")
msg = _lstrip_str(msg, "[Error]: ") msg = msg.removeprefix("[Error]: ")
msg = _lstrip_str(msg, "Bad Request: ") msg = msg.removeprefix("Bad Request: ")
if msg != message: if msg != message:
# api_error - capitalize the msg... # api_error - capitalize the msg...
msg = msg.capitalize() msg = msg.capitalize()
@ -94,7 +81,7 @@ class TelegramError(Exception):
""" """
return f"{self.__class__.__name__}('{self.message}')" return f"{self.__class__.__name__}('{self.message}')"
def __reduce__(self) -> Tuple[type, Tuple[str]]: def __reduce__(self) -> tuple[type, tuple[str]]:
"""Defines how to serialize the exception for pickle. """Defines how to serialize the exception for pickle.
.. seealso:: .. seealso::
@ -209,7 +196,7 @@ class ChatMigrated(TelegramError):
super().__init__(f"Group migrated to supergroup. New chat id: {new_chat_id}") super().__init__(f"Group migrated to supergroup. New chat id: {new_chat_id}")
self.new_chat_id: int = new_chat_id self.new_chat_id: int = new_chat_id
def __reduce__(self) -> Tuple[type, Tuple[int]]: # type: ignore[override] def __reduce__(self) -> tuple[type, tuple[int]]: # type: ignore[override]
return self.__class__, (self.new_chat_id,) return self.__class__, (self.new_chat_id,)
@ -234,7 +221,7 @@ class RetryAfter(TelegramError):
super().__init__(f"Flood control exceeded. Retry in {retry_after} seconds") super().__init__(f"Flood control exceeded. Retry in {retry_after} seconds")
self.retry_after: int = retry_after self.retry_after: int = retry_after
def __reduce__(self) -> Tuple[type, Tuple[float]]: # type: ignore[override] def __reduce__(self) -> tuple[type, tuple[float]]: # type: ignore[override]
return self.__class__, (self.retry_after,) return self.__class__, (self.retry_after,)
@ -243,7 +230,7 @@ class Conflict(TelegramError):
__slots__ = () __slots__ = ()
def __reduce__(self) -> Tuple[type, Tuple[str]]: def __reduce__(self) -> tuple[type, tuple[str]]:
return self.__class__, (self.message,) return self.__class__, (self.message,)
@ -261,5 +248,5 @@ class PassportDecryptionError(TelegramError):
super().__init__(f"PassportDecryptionError: {message}") super().__init__(f"PassportDecryptionError: {message}")
self._msg = str(message) self._msg = str(message)
def __reduce__(self) -> Tuple[type, Tuple[str]]: def __reduce__(self) -> tuple[type, tuple[str]]:
return self.__class__, (self._msg,) return self.__class__, (self._msg,)

View file

@ -22,7 +22,8 @@ library.
import asyncio import asyncio
import contextlib import contextlib
import sys import sys
from typing import Any, AsyncIterator, Callable, Coroutine, Dict, List, Optional, Union from collections.abc import AsyncIterator, Coroutine
from typing import Any, Callable, Optional, Union
try: try:
from aiolimiter import AsyncLimiter from aiolimiter import AsyncLimiter
@ -152,7 +153,7 @@ class AIORateLimiter(BaseRateLimiter[int]):
self._group_max_rate = 0 self._group_max_rate = 0
self._group_time_period = 0 self._group_time_period = 0
self._group_limiters: Dict[Union[str, int], AsyncLimiter] = {} self._group_limiters: dict[Union[str, int], AsyncLimiter] = {}
self._max_retries: int = max_retries self._max_retries: int = max_retries
self._retry_after_event = asyncio.Event() self._retry_after_event = asyncio.Event()
self._retry_after_event.set() self._retry_after_event.set()
@ -187,10 +188,10 @@ class AIORateLimiter(BaseRateLimiter[int]):
self, self,
chat: bool, chat: bool,
group: Union[str, int, bool], group: Union[str, int, bool],
callback: Callable[..., Coroutine[Any, Any, Union[bool, JSONDict, List[JSONDict]]]], callback: Callable[..., Coroutine[Any, Any, Union[bool, JSONDict, list[JSONDict]]]],
args: Any, args: Any,
kwargs: Dict[str, Any], kwargs: dict[str, Any],
) -> Union[bool, JSONDict, List[JSONDict]]: ) -> Union[bool, JSONDict, list[JSONDict]]:
base_context = self._base_limiter if (chat and self._base_limiter) else null_context() base_context = self._base_limiter if (chat and self._base_limiter) else null_context()
group_context = ( group_context = (
self._get_group_limiter(group) if group and self._group_max_rate else null_context() self._get_group_limiter(group) if group and self._group_max_rate else null_context()
@ -205,13 +206,13 @@ class AIORateLimiter(BaseRateLimiter[int]):
# mypy doesn't understand that the last run of the for loop raises an exception # mypy doesn't understand that the last run of the for loop raises an exception
async def process_request( async def process_request(
self, self,
callback: Callable[..., Coroutine[Any, Any, Union[bool, JSONDict, List[JSONDict]]]], callback: Callable[..., Coroutine[Any, Any, Union[bool, JSONDict, list[JSONDict]]]],
args: Any, args: Any,
kwargs: Dict[str, Any], kwargs: dict[str, Any],
endpoint: str, # noqa: ARG002 endpoint: str, # noqa: ARG002
data: Dict[str, Any], data: dict[str, Any],
rate_limit_args: Optional[int], rate_limit_args: Optional[int],
) -> Union[bool, JSONDict, List[JSONDict]]: ) -> Union[bool, JSONDict, list[JSONDict]]:
""" """
Processes a request by applying rate limiting. Processes a request by applying rate limiting.

View file

@ -26,30 +26,11 @@ import platform
import signal import signal
import sys import sys
from collections import defaultdict from collections import defaultdict
from collections.abc import Awaitable, Coroutine, Generator, Mapping, Sequence
from copy import deepcopy from copy import deepcopy
from pathlib import Path from pathlib import Path
from types import MappingProxyType, TracebackType from types import MappingProxyType, TracebackType
from typing import ( from typing import TYPE_CHECKING, Any, Callable, Generic, NoReturn, Optional, TypeVar, Union
TYPE_CHECKING,
Any,
AsyncContextManager,
Awaitable,
Callable,
Coroutine,
DefaultDict,
Dict,
Generator,
Generic,
List,
Mapping,
NoReturn,
Optional,
Sequence,
Set,
Type,
TypeVar,
Union,
)
from telegram._update import Update from telegram._update import Update
from telegram._utils.defaultvalue import ( from telegram._utils.defaultvalue import (
@ -132,7 +113,10 @@ class ApplicationHandlerStop(Exception):
self.state: Optional[object] = state self.state: Optional[object] = state
class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Application"]): class Application(
Generic[BT, CCT, UD, CD, BD, JQ],
contextlib.AbstractAsyncContextManager["Application"],
):
"""This class dispatches all kinds of updates to its registered handlers, and is the entry """This class dispatches all kinds of updates to its registered handlers, and is the entry
point to a PTB application. point to a PTB application.
@ -224,12 +208,12 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
bot_data (:obj:`dict`): A dictionary handlers can use to store data for the bot. bot_data (:obj:`dict`): A dictionary handlers can use to store data for the bot.
persistence (:class:`telegram.ext.BasePersistence`): The persistence class to persistence (:class:`telegram.ext.BasePersistence`): The persistence class to
store data that should be persistent over restarts. store data that should be persistent over restarts.
handlers (Dict[:obj:`int`, List[:class:`telegram.ext.BaseHandler`]]): A dictionary mapping handlers (dict[:obj:`int`, list[:class:`telegram.ext.BaseHandler`]]): A dictionary mapping
each handler group to the list of handlers registered to that group. each handler group to the list of handlers registered to that group.
.. seealso:: .. seealso::
:meth:`add_handler`, :meth:`add_handlers`. :meth:`add_handler`, :meth:`add_handlers`.
error_handlers (Dict[:term:`coroutine function`, :obj:`bool`]): A dictionary where the keys error_handlers (dict[:term:`coroutine function`, :obj:`bool`]): A dictionary where the keys
are error handlers and the values indicate whether they are to be run blocking. are error handlers and the values indicate whether they are to be run blocking.
.. seealso:: .. seealso::
@ -323,8 +307,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
self.update_queue: asyncio.Queue[object] = update_queue self.update_queue: asyncio.Queue[object] = update_queue
self.context_types: ContextTypes[CCT, UD, CD, BD] = context_types self.context_types: ContextTypes[CCT, UD, CD, BD] = context_types
self.updater: Optional[Updater] = updater self.updater: Optional[Updater] = updater
self.handlers: Dict[int, List[BaseHandler[Any, CCT, Any]]] = {} self.handlers: dict[int, list[BaseHandler[Any, CCT, Any]]] = {}
self.error_handlers: Dict[ self.error_handlers: dict[
HandlerCallback[object, CCT, None], Union[bool, DefaultValue[bool]] HandlerCallback[object, CCT, None], Union[bool, DefaultValue[bool]]
] = {} ] = {}
self.post_init: Optional[ self.post_init: Optional[
@ -338,8 +322,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
] = post_stop ] = post_stop
self._update_processor = update_processor self._update_processor = update_processor
self.bot_data: BD = self.context_types.bot_data() self.bot_data: BD = self.context_types.bot_data()
self._user_data: DefaultDict[int, UD] = defaultdict(self.context_types.user_data) self._user_data: defaultdict[int, UD] = defaultdict(self.context_types.user_data)
self._chat_data: DefaultDict[int, CD] = defaultdict(self.context_types.chat_data) self._chat_data: defaultdict[int, CD] = defaultdict(self.context_types.chat_data)
# Read only mapping # Read only mapping
self.user_data: Mapping[int, UD] = MappingProxyType(self._user_data) self.user_data: Mapping[int, UD] = MappingProxyType(self._user_data)
self.chat_data: Mapping[int, CD] = MappingProxyType(self._chat_data) self.chat_data: Mapping[int, CD] = MappingProxyType(self._chat_data)
@ -350,14 +334,14 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
self.persistence = persistence self.persistence = persistence
# Some bookkeeping for persistence logic # Some bookkeeping for persistence logic
self._chat_ids_to_be_updated_in_persistence: Set[int] = set() self._chat_ids_to_be_updated_in_persistence: set[int] = set()
self._user_ids_to_be_updated_in_persistence: Set[int] = set() self._user_ids_to_be_updated_in_persistence: set[int] = set()
self._chat_ids_to_be_deleted_in_persistence: Set[int] = set() self._chat_ids_to_be_deleted_in_persistence: set[int] = set()
self._user_ids_to_be_deleted_in_persistence: Set[int] = set() self._user_ids_to_be_deleted_in_persistence: set[int] = set()
# This attribute will hold references to the conversation dicts of all conversation # This attribute will hold references to the conversation dicts of all conversation
# handlers so that we can extract the changed states during `update_persistence` # handlers so that we can extract the changed states during `update_persistence`
self._conversation_handler_conversations: Dict[ self._conversation_handler_conversations: dict[
str, TrackingDict[ConversationKey, object] str, TrackingDict[ConversationKey, object]
] = {} ] = {}
@ -369,7 +353,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
self.__update_persistence_task: Optional[asyncio.Task] = None self.__update_persistence_task: Optional[asyncio.Task] = None
self.__update_persistence_event = asyncio.Event() self.__update_persistence_event = asyncio.Event()
self.__update_persistence_lock = asyncio.Lock() self.__update_persistence_lock = asyncio.Lock()
self.__create_task_tasks: Set[asyncio.Task] = set() # Used for awaiting tasks upon exit self.__create_task_tasks: set[asyncio.Task] = set() # Used for awaiting tasks upon exit
self.__stop_running_marker = asyncio.Event() self.__stop_running_marker = asyncio.Event()
async def __aenter__(self: _AppType) -> _AppType: # noqa: PYI019 async def __aenter__(self: _AppType) -> _AppType: # noqa: PYI019
@ -391,7 +375,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
async def __aexit__( async def __aexit__(
self, self,
exc_type: Optional[Type[BaseException]], exc_type: Optional[type[BaseException]],
exc_val: Optional[BaseException], exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType], exc_tb: Optional[TracebackType],
) -> None: ) -> None:
@ -762,7 +746,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
allowed_updates: Optional[List[str]] = None, allowed_updates: Optional[list[str]] = None,
drop_pending_updates: Optional[bool] = None, drop_pending_updates: Optional[bool] = None,
close_loop: bool = True, close_loop: bool = True,
stop_signals: ODVInput[Sequence[int]] = DEFAULT_NONE, stop_signals: ODVInput[Sequence[int]] = DEFAULT_NONE,
@ -839,7 +823,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
:meth:`telegram.ext.ApplicationBuilder.get_updates_pool_timeout`. :meth:`telegram.ext.ApplicationBuilder.get_updates_pool_timeout`.
drop_pending_updates (:obj:`bool`, optional): Whether to clean any pending updates on drop_pending_updates (:obj:`bool`, optional): Whether to clean any pending updates on
Telegram servers before actually starting to poll. Default is :obj:`False`. Telegram servers before actually starting to poll. Default is :obj:`False`.
allowed_updates (List[:obj:`str`], optional): Passed to allowed_updates (list[:obj:`str`], optional): Passed to
:meth:`telegram.Bot.get_updates`. :meth:`telegram.Bot.get_updates`.
close_loop (:obj:`bool`, optional): If :obj:`True`, the current event loop will be close_loop (:obj:`bool`, optional): If :obj:`True`, the current event loop will be
closed upon shutdown. Defaults to :obj:`True`. closed upon shutdown. Defaults to :obj:`True`.
@ -904,7 +888,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
key: Optional[Union[str, Path]] = None, key: Optional[Union[str, Path]] = None,
bootstrap_retries: int = 0, bootstrap_retries: int = 0,
webhook_url: Optional[str] = None, webhook_url: Optional[str] = None,
allowed_updates: Optional[List[str]] = None, allowed_updates: Optional[list[str]] = None,
drop_pending_updates: Optional[bool] = None, drop_pending_updates: Optional[bool] = None,
ip_address: Optional[str] = None, ip_address: Optional[str] = None,
max_connections: int = 40, max_connections: int = 40,
@ -970,7 +954,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
webhook_url (:obj:`str`, optional): Explicitly specify the webhook url. Useful behind webhook_url (:obj:`str`, optional): Explicitly specify the webhook url. Useful behind
NAT, reverse proxy, etc. Default is derived from :paramref:`listen`, NAT, reverse proxy, etc. Default is derived from :paramref:`listen`,
:paramref:`port`, :paramref:`url_path`, :paramref:`cert`, and :paramref:`key`. :paramref:`port`, :paramref:`url_path`, :paramref:`cert`, and :paramref:`key`.
allowed_updates (List[:obj:`str`], optional): Passed to allowed_updates (list[:obj:`str`], optional): Passed to
:meth:`telegram.Bot.set_webhook`. :meth:`telegram.Bot.set_webhook`.
drop_pending_updates (:obj:`bool`, optional): Whether to clean any pending updates on drop_pending_updates (:obj:`bool`, optional): Whether to clean any pending updates on
Telegram servers before actually starting to poll. Default is :obj:`False`. Telegram servers before actually starting to poll. Default is :obj:`False`.
@ -1421,7 +1405,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
self, self,
handlers: Union[ handlers: Union[
Sequence[BaseHandler[Any, CCT, Any]], Sequence[BaseHandler[Any, CCT, Any]],
Dict[int, Sequence[BaseHandler[Any, CCT, Any]]], dict[int, Sequence[BaseHandler[Any, CCT, Any]]],
], ],
group: Union[int, DefaultValue[int]] = _DEFAULT_0, group: Union[int, DefaultValue[int]] = _DEFAULT_0,
) -> None: ) -> None:
@ -1432,7 +1416,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
Args: Args:
handlers (Sequence[:class:`telegram.ext.BaseHandler`] | \ handlers (Sequence[:class:`telegram.ext.BaseHandler`] | \
Dict[int, Sequence[:class:`telegram.ext.BaseHandler`]]): dict[int, Sequence[:class:`telegram.ext.BaseHandler`]]):
Specify a sequence of handlers *or* a dictionary where the keys are groups and Specify a sequence of handlers *or* a dictionary where the keys are groups and
values are handlers. values are handlers.
@ -1693,7 +1677,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
_LOGGER.debug("Starting next run of updating the persistence.") _LOGGER.debug("Starting next run of updating the persistence.")
coroutines: Set[Coroutine] = set() coroutines: set[Coroutine] = set()
# Mypy doesn't know that persistence.set_bot (see above) already checks that # Mypy doesn't know that persistence.set_bot (see above) already checks that
# self.bot is an instance of ExtBot if callback_data should be stored ... # self.bot is an instance of ExtBot if callback_data should be stored ...

View file

@ -18,20 +18,9 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the Builder classes for the telegram.ext module.""" """This module contains the Builder classes for the telegram.ext module."""
from asyncio import Queue from asyncio import Queue
from collections.abc import Collection, Coroutine
from pathlib import Path from pathlib import Path
from typing import ( from typing import TYPE_CHECKING, Any, Callable, Generic, Optional, TypeVar, Union
TYPE_CHECKING,
Any,
Callable,
Collection,
Coroutine,
Dict,
Generic,
Optional,
Type,
TypeVar,
Union,
)
import httpx import httpx
@ -212,8 +201,8 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
self._persistence: ODVInput[BasePersistence] = DEFAULT_NONE self._persistence: ODVInput[BasePersistence] = DEFAULT_NONE
self._context_types: DVType[ContextTypes] = DefaultValue(ContextTypes()) self._context_types: DVType[ContextTypes] = DefaultValue(ContextTypes())
self._application_class: DVType[Type[Application]] = DefaultValue(Application) self._application_class: DVType[type[Application]] = DefaultValue(Application)
self._application_kwargs: Dict[str, object] = {} self._application_kwargs: dict[str, object] = {}
self._update_processor: BaseUpdateProcessor = SimpleUpdateProcessor( self._update_processor: BaseUpdateProcessor = SimpleUpdateProcessor(
max_concurrent_updates=1 max_concurrent_updates=1
) )
@ -350,8 +339,8 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
def application_class( def application_class(
self: BuilderType, self: BuilderType,
application_class: Type[Application[Any, Any, Any, Any, Any, Any]], application_class: type[Application[Any, Any, Any, Any, Any, Any]],
kwargs: Optional[Dict[str, object]] = None, kwargs: Optional[dict[str, object]] = None,
) -> BuilderType: ) -> BuilderType:
"""Sets a custom subclass instead of :class:`telegram.ext.Application`. The """Sets a custom subclass instead of :class:`telegram.ext.Application`. The
subclass's ``__init__`` should look like this subclass's ``__init__`` should look like this
@ -365,7 +354,7 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
Args: Args:
application_class (:obj:`type`): A subclass of :class:`telegram.ext.Application` application_class (:obj:`type`): A subclass of :class:`telegram.ext.Application`
kwargs (Dict[:obj:`str`, :obj:`object`], optional): Keyword arguments for the kwargs (dict[:obj:`str`, :obj:`object`], optional): Keyword arguments for the
initialization. Defaults to an empty dict. initialization. Defaults to an empty dict.
Returns: Returns:
@ -1397,9 +1386,9 @@ InitApplicationBuilder = ( # This is defined all the way down here so that its
ApplicationBuilder[ # by Pylance correctly. ApplicationBuilder[ # by Pylance correctly.
ExtBot[None], ExtBot[None],
ContextTypes.DEFAULT_TYPE, ContextTypes.DEFAULT_TYPE,
Dict[Any, Any], dict[Any, Any],
Dict[Any, Any], dict[Any, Any],
Dict[Any, Any], dict[Any, Any],
JobQueue[ContextTypes.DEFAULT_TYPE], JobQueue[ContextTypes.DEFAULT_TYPE],
] ]
) )

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the BasePersistence class.""" """This module contains the BasePersistence class."""
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Dict, Generic, NamedTuple, NoReturn, Optional from typing import Generic, NamedTuple, NoReturn, Optional
from telegram._bot import Bot from telegram._bot import Bot
from telegram.ext._extbot import ExtBot from telegram.ext._extbot import ExtBot
@ -184,7 +184,7 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
self.bot = bot self.bot = bot
@abstractmethod @abstractmethod
async def get_user_data(self) -> Dict[int, UD]: async def get_user_data(self) -> dict[int, UD]:
"""Will be called by :class:`telegram.ext.Application` upon creation with a """Will be called by :class:`telegram.ext.Application` upon creation with a
persistence object. It should return the ``user_data`` if stored, or an empty persistence object. It should return the ``user_data`` if stored, or an empty
:obj:`dict`. In the latter case, the dictionary should produce values :obj:`dict`. In the latter case, the dictionary should produce values
@ -198,12 +198,12 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
This method may now return a :obj:`dict` instead of a :obj:`collections.defaultdict` This method may now return a :obj:`dict` instead of a :obj:`collections.defaultdict`
Returns: Returns:
Dict[:obj:`int`, :obj:`dict` | :attr:`telegram.ext.ContextTypes.user_data`]: dict[:obj:`int`, :obj:`dict` | :attr:`telegram.ext.ContextTypes.user_data`]:
The restored user data. The restored user data.
""" """
@abstractmethod @abstractmethod
async def get_chat_data(self) -> Dict[int, CD]: async def get_chat_data(self) -> dict[int, CD]:
"""Will be called by :class:`telegram.ext.Application` upon creation with a """Will be called by :class:`telegram.ext.Application` upon creation with a
persistence object. It should return the ``chat_data`` if stored, or an empty persistence object. It should return the ``chat_data`` if stored, or an empty
:obj:`dict`. In the latter case, the dictionary should produce values :obj:`dict`. In the latter case, the dictionary should produce values
@ -217,7 +217,7 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
This method may now return a :obj:`dict` instead of a :obj:`collections.defaultdict` This method may now return a :obj:`dict` instead of a :obj:`collections.defaultdict`
Returns: Returns:
Dict[:obj:`int`, :obj:`dict` | :attr:`telegram.ext.ContextTypes.chat_data`]: dict[:obj:`int`, :obj:`dict` | :attr:`telegram.ext.ContextTypes.chat_data`]:
The restored chat data. The restored chat data.
""" """
@ -233,7 +233,7 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
if :class:`telegram.ext.ContextTypes` are used. if :class:`telegram.ext.ContextTypes` are used.
Returns: Returns:
Dict[:obj:`int`, :obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`]: dict[:obj:`int`, :obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`]:
The restored bot data. The restored bot data.
""" """
@ -248,8 +248,8 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
Changed this method into an :external:func:`~abc.abstractmethod`. Changed this method into an :external:func:`~abc.abstractmethod`.
Returns: Returns:
Tuple[List[Tuple[:obj:`str`, :obj:`float`, Dict[:obj:`str`, :class:`object`]]], tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]],
Dict[:obj:`str`, :obj:`str`]] | :obj:`None`: The restored metadata or :obj:`None`, dict[:obj:`str`, :obj:`str`]] | :obj:`None`: The restored metadata or :obj:`None`,
if no data was stored. if no data was stored.
""" """
@ -324,8 +324,8 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
Changed this method into an :external:func:`~abc.abstractmethod`. Changed this method into an :external:func:`~abc.abstractmethod`.
Args: Args:
data (Tuple[List[Tuple[:obj:`str`, :obj:`float`, \ data (tuple[list[tuple[:obj:`str`, :obj:`float`, \
Dict[:obj:`str`, :obj:`Any`]]], Dict[:obj:`str`, :obj:`str`]] | :obj:`None`): dict[:obj:`str`, :obj:`Any`]]], dict[:obj:`str`, :obj:`str`]] | :obj:`None`):
The relevant data to restore :class:`telegram.ext.CallbackDataCache`. The relevant data to restore :class:`telegram.ext.CallbackDataCache`.
""" """

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a class that allows to rate limit requests to the Bot API.""" """This module contains a class that allows to rate limit requests to the Bot API."""
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Any, Callable, Coroutine, Dict, Generic, List, Optional, Union from collections.abc import Coroutine
from typing import Any, Callable, Generic, Optional, Union
from telegram._utils.types import JSONDict from telegram._utils.types import JSONDict
from telegram.ext._utils.types import RLARGS from telegram.ext._utils.types import RLARGS
@ -56,13 +57,13 @@ class BaseRateLimiter(ABC, Generic[RLARGS]):
@abstractmethod @abstractmethod
async def process_request( async def process_request(
self, self,
callback: Callable[..., Coroutine[Any, Any, Union[bool, JSONDict, List[JSONDict]]]], callback: Callable[..., Coroutine[Any, Any, Union[bool, JSONDict, list[JSONDict]]]],
args: Any, args: Any,
kwargs: Dict[str, Any], kwargs: dict[str, Any],
endpoint: str, endpoint: str,
data: Dict[str, Any], data: dict[str, Any],
rate_limit_args: Optional[RLARGS], rate_limit_args: Optional[RLARGS],
) -> Union[bool, JSONDict, List[JSONDict]]: ) -> Union[bool, JSONDict, list[JSONDict]]:
""" """
Process a request. Must be implemented by a subclass. Process a request. Must be implemented by a subclass.
@ -107,13 +108,13 @@ class BaseRateLimiter(ABC, Generic[RLARGS]):
Args: Args:
callback (Callable[..., :term:`coroutine`]): The coroutine function that must be called callback (Callable[..., :term:`coroutine`]): The coroutine function that must be called
to make the request. to make the request.
args (Tuple[:obj:`object`]): The positional arguments for the :paramref:`callback` args (tuple[:obj:`object`]): The positional arguments for the :paramref:`callback`
function. function.
kwargs (Dict[:obj:`str`, :obj:`object`]): The keyword arguments for the kwargs (dict[:obj:`str`, :obj:`object`]): The keyword arguments for the
:paramref:`callback` function. :paramref:`callback` function.
endpoint (:obj:`str`): The endpoint that the request is made for, e.g. endpoint (:obj:`str`): The endpoint that the request is made for, e.g.
``"sendMessage"``. ``"sendMessage"``.
data (Dict[:obj:`str`, :obj:`object`]): The parameters that were passed to the method data (dict[:obj:`str`, :obj:`object`]): The parameters that were passed to the method
of :class:`~telegram.ext.ExtBot`. Any ``api_kwargs`` are included in this and of :class:`~telegram.ext.ExtBot`. Any ``api_kwargs`` are included in this and
any :paramref:`~telegram.ext.ExtBot.defaults` are already applied. any :paramref:`~telegram.ext.ExtBot.defaults` are already applied.
@ -136,6 +137,6 @@ class BaseRateLimiter(ABC, Generic[RLARGS]):
the request. the request.
Returns: Returns:
:obj:`bool` | Dict[:obj:`str`, :obj:`object`] | :obj:`None`: The result of the :obj:`bool` | dict[:obj:`str`, :obj:`object`] | :obj:`None`: The result of the
callback function. callback function.
""" """

View file

@ -19,13 +19,17 @@
"""This module contains the BaseProcessor class.""" """This module contains the BaseProcessor class."""
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from asyncio import BoundedSemaphore from asyncio import BoundedSemaphore
from contextlib import AbstractAsyncContextManager
from types import TracebackType from types import TracebackType
from typing import Any, AsyncContextManager, Awaitable, Optional, Type, TypeVar, final from typing import TYPE_CHECKING, Any, Optional, TypeVar, final
if TYPE_CHECKING:
from collections.abc import Awaitable
_BUPT = TypeVar("_BUPT", bound="BaseUpdateProcessor") _BUPT = TypeVar("_BUPT", bound="BaseUpdateProcessor")
class BaseUpdateProcessor(AsyncContextManager["BaseUpdateProcessor"], ABC): class BaseUpdateProcessor(AbstractAsyncContextManager["BaseUpdateProcessor"], ABC):
"""An abstract base class for update processors. You can use this class to implement """An abstract base class for update processors. You can use this class to implement
your own update processor. your own update processor.
@ -88,7 +92,7 @@ class BaseUpdateProcessor(AsyncContextManager["BaseUpdateProcessor"], ABC):
async def __aexit__( async def __aexit__(
self, self,
exc_type: Optional[Type[BaseException]], exc_type: Optional[type[BaseException]],
exc_val: Optional[BaseException], exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType], exc_tb: Optional[TracebackType],
) -> None: ) -> None:

View file

@ -17,21 +17,10 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the CallbackContext class.""" """This module contains the CallbackContext class."""
from typing import (
TYPE_CHECKING, from collections.abc import Awaitable, Generator
Any, from re import Match
Awaitable, from typing import TYPE_CHECKING, Any, Generic, NoReturn, Optional, TypeVar, Union
Dict,
Generator,
Generic,
List,
Match,
NoReturn,
Optional,
Type,
TypeVar,
Union,
)
from telegram._callbackquery import CallbackQuery from telegram._callbackquery import CallbackQuery
from telegram._update import Update from telegram._update import Update
@ -105,11 +94,11 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
coroutine (:term:`awaitable`): Optional. Only present in error handlers if the coroutine (:term:`awaitable`): Optional. Only present in error handlers if the
error was caused by an awaitable run with :meth:`Application.create_task` or a handler error was caused by an awaitable run with :meth:`Application.create_task` or a handler
callback with :attr:`block=False <BaseHandler.block>`. callback with :attr:`block=False <BaseHandler.block>`.
matches (List[:meth:`re.Match <re.Match.expand>`]): Optional. If the associated update matches (list[:meth:`re.Match <re.Match.expand>`]): Optional. If the associated update
originated from a :class:`filters.Regex`, this will contain a list of match objects for originated from a :class:`filters.Regex`, this will contain a list of match objects for
every pattern where ``re.search(pattern, string)`` returned a match. Note that filters every pattern where ``re.search(pattern, string)`` returned a match. Note that filters
short circuit, so combined regex filters will not always be evaluated. short circuit, so combined regex filters will not always be evaluated.
args (List[:obj:`str`]): Optional. Arguments passed to a command if the associated update args (list[:obj:`str`]): Optional. Arguments passed to a command if the associated update
is handled by :class:`telegram.ext.CommandHandler`, :class:`telegram.ext.PrefixHandler` is handled by :class:`telegram.ext.CommandHandler`, :class:`telegram.ext.PrefixHandler`
or :class:`telegram.ext.StringCommandHandler`. It contains a list of the words in the or :class:`telegram.ext.StringCommandHandler`. It contains a list of the words in the
text after the command, using any whitespace string as a delimiter. text after the command, using any whitespace string as a delimiter.
@ -145,8 +134,8 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
self._application: Application[BT, ST, UD, CD, BD, Any] = application self._application: Application[BT, ST, UD, CD, BD, Any] = application
self._chat_id: Optional[int] = chat_id self._chat_id: Optional[int] = chat_id
self._user_id: Optional[int] = user_id self._user_id: Optional[int] = user_id
self.args: Optional[List[str]] = None self.args: Optional[list[str]] = None
self.matches: Optional[List[Match[str]]] = None self.matches: Optional[list[Match[str]]] = None
self.error: Optional[Exception] = None self.error: Optional[Exception] = None
self.job: Optional[Job[Any]] = None self.job: Optional[Job[Any]] = None
self.coroutine: Optional[ self.coroutine: Optional[
@ -282,7 +271,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
@classmethod @classmethod
def from_error( def from_error(
cls: Type["CCT"], cls: type["CCT"],
update: object, update: object,
error: Exception, error: Exception,
application: "Application[BT, CCT, UD, CD, BD, Any]", application: "Application[BT, CCT, UD, CD, BD, Any]",
@ -335,7 +324,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
@classmethod @classmethod
def from_update( def from_update(
cls: Type["CCT"], cls: type["CCT"],
update: object, update: object,
application: "Application[Any, CCT, Any, Any, Any, Any]", application: "Application[Any, CCT, Any, Any, Any, Any]",
) -> "CCT": ) -> "CCT":
@ -365,7 +354,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
@classmethod @classmethod
def from_job( def from_job(
cls: Type["CCT"], cls: type["CCT"],
job: "Job[CCT]", job: "Job[CCT]",
application: "Application[Any, CCT, Any, Any, Any, Any]", application: "Application[Any, CCT, Any, Any, Any, Any]",
) -> "CCT": ) -> "CCT":
@ -387,11 +376,11 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
self.job = job self.job = job
return self return self
def update(self, data: Dict[str, object]) -> None: def update(self, data: dict[str, object]) -> None:
"""Updates ``self.__slots__`` with the passed data. """Updates ``self.__slots__`` with the passed data.
Args: Args:
data (Dict[:obj:`str`, :obj:`object`]): The data. data (dict[:obj:`str`, :obj:`object`]): The data.
""" """
for key, value in data.items(): for key, value in data.items():
setattr(self, key, value) setattr(self, key, value)

View file

@ -18,8 +18,9 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the CallbackDataCache class.""" """This module contains the CallbackDataCache class."""
import time import time
from collections.abc import MutableMapping
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Any, Dict, MutableMapping, Optional, Tuple, Union, cast from typing import TYPE_CHECKING, Any, Optional, Union, cast
from uuid import uuid4 from uuid import uuid4
try: try:
@ -70,7 +71,7 @@ class InvalidCallbackData(TelegramError):
) )
self.callback_data: Optional[str] = callback_data self.callback_data: Optional[str] = callback_data
def __reduce__(self) -> Tuple[type, Tuple[Optional[str]]]: # type: ignore[override] def __reduce__(self) -> tuple[type, tuple[Optional[str]]]: # type: ignore[override]
"""Defines how to serialize the exception for pickle. See """Defines how to serialize the exception for pickle. See
:py:meth:`object.__reduce__` for more info. :py:meth:`object.__reduce__` for more info.
@ -87,7 +88,7 @@ class _KeyboardData:
self, self,
keyboard_uuid: str, keyboard_uuid: str,
access_time: Optional[float] = None, access_time: Optional[float] = None,
button_data: Optional[Dict[str, object]] = None, button_data: Optional[dict[str, object]] = None,
): ):
self.keyboard_uuid = keyboard_uuid self.keyboard_uuid = keyboard_uuid
self.button_data = button_data or {} self.button_data = button_data or {}
@ -97,7 +98,7 @@ class _KeyboardData:
"""Updates the access time with the current time.""" """Updates the access time with the current time."""
self.access_time = time.time() self.access_time = time.time()
def to_tuple(self) -> Tuple[str, float, Dict[str, object]]: def to_tuple(self) -> tuple[str, float, dict[str, object]]:
"""Gives a tuple representation consisting of the keyboard uuid, the access time and the """Gives a tuple representation consisting of the keyboard uuid, the access time and the
button data. button data.
""" """
@ -140,8 +141,8 @@ class CallbackDataCache:
maxsize (:obj:`int`, optional): Maximum number of items in each of the internal mappings. maxsize (:obj:`int`, optional): Maximum number of items in each of the internal mappings.
Defaults to ``1024``. Defaults to ``1024``.
persistent_data (Tuple[List[Tuple[:obj:`str`, :obj:`float`, \ persistent_data (tuple[list[tuple[:obj:`str`, :obj:`float`, \
Dict[:obj:`str`, :class:`object`]]], Dict[:obj:`str`, :obj:`str`]], optional): \ dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]], optional): \
Data to initialize the cache with, as returned by \ Data to initialize the cache with, as returned by \
:meth:`telegram.ext.BasePersistence.get_callback_data`. :meth:`telegram.ext.BasePersistence.get_callback_data`.
@ -181,8 +182,8 @@ class CallbackDataCache:
.. versionadded:: 20.0 .. versionadded:: 20.0
Args: Args:
persistent_data (Tuple[List[Tuple[:obj:`str`, :obj:`float`, \ persistent_data (tuple[list[tuple[:obj:`str`, :obj:`float`, \
Dict[:obj:`str`, :class:`object`]]], Dict[:obj:`str`, :obj:`str`]], optional): \ dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]], optional): \
Data to load, as returned by \ Data to load, as returned by \
:meth:`telegram.ext.BasePersistence.get_callback_data`. :meth:`telegram.ext.BasePersistence.get_callback_data`.
""" """
@ -205,8 +206,8 @@ class CallbackDataCache:
@property @property
def persistence_data(self) -> CDCData: def persistence_data(self) -> CDCData:
"""Tuple[List[Tuple[:obj:`str`, :obj:`float`, Dict[:obj:`str`, :class:`object`]]], """tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]],
Dict[:obj:`str`, :obj:`str`]]: The data that needs to be persisted to allow dict[:obj:`str`, :obj:`str`]]: The data that needs to be persisted to allow
caching callback data across bot reboots. caching callback data across bot reboots.
""" """
# While building a list/dict from the LRUCaches has linear runtime (in the number of # While building a list/dict from the LRUCaches has linear runtime (in the number of
@ -269,7 +270,7 @@ class CallbackDataCache:
def __get_keyboard_uuid_and_button_data( def __get_keyboard_uuid_and_button_data(
self, callback_data: str self, callback_data: str
) -> Union[Tuple[str, object], Tuple[None, InvalidCallbackData]]: ) -> Union[tuple[str, object], tuple[None, InvalidCallbackData]]:
keyboard, button = self.extract_uuids(callback_data) keyboard, button = self.extract_uuids(callback_data)
try: try:
# we get the values before calling update() in case KeyErrors are raised # we get the values before calling update() in case KeyErrors are raised
@ -283,7 +284,7 @@ class CallbackDataCache:
return keyboard, button_data return keyboard, button_data
@staticmethod @staticmethod
def extract_uuids(callback_data: str) -> Tuple[str, str]: def extract_uuids(callback_data: str) -> tuple[str, str]:
"""Extracts the keyboard uuid and the button uuid from the given :paramref:`callback_data`. """Extracts the keyboard uuid and the button uuid from the given :paramref:`callback_data`.
Args: Args:

View file

@ -17,13 +17,13 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the auxiliary class ContextTypes.""" """This module contains the auxiliary class ContextTypes."""
from typing import Any, Dict, Generic, Type, overload from typing import Any, Generic, overload
from telegram.ext._callbackcontext import CallbackContext from telegram.ext._callbackcontext import CallbackContext
from telegram.ext._extbot import ExtBot from telegram.ext._extbot import ExtBot
from telegram.ext._utils.types import BD, CCT, CD, UD from telegram.ext._utils.types import BD, CCT, CD, UD
ADict = Dict[Any, Any] ADict = dict[Any, Any]
class ContextTypes(Generic[CCT, UD, CD, BD]): class ContextTypes(Generic[CCT, UD, CD, BD]):
@ -83,109 +83,109 @@ class ContextTypes(Generic[CCT, UD, CD, BD]):
): ... ): ...
@overload @overload
def __init__(self: "ContextTypes[CCT, ADict, ADict, ADict]", context: Type[CCT]): ... def __init__(self: "ContextTypes[CCT, ADict, ADict, ADict]", context: type[CCT]): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CallbackContext[ExtBot[Any], UD, ADict, ADict], UD, ADict, ADict]", self: "ContextTypes[CallbackContext[ExtBot[Any], UD, ADict, ADict], UD, ADict, ADict]",
user_data: Type[UD], user_data: type[UD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CallbackContext[ExtBot[Any], ADict, CD, ADict], ADict, CD, ADict]", self: "ContextTypes[CallbackContext[ExtBot[Any], ADict, CD, ADict], ADict, CD, ADict]",
chat_data: Type[CD], chat_data: type[CD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CallbackContext[ExtBot[Any], ADict, ADict, BD], ADict, ADict, BD]", self: "ContextTypes[CallbackContext[ExtBot[Any], ADict, ADict, BD], ADict, ADict, BD]",
bot_data: Type[BD], bot_data: type[BD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CCT, UD, ADict, ADict]", context: Type[CCT], user_data: Type[UD] self: "ContextTypes[CCT, UD, ADict, ADict]", context: type[CCT], user_data: type[UD]
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CCT, ADict, CD, ADict]", context: Type[CCT], chat_data: Type[CD] self: "ContextTypes[CCT, ADict, CD, ADict]", context: type[CCT], chat_data: type[CD]
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CCT, ADict, ADict, BD]", context: Type[CCT], bot_data: Type[BD] self: "ContextTypes[CCT, ADict, ADict, BD]", context: type[CCT], bot_data: type[BD]
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CallbackContext[ExtBot[Any], UD, CD, ADict], UD, CD, ADict]", self: "ContextTypes[CallbackContext[ExtBot[Any], UD, CD, ADict], UD, CD, ADict]",
user_data: Type[UD], user_data: type[UD],
chat_data: Type[CD], chat_data: type[CD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CallbackContext[ExtBot[Any], UD, ADict, BD], UD, ADict, BD]", self: "ContextTypes[CallbackContext[ExtBot[Any], UD, ADict, BD], UD, ADict, BD]",
user_data: Type[UD], user_data: type[UD],
bot_data: Type[BD], bot_data: type[BD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CallbackContext[ExtBot[Any], ADict, CD, BD], ADict, CD, BD]", self: "ContextTypes[CallbackContext[ExtBot[Any], ADict, CD, BD], ADict, CD, BD]",
chat_data: Type[CD], chat_data: type[CD],
bot_data: Type[BD], bot_data: type[BD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CCT, UD, CD, ADict]", self: "ContextTypes[CCT, UD, CD, ADict]",
context: Type[CCT], context: type[CCT],
user_data: Type[UD], user_data: type[UD],
chat_data: Type[CD], chat_data: type[CD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CCT, UD, ADict, BD]", self: "ContextTypes[CCT, UD, ADict, BD]",
context: Type[CCT], context: type[CCT],
user_data: Type[UD], user_data: type[UD],
bot_data: Type[BD], bot_data: type[BD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CCT, ADict, CD, BD]", self: "ContextTypes[CCT, ADict, CD, BD]",
context: Type[CCT], context: type[CCT],
chat_data: Type[CD], chat_data: type[CD],
bot_data: Type[BD], bot_data: type[BD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CallbackContext[ExtBot[Any], UD, CD, BD], UD, CD, BD]", self: "ContextTypes[CallbackContext[ExtBot[Any], UD, CD, BD], UD, CD, BD]",
user_data: Type[UD], user_data: type[UD],
chat_data: Type[CD], chat_data: type[CD],
bot_data: Type[BD], bot_data: type[BD],
): ... ): ...
@overload @overload
def __init__( def __init__(
self: "ContextTypes[CCT, UD, CD, BD]", self: "ContextTypes[CCT, UD, CD, BD]",
context: Type[CCT], context: type[CCT],
user_data: Type[UD], user_data: type[UD],
chat_data: Type[CD], chat_data: type[CD],
bot_data: Type[BD], bot_data: type[BD],
): ... ): ...
def __init__( # type: ignore[misc] def __init__( # type: ignore[misc]
self, self,
context: "Type[CallbackContext[ExtBot[Any], ADict, ADict, ADict]]" = CallbackContext, context: "type[CallbackContext[ExtBot[Any], ADict, ADict, ADict]]" = CallbackContext,
bot_data: Type[ADict] = dict, bot_data: type[ADict] = dict,
chat_data: Type[ADict] = dict, chat_data: type[ADict] = dict,
user_data: Type[ADict] = dict, user_data: type[ADict] = dict,
): ):
if not issubclass(context, CallbackContext): if not issubclass(context, CallbackContext):
raise TypeError("context must be a subclass of CallbackContext.") raise TypeError("context must be a subclass of CallbackContext.")
@ -198,28 +198,28 @@ class ContextTypes(Generic[CCT, UD, CD, BD]):
self._user_data = user_data self._user_data = user_data
@property @property
def context(self) -> Type[CCT]: def context(self) -> type[CCT]:
"""The type of the ``context`` argument of all (error-)handler callbacks and job """The type of the ``context`` argument of all (error-)handler callbacks and job
callbacks. callbacks.
""" """
return self._context # type: ignore[return-value] return self._context # type: ignore[return-value]
@property @property
def bot_data(self) -> Type[BD]: def bot_data(self) -> type[BD]:
"""The type of :attr:`context.bot_data <CallbackContext.bot_data>` of all (error-)handler """The type of :attr:`context.bot_data <CallbackContext.bot_data>` of all (error-)handler
callbacks and job callbacks. callbacks and job callbacks.
""" """
return self._bot_data # type: ignore[return-value] return self._bot_data # type: ignore[return-value]
@property @property
def chat_data(self) -> Type[CD]: def chat_data(self) -> type[CD]:
"""The type of :attr:`context.chat_data <CallbackContext.chat_data>` of all (error-)handler """The type of :attr:`context.chat_data <CallbackContext.chat_data>` of all (error-)handler
callbacks and job callbacks. callbacks and job callbacks.
""" """
return self._chat_data # type: ignore[return-value] return self._chat_data # type: ignore[return-value]
@property @property
def user_data(self) -> Type[UD]: def user_data(self) -> type[UD]:
"""The type of :attr:`context.user_data <CallbackContext.user_data>` of all (error-)handler """The type of :attr:`context.user_data <CallbackContext.user_data>` of all (error-)handler
callbacks and job callbacks. callbacks and job callbacks.
""" """

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # 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.""" """This module contains the class Defaults, which allows passing default values to Application."""
import datetime import datetime
from typing import Any, Dict, NoReturn, Optional, final from typing import Any, NoReturn, Optional, final
from telegram import LinkPreviewOptions from telegram import LinkPreviewOptions
from telegram._utils.datetime import UTC from telegram._utils.datetime import UTC
@ -228,7 +228,7 @@ class Defaults:
return False return False
@property @property
def api_defaults(self) -> Dict[str, Any]: # skip-cq: PY-D0003 def api_defaults(self) -> dict[str, Any]: # skip-cq: PY-D0003
return self._api_defaults return self._api_defaults
@property @property

View file

@ -19,7 +19,7 @@
"""This module contains the DictPersistence class.""" """This module contains the DictPersistence class."""
import json import json
from copy import deepcopy from copy import deepcopy
from typing import TYPE_CHECKING, Any, Dict, Optional, cast from typing import TYPE_CHECKING, Any, Optional, cast
from telegram.ext import BasePersistence, PersistenceInput from telegram.ext import BasePersistence, PersistenceInput
from telegram.ext._utils.types import CDCData, ConversationDict, ConversationKey from telegram.ext._utils.types import CDCData, ConversationDict, ConversationKey
@ -28,7 +28,7 @@ if TYPE_CHECKING:
from telegram._utils.types import JSONDict from telegram._utils.types import JSONDict
class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any, Any]]): class DictPersistence(BasePersistence[dict[Any, Any], dict[Any, Any], dict[Any, Any]]):
"""Using Python's :obj:`dict` and :mod:`json` for making your bot persistent. """Using Python's :obj:`dict` and :mod:`json` for making your bot persistent.
Attention: Attention:
@ -170,7 +170,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
) from exc ) from exc
@property @property
def user_data(self) -> Optional[Dict[int, Dict[Any, Any]]]: def user_data(self) -> Optional[dict[int, dict[Any, Any]]]:
""":obj:`dict`: The user_data as a dict.""" """:obj:`dict`: The user_data as a dict."""
return self._user_data return self._user_data
@ -182,7 +182,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
return json.dumps(self.user_data) return json.dumps(self.user_data)
@property @property
def chat_data(self) -> Optional[Dict[int, Dict[Any, Any]]]: def chat_data(self) -> Optional[dict[int, dict[Any, Any]]]:
""":obj:`dict`: The chat_data as a dict.""" """:obj:`dict`: The chat_data as a dict."""
return self._chat_data return self._chat_data
@ -194,7 +194,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
return json.dumps(self.chat_data) return json.dumps(self.chat_data)
@property @property
def bot_data(self) -> Optional[Dict[Any, Any]]: def bot_data(self) -> Optional[dict[Any, Any]]:
""":obj:`dict`: The bot_data as a dict.""" """:obj:`dict`: The bot_data as a dict."""
return self._bot_data return self._bot_data
@ -207,8 +207,8 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
@property @property
def callback_data(self) -> Optional[CDCData]: def callback_data(self) -> Optional[CDCData]:
"""Tuple[List[Tuple[:obj:`str`, :obj:`float`, Dict[:obj:`str`, :class:`object`]]], \ """tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], \
Dict[:obj:`str`, :obj:`str`]]: The metadata on the stored callback data. dict[:obj:`str`, :obj:`str`]]: The metadata on the stored callback data.
.. versionadded:: 13.6 .. versionadded:: 13.6
""" """
@ -225,7 +225,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
return json.dumps(self.callback_data) return json.dumps(self.callback_data)
@property @property
def conversations(self) -> Optional[Dict[str, ConversationDict]]: def conversations(self) -> Optional[dict[str, ConversationDict]]:
""":obj:`dict`: The conversations as a dict.""" """:obj:`dict`: The conversations as a dict."""
return self._conversations return self._conversations
@ -238,7 +238,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
return self._encode_conversations_to_json(self.conversations) return self._encode_conversations_to_json(self.conversations)
return json.dumps(self.conversations) return json.dumps(self.conversations)
async def get_user_data(self) -> Dict[int, Dict[object, object]]: async def get_user_data(self) -> dict[int, dict[object, object]]:
"""Returns the user_data created from the ``user_data_json`` or an empty :obj:`dict`. """Returns the user_data created from the ``user_data_json`` or an empty :obj:`dict`.
Returns: Returns:
@ -248,7 +248,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
self._user_data = {} self._user_data = {}
return deepcopy(self.user_data) # type: ignore[arg-type] return deepcopy(self.user_data) # type: ignore[arg-type]
async def get_chat_data(self) -> Dict[int, Dict[object, object]]: async def get_chat_data(self) -> dict[int, dict[object, object]]:
"""Returns the chat_data created from the ``chat_data_json`` or an empty :obj:`dict`. """Returns the chat_data created from the ``chat_data_json`` or an empty :obj:`dict`.
Returns: Returns:
@ -258,7 +258,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
self._chat_data = {} self._chat_data = {}
return deepcopy(self.chat_data) # type: ignore[arg-type] return deepcopy(self.chat_data) # type: ignore[arg-type]
async def get_bot_data(self) -> Dict[object, object]: async def get_bot_data(self) -> dict[object, object]:
"""Returns the bot_data created from the ``bot_data_json`` or an empty :obj:`dict`. """Returns the bot_data created from the ``bot_data_json`` or an empty :obj:`dict`.
Returns: Returns:
@ -274,8 +274,8 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
.. versionadded:: 13.6 .. versionadded:: 13.6
Returns: Returns:
Tuple[List[Tuple[:obj:`str`, :obj:`float`, Dict[:obj:`str`, :class:`object`]]], \ tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], \
Dict[:obj:`str`, :obj:`str`]]: The restored metadata or :obj:`None`, \ dict[:obj:`str`, :obj:`str`]]: The restored metadata or :obj:`None`, \
if no data was stored. if no data was stored.
""" """
if self.callback_data is None: if self.callback_data is None:
@ -311,7 +311,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
self._conversations[name][key] = new_state self._conversations[name][key] = new_state
self._conversations_json = None self._conversations_json = None
async def update_user_data(self, user_id: int, data: Dict[Any, Any]) -> None: async def update_user_data(self, user_id: int, data: dict[Any, Any]) -> None:
"""Will update the user_data (if changed). """Will update the user_data (if changed).
Args: Args:
@ -325,7 +325,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
self._user_data[user_id] = data self._user_data[user_id] = data
self._user_data_json = None self._user_data_json = None
async def update_chat_data(self, chat_id: int, data: Dict[Any, Any]) -> None: async def update_chat_data(self, chat_id: int, data: dict[Any, Any]) -> None:
"""Will update the chat_data (if changed). """Will update the chat_data (if changed).
Args: Args:
@ -339,7 +339,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
self._chat_data[chat_id] = data self._chat_data[chat_id] = data
self._chat_data_json = None self._chat_data_json = None
async def update_bot_data(self, data: Dict[Any, Any]) -> None: async def update_bot_data(self, data: dict[Any, Any]) -> None:
"""Will update the bot_data (if changed). """Will update the bot_data (if changed).
Args: Args:
@ -356,8 +356,8 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
.. versionadded:: 13.6 .. versionadded:: 13.6
Args: Args:
data (Tuple[List[Tuple[:obj:`str`, :obj:`float`, Dict[:obj:`str`, :class:`object`]]], \ data (tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], \
Dict[:obj:`str`, :obj:`str`]]): The relevant data to restore dict[:obj:`str`, :obj:`str`]]): The relevant data to restore
:class:`telegram.ext.CallbackDataCache`. :class:`telegram.ext.CallbackDataCache`.
""" """
if self._callback_data == data: if self._callback_data == data:
@ -391,21 +391,21 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
self._user_data.pop(user_id, None) self._user_data.pop(user_id, None)
self._user_data_json = None self._user_data_json = None
async def refresh_user_data(self, user_id: int, user_data: Dict[Any, Any]) -> None: async def refresh_user_data(self, user_id: int, user_data: dict[Any, Any]) -> None:
"""Does nothing. """Does nothing.
.. versionadded:: 13.6 .. versionadded:: 13.6
.. seealso:: :meth:`telegram.ext.BasePersistence.refresh_user_data` .. seealso:: :meth:`telegram.ext.BasePersistence.refresh_user_data`
""" """
async def refresh_chat_data(self, chat_id: int, chat_data: Dict[Any, Any]) -> None: async def refresh_chat_data(self, chat_id: int, chat_data: dict[Any, Any]) -> None:
"""Does nothing. """Does nothing.
.. versionadded:: 13.6 .. versionadded:: 13.6
.. seealso:: :meth:`telegram.ext.BasePersistence.refresh_chat_data` .. seealso:: :meth:`telegram.ext.BasePersistence.refresh_chat_data`
""" """
async def refresh_bot_data(self, bot_data: Dict[Any, Any]) -> None: async def refresh_bot_data(self, bot_data: dict[Any, Any]) -> None:
"""Does nothing. """Does nothing.
.. versionadded:: 13.6 .. versionadded:: 13.6
@ -420,7 +420,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
""" """
@staticmethod @staticmethod
def _encode_conversations_to_json(conversations: Dict[str, ConversationDict]) -> str: def _encode_conversations_to_json(conversations: dict[str, ConversationDict]) -> str:
"""Helper method to encode a conversations dict (that uses tuples as keys) to a """Helper method to encode a conversations dict (that uses tuples as keys) to a
JSON-serializable way. Use :meth:`self._decode_conversations_from_json` to decode. JSON-serializable way. Use :meth:`self._decode_conversations_from_json` to decode.
@ -430,7 +430,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
Returns: Returns:
:obj:`str`: The JSON-serialized conversations dict :obj:`str`: The JSON-serialized conversations dict
""" """
tmp: Dict[str, JSONDict] = {} tmp: dict[str, JSONDict] = {}
for handler, states in conversations.items(): for handler, states in conversations.items():
tmp[handler] = {} tmp[handler] = {}
for key, state in states.items(): for key, state in states.items():
@ -438,7 +438,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
return json.dumps(tmp) return json.dumps(tmp)
@staticmethod @staticmethod
def _decode_conversations_from_json(json_string: str) -> Dict[str, ConversationDict]: def _decode_conversations_from_json(json_string: str) -> dict[str, ConversationDict]:
"""Helper method to decode a conversations dict (that uses tuples as keys) from a """Helper method to decode a conversations dict (that uses tuples as keys) from a
JSON-string created with :meth:`self._encode_conversations_to_json`. JSON-string created with :meth:`self._encode_conversations_to_json`.
@ -449,7 +449,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
:obj:`dict`: The conversations dict after decoding :obj:`dict`: The conversations dict after decoding
""" """
tmp = json.loads(json_string) tmp = json.loads(json_string)
conversations: Dict[str, ConversationDict] = {} conversations: dict[str, ConversationDict] = {}
for handler, states in tmp.items(): for handler, states in tmp.items():
conversations[handler] = {} conversations[handler] = {}
for key, state in states.items(): for key, state in states.items():
@ -457,7 +457,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
return conversations return conversations
@staticmethod @staticmethod
def _decode_user_chat_data_from_json(data: str) -> Dict[int, Dict[object, object]]: def _decode_user_chat_data_from_json(data: str) -> dict[int, dict[object, object]]:
"""Helper method to decode chat or user data (that uses ints as keys) from a """Helper method to decode chat or user data (that uses ints as keys) from a
JSON-string. JSON-string.
@ -467,7 +467,7 @@ class DictPersistence(BasePersistence[Dict[Any, Any], Dict[Any, Any], Dict[Any,
Returns: Returns:
:obj:`dict`: The user/chat_data defaultdict after decoding :obj:`dict`: The user/chat_data defaultdict after decoding
""" """
tmp: Dict[int, Dict[object, object]] = {} tmp: dict[int, dict[object, object]] = {}
decoded_data = json.loads(data) decoded_data = json.loads(data)
for user, user_data in decoded_data.items(): for user, user_data in decoded_data.items():
int_user_id = int(user) int_user_id = int(user)

View file

@ -18,19 +18,15 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Bot with convenience extensions.""" """This module contains an object that represents a Telegram Bot with convenience extensions."""
from collections.abc import Sequence
from copy import copy from copy import copy
from datetime import datetime from datetime import datetime
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
Callable, Callable,
Dict,
Generic, Generic,
List,
Optional, Optional,
Sequence,
Tuple,
Type,
TypeVar, TypeVar,
Union, Union,
cast, cast,
@ -267,7 +263,7 @@ class ExtBot(Bot, Generic[RLARGS]):
def _warn( def _warn(
cls, cls,
message: Union[str, PTBUserWarning], message: Union[str, PTBUserWarning],
category: Type[Warning] = PTBUserWarning, category: type[Warning] = PTBUserWarning,
stacklevel: int = 0, stacklevel: int = 0,
) -> None: ) -> None:
"""We override this method to add one more level to the stacklevel, so that the warning """We override this method to add one more level to the stacklevel, so that the warning
@ -340,7 +336,7 @@ class ExtBot(Bot, Generic[RLARGS]):
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
) -> Union[bool, JSONDict, List[JSONDict]]: ) -> Union[bool, JSONDict, list[JSONDict]]:
"""Order of method calls is: Bot.some_method -> Bot._post -> Bot._do_post. """Order of method calls is: Bot.some_method -> Bot._post -> Bot._do_post.
So we can override Bot._do_post to add rate limiting. So we can override Bot._do_post to add rate limiting.
""" """
@ -421,7 +417,7 @@ class ExtBot(Bot, Generic[RLARGS]):
} }
) )
def _insert_defaults(self, data: Dict[str, object]) -> None: def _insert_defaults(self, data: dict[str, object]) -> None:
"""Inserts the defaults values for optional kwargs for which tg.ext.Defaults provides """Inserts the defaults values for optional kwargs for which tg.ext.Defaults provides
convenience functionality, i.e. the kwargs with a tg.utils.helpers.DefaultValue default convenience functionality, i.e. the kwargs with a tg.utils.helpers.DefaultValue default
@ -645,7 +641,7 @@ class ExtBot(Bot, Generic[RLARGS]):
connect_timeout: ODVInput[float] = DEFAULT_NONE, connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
) -> Tuple[Update, ...]: ) -> tuple[Update, ...]:
updates = await super().get_updates( updates = await super().get_updates(
offset=offset, offset=offset,
limit=limit, limit=limit,
@ -670,7 +666,7 @@ class ExtBot(Bot, Generic[RLARGS]):
], ],
next_offset: Optional[str] = None, next_offset: Optional[str] = None,
current_offset: Optional[str] = None, current_offset: Optional[str] = None,
) -> Tuple[Sequence["InlineQueryResult"], Optional[str]]: ) -> tuple[Sequence["InlineQueryResult"], Optional[str]]:
"""This method is called by Bot.answer_inline_query to build the actual results list. """This method is called by Bot.answer_inline_query to build the actual results list.
Overriding this to call self._replace_keyboard suffices Overriding this to call self._replace_keyboard suffices
""" """
@ -746,7 +742,7 @@ class ExtBot(Bot, Generic[RLARGS]):
self, self,
endpoint: str, endpoint: str,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
return_type: Optional[Type[TelegramObject]] = None, return_type: Optional[type[TelegramObject]] = None,
*, *,
read_timeout: ODVInput[float] = DEFAULT_NONE, read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE,
@ -854,7 +850,7 @@ class ExtBot(Bot, Generic[RLARGS]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None, rate_limit_args: Optional[RLARGS] = None,
) -> Tuple["MessageId", ...]: ) -> tuple["MessageId", ...]:
# We override this method to call self._replace_keyboard # We override this method to call self._replace_keyboard
return await super().copy_messages( return await super().copy_messages(
chat_id=chat_id, chat_id=chat_id,
@ -1744,7 +1740,7 @@ class ExtBot(Bot, Generic[RLARGS]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None, rate_limit_args: Optional[RLARGS] = None,
) -> Tuple[MessageId, ...]: ) -> tuple[MessageId, ...]:
return await super().forward_messages( return await super().forward_messages(
chat_id=chat_id, chat_id=chat_id,
from_chat_id=from_chat_id, from_chat_id=from_chat_id,
@ -1769,7 +1765,7 @@ class ExtBot(Bot, Generic[RLARGS]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None, rate_limit_args: Optional[RLARGS] = None,
) -> Tuple[ChatMember, ...]: ) -> tuple[ChatMember, ...]:
return await super().get_chat_administrators( return await super().get_chat_administrators(
chat_id=chat_id, chat_id=chat_id,
read_timeout=read_timeout, read_timeout=read_timeout,
@ -1872,7 +1868,7 @@ class ExtBot(Bot, Generic[RLARGS]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None, rate_limit_args: Optional[RLARGS] = None,
) -> Tuple[Sticker, ...]: ) -> tuple[Sticker, ...]:
return await super().get_forum_topic_icon_stickers( return await super().get_forum_topic_icon_stickers(
read_timeout=read_timeout, read_timeout=read_timeout,
write_timeout=write_timeout, write_timeout=write_timeout,
@ -1894,7 +1890,7 @@ class ExtBot(Bot, Generic[RLARGS]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None, rate_limit_args: Optional[RLARGS] = None,
) -> Tuple[GameHighScore, ...]: ) -> tuple[GameHighScore, ...]:
return await super().get_game_high_scores( return await super().get_game_high_scores(
user_id=user_id, user_id=user_id,
chat_id=chat_id, chat_id=chat_id,
@ -1936,7 +1932,7 @@ class ExtBot(Bot, Generic[RLARGS]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None, rate_limit_args: Optional[RLARGS] = None,
) -> Tuple[BotCommand, ...]: ) -> tuple[BotCommand, ...]:
return await super().get_my_commands( return await super().get_my_commands(
scope=scope, scope=scope,
language_code=language_code, language_code=language_code,
@ -1997,7 +1993,7 @@ class ExtBot(Bot, Generic[RLARGS]):
pool_timeout: ODVInput[float] = DEFAULT_NONE, pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None, api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None, rate_limit_args: Optional[RLARGS] = None,
) -> Tuple[Sticker, ...]: ) -> tuple[Sticker, ...]:
return await super().get_custom_emoji_stickers( return await super().get_custom_emoji_stickers(
custom_emoji_ids=custom_emoji_ids, custom_emoji_ids=custom_emoji_ids,
read_timeout=read_timeout, read_timeout=read_timeout,
@ -2859,7 +2855,7 @@ class ExtBot(Bot, Generic[RLARGS]):
caption: Optional[str] = None, caption: Optional[str] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE, parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Optional[Sequence["MessageEntity"]] = None, caption_entities: Optional[Sequence["MessageEntity"]] = None,
) -> Tuple[Message, ...]: ) -> tuple[Message, ...]:
return await super().send_media_group( return await super().send_media_group(
chat_id=chat_id, chat_id=chat_id,
media=media, media=media,
@ -3497,7 +3493,7 @@ class ExtBot(Bot, Generic[RLARGS]):
async def set_my_commands( async def set_my_commands(
self, self,
commands: Sequence[Union[BotCommand, Tuple[str, str]]], commands: Sequence[Union[BotCommand, tuple[str, str]]],
scope: Optional[BotCommandScope] = None, scope: Optional[BotCommandScope] = None,
language_code: Optional[str] = None, language_code: Optional[str] = None,
*, *,

View file

@ -19,7 +19,8 @@
"""This module contains the CallbackQueryHandler class.""" """This module contains the CallbackQueryHandler class."""
import asyncio import asyncio
import re import re
from typing import TYPE_CHECKING, Any, Callable, Match, Optional, Pattern, TypeVar, Union, cast from re import Match, Pattern
from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union, cast
from telegram import Update from telegram import Update
from telegram._utils.defaultvalue import DEFAULT_TRUE from telegram._utils.defaultvalue import DEFAULT_TRUE

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the ChosenInlineResultHandler class.""" """This module contains the ChosenInlineResultHandler class."""
import re import re
from typing import TYPE_CHECKING, Any, Match, Optional, Pattern, TypeVar, Union, cast from re import Match, Pattern
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union, cast
from telegram import Update from telegram import Update
from telegram._utils.defaultvalue import DEFAULT_TRUE from telegram._utils.defaultvalue import DEFAULT_TRUE

View file

@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the CommandHandler class.""" """This module contains the CommandHandler class."""
import re import re
from typing import TYPE_CHECKING, Any, FrozenSet, List, Optional, Tuple, TypeVar, Union from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
from telegram import MessageEntity, Update from telegram import MessageEntity, Update
from telegram._utils.defaultvalue import DEFAULT_TRUE from telegram._utils.defaultvalue import DEFAULT_TRUE
@ -101,7 +101,7 @@ class CommandHandler(BaseHandler[Update, CCT, RT]):
:exc:`ValueError`: When the command is too long or has illegal chars. :exc:`ValueError`: When the command is too long or has illegal chars.
Attributes: Attributes:
commands (FrozenSet[:obj:`str`]): The set of commands this handler should listen for. commands (frozenset[:obj:`str`]): The set of commands this handler should listen for.
callback (:term:`coroutine function`): The callback function for this handler. callback (:term:`coroutine function`): The callback function for this handler.
filters (:class:`telegram.ext.filters.BaseFilter`): Optional. Only allow updates with these filters (:class:`telegram.ext.filters.BaseFilter`): Optional. Only allow updates with these
filters. filters.
@ -134,7 +134,7 @@ class CommandHandler(BaseHandler[Update, CCT, RT]):
for comm in commands: for comm in commands:
if not re.match(r"^[\da-z_]{1,32}$", comm): if not re.match(r"^[\da-z_]{1,32}$", comm):
raise ValueError(f"Command `{comm}` is not a valid bot command") raise ValueError(f"Command `{comm}` is not a valid bot command")
self.commands: FrozenSet[str] = commands self.commands: frozenset[str] = commands
self.filters: filters_module.BaseFilter = ( self.filters: filters_module.BaseFilter = (
filters if filters is not None else filters_module.UpdateType.MESSAGES filters if filters is not None else filters_module.UpdateType.MESSAGES
@ -145,7 +145,7 @@ class CommandHandler(BaseHandler[Update, CCT, RT]):
if (isinstance(self.has_args, int)) and (self.has_args < 0): if (isinstance(self.has_args, int)) and (self.has_args < 0):
raise ValueError("CommandHandler argument has_args cannot be a negative integer") raise ValueError("CommandHandler argument has_args cannot be a negative integer")
def _check_correct_args(self, args: List[str]) -> Optional[bool]: def _check_correct_args(self, args: list[str]) -> Optional[bool]:
"""Determines whether the args are correct for this handler. Implemented in check_update(). """Determines whether the args are correct for this handler. Implemented in check_update().
Args: Args:
args (:obj:`list`): The args for the handler. args (:obj:`list`): The args for the handler.
@ -161,7 +161,7 @@ class CommandHandler(BaseHandler[Update, CCT, RT]):
def check_update( def check_update(
self, update: object self, update: object
) -> Optional[Union[bool, Tuple[List[str], Optional[Union[bool, FilterDataDict]]]]]: ) -> Optional[Union[bool, tuple[list[str], Optional[Union[bool, FilterDataDict]]]]]:
"""Determines whether an update should be passed to this handler's :attr:`callback`. """Determines whether an update should be passed to this handler's :attr:`callback`.
Args: Args:
@ -206,7 +206,7 @@ class CommandHandler(BaseHandler[Update, CCT, RT]):
context: CCT, context: CCT,
update: Update, # noqa: ARG002 update: Update, # noqa: ARG002
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002 application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]], check_result: Optional[Union[bool, tuple[list[str], Optional[bool]]]],
) -> None: ) -> None:
"""Add text after the command to :attr:`CallbackContext.args` as list, split on single """Add text after the command to :attr:`CallbackContext.args` as list, split on single
whitespaces and add output of data filters to :attr:`CallbackContext` as well. whitespaces and add output of data filters to :attr:`CallbackContext` as well.

View file

@ -20,20 +20,7 @@
import asyncio import asyncio
import datetime import datetime
from dataclasses import dataclass from dataclasses import dataclass
from typing import ( from typing import TYPE_CHECKING, Any, Final, Generic, NoReturn, Optional, Union, cast
TYPE_CHECKING,
Any,
Dict,
Final,
Generic,
List,
NoReturn,
Optional,
Set,
Tuple,
Union,
cast,
)
from telegram import Update from telegram import Update
from telegram._utils.defaultvalue import DEFAULT_TRUE, DefaultValue from telegram._utils.defaultvalue import DEFAULT_TRUE, DefaultValue
@ -55,7 +42,7 @@ from telegram.ext._utils.types import CCT, ConversationDict, ConversationKey
if TYPE_CHECKING: if TYPE_CHECKING:
from telegram.ext import Application, Job, JobQueue from telegram.ext import Application, Job, JobQueue
_CheckUpdateType = Tuple[object, ConversationKey, BaseHandler[Update, CCT, object], object] _CheckUpdateType = tuple[object, ConversationKey, BaseHandler[Update, CCT, object], object]
_LOGGER = get_logger(__name__, class_name="ConversationHandler") _LOGGER = get_logger(__name__, class_name="ConversationHandler")
@ -192,16 +179,16 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
* :any:`Persistent Conversation Bot <examples.persistentconversationbot>` * :any:`Persistent Conversation Bot <examples.persistentconversationbot>`
Args: Args:
entry_points (List[:class:`telegram.ext.BaseHandler`]): A list of :obj:`BaseHandler` entry_points (list[:class:`telegram.ext.BaseHandler`]): A list of :obj:`BaseHandler`
objects that objects that
can trigger the start of the conversation. The first handler whose :meth:`check_update` can trigger the start of the conversation. The first handler whose :meth:`check_update`
method returns :obj:`True` will be used. If all return :obj:`False`, the update is not method returns :obj:`True` will be used. If all return :obj:`False`, the update is not
handled. handled.
states (Dict[:obj:`object`, List[:class:`telegram.ext.BaseHandler`]]): A :obj:`dict` that states (dict[:obj:`object`, list[:class:`telegram.ext.BaseHandler`]]): A :obj:`dict` that
defines the different states of conversation a user can be in and one or more defines the different states of conversation a user can be in and one or more
associated :obj:`BaseHandler` objects that should be used in that state. The first associated :obj:`BaseHandler` objects that should be used in that state. The first
handler whose :meth:`check_update` method returns :obj:`True` will be used. handler whose :meth:`check_update` method returns :obj:`True` will be used.
fallbacks (List[:class:`telegram.ext.BaseHandler`]): A list of handlers that might be used fallbacks (list[:class:`telegram.ext.BaseHandler`]): A list of handlers that might be used
if the user is in a conversation, but every handler for their current state returned if the user is in a conversation, but every handler for their current state returned
:obj:`False` on :meth:`check_update`. The first handler which :meth:`check_update` :obj:`False` on :meth:`check_update`. The first handler which :meth:`check_update`
method returns :obj:`True` will be used. If all return :obj:`False`, the update is not method returns :obj:`True` will be used. If all return :obj:`False`, the update is not
@ -238,7 +225,7 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
.. versionchanged:: 20.0 .. versionchanged:: 20.0
Was previously named as ``persistence``. Was previously named as ``persistence``.
map_to_parent (Dict[:obj:`object`, :obj:`object`], optional): A :obj:`dict` that can be map_to_parent (dict[:obj:`object`, :obj:`object`], optional): A :obj:`dict` that can be
used to instruct a child conversation handler to transition into a mapped state on used to instruct a child conversation handler to transition into a mapped state on
its parent conversation handler in place of a specified nested state. its parent conversation handler in place of a specified nested state.
block (:obj:`bool`, optional): Pass :obj:`False` or :obj:`True` to set a default value for block (:obj:`bool`, optional): Pass :obj:`False` or :obj:`True` to set a default value for
@ -297,9 +284,9 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
# pylint: disable=super-init-not-called # pylint: disable=super-init-not-called
def __init__( def __init__(
self: "ConversationHandler[CCT]", self: "ConversationHandler[CCT]",
entry_points: List[BaseHandler[Update, CCT, object]], entry_points: list[BaseHandler[Update, CCT, object]],
states: Dict[object, List[BaseHandler[Update, CCT, object]]], states: dict[object, list[BaseHandler[Update, CCT, object]]],
fallbacks: List[BaseHandler[Update, CCT, object]], fallbacks: list[BaseHandler[Update, CCT, object]],
allow_reentry: bool = False, allow_reentry: bool = False,
per_chat: bool = True, per_chat: bool = True,
per_user: bool = True, per_user: bool = True,
@ -307,7 +294,7 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
conversation_timeout: Optional[Union[float, datetime.timedelta]] = None, conversation_timeout: Optional[Union[float, datetime.timedelta]] = None,
name: Optional[str] = None, name: Optional[str] = None,
persistent: bool = False, persistent: bool = False,
map_to_parent: Optional[Dict[object, object]] = None, map_to_parent: Optional[dict[object, object]] = None,
block: DVType[bool] = DEFAULT_TRUE, block: DVType[bool] = DEFAULT_TRUE,
): ):
# these imports need to be here because of circular import error otherwise # these imports need to be here because of circular import error otherwise
@ -324,9 +311,9 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
# Store the actual setting in a protected variable instead # Store the actual setting in a protected variable instead
self._block: DVType[bool] = block self._block: DVType[bool] = block
self._entry_points: List[BaseHandler[Update, CCT, object]] = entry_points self._entry_points: list[BaseHandler[Update, CCT, object]] = entry_points
self._states: Dict[object, List[BaseHandler[Update, CCT, object]]] = states self._states: dict[object, list[BaseHandler[Update, CCT, object]]] = states
self._fallbacks: List[BaseHandler[Update, CCT, object]] = fallbacks self._fallbacks: list[BaseHandler[Update, CCT, object]] = fallbacks
self._allow_reentry: bool = allow_reentry self._allow_reentry: bool = allow_reentry
self._per_user: bool = per_user self._per_user: bool = per_user
@ -336,14 +323,14 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
conversation_timeout conversation_timeout
) )
self._name: Optional[str] = name self._name: Optional[str] = name
self._map_to_parent: Optional[Dict[object, object]] = map_to_parent self._map_to_parent: Optional[dict[object, object]] = map_to_parent
# if conversation_timeout is used, this dict is used to schedule a job which runs when the # if conversation_timeout is used, this dict is used to schedule a job which runs when the
# conv has timed out. # conv has timed out.
self.timeout_jobs: Dict[ConversationKey, Job[Any]] = {} self.timeout_jobs: dict[ConversationKey, Job[Any]] = {}
self._timeout_jobs_lock = asyncio.Lock() self._timeout_jobs_lock = asyncio.Lock()
self._conversations: ConversationDict = {} self._conversations: ConversationDict = {}
self._child_conversations: Set[ConversationHandler] = set() self._child_conversations: set[ConversationHandler] = set()
if persistent and not self.name: if persistent and not self.name:
raise ValueError("Conversations can't be persistent when handler is unnamed.") raise ValueError("Conversations can't be persistent when handler is unnamed.")
@ -359,7 +346,7 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
stacklevel=2, stacklevel=2,
) )
all_handlers: List[BaseHandler[Update, CCT, object]] = [] all_handlers: list[BaseHandler[Update, CCT, object]] = []
all_handlers.extend(entry_points) all_handlers.extend(entry_points)
all_handlers.extend(fallbacks) all_handlers.extend(fallbacks)
@ -466,8 +453,8 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
) )
@property @property
def entry_points(self) -> List[BaseHandler[Update, CCT, object]]: def entry_points(self) -> list[BaseHandler[Update, CCT, object]]:
"""List[:class:`telegram.ext.BaseHandler`]: A list of :obj:`BaseHandler` objects that can """list[:class:`telegram.ext.BaseHandler`]: A list of :obj:`BaseHandler` objects that can
trigger the start of the conversation. trigger the start of the conversation.
""" """
return self._entry_points return self._entry_points
@ -479,8 +466,8 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
) )
@property @property
def states(self) -> Dict[object, List[BaseHandler[Update, CCT, object]]]: def states(self) -> dict[object, list[BaseHandler[Update, CCT, object]]]:
"""Dict[:obj:`object`, List[:class:`telegram.ext.BaseHandler`]]: A :obj:`dict` that """dict[:obj:`object`, list[:class:`telegram.ext.BaseHandler`]]: A :obj:`dict` that
defines the different states of conversation a user can be in and one or more defines the different states of conversation a user can be in and one or more
associated :obj:`BaseHandler` objects that should be used in that state. associated :obj:`BaseHandler` objects that should be used in that state.
""" """
@ -491,8 +478,8 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
raise AttributeError("You can not assign a new value to states after initialization.") raise AttributeError("You can not assign a new value to states after initialization.")
@property @property
def fallbacks(self) -> List[BaseHandler[Update, CCT, object]]: def fallbacks(self) -> list[BaseHandler[Update, CCT, object]]:
"""List[:class:`telegram.ext.BaseHandler`]: A list of handlers that might be used if """list[:class:`telegram.ext.BaseHandler`]: A list of handlers that might be used if
the user is in a conversation, but every handler for their current state returned the user is in a conversation, but every handler for their current state returned
:obj:`False` on :meth:`check_update`. :obj:`False` on :meth:`check_update`.
""" """
@ -578,8 +565,8 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
raise AttributeError("You can not assign a new value to persistent after initialization.") raise AttributeError("You can not assign a new value to persistent after initialization.")
@property @property
def map_to_parent(self) -> Optional[Dict[object, object]]: def map_to_parent(self) -> Optional[dict[object, object]]:
"""Dict[:obj:`object`, :obj:`object`]: Optional. A :obj:`dict` that can be """dict[:obj:`object`, :obj:`object`]: Optional. A :obj:`dict` that can be
used to instruct a nested :class:`ConversationHandler` to transition into a mapped state on used to instruct a nested :class:`ConversationHandler` to transition into a mapped state on
its parent :class:`ConversationHandler` in place of a specified nested state. its parent :class:`ConversationHandler` in place of a specified nested state.
""" """
@ -593,7 +580,7 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
async def _initialize_persistence( async def _initialize_persistence(
self, application: "Application" self, application: "Application"
) -> Dict[str, TrackingDict[ConversationKey, object]]: ) -> dict[str, TrackingDict[ConversationKey, object]]:
"""Initializes the persistence for this handler and its child conversations. """Initializes the persistence for this handler and its child conversations.
While this method is marked as protected, we expect it to be called by the While this method is marked as protected, we expect it to be called by the
Application/parent conversations. It's just protected to hide it from users. Application/parent conversations. It's just protected to hide it from users.
@ -648,7 +635,7 @@ class ConversationHandler(BaseHandler[Update, CCT, object]):
chat = update.effective_chat chat = update.effective_chat
user = update.effective_user user = update.effective_user
key: List[Union[int, str]] = [] key: list[Union[int, str]] = []
if self.per_chat: if self.per_chat:
if chat is None: if chat is None:

View file

@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the InlineQueryHandler class.""" """This module contains the InlineQueryHandler class."""
import re import re
from typing import TYPE_CHECKING, Any, List, Match, Optional, Pattern, TypeVar, Union, cast from re import Match, Pattern
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union, cast
from telegram import Update from telegram import Update
from telegram._utils.defaultvalue import DEFAULT_TRUE from telegram._utils.defaultvalue import DEFAULT_TRUE
@ -67,7 +68,7 @@ class InlineQueryHandler(BaseHandler[Update, CCT, RT]):
:meth:`telegram.ext.Application.process_update`. Defaults to :obj:`True`. :meth:`telegram.ext.Application.process_update`. Defaults to :obj:`True`.
.. seealso:: :wiki:`Concurrency` .. seealso:: :wiki:`Concurrency`
chat_types (List[:obj:`str`], optional): List of allowed chat types. If passed, will only chat_types (list[:obj:`str`], optional): List of allowed chat types. If passed, will only
handle inline queries with the appropriate :attr:`telegram.InlineQuery.chat_type`. handle inline queries with the appropriate :attr:`telegram.InlineQuery.chat_type`.
.. versionadded:: 13.5 .. versionadded:: 13.5
@ -75,7 +76,7 @@ class InlineQueryHandler(BaseHandler[Update, CCT, RT]):
callback (:term:`coroutine function`): The callback function for this handler. callback (:term:`coroutine function`): The callback function for this handler.
pattern (:obj:`str` | :func:`re.Pattern <re.compile>`): Optional. Regex pattern to test pattern (:obj:`str` | :func:`re.Pattern <re.compile>`): Optional. Regex pattern to test
:attr:`telegram.InlineQuery.query` against. :attr:`telegram.InlineQuery.query` against.
chat_types (List[:obj:`str`]): Optional. List of allowed chat types. chat_types (list[:obj:`str`]): Optional. List of allowed chat types.
.. versionadded:: 13.5 .. versionadded:: 13.5
block (:obj:`bool`): Determines whether the return value of the callback should be block (:obj:`bool`): Determines whether the return value of the callback should be
@ -91,7 +92,7 @@ class InlineQueryHandler(BaseHandler[Update, CCT, RT]):
callback: HandlerCallback[Update, CCT, RT], callback: HandlerCallback[Update, CCT, RT],
pattern: Optional[Union[str, Pattern[str]]] = None, pattern: Optional[Union[str, Pattern[str]]] = None,
block: DVType[bool] = DEFAULT_TRUE, block: DVType[bool] = DEFAULT_TRUE,
chat_types: Optional[List[str]] = None, chat_types: Optional[list[str]] = None,
): ):
super().__init__(callback, block=block) super().__init__(callback, block=block)
@ -99,7 +100,7 @@ class InlineQueryHandler(BaseHandler[Update, CCT, RT]):
pattern = re.compile(pattern) pattern = re.compile(pattern)
self.pattern: Optional[Union[str, Pattern[str]]] = pattern self.pattern: Optional[Union[str, Pattern[str]]] = pattern
self.chat_types: Optional[List[str]] = chat_types self.chat_types: Optional[list[str]] = chat_types
def check_update(self, update: object) -> Optional[Union[bool, Match[str]]]: def check_update(self, update: object) -> Optional[Union[bool, Match[str]]]:
""" """

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