diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index 011ff46..0e1deae 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -1335,7 +1335,7 @@ class AsyncTeleBot: """ 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, drop_pending_updates = None, timeout=None): @@ -1790,6 +1790,7 @@ class AsyncTeleBot: :param timeout: timeout :param allow_sending_without_reply: :param protect_content: + :param data: deprecated, for backward compatibility :return: API reply. """ if data and not(sticker): @@ -1837,13 +1838,16 @@ class AsyncTeleBot: :param allow_sending_without_reply: :param reply_markup: :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 + if data and not(video): + # function typo miss compatibility + video = data return types.Message.de_json( 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, 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 caption: String : Animation caption (may also be used when resending animation by file_id). :param parse_mode: + :param protect_content: :param reply_to_message_id: :param reply_markup: :param disable_notification: @@ -3057,4 +3062,4 @@ class AsyncTeleBot: :param chat_id: """ for key, value in kwargs.items(): - await self.current_states._add_data(chat_id, key, value) \ No newline at end of file + await self.current_states.add_data(chat_id, key, value) diff --git a/telebot/asyncio_handler_backends.py b/telebot/asyncio_handler_backends.py index d3c452f..0a78a90 100644 --- a/telebot/asyncio_handler_backends.py +++ b/telebot/asyncio_handler_backends.py @@ -28,7 +28,7 @@ class StateMemory: """Delete a state""" self._states.pop(chat_id) - def _get_data(self, chat_id): + def get_data(self, chat_id): return self._states[chat_id]['data'] async def set(self, chat_id, new_state): @@ -39,7 +39,7 @@ class StateMemory: """ 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 return result @@ -77,28 +77,28 @@ class StateFile: :param chat_id: :param state: new state """ - states_data = self._read_data() + states_data = self.read_data() if chat_id in states_data: states_data[chat_id]['state'] = state - return await self._save_data(states_data) + return await self.save_data(states_data) else: - new_data = states_data[chat_id] = {'state': state,'data': {}} - return await self._save_data(states_data) + states_data[chat_id] = {'state': state,'data': {}} + return await self.save_data(states_data) async def current_state(self, chat_id): """Current state.""" - states_data = self._read_data() + states_data = self.read_data() if chat_id in states_data: return states_data[chat_id]['state'] else: return False async def delete_state(self, chat_id): """Delete a state""" - states_data = self._read_data() + states_data = self.read_data() 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. """ @@ -107,7 +107,7 @@ class StateFile: file.close() return states_data - def _create_dir(self): + def create_dir(self): """ Create directory .save-handlers. """ @@ -117,7 +117,7 @@ class StateFile: with open(self.file_path,'wb') as file: pickle.dump({}, file) - async def _save_data(self, new_data): + async def save_data(self, new_data): """ Save data after editing. :param new_data: @@ -126,8 +126,8 @@ class StateFile: pickle.dump(new_data, state_file, protocol=pickle.HIGHEST_PROTOCOL) return True - def _get_data(self, chat_id): - return self._read_data()[chat_id]['data'] + def get_data(self, chat_id): + return self.read_data()[chat_id]['data'] async def set(self, chat_id, new_state): """ @@ -138,10 +138,10 @@ class StateFile: """ await self.add_state(chat_id,new_state) - async def _add_data(self, chat_id, key, value): - states_data = self._read_data() + async def add_data(self, chat_id, key, value): + states_data = self.read_data() result = states_data[chat_id]['data'][key] = value - await self._save_data(result) + await self.save_data(result) return result @@ -173,7 +173,7 @@ class StateContext: def __init__(self , obj: StateMemory, chat_id) -> None: self.obj = obj self.chat_id = chat_id - self.data = obj._get_data(chat_id) + self.data = obj.get_data(chat_id) async def __aenter__(self): return self.data @@ -191,14 +191,14 @@ class StateFileContext: self.data = None 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 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: 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 diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index fc02775..e36a974 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -1,8 +1,6 @@ import asyncio # for future uses -from time import time import aiohttp from telebot import types -import json try: 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)) if allow_sending_without_reply is not None: 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: payload['disable_content_type_detection'] = disable_content_type_detection return await _process_request(token, method_url, params=payload, files=files, method='post') diff --git a/telebot/handler_backends.py b/telebot/handler_backends.py index 6f12c35..1e67870 100644 --- a/telebot/handler_backends.py +++ b/telebot/handler_backends.py @@ -276,7 +276,7 @@ class StateFile: """ 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() result = states_data[chat_id]['data'][key] = value self.save_data(result) diff --git a/telebot/util.py b/telebot/util.py index 414fa56..8ec6be6 100644 --- a/telebot/util.py +++ b/telebot/util.py @@ -4,6 +4,7 @@ import re import string import threading import traceback +import warnings from typing import Any, Callable, List, Dict, Optional, Union # noinspection PyPep8Naming @@ -436,7 +437,7 @@ def generate_random_token(): 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. 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 wrapper(*args, **kwargs): + info = f"`{function.__name__}` is deprecated." + (f" Use `{alternative.__name__}` instead" if alternative else "") if not warn: - logger.info(f"`{function.__name__}` is deprecated." - + (f" Use `{alternative.__name__}` instead" if alternative else "")) + logger.info(info) else: - logger.warning(f"`{function.__name__}` is deprecated." - + (f" Use `{alternative.__name__}` instead" if alternative else "")) + logger.warning(info) return function(*args, **kwargs) return wrapper return decorator diff --git a/tests/test_telebot.py b/tests/test_telebot.py index 2976a9a..1a4dc03 100644 --- a/tests/test_telebot.py +++ b/tests/test_telebot.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import sys +import warnings sys.path.append('../') @@ -19,14 +20,19 @@ if not should_skip: CHAT_ID = os.environ['CHAT_ID'] GROUP_ID = os.environ['GROUP_ID'] -def _new_test(): - pass -@util.deprecated(alternative=_new_test) -def _test(): - pass - +def deprecated1_new_function(): + print("deprecated1_new_function") +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") class TestTeleBot: @@ -633,7 +639,8 @@ class TestTeleBot: assert update.message.text == 'got' * 2 def test_deprecated_dec(self): - _test() + deprecated1_old_function() + deprecated2_old_function() def test_chat_permissions(self): return # CHAT_ID is private chat, no permissions can be set