Remove Python 2 Support (#1715)

* Remove usages of python-future lib

* Remove python2 datetime.timezone replacement

* Remove python2 workaround in InputFile.__init__

* Remove import of str necessary for python2

* Remove urllib2 import necessary for python2

* Remove a mention of python 2 in doc

* Remove python 2 from travis config file

* Remove python 2 from appveyor config

* Remove python2 from debian build rules

* Remove unnecessarry aliasing of time.perf_counter

* Remove python 2 from github workflow

* Remove mention of python 2 in descriptions/readme

* Remove version check for queue import

* Remove version checks in tests

* Adjust docs to correctly mention supported version

* Fix indentation

* Remove unused 'sys' imports

* Fix indentation

* Remove references to mq.curtime in tests

* Replace super calls by argumentsless version

* Remove future dependency

* Fix error in de_json declaration

* Use python3 metaclass syntax

* Use implicit inheriting from object

* Remove accidentally committed .vscode folder

* Use nameless f-string and raw string

* Fix regex string literal syntax

* Remove old style classes

* Run pyupgrade

* Fix leftover from automatic merge

* Fix lint errors

* Update telegram/files/sticker.py

Co-authored-by: Bibo-Joshi <hinrich.mahler@freenet.de>
This commit is contained in:
Nils K 2020-06-15 18:20:51 +02:00 committed by GitHub
parent a4e78f6183
commit 8406889179
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
199 changed files with 483 additions and 537 deletions

View file

@ -15,7 +15,7 @@ Depends: ${python3:Depends}, ${misc:Depends}
Description: We have made you a wrapper you can't refuse!
The Python Telegram bot (Python 3)
This library provides a pure Python interface for the Telegram Bot API.
It's compatible with Python versions 2.7, 3.3+ and PyPy.
It's compatible with Python versions 3.5+ and PyPy.
.
In addition to the pure API implementation, this library features
a number of high-level

View file

@ -6,7 +6,7 @@
export PYBUILD_NAME=telegram
%:
DEB_BUILD_OPTIONS=nocheck dh $@ --with python2,python3 --buildsystem=pybuild
DEB_BUILD_OPTIONS=nocheck dh $@ --with python3 --buildsystem=pybuild
# If you need to rebuild the Sphinx documentation

View file

@ -61,7 +61,7 @@ def deep_linked_level_2(update, context):
bot = context.bot
url = helpers.create_deep_linked_url(bot.get_me().username, USING_ENTITIES)
text = "You can also mask the deep-linked URLs as links: " \
"[▶️ CLICK HERE]({0}).".format(url)
"[▶️ CLICK HERE]({}).".format(url)
update.message.reply_text(text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True)
@ -69,7 +69,7 @@ def deep_linked_level_3(update, context):
"""Reached through the USING_ENTITIES payload"""
payload = context.args
update.message.reply_text("Congratulations! This is as deep as it gets 👏🏻\n\n"
"The payload was: {0}".format(payload))
"The payload was: {}".format(payload))
def main():

View file

@ -100,14 +100,14 @@ def show_data(update, context):
text = ''
if level == SELF:
for person in user_data[level]:
text += '\nName: {0}, Age: {1}'.format(person.get(NAME, '-'), person.get(AGE, '-'))
text += '\nName: {}, Age: {}'.format(person.get(NAME, '-'), person.get(AGE, '-'))
else:
male, female = _name_switcher(level)
for person in user_data[level]:
gender = female if person[GENDER] == FEMALE else male
text += '\n{0}: Name: {1}, Age: {2}'.format(gender, person.get(NAME, '-'),
person.get(AGE, '-'))
text += '\n{}: Name: {}, Age: {}'.format(gender, person.get(NAME, '-'),
person.get(AGE, '-'))
return text
ud = context.user_data
@ -307,8 +307,8 @@ def main():
states={
SELECTING_LEVEL: [CallbackQueryHandler(select_gender,
pattern='^{0}$|^{1}$'.format(str(PARENTS),
str(CHILDREN)))],
pattern='^{}$|^{}$'.format(str(PARENTS),
str(CHILDREN)))],
SELECTING_GENDER: [description_conv]
},

View file

@ -1,4 +1,3 @@
future>=0.16.0
certifi
tornado>=5.1
cryptography

View file

@ -20,7 +20,6 @@ import sys
import subprocess
import certifi
import future
from . import __version__ as telegram_ver
@ -37,11 +36,10 @@ def _git_revision():
def print_ver_info():
git_revision = _git_revision()
print('python-telegram-bot {0}'.format(telegram_ver) + (' ({0})'.format(git_revision)
if git_revision else ''))
print('certifi {0}'.format(certifi.__version__))
print('future {0}'.format(future.__version__))
print('Python {0}'.format(sys.version.replace('\n', ' ')))
print('python-telegram-bot {}'.format(telegram_ver) + (' ({})'.format(git_revision)
if git_revision else ''))
print('certifi {}'.format(certifi.__version__))
print('Python {}'.format(sys.version.replace('\n', ' ')))
def main():

View file

@ -24,7 +24,7 @@ except ImportError:
import json
class TelegramObject(object):
class TelegramObject:
"""Base class for most telegram objects."""
_id_attrs = ()
@ -74,9 +74,9 @@ class TelegramObject(object):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self._id_attrs == other._id_attrs
return super(TelegramObject, self).__eq__(other) # pylint: disable=no-member
return super().__eq__(other) # pylint: disable=no-member
def __hash__(self):
if self._id_attrs:
return hash((self.__class__, self._id_attrs)) # pylint: disable=no-member
return super(TelegramObject, self).__hash__()
return super().__hash__()

View file

@ -34,7 +34,6 @@ from datetime import datetime
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from future.utils import string_types
from telegram import (User, Message, Update, Chat, ChatMember, UserProfilePhotos, File,
ReplyMarkup, TelegramObject, WebhookInfo, GameHighScore, StickerSet,
@ -94,7 +93,7 @@ class Bot(TelegramObject):
defaults = kwargs.get('defaults')
# Make an instance of the class
instance = super(Bot, cls).__new__(cls)
instance = super().__new__(cls)
if not defaults:
return instance
@ -266,7 +265,7 @@ class Bot(TelegramObject):
def name(self):
""":obj:`str`: Bot's @username."""
return '@{0}'.format(self.username)
return '@{}'.format(self.username)
@log
def get_me(self, timeout=None, **kwargs):
@ -285,7 +284,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getMe'.format(self.base_url)
url = '{}/getMe'.format(self.base_url)
result = self._request.get(url, timeout=timeout)
@ -335,7 +334,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendMessage'.format(self.base_url)
url = '{}/sendMessage'.format(self.base_url)
data = {'chat_id': chat_id, 'text': text}
@ -380,7 +379,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/deleteMessage'.format(self.base_url)
url = '{}/deleteMessage'.format(self.base_url)
data = {'chat_id': chat_id, 'message_id': message_id}
@ -418,7 +417,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/forwardMessage'.format(self.base_url)
url = '{}/forwardMessage'.format(self.base_url)
data = {}
@ -479,7 +478,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendPhoto'.format(self.base_url)
url = '{}/sendPhoto'.format(self.base_url)
if isinstance(photo, PhotoSize):
photo = photo.file_id
@ -563,7 +562,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendAudio'.format(self.base_url)
url = '{}/sendAudio'.format(self.base_url)
if isinstance(audio, Audio):
audio = audio.file_id
@ -651,7 +650,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendDocument'.format(self.base_url)
url = '{}/sendDocument'.format(self.base_url)
if isinstance(document, Document):
document = document.file_id
@ -714,7 +713,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendSticker'.format(self.base_url)
url = '{}/sendSticker'.format(self.base_url)
if isinstance(sticker, Sticker):
sticker = sticker.file_id
@ -794,7 +793,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendVideo'.format(self.base_url)
url = '{}/sendVideo'.format(self.base_url)
if isinstance(video, Video):
video = video.file_id
@ -877,7 +876,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendVideoNote'.format(self.base_url)
url = '{}/sendVideoNote'.format(self.base_url)
if isinstance(video_note, VideoNote):
video_note = video_note.file_id
@ -957,7 +956,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendAnimation'.format(self.base_url)
url = '{}/sendAnimation'.format(self.base_url)
if isinstance(animation, Animation):
animation = animation.file_id
@ -1038,7 +1037,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendVoice'.format(self.base_url)
url = '{}/sendVoice'.format(self.base_url)
if isinstance(voice, Voice):
voice = voice.file_id
@ -1087,7 +1086,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendMediaGroup'.format(self.base_url)
url = '{}/sendMediaGroup'.format(self.base_url)
data = {'chat_id': chat_id, 'media': media}
@ -1155,7 +1154,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendLocation'.format(self.base_url)
url = '{}/sendLocation'.format(self.base_url)
if not ((latitude is not None and longitude is not None) or location):
raise ValueError("Either location or latitude and longitude must be passed as"
@ -1218,7 +1217,7 @@ class Bot(TelegramObject):
edited Message is returned, otherwise ``True`` is returned.
"""
url = '{0}/editMessageLiveLocation'.format(self.base_url)
url = '{}/editMessageLiveLocation'.format(self.base_url)
if not (all([latitude, longitude]) or location):
raise ValueError("Either location or latitude and longitude must be passed as"
@ -1272,7 +1271,7 @@ class Bot(TelegramObject):
edited Message is returned, otherwise ``True`` is returned.
"""
url = '{0}/stopMessageLiveLocation'.format(self.base_url)
url = '{}/stopMessageLiveLocation'.format(self.base_url)
data = {}
@ -1338,7 +1337,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendVenue'.format(self.base_url)
url = '{}/sendVenue'.format(self.base_url)
if not (venue or all([latitude, longitude, address, title])):
raise ValueError("Either venue or latitude, longitude, address and title must be"
@ -1416,7 +1415,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendContact'.format(self.base_url)
url = '{}/sendContact'.format(self.base_url)
if (not contact) and (not all([phone_number, first_name])):
raise ValueError("Either contact or phone_number and first_name must be passed as"
@ -1474,7 +1473,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendGame'.format(self.base_url)
url = '{}/sendGame'.format(self.base_url)
data = {'chat_id': chat_id, 'game_short_name': game_short_name}
@ -1508,7 +1507,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendChatAction'.format(self.base_url)
url = '{}/sendChatAction'.format(self.base_url)
data = {'chat_id': chat_id, 'action': action}
data.update(kwargs)
@ -1572,7 +1571,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/answerInlineQuery'.format(self.base_url)
url = '{}/answerInlineQuery'.format(self.base_url)
for res in results:
if res._has_parse_mode and res.parse_mode == DEFAULT_NONE:
@ -1638,7 +1637,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getUserProfilePhotos'.format(self.base_url)
url = '{}/getUserProfilePhotos'.format(self.base_url)
data = {'user_id': user_id}
@ -1686,7 +1685,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getFile'.format(self.base_url)
url = '{}/getFile'.format(self.base_url)
try:
file_id = file_id.file_id
@ -1699,7 +1698,7 @@ class Bot(TelegramObject):
result = self._request.post(url, data, timeout=timeout)
if result.get('file_path'):
result['file_path'] = '%s/%s' % (self.base_file_url, result['file_path'])
result['file_path'] = '{}/{}'.format(self.base_file_url, result['file_path'])
return File.de_json(result, self)
@ -1730,7 +1729,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/kickChatMember'.format(self.base_url)
url = '{}/kickChatMember'.format(self.base_url)
data = {'chat_id': chat_id, 'user_id': user_id}
data.update(kwargs)
@ -1767,7 +1766,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/unbanChatMember'.format(self.base_url)
url = '{}/unbanChatMember'.format(self.base_url)
data = {'chat_id': chat_id, 'user_id': user_id}
data.update(kwargs)
@ -1819,7 +1818,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url_ = '{0}/answerCallbackQuery'.format(self.base_url)
url_ = '{}/answerCallbackQuery'.format(self.base_url)
data = {'callback_query_id': callback_query_id}
@ -1881,7 +1880,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/editMessageText'.format(self.base_url)
url = '{}/editMessageText'.format(self.base_url)
data = {'text': text}
@ -1945,7 +1944,7 @@ class Bot(TelegramObject):
'edit_message_caption: Both chat_id and message_id are required when '
'inline_message_id is not specified')
url = '{0}/editMessageCaption'.format(self.base_url)
url = '{}/editMessageCaption'.format(self.base_url)
data = {}
@ -2007,7 +2006,7 @@ class Bot(TelegramObject):
'edit_message_media: Both chat_id and message_id are required when '
'inline_message_id is not specified')
url = '{0}/editMessageMedia'.format(self.base_url)
url = '{}/editMessageMedia'.format(self.base_url)
data = {'media': media}
@ -2060,7 +2059,7 @@ class Bot(TelegramObject):
'edit_message_reply_markup: Both chat_id and message_id are required when '
'inline_message_id is not specified')
url = '{0}/editMessageReplyMarkup'.format(self.base_url)
url = '{}/editMessageReplyMarkup'.format(self.base_url)
data = {}
@ -2119,7 +2118,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getUpdates'.format(self.base_url)
url = '{}/getUpdates'.format(self.base_url)
data = {'timeout': timeout}
@ -2213,7 +2212,7 @@ class Bot(TelegramObject):
.. _`guide to Webhooks`: https://core.telegram.org/bots/webhooks
"""
url_ = '{0}/setWebhook'.format(self.base_url)
url_ = '{}/setWebhook'.format(self.base_url)
# Backwards-compatibility: 'url' used to be named 'webhook_url'
if 'webhook_url' in kwargs: # pragma: no cover
@ -2263,7 +2262,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/deleteWebhook'.format(self.base_url)
url = '{}/deleteWebhook'.format(self.base_url)
data = kwargs
@ -2290,7 +2289,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/leaveChat'.format(self.base_url)
url = '{}/leaveChat'.format(self.base_url)
data = {'chat_id': chat_id}
data.update(kwargs)
@ -2320,7 +2319,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getChat'.format(self.base_url)
url = '{}/getChat'.format(self.base_url)
data = {'chat_id': chat_id}
data.update(kwargs)
@ -2355,7 +2354,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getChatAdministrators'.format(self.base_url)
url = '{}/getChatAdministrators'.format(self.base_url)
data = {'chat_id': chat_id}
data.update(kwargs)
@ -2383,7 +2382,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getChatMembersCount'.format(self.base_url)
url = '{}/getChatMembersCount'.format(self.base_url)
data = {'chat_id': chat_id}
data.update(kwargs)
@ -2412,7 +2411,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getChatMember'.format(self.base_url)
url = '{}/getChatMember'.format(self.base_url)
data = {'chat_id': chat_id, 'user_id': user_id}
data.update(kwargs)
@ -2443,7 +2442,7 @@ class Bot(TelegramObject):
:obj:`bool`: On success, ``True`` is returned.
"""
url = '{0}/setChatStickerSet'.format(self.base_url)
url = '{}/setChatStickerSet'.format(self.base_url)
data = {'chat_id': chat_id, 'sticker_set_name': sticker_set_name}
@ -2470,7 +2469,7 @@ class Bot(TelegramObject):
:obj:`bool`: On success, ``True`` is returned.
"""
url = '{0}/deleteChatStickerSet'.format(self.base_url)
url = '{}/deleteChatStickerSet'.format(self.base_url)
data = {'chat_id': chat_id}
@ -2493,7 +2492,7 @@ class Bot(TelegramObject):
:class:`telegram.WebhookInfo`
"""
url = '{0}/getWebhookInfo'.format(self.base_url)
url = '{}/getWebhookInfo'.format(self.base_url)
data = kwargs
@ -2542,7 +2541,7 @@ class Bot(TelegramObject):
current score in the chat and force is False.
"""
url = '{0}/setGameScore'.format(self.base_url)
url = '{}/setGameScore'.format(self.base_url)
data = {'user_id': user_id, 'score': score}
@ -2591,7 +2590,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getGameHighScores'.format(self.base_url)
url = '{}/getGameHighScores'.format(self.base_url)
data = {'user_id': user_id}
@ -2692,7 +2691,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendInvoice'.format(self.base_url)
url = '{}/sendInvoice'.format(self.base_url)
data = {
'chat_id': chat_id,
@ -2705,7 +2704,7 @@ class Bot(TelegramObject):
'prices': [p.to_dict() for p in prices]
}
if provider_data is not None:
if isinstance(provider_data, string_types):
if isinstance(provider_data, str):
data['provider_data'] = provider_data
else:
data['provider_data'] = json.dumps(provider_data)
@ -2784,7 +2783,7 @@ class Bot(TelegramObject):
'answerShippingQuery: If ok is False, error_message '
'should not be empty and there should not be shipping_options')
url_ = '{0}/answerShippingQuery'.format(self.base_url)
url_ = '{}/answerShippingQuery'.format(self.base_url)
data = {'shipping_query_id': shipping_query_id, 'ok': ok}
@ -2839,7 +2838,7 @@ class Bot(TelegramObject):
'not be error_message; if ok is False, error_message '
'should not be empty')
url_ = '{0}/answerPreCheckoutQuery'.format(self.base_url)
url_ = '{}/answerPreCheckoutQuery'.format(self.base_url)
data = {'pre_checkout_query_id': pre_checkout_query_id, 'ok': ok}
@ -2884,7 +2883,7 @@ class Bot(TelegramObject):
Raises:
:class:`telegram.TelegramError`
"""
url = '{0}/restrictChatMember'.format(self.base_url)
url = '{}/restrictChatMember'.format(self.base_url)
data = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions.to_dict()}
@ -2943,7 +2942,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/promoteChatMember'.format(self.base_url)
url = '{}/promoteChatMember'.format(self.base_url)
data = {'chat_id': chat_id, 'user_id': user_id}
@ -2992,7 +2991,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/setChatPermissions'.format(self.base_url)
url = '{}/setChatPermissions'.format(self.base_url)
data = {'chat_id': chat_id, 'permissions': permissions.to_dict()}
data.update(kwargs)
@ -3030,7 +3029,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/setChatAdministratorCustomTitle'.format(self.base_url)
url = '{}/setChatAdministratorCustomTitle'.format(self.base_url)
data = {'chat_id': chat_id, 'user_id': user_id, 'custom_title': custom_title}
data.update(kwargs)
@ -3061,7 +3060,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/exportChatInviteLink'.format(self.base_url)
url = '{}/exportChatInviteLink'.format(self.base_url)
data = {'chat_id': chat_id}
data.update(kwargs)
@ -3093,7 +3092,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/setChatPhoto'.format(self.base_url)
url = '{}/setChatPhoto'.format(self.base_url)
if InputFile.is_file(photo):
photo = InputFile(photo)
@ -3127,7 +3126,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/deleteChatPhoto'.format(self.base_url)
url = '{}/deleteChatPhoto'.format(self.base_url)
data = {'chat_id': chat_id}
data.update(kwargs)
@ -3159,7 +3158,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/setChatTitle'.format(self.base_url)
url = '{}/setChatTitle'.format(self.base_url)
data = {'chat_id': chat_id, 'title': title}
data.update(kwargs)
@ -3191,7 +3190,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/setChatDescription'.format(self.base_url)
url = '{}/setChatDescription'.format(self.base_url)
data = {'chat_id': chat_id, 'description': description}
data.update(kwargs)
@ -3228,7 +3227,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/pinChatMessage'.format(self.base_url)
url = '{}/pinChatMessage'.format(self.base_url)
data = {'chat_id': chat_id, 'message_id': message_id}
@ -3263,7 +3262,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/unpinChatMessage'.format(self.base_url)
url = '{}/unpinChatMessage'.format(self.base_url)
data = {'chat_id': chat_id}
data.update(kwargs)
@ -3290,7 +3289,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getStickerSet'.format(self.base_url)
url = '{}/getStickerSet'.format(self.base_url)
data = {'name': name}
data.update(kwargs)
@ -3327,7 +3326,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/uploadStickerFile'.format(self.base_url)
url = '{}/uploadStickerFile'.format(self.base_url)
if InputFile.is_file(png_sticker):
png_sticker = InputFile(png_sticker)
@ -3392,7 +3391,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/createNewStickerSet'.format(self.base_url)
url = '{}/createNewStickerSet'.format(self.base_url)
if InputFile.is_file(png_sticker):
png_sticker = InputFile(png_sticker)
@ -3464,7 +3463,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/addStickerToSet'.format(self.base_url)
url = '{}/addStickerToSet'.format(self.base_url)
if InputFile.is_file(png_sticker):
png_sticker = InputFile(png_sticker)
@ -3507,7 +3506,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/setStickerPositionInSet'.format(self.base_url)
url = '{}/setStickerPositionInSet'.format(self.base_url)
data = {'sticker': sticker, 'position': position}
data.update(kwargs)
@ -3534,7 +3533,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/deleteStickerFromSet'.format(self.base_url)
url = '{}/deleteStickerFromSet'.format(self.base_url)
data = {'sticker': sticker}
data.update(kwargs)
@ -3613,7 +3612,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url_ = '{0}/setPassportDataErrors'.format(self.base_url)
url_ = '{}/setPassportDataErrors'.format(self.base_url)
data = {'user_id': user_id, 'errors': [error.to_dict() for error in errors]}
data.update(kwargs)
@ -3690,7 +3689,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendPoll'.format(self.base_url)
url = '{}/sendPoll'.format(self.base_url)
data = {
'chat_id': chat_id,
@ -3758,7 +3757,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/stopPoll'.format(self.base_url)
url = '{}/stopPoll'.format(self.base_url)
data = {
'chat_id': chat_id,
@ -3813,7 +3812,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/sendDice'.format(self.base_url)
url = '{}/sendDice'.format(self.base_url)
data = {
'chat_id': chat_id,
@ -3844,7 +3843,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/getMyCommands'.format(self.base_url)
url = '{}/getMyCommands'.format(self.base_url)
result = self._request.get(url, timeout=timeout)
@ -3873,7 +3872,7 @@ class Bot(TelegramObject):
:class:`telegram.TelegramError`
"""
url = '{0}/setMyCommands'.format(self.base_url)
url = '{}/setMyCommands'.format(self.base_url)
cmds = [c if isinstance(c, BotCommand) else BotCommand(c[0], c[1]) for c in commands]

View file

@ -99,7 +99,7 @@ class CallbackQuery(TelegramObject):
if not data:
return None
data = super(CallbackQuery, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['from_user'] = User.de_json(data.get('from'), bot)
message = data.get('message')

View file

@ -20,7 +20,7 @@
"""This module contains an object that represents a Telegram ChatAction."""
class ChatAction(object):
class ChatAction:
"""Helper class to provide constants for different chatactions."""
FIND_LOCATION = 'find_location'

View file

@ -150,7 +150,7 @@ class ChatMember(TelegramObject):
if not data:
return None
data = super(ChatMember, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['user'] = User.de_json(data.get('user'), bot)
data['until_date'] = from_timestamp(data.get('until_date', None))
@ -158,7 +158,7 @@ class ChatMember(TelegramObject):
return cls(**data)
def to_dict(self):
data = super(ChatMember, self).to_dict()
data = super().to_dict()
data['until_date'] = to_timestamp(self.until_date)

View file

@ -72,7 +72,7 @@ class ChosenInlineResult(TelegramObject):
if not data:
return None
data = super(ChosenInlineResult, cls).de_json(data, bot)
data = super().de_json(data, bot)
# Required
data['from_user'] = User.de_json(data.pop('from'), bot)
# Optionals

View file

@ -38,7 +38,7 @@ def _lstrip_str(in_s, lstr):
class TelegramError(Exception):
def __init__(self, message):
super(TelegramError, self).__init__()
super().__init__()
msg = _lstrip_str(message, 'Error: ')
msg = _lstrip_str(msg, '[Error]: ')
@ -58,7 +58,7 @@ class Unauthorized(TelegramError):
class InvalidToken(TelegramError):
def __init__(self):
super(InvalidToken, self).__init__('Invalid token')
super().__init__('Invalid token')
class NetworkError(TelegramError):
@ -71,7 +71,7 @@ class BadRequest(NetworkError):
class TimedOut(NetworkError):
def __init__(self):
super(TimedOut, self).__init__('Timed out')
super().__init__('Timed out')
class ChatMigrated(TelegramError):
@ -82,8 +82,7 @@ class ChatMigrated(TelegramError):
"""
def __init__(self, new_chat_id):
super(ChatMigrated,
self).__init__('Group migrated to supergroup. New chat id: {}'.format(new_chat_id))
super().__init__('Group migrated to supergroup. New chat id: {}'.format(new_chat_id))
self.new_chat_id = new_chat_id
@ -95,8 +94,7 @@ class RetryAfter(TelegramError):
"""
def __init__(self, retry_after):
super(RetryAfter,
self).__init__('Flood control exceeded. Retry in {} seconds'.format(retry_after))
super().__init__('Flood control exceeded. Retry in {} seconds'.format(retry_after))
self.retry_after = float(retry_after)
@ -110,4 +108,4 @@ class Conflict(TelegramError):
"""
def __init__(self, msg):
super(Conflict, self).__init__(msg)
super().__init__(msg)

View file

@ -21,7 +21,7 @@
from telegram import Update
class CallbackContext(object):
class CallbackContext:
"""
This is a context object passed to the callback called by :class:`telegram.ext.Handler`
or by the :class:`telegram.ext.Dispatcher` in an error handler added by

View file

@ -20,8 +20,6 @@
import re
from future.utils import string_types
from telegram import Update
from .handler import Handler
@ -105,14 +103,14 @@ class CallbackQueryHandler(Handler):
pass_groupdict=False,
pass_user_data=False,
pass_chat_data=False):
super(CallbackQueryHandler, self).__init__(
super().__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
if isinstance(pattern, string_types):
if isinstance(pattern, str):
pattern = re.compile(pattern)
self.pattern = pattern
@ -139,9 +137,7 @@ class CallbackQueryHandler(Handler):
return True
def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(CallbackQueryHandler, self).collect_optional_args(dispatcher,
update,
check_result)
optional_args = super().collect_optional_args(dispatcher, update, check_result)
if self.pattern:
if self.pass_groups:
optional_args['groups'] = check_result.groups()

View file

@ -20,8 +20,6 @@
import re
import warnings
from future.utils import string_types
from telegram.ext import Filters
from telegram.utils.deprecate import TelegramDeprecationWarning
@ -125,14 +123,14 @@ class CommandHandler(Handler):
pass_job_queue=False,
pass_user_data=False,
pass_chat_data=False):
super(CommandHandler, self).__init__(
super().__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
if isinstance(command, string_types):
if isinstance(command, str):
self.command = [command.lower()]
else:
self.command = [x.lower() for x in command]
@ -184,7 +182,7 @@ class CommandHandler(Handler):
return False
def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(CommandHandler, self).collect_optional_args(dispatcher, update)
optional_args = super().collect_optional_args(dispatcher, update)
if self.pass_args:
optional_args['args'] = check_result[0]
return optional_args
@ -306,7 +304,7 @@ class PrefixHandler(CommandHandler):
self._command = list()
self._commands = list()
super(PrefixHandler, self).__init__(
super().__init__(
'nocommand', callback, filters=filters, allow_edited=None, pass_args=pass_args,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
@ -323,7 +321,7 @@ class PrefixHandler(CommandHandler):
@prefix.setter
def prefix(self, prefix):
if isinstance(prefix, string_types):
if isinstance(prefix, str):
self._prefix = [prefix.lower()]
else:
self._prefix = prefix
@ -335,7 +333,7 @@ class PrefixHandler(CommandHandler):
@command.setter
def command(self, command):
if isinstance(command, string_types):
if isinstance(command, str):
self._command = [command.lower()]
else:
self._command = command

View file

@ -28,7 +28,7 @@ from telegram.ext import (Handler, CallbackQueryHandler, InlineQueryHandler,
from telegram.utils.promise import Promise
class _ConversationTimeoutContext(object):
class _ConversationTimeoutContext:
def __init__(self, conversation_key, update, dispatcher, callback_context):
self.conversation_key = conversation_key
self.update = update
@ -404,7 +404,7 @@ class ConversationHandler(Handler):
return key, handler, check
return None
self.logger.debug('selecting conversation %s with state %s' % (str(key), str(state)))
self.logger.debug('selecting conversation {} with state {}'.format(str(key), str(state)))
handler = None

View file

@ -66,9 +66,9 @@ class DictPersistence(BasePersistence):
chat_data_json='',
bot_data_json='',
conversations_json=''):
super(DictPersistence, self).__init__(store_user_data=store_user_data,
store_chat_data=store_chat_data,
store_bot_data=store_bot_data)
super().__init__(store_user_data=store_user_data,
store_chat_data=store_chat_data,
store_bot_data=store_bot_data)
self._user_data = None
self._chat_data = None
self._bot_data = None

View file

@ -29,8 +29,6 @@ from collections import defaultdict
from queue import Queue, Empty
from future.builtins import range
from telegram import TelegramError, Update
from telegram.ext.handler import Handler
from telegram.ext.callbackcontext import CallbackContext
@ -66,7 +64,7 @@ class DispatcherHandlerStop(Exception):
pass
class Dispatcher(object):
class Dispatcher:
"""This class dispatches all kinds of updates to its registered handlers.
Attributes:
@ -304,10 +302,10 @@ class Dispatcher(object):
self.__async_queue.put(None)
for i, thr in enumerate(threads):
self.logger.debug('Waiting for async thread {0}/{1} to end'.format(i + 1, total))
self.logger.debug('Waiting for async thread {}/{} to end'.format(i + 1, total))
thr.join()
self.__async_threads.remove(thr)
self.logger.debug('async thread {0}/{1} has ended'.format(i + 1, total))
self.logger.debug('async thread {}/{} has ended'.format(i + 1, total))
@property
def has_running_threads(self):
@ -391,7 +389,7 @@ class Dispatcher(object):
from .conversationhandler import ConversationHandler
if not isinstance(handler, Handler):
raise TypeError('handler is not an instance of {0}'.format(Handler.__name__))
raise TypeError('handler is not an instance of {}'.format(Handler.__name__))
if not isinstance(group, int):
raise TypeError('group is not int')
if isinstance(handler, ConversationHandler) and handler.persistent:

View file

@ -21,7 +21,6 @@
import re
from abc import ABC, abstractmethod
from future.utils import string_types
from threading import Lock
from telegram import Chat, Update, MessageEntity
@ -248,7 +247,7 @@ class _DiceEmoji(BaseFilter):
return True
class Filters(object):
class Filters:
"""Predefined filters for use as the `filter` argument of :class:`telegram.ext.MessageHandler`.
Examples:
@ -426,7 +425,7 @@ class Filters(object):
data_filter = True
def __init__(self, pattern):
if isinstance(pattern, string_types):
if isinstance(pattern, str):
pattern = re.compile(pattern)
self.pattern = pattern
self.name = 'Filters.regex({})'.format(self.pattern)
@ -1306,7 +1305,7 @@ officedocument.wordprocessingml.document")``-
"""
def __init__(self, lang):
if isinstance(lang, string_types):
if isinstance(lang, str):
self.lang = [lang]
else:
self.lang = lang

View file

@ -19,9 +19,8 @@
""" This module contains the InlineQueryHandler class """
import re
from future.utils import string_types
from telegram import Update
from .handler import Handler
@ -104,14 +103,14 @@ class InlineQueryHandler(Handler):
pass_groupdict=False,
pass_user_data=False,
pass_chat_data=False):
super(InlineQueryHandler, self).__init__(
super().__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
if isinstance(pattern, string_types):
if isinstance(pattern, str):
pattern = re.compile(pattern)
self.pattern = pattern
@ -140,8 +139,7 @@ class InlineQueryHandler(Handler):
return True
def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(InlineQueryHandler, self).collect_optional_args(dispatcher,
update, check_result)
optional_args = super().collect_optional_args(dispatcher, update, check_result)
if self.pattern:
if self.pass_groups:
optional_args['groups'] = check_result.groups()

View file

@ -33,12 +33,12 @@ from telegram.utils.deprecate import TelegramDeprecationWarning
from telegram.utils.helpers import to_float_timestamp
class Days(object):
class Days:
MON, TUE, WED, THU, FRI, SAT, SUN = range(7)
EVERY_DAY = tuple(range(7))
class JobQueue(object):
class JobQueue:
"""This class allows you to periodically perform tasks with the bot.
Attributes:
@ -54,7 +54,7 @@ class JobQueue(object):
warnings.warn("Passing bot to jobqueue is deprecated. Please use set_dispatcher "
"instead!", TelegramDeprecationWarning, stacklevel=2)
class MockDispatcher(object):
class MockDispatcher:
def __init__(self):
self.bot = bot
self.use_context = False
@ -492,7 +492,7 @@ class JobQueue(object):
return tuple(job[1] for job in self._queue.queue if job and job[1].name == name)
class Job(object):
class Job:
"""This class encapsulates a Job.
Attributes:

View file

@ -117,7 +117,7 @@ class MessageHandler(Handler):
channel_post_updates=None,
edited_updates=None):
super(MessageHandler, self).__init__(
super().__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,

View file

@ -23,24 +23,9 @@
from telegram.utils import promise
import functools
import sys
import time
import threading
if sys.version_info.major > 2:
import queue as q
else:
import Queue as q
# We need to count < 1s intervals, so the most accurate timer is needed
# Starting from Python 3.3 we have time.perf_counter which is the clock
# with the highest resolution available to the system, so let's use it there.
# In Python 2.7, there's no perf_counter yet, so fallback on what we have:
# on Windows, the best available is time.clock while time.time is on
# another platforms (M. Lutz, "Learning Python," 4ed, p.630-634)
if sys.version_info.major == 3 and sys.version_info.minor >= 3:
curtime = time.perf_counter # pylint: disable=E1101
else:
curtime = time.clock if sys.platform[:3] == 'win' else time.time
import queue as q
class DelayQueueError(RuntimeError):
@ -95,11 +80,11 @@ class DelayQueue(threading.Thread):
self.__exit_req = False # flag to gently exit thread
self.__class__._instcnt += 1
if name is None:
name = '%s-%s' % (self.__class__.__name__, self.__class__._instcnt)
super(DelayQueue, self).__init__(name=name)
name = '{}-{}'.format(self.__class__.__name__, self.__class__._instcnt)
super().__init__(name=name)
self.daemon = False
if autostart: # immediately start processing
super(DelayQueue, self).start()
super().start()
def run(self):
"""
@ -114,7 +99,7 @@ class DelayQueue(threading.Thread):
if self.__exit_req:
return # shutdown thread
# delay routine
now = curtime()
now = time.perf_counter()
t_delta = now - self.time_limit # calculate early to improve perf.
if times and t_delta > times[-1]:
# if last call was before the limit time-window
@ -146,7 +131,7 @@ class DelayQueue(threading.Thread):
self.__exit_req = True # gently request
self._queue.put(None) # put something to unfreeze if frozen
super(DelayQueue, self).join(timeout=timeout)
super().join(timeout=timeout)
@staticmethod
def _default_exception_handler(exc):
@ -180,7 +165,7 @@ class DelayQueue(threading.Thread):
# msg --> group delay if group msg, else no delay --> normal msg delay --> out
# This way OS threading scheduler cares of timings accuracy.
# (see time.time, time.clock, time.perf_counter, time.sleep @ docs.python.org)
class MessageQueue(object):
class MessageQueue:
"""
Implements callback processing with proper delays to avoid hitting Telegram's message limits.
Contains two ``DelayQueue``, for group and for all messages, interconnected in delay chain.

View file

@ -66,9 +66,9 @@ class PicklePersistence(BasePersistence):
store_bot_data=True,
single_file=True,
on_flush=False):
super(PicklePersistence, self).__init__(store_user_data=store_user_data,
store_chat_data=store_chat_data,
store_bot_data=store_bot_data)
super().__init__(store_user_data=store_user_data,
store_chat_data=store_chat_data,
store_bot_data=store_bot_data)
self.filename = filename
self.single_file = single_file
self.on_flush = on_flush

View file

@ -110,21 +110,20 @@ class RegexHandler(MessageHandler):
warnings.warn('RegexHandler is deprecated. See https://git.io/fxJuV for more info',
TelegramDeprecationWarning,
stacklevel=2)
super(RegexHandler, self).__init__(Filters.regex(pattern),
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data,
message_updates=message_updates,
channel_post_updates=channel_post_updates,
edited_updates=edited_updates)
super().__init__(Filters.regex(pattern),
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data,
message_updates=message_updates,
channel_post_updates=channel_post_updates,
edited_updates=edited_updates)
self.pass_groups = pass_groups
self.pass_groupdict = pass_groupdict
def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(RegexHandler, self).collect_optional_args(dispatcher, update,
check_result)
optional_args = super().collect_optional_args(dispatcher, update, check_result)
if self.pass_groups:
optional_args['groups'] = check_result['matches'][0].groups()
if self.pass_groupdict:

View file

@ -18,8 +18,6 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the StringCommandHandler class."""
from future.utils import string_types
from .handler import Handler
@ -73,7 +71,7 @@ class StringCommandHandler(Handler):
pass_args=False,
pass_update_queue=False,
pass_job_queue=False):
super(StringCommandHandler, self).__init__(
super().__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue)
@ -90,15 +88,13 @@ class StringCommandHandler(Handler):
:obj:`bool`
"""
if isinstance(update, string_types) and update.startswith('/'):
if isinstance(update, str) and update.startswith('/'):
args = update[1:].split(' ')
if args[0] == self.command:
return args[1:]
def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(StringCommandHandler, self).collect_optional_args(dispatcher,
update,
check_result)
optional_args = super().collect_optional_args(dispatcher, update, check_result)
if self.pass_args:
optional_args['args'] = check_result
return optional_args

View file

@ -20,8 +20,6 @@
import re
from future.utils import string_types
from .handler import Handler
@ -85,12 +83,12 @@ class StringRegexHandler(Handler):
pass_groupdict=False,
pass_update_queue=False,
pass_job_queue=False):
super(StringRegexHandler, self).__init__(
super().__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue)
if isinstance(pattern, string_types):
if isinstance(pattern, str):
pattern = re.compile(pattern)
self.pattern = pattern
@ -107,14 +105,13 @@ class StringRegexHandler(Handler):
:obj:`bool`
"""
if isinstance(update, string_types):
if isinstance(update, str):
match = re.match(self.pattern, update)
if match:
return match
def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(StringRegexHandler, self).collect_optional_args(dispatcher,
update, check_result)
optional_args = super().collect_optional_args(dispatcher, update, check_result)
if self.pattern:
if self.pass_groups:
optional_args['groups'] = check_result.groups()

View file

@ -65,7 +65,7 @@ class TypeHandler(Handler):
strict=False,
pass_update_queue=False,
pass_job_queue=False):
super(TypeHandler, self).__init__(
super().__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue)

View file

@ -33,7 +33,7 @@ from telegram.utils.request import Request
from telegram.utils.webhookhandler import (WebhookServer, WebhookAppClass)
class Updater(object):
class Updater:
"""
This class, which employs the :class:`telegram.ext.Dispatcher`, provides a frontend to
:class:`telegram.Bot` to the programmer, so they can focus on coding the bot. Its purpose is to
@ -210,14 +210,14 @@ class Updater(object):
def _thread_wrapper(self, target, *args, **kwargs):
thr_name = current_thread().name
self.logger.debug('{0} - started'.format(thr_name))
self.logger.debug('{} - started'.format(thr_name))
try:
target(*args, **kwargs)
except Exception:
self.__exception_event.set()
self.logger.exception('unhandled exception in %s', thr_name)
raise
self.logger.debug('{0} - ended'.format(thr_name))
self.logger.debug('{} - ended'.format(thr_name))
def start_polling(self,
poll_interval=0.0,
@ -414,7 +414,7 @@ class Updater(object):
self.logger.debug('Updater thread started (webhook)')
use_ssl = cert is not None and key is not None
if not url_path.startswith('/'):
url_path = '/{0}'.format(url_path)
url_path = '/{}'.format(url_path)
# Create Tornado app instance
app = WebhookAppClass(url_path, self.bot, self.update_queue,
@ -543,9 +543,9 @@ class Updater(object):
def _join_threads(self):
for thr in self.__threads:
self.logger.debug('Waiting for {0} thread to end'.format(thr.name))
self.logger.debug('Waiting for {} thread to end'.format(thr.name))
thr.join()
self.logger.debug('{0} thread has ended'.format(thr.name))
self.logger.debug('{} thread has ended'.format(thr.name))
self.__threads = []
def signal_handler(self, signum, frame):

View file

@ -88,7 +88,7 @@ class Animation(TelegramObject):
if not data:
return None
data = super(Animation, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

@ -76,7 +76,7 @@ class Document(TelegramObject):
if not data:
return None
data = super(Document, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

@ -21,7 +21,7 @@ from base64 import b64decode
from os.path import basename
import os
from future.backports.urllib import parse as urllib_parse
import urllib.parse as urllib_parse
from telegram import TelegramObject
from telegram.passport.credentials import decrypt

View file

@ -29,7 +29,7 @@ from telegram import TelegramError
DEFAULT_MIME_TYPE = 'application/octet-stream'
class InputFile(object):
class InputFile:
"""This object represents a Telegram InputFile.
Attributes:
@ -55,11 +55,7 @@ class InputFile(object):
if filename:
self.filename = filename
elif (hasattr(obj, 'name')
and not isinstance(obj.name, int) # py3
and obj.name != '<fdopen>'): # py2
# on py2.7, pylint fails to understand this properly
# pylint: disable=E1101
elif (hasattr(obj, 'name') and not isinstance(obj.name, int)):
self.filename = os.path.basename(obj.name)
try:

View file

@ -96,7 +96,7 @@ class Sticker(TelegramObject):
if not data:
return None
data = super(Sticker, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
data['mask_position'] = MaskPosition.de_json(data.get('mask_position'), bot)
@ -164,20 +164,20 @@ class StickerSet(TelegramObject):
self._id_attrs = (self.name,)
@staticmethod
def de_json(data, bot):
@classmethod
def de_json(cls, data, bot):
if not data:
return None
data = super(StickerSet, StickerSet).de_json(data, bot)
data = super().de_json(data, bot)
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
data['stickers'] = Sticker.de_list(data.get('stickers'), bot)
return StickerSet(bot=bot, **data)
return cls(bot=bot, **data)
def to_dict(self):
data = super(StickerSet, self).to_dict()
data = super().to_dict()
data['stickers'] = [s.to_dict() for s in data.get('stickers')]

View file

@ -57,7 +57,7 @@ class Venue(TelegramObject):
@classmethod
def de_json(cls, data, bot):
data = super(Venue, cls).de_json(data, bot)
data = super().de_json(data, bot)
if not data:
return None

View file

@ -83,7 +83,7 @@ class Video(TelegramObject):
if not data:
return None
data = super(Video, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

@ -75,7 +75,7 @@ class VideoNote(TelegramObject):
if not data:
return None
data = super(VideoNote, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

@ -71,7 +71,7 @@ class Voice(TelegramObject):
if not data:
return None
data = super(Voice, cls).de_json(data, bot)
data = super().de_json(data, bot)
return cls(bot=bot, **data)

View file

@ -77,7 +77,7 @@ class Game(TelegramObject):
if not data:
return None
data = super(Game, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['photo'] = PhotoSize.de_list(data.get('photo'), bot)
data['text_entities'] = MessageEntity.de_list(data.get('text_entities'), bot)
@ -86,7 +86,7 @@ class Game(TelegramObject):
return cls(**data)
def to_dict(self):
data = super(Game, self).to_dict()
data = super().to_dict()
data['photo'] = [p.to_dict() for p in self.photo]
if self.text_entities:

View file

@ -46,7 +46,7 @@ class GameHighScore(TelegramObject):
if not data:
return None
data = super(GameHighScore, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['user'] = User.de_json(data.get('user'), bot)

View file

@ -41,7 +41,7 @@ class InlineKeyboardMarkup(ReplyMarkup):
self.inline_keyboard = inline_keyboard
def to_dict(self):
data = super(InlineKeyboardMarkup, self).to_dict()
data = super().to_dict()
data['inline_keyboard'] = []
for inline_keyboard in self.inline_keyboard:

View file

@ -65,7 +65,7 @@ class InlineQuery(TelegramObject):
@classmethod
def de_json(cls, data, bot):
data = super(InlineQuery, cls).de_json(data, bot)
data = super().de_json(data, bot)
if not data:
return None

View file

@ -72,7 +72,7 @@ class InlineQueryResultArticle(InlineQueryResult):
**kwargs):
# Required
super(InlineQueryResultArticle, self).__init__('article', id)
super().__init__('article', id)
self.title = title
self.input_message_content = input_message_content

View file

@ -75,7 +75,7 @@ class InlineQueryResultAudio(InlineQueryResult):
**kwargs):
# Required
super(InlineQueryResultAudio, self).__init__('audio', id)
super().__init__('audio', id)
self.audio_url = audio_url
self.title = title

View file

@ -65,7 +65,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultCachedAudio, self).__init__('audio', id)
super().__init__('audio', id)
self.audio_file_id = audio_file_id
# Optionals

View file

@ -73,7 +73,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultCachedDocument, self).__init__('document', id)
super().__init__('document', id)
self.title = title
self.document_file_id = document_file_id

View file

@ -71,7 +71,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultCachedGif, self).__init__('gif', id)
super().__init__('gif', id)
self.gif_file_id = gif_file_id
# Optionals

View file

@ -71,7 +71,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultCachedMpeg4Gif, self).__init__('mpeg4_gif', id)
super().__init__('mpeg4_gif', id)
self.mpeg4_file_id = mpeg4_file_id
# Optionals

View file

@ -74,7 +74,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultCachedPhoto, self).__init__('photo', id)
super().__init__('photo', id)
self.photo_file_id = photo_file_id
# Optionals

View file

@ -54,7 +54,7 @@ class InlineQueryResultCachedSticker(InlineQueryResult):
input_message_content=None,
**kwargs):
# Required
super(InlineQueryResultCachedSticker, self).__init__('sticker', id)
super().__init__('sticker', id)
self.sticker_file_id = sticker_file_id
# Optionals

View file

@ -74,7 +74,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultCachedVideo, self).__init__('video', id)
super().__init__('video', id)
self.video_file_id = video_file_id
self.title = title

View file

@ -68,7 +68,7 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultCachedVoice, self).__init__('voice', id)
super().__init__('voice', id)
self.voice_file_id = voice_file_id
self.title = title

View file

@ -74,7 +74,7 @@ class InlineQueryResultContact(InlineQueryResult):
vcard=None,
**kwargs):
# Required
super(InlineQueryResultContact, self).__init__('contact', id)
super().__init__('contact', id)
self.phone_number = phone_number
self.first_name = first_name

View file

@ -88,7 +88,7 @@ class InlineQueryResultDocument(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultDocument, self).__init__('document', id)
super().__init__('document', id)
self.document_url = document_url
self.title = title
self.mime_type = mime_type

View file

@ -42,7 +42,7 @@ class InlineQueryResultGame(InlineQueryResult):
def __init__(self, id, game_short_name, reply_markup=None, **kwargs):
# Required
super(InlineQueryResultGame, self).__init__('game', id)
super().__init__('game', id)
self.id = id
self.game_short_name = game_short_name

View file

@ -83,7 +83,7 @@ class InlineQueryResultGif(InlineQueryResult):
**kwargs):
# Required
super(InlineQueryResultGif, self).__init__('gif', id)
super().__init__('gif', id)
self.gif_url = gif_url
self.thumb_url = thumb_url

View file

@ -74,7 +74,7 @@ class InlineQueryResultLocation(InlineQueryResult):
thumb_height=None,
**kwargs):
# Required
super(InlineQueryResultLocation, self).__init__('location', id)
super().__init__('location', id)
self.latitude = latitude
self.longitude = longitude
self.title = title

View file

@ -84,7 +84,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
**kwargs):
# Required
super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id)
super().__init__('mpeg4_gif', id)
self.mpeg4_url = mpeg4_url
self.thumb_url = thumb_url

View file

@ -84,7 +84,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
parse_mode=DEFAULT_NONE,
**kwargs):
# Required
super(InlineQueryResultPhoto, self).__init__('photo', id)
super().__init__('photo', id)
self.photo_url = photo_url
self.thumb_url = thumb_url

View file

@ -83,7 +83,7 @@ class InlineQueryResultVenue(InlineQueryResult):
**kwargs):
# Required
super(InlineQueryResultVenue, self).__init__('venue', id)
super().__init__('venue', id)
self.latitude = latitude
self.longitude = longitude
self.title = title

View file

@ -97,7 +97,7 @@ class InlineQueryResultVideo(InlineQueryResult):
**kwargs):
# Required
super(InlineQueryResultVideo, self).__init__('video', id)
super().__init__('video', id)
self.video_url = video_url
self.mime_type = mime_type
self.thumb_url = thumb_url

View file

@ -73,7 +73,7 @@ class InlineQueryResultVoice(InlineQueryResult):
**kwargs):
# Required
super(InlineQueryResultVoice, self).__init__('voice', id)
super().__init__('voice', id)
self.voice_url = voice_url
self.title = title

View file

@ -364,7 +364,7 @@ class Message(TelegramObject):
if not data:
return None
data = super(Message, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['from_user'] = User.de_json(data.get('from'), bot)
data['date'] = from_timestamp(data['date'])
@ -452,7 +452,7 @@ class Message(TelegramObject):
return self.chat.id
def to_dict(self):
data = super(Message, self).to_dict()
data = super().to_dict()
# Required
data['date'] = to_timestamp(self.date)

View file

@ -65,7 +65,7 @@ class MessageEntity(TelegramObject):
@classmethod
def de_json(cls, data, bot):
data = super(MessageEntity, cls).de_json(data, bot)
data = super().de_json(data, bot)
if not data:
return None

View file

@ -20,7 +20,7 @@
"""This module contains an object that represents a Telegram Message Parse Modes."""
class ParseMode(object):
class ParseMode:
"""This object represents a Telegram Message Parse Modes."""
MARKDOWN = 'Markdown'

View file

@ -28,7 +28,6 @@ from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers.algorithms import AES
from cryptography.hazmat.primitives.ciphers.modes import CBC
from cryptography.hazmat.primitives.hashes import SHA512, SHA256, Hash, SHA1
from future.utils import bord
from telegram import TelegramObject, TelegramError
@ -39,8 +38,7 @@ class TelegramDecryptionError(TelegramError):
"""
def __init__(self, message):
super(TelegramDecryptionError, self).__init__("TelegramDecryptionError: "
"{}".format(message))
super().__init__("TelegramDecryptionError: {}".format(message))
def decrypt(secret, hash, data):
@ -83,7 +81,7 @@ def decrypt(secret, hash, data):
# Raise a error that is caught inside telegram.PassportData and transformed into a warning
raise TelegramDecryptionError("Hashes are not equal! {} != {}".format(data_hash, hash))
# Return data without padding
return data[bord(data[0]):]
return data[data[0]:]
def decrypt_json(secret, hash, data):
@ -134,7 +132,7 @@ class EncryptedCredentials(TelegramObject):
if not data:
return None
data = super(EncryptedCredentials, cls).de_json(data, bot)
data = super().de_json(data, bot)
return cls(bot=bot, **data)
@ -347,7 +345,7 @@ class SecureValue(TelegramObject):
return cls(bot=bot, **data)
def to_dict(self):
data = super(SecureValue, self).to_dict()
data = super().to_dict()
data['files'] = [p.to_dict() for p in self.files]
data['translation'] = [p.to_dict() for p in self.translation]
@ -402,10 +400,10 @@ class DataCredentials(_CredentialsBase):
"""
def __init__(self, data_hash, secret, **kwargs):
super(DataCredentials, self).__init__(data_hash, secret, **kwargs)
super().__init__(data_hash, secret, **kwargs)
def to_dict(self):
data = super(DataCredentials, self).to_dict()
data = super().to_dict()
del data['file_hash']
del data['hash']
@ -428,10 +426,10 @@ class FileCredentials(_CredentialsBase):
"""
def __init__(self, file_hash, secret, **kwargs):
super(FileCredentials, self).__init__(file_hash, secret, **kwargs)
super().__init__(file_hash, secret, **kwargs)
def to_dict(self):
data = super(FileCredentials, self).to_dict()
data = super().to_dict()
del data['data_hash']
del data['hash']

View file

@ -19,8 +19,8 @@
"""This module contains an object that represents a Telegram EncryptedPassportElement."""
from base64 import b64decode
from telegram import (TelegramObject, PassportFile, PersonalDetails, IdDocumentData,
ResidentialAddress)
from telegram import (IdDocumentData, PassportFile, PersonalDetails,
ResidentialAddress, TelegramObject)
from telegram.passport.credentials import decrypt_json
@ -138,7 +138,7 @@ class EncryptedPassportElement(TelegramObject):
if not data:
return None
data = super(EncryptedPassportElement, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['files'] = PassportFile.de_list(data.get('files'), bot) or None
data['front_side'] = PassportFile.de_json(data.get('front_side'), bot)
@ -153,7 +153,7 @@ class EncryptedPassportElement(TelegramObject):
if not data:
return None
data = super(EncryptedPassportElement, cls).de_json(data, bot)
data = super().de_json(data, bot)
if data['type'] not in ('phone_number', 'email'):
secure_data = getattr(credentials.secure_data, data['type'])
@ -197,7 +197,7 @@ class EncryptedPassportElement(TelegramObject):
return encrypted_passport_elements
def to_dict(self):
data = super(EncryptedPassportElement, self).to_dict()
data = super().to_dict()
if self.files:
data['files'] = [p.to_dict() for p in self.files]

View file

@ -58,7 +58,7 @@ class PassportData(TelegramObject):
if not data:
return None
data = super(PassportData, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['data'] = EncryptedPassportElement.de_list(data.get('data'), bot)
data['credentials'] = EncryptedCredentials.de_json(data.get('credentials'), bot)
@ -66,7 +66,7 @@ class PassportData(TelegramObject):
return cls(bot=bot, **data)
def to_dict(self):
data = super(PassportData, self).to_dict()
data = super().to_dict()
data['data'] = [e.to_dict() for e in self.data]

View file

@ -76,7 +76,7 @@ class PassportElementErrorDataField(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorDataField, self).__init__('data', type, message)
super().__init__('data', type, message)
self.field_name = field_name
self.data_hash = data_hash
@ -111,7 +111,7 @@ class PassportElementErrorFile(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorFile, self).__init__('file', type, message)
super().__init__('file', type, message)
self.file_hash = file_hash
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
@ -145,7 +145,7 @@ class PassportElementErrorFiles(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorFiles, self).__init__('files', type, message)
super().__init__('files', type, message)
self.file_hashes = file_hashes
self._id_attrs = ((self.source, self.type, self.message)
@ -180,7 +180,7 @@ class PassportElementErrorFrontSide(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorFrontSide, self).__init__('front_side', type, message)
super().__init__('front_side', type, message)
self.file_hash = file_hash
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
@ -214,7 +214,7 @@ class PassportElementErrorReverseSide(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorReverseSide, self).__init__('reverse_side', type, message)
super().__init__('reverse_side', type, message)
self.file_hash = file_hash
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
@ -246,7 +246,7 @@ class PassportElementErrorSelfie(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorSelfie, self).__init__('selfie', type, message)
super().__init__('selfie', type, message)
self.file_hash = file_hash
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
@ -282,8 +282,7 @@ class PassportElementErrorTranslationFile(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorTranslationFile, self).__init__('translation_file',
type, message)
super().__init__('translation_file', type, message)
self.file_hash = file_hash
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
@ -319,8 +318,7 @@ class PassportElementErrorTranslationFiles(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorTranslationFiles, self).__init__('translation_files',
type, message)
super().__init__('translation_files', type, message)
self.file_hashes = file_hashes
self._id_attrs = ((self.source, self.type, self.message)
@ -351,7 +349,7 @@ class PassportElementErrorUnspecified(PassportElementError):
message,
**kwargs):
# Required
super(PassportElementErrorUnspecified, self).__init__('unspecified', type, message)
super().__init__('unspecified', type, message)
self.element_hash = element_hash
self._id_attrs = (self.source, self.type, self.element_hash, self.message)

View file

@ -71,7 +71,7 @@ class PassportFile(TelegramObject):
if not data:
return None
data = super(PassportFile, cls).de_json(data, bot)
data = super().de_json(data, bot)
return cls(bot=bot, **data)
@ -80,7 +80,7 @@ class PassportFile(TelegramObject):
if not data:
return None
data = super(PassportFile, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['credentials'] = credentials

View file

@ -50,7 +50,7 @@ class OrderInfo(TelegramObject):
if not data:
return cls()
data = super(OrderInfo, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['shipping_address'] = ShippingAddress.de_json(data.get('shipping_address'), bot)

View file

@ -82,7 +82,7 @@ class PreCheckoutQuery(TelegramObject):
if not data:
return None
data = super(PreCheckoutQuery, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['from_user'] = User.de_json(data.pop('from'), bot)
data['order_info'] = OrderInfo.de_json(data.get('order_info'), bot)

View file

@ -45,7 +45,7 @@ class ShippingOption(TelegramObject):
self._id_attrs = (self.id,)
def to_dict(self):
data = super(ShippingOption, self).to_dict()
data = super().to_dict()
data['prices'] = [p.to_dict() for p in self.prices]

View file

@ -59,7 +59,7 @@ class ShippingQuery(TelegramObject):
if not data:
return None
data = super(ShippingQuery, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['from_user'] = User.de_json(data.pop('from'), bot)
data['shipping_address'] = ShippingAddress.de_json(data.get('shipping_address'), bot)

View file

@ -74,7 +74,7 @@ class SuccessfulPayment(TelegramObject):
if not data:
return None
data = super(SuccessfulPayment, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['order_info'] = OrderInfo.de_json(data.get('order_info'), bot)
return cls(**data)

View file

@ -165,7 +165,7 @@ class Poll(TelegramObject):
if not data:
return None
data = super(Poll, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['options'] = [PollOption.de_json(option, bot) for option in data['options']]
data['explanation_entities'] = MessageEntity.de_list(data.get('explanation_entities'), bot)
@ -174,7 +174,7 @@ class Poll(TelegramObject):
return cls(**data)
def to_dict(self):
data = super(Poll, self).to_dict()
data = super().to_dict()
data['options'] = [x.to_dict() for x in self.options]
if self.explanation_entities:

View file

@ -73,7 +73,7 @@ class ReplyKeyboardMarkup(ReplyMarkup):
self.selective = bool(selective)
def to_dict(self):
data = super(ReplyKeyboardMarkup, self).to_dict()
data = super().to_dict()
data['keyboard'] = []
for row in self.keyboard:

View file

@ -223,7 +223,7 @@ class Update(TelegramObject):
if not data:
return None
data = super(Update, cls).de_json(data, bot)
data = super().de_json(data, bot)
message = data.get('message')
if message:

View file

@ -116,7 +116,7 @@ class User(TelegramObject):
def de_json(cls, data, bot):
if not data:
return None
data = super(User, cls).de_json(data, bot)
data = super().de_json(data, bot)
return cls(bot=bot, **data)

View file

@ -45,14 +45,14 @@ class UserProfilePhotos(TelegramObject):
if not data:
return None
data = super(UserProfilePhotos, cls).de_json(data, bot)
data = super().de_json(data, bot)
data['photos'] = [PhotoSize.de_list(photo, bot) for photo in data['photos']]
return cls(**data)
def to_dict(self):
data = super(UserProfilePhotos, self).to_dict()
data = super().to_dict()
data['photos'] = []
for photo in self.photos:

View file

@ -30,7 +30,7 @@ class TelegramDeprecationWarning(Warning):
def warn_deprecate_obj(old, new, stacklevel=3):
warnings.warn(
'{0} is being deprecated, please use {1} from now on.'.format(old, new),
'{} is being deprecated, please use {} from now on.'.format(old, new),
category=TelegramDeprecationWarning,
stacklevel=stacklevel)

View file

@ -19,19 +19,18 @@
"""This module contains helper functions."""
import datetime as dtm # dtm = "DateTime Module"
import re
import signal
import time
from collections import defaultdict
from html import escape
from numbers import Number
try:
import ujson as json
except ImportError:
import json
from html import escape
import re
import signal
# From https://stackoverflow.com/questions/2549939/get-signal-names-from-numbers-in-python
_signames = {v: k
@ -58,26 +57,29 @@ def escape_markdown(text, version=1, entity_type=None):
``version=2``, will be ignored else.
"""
if int(version) == 1:
escape_chars = '\*_`\['
escape_chars = r'_*`['
elif int(version) == 2:
if entity_type == 'pre' or entity_type == 'code':
escape_chars = '`\\\\'
escape_chars = r'\`'
elif entity_type == 'text_link':
escape_chars = ')\\\\'
escape_chars = r'\)'
else:
escape_chars = '_*\[\]()~`>\#\+\-=|{}\.!'
escape_chars = r'_*[]()~`>#+-=|{}.!'
else:
raise ValueError('Markdown version must be either 1 or 2!')
return re.sub(r'([%s])' % escape_chars, r'\\\1', text)
return re.sub('([{}])'.format(re.escape(escape_chars)), r'\\\1', text)
# -------- date/time related helpers --------
# TODO: add generic specification of UTC for naive datetimes to docs
def _datetime_to_float_timestamp(dt_obj):
"""Converts a datetime object to a float timestamp (with sub-second precision).
If the datetime object is timezone-naive, it is assumed to be in UTC."""
"""
Converts a datetime object to a float timestamp (with sub-second precision).
If the datetime object is timezone-naive, it is assumed to be in UTC.
"""
if dt_obj.tzinfo is None:
dt_obj = dt_obj.replace(tzinfo=dtm.timezone.utc)
return dt_obj.timestamp()
@ -288,7 +290,7 @@ def create_deep_linked_url(bot_username, payload=None, group=False):
else:
key = 'start'
return '{0}?{1}={2}'.format(
return '{}?{}={}'.format(
base_url,
key,
payload

View file

@ -25,7 +25,7 @@ from threading import Event
logger = logging.getLogger(__name__)
class Promise(object):
class Promise:
"""A simple Promise implementation for use with the run_async decorator, DelayQueue etc.
Args:

View file

@ -22,7 +22,6 @@ import os
import socket
import sys
import warnings
from builtins import str # For PY2
try:
import ujson as json
@ -62,11 +61,11 @@ def _render_part(self, name, value):
"""
Monkey patch urllib3.urllib3.fields.RequestField to make it *not* support RFC2231 compliant
Content-Disposition headers since telegram servers don't understand it. Instead just escape
\ and " and replace any \n and \r with a space.
\\ and " and replace any \n and \r with a space.
"""
value = value.replace(u'\\', u'\\\\').replace(u'"', u'\\"')
value = value.replace(u'\r', u' ').replace(u'\n', u' ')
return u'%s="%s"' % (name, value)
return u'{}="{}"'.format(name, value)
RequestField._render_part = _render_part
@ -76,7 +75,7 @@ logging.getLogger('urllib3').setLevel(logging.WARNING)
USER_AGENT = 'Python Telegram Bot (https://github.com/python-telegram-bot/python-telegram-bot)'
class Request(object):
class Request:
"""
Helper class for python-telegram-bot which provides methods to perform POST & GET towards
telegram servers.
@ -228,7 +227,7 @@ class Request(object):
except urllib3.exceptions.HTTPError as error:
# HTTPError must come last as its the base urllib3 exception class
# TODO: do something smart here; for now just raise NetworkError
raise NetworkError('urllib3 HTTPError {0}'.format(error))
raise NetworkError('urllib3 HTTPError {}'.format(error))
if 200 <= resp.status <= 299:
# 200-299 range are HTTP success statuses
@ -254,7 +253,7 @@ class Request(object):
elif resp.status == 502:
raise NetworkError('Bad Gateway')
else:
raise NetworkError('{0} ({1})'.format(message, resp.status))
raise NetworkError('{} ({})'.format(message, resp.status))
def get(self, url, timeout=None):
"""Request an URL.
@ -282,7 +281,7 @@ class Request(object):
Args:
url (:obj:`str`): The web location we want to retrieve.
data (dict[str, str|int]): A dict of key/value pairs. Note: On py2.7 value is unicode.
data (dict[str, str|int]): A dict of key/value pairs.
timeout (:obj:`int` | :obj:`float`): If this value is specified, use it as the read
timeout from the server (instead of the one specified during creation of the
connection pool).

View file

@ -19,7 +19,6 @@
import sys
import logging
from telegram import Update
from future.utils import bytes_to_native_str
from threading import Lock
try:
import ujson as json
@ -30,7 +29,7 @@ from tornado.ioloop import IOLoop
import tornado.web
class WebhookServer(object):
class WebhookServer:
def __init__(self, listen, port, webhook_app, ssl_ctx):
self.http_server = HTTPServer(webhook_app, ssl_options=ssl_ctx)
@ -73,7 +72,7 @@ class WebhookAppClass(tornado.web.Application):
self.shared_objects = {"bot": bot, "update_queue": update_queue,
"default_quote": default_quote}
handlers = [
(r"{0}/?".format(webhook_path), WebhookHandler,
(r"{}/?".format(webhook_path), WebhookHandler,
self.shared_objects)
] # noqa
tornado.web.Application.__init__(self, handlers)
@ -87,7 +86,7 @@ class WebhookHandler(tornado.web.RequestHandler):
SUPPORTED_METHODS = ["POST"]
def __init__(self, application, request, **kwargs):
super(WebhookHandler, self).__init__(application, request, **kwargs)
super().__init__(application, request, **kwargs)
self.logger = logging.getLogger(__name__)
self._init_asyncio_patch()
@ -130,7 +129,7 @@ class WebhookHandler(tornado.web.RequestHandler):
def post(self):
self.logger.debug('Webhook triggered')
self._validate_post()
json_string = bytes_to_native_str(self.request.body)
json_string = self.request.body.decode()
data = json.loads(json_string)
self.set_status(200)
self.logger.debug('Webhook received data: ' + json_string)
@ -158,6 +157,7 @@ class WebhookHandler(tornado.web.RequestHandler):
The client ip is prefixed to every message.
"""
super(WebhookHandler, self).write_error(status_code, **kwargs)
self.logger.debug("%s - - %s" % (self.request.remote_ip, "Exception in WebhookHandler"),
super().write_error(status_code, **kwargs)
self.logger.debug("{} - - {}".format(self.request.remote_ip,
"Exception in WebhookHandler"),
exc_info=kwargs['exc_info'])

View file

@ -18,7 +18,6 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
import datetime
import os
import sys
import re
from collections import defaultdict
from queue import Queue
@ -164,9 +163,8 @@ def class_thumb_file():
def pytest_configure(config):
if sys.version_info >= (3,):
config.addinivalue_line('filterwarnings', 'ignore::ResourceWarning')
# TODO: Write so good code that we don't need to ignore ResourceWarnings anymore
config.addinivalue_line('filterwarnings', 'ignore::ResourceWarning')
# TODO: Write so good code that we don't need to ignore ResourceWarnings anymore
def make_bot(bot_info, **kwargs):

View file

@ -39,7 +39,7 @@ def animation(bot, chat_id):
thumb=open('tests/data/thumb.jpg', 'rb')).animation
class TestAnimation(object):
class TestAnimation:
animation_file_id = 'CgADAQADngIAAuyVeEez0xRovKi9VAI'
animation_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
width = 320

View file

@ -39,7 +39,7 @@ def audio(bot, chat_id):
thumb=open('tests/data/thumb.jpg', 'rb')).audio
class TestAudio(object):
class TestAudio:
caption = 'Test *audio*'
performer = 'Leandro Toledo'
title = 'Teste'

View file

@ -22,7 +22,6 @@ from platform import python_implementation
import pytest
from flaky import flaky
from future.utils import string_types
from telegram import (Bot, Update, ChatAction, TelegramError, User, InlineKeyboardMarkup,
InlineKeyboardButton, InlineQueryResultArticle, InputTextMessageContent,
@ -55,7 +54,7 @@ def chat_permissions():
return ChatPermissions(can_send_messages=False, can_change_info=False, can_invite_users=False)
class TestBot(object):
class TestBot:
@pytest.mark.parametrize('token', argvalues=[
'123',
'12a:abcd1234',
@ -879,7 +878,7 @@ class TestBot(object):
def test_export_chat_invite_link(self, bot, channel_id):
# Each link is unique apparently
invite_link = bot.export_chat_invite_link(channel_id)
assert isinstance(invite_link, string_types)
assert isinstance(invite_link, str)
assert invite_link != ''
@flaky(3, 1)

View file

@ -27,7 +27,7 @@ def bot_command():
return BotCommand(command='start', description='A command')
class TestBotCommand(object):
class TestBotCommand:
command = 'start'
description = 'A command'

View file

@ -22,7 +22,7 @@ from telegram import Update, Message, Chat, User, TelegramError
from telegram.ext import CallbackContext
class TestCallbackContext(object):
class TestCallbackContext:
def test_non_context_dp(self, dp):
with pytest.raises(ValueError):
CallbackContext(dp)

View file

@ -37,7 +37,7 @@ def callback_query(bot, request):
return cbq
class TestCallbackQuery(object):
class TestCallbackQuery:
id_ = 'id'
from_user = User(1, 'test_user', False)
chat_instance = 'chat_instance'

View file

@ -52,7 +52,7 @@ def callback_query(bot):
return Update(0, callback_query=CallbackQuery(2, User(1, '', False), None, data='test data'))
class TestCallbackQueryHandler(object):
class TestCallbackQueryHandler:
test_flag = False
@pytest.fixture(autouse=True)

View file

@ -33,7 +33,7 @@ def chat(bot):
slow_mode_delay=TestChat.slow_mode_delay)
class TestChat(object):
class TestChat:
id_ = -28767330
title = 'ToledosPalaceBot - Group'
type_ = 'group'

View file

@ -34,7 +34,7 @@ def chat_member(user):
return ChatMember(user, TestChatMember.status)
class TestChatMember(object):
class TestChatMember:
status = ChatMember.CREATOR
def test_de_json_required_args(self, bot, user):

View file

@ -30,7 +30,7 @@ def chat_permissions():
can_invite_users=True, can_pin_messages=True)
class TestChatPermissions(object):
class TestChatPermissions:
can_send_messages = True
can_send_media_messages = True
can_send_polls = True

View file

@ -40,7 +40,7 @@ def chat_photo(bot, super_group_id):
return expect_bad_request(func, 'Type of file mismatch', 'Telegram did not accept the file.')
class TestChatPhoto(object):
class TestChatPhoto:
chatphoto_small_file_id = 'smallCgADAQADngIAAuyVeEez0xRovKi9VAI'
chatphoto_big_file_id = 'bigCgADAQADngIAAuyVeEez0xRovKi9VAI'
chatphoto_small_file_unique_id = 'smalladc3145fd2e84d95b64d68eaa22aa33e'

View file

@ -32,7 +32,7 @@ def chosen_inline_result(user):
return ChosenInlineResult(TestChosenInlineResult.result_id, user, TestChosenInlineResult.query)
class TestChosenInlineResult(object):
class TestChosenInlineResult:
result_id = 'result id'
query = 'query text'

View file

@ -55,7 +55,7 @@ def chosen_inline_result():
'query'))
class TestChosenInlineResultHandler(object):
class TestChosenInlineResultHandler:
test_flag = False
@pytest.fixture(autouse=True)

Some files were not shown because too many files have changed in this diff Show more