From 1fb9db1cc3022d8858c53315ec910735d7068594 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 14 Sep 2021 20:20:55 +0400 Subject: [PATCH 1/6] Check that the keyboard is of right type --- telegram/inline/inlinekeyboardmarkup.py | 6 ++++++ telegram/replykeyboardmarkup.py | 6 ++++++ telegram/replymarkup.py | 15 +++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/telegram/inline/inlinekeyboardmarkup.py b/telegram/inline/inlinekeyboardmarkup.py index cff50391bac..57fe1584d3a 100644 --- a/telegram/inline/inlinekeyboardmarkup.py +++ b/telegram/inline/inlinekeyboardmarkup.py @@ -53,6 +53,12 @@ def __init__(self, inline_keyboard: List[List[InlineKeyboardButton]], **_kwargs: self._id_attrs = (self.inline_keyboard,) + if not self._check_keyboard_type(inline_keyboard): + raise ValueError( + "The parameter `inline_keyboard` should be a list of " + "list of InlineKeyboardButtons" + ) + def to_dict(self) -> JSONDict: """See :meth:`telegram.TelegramObject.to_dict`.""" data = super().to_dict() diff --git a/telegram/replykeyboardmarkup.py b/telegram/replykeyboardmarkup.py index 28eb87047e8..cc24a51e2b0 100644 --- a/telegram/replykeyboardmarkup.py +++ b/telegram/replykeyboardmarkup.py @@ -93,6 +93,12 @@ def __init__( **_kwargs: Any, ): # Required + if not self._check_keyboard_type(keyboard): + raise ValueError( + "The parameter `keyboard` should be a list of list of " + "strings or KeyboardButtons" + ) + self.keyboard = [] for row in keyboard: button_row = [] diff --git a/telegram/replymarkup.py b/telegram/replymarkup.py index 4f2c01d2710..eebec726fc3 100644 --- a/telegram/replymarkup.py +++ b/telegram/replymarkup.py @@ -17,9 +17,13 @@ # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. """Base class for Telegram ReplyMarkup Objects.""" +from typing import Union, TYPE_CHECKING, Sequence from telegram import TelegramObject +if TYPE_CHECKING: + from telegram import KeyboardButton, InlineKeyboardButton + class ReplyMarkup(TelegramObject): """Base class for Telegram ReplyMarkup Objects. @@ -31,3 +35,14 @@ class ReplyMarkup(TelegramObject): """ __slots__ = () + + @staticmethod + def _check_keyboard_type( + keyboard: Sequence[Sequence[Union['KeyboardButton', 'str', 'InlineKeyboardButton']]] + ) -> bool: + """Checks if the keyboard provided is of the correct type - A list of lists.""" + + for row in keyboard: + if not isinstance(row, list): + return False + return True From e6583f7b94e665d1843c4b696e9a69447a2e3e15 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 14 Sep 2021 20:21:22 +0400 Subject: [PATCH 2/6] Add supporting tests --- tests/test_inlinekeyboardmarkup.py | 6 ++++++ tests/test_replykeyboardmarkup.py | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index 8d4e35daaa5..7492967318d 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -81,6 +81,12 @@ def test_from_column(self): def test_expected_values(self, inline_keyboard_markup): assert inline_keyboard_markup.inline_keyboard == self.inline_keyboard + def test_wrong_keyboard_inputs(self): + with pytest.raises(ValueError): + InlineKeyboardMarkup( + [[InlineKeyboardButton('b1', '1')], InlineKeyboardButton('b2', '2')] + ) + def test_expected_values_empty_switch(self, inline_keyboard_markup, bot, monkeypatch): def test( url, diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index b95cdec8c05..c9494da09fe 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -102,6 +102,10 @@ def test_expected_values(self, reply_keyboard_markup): assert reply_keyboard_markup.selective == self.selective assert reply_keyboard_markup.input_field_placeholder == self.input_field_placeholder + def test_wrong_keyboard_inputs(self): + with pytest.raises(ValueError): + ReplyKeyboardMarkup([[KeyboardButton('b1')], 'b2']) + def test_to_dict(self, reply_keyboard_markup): reply_keyboard_markup_dict = reply_keyboard_markup.to_dict() From b18c88106984094c5ae4e295d0aa4dcb1cdb9c9b Mon Sep 17 00:00:00 2001 From: "deepsource-autofix[bot]" <62050782+deepsource-autofix[bot]@users.noreply.github.com> Date: Tue, 14 Sep 2021 16:36:24 +0000 Subject: [PATCH 3/6] Autofix issues in 1 file Resolved issues in telegram/replymarkup.py via DeepSource Autofix --- telegram/replymarkup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/telegram/replymarkup.py b/telegram/replymarkup.py index eebec726fc3..4aad736650c 100644 --- a/telegram/replymarkup.py +++ b/telegram/replymarkup.py @@ -41,7 +41,6 @@ def _check_keyboard_type( keyboard: Sequence[Sequence[Union['KeyboardButton', 'str', 'InlineKeyboardButton']]] ) -> bool: """Checks if the keyboard provided is of the correct type - A list of lists.""" - for row in keyboard: if not isinstance(row, list): return False From 5870ba9e155ae2e68dc02cbf08fac854fb3e1acb Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 14 Sep 2021 21:34:57 +0400 Subject: [PATCH 4/6] check keyboard at the top of init --- telegram/inline/inlinekeyboardmarkup.py | 9 ++++----- telegram/replykeyboardmarkup.py | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/telegram/inline/inlinekeyboardmarkup.py b/telegram/inline/inlinekeyboardmarkup.py index 57fe1584d3a..634105296b8 100644 --- a/telegram/inline/inlinekeyboardmarkup.py +++ b/telegram/inline/inlinekeyboardmarkup.py @@ -48,16 +48,15 @@ class InlineKeyboardMarkup(ReplyMarkup): __slots__ = ('inline_keyboard',) def __init__(self, inline_keyboard: List[List[InlineKeyboardButton]], **_kwargs: Any): - # Required - self.inline_keyboard = inline_keyboard - - self._id_attrs = (self.inline_keyboard,) - if not self._check_keyboard_type(inline_keyboard): raise ValueError( "The parameter `inline_keyboard` should be a list of " "list of InlineKeyboardButtons" ) + # Required + self.inline_keyboard = inline_keyboard + + self._id_attrs = (self.inline_keyboard,) def to_dict(self) -> JSONDict: """See :meth:`telegram.TelegramObject.to_dict`.""" diff --git a/telegram/replykeyboardmarkup.py b/telegram/replykeyboardmarkup.py index cc24a51e2b0..7b59dc0dbc4 100644 --- a/telegram/replykeyboardmarkup.py +++ b/telegram/replykeyboardmarkup.py @@ -92,13 +92,13 @@ def __init__( input_field_placeholder: str = None, **_kwargs: Any, ): - # Required if not self._check_keyboard_type(keyboard): raise ValueError( "The parameter `keyboard` should be a list of list of " "strings or KeyboardButtons" ) + # Required self.keyboard = [] for row in keyboard: button_row = [] From dcd79f26a8535d8d9bce7256d70fdc2ab96b8402 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 14 Sep 2021 22:01:14 +0400 Subject: [PATCH 5/6] change kb type to object --- telegram/replymarkup.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/telegram/replymarkup.py b/telegram/replymarkup.py index 4aad736650c..80671277546 100644 --- a/telegram/replymarkup.py +++ b/telegram/replymarkup.py @@ -17,13 +17,8 @@ # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. """Base class for Telegram ReplyMarkup Objects.""" -from typing import Union, TYPE_CHECKING, Sequence - from telegram import TelegramObject -if TYPE_CHECKING: - from telegram import KeyboardButton, InlineKeyboardButton - class ReplyMarkup(TelegramObject): """Base class for Telegram ReplyMarkup Objects. @@ -37,11 +32,9 @@ class ReplyMarkup(TelegramObject): __slots__ = () @staticmethod - def _check_keyboard_type( - keyboard: Sequence[Sequence[Union['KeyboardButton', 'str', 'InlineKeyboardButton']]] - ) -> bool: + def _check_keyboard_type(keyboard: object) -> bool: """Checks if the keyboard provided is of the correct type - A list of lists.""" - for row in keyboard: + for row in keyboard: # type: ignore[attr-defined] if not isinstance(row, list): return False return True From 1edcde621c8623d2fb1160a3961b62b94d8057b9 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 15 Sep 2021 12:13:54 +0400 Subject: [PATCH 6/6] address review - add check + tests --- telegram/replymarkup.py | 4 +++- tests/test_inlinekeyboardmarkup.py | 2 ++ tests/test_replykeyboardmarkup.py | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/telegram/replymarkup.py b/telegram/replymarkup.py index 80671277546..5c2ddf33f1d 100644 --- a/telegram/replymarkup.py +++ b/telegram/replymarkup.py @@ -34,7 +34,9 @@ class ReplyMarkup(TelegramObject): @staticmethod def _check_keyboard_type(keyboard: object) -> bool: """Checks if the keyboard provided is of the correct type - A list of lists.""" - for row in keyboard: # type: ignore[attr-defined] + if not isinstance(keyboard, list): + return False + for row in keyboard: if not isinstance(row, list): return False return True diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index 7492967318d..0e19d7931c5 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -86,6 +86,8 @@ def test_wrong_keyboard_inputs(self): InlineKeyboardMarkup( [[InlineKeyboardButton('b1', '1')], InlineKeyboardButton('b2', '2')] ) + with pytest.raises(ValueError): + InlineKeyboardMarkup(InlineKeyboardButton('b1', '1')) def test_expected_values_empty_switch(self, inline_keyboard_markup, bot, monkeypatch): def test( diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index c9494da09fe..d0a4532a27e 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -105,6 +105,8 @@ def test_expected_values(self, reply_keyboard_markup): def test_wrong_keyboard_inputs(self): with pytest.raises(ValueError): ReplyKeyboardMarkup([[KeyboardButton('b1')], 'b2']) + with pytest.raises(ValueError): + ReplyKeyboardMarkup(KeyboardButton('b1')) def test_to_dict(self, reply_keyboard_markup): reply_keyboard_markup_dict = reply_keyboard_markup.to_dict()