diff --git a/.github/workflows/type_completeness_monthly.yml b/.github/workflows/type_completeness_monthly.yml new file mode 100644 index 000000000..a5492f903 --- /dev/null +++ b/.github/workflows/type_completeness_monthly.yml @@ -0,0 +1,33 @@ +name: Check Type Completeness Monthly Run +on: + schedule: + # Run first friday of the month at 03:17 - odd time to spread load on GitHub Actions + - cron: '17 3 1-7 * 5' + +jobs: + test-type-completeness: + name: test-type-completeness + runs-on: ubuntu-latest + steps: + - uses: Bibo-Joshi/pyright-type-completeness@1.0.0 + id: pyright-type-completeness + with: + package-name: telegram + python-version: 3.12 + pyright-version: ~=1.1.367 + - name: Check Output + uses: jannekem/run-python-script-action@v1 + env: + TYPE_COMPLETENESS: ${{ steps.pyright-type-completeness.outputs.base-completeness-score }} + with: + script: | + import os + completeness = float(os.getenv("TYPE_COMPLETENESS")) + + if completeness >= 1: + exit(0) + + text = f"Type Completeness Decreased to {completeness}. ❌" + error(text) + set_summary(text) + exit(1) diff --git a/examples/nestedconversationbot.py b/examples/nestedconversationbot.py index 918f0becf..fdc49de2b 100644 --- a/examples/nestedconversationbot.py +++ b/examples/nestedconversationbot.py @@ -371,8 +371,8 @@ def main() -> None: entry_points=[CommandHandler("start", start)], states={ SHOWING: [CallbackQueryHandler(start, pattern="^" + str(END) + "$")], - SELECTING_ACTION: selection_handlers, - SELECTING_LEVEL: selection_handlers, + SELECTING_ACTION: selection_handlers, # type: ignore[dict-item] + SELECTING_LEVEL: selection_handlers, # type: ignore[dict-item] DESCRIBING_SELF: [description_conv], STOPPING: [CommandHandler("start", start)], }, diff --git a/telegram/ext/_application.py b/telegram/ext/_application.py index a1013ce57..86e38b1de 100644 --- a/telegram/ext/_application.py +++ b/telegram/ext/_application.py @@ -323,7 +323,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica self.update_queue: asyncio.Queue[object] = update_queue self.context_types: ContextTypes[CCT, UD, CD, BD] = context_types self.updater: Optional[Updater] = updater - self.handlers: Dict[int, List[BaseHandler[Any, CCT]]] = {} + self.handlers: Dict[int, List[BaseHandler[Any, CCT, Any]]] = {} self.error_handlers: Dict[ HandlerCallback[object, CCT, None], Union[bool, DefaultValue[bool]] ] = {} @@ -1352,7 +1352,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica # (in __create_task_callback) self._mark_for_persistence_update(update=update) - def add_handler(self, handler: BaseHandler[Any, CCT], group: int = DEFAULT_GROUP) -> None: + def add_handler(self, handler: BaseHandler[Any, CCT, Any], group: int = DEFAULT_GROUP) -> None: """Register a handler. TL;DR: Order and priority counts. 0 or 1 handlers per group will be used. End handling of @@ -1420,8 +1420,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica def add_handlers( self, handlers: Union[ - Union[List[BaseHandler[Any, CCT]], Tuple[BaseHandler[Any, CCT]]], - Dict[int, Union[List[BaseHandler[Any, CCT]], Tuple[BaseHandler[Any, CCT]]]], + Union[List[BaseHandler[Any, CCT, Any]], Tuple[BaseHandler[Any, CCT, Any]]], + Dict[int, Union[List[BaseHandler[Any, CCT, Any]], Tuple[BaseHandler[Any, CCT, Any]]]], ], group: Union[int, DefaultValue[int]] = _DEFAULT_0, ) -> None: @@ -1469,7 +1469,9 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica "dictionary where the keys are groups and values are sequences of handlers." ) - def remove_handler(self, handler: BaseHandler[Any, CCT], group: int = DEFAULT_GROUP) -> None: + def remove_handler( + self, handler: BaseHandler[Any, CCT, Any], group: int = DEFAULT_GROUP + ) -> None: """Remove a handler from the specified group. Args: diff --git a/telegram/ext/_callbackcontext.py b/telegram/ext/_callbackcontext.py index ea708e0e6..dfd2c3cc8 100644 --- a/telegram/ext/_callbackcontext.py +++ b/telegram/ext/_callbackcontext.py @@ -29,6 +29,7 @@ from typing import ( NoReturn, Optional, Type, + TypeVar, Union, ) @@ -49,6 +50,9 @@ _STORING_DATA_WIKI = ( "/wiki/Storing-bot%2C-user-and-chat-related-data" ) +# something like poor mans "typing.Self" for py<3.11 +ST = TypeVar("ST", bound="CallbackContext[Any, Any, Any, Any]") + class CallbackContext(Generic[BT, UD, CD, BD]): """ @@ -133,24 +137,24 @@ class CallbackContext(Generic[BT, UD, CD, BD]): ) def __init__( - self: "CCT", - application: "Application[BT, CCT, UD, CD, BD, Any]", + self: ST, + application: "Application[BT, ST, UD, CD, BD, Any]", chat_id: Optional[int] = None, user_id: Optional[int] = None, ): - self._application: Application[BT, CCT, UD, CD, BD, Any] = application + self._application: Application[BT, ST, UD, CD, BD, Any] = application self._chat_id: Optional[int] = chat_id self._user_id: Optional[int] = user_id self.args: Optional[List[str]] = None self.matches: Optional[List[Match[str]]] = None self.error: Optional[Exception] = None - self.job: Optional[Job[CCT]] = None + self.job: Optional[Job[Any]] = None self.coroutine: Optional[ Union[Generator[Optional[Future[object]], None, Any], Awaitable[Any]] ] = None @property - def application(self) -> "Application[BT, CCT, UD, CD, BD, Any]": + def application(self) -> "Application[BT, ST, UD, CD, BD, Any]": """:class:`telegram.ext.Application`: The application associated with this context.""" return self._application @@ -398,7 +402,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]): return self._application.bot @property - def job_queue(self) -> Optional["JobQueue[CCT]"]: + def job_queue(self) -> Optional["JobQueue[ST]"]: """ :class:`telegram.ext.JobQueue`: The :class:`JobQueue` used by the :class:`telegram.ext.Application`. diff --git a/telegram/ext/_handlers/basehandler.py b/telegram/ext/_handlers/basehandler.py index ea0d9b164..bf6f5f155 100644 --- a/telegram/ext/_handlers/basehandler.py +++ b/telegram/ext/_handlers/basehandler.py @@ -32,14 +32,14 @@ RT = TypeVar("RT") UT = TypeVar("UT") -class BaseHandler(Generic[UT, CCT], ABC): +class BaseHandler(Generic[UT, CCT, RT], ABC): """The base class for all update handlers. Create custom handlers by inheriting from it. Warning: When setting :paramref:`block` to :obj:`False`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. - This class is a :class:`~typing.Generic` class and accepts two type variables: + This class is a :class:`~typing.Generic` class and accepts three type variables: 1. The type of the updates that this handler will handle. Must coincide with the type of the first argument of :paramref:`callback`. :meth:`check_update` must only accept @@ -54,6 +54,7 @@ class BaseHandler(Generic[UT, CCT], ABC): For this type variable, one should usually provide a :class:`~typing.TypeVar` that is also used for the mentioned method arguments. That way, a type checker can check whether this handler fits the definition of the :class:`~Application`. + 3. The return type of the :paramref:`callback` function accepted by this handler. .. seealso:: :wiki:`Types of Handlers ` @@ -89,7 +90,7 @@ class BaseHandler(Generic[UT, CCT], ABC): ) def __init__( - self, + self: "BaseHandler[UT, CCT, RT]", callback: HandlerCallback[UT, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, ): diff --git a/telegram/ext/_handlers/businessconnectionhandler.py b/telegram/ext/_handlers/businessconnectionhandler.py index c8cb3e843..e5d09c77c 100644 --- a/telegram/ext/_handlers/businessconnectionhandler.py +++ b/telegram/ext/_handlers/businessconnectionhandler.py @@ -29,7 +29,7 @@ from telegram.ext._utils.types import CCT, HandlerCallback RT = TypeVar("RT") -class BusinessConnectionHandler(BaseHandler[Update, CCT]): +class BusinessConnectionHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`Business Connections `. @@ -65,7 +65,7 @@ class BusinessConnectionHandler(BaseHandler[Update, CCT]): ) def __init__( - self, + self: "BusinessConnectionHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], user_id: Optional[SCT[int]] = None, username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/businessmessagesdeletedhandler.py b/telegram/ext/_handlers/businessmessagesdeletedhandler.py index 0ceb58fe0..c041bb0ad 100644 --- a/telegram/ext/_handlers/businessmessagesdeletedhandler.py +++ b/telegram/ext/_handlers/businessmessagesdeletedhandler.py @@ -29,7 +29,7 @@ from telegram.ext._utils.types import CCT, HandlerCallback RT = TypeVar("RT") -class BusinessMessagesDeletedHandler(BaseHandler[Update, CCT]): +class BusinessMessagesDeletedHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle :attr:`deleted Telegram Business messages `. @@ -65,7 +65,7 @@ class BusinessMessagesDeletedHandler(BaseHandler[Update, CCT]): ) def __init__( - self, + self: "BusinessMessagesDeletedHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_id: Optional[SCT[int]] = None, username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/callbackqueryhandler.py b/telegram/ext/_handlers/callbackqueryhandler.py index a149739a2..5e0a0a12a 100644 --- a/telegram/ext/_handlers/callbackqueryhandler.py +++ b/telegram/ext/_handlers/callbackqueryhandler.py @@ -33,7 +33,7 @@ if TYPE_CHECKING: RT = TypeVar("RT") -class CallbackQueryHandler(BaseHandler[Update, CCT]): +class CallbackQueryHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`callback queries `. Optionally based on a regex. @@ -125,7 +125,7 @@ class CallbackQueryHandler(BaseHandler[Update, CCT]): __slots__ = ("game_pattern", "pattern") def __init__( - self, + self: "CallbackQueryHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], pattern: Optional[ Union[str, Pattern[str], type, Callable[[object], Optional[bool]]] diff --git a/telegram/ext/_handlers/chatboosthandler.py b/telegram/ext/_handlers/chatboosthandler.py index 9d7219632..7a2dd1be6 100644 --- a/telegram/ext/_handlers/chatboosthandler.py +++ b/telegram/ext/_handlers/chatboosthandler.py @@ -23,10 +23,10 @@ from typing import Final, Optional from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler from telegram.ext._utils._update_parsing import parse_chat_id, parse_username -from telegram.ext._utils.types import CCT, HandlerCallback +from telegram.ext._utils.types import CCT, RT, HandlerCallback -class ChatBoostHandler(BaseHandler[Update, CCT]): +class ChatBoostHandler(BaseHandler[Update, CCT, RT]): """ Handler class to handle Telegram updates that contain a chat boost. @@ -84,8 +84,8 @@ class ChatBoostHandler(BaseHandler[Update, CCT]): and :attr:`telegram.Update.removed_chat_boost`.""" def __init__( - self, - callback: HandlerCallback[Update, CCT, None], + self: "ChatBoostHandler[CCT, RT]", + callback: HandlerCallback[Update, CCT, RT], chat_boost_types: int = CHAT_BOOST, chat_id: Optional[int] = None, chat_username: Optional[str] = None, diff --git a/telegram/ext/_handlers/chatjoinrequesthandler.py b/telegram/ext/_handlers/chatjoinrequesthandler.py index 7007f61ab..04576e63c 100644 --- a/telegram/ext/_handlers/chatjoinrequesthandler.py +++ b/telegram/ext/_handlers/chatjoinrequesthandler.py @@ -28,7 +28,7 @@ from telegram.ext._utils._update_parsing import parse_chat_id, parse_username from telegram.ext._utils.types import CCT, HandlerCallback -class ChatJoinRequestHandler(BaseHandler[Update, CCT]): +class ChatJoinRequestHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain :attr:`telegram.Update.chat_join_request`. @@ -81,7 +81,7 @@ class ChatJoinRequestHandler(BaseHandler[Update, CCT]): ) def __init__( - self, + self: "ChatJoinRequestHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_id: Optional[SCT[int]] = None, username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/chatmemberhandler.py b/telegram/ext/_handlers/chatmemberhandler.py index 592361b64..cf8bb28db 100644 --- a/telegram/ext/_handlers/chatmemberhandler.py +++ b/telegram/ext/_handlers/chatmemberhandler.py @@ -29,7 +29,7 @@ from telegram.ext._utils.types import CCT, HandlerCallback RT = TypeVar("RT") -class ChatMemberHandler(BaseHandler[Update, CCT]): +class ChatMemberHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a chat member update. Warning: @@ -87,7 +87,7 @@ class ChatMemberHandler(BaseHandler[Update, CCT]): and :attr:`telegram.Update.chat_member`.""" def __init__( - self, + self: "ChatMemberHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_member_types: int = MY_CHAT_MEMBER, block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/choseninlineresulthandler.py b/telegram/ext/_handlers/choseninlineresulthandler.py index db7a87214..feac28ba6 100644 --- a/telegram/ext/_handlers/choseninlineresulthandler.py +++ b/telegram/ext/_handlers/choseninlineresulthandler.py @@ -32,7 +32,7 @@ if TYPE_CHECKING: from telegram.ext import Application -class ChosenInlineResultHandler(BaseHandler[Update, CCT]): +class ChosenInlineResultHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain :attr:`telegram.Update.chosen_inline_result`. @@ -76,7 +76,7 @@ class ChosenInlineResultHandler(BaseHandler[Update, CCT]): __slots__ = ("pattern",) def __init__( - self, + self: "ChosenInlineResultHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, pattern: Optional[Union[str, Pattern[str]]] = None, diff --git a/telegram/ext/_handlers/commandhandler.py b/telegram/ext/_handlers/commandhandler.py index edad3963a..54d01acd6 100644 --- a/telegram/ext/_handlers/commandhandler.py +++ b/telegram/ext/_handlers/commandhandler.py @@ -33,7 +33,7 @@ if TYPE_CHECKING: RT = TypeVar("RT") -class CommandHandler(BaseHandler[Update, CCT]): +class CommandHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram commands. Commands are Telegram messages that start with ``/``, optionally followed by an ``@`` and the @@ -118,7 +118,7 @@ class CommandHandler(BaseHandler[Update, CCT]): __slots__ = ("commands", "filters", "has_args") def __init__( - self, + self: "CommandHandler[CCT, RT]", command: SCT[str], callback: HandlerCallback[Update, CCT, RT], filters: Optional[filters_module.BaseFilter] = None, diff --git a/telegram/ext/_handlers/conversationhandler.py b/telegram/ext/_handlers/conversationhandler.py index f3fad9f83..83fa373fc 100644 --- a/telegram/ext/_handlers/conversationhandler.py +++ b/telegram/ext/_handlers/conversationhandler.py @@ -55,7 +55,7 @@ from telegram.ext._utils.types import CCT, ConversationDict, ConversationKey if TYPE_CHECKING: from telegram.ext import Application, Job, JobQueue -_CheckUpdateType = Tuple[object, ConversationKey, BaseHandler[Update, CCT], object] +_CheckUpdateType = Tuple[object, ConversationKey, BaseHandler[Update, CCT, object], object] _LOGGER = get_logger(__name__, class_name="ConversationHandler") @@ -119,7 +119,7 @@ class PendingState: return res -class ConversationHandler(BaseHandler[Update, CCT]): +class ConversationHandler(BaseHandler[Update, CCT, object]): """ A handler to hold a conversation with a single or multiple users through Telegram updates by managing three collections of other handlers. @@ -296,10 +296,10 @@ class ConversationHandler(BaseHandler[Update, CCT]): # pylint: disable=super-init-not-called def __init__( - self, - entry_points: List[BaseHandler[Update, CCT]], - states: Dict[object, List[BaseHandler[Update, CCT]]], - fallbacks: List[BaseHandler[Update, CCT]], + self: "ConversationHandler[CCT]", + entry_points: List[BaseHandler[Update, CCT, object]], + states: Dict[object, List[BaseHandler[Update, CCT, object]]], + fallbacks: List[BaseHandler[Update, CCT, object]], allow_reentry: bool = False, per_chat: bool = True, per_user: bool = True, @@ -324,9 +324,9 @@ class ConversationHandler(BaseHandler[Update, CCT]): # Store the actual setting in a protected variable instead self._block: DVType[bool] = block - self._entry_points: List[BaseHandler[Update, CCT]] = entry_points - self._states: Dict[object, List[BaseHandler[Update, CCT]]] = states - self._fallbacks: List[BaseHandler[Update, CCT]] = fallbacks + self._entry_points: List[BaseHandler[Update, CCT, object]] = entry_points + self._states: Dict[object, List[BaseHandler[Update, CCT, object]]] = states + self._fallbacks: List[BaseHandler[Update, CCT, object]] = fallbacks self._allow_reentry: bool = allow_reentry self._per_user: bool = per_user @@ -359,7 +359,7 @@ class ConversationHandler(BaseHandler[Update, CCT]): stacklevel=2, ) - all_handlers: List[BaseHandler[Update, CCT]] = [] + all_handlers: List[BaseHandler[Update, CCT, object]] = [] all_handlers.extend(entry_points) all_handlers.extend(fallbacks) @@ -466,7 +466,7 @@ class ConversationHandler(BaseHandler[Update, CCT]): ) @property - def entry_points(self) -> List[BaseHandler[Update, CCT]]: + def entry_points(self) -> List[BaseHandler[Update, CCT, object]]: """List[:class:`telegram.ext.BaseHandler`]: A list of :obj:`BaseHandler` objects that can trigger the start of the conversation. """ @@ -479,7 +479,7 @@ class ConversationHandler(BaseHandler[Update, CCT]): ) @property - def states(self) -> Dict[object, List[BaseHandler[Update, CCT]]]: + def states(self) -> Dict[object, List[BaseHandler[Update, CCT, object]]]: """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 associated :obj:`BaseHandler` objects that should be used in that state. @@ -491,7 +491,7 @@ class ConversationHandler(BaseHandler[Update, CCT]): raise AttributeError("You can not assign a new value to states after initialization.") @property - def fallbacks(self) -> List[BaseHandler[Update, CCT]]: + def fallbacks(self) -> List[BaseHandler[Update, CCT, object]]: """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 :obj:`False` on :meth:`check_update`. diff --git a/telegram/ext/_handlers/inlinequeryhandler.py b/telegram/ext/_handlers/inlinequeryhandler.py index 21a5925cb..9d2cbb710 100644 --- a/telegram/ext/_handlers/inlinequeryhandler.py +++ b/telegram/ext/_handlers/inlinequeryhandler.py @@ -32,7 +32,7 @@ if TYPE_CHECKING: RT = TypeVar("RT") -class InlineQueryHandler(BaseHandler[Update, CCT]): +class InlineQueryHandler(BaseHandler[Update, CCT, RT]): """ BaseHandler class to handle Telegram updates that contain a :attr:`telegram.Update.inline_query`. @@ -87,7 +87,7 @@ class InlineQueryHandler(BaseHandler[Update, CCT]): __slots__ = ("chat_types", "pattern") def __init__( - self, + self: "InlineQueryHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], pattern: Optional[Union[str, Pattern[str]]] = None, block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/messagehandler.py b/telegram/ext/_handlers/messagehandler.py index 0cd42884b..43d8c8d81 100644 --- a/telegram/ext/_handlers/messagehandler.py +++ b/telegram/ext/_handlers/messagehandler.py @@ -32,7 +32,7 @@ if TYPE_CHECKING: RT = TypeVar("RT") -class MessageHandler(BaseHandler[Update, CCT]): +class MessageHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram messages. They might contain text, media or status updates. @@ -75,7 +75,7 @@ class MessageHandler(BaseHandler[Update, CCT]): __slots__ = ("filters",) def __init__( - self, + self: "MessageHandler[CCT, RT]", filters: Optional[filters_module.BaseFilter], callback: HandlerCallback[Update, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/messagereactionhandler.py b/telegram/ext/_handlers/messagereactionhandler.py index 4b52a17a8..34a5292be 100644 --- a/telegram/ext/_handlers/messagereactionhandler.py +++ b/telegram/ext/_handlers/messagereactionhandler.py @@ -28,7 +28,7 @@ from telegram.ext._utils._update_parsing import parse_chat_id, parse_username from telegram.ext._utils.types import CCT, HandlerCallback -class MessageReactionHandler(BaseHandler[Update, CCT]): +class MessageReactionHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a message reaction. Note: @@ -110,7 +110,7 @@ class MessageReactionHandler(BaseHandler[Update, CCT]): and :attr:`telegram.Update.message_reaction_count`.""" def __init__( - self, + self: "MessageReactionHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_id: Optional[SCT[int]] = None, chat_username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/pollanswerhandler.py b/telegram/ext/_handlers/pollanswerhandler.py index 91e8df82b..5e0bb34db 100644 --- a/telegram/ext/_handlers/pollanswerhandler.py +++ b/telegram/ext/_handlers/pollanswerhandler.py @@ -21,10 +21,10 @@ from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler -from telegram.ext._utils.types import CCT +from telegram.ext._utils.types import CCT, RT -class PollAnswerHandler(BaseHandler[Update, CCT]): +class PollAnswerHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a :attr:`poll answer `. diff --git a/telegram/ext/_handlers/pollhandler.py b/telegram/ext/_handlers/pollhandler.py index fb183c538..6bb41c323 100644 --- a/telegram/ext/_handlers/pollhandler.py +++ b/telegram/ext/_handlers/pollhandler.py @@ -21,10 +21,10 @@ from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler -from telegram.ext._utils.types import CCT +from telegram.ext._utils.types import CCT, RT -class PollHandler(BaseHandler[Update, CCT]): +class PollHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a :attr:`poll `. diff --git a/telegram/ext/_handlers/precheckoutqueryhandler.py b/telegram/ext/_handlers/precheckoutqueryhandler.py index 3c6f3f186..de035364e 100644 --- a/telegram/ext/_handlers/precheckoutqueryhandler.py +++ b/telegram/ext/_handlers/precheckoutqueryhandler.py @@ -31,7 +31,7 @@ from telegram.ext._utils.types import CCT, HandlerCallback RT = TypeVar("RT") -class PreCheckoutQueryHandler(BaseHandler[Update, CCT]): +class PreCheckoutQueryHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`telegram.Update.pre_checkout_query`. Warning: @@ -73,7 +73,7 @@ class PreCheckoutQueryHandler(BaseHandler[Update, CCT]): __slots__ = ("pattern",) def __init__( - self, + self: "PreCheckoutQueryHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, pattern: Optional[Union[str, Pattern[str]]] = None, diff --git a/telegram/ext/_handlers/prefixhandler.py b/telegram/ext/_handlers/prefixhandler.py index 3b10a0a1c..bda265e10 100644 --- a/telegram/ext/_handlers/prefixhandler.py +++ b/telegram/ext/_handlers/prefixhandler.py @@ -33,7 +33,7 @@ if TYPE_CHECKING: RT = TypeVar("RT") -class PrefixHandler(BaseHandler[Update, CCT]): +class PrefixHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle custom prefix commands. This is an intermediate handler between :class:`MessageHandler` and :class:`CommandHandler`. @@ -123,7 +123,7 @@ class PrefixHandler(BaseHandler[Update, CCT]): __slots__ = ("commands", "filters") def __init__( - self, + self: "PrefixHandler[CCT, RT]", prefix: SCT[str], command: SCT[str], callback: HandlerCallback[Update, CCT, RT], diff --git a/telegram/ext/_handlers/shippingqueryhandler.py b/telegram/ext/_handlers/shippingqueryhandler.py index f0234c2a9..c18651309 100644 --- a/telegram/ext/_handlers/shippingqueryhandler.py +++ b/telegram/ext/_handlers/shippingqueryhandler.py @@ -21,10 +21,10 @@ from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler -from telegram.ext._utils.types import CCT +from telegram.ext._utils.types import CCT, RT -class ShippingQueryHandler(BaseHandler[Update, CCT]): +class ShippingQueryHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`telegram.Update.shipping_query`. Warning: diff --git a/telegram/ext/_handlers/stringcommandhandler.py b/telegram/ext/_handlers/stringcommandhandler.py index d5c29bf66..ff655d9d6 100644 --- a/telegram/ext/_handlers/stringcommandhandler.py +++ b/telegram/ext/_handlers/stringcommandhandler.py @@ -29,7 +29,7 @@ if TYPE_CHECKING: from telegram.ext import Application -class StringCommandHandler(BaseHandler[str, CCT]): +class StringCommandHandler(BaseHandler[str, CCT, RT]): """Handler class to handle string commands. Commands are string updates that start with ``/``. The handler will add a :obj:`list` to the :class:`CallbackContext` named :attr:`CallbackContext.args`. It will contain a list of strings, @@ -71,7 +71,7 @@ class StringCommandHandler(BaseHandler[str, CCT]): __slots__ = ("command",) def __init__( - self, + self: "StringCommandHandler[CCT, RT]", command: str, callback: HandlerCallback[str, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/stringregexhandler.py b/telegram/ext/_handlers/stringregexhandler.py index c2e22c106..bd9746949 100644 --- a/telegram/ext/_handlers/stringregexhandler.py +++ b/telegram/ext/_handlers/stringregexhandler.py @@ -32,7 +32,7 @@ if TYPE_CHECKING: RT = TypeVar("RT") -class StringRegexHandler(BaseHandler[str, CCT]): +class StringRegexHandler(BaseHandler[str, CCT, RT]): """Handler class to handle string updates based on a regex which checks the update content. Read the documentation of the :mod:`re` module for more information. The :func:`re.match` @@ -74,7 +74,7 @@ class StringRegexHandler(BaseHandler[str, CCT]): __slots__ = ("pattern",) def __init__( - self, + self: "StringRegexHandler[CCT, RT]", pattern: Union[str, Pattern[str]], callback: HandlerCallback[str, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/typehandler.py b/telegram/ext/_handlers/typehandler.py index 151a7fbf1..48a4530bc 100644 --- a/telegram/ext/_handlers/typehandler.py +++ b/telegram/ext/_handlers/typehandler.py @@ -29,7 +29,7 @@ RT = TypeVar("RT") UT = TypeVar("UT") -class TypeHandler(BaseHandler[UT, CCT]): +class TypeHandler(BaseHandler[UT, CCT, RT]): """Handler class to handle updates of custom types. Warning: @@ -70,7 +70,7 @@ class TypeHandler(BaseHandler[UT, CCT]): __slots__ = ("strict", "type") def __init__( - self, + self: "TypeHandler[UT, CCT, RT]", type: Type[UT], # pylint: disable=redefined-builtin callback: HandlerCallback[UT, CCT, RT], strict: bool = False,