1
0
mirror of https://github.com/eternnoir/pyTelegramBotAPI.git synced 2023-08-10 21:12:57 +03:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Badiboy
fdbc0e6a61
Merge pull request #1410 from barbax7/patch-1
Correct test for antiflood function
2022-01-10 18:36:15 +03:00
Andrea Barbagallo
7fe8d27686
Correct test for antiflood function 2022-01-10 16:19:21 +01:00
Badiboy
9050f4af1f
Merge pull request #1409 from Badiboy/master
Bugfix in send_data
2022-01-10 16:51:44 +03:00
Badiboy
9140044956 Tests ant type hint fix 2022-01-10 16:49:49 +03:00
Badiboy
2e6b6bda53 Additional bugfix
Additional bugfix
Plus protected methods removal
2022-01-10 16:40:33 +03:00
Badiboy
8d8aa5a380 Bugfix in send_data
Bugfix in send_data
Protected methods renamed
Some hints added
2022-01-10 14:38:28 +03:00
9 changed files with 107 additions and 83 deletions

View File

@ -252,7 +252,7 @@ class TeleBot:
""" """
self.current_states = StateFile(filename=filename) self.current_states = StateFile(filename=filename)
self.current_states._create_dir() self.current_states.create_dir()
def enable_save_reply_handlers(self, delay=120, filename="./.handler-saves/reply.save"): def enable_save_reply_handlers(self, delay=120, filename="./.handler-saves/reply.save"):
""" """
@ -1221,11 +1221,13 @@ class TeleBot:
reply_to_message_id = reply_to_message_id, reply_markup = reply_markup, parse_mode = parse_mode, reply_to_message_id = reply_to_message_id, reply_markup = reply_markup, parse_mode = parse_mode,
disable_notification = disable_notification, timeout = timeout, caption = caption, thumb = thumb, disable_notification = disable_notification, timeout = timeout, caption = caption, thumb = thumb,
caption_entities = caption_entities, allow_sending_without_reply = allow_sending_without_reply, caption_entities = caption_entities, allow_sending_without_reply = allow_sending_without_reply,
disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name, protect_content = protect_content)) disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name,
protect_content = protect_content))
# TODO: Rewrite this method like in API. # TODO: Rewrite this method like in API.
def send_sticker( def send_sticker(
self, chat_id: Union[int, str], sticker: Union[Any, str], self, chat_id: Union[int, str],
sticker: Union[Any, str],
reply_to_message_id: Optional[int]=None, reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None, reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
disable_notification: Optional[bool]=None, disable_notification: Optional[bool]=None,
@ -1236,6 +1238,7 @@ class TeleBot:
""" """
Use this method to send .webp stickers. Use this method to send .webp stickers.
:param chat_id: :param chat_id:
:param sticker:
:param data: :param data:
:param reply_to_message_id: :param reply_to_message_id:
:param reply_markup: :param reply_markup:
@ -1254,7 +1257,8 @@ class TeleBot:
self.token, chat_id, sticker, 'sticker', self.token, chat_id, sticker, 'sticker',
reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, reply_to_message_id=reply_to_message_id, reply_markup=reply_markup,
disable_notification=disable_notification, timeout=timeout, disable_notification=disable_notification, timeout=timeout,
allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content)) allow_sending_without_reply=allow_sending_without_reply,
protect_content=protect_content))
def send_video( def send_video(
self, chat_id: Union[int, str], video: Union[Any, str], self, chat_id: Union[int, str], video: Union[Any, str],
@ -1330,6 +1334,7 @@ class TeleBot:
:param thumb: InputFile or String : Thumbnail of the file sent :param thumb: InputFile or String : Thumbnail of the file sent
:param caption: String : Animation caption (may also be used when resending animation by file_id). :param caption: String : Animation caption (may also be used when resending animation by file_id).
:param parse_mode: :param parse_mode:
:param protect_content:
:param reply_to_message_id: :param reply_to_message_id:
:param reply_markup: :param reply_markup:
:param disable_notification: :param disable_notification:
@ -1924,7 +1929,7 @@ class TeleBot:
return apihelper.set_my_commands(self.token, commands, scope, language_code) return apihelper.set_my_commands(self.token, commands, scope, language_code)
def delete_my_commands(self, scope: Optional[types.BotCommandScope]=None, def delete_my_commands(self, scope: Optional[types.BotCommandScope]=None,
language_code: Optional[int]=None) -> bool: language_code: Optional[str]=None) -> bool:
""" """
Use this method to delete the list of the bot's commands for the given scope and user language. Use this method to delete the list of the bot's commands for the given scope and user language.
After deletion, higher level commands will be shown to affected users. After deletion, higher level commands will be shown to affected users.
@ -2559,7 +2564,7 @@ class TeleBot:
:param chat_id: :param chat_id:
""" """
for key, value in kwargs.items(): for key, value in kwargs.items():
self.current_states._add_data(chat_id, key, value) self.current_states.add_data(chat_id, key, value)
def register_next_step_handler_by_chat_id( def register_next_step_handler_by_chat_id(
self, chat_id: Union[int, str], callback: Callable, *args, **kwargs) -> None: self, chat_id: Union[int, str], callback: Callable, *args, **kwargs) -> None:

View File

@ -144,6 +144,7 @@ def _make_request(token, method_name, method='get', params=None, files=None):
method, request_url, params=params, files=files, method, request_url, params=params, files=files,
timeout=(connect_timeout, read_timeout), proxies=proxy) timeout=(connect_timeout, read_timeout), proxies=proxy)
elif CUSTOM_REQUEST_SENDER: elif CUSTOM_REQUEST_SENDER:
# noinspection PyCallingNonCallable
result = CUSTOM_REQUEST_SENDER( result = CUSTOM_REQUEST_SENDER(
method, request_url, params=params, files=files, method, request_url, params=params, files=files,
timeout=(connect_timeout, read_timeout), proxies=proxy) timeout=(connect_timeout, read_timeout), proxies=proxy)
@ -246,6 +247,7 @@ def send_message(
:param timeout: :param timeout:
:param entities: :param entities:
:param allow_sending_without_reply: :param allow_sending_without_reply:
:param protect_content:
:return: :return:
""" """
method_url = r'sendMessage' method_url = r'sendMessage'
@ -861,7 +863,8 @@ def send_audio(token, chat_id, audio, caption=None, duration=None, performer=Non
def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_markup=None, parse_mode=None, def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_markup=None, parse_mode=None,
disable_notification=None, timeout=None, caption=None, thumb=None, caption_entities=None, disable_notification=None, timeout=None, caption=None, thumb=None, caption_entities=None,
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None): allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None,
protect_content = None):
method_url = get_method_by_type(data_type) method_url = get_method_by_type(data_type)
payload = {'chat_id': chat_id} payload = {'chat_id': chat_id}
files = None files = None
@ -896,6 +899,8 @@ def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_m
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities)) payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None: if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if method_url == 'sendDocument' and disable_content_type_detection is not None: if method_url == 'sendDocument' and disable_content_type_detection is not None:
payload['disable_content_type_detection'] = disable_content_type_detection payload['disable_content_type_detection'] = disable_content_type_detection
return _make_request(token, method_url, params=payload, files=files, method='post') return _make_request(token, method_url, params=payload, files=files, method='post')
@ -1382,6 +1387,7 @@ def send_invoice(
:param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency :param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest units of the currency. :param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest units of the currency.
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount. At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
:param protect_content:
:return: :return:
""" """
method_url = r'sendInvoice' method_url = r'sendInvoice'

View File

@ -1335,7 +1335,7 @@ class AsyncTeleBot:
""" """
self.current_states = asyncio_handler_backends.StateFile(filename=filename) self.current_states = asyncio_handler_backends.StateFile(filename=filename)
self.current_states._create_dir() self.current_states.create_dir()
async def set_webhook(self, url=None, certificate=None, max_connections=None, allowed_updates=None, ip_address=None, async def set_webhook(self, url=None, certificate=None, max_connections=None, allowed_updates=None, ip_address=None,
drop_pending_updates = None, timeout=None): drop_pending_updates = None, timeout=None):
@ -1790,6 +1790,7 @@ class AsyncTeleBot:
:param timeout: timeout :param timeout: timeout
:param allow_sending_without_reply: :param allow_sending_without_reply:
:param protect_content: :param protect_content:
:param data: deprecated, for backward compatibility
:return: API reply. :return: API reply.
""" """
if data and not(sticker): if data and not(sticker):
@ -1837,13 +1838,16 @@ class AsyncTeleBot:
:param allow_sending_without_reply: :param allow_sending_without_reply:
:param reply_markup: :param reply_markup:
:param timeout: :param timeout:
:param data: function typo miss compatibility: do not use it :param data: deprecated, for backward compatibility
""" """
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
if data and not(video):
# function typo miss compatibility
video = data
return types.Message.de_json( return types.Message.de_json(
await asyncio_helper.send_video( await asyncio_helper.send_video(
self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup, self.token, chat_id, video, duration, caption, reply_to_message_id, reply_markup,
parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height, parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height,
caption_entities, allow_sending_without_reply, protect_content)) caption_entities, allow_sending_without_reply, protect_content))
@ -1873,6 +1877,7 @@ class AsyncTeleBot:
:param thumb: InputFile or String : Thumbnail of the file sent :param thumb: InputFile or String : Thumbnail of the file sent
:param caption: String : Animation caption (may also be used when resending animation by file_id). :param caption: String : Animation caption (may also be used when resending animation by file_id).
:param parse_mode: :param parse_mode:
:param protect_content:
:param reply_to_message_id: :param reply_to_message_id:
:param reply_markup: :param reply_markup:
:param disable_notification: :param disable_notification:
@ -3057,4 +3062,4 @@ class AsyncTeleBot:
:param chat_id: :param chat_id:
""" """
for key, value in kwargs.items(): for key, value in kwargs.items():
await self.current_states._add_data(chat_id, key, value) await self.current_states.add_data(chat_id, key, value)

View File

@ -28,7 +28,7 @@ class StateMemory:
"""Delete a state""" """Delete a state"""
self._states.pop(chat_id) self._states.pop(chat_id)
def _get_data(self, chat_id): def get_data(self, chat_id):
return self._states[chat_id]['data'] return self._states[chat_id]['data']
async def set(self, chat_id, new_state): async def set(self, chat_id, new_state):
@ -39,7 +39,7 @@ class StateMemory:
""" """
await self.add_state(chat_id,new_state) await self.add_state(chat_id,new_state)
async def _add_data(self, chat_id, key, value): async def add_data(self, chat_id, key, value):
result = self._states[chat_id]['data'][key] = value result = self._states[chat_id]['data'][key] = value
return result return result
@ -77,28 +77,28 @@ class StateFile:
:param chat_id: :param chat_id:
:param state: new state :param state: new state
""" """
states_data = self._read_data() states_data = self.read_data()
if chat_id in states_data: if chat_id in states_data:
states_data[chat_id]['state'] = state states_data[chat_id]['state'] = state
return await self._save_data(states_data) return await self.save_data(states_data)
else: else:
new_data = states_data[chat_id] = {'state': state,'data': {}} states_data[chat_id] = {'state': state,'data': {}}
return await self._save_data(states_data) return await self.save_data(states_data)
async def current_state(self, chat_id): async def current_state(self, chat_id):
"""Current state.""" """Current state."""
states_data = self._read_data() states_data = self.read_data()
if chat_id in states_data: return states_data[chat_id]['state'] if chat_id in states_data: return states_data[chat_id]['state']
else: return False else: return False
async def delete_state(self, chat_id): async def delete_state(self, chat_id):
"""Delete a state""" """Delete a state"""
states_data = self._read_data() states_data = self.read_data()
states_data.pop(chat_id) states_data.pop(chat_id)
await self._save_data(states_data) await self.save_data(states_data)
def _read_data(self): def read_data(self):
""" """
Read the data from file. Read the data from file.
""" """
@ -107,7 +107,7 @@ class StateFile:
file.close() file.close()
return states_data return states_data
def _create_dir(self): def create_dir(self):
""" """
Create directory .save-handlers. Create directory .save-handlers.
""" """
@ -117,7 +117,7 @@ class StateFile:
with open(self.file_path,'wb') as file: with open(self.file_path,'wb') as file:
pickle.dump({}, file) pickle.dump({}, file)
async def _save_data(self, new_data): async def save_data(self, new_data):
""" """
Save data after editing. Save data after editing.
:param new_data: :param new_data:
@ -126,8 +126,8 @@ class StateFile:
pickle.dump(new_data, state_file, protocol=pickle.HIGHEST_PROTOCOL) pickle.dump(new_data, state_file, protocol=pickle.HIGHEST_PROTOCOL)
return True return True
def _get_data(self, chat_id): def get_data(self, chat_id):
return self._read_data()[chat_id]['data'] return self.read_data()[chat_id]['data']
async def set(self, chat_id, new_state): async def set(self, chat_id, new_state):
""" """
@ -138,10 +138,10 @@ class StateFile:
""" """
await self.add_state(chat_id,new_state) await self.add_state(chat_id,new_state)
async def _add_data(self, chat_id, key, value): async def add_data(self, chat_id, key, value):
states_data = self._read_data() states_data = self.read_data()
result = states_data[chat_id]['data'][key] = value result = states_data[chat_id]['data'][key] = value
await self._save_data(result) await self.save_data(result)
return result return result
@ -173,7 +173,7 @@ class StateContext:
def __init__(self , obj: StateMemory, chat_id) -> None: def __init__(self , obj: StateMemory, chat_id) -> None:
self.obj = obj self.obj = obj
self.chat_id = chat_id self.chat_id = chat_id
self.data = obj._get_data(chat_id) self.data = obj.get_data(chat_id)
async def __aenter__(self): async def __aenter__(self):
return self.data return self.data
@ -191,14 +191,14 @@ class StateFileContext:
self.data = None self.data = None
async def __aenter__(self): async def __aenter__(self):
self.data = self.obj._get_data(self.chat_id) self.data = self.obj.get_data(self.chat_id)
return self.data return self.data
async def __aexit__(self, exc_type, exc_val, exc_tb): async def __aexit__(self, exc_type, exc_val, exc_tb):
old_data = self.obj._read_data() old_data = self.obj.read_data()
for i in self.data: for i in self.data:
old_data[self.chat_id]['data'][i] = self.data.get(i) old_data[self.chat_id]['data'][i] = self.data.get(i)
await self.obj._save_data(old_data) await self.obj.save_data(old_data)
return return

View File

@ -1,8 +1,6 @@
import asyncio # for future uses import asyncio # for future uses
from time import time
import aiohttp import aiohttp
from telebot import types from telebot import types
import json
try: try:
import ujson as json import ujson as json
@ -853,6 +851,8 @@ async def send_data(token, chat_id, data, data_type, reply_to_message_id=None, r
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities)) payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None: if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if method_url == 'sendDocument' and disable_content_type_detection is not None: if method_url == 'sendDocument' and disable_content_type_detection is not None:
payload['disable_content_type_detection'] = disable_content_type_detection payload['disable_content_type_detection'] = disable_content_type_detection
return await _process_request(token, method_url, params=payload, files=files, method='post') return await _process_request(token, method_url, params=payload, files=files, method='post')

View File

@ -168,7 +168,7 @@ class StateMemory:
"""Delete a state""" """Delete a state"""
self._states.pop(chat_id) self._states.pop(chat_id)
def _get_data(self, chat_id): def get_data(self, chat_id):
return self._states[chat_id]['data'] return self._states[chat_id]['data']
def set(self, chat_id, new_state): def set(self, chat_id, new_state):
@ -179,7 +179,7 @@ class StateMemory:
""" """
self.add_state(chat_id,new_state) self.add_state(chat_id,new_state)
def _add_data(self, chat_id, key, value): def add_data(self, chat_id, key, value):
result = self._states[chat_id]['data'][key] = value result = self._states[chat_id]['data'][key] = value
return result return result
@ -217,28 +217,27 @@ class StateFile:
:param chat_id: :param chat_id:
:param state: new state :param state: new state
""" """
states_data = self._read_data() states_data = self.read_data()
if chat_id in states_data: if chat_id in states_data:
states_data[chat_id]['state'] = state states_data[chat_id]['state'] = state
return self._save_data(states_data) return self.save_data(states_data)
else: else:
new_data = states_data[chat_id] = {'state': state,'data': {}} states_data[chat_id] = {'state': state,'data': {}}
return self._save_data(states_data) return self.save_data(states_data)
def current_state(self, chat_id): def current_state(self, chat_id):
"""Current state.""" """Current state."""
states_data = self._read_data() states_data = self.read_data()
if chat_id in states_data: return states_data[chat_id]['state'] if chat_id in states_data: return states_data[chat_id]['state']
else: return False else: return False
def delete_state(self, chat_id): def delete_state(self, chat_id):
"""Delete a state""" """Delete a state"""
states_data = self._read_data() states_data = self.read_data()
states_data.pop(chat_id) states_data.pop(chat_id)
self._save_data(states_data) self.save_data(states_data)
def _read_data(self): def read_data(self):
""" """
Read the data from file. Read the data from file.
""" """
@ -247,7 +246,7 @@ class StateFile:
file.close() file.close()
return states_data return states_data
def _create_dir(self): def create_dir(self):
""" """
Create directory .save-handlers. Create directory .save-handlers.
""" """
@ -257,7 +256,7 @@ class StateFile:
with open(self.file_path,'wb') as file: with open(self.file_path,'wb') as file:
pickle.dump({}, file) pickle.dump({}, file)
def _save_data(self, new_data): def save_data(self, new_data):
""" """
Save data after editing. Save data after editing.
:param new_data: :param new_data:
@ -266,23 +265,21 @@ class StateFile:
pickle.dump(new_data, state_file, protocol=pickle.HIGHEST_PROTOCOL) pickle.dump(new_data, state_file, protocol=pickle.HIGHEST_PROTOCOL)
return True return True
def _get_data(self, chat_id): def get_data(self, chat_id):
return self._read_data()[chat_id]['data'] return self.read_data()[chat_id]['data']
def set(self, chat_id, new_state): def set(self, chat_id, new_state):
""" """
Set a new state for a user. Set a new state for a user.
:param chat_id: :param chat_id:
:param new_state: new_state of a user :param new_state: new_state of a user
""" """
self.add_state(chat_id,new_state) self.add_state(chat_id,new_state)
def _add_data(self, chat_id, key, value): def add_data(self, chat_id, key, value):
states_data = self._read_data() states_data = self.read_data()
result = states_data[chat_id]['data'][key] = value result = states_data[chat_id]['data'][key] = value
self._save_data(result) self.save_data(result)
return result return result
def finish(self, chat_id): def finish(self, chat_id):
@ -313,7 +310,7 @@ class StateContext:
def __init__(self , obj: StateMemory, chat_id) -> None: def __init__(self , obj: StateMemory, chat_id) -> None:
self.obj = obj self.obj = obj
self.chat_id = chat_id self.chat_id = chat_id
self.data = obj._get_data(chat_id) self.data = obj.get_data(chat_id)
def __enter__(self): def __enter__(self):
return self.data return self.data
@ -321,6 +318,7 @@ class StateContext:
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
return return
class StateFileContext: class StateFileContext:
""" """
Class for data. Class for data.
@ -328,15 +326,14 @@ class StateFileContext:
def __init__(self , obj: StateFile, chat_id) -> None: def __init__(self , obj: StateFile, chat_id) -> None:
self.obj = obj self.obj = obj
self.chat_id = chat_id self.chat_id = chat_id
self.data = self.obj._get_data(self.chat_id) self.data = self.obj.get_data(self.chat_id)
def __enter__(self): def __enter__(self):
return self.data return self.data
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
old_data = self.obj._read_data() old_data = self.obj.read_data()
for i in self.data: for i in self.data:
old_data[self.chat_id]['data'][i] = self.data.get(i) old_data[self.chat_id]['data'][i] = self.data.get(i)
self.obj._save_data(old_data) self.obj.save_data(old_data)
return return

View File

@ -4,6 +4,7 @@ import re
import string import string
import threading import threading
import traceback import traceback
import warnings
from typing import Any, Callable, List, Dict, Optional, Union from typing import Any, Callable, List, Dict, Optional, Union
# noinspection PyPep8Naming # noinspection PyPep8Naming
@ -436,7 +437,7 @@ def generate_random_token():
return ''.join(random.sample(string.ascii_letters, 16)) return ''.join(random.sample(string.ascii_letters, 16))
def deprecated(warn: bool=False, alternative: Optional[Callable]=None): def deprecated(warn: bool=True, alternative: Optional[Callable]=None):
""" """
Use this decorator to mark functions as deprecated. Use this decorator to mark functions as deprecated.
When the function is used, an info (or warning if `warn` is True) is logged. When the function is used, an info (or warning if `warn` is True) is logged.
@ -445,12 +446,11 @@ def deprecated(warn: bool=False, alternative: Optional[Callable]=None):
""" """
def decorator(function): def decorator(function):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
info = f"`{function.__name__}` is deprecated." + (f" Use `{alternative.__name__}` instead" if alternative else "")
if not warn: if not warn:
logger.info(f"`{function.__name__}` is deprecated." logger.info(info)
+ (f" Use `{alternative.__name__}` instead" if alternative else ""))
else: else:
logger.warn(f"`{function.__name__}` is deprecated." logger.warning(info)
+ (f" Use `{alternative.__name__}` instead" if alternative else ""))
return function(*args, **kwargs) return function(*args, **kwargs)
return wrapper return wrapper
return decorator return decorator
@ -484,6 +484,7 @@ def antiflood(function, *args, **kwargs):
""" """
from telebot.apihelper import ApiTelegramException from telebot.apihelper import ApiTelegramException
from time import sleep from time import sleep
msg = None
try: try:
msg = function(*args, **kwargs) msg = function(*args, **kwargs)
except ApiTelegramException as ex: except ApiTelegramException as ex:
@ -491,4 +492,4 @@ def antiflood(function, *args, **kwargs):
sleep(ex.result_json['parameters']['retry_after']) sleep(ex.result_json['parameters']['retry_after'])
msg = function(*args, **kwargs) msg = function(*args, **kwargs)
finally: finally:
return msg return msg

View File

@ -1,3 +1,3 @@
# Versions should comply with PEP440. # Versions should comply with PEP440.
# This line is parsed in setup.py: # This line is parsed in setup.py:
__version__ = '4.3.0' __version__ = '4.3.1'

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
import warnings
sys.path.append('../') sys.path.append('../')
@ -19,14 +20,19 @@ if not should_skip:
CHAT_ID = os.environ['CHAT_ID'] CHAT_ID = os.environ['CHAT_ID']
GROUP_ID = os.environ['GROUP_ID'] GROUP_ID = os.environ['GROUP_ID']
def _new_test():
pass
@util.deprecated(alternative=_new_test) def deprecated1_new_function():
def _test(): print("deprecated1_new_function")
pass def deprecated1_old_function():
print("deprecated1_old_function")
warnings.warn("The 'deprecated1_old_function' is deprecated. Use `deprecated1_new_function` instead", DeprecationWarning, 2)
deprecated1_new_function()
def deprecated2_new_function():
print("deprecated2_new_function")
@util.deprecated(alternative=deprecated2_new_function)
def deprecated2_old_function():
print("deprecated2_old_function")
@pytest.mark.skipif(should_skip, reason="No environment variables configured") @pytest.mark.skipif(should_skip, reason="No environment variables configured")
class TestTeleBot: class TestTeleBot:
@ -216,7 +222,7 @@ class TestTeleBot:
def test_send_audio(self): def test_send_audio(self):
file_data = open('./test_data/record.mp3', 'rb') file_data = open('./test_data/record.mp3', 'rb')
tb = telebot.TeleBot(TOKEN) tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_audio(CHAT_ID, file_data, 1, performer='eternnoir', title='pyTelegram') ret_msg = tb.send_audio(CHAT_ID, file_data, duration = 1, performer='eternnoir', title='pyTelegram')
assert ret_msg.content_type == 'audio' assert ret_msg.content_type == 'audio'
assert ret_msg.audio.performer == 'eternnoir' assert ret_msg.audio.performer == 'eternnoir'
assert ret_msg.audio.title == 'pyTelegram' assert ret_msg.audio.title == 'pyTelegram'
@ -224,7 +230,7 @@ class TestTeleBot:
def test_send_audio_dis_noti(self): def test_send_audio_dis_noti(self):
file_data = open('./test_data/record.mp3', 'rb') file_data = open('./test_data/record.mp3', 'rb')
tb = telebot.TeleBot(TOKEN) tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_audio(CHAT_ID, file_data, 1, performer='eternnoir', title='pyTelegram', ret_msg = tb.send_audio(CHAT_ID, file_data, duration = 1, performer='eternnoir', title='pyTelegram',
disable_notification=True) disable_notification=True)
assert ret_msg.content_type == 'audio' assert ret_msg.content_type == 'audio'
assert ret_msg.audio.performer == 'eternnoir' assert ret_msg.audio.performer == 'eternnoir'
@ -433,8 +439,10 @@ class TestTeleBot:
def test_create_revoke_detailed_chat_invite_link(self): def test_create_revoke_detailed_chat_invite_link(self):
tb = telebot.TeleBot(TOKEN) tb = telebot.TeleBot(TOKEN)
cil = tb.create_chat_invite_link(GROUP_ID, cil = tb.create_chat_invite_link(
(datetime.now() + timedelta(minutes=1)).timestamp(), member_limit=5) GROUP_ID,
expire_date = datetime.now() + timedelta(minutes=1),
member_limit=5)
assert isinstance(cil.invite_link, str) assert isinstance(cil.invite_link, str)
assert cil.creator.id == tb.get_me().id assert cil.creator.id == tb.get_me().id
assert isinstance(cil.expire_date, (float, int)) assert isinstance(cil.expire_date, (float, int))
@ -456,11 +464,12 @@ class TestTeleBot:
assert new_msg.message_id assert new_msg.message_id
def test_antiflood(self): def test_antiflood(self):
text = "Flooding" text = "Testing antiflood function"
tb = telebot.TeleBot(TOKEN) tb = telebot.TeleBot(TOKEN)
for _ in range(0,100): i = -1
for i in range(0,200):
util.antiflood(tb.send_message, CHAT_ID, text) util.antiflood(tb.send_message, CHAT_ID, text)
assert _ assert i == 199
@staticmethod @staticmethod
def create_text_message(text): def create_text_message(text):
@ -579,14 +588,14 @@ class TestTeleBot:
ret_msg = tb.set_my_commands([telebot.types.BotCommand(command, description)], scope, lang) ret_msg = tb.set_my_commands([telebot.types.BotCommand(command, description)], scope, lang)
assert ret_msg is True assert ret_msg is True
ret_msg = tb.get_my_commands(scope, lang) ret_msg = tb.get_my_commands(scope = scope, language_code = lang)
assert ret_msg[0].command == command assert ret_msg[0].command == command
assert ret_msg[0].description == description assert ret_msg[0].description == description
ret_msg = tb.delete_my_commands(scope, lang) ret_msg = tb.delete_my_commands(scope = scope, language_code = lang)
assert ret_msg is True assert ret_msg is True
ret_msg = tb.get_my_commands(scope, lang) ret_msg = tb.get_my_commands(scope = scope, language_code = lang)
assert ret_msg == [] assert ret_msg == []
@ -633,7 +642,8 @@ class TestTeleBot:
assert update.message.text == 'got' * 2 assert update.message.text == 'got' * 2
def test_deprecated_dec(self): def test_deprecated_dec(self):
_test() deprecated1_old_function()
deprecated2_old_function()
def test_chat_permissions(self): def test_chat_permissions(self):
return # CHAT_ID is private chat, no permissions can be set return # CHAT_ID is private chat, no permissions can be set