Add api_kwargs Paramater to Bot.log_out and Improve Related Unit Tests (#3147)

This commit is contained in:
Bibo-Joshi 2022-07-10 15:37:12 +02:00 committed by GitHub
parent d4b7a2b3e9
commit 142e3c0177
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 62 deletions

View file

@ -7422,6 +7422,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager):
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: JSONDict = None,
) -> bool:
"""
Use this method to log out from the cloud Bot API server before launching the bot locally.
@ -7443,6 +7444,10 @@ class Bot(TelegramObject, AbstractAsyncContextManager):
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
Telegram API.
.. versionadded:: 20.0
Returns:
:obj:`True`: On success
@ -7457,6 +7462,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager):
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
@_log

View file

@ -137,6 +137,34 @@ xfail = pytest.mark.xfail(
)
def bot_methods(ext_bot=True):
arg_values = []
ids = []
non_api_methods = [
"de_json",
"de_list",
"to_dict",
"to_json",
"parse_data",
"get_bot",
"set_bot",
"initialize",
"shutdown",
"insert_callback_data",
]
classes = (Bot, ExtBot) if ext_bot else (Bot,)
for cls in classes:
for name, attribute in inspect.getmembers(cls, predicate=inspect.isfunction):
if name.startswith("_") or name in non_api_methods:
continue
arg_values.append((cls, name, attribute))
ids.append(f"{cls.__name__}.{name}")
return pytest.mark.parametrize(
argnames="bot_class, bot_method_name,bot_method", argvalues=arg_values, ids=ids
)
class TestBot:
"""
Most are executed on tg.ext.ExtBot, as that class only extends the functionality of tg.bot
@ -366,29 +394,10 @@ class TestBot:
with pytest.raises(pickle.PicklingError, match="Bot objects cannot be pickled"):
pickle.dumps(bot)
@pytest.mark.parametrize(
"bot_method_name",
argvalues=[
name
for name, _ in inspect.getmembers(Bot, predicate=inspect.isfunction)
if not name.startswith("_")
and name
not in [
"de_json",
"de_list",
"to_dict",
"to_json",
"parse_data",
"get_updates",
"getUpdates",
"get_bot",
"set_bot",
"initialize",
"shutdown",
]
],
)
async def test_defaults_handling(self, bot_method_name, bot, raw_bot, monkeypatch):
@bot_methods(ext_bot=False)
async def test_defaults_handling(
self, bot_class, bot_method_name, bot_method, bot, raw_bot, monkeypatch
):
"""
Here we check that the bot methods handle tg.ext.Defaults correctly. This has two parts:
@ -408,6 +417,9 @@ class TestBot:
Finally, there are some tests for Defaults.{parse_mode, quote, allow_sending_without_reply}
at the appropriate places, as those are the only things we can actually check.
"""
if bot_method_name.lower().replace("_", "") == "getupdates":
return
try:
# Check that ExtBot does the right thing
bot_method = getattr(bot, bot_method_name)
@ -982,6 +994,7 @@ class TestBot:
@pytest.mark.asyncio
async def test_answer_web_app_query(self, bot, monkeypatch):
params = False
# For now just test that our internals pass the correct data
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
@ -2923,44 +2936,42 @@ class TestBot:
bot.callback_data_cache.clear_callback_data()
bot.callback_data_cache.clear_callback_queries()
def test_camel_case_redefinition_extbot(self):
invalid_camel_case_functions = []
for function_name, function in ExtBot.__dict__.items():
camel_case_function = getattr(ExtBot, to_camel_case(function_name), False)
if callable(function) and camel_case_function and camel_case_function is not function:
invalid_camel_case_functions.append(function_name)
assert invalid_camel_case_functions == []
@bot_methods()
def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method):
camel_case_name = to_camel_case(bot_method_name)
camel_case_function = getattr(bot_class, camel_case_name, False)
assert camel_case_function is not False, f"{camel_case_name} not found"
assert camel_case_function is bot_method, f"{camel_case_name} is not {bot_method}"
def test_camel_case_bot(self):
not_available_camelcase_functions = []
for function_name, function in Bot.__dict__.items():
if (
function_name.startswith("_")
or not callable(function)
or function_name in ["to_dict"]
):
continue
camel_case_function = getattr(Bot, to_camel_case(function_name), False)
if not camel_case_function:
not_available_camelcase_functions.append(function_name)
assert not_available_camelcase_functions == []
def test_coroutine_functions(self):
@bot_methods()
def test_coroutine_functions(self, bot_class, bot_method_name, bot_method):
"""Check that all bot methods are defined as async def ..."""
non_coroutine_functions = set()
for attr_name, attribute in Bot.__dict__.items():
# not islower() skips the camelcase aliases
if not callable(attribute) or attr_name.startswith("_") or not attr_name.islower():
continue
if not bot_method_name.islower():
return
# unfortunately `inspect.iscoroutinefunction` doesn't do the trick directly,
# as the @_log decorator interferes
source = "".join(inspect.getsourcelines(attribute)[0])
if (
"pool_timeout: ODVInput[float]" in source
and f"async def {attr_name}" not in source
):
non_coroutine_functions.add(attr_name)
assert non_coroutine_functions == set(), (
"The following methods should be defined as coroutine functions: "
f"{','.join(non_coroutine_functions)} "
)
source = "".join(inspect.getsourcelines(bot_method)[0])
assert (
f"async def {bot_method_name}" in source
), f"{bot_method_name} should be a coroutine function"
@bot_methods()
def test_api_kwargs_and_timeouts_present(self, bot_class, bot_method_name, bot_method):
"""Check that all bot methods have `api_kwargs` and timeout params."""
param_names = inspect.signature(bot_method).parameters.keys()
assert (
"pool_timeout" in param_names
), f"{bot_method_name} is missing the parameter `pool_timeout`"
assert (
"read_timeout" in param_names
), f"{bot_method_name} is missing the parameter `read_timeout`"
assert (
"connect_timeout" in param_names
), f"{bot_method_name} is missing the parameter `connect_timeout`"
assert (
"write_timeout" in param_names
), f"{bot_method_name} is missing the parameter `write_timeout`"
assert (
"api_kwargs" in param_names
), f"{bot_method_name} is missing the parameter `api_kwargs`"