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! Description: We have made you a wrapper you can't refuse!
The Python Telegram bot (Python 3) The Python Telegram bot (Python 3)
This library provides a pure Python interface for the Telegram Bot API. 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 In addition to the pure API implementation, this library features
a number of high-level a number of high-level

View file

@ -6,7 +6,7 @@
export PYBUILD_NAME=telegram 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 # If you need to rebuild the Sphinx documentation

View file

@ -61,7 +61,7 @@ def deep_linked_level_2(update, context):
bot = context.bot bot = context.bot
url = helpers.create_deep_linked_url(bot.get_me().username, USING_ENTITIES) url = helpers.create_deep_linked_url(bot.get_me().username, USING_ENTITIES)
text = "You can also mask the deep-linked URLs as links: " \ 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) 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""" """Reached through the USING_ENTITIES payload"""
payload = context.args payload = context.args
update.message.reply_text("Congratulations! This is as deep as it gets 👏🏻\n\n" 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(): def main():

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,7 +28,7 @@ from telegram.ext import (Handler, CallbackQueryHandler, InlineQueryHandler,
from telegram.utils.promise import Promise from telegram.utils.promise import Promise
class _ConversationTimeoutContext(object): class _ConversationTimeoutContext:
def __init__(self, conversation_key, update, dispatcher, callback_context): def __init__(self, conversation_key, update, dispatcher, callback_context):
self.conversation_key = conversation_key self.conversation_key = conversation_key
self.update = update self.update = update
@ -404,7 +404,7 @@ class ConversationHandler(Handler):
return key, handler, check return key, handler, check
return None 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 handler = None

View file

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

View file

@ -29,8 +29,6 @@ from collections import defaultdict
from queue import Queue, Empty from queue import Queue, Empty
from future.builtins import range
from telegram import TelegramError, Update from telegram import TelegramError, Update
from telegram.ext.handler import Handler from telegram.ext.handler import Handler
from telegram.ext.callbackcontext import CallbackContext from telegram.ext.callbackcontext import CallbackContext
@ -66,7 +64,7 @@ class DispatcherHandlerStop(Exception):
pass pass
class Dispatcher(object): class Dispatcher:
"""This class dispatches all kinds of updates to its registered handlers. """This class dispatches all kinds of updates to its registered handlers.
Attributes: Attributes:
@ -304,10 +302,10 @@ class Dispatcher(object):
self.__async_queue.put(None) self.__async_queue.put(None)
for i, thr in enumerate(threads): 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() thr.join()
self.__async_threads.remove(thr) 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 @property
def has_running_threads(self): def has_running_threads(self):
@ -391,7 +389,7 @@ class Dispatcher(object):
from .conversationhandler import ConversationHandler from .conversationhandler import ConversationHandler
if not isinstance(handler, Handler): 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): if not isinstance(group, int):
raise TypeError('group is not int') raise TypeError('group is not int')
if isinstance(handler, ConversationHandler) and handler.persistent: if isinstance(handler, ConversationHandler) and handler.persistent:

View file

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

View file

@ -19,9 +19,8 @@
""" This module contains the InlineQueryHandler class """ """ This module contains the InlineQueryHandler class """
import re import re
from future.utils import string_types
from telegram import Update from telegram import Update
from .handler import Handler from .handler import Handler
@ -104,14 +103,14 @@ class InlineQueryHandler(Handler):
pass_groupdict=False, pass_groupdict=False,
pass_user_data=False, pass_user_data=False,
pass_chat_data=False): pass_chat_data=False):
super(InlineQueryHandler, self).__init__( super().__init__(
callback, callback,
pass_update_queue=pass_update_queue, pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue, pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data, pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data) pass_chat_data=pass_chat_data)
if isinstance(pattern, string_types): if isinstance(pattern, str):
pattern = re.compile(pattern) pattern = re.compile(pattern)
self.pattern = pattern self.pattern = pattern
@ -140,8 +139,7 @@ class InlineQueryHandler(Handler):
return True return True
def collect_optional_args(self, dispatcher, update=None, check_result=None): def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(InlineQueryHandler, self).collect_optional_args(dispatcher, optional_args = super().collect_optional_args(dispatcher, update, check_result)
update, check_result)
if self.pattern: if self.pattern:
if self.pass_groups: if self.pass_groups:
optional_args['groups'] = check_result.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 from telegram.utils.helpers import to_float_timestamp
class Days(object): class Days:
MON, TUE, WED, THU, FRI, SAT, SUN = range(7) MON, TUE, WED, THU, FRI, SAT, SUN = range(7)
EVERY_DAY = tuple(range(7)) EVERY_DAY = tuple(range(7))
class JobQueue(object): class JobQueue:
"""This class allows you to periodically perform tasks with the bot. """This class allows you to periodically perform tasks with the bot.
Attributes: Attributes:
@ -54,7 +54,7 @@ class JobQueue(object):
warnings.warn("Passing bot to jobqueue is deprecated. Please use set_dispatcher " warnings.warn("Passing bot to jobqueue is deprecated. Please use set_dispatcher "
"instead!", TelegramDeprecationWarning, stacklevel=2) "instead!", TelegramDeprecationWarning, stacklevel=2)
class MockDispatcher(object): class MockDispatcher:
def __init__(self): def __init__(self):
self.bot = bot self.bot = bot
self.use_context = False 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) 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. """This class encapsulates a Job.
Attributes: Attributes:

View file

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

View file

@ -23,24 +23,9 @@
from telegram.utils import promise from telegram.utils import promise
import functools import functools
import sys
import time import time
import threading import threading
if sys.version_info.major > 2: import queue as q
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
class DelayQueueError(RuntimeError): class DelayQueueError(RuntimeError):
@ -95,11 +80,11 @@ class DelayQueue(threading.Thread):
self.__exit_req = False # flag to gently exit thread self.__exit_req = False # flag to gently exit thread
self.__class__._instcnt += 1 self.__class__._instcnt += 1
if name is None: if name is None:
name = '%s-%s' % (self.__class__.__name__, self.__class__._instcnt) name = '{}-{}'.format(self.__class__.__name__, self.__class__._instcnt)
super(DelayQueue, self).__init__(name=name) super().__init__(name=name)
self.daemon = False self.daemon = False
if autostart: # immediately start processing if autostart: # immediately start processing
super(DelayQueue, self).start() super().start()
def run(self): def run(self):
""" """
@ -114,7 +99,7 @@ class DelayQueue(threading.Thread):
if self.__exit_req: if self.__exit_req:
return # shutdown thread return # shutdown thread
# delay routine # delay routine
now = curtime() now = time.perf_counter()
t_delta = now - self.time_limit # calculate early to improve perf. t_delta = now - self.time_limit # calculate early to improve perf.
if times and t_delta > times[-1]: if times and t_delta > times[-1]:
# if last call was before the limit time-window # if last call was before the limit time-window
@ -146,7 +131,7 @@ class DelayQueue(threading.Thread):
self.__exit_req = True # gently request self.__exit_req = True # gently request
self._queue.put(None) # put something to unfreeze if frozen self._queue.put(None) # put something to unfreeze if frozen
super(DelayQueue, self).join(timeout=timeout) super().join(timeout=timeout)
@staticmethod @staticmethod
def _default_exception_handler(exc): 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 # msg --> group delay if group msg, else no delay --> normal msg delay --> out
# This way OS threading scheduler cares of timings accuracy. # This way OS threading scheduler cares of timings accuracy.
# (see time.time, time.clock, time.perf_counter, time.sleep @ docs.python.org) # (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. 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. 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, store_bot_data=True,
single_file=True, single_file=True,
on_flush=False): on_flush=False):
super(PicklePersistence, self).__init__(store_user_data=store_user_data, super().__init__(store_user_data=store_user_data,
store_chat_data=store_chat_data, store_chat_data=store_chat_data,
store_bot_data=store_bot_data) store_bot_data=store_bot_data)
self.filename = filename self.filename = filename
self.single_file = single_file self.single_file = single_file
self.on_flush = on_flush 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', warnings.warn('RegexHandler is deprecated. See https://git.io/fxJuV for more info',
TelegramDeprecationWarning, TelegramDeprecationWarning,
stacklevel=2) stacklevel=2)
super(RegexHandler, self).__init__(Filters.regex(pattern), super().__init__(Filters.regex(pattern),
callback, callback,
pass_update_queue=pass_update_queue, pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue, pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data, pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data, pass_chat_data=pass_chat_data,
message_updates=message_updates, message_updates=message_updates,
channel_post_updates=channel_post_updates, channel_post_updates=channel_post_updates,
edited_updates=edited_updates) edited_updates=edited_updates)
self.pass_groups = pass_groups self.pass_groups = pass_groups
self.pass_groupdict = pass_groupdict self.pass_groupdict = pass_groupdict
def collect_optional_args(self, dispatcher, update=None, check_result=None): def collect_optional_args(self, dispatcher, update=None, check_result=None):
optional_args = super(RegexHandler, self).collect_optional_args(dispatcher, update, optional_args = super().collect_optional_args(dispatcher, update, check_result)
check_result)
if self.pass_groups: if self.pass_groups:
optional_args['groups'] = check_result['matches'][0].groups() optional_args['groups'] = check_result['matches'][0].groups()
if self.pass_groupdict: if self.pass_groupdict:

View file

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

View file

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

View file

@ -65,7 +65,7 @@ class TypeHandler(Handler):
strict=False, strict=False,
pass_update_queue=False, pass_update_queue=False,
pass_job_queue=False): pass_job_queue=False):
super(TypeHandler, self).__init__( super().__init__(
callback, callback,
pass_update_queue=pass_update_queue, pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_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) 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 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 :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): def _thread_wrapper(self, target, *args, **kwargs):
thr_name = current_thread().name thr_name = current_thread().name
self.logger.debug('{0} - started'.format(thr_name)) self.logger.debug('{} - started'.format(thr_name))
try: try:
target(*args, **kwargs) target(*args, **kwargs)
except Exception: except Exception:
self.__exception_event.set() self.__exception_event.set()
self.logger.exception('unhandled exception in %s', thr_name) self.logger.exception('unhandled exception in %s', thr_name)
raise raise
self.logger.debug('{0} - ended'.format(thr_name)) self.logger.debug('{} - ended'.format(thr_name))
def start_polling(self, def start_polling(self,
poll_interval=0.0, poll_interval=0.0,
@ -414,7 +414,7 @@ class Updater(object):
self.logger.debug('Updater thread started (webhook)') self.logger.debug('Updater thread started (webhook)')
use_ssl = cert is not None and key is not None use_ssl = cert is not None and key is not None
if not url_path.startswith('/'): if not url_path.startswith('/'):
url_path = '/{0}'.format(url_path) url_path = '/{}'.format(url_path)
# Create Tornado app instance # Create Tornado app instance
app = WebhookAppClass(url_path, self.bot, self.update_queue, app = WebhookAppClass(url_path, self.bot, self.update_queue,
@ -543,9 +543,9 @@ class Updater(object):
def _join_threads(self): def _join_threads(self):
for thr in self.__threads: 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() thr.join()
self.logger.debug('{0} thread has ended'.format(thr.name)) self.logger.debug('{} thread has ended'.format(thr.name))
self.__threads = [] self.__threads = []
def signal_handler(self, signum, frame): def signal_handler(self, signum, frame):

View file

@ -88,7 +88,7 @@ class Animation(TelegramObject):
if not data: if not data:
return None 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) data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

@ -76,7 +76,7 @@ class Document(TelegramObject):
if not data: if not data:
return None 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) data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

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

View file

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

View file

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

View file

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

View file

@ -83,7 +83,7 @@ class Video(TelegramObject):
if not data: if not data:
return None 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) data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

@ -75,7 +75,7 @@ class VideoNote(TelegramObject):
if not data: if not data:
return None 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) data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)

View file

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

View file

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

View file

@ -46,7 +46,7 @@ class GameHighScore(TelegramObject):
if not data: if not data:
return None 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) data['user'] = User.de_json(data.get('user'), bot)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -88,7 +88,7 @@ class InlineQueryResultDocument(InlineQueryResult):
parse_mode=DEFAULT_NONE, parse_mode=DEFAULT_NONE,
**kwargs): **kwargs):
# Required # Required
super(InlineQueryResultDocument, self).__init__('document', id) super().__init__('document', id)
self.document_url = document_url self.document_url = document_url
self.title = title self.title = title
self.mime_type = mime_type 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): def __init__(self, id, game_short_name, reply_markup=None, **kwargs):
# Required # Required
super(InlineQueryResultGame, self).__init__('game', id) super().__init__('game', id)
self.id = id self.id = id
self.game_short_name = game_short_name self.game_short_name = game_short_name

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -50,7 +50,7 @@ class OrderInfo(TelegramObject):
if not data: if not data:
return cls() 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) data['shipping_address'] = ShippingAddress.de_json(data.get('shipping_address'), bot)

View file

@ -82,7 +82,7 @@ class PreCheckoutQuery(TelegramObject):
if not data: if not data:
return None 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['from_user'] = User.de_json(data.pop('from'), bot)
data['order_info'] = OrderInfo.de_json(data.get('order_info'), 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,) self._id_attrs = (self.id,)
def to_dict(self): def to_dict(self):
data = super(ShippingOption, self).to_dict() data = super().to_dict()
data['prices'] = [p.to_dict() for p in self.prices] data['prices'] = [p.to_dict() for p in self.prices]

View file

@ -59,7 +59,7 @@ class ShippingQuery(TelegramObject):
if not data: if not data:
return None 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['from_user'] = User.de_json(data.pop('from'), bot)
data['shipping_address'] = ShippingAddress.de_json(data.get('shipping_address'), bot) data['shipping_address'] = ShippingAddress.de_json(data.get('shipping_address'), bot)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -30,7 +30,7 @@ class TelegramDeprecationWarning(Warning):
def warn_deprecate_obj(old, new, stacklevel=3): def warn_deprecate_obj(old, new, stacklevel=3):
warnings.warn( 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, category=TelegramDeprecationWarning,
stacklevel=stacklevel) stacklevel=stacklevel)

View file

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

View file

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

View file

@ -22,7 +22,6 @@ import os
import socket import socket
import sys import sys
import warnings import warnings
from builtins import str # For PY2
try: try:
import ujson as json 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 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 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'\\', u'\\\\').replace(u'"', u'\\"')
value = value.replace(u'\r', u' ').replace(u'\n', 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 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)' 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 Helper class for python-telegram-bot which provides methods to perform POST & GET towards
telegram servers. telegram servers.
@ -228,7 +227,7 @@ class Request(object):
except urllib3.exceptions.HTTPError as error: except urllib3.exceptions.HTTPError as error:
# HTTPError must come last as its the base urllib3 exception class # HTTPError must come last as its the base urllib3 exception class
# TODO: do something smart here; for now just raise NetworkError # 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: if 200 <= resp.status <= 299:
# 200-299 range are HTTP success statuses # 200-299 range are HTTP success statuses
@ -254,7 +253,7 @@ class Request(object):
elif resp.status == 502: elif resp.status == 502:
raise NetworkError('Bad Gateway') raise NetworkError('Bad Gateway')
else: else:
raise NetworkError('{0} ({1})'.format(message, resp.status)) raise NetworkError('{} ({})'.format(message, resp.status))
def get(self, url, timeout=None): def get(self, url, timeout=None):
"""Request an URL. """Request an URL.
@ -282,7 +281,7 @@ class Request(object):
Args: Args:
url (:obj:`str`): The web location we want to retrieve. 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 (: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 timeout from the server (instead of the one specified during creation of the
connection pool). connection pool).

View file

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

View file

@ -18,7 +18,6 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
import datetime import datetime
import os import os
import sys
import re import re
from collections import defaultdict from collections import defaultdict
from queue import Queue from queue import Queue
@ -164,9 +163,8 @@ def class_thumb_file():
def pytest_configure(config): def pytest_configure(config):
if sys.version_info >= (3,): config.addinivalue_line('filterwarnings', 'ignore::ResourceWarning')
config.addinivalue_line('filterwarnings', 'ignore::ResourceWarning') # TODO: Write so good code that we don't need to ignore ResourceWarnings anymore
# TODO: Write so good code that we don't need to ignore ResourceWarnings anymore
def make_bot(bot_info, **kwargs): 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 thumb=open('tests/data/thumb.jpg', 'rb')).animation
class TestAnimation(object): class TestAnimation:
animation_file_id = 'CgADAQADngIAAuyVeEez0xRovKi9VAI' animation_file_id = 'CgADAQADngIAAuyVeEez0xRovKi9VAI'
animation_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e' animation_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
width = 320 width = 320

View file

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

View file

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

View file

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

View file

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

View file

@ -37,7 +37,7 @@ def callback_query(bot, request):
return cbq return cbq
class TestCallbackQuery(object): class TestCallbackQuery:
id_ = 'id' id_ = 'id'
from_user = User(1, 'test_user', False) from_user = User(1, 'test_user', False)
chat_instance = 'chat_instance' 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')) return Update(0, callback_query=CallbackQuery(2, User(1, '', False), None, data='test data'))
class TestCallbackQueryHandler(object): class TestCallbackQueryHandler:
test_flag = False test_flag = False
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)

View file

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

View file

@ -34,7 +34,7 @@ def chat_member(user):
return ChatMember(user, TestChatMember.status) return ChatMember(user, TestChatMember.status)
class TestChatMember(object): class TestChatMember:
status = ChatMember.CREATOR status = ChatMember.CREATOR
def test_de_json_required_args(self, bot, user): 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) can_invite_users=True, can_pin_messages=True)
class TestChatPermissions(object): class TestChatPermissions:
can_send_messages = True can_send_messages = True
can_send_media_messages = True can_send_media_messages = True
can_send_polls = 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.') 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_small_file_id = 'smallCgADAQADngIAAuyVeEez0xRovKi9VAI'
chatphoto_big_file_id = 'bigCgADAQADngIAAuyVeEez0xRovKi9VAI' chatphoto_big_file_id = 'bigCgADAQADngIAAuyVeEez0xRovKi9VAI'
chatphoto_small_file_unique_id = 'smalladc3145fd2e84d95b64d68eaa22aa33e' 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) return ChosenInlineResult(TestChosenInlineResult.result_id, user, TestChosenInlineResult.query)
class TestChosenInlineResult(object): class TestChosenInlineResult:
result_id = 'result id' result_id = 'result id'
query = 'query text' query = 'query text'

View file

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

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