diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e2cd308e78f..6b56f457ed3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ ci: repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.5.6' + rev: 'v0.8.6' hooks: - id: ruff name: ruff @@ -18,18 +18,18 @@ repos: - cachetools>=5.3.3,<5.5.0 - aiolimiter~=1.1,<1.3 - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.4.2 + rev: 24.10.0 hooks: - id: black args: - --diff - --check - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 + rev: 7.1.1 hooks: - id: flake8 - repo: https://github.com/PyCQA/pylint - rev: v3.3.2 + rev: v3.3.3 hooks: - id: pylint files: ^(?!(tests|docs)).*\.py$ @@ -41,7 +41,7 @@ repos: - aiolimiter~=1.1,<1.3 - . # this basically does `pip install -e .` - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.1 + rev: v1.14.1 hooks: - id: mypy name: mypy-ptb @@ -68,7 +68,7 @@ repos: - cachetools>=5.3.3,<5.5.0 - . # this basically does `pip install -e .` - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.19.1 hooks: - id: pyupgrade args: diff --git a/docs/auxil/admonition_inserter.py b/docs/auxil/admonition_inserter.py index f423eae5e44..abbefccca75 100644 --- a/docs/auxil/admonition_inserter.py +++ b/docs/auxil/admonition_inserter.py @@ -435,12 +435,12 @@ def _generate_admonitions( return admonition_for_class @staticmethod - def _generate_class_name_for_link(cls: type) -> str: + def _generate_class_name_for_link(cls_: type) -> str: """Generates class name that can be used in a ReST link.""" # Check for potential presence of ".ext.", we will need to keep it. - ext = ".ext" if ".ext." in str(cls) else "" - return f"telegram{ext}.{cls.__name__}" + ext = ".ext" if ".ext." in str(cls_) else "" + return f"telegram{ext}.{cls_.__name__}" def _generate_link_to_method(self, method_name: str, cls: type) -> str: """Generates a ReST link to a method of a telegram class.""" @@ -448,11 +448,11 @@ def _generate_link_to_method(self, method_name: str, cls: type) -> str: return f":meth:`{self._generate_class_name_for_link(cls)}.{method_name}`" @staticmethod - def _iter_subclasses(cls: type) -> Iterator: + def _iter_subclasses(cls_: type) -> Iterator: return ( # exclude private classes c - for c in cls.__subclasses__() + for c in cls_.__subclasses__() if not str(c).split(".")[-1].startswith("_") ) diff --git a/pyproject.toml b/pyproject.toml index 01406663f55..ef6556ecef8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ description = "We have made you a wrapper you can't refuse" readme = "README.rst" requires-python = ">=3.9" license = "LGPL-3.0-only" -license-files = { paths = ["LICENSE", "LICENSE.dual", "LICENSE.lesser"] } +license-files = ["LICENSE", "LICENSE.dual", "LICENSE.lesser"] authors = [ { name = "Leandro Toledo", email = "devs@python-telegram-bot.org" } ] diff --git a/telegram/_bot.py b/telegram/_bot.py index 1d684a77eb5..8cb2431a336 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -4386,7 +4386,7 @@ async def get_updates( self, offset: Optional[int] = None, limit: Optional[int] = None, - timeout: Optional[int] = None, # noqa: ASYNC109 + timeout: Optional[int] = None, allowed_updates: Optional[Sequence[str]] = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, diff --git a/telegram/ext/_aioratelimiter.py b/telegram/ext/_aioratelimiter.py index c990a54b923..4a7c2e18223 100644 --- a/telegram/ext/_aioratelimiter.py +++ b/telegram/ext/_aioratelimiter.py @@ -247,7 +247,7 @@ async def process_request( # In case user passes integer chat id as string with contextlib.suppress(ValueError, TypeError): - chat_id = int(chat_id) + chat_id = int(chat_id) # type: ignore[arg-type] if (isinstance(chat_id, int) and chat_id < 0) or isinstance(chat_id, str): # string chat_id only works for channels and supergroups diff --git a/telegram/ext/_callbackcontext.py b/telegram/ext/_callbackcontext.py index d03250ca835..66901befd60 100644 --- a/telegram/ext/_callbackcontext.py +++ b/telegram/ext/_callbackcontext.py @@ -145,7 +145,7 @@ def __init__( @property def application(self) -> "Application[BT, ST, UD, CD, BD, Any]": """:class:`telegram.ext.Application`: The application associated with this context.""" - return self._application + return self._application # type: ignore[return-value] @property def bot_data(self) -> BD: diff --git a/telegram/ext/_extbot.py b/telegram/ext/_extbot.py index d21b1f76dcc..80eede9d841 100644 --- a/telegram/ext/_extbot.py +++ b/telegram/ext/_extbot.py @@ -638,7 +638,7 @@ async def get_updates( self, offset: Optional[int] = None, limit: Optional[int] = None, - timeout: Optional[int] = None, # noqa: ASYNC109 + timeout: Optional[int] = None, allowed_updates: Optional[Sequence[str]] = None, *, read_timeout: ODVInput[float] = DEFAULT_NONE, diff --git a/telegram/ext/_updater.py b/telegram/ext/_updater.py index 11c225c4f33..5b126a9803d 100644 --- a/telegram/ext/_updater.py +++ b/telegram/ext/_updater.py @@ -205,7 +205,7 @@ async def shutdown(self) -> None: async def start_polling( self, poll_interval: float = 0.0, - timeout: int = 10, # noqa: ASYNC109 + timeout: int = 10, bootstrap_retries: int = -1, read_timeout: ODVInput[float] = DEFAULT_NONE, write_timeout: ODVInput[float] = DEFAULT_NONE, @@ -341,7 +341,7 @@ def callback(error: telegram.error.TelegramError) async def _start_polling( self, poll_interval: float, - timeout: int, # noqa: ASYNC109 + timeout: int, read_timeout: ODVInput[float], write_timeout: ODVInput[float], connect_timeout: ODVInput[float], diff --git a/tests/conftest.py b/tests/conftest.py index e5e74a0271b..40e7c34b8bc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -311,7 +311,7 @@ def false_update(request): scope="session", params=[pytz.timezone, zoneinfo.ZoneInfo] if TEST_WITH_OPT_DEPS else [zoneinfo.ZoneInfo], ) -def _tz_implementation(request): # noqa: PT005 +def _tz_implementation(request): # This fixture is used to parametrize the timezone fixture # This is similar to what @pyttest.mark.parametrize does but for fixtures # However, this is needed only internally for the `tzinfo` fixture, so we keep it private diff --git a/tests/ext/test_chatboosthandler.py b/tests/ext/test_chatboosthandler.py index 5e0d1c07a81..d3687168599 100644 --- a/tests/ext/test_chatboosthandler.py +++ b/tests/ext/test_chatboosthandler.py @@ -132,7 +132,7 @@ async def cb_chat_boost_any(self, update, context): ) @pytest.mark.parametrize( - argnames=["allowed_types", "cb", "expected"], + argnames=("allowed_types", "cb", "expected"), argvalues=[ (ChatBoostHandler.CHAT_BOOST, "cb_chat_boost_updated", (True, False)), (ChatBoostHandler.REMOVED_CHAT_BOOST, "cb_chat_boost_removed", (False, True)), diff --git a/tests/ext/test_chatmemberhandler.py b/tests/ext/test_chatmemberhandler.py index 7846d3607b1..c84efa26fb1 100644 --- a/tests/ext/test_chatmemberhandler.py +++ b/tests/ext/test_chatmemberhandler.py @@ -115,7 +115,7 @@ async def callback(self, update, context): ) @pytest.mark.parametrize( - argnames=["allowed_types", "expected"], + argnames=("allowed_types", "expected"), argvalues=[ (ChatMemberHandler.MY_CHAT_MEMBER, (True, False)), (ChatMemberHandler.CHAT_MEMBER, (False, True)), @@ -145,7 +145,7 @@ async def test_chat_member_types( assert self.test_flag == result_2 @pytest.mark.parametrize( - argnames=["allowed_types", "chat_id", "expected"], + argnames=("allowed_types", "chat_id", "expected"), argvalues=[ (ChatMemberHandler.MY_CHAT_MEMBER, None, (True, False)), (ChatMemberHandler.CHAT_MEMBER, None, (False, True)), diff --git a/tests/ext/test_messagereactionhandler.py b/tests/ext/test_messagereactionhandler.py index e22e78230ad..dd843be91ac 100644 --- a/tests/ext/test_messagereactionhandler.py +++ b/tests/ext/test_messagereactionhandler.py @@ -173,7 +173,7 @@ async def test_context(self, app, message_reaction_update, message_reaction_coun assert self.test_flag @pytest.mark.parametrize( - argnames=["allowed_types", "expected"], + argnames=("allowed_types", "expected"), argvalues=[ (MessageReactionHandler.MESSAGE_REACTION_UPDATED, (True, False)), (MessageReactionHandler.MESSAGE_REACTION_COUNT_UPDATED, (False, True)), @@ -201,7 +201,7 @@ async def test_message_reaction_types( assert self.test_flag == result_2 @pytest.mark.parametrize( - argnames=["allowed_types", "kwargs"], + argnames=("allowed_types", "kwargs"), argvalues=[ (MessageReactionHandler.MESSAGE_REACTION_COUNT_UPDATED, {"user_username": "user"}), (MessageReactionHandler.MESSAGE_REACTION, {"user_id": 123}), @@ -215,7 +215,7 @@ async def test_username_with_anonymous_reaction(self, app, allowed_types, kwargs MessageReactionHandler(self.callback, message_reaction_types=allowed_types, **kwargs) @pytest.mark.parametrize( - argnames=["chat_id", "expected"], + argnames=("chat_id", "expected"), argvalues=[(1, True), ([1], True), (2, False), ([2], False)], ) async def test_with_chat_ids( @@ -226,8 +226,8 @@ async def test_with_chat_ids( assert handler.check_update(message_reaction_count_update) == expected @pytest.mark.parametrize( - argnames=["chat_username"], - argvalues=[("group_a",), ("@group_a",), (["group_a"],), (["@group_a"],)], + argnames="chat_username", + argvalues=["group_a", "@group_a", ["group_a"], ["@group_a"]], ids=["group_a", "@group_a", "['group_a']", "['@group_a']"], ) async def test_with_chat_usernames( @@ -247,7 +247,7 @@ async def test_with_chat_usernames( message_reaction_count_update.message_reaction_count.chat.username = None @pytest.mark.parametrize( - argnames=["user_id", "expected"], + argnames=("user_id", "expected"), argvalues=[(1, True), ([1], True), (2, False), ([2], False)], ) async def test_with_user_ids( @@ -262,8 +262,8 @@ async def test_with_user_ids( assert not handler.check_update(message_reaction_count_update) @pytest.mark.parametrize( - argnames=["user_username"], - argvalues=[("user_a",), ("@user_a",), (["user_a"],), (["@user_a"],)], + argnames="user_username", + argvalues=["user_a", "@user_a", ["user_a"], ["@user_a"]], ids=["user_a", "@user_a", "['user_a']", "['@user_a']"], ) async def test_with_user_usernames( diff --git a/tests/test_bot.py b/tests/test_bot.py index fe0307a86cb..35a9fa017ac 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -191,7 +191,7 @@ def bot_methods(ext_bot=True, include_camel_case=False, include_do_api_request=F ids.append(f"{cls.__name__}.{name}") return pytest.mark.parametrize( - argnames="bot_class, bot_method_name,bot_method", argvalues=arg_values, ids=ids + argnames=("bot_class", "bot_method_name", "bot_method"), argvalues=arg_values, ids=ids ) diff --git a/tests/test_chat.py b/tests/test_chat.py index e39281ee010..27c3f934008 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -286,7 +286,7 @@ async def test_unban_member(self, monkeypatch, chat, only_if_banned): async def make_assertion(*_, **kwargs): chat_id = kwargs["chat_id"] == chat.id user_id = kwargs["user_id"] == 42 - o_i_b = kwargs.get("only_if_banned", None) == only_if_banned + o_i_b = kwargs.get("only_if_banned") == only_if_banned return chat_id and user_id and o_i_b assert check_shortcut_signature(Chat.unban_member, Bot.unban_chat_member, ["chat_id"], []) @@ -333,7 +333,7 @@ async def test_promote_member(self, monkeypatch, chat, is_anonymous): async def make_assertion(*_, **kwargs): chat_id = kwargs["chat_id"] == chat.id user_id = kwargs["user_id"] == 42 - o_i_b = kwargs.get("is_anonymous", None) == is_anonymous + o_i_b = kwargs.get("is_anonymous") == is_anonymous return chat_id and user_id and o_i_b assert check_shortcut_signature( @@ -353,7 +353,7 @@ async def test_restrict_member(self, monkeypatch, chat): async def make_assertion(*_, **kwargs): chat_id = kwargs["chat_id"] == chat.id user_id = kwargs["user_id"] == 42 - o_i_b = kwargs.get("permissions", None) == permissions + o_i_b = kwargs.get("permissions") == permissions return chat_id and user_id and o_i_b assert check_shortcut_signature( diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index 6249fccfe08..e4f6da387ac 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -153,10 +153,8 @@ def make_json_dict(instance: ChatMember, include_optional_args: bool = False) -> # If we want to test all args (for de_json) # or if the param is optional but for backwards compatability elif ( - param.default is not inspect.Parameter.empty - and include_optional_args - or param.name in ["can_delete_stories", "can_post_stories", "can_edit_stories"] - ): + param.default is not inspect.Parameter.empty and include_optional_args + ) or param.name in ["can_delete_stories", "can_post_stories", "can_edit_stories"]: json_dict[param.name] = val return json_dict