We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Don't allow more than 2 dimensional input for `Inline/ReplyKeyboardMarkup`
### What kind of feature are you missing? Where do you notice a shortcoming of PTB?

When a user passes their list to `Inline/ReplyKeyboardMarkup`, we currently check if their input is valid (exactly 2 dimensional input is valid), i.e. 

* the input is a sequence, not just a single button
* it's not just a simple sequence (sequence of buttons)

However it doesn't check if it's more than 2D, i.e. `[[[KeyboardButton(...)], [...], ]]` is invalid.

### Describe the solution you'd like

Modify `tg._utils.markup.check_keyboard_type` to return `False` if we find another sequence.

### Describe alternatives you've considered

_No response_

### Additional context

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `telegram/_utils/markup.py`
Content:
```
1 #!/usr/bin/env python
2 #
3 # A library that provides a Python interface to the Telegram Bot API
4 # Copyright (C) 2015-2023
5 # Leandro Toledo de Souza <devs@python-telegram-bot.org>
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Lesser Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Lesser Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser Public License
18 # along with this program.  If not, see [http://www.gnu.org/licenses/].
19 """This module contains a helper function for Telegram's ReplyMarkups
20 
21 .. versionchanged:: 20.0
22    Previously, the contents of this module were available through the (no longer existing)
23    class ``telegram.ReplyMarkup``.
24 
25 Warning:
26     Contents of this module are intended to be used internally by the library and *not* by the
27     user. Changes to this module are not considered breaking changes and may not be documented in
28     the changelog.
29 """
30 from collections.abc import Sequence
31 
32 
33 def check_keyboard_type(keyboard: object) -> bool:
34     """Checks if the keyboard provided is of the correct type - A list of lists.
35     Implicitly tested in the init-tests of `{Inline, Reply}KeyboardMarkup`
36     """
37     # string and bytes may actually be used for ReplyKeyboardMarkup in which case each button
38     # would contain a single character. But that use case should be discouraged and we don't
39     # allow it here.
40     if not isinstance(keyboard, Sequence) or isinstance(keyboard, (str, bytes)):
41         return False
42     for row in keyboard:
43         if not isinstance(row, Sequence) or isinstance(row, (str, bytes)):
44             return False
45     return True
46
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/telegram/_utils/markup.py b/telegram/_utils/markup.py
--- a/telegram/_utils/markup.py
+++ b/telegram/_utils/markup.py
@@ -31,7 +31,7 @@
 
 
 def check_keyboard_type(keyboard: object) -> bool:
-    """Checks if the keyboard provided is of the correct type - A list of lists.
+    """Checks if the keyboard provided is of the correct type - A sequence of sequences.
     Implicitly tested in the init-tests of `{Inline, Reply}KeyboardMarkup`
     """
     # string and bytes may actually be used for ReplyKeyboardMarkup in which case each button
@@ -39,7 +39,11 @@
     # allow it here.
     if not isinstance(keyboard, Sequence) or isinstance(keyboard, (str, bytes)):
         return False
+
     for row in keyboard:
         if not isinstance(row, Sequence) or isinstance(row, (str, bytes)):
             return False
+        for inner in row:
+            if isinstance(inner, Sequence) and not isinstance(inner, str):
+                return False
     return True

{"golden_diff": "diff --git a/telegram/_utils/markup.py b/telegram/_utils/markup.py\n--- a/telegram/_utils/markup.py\n+++ b/telegram/_utils/markup.py\n@@ -31,7 +31,7 @@\n \n \n def check_keyboard_type(keyboard: object) -> bool:\n-    \"\"\"Checks if the keyboard provided is of the correct type - A list of lists.\n+    \"\"\"Checks if the keyboard provided is of the correct type - A sequence of sequences.\n     Implicitly tested in the init-tests of `{Inline, Reply}KeyboardMarkup`\n     \"\"\"\n     # string and bytes may actually be used for ReplyKeyboardMarkup in which case each button\n@@ -39,7 +39,11 @@\n     # allow it here.\n     if not isinstance(keyboard, Sequence) or isinstance(keyboard, (str, bytes)):\n         return False\n+\n     for row in keyboard:\n         if not isinstance(row, Sequence) or isinstance(row, (str, bytes)):\n             return False\n+        for inner in row:\n+            if isinstance(inner, Sequence) and not isinstance(inner, str):\n+                return False\n     return True\n", "issue": "Don't allow more than 2 dimensional input for `Inline/ReplyKeyboardMarkup`\n### What kind of feature are you missing? Where do you notice a shortcoming of PTB?\n\nWhen a user passes their list to `Inline/ReplyKeyboardMarkup`, we currently check if their input is valid (exactly 2 dimensional input is valid), i.e. \r\n\r\n* the input is a sequence, not just a single button\r\n* it's not just a simple sequence (sequence of buttons)\r\n\r\nHowever it doesn't check if it's more than 2D, i.e. `[[[KeyboardButton(...)], [...], ]]` is invalid.\n\n### Describe the solution you'd like\n\nModify `tg._utils.markup.check_keyboard_type` to return `False` if we find another sequence.\n\n### Describe alternatives you've considered\n\n_No response_\n\n### Additional context\n\n_No response_\n", "before_files": [{"content": "#!/usr/bin/env python\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2023\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains a helper function for Telegram's ReplyMarkups\n\n.. versionchanged:: 20.0\n   Previously, the contents of this module were available through the (no longer existing)\n   class ``telegram.ReplyMarkup``.\n\nWarning:\n    Contents of this module are intended to be used internally by the library and *not* by the\n    user. Changes to this module are not considered breaking changes and may not be documented in\n    the changelog.\n\"\"\"\nfrom collections.abc import Sequence\n\n\ndef check_keyboard_type(keyboard: object) -> bool:\n    \"\"\"Checks if the keyboard provided is of the correct type - A list of lists.\n    Implicitly tested in the init-tests of `{Inline, Reply}KeyboardMarkup`\n    \"\"\"\n    # string and bytes may actually be used for ReplyKeyboardMarkup in which case each button\n    # would contain a single character. But that use case should be discouraged and we don't\n    # allow it here.\n    if not isinstance(keyboard, Sequence) or isinstance(keyboard, (str, bytes)):\n        return False\n    for row in keyboard:\n        if not isinstance(row, Sequence) or isinstance(row, (str, bytes)):\n            return False\n    return True\n", "path": "telegram/_utils/markup.py"}], "after_files": [{"content": "#!/usr/bin/env python\n#\n# A library that provides a Python interface to the Telegram Bot API\n# Copyright (C) 2015-2023\n# Leandro Toledo de Souza <devs@python-telegram-bot.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU Lesser Public License for more details.\n#\n# You should have received a copy of the GNU Lesser Public License\n# along with this program.  If not, see [http://www.gnu.org/licenses/].\n\"\"\"This module contains a helper function for Telegram's ReplyMarkups\n\n.. versionchanged:: 20.0\n   Previously, the contents of this module were available through the (no longer existing)\n   class ``telegram.ReplyMarkup``.\n\nWarning:\n    Contents of this module are intended to be used internally by the library and *not* by the\n    user. Changes to this module are not considered breaking changes and may not be documented in\n    the changelog.\n\"\"\"\nfrom collections.abc import Sequence\n\n\ndef check_keyboard_type(keyboard: object) -> bool:\n    \"\"\"Checks if the keyboard provided is of the correct type - A sequence of sequences.\n    Implicitly tested in the init-tests of `{Inline, Reply}KeyboardMarkup`\n    \"\"\"\n    # string and bytes may actually be used for ReplyKeyboardMarkup in which case each button\n    # would contain a single character. But that use case should be discouraged and we don't\n    # allow it here.\n    if not isinstance(keyboard, Sequence) or isinstance(keyboard, (str, bytes)):\n        return False\n\n    for row in keyboard:\n        if not isinstance(row, Sequence) or isinstance(row, (str, bytes)):\n            return False\n        for inner in row:\n            if isinstance(inner, Sequence) and not isinstance(inner, str):\n                return False\n    return True\n", "path": "telegram/_utils/markup.py"}]}