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

Merge pull request #1512 from Badiboy/master

Bot API 6.0. Deprecation fixes
This commit is contained in:
Badiboy 2022-04-23 19:37:01 +03:00 committed by GitHub
commit fa80cb0002
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 100 additions and 87 deletions

View File

@ -17,12 +17,12 @@
# -- Project information -----------------------------------------------------
project = 'pyTelegramBotAPI'
project = 'pyTelegramBotAPI Documentation'
copyright = '2022, coder2020official'
author = 'coder2020official'
# The full version, including alpha/beta/rc tags
release = '4.4.1'
release = '4.5.0'
# -- General configuration ---------------------------------------------------

View File

@ -23,8 +23,8 @@ async def my_chat_m(message: types.ChatMemberUpdated):
#content_Type_service is:
#'new_chat_members', 'left_chat_member', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created',
#'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id', 'migrate_from_chat_id', 'pinned_message',
#'proximity_alert_triggered', 'voice_chat_scheduled', 'voice_chat_started', 'voice_chat_ended',
#'voice_chat_participants_invited', 'message_auto_delete_timer_changed'
#'proximity_alert_triggered', 'video_chat_scheduled', 'video_chat_started', 'video_chat_ended',
#'video_chat_participants_invited', 'message_auto_delete_timer_changed'
# this handler deletes service messages
@bot.message_handler(content_types=util.content_type_service)

View File

@ -23,8 +23,8 @@ def my_chat_m(message: types.ChatMemberUpdated):
#content_Type_service is:
#'new_chat_members', 'left_chat_member', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created',
#'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id', 'migrate_from_chat_id', 'pinned_message',
#'proximity_alert_triggered', 'voice_chat_scheduled', 'voice_chat_started', 'voice_chat_ended',
#'voice_chat_participants_invited', 'message_auto_delete_timer_changed'
#'proximity_alert_triggered', 'video_chat_scheduled', 'video_chat_started', 'video_chat_ended',
#'video_chat_participants_invited', 'message_auto_delete_timer_changed'
# this handler deletes service messages
@bot.message_handler(content_types=util.content_type_service)

View File

@ -38,21 +38,20 @@ def command_pay(message):
"Real cards won't work with me, no money will be debited from your account."
" Use this test card number to pay for your Time Machine: `4242 4242 4242 4242`"
"\n\nThis is your demo invoice:", parse_mode='Markdown')
bot.send_invoice(message.chat.id, title='Working Time Machine',
description='Want to visit your great-great-great-grandparents?'
' Make a fortune at the races?'
' Shake hands with Hammurabi and take a stroll in the Hanging Gardens?'
' Order our Working Time Machine today!',
provider_token=provider_token,
currency='usd',
bot.send_invoice(
message.chat.id, #chat_id
'Working Time Machine', #title
' Want to visit your great-great-great-grandparents? Make a fortune at the races? Shake hands with Hammurabi and take a stroll in the Hanging Gardens? Order our Working Time Machine today!', #description
'HAPPY FRIDAYS COUPON', #invoice_payload
provider_token, #provider_token
'usd', #currency
prices, #prices
photo_url='http://erkelzaar.tsudao.com/models/perrotta/TIME_MACHINE.jpg',
photo_height=512, # !=0/None or picture won't be shown
photo_width=512,
photo_size=512,
is_flexible=False, # True If you need to set up Shipping Fee
prices=prices,
start_parameter='time-machine-example',
invoice_payload='HAPPY FRIDAYS COUPON')
start_parameter='time-machine-example')
@bot.shipping_query_handler(func=lambda query: True)

View File

@ -26,7 +26,8 @@ setup(name='pyTelegramBotAPI',
extras_require={
'json': 'ujson',
'PIL': 'Pillow',
'redis': 'redis>=3.4.1'
'redis': 'redis>=3.4.1',
'aiohttp': 'aiohttp',
},
classifiers=[
'Development Status :: 5 - Production/Stable',

View File

@ -187,8 +187,6 @@ class TeleBot:
compatibility whose purpose was to enable file saving capability for handlers. And the same
implementation is now available with FileHandlerBackend
Most probably this function should be deprecated in future major releases
:param delay: Delay between changes in handlers and saving
:param filename: Filename of save file
"""
@ -211,8 +209,6 @@ class TeleBot:
compatibility whose purpose was to enable file saving capability for handlers. And the same
implementation is now available with FileHandlerBackend
Most probably this function should be deprecated in future major releases
:param delay: Delay between changes in handlers and saving
:param filename: Filename of save file
"""
@ -225,8 +221,6 @@ class TeleBot:
This function is left to keep backward compatibility whose purpose was to disable file saving capability
for handlers. For the same purpose, MemoryHandlerBackend is reassigned as a new next_step_backend backend
instead of FileHandlerBackend.
Most probably this function should be deprecated in future major releases
"""
self.next_step_backend = MemoryHandlerBackend(self.next_step_backend.handlers)
@ -237,8 +231,6 @@ class TeleBot:
This function is left to keep backward compatibility whose purpose was to disable file saving capability
for handlers. For the same purpose, MemoryHandlerBackend is reassigned as a new reply_backend backend
instead of FileHandlerBackend.
Most probably this function should be deprecated in future major releases
"""
self.reply_backend = MemoryHandlerBackend(self.reply_backend.handlers)
@ -250,8 +242,6 @@ class TeleBot:
help of FileHandlerBackend and is only recommended to use if next_step_backend was assigned as
FileHandlerBackend before entering this function
Most probably this function should be deprecated in future major releases
:param filename: Filename of the file where handlers was saved
:param del_file_after_loading: Is passed True, after loading save file will be deleted
"""
@ -265,8 +255,6 @@ class TeleBot:
help of FileHandlerBackend and is only recommended to use if reply_backend was assigned as
FileHandlerBackend before entering this function
Most probably this function should be deprecated in future major releases
:param filename: Filename of the file where handlers was saved
:param del_file_after_loading: Is passed True, after loading save file will be deleted
"""
@ -620,6 +608,7 @@ class TeleBot:
:return:
"""
if none_stop is not None:
logger.warning("polling: none_stop parameter is deprecated. Use non_stop instead.")
non_stop = none_stop
if skip_pending:
@ -887,11 +876,11 @@ class TeleBot:
result = apihelper.get_chat_administrators(self.token, chat_id)
return [types.ChatMember.de_json(r) for r in result]
@util.deprecated(deprecation_text="Use get_chat_member_count instead")
def get_chat_members_count(self, chat_id: Union[int, str]) -> int:
"""
This function is deprecated. Use `get_chat_member_count` instead
"""
logger.info('get_chat_members_count is deprecated. Use get_chat_member_count instead.')
result = apihelper.get_chat_member_count(self.token, chat_id)
return result
@ -1662,6 +1651,7 @@ class TeleBot:
"""
return apihelper.send_chat_action(self.token, chat_id, action, timeout)
@util.deprecated(deprecation_text="Use ban_chat_member instead")
def kick_chat_member(
self, chat_id: Union[int, str], user_id: int,
until_date:Optional[Union[int, datetime]]=None,
@ -1669,7 +1659,6 @@ class TeleBot:
"""
This function is deprecated. Use `ban_chat_member` instead
"""
logger.info('kick_chat_member is deprecated. Use ban_chat_member instead.')
return apihelper.ban_chat_member(self.token, chat_id, user_id, until_date, revoke_messages)
def ban_chat_member(
@ -1805,8 +1794,10 @@ class TeleBot:
:return: True on success.
"""
if can_manage_voice_chats and not can_manage_video_chats is None:
can_manage_video_chats = can_manage_voice_chats
if can_manage_voice_chats is not None:
logger.warning("promote_chat_member: can_manage_voice_chats parameter is deprecated. Use can_manage_video_chats instead.")
if can_manage_video_chats is None:
can_manage_video_chats = can_manage_voice_chats
return apihelper.promote_chat_member(
self.token, chat_id, user_id, can_change_info, can_post_messages,

View File

@ -47,7 +47,6 @@ CUSTOM_REQUEST_SENDER = None
ENABLE_MIDDLEWARE = False
def _get_req_session(reset=False):
if SESSION_TIME_TO_LIVE:
# If session TTL is set - check time passed
@ -94,20 +93,14 @@ def _make_request(token, method_name, method='get', params=None, files=None):
if 'timeout' in params:
read_timeout = params.pop('timeout')
connect_timeout = read_timeout
# if 'connect-timeout' in params:
# connect_timeout = params.pop('connect-timeout') + 10
if 'long_polling_timeout' in params:
# For getUpdates: it's the only function with timeout parameter on the BOT API side
# For getUpdates. It's the only function with timeout parameter on the BOT API side
long_polling_timeout = params.pop('long_polling_timeout')
params['timeout'] = long_polling_timeout
# Long polling hangs for a given time. Read timeout should be greater that long_polling_timeout
read_timeout = max(long_polling_timeout + 5, read_timeout)
# Lets stop suppose that user is stupid and assume that he knows what he do...
# read_timeout = read_timeout + 10
# connect_timeout = connect_timeout + 10
params = params or None # Set params to None if empty
result = None
if RETRY_ON_ERROR and RETRY_ENGINE == 1:
got_result = False
@ -134,6 +127,7 @@ def _make_request(token, method_name, method='get', params=None, files=None):
timeout=(connect_timeout, read_timeout), proxies=proxy)
elif RETRY_ON_ERROR and RETRY_ENGINE == 2:
http = _get_req_session()
# noinspection PyUnresolvedReferences
retry_strategy = requests.packages.urllib3.util.retry.Retry(
total=MAX_RETRIES,
)
@ -1146,7 +1140,6 @@ def set_chat_menu_button(token, chat_id=None, menu_button=None):
payload['chat_id'] = chat_id
if menu_button:
payload['menu_button'] = menu_button.to_json()
return _make_request(token, method_url, params=payload, method='post')
def get_chat_menu_button(token, chat_id=None):
@ -1154,7 +1147,6 @@ def get_chat_menu_button(token, chat_id=None):
payload = {}
if chat_id:
payload['chat_id'] = chat_id
return _make_request(token, method_url, params=payload, method='post')
@ -1163,17 +1155,16 @@ def set_my_default_administrator_rights(token, rights=None, for_channels=None):
payload = {}
if rights:
payload['rights'] = rights.to_json()
if for_channels:
if for_channels is not None:
payload['for_channels'] = for_channels
return _make_request(token, method_url, params=payload, method='post')
def get_my_default_administrator_rights(token, for_channels=None):
method_url = r'getMyDefaultAdministratorRights'
payload = {}
if for_channels:
payload['for_channels'] = for_channels
return _make_request(token, method_url, params=payload, method='post')
@ -1326,7 +1317,6 @@ def send_game(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
@ -1573,7 +1563,6 @@ def create_new_sticker_set(
contains_masks=None, mask_position=None, webm_sticker=None):
method_url = 'createNewStickerSet'
payload = {'user_id': user_id, 'name': name, 'title': title, 'emojis': emojis}
stype = None
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:
@ -1598,7 +1587,6 @@ def create_new_sticker_set(
def add_sticker_to_set(token, user_id, name, emojis, png_sticker, tgs_sticker, mask_position, webm_sticker):
method_url = 'addStickerToSet'
payload = {'user_id': user_id, 'name': name, 'emojis': emojis}
stype = None
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:
@ -1705,7 +1693,6 @@ def _convert_list_json_serializable(results):
return '[' + ret + ']'
def _convert_markup(markup):
if isinstance(markup, types.JsonSerializable):
return markup.to_json()
@ -1778,7 +1765,8 @@ class ApiException(Exception):
super(ApiException, self).__init__("A request to the Telegram API was unsuccessful. {0}".format(msg))
self.function_name = function_name
self.result = result
class ApiHTTPException(ApiException):
"""
This class represents an Exception thrown when a call to the
@ -1790,7 +1778,8 @@ class ApiHTTPException(ApiException):
.format(result.status_code, result.reason, result.text.encode('utf8')),
function_name,
result)
class ApiInvalidJSONException(ApiException):
"""
This class represents an Exception thrown when a call to the
@ -1802,7 +1791,8 @@ class ApiInvalidJSONException(ApiException):
.format(result.text.encode('utf8')),
function_name,
result)
class ApiTelegramException(ApiException):
"""
This class represents an Exception thrown when a Telegram API returns error code.
@ -1816,4 +1806,3 @@ class ApiTelegramException(ApiException):
self.result_json = result_json
self.error_code = result_json['error_code']
self.description = result_json['description']

View File

@ -149,6 +149,7 @@ class AsyncTeleBot:
:return:
"""
if none_stop is not None:
logger.warning("polling: none_stop parameter is deprecated. Use non_stop instead.")
non_stop = none_stop
if skip_pending:
@ -1919,7 +1920,9 @@ class AsyncTeleBot:
"""
if data and not(sticker):
# function typo miss compatibility
logger.warning("send_sticker: data parameter is deprecated. Use sticker instead.")
sticker = data
return types.Message.de_json(
await asyncio_helper.send_data(
self.token, chat_id, sticker, 'sticker',
@ -1970,6 +1973,7 @@ class AsyncTeleBot:
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
if data and not(video):
# function typo miss compatibility
logger.warning("send_sticker: data parameter is deprecated. Use video instead.")
video = data
return types.Message.de_json(
@ -2423,8 +2427,10 @@ class AsyncTeleBot:
:return: True on success.
"""
if can_manage_voice_chats and not can_manage_video_chats is None:
can_manage_video_chats = can_manage_voice_chats
if can_manage_voice_chats is not None:
logger.warning("promote_chat_member: can_manage_voice_chats parameter is deprecated. Use can_manage_video_chats instead.")
if can_manage_video_chats is None:
can_manage_video_chats = can_manage_voice_chats
return await asyncio_helper.promote_chat_member(
self.token, chat_id, user_id, can_change_info, can_post_messages,

View File

@ -11,7 +11,6 @@ API_URL = 'https://api.telegram.org/bot{0}/{1}'
from datetime import datetime
import telebot
from telebot import util, logger
@ -26,8 +25,6 @@ READ_TIMEOUT = 30
LONG_POLLING_TIMEOUT = 10 # Should be positive, short polling should be used for testing purposes only (https://core.telegram.org/bots/api#getupdates)
REQUEST_TIMEOUT = 10
MAX_RETRIES = 3
logger = telebot.logger
REQUEST_LIMIT = 50
@ -1136,7 +1133,7 @@ async def set_my_default_administrator_rights(token, rights=None, for_channels=N
payload = {}
if rights:
payload['rights'] = rights.to_json()
if for_channels:
if for_channels is not None:
payload['for_channels'] = for_channels
return await _process_request(token, method_url, params=payload, method='post')
@ -1543,7 +1540,6 @@ async def create_new_sticker_set(
contains_masks=None, mask_position=None, webm_sticker=None):
method_url = 'createNewStickerSet'
payload = {'user_id': user_id, 'name': name, 'title': title, 'emojis': emojis}
stype = None
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:
@ -1568,7 +1564,6 @@ async def create_new_sticker_set(
async def add_sticker_to_set(token, user_id, name, emojis, png_sticker, tgs_sticker, mask_position, webm_sticker):
method_url = 'addStickerToSet'
payload = {'user_id': user_id, 'name': name, 'emojis': emojis}
stype = None
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:

View File

@ -473,20 +473,20 @@ class Message(JsonDeserializable):
'proximity_alert_triggered'])
content_type = 'proximity_alert_triggered'
if 'video_chat_scheduled' in obj:
opts['video_chat_scheduled'] = VoiceChatScheduled.de_json(obj['video_chat_scheduled'])
opts['voice_chat_scheduled'] = opts['video_chat_scheduled']
opts['video_chat_scheduled'] = VideoChatScheduled.de_json(obj['video_chat_scheduled'])
opts['voice_chat_scheduled'] = opts['video_chat_scheduled'] # deprecated, for backward compatibility
content_type = 'video_chat_scheduled'
if 'video_chat_started' in obj:
opts['video_chat_started'] = VoiceChatStarted.de_json(obj['video_chat_started'])
opts['voice_chat_started'] = opts['video_chat_started']
opts['video_chat_started'] = VideoChatStarted.de_json(obj['video_chat_started'])
opts['voice_chat_started'] = opts['video_chat_started'] # deprecated, for backward compatibility
content_type = 'video_chat_started'
if 'video_chat_ended' in obj:
opts['video_chat_ended'] = VoiceChatEnded.de_json(obj['video_chat_ended'])
opts['voice_chat_ended'] = opts['video_chat_ended']
opts['video_chat_ended'] = VideoChatEnded.de_json(obj['video_chat_ended'])
opts['voice_chat_ended'] = opts['video_chat_ended'] # deprecated, for backward compatibility
content_type = 'video_chat_ended'
if 'video_chat_participants_invited' in obj:
opts['video_chat_participants_invited'] = VoiceChatParticipantsInvited.de_json(obj['video_chat_participants_invited'])
opts['voice_chat_participants_invited'] = opts['video_chat_participants_invited']
opts['video_chat_participants_invited'] = VideoChatParticipantsInvited.de_json(obj['video_chat_participants_invited'])
opts['voice_chat_participants_invited'] = opts['video_chat_participants_invited'] # deprecated, for backward compatibility
content_type = 'video_chat_participants_invited'
if 'web_app_data' in obj:
opts['web_app_data'] = WebAppData.de_json(obj['web_app_data'])
@ -1304,7 +1304,7 @@ class ChatMember(JsonDeserializable):
self.can_add_web_page_previews: bool = can_add_web_page_previews
self.can_manage_chat: bool = can_manage_chat
self.can_manage_video_chats: bool = can_manage_video_chats
self.can_manage_voice_chats: bool = self.can_manage_video_chats
self.can_manage_voice_chats: bool = self.can_manage_video_chats # deprecated, for backward compatibility
self.until_date: int = until_date
@ -1743,11 +1743,14 @@ class SentWebAppMessage(JsonDeserializable):
obj = cls.check_json(json_string)
return cls(**obj)
def __init__(self, inline_message_id):
def __init__(self, inline_message_id=None):
self.inline_message_id = inline_message_id
def to_dict(self):
return {'inline_message_id': self.inline_message_id}
json_dict = {}
if self.inline_message_id:
json_dict['inline_message_id'] = self.inline_message_id
return json_dict
@ -2897,7 +2900,7 @@ class ProximityAlertTriggered(JsonDeserializable):
self.distance: int = distance
class VoiceChatStarted(JsonDeserializable):
class VideoChatStarted(JsonDeserializable):
@classmethod
def de_json(cls, json_string):
return cls()
@ -2909,8 +2912,13 @@ class VoiceChatStarted(JsonDeserializable):
"""
pass
class VoiceChatStarted(VideoChatStarted):
def __init__(self):
logger.warning('VoiceChatStarted is deprecated. Use VideoChatStarted instead.')
super().__init__()
class VoiceChatScheduled(JsonDeserializable):
class VideoChatScheduled(JsonDeserializable):
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
@ -2920,8 +2928,13 @@ class VoiceChatScheduled(JsonDeserializable):
def __init__(self, start_date, **kwargs):
self.start_date: int = start_date
class VoiceChatScheduled(VideoChatScheduled):
def __init__(self, *args, **kwargs):
logger.warning('VoiceChatScheduled is deprecated. Use VideoChatScheduled instead.')
super().__init__(*args, **kwargs)
class VoiceChatEnded(JsonDeserializable):
class VideoChatEnded(JsonDeserializable):
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
@ -2931,8 +2944,14 @@ class VoiceChatEnded(JsonDeserializable):
def __init__(self, duration, **kwargs):
self.duration: int = duration
class VoiceChatEnded(VideoChatEnded):
def __init__(self, *args, **kwargs):
logger.warning('VoiceChatEnded is deprecated. Use VideoChatEnded instead.')
super().__init__(*args, **kwargs)
class VoiceChatParticipantsInvited(JsonDeserializable):
class VideoChatParticipantsInvited(JsonDeserializable):
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
@ -2944,6 +2963,11 @@ class VoiceChatParticipantsInvited(JsonDeserializable):
def __init__(self, users=None, **kwargs):
self.users: List[User] = users
class VoiceChatParticipantsInvited(VideoChatParticipantsInvited):
def __init__(self, *args, **kwargs):
logger.warning('VoiceChatParticipantsInvited is deprecated. Use VideoChatParticipantsInvited instead.')
super().__init__(*args, **kwargs)
class MessageAutoDeleteTimerChanged(JsonDeserializable):
@classmethod
@ -3042,7 +3066,7 @@ class ChatAdministratorRights(JsonDeserializable, JsonSerializable):
self.can_pin_messages: bool = can_pin_messages
def to_dict(self):
data = {
json_dict = {
'is_anonymous': self.is_anonymous,
'can_manage_chat': self.can_manage_chat,
'can_delete_messages': self.can_delete_messages,
@ -3051,11 +3075,14 @@ class ChatAdministratorRights(JsonDeserializable, JsonSerializable):
'can_promote_members': self.can_promote_members,
'can_change_info': self.can_change_info,
'can_invite_users': self.can_invite_users,
'can_post_messages': self.can_post_messages,
'can_edit_messages': self.can_edit_messages,
'can_pin_messages': self.can_pin_messages
}
return data
if 'can_post_messages' is not None:
json_dict['can_post_messages'] = self.can_post_messages
if 'can_edit_messages' is not None:
json_dict['can_edit_messages'] = self.can_edit_messages
if 'can_pin_messages' is not None:
json_dict['can_pin_messages'] = self.can_pin_messages
return json_dict
def to_json(self):
return json.dumps(self.to_dict())

View File

@ -40,8 +40,8 @@ content_type_media = [
content_type_service = [
'new_chat_members', 'left_chat_member', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created',
'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id', 'migrate_from_chat_id', 'pinned_message',
'proximity_alert_triggered', 'voice_chat_scheduled', 'voice_chat_started', 'voice_chat_ended',
'voice_chat_participants_invited', 'message_auto_delete_timer_changed'
'proximity_alert_triggered', 'video_chat_scheduled', 'video_chat_started', 'video_chat_ended',
'video_chat_participants_invited', 'message_auto_delete_timer_changed'
]
update_types = [
@ -449,17 +449,22 @@ def generate_random_token():
return ''.join(random.sample(string.ascii_letters, 16))
def deprecated(warn: bool=True, alternative: Optional[Callable]=None):
def deprecated(warn: bool=True, alternative: Optional[Callable]=None, deprecation_text=None):
"""
Use this decorator to mark functions as deprecated.
When the function is used, an info (or warning if `warn` is True) is logged.
:param warn: If True a warning is logged else an info
:param alternative: The new function to use instead
:param deprecation_text: Custom deprecation text
"""
def decorator(function):
def wrapper(*args, **kwargs):
info = f"`{function.__name__}` is deprecated." + (f" Use `{alternative.__name__}` instead" if alternative else "")
info = f"`{function.__name__}` is deprecated."
if alternative:
info += f" Use `{alternative.__name__}` instead"
if deprecation_text:
info += " " + deprecation_text
if not warn:
logger.info(info)
else:

View File

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