diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 453845ff4..2ffbf8376 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -91,12 +91,14 @@ Here's how to make a one-off code change. Once the process terminates, you can view the built documentation by opening ``docs/build/html/index.html`` with a browser. - - For consistency, please conform to `Google Python Style Guide`_ and `Google Python Style Docstrings`_. In addition, code should be formatted consistently with other code around it. + - For consistency, please conform to `Google Python Style Guide`_ and `Google Python Style Docstrings`_. - The following exceptions to the above (Google's) style guides applies: - Documenting types of global variables and complex types of class members can be done using the Sphinx docstring convention. + - In addition, PTB uses the `Black`_ coder formatting. Plugins for Black exist for some `popular editors`_. You can use those instead of manually formatting everything. + - Please ensure that the code you write is well-tested. - Don’t break backward compatibility. @@ -189,11 +191,6 @@ Here's how to make a one-off code change. Style commandments ------------------ -Specific commandments -##################### - -- Avoid using "double quotes" where you can reasonably use 'single quotes'. - Assert comparison order ####################### @@ -255,3 +252,5 @@ break the API classes. For example: .. _AUTHORS.rst: ../AUTHORS.rst .. _`MyPy`: https://mypy.readthedocs.io/en/stable/index.html .. _`here`: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html +.. _`Black`: https://black.readthedocs.io/en/stable/index.html +.. _`popular editors`: https://black.readthedocs.io/en/stable/editor_integration.html diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dff4bf4e6..5abfb14ab 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,8 @@ repos: -- repo: git://github.com/python-telegram-bot/mirrors-yapf - rev: 5769e088ef6e0a0d1eb63bd6d0c1fe9f3606d6c8 +- repo: https://github.com/psf/black + rev: 20.8b1 hooks: - - id: yapf - files: ^(telegram|tests)/.*\.py$ + - id: black args: - --diff - repo: https://gitlab.com/pycqa/flake8 diff --git a/README.rst b/README.rst index f5589ce6e..11599318c 100644 --- a/README.rst +++ b/README.rst @@ -45,6 +45,9 @@ We have a vibrant community of developers helping each other in our `Telegram gr :target: https://www.codacy.com/app/python-telegram-bot/python-telegram-bot?utm_source=github.com&utm_medium=referral&utm_content=python-telegram-bot/python-telegram-bot&utm_campaign=Badge_Grade :alt: Code quality +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + .. image:: https://img.shields.io/badge/Telegram-Group-blue.svg :target: https://telegram.me/pythontelegrambotgroup :alt: Telegram Group diff --git a/examples/conversationbot.py b/examples/conversationbot.py index a093d6209..c72d02804 100644 --- a/examples/conversationbot.py +++ b/examples/conversationbot.py @@ -16,13 +16,13 @@ bot. import logging -from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove) -from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, - ConversationHandler) +from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove +from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, ConversationHandler # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -36,7 +36,8 @@ def start(update, context): 'Hi! My name is Professor Bot. I will hold a conversation with you. ' 'Send /cancel to stop talking to me.\n\n' 'Are you a boy or a girl?', - reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)) + reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True), + ) return GENDER @@ -44,9 +45,11 @@ def start(update, context): def gender(update, context): user = update.message.from_user logger.info("Gender of %s: %s", user.first_name, update.message.text) - update.message.reply_text('I see! Please send me a photo of yourself, ' - 'so I know what you look like, or send /skip if you don\'t want to.', - reply_markup=ReplyKeyboardRemove()) + update.message.reply_text( + 'I see! Please send me a photo of yourself, ' + 'so I know what you look like, or send /skip if you don\'t want to.', + reply_markup=ReplyKeyboardRemove(), + ) return PHOTO @@ -56,8 +59,9 @@ def photo(update, context): photo_file = update.message.photo[-1].get_file() photo_file.download('user_photo.jpg') logger.info("Photo of %s: %s", user.first_name, 'user_photo.jpg') - update.message.reply_text('Gorgeous! Now, send me your location please, ' - 'or send /skip if you don\'t want to.') + update.message.reply_text( + 'Gorgeous! Now, send me your location please, ' 'or send /skip if you don\'t want to.' + ) return LOCATION @@ -65,8 +69,9 @@ def photo(update, context): def skip_photo(update, context): user = update.message.from_user logger.info("User %s did not send a photo.", user.first_name) - update.message.reply_text('I bet you look great! Now, send me your location please, ' - 'or send /skip.') + update.message.reply_text( + 'I bet you look great! Now, send me your location please, ' 'or send /skip.' + ) return LOCATION @@ -74,10 +79,12 @@ def skip_photo(update, context): def location(update, context): user = update.message.from_user user_location = update.message.location - logger.info("Location of %s: %f / %f", user.first_name, user_location.latitude, - user_location.longitude) - update.message.reply_text('Maybe I can visit you sometime! ' - 'At last, tell me something about yourself.') + logger.info( + "Location of %s: %f / %f", user.first_name, user_location.latitude, user_location.longitude + ) + update.message.reply_text( + 'Maybe I can visit you sometime! ' 'At last, tell me something about yourself.' + ) return BIO @@ -85,8 +92,9 @@ def location(update, context): def skip_location(update, context): user = update.message.from_user logger.info("User %s did not send a location.", user.first_name) - update.message.reply_text('You seem a bit paranoid! ' - 'At last, tell me something about yourself.') + update.message.reply_text( + 'You seem a bit paranoid! ' 'At last, tell me something about yourself.' + ) return BIO @@ -102,8 +110,9 @@ def bio(update, context): def cancel(update, context): user = update.message.from_user logger.info("User %s canceled the conversation.", user.first_name) - update.message.reply_text('Bye! I hope we can talk again some day.', - reply_markup=ReplyKeyboardRemove()) + update.message.reply_text( + 'Bye! I hope we can talk again some day.', reply_markup=ReplyKeyboardRemove() + ) return ConversationHandler.END @@ -120,20 +129,16 @@ def main(): # Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], - states={ GENDER: [MessageHandler(Filters.regex('^(Boy|Girl|Other)$'), gender)], - - PHOTO: [MessageHandler(Filters.photo, photo), - CommandHandler('skip', skip_photo)], - - LOCATION: [MessageHandler(Filters.location, location), - CommandHandler('skip', skip_location)], - - BIO: [MessageHandler(Filters.text & ~Filters.command, bio)] + PHOTO: [MessageHandler(Filters.photo, photo), CommandHandler('skip', skip_photo)], + LOCATION: [ + MessageHandler(Filters.location, location), + CommandHandler('skip', skip_location), + ], + BIO: [MessageHandler(Filters.text & ~Filters.command, bio)], }, - - fallbacks=[CommandHandler('cancel', cancel)] + fallbacks=[CommandHandler('cancel', cancel)], ) dp.add_handler(conv_handler) diff --git a/examples/conversationbot2.py b/examples/conversationbot2.py index edab0cf75..4f08ef130 100644 --- a/examples/conversationbot2.py +++ b/examples/conversationbot2.py @@ -17,20 +17,22 @@ bot. import logging from telegram import ReplyKeyboardMarkup -from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, - ConversationHandler) +from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, ConversationHandler # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) CHOOSING, TYPING_REPLY, TYPING_CHOICE = range(3) -reply_keyboard = [['Age', 'Favourite colour'], - ['Number of siblings', 'Something else...'], - ['Done']] +reply_keyboard = [ + ['Age', 'Favourite colour'], + ['Number of siblings', 'Something else...'], + ['Done'], +] markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True) @@ -47,7 +49,8 @@ def start(update, context): update.message.reply_text( "Hi! My name is Doctor Botter. I will hold a more complex conversation with you. " "Why don't you tell me something about yourself?", - reply_markup=markup) + reply_markup=markup, + ) return CHOOSING @@ -56,14 +59,16 @@ def regular_choice(update, context): text = update.message.text context.user_data['choice'] = text update.message.reply_text( - 'Your {}? Yes, I would love to hear about that!'.format(text.lower())) + 'Your {}? Yes, I would love to hear about that!'.format(text.lower()) + ) return TYPING_REPLY def custom_choice(update, context): - update.message.reply_text('Alright, please send me the category first, ' - 'for example "Most impressive skill"') + update.message.reply_text( + 'Alright, please send me the category first, ' 'for example "Most impressive skill"' + ) return TYPING_CHOICE @@ -75,10 +80,12 @@ def received_information(update, context): user_data[category] = text del user_data['choice'] - update.message.reply_text("Neat! Just so you know, this is what you already told me:" - "{} You can tell me more, or change your opinion" - " on something.".format(facts_to_str(user_data)), - reply_markup=markup) + update.message.reply_text( + "Neat! Just so you know, this is what you already told me:" + "{} You can tell me more, or change your opinion" + " on something.".format(facts_to_str(user_data)), + reply_markup=markup, + ) return CHOOSING @@ -88,9 +95,9 @@ def done(update, context): if 'choice' in user_data: del user_data['choice'] - update.message.reply_text("I learned these facts about you:" - "{}" - "Until next time!".format(facts_to_str(user_data))) + update.message.reply_text( + "I learned these facts about you:" "{}" "Until next time!".format(facts_to_str(user_data)) + ) user_data.clear() return ConversationHandler.END @@ -108,24 +115,26 @@ def main(): # Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], - states={ - CHOOSING: [MessageHandler(Filters.regex('^(Age|Favourite colour|Number of siblings)$'), - regular_choice), - MessageHandler(Filters.regex('^Something else...$'), - custom_choice) - ], - + CHOOSING: [ + MessageHandler( + Filters.regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice + ), + MessageHandler(Filters.regex('^Something else...$'), custom_choice), + ], TYPING_CHOICE: [ - MessageHandler(Filters.text & ~(Filters.command | Filters.regex('^Done$')), - regular_choice)], - + MessageHandler( + Filters.text & ~(Filters.command | Filters.regex('^Done$')), regular_choice + ) + ], TYPING_REPLY: [ - MessageHandler(Filters.text & ~(Filters.command | Filters.regex('^Done$')), - received_information)], + MessageHandler( + Filters.text & ~(Filters.command | Filters.regex('^Done$')), + received_information, + ) + ], }, - - fallbacks=[MessageHandler(Filters.regex('^Done$'), done)] + fallbacks=[MessageHandler(Filters.regex('^Done$'), done)], ) dp.add_handler(conv_handler) diff --git a/examples/deeplinking.py b/examples/deeplinking.py index 609600974..1a71e959d 100644 --- a/examples/deeplinking.py +++ b/examples/deeplinking.py @@ -25,8 +25,9 @@ from telegram.ext import Updater, CommandHandler, Filters # Enable logging from telegram.utils import helpers -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -48,8 +49,10 @@ def deep_linked_level_1(update, context): """Reached through the CHECK_THIS_OUT payload""" bot = context.bot url = helpers.create_deep_linked_url(bot.get_me().username, SO_COOL) - text = "Awesome, you just accessed hidden functionality! " \ - " Now let's get back to the private chat." + text = ( + "Awesome, you just accessed hidden functionality! " + " Now let's get back to the private chat." + ) keyboard = InlineKeyboardMarkup.from_button( InlineKeyboardButton(text='Continue here!', url=url) ) @@ -60,16 +63,16 @@ def deep_linked_level_2(update, context): """Reached through the SO_COOL payload""" bot = context.bot url = helpers.create_deep_linked_url(bot.get_me().username, USING_ENTITIES) - text = "You can also mask the deep-linked URLs as links: " \ - "[▶️ CLICK HERE]({}).".format(url) + text = "You can also mask the deep-linked URLs as links: " "[▶️ CLICK HERE]({}).".format(url) update.message.reply_text(text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True) def deep_linked_level_3(update, context): """Reached through the USING_ENTITIES payload""" payload = context.args - update.message.reply_text("Congratulations! This is as deep as it gets 👏🏻\n\n" - "The payload was: {}".format(payload)) + update.message.reply_text( + "Congratulations! This is as deep as it gets 👏🏻\n\n" "The payload was: {}".format(payload) + ) def main(): @@ -90,10 +93,9 @@ def main(): dp.add_handler(CommandHandler("start", deep_linked_level_2, Filters.regex(SO_COOL))) # We can also pass on the deep-linking payload - dp.add_handler(CommandHandler("start", - deep_linked_level_3, - Filters.regex(USING_ENTITIES), - pass_args=True)) + dp.add_handler( + CommandHandler("start", deep_linked_level_3, Filters.regex(USING_ENTITIES), pass_args=True) + ) # Make sure the deep-linking handlers occur *before* the normal /start handler. dp.add_handler(CommandHandler("start", start)) diff --git a/examples/echobot.py b/examples/echobot.py index 09a488e15..8dfb1aa03 100644 --- a/examples/echobot.py +++ b/examples/echobot.py @@ -20,8 +20,9 @@ import logging from telegram.ext import Updater, CommandHandler, MessageHandler, Filters # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) diff --git a/examples/errorhandlerbot.py b/examples/errorhandlerbot.py index 1dfbac756..2f2133e15 100644 --- a/examples/errorhandlerbot.py +++ b/examples/errorhandlerbot.py @@ -13,8 +13,9 @@ import traceback from telegram import Update, ParseMode from telegram.ext import Updater, CallbackContext, CommandHandler -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -48,7 +49,7 @@ def error_handler(update: Update, context: CallbackContext): html.escape(json.dumps(update.to_dict(), indent=2, ensure_ascii=False)), html.escape(str(context.chat_data)), html.escape(str(context.user_data)), - html.escape(tb) + html.escape(tb), ) # Finally, send the message @@ -61,9 +62,10 @@ def bad_command(update: Update, context: CallbackContext): def start(update: Update, context: CallbackContext): - update.effective_message.reply_html('Use /bad_command to cause an error.\n' - 'Your chat id is {}.' - .format(update.effective_chat.id)) + update.effective_message.reply_html( + 'Use /bad_command to cause an error.\n' + 'Your chat id is {}.'.format(update.effective_chat.id) + ) def main(): diff --git a/examples/inlinebot.py b/examples/inlinebot.py index f65cd0aa4..dc5b63eca 100644 --- a/examples/inlinebot.py +++ b/examples/inlinebot.py @@ -15,14 +15,14 @@ bot. import logging from uuid import uuid4 -from telegram import InlineQueryResultArticle, ParseMode, \ - InputTextMessageContent +from telegram import InlineQueryResultArticle, ParseMode, InputTextMessageContent from telegram.ext import Updater, InlineQueryHandler, CommandHandler from telegram.utils.helpers import escape_markdown # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -44,22 +44,23 @@ def inlinequery(update, context): query = update.inline_query.query results = [ InlineQueryResultArticle( - id=uuid4(), - title="Caps", - input_message_content=InputTextMessageContent( - query.upper())), + id=uuid4(), title="Caps", input_message_content=InputTextMessageContent(query.upper()) + ), InlineQueryResultArticle( id=uuid4(), title="Bold", input_message_content=InputTextMessageContent( - "*{}*".format(escape_markdown(query)), - parse_mode=ParseMode.MARKDOWN)), + "*{}*".format(escape_markdown(query)), parse_mode=ParseMode.MARKDOWN + ), + ), InlineQueryResultArticle( id=uuid4(), title="Italic", input_message_content=InputTextMessageContent( - "_{}_".format(escape_markdown(query)), - parse_mode=ParseMode.MARKDOWN))] + "_{}_".format(escape_markdown(query)), parse_mode=ParseMode.MARKDOWN + ), + ), + ] update.inline_query.answer(results) diff --git a/examples/inlinekeyboard.py b/examples/inlinekeyboard.py index b5d2cdfb7..5eb452b64 100644 --- a/examples/inlinekeyboard.py +++ b/examples/inlinekeyboard.py @@ -10,16 +10,20 @@ import logging from telegram import InlineKeyboardButton, InlineKeyboardMarkup from telegram.ext import Updater, CommandHandler, CallbackQueryHandler -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) def start(update, context): - keyboard = [[InlineKeyboardButton("Option 1", callback_data='1'), - InlineKeyboardButton("Option 2", callback_data='2')], - - [InlineKeyboardButton("Option 3", callback_data='3')]] + keyboard = [ + [ + InlineKeyboardButton("Option 1", callback_data='1'), + InlineKeyboardButton("Option 2", callback_data='2'), + ], + [InlineKeyboardButton("Option 3", callback_data='3')], + ] reply_markup = InlineKeyboardMarkup(keyboard) diff --git a/examples/inlinekeyboard2.py b/examples/inlinekeyboard2.py index 1242f7066..aaca1bd89 100644 --- a/examples/inlinekeyboard2.py +++ b/examples/inlinekeyboard2.py @@ -17,8 +17,9 @@ from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, Conversa import logging # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -38,15 +39,14 @@ def start(update, context): # The keyboard is a list of button rows, where each row is in turn # a list (hence `[[...]]`). keyboard = [ - [InlineKeyboardButton("1", callback_data=str(ONE)), - InlineKeyboardButton("2", callback_data=str(TWO))] + [ + InlineKeyboardButton("1", callback_data=str(ONE)), + InlineKeyboardButton("2", callback_data=str(TWO)), + ] ] reply_markup = InlineKeyboardMarkup(keyboard) # Send message with text and appended InlineKeyboard - update.message.reply_text( - "Start handler, Choose a route", - reply_markup=reply_markup - ) + update.message.reply_text("Start handler, Choose a route", reply_markup=reply_markup) # Tell ConversationHandler that we're in state `FIRST` now return FIRST @@ -59,17 +59,16 @@ def start_over(update, context): # Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery query.answer() keyboard = [ - [InlineKeyboardButton("1", callback_data=str(ONE)), - InlineKeyboardButton("2", callback_data=str(TWO))] + [ + InlineKeyboardButton("1", callback_data=str(ONE)), + InlineKeyboardButton("2", callback_data=str(TWO)), + ] ] reply_markup = InlineKeyboardMarkup(keyboard) # Instead of sending a new message, edit the message that # originated the CallbackQuery. This gives the feeling of an # interactive menu. - query.edit_message_text( - text="Start handler, Choose a route", - reply_markup=reply_markup - ) + query.edit_message_text(text="Start handler, Choose a route", reply_markup=reply_markup) return FIRST @@ -78,13 +77,14 @@ def one(update, context): query = update.callback_query query.answer() keyboard = [ - [InlineKeyboardButton("3", callback_data=str(THREE)), - InlineKeyboardButton("4", callback_data=str(FOUR))] + [ + InlineKeyboardButton("3", callback_data=str(THREE)), + InlineKeyboardButton("4", callback_data=str(FOUR)), + ] ] reply_markup = InlineKeyboardMarkup(keyboard) query.edit_message_text( - text="First CallbackQueryHandler, Choose a route", - reply_markup=reply_markup + text="First CallbackQueryHandler, Choose a route", reply_markup=reply_markup ) return FIRST @@ -94,13 +94,14 @@ def two(update, context): query = update.callback_query query.answer() keyboard = [ - [InlineKeyboardButton("1", callback_data=str(ONE)), - InlineKeyboardButton("3", callback_data=str(THREE))] + [ + InlineKeyboardButton("1", callback_data=str(ONE)), + InlineKeyboardButton("3", callback_data=str(THREE)), + ] ] reply_markup = InlineKeyboardMarkup(keyboard) query.edit_message_text( - text="Second CallbackQueryHandler, Choose a route", - reply_markup=reply_markup + text="Second CallbackQueryHandler, Choose a route", reply_markup=reply_markup ) return FIRST @@ -110,13 +111,14 @@ def three(update, context): query = update.callback_query query.answer() keyboard = [ - [InlineKeyboardButton("Yes, let's do it again!", callback_data=str(ONE)), - InlineKeyboardButton("Nah, I've had enough ...", callback_data=str(TWO))] + [ + InlineKeyboardButton("Yes, let's do it again!", callback_data=str(ONE)), + InlineKeyboardButton("Nah, I've had enough ...", callback_data=str(TWO)), + ] ] reply_markup = InlineKeyboardMarkup(keyboard) query.edit_message_text( - text="Third CallbackQueryHandler. Do want to start over?", - reply_markup=reply_markup + text="Third CallbackQueryHandler. Do want to start over?", reply_markup=reply_markup ) # Transfer to conversation state `SECOND` return SECOND @@ -127,13 +129,14 @@ def four(update, context): query = update.callback_query query.answer() keyboard = [ - [InlineKeyboardButton("2", callback_data=str(TWO)), - InlineKeyboardButton("4", callback_data=str(FOUR))] + [ + InlineKeyboardButton("2", callback_data=str(TWO)), + InlineKeyboardButton("4", callback_data=str(FOUR)), + ] ] reply_markup = InlineKeyboardMarkup(keyboard) query.edit_message_text( - text="Fourth CallbackQueryHandler, Choose a route", - reply_markup=reply_markup + text="Fourth CallbackQueryHandler, Choose a route", reply_markup=reply_markup ) return FIRST @@ -143,9 +146,7 @@ def end(update, context): ConversationHandler that the conversation is over""" query = update.callback_query query.answer() - query.edit_message_text( - text="See you next time!" - ) + query.edit_message_text(text="See you next time!") return ConversationHandler.END @@ -165,14 +166,18 @@ def main(): conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], states={ - FIRST: [CallbackQueryHandler(one, pattern='^' + str(ONE) + '$'), - CallbackQueryHandler(two, pattern='^' + str(TWO) + '$'), - CallbackQueryHandler(three, pattern='^' + str(THREE) + '$'), - CallbackQueryHandler(four, pattern='^' + str(FOUR) + '$')], - SECOND: [CallbackQueryHandler(start_over, pattern='^' + str(ONE) + '$'), - CallbackQueryHandler(end, pattern='^' + str(TWO) + '$')] + FIRST: [ + CallbackQueryHandler(one, pattern='^' + str(ONE) + '$'), + CallbackQueryHandler(two, pattern='^' + str(TWO) + '$'), + CallbackQueryHandler(three, pattern='^' + str(THREE) + '$'), + CallbackQueryHandler(four, pattern='^' + str(FOUR) + '$'), + ], + SECOND: [ + CallbackQueryHandler(start_over, pattern='^' + str(ONE) + '$'), + CallbackQueryHandler(end, pattern='^' + str(TWO) + '$'), + ], }, - fallbacks=[CommandHandler('start', start)] + fallbacks=[CommandHandler('start', start)], ) # Add ConversationHandler to dispatcher that will be used for handling diff --git a/examples/nestedconversationbot.py b/examples/nestedconversationbot.py index d22f465cb..a50c8344a 100644 --- a/examples/nestedconversationbot.py +++ b/examples/nestedconversationbot.py @@ -16,13 +16,20 @@ bot. import logging -from telegram import (InlineKeyboardMarkup, InlineKeyboardButton) -from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, - ConversationHandler, CallbackQueryHandler) +from telegram import InlineKeyboardMarkup, InlineKeyboardButton +from telegram.ext import ( + Updater, + CommandHandler, + MessageHandler, + Filters, + ConversationHandler, + CallbackQueryHandler, +) # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -38,8 +45,20 @@ STOPPING, SHOWING = map(chr, range(8, 10)) END = ConversationHandler.END # Different constants for this example -(PARENTS, CHILDREN, SELF, GENDER, MALE, FEMALE, AGE, NAME, START_OVER, FEATURES, - CURRENT_FEATURE, CURRENT_LEVEL) = map(chr, range(10, 22)) +( + PARENTS, + CHILDREN, + SELF, + GENDER, + MALE, + FEMALE, + AGE, + NAME, + START_OVER, + FEATURES, + CURRENT_FEATURE, + CURRENT_LEVEL, +) = map(chr, range(10, 22)) # Helper @@ -53,15 +72,20 @@ def _name_switcher(level): # Top level conversation callbacks def start(update, context): """Select an action: Adding parent/child or show data.""" - text = 'You may add a familiy member, yourself show the gathered data or end the ' \ - 'conversation. To abort, simply type /stop.' - buttons = [[ - InlineKeyboardButton(text='Add family member', callback_data=str(ADDING_MEMBER)), - InlineKeyboardButton(text='Add yourself', callback_data=str(ADDING_SELF)) - ], [ - InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)), - InlineKeyboardButton(text='Done', callback_data=str(END)) - ]] + text = ( + 'You may add a familiy member, yourself show the gathered data or end the ' + 'conversation. To abort, simply type /stop.' + ) + buttons = [ + [ + InlineKeyboardButton(text='Add family member', callback_data=str(ADDING_MEMBER)), + InlineKeyboardButton(text='Add yourself', callback_data=str(ADDING_SELF)), + ], + [ + InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)), + InlineKeyboardButton(text='Done', callback_data=str(END)), + ], + ] keyboard = InlineKeyboardMarkup(buttons) # If we're starting over we don't need do send a new message @@ -69,8 +93,9 @@ def start(update, context): update.callback_query.answer() update.callback_query.edit_message_text(text=text, reply_markup=keyboard) else: - update.message.reply_text('Hi, I\'m FamiliyBot and here to help you gather information' - 'about your family.') + update.message.reply_text( + 'Hi, I\'m FamiliyBot and here to help you gather information' 'about your family.' + ) update.message.reply_text(text=text, reply_markup=keyboard) context.user_data[START_OVER] = False @@ -92,6 +117,7 @@ def adding_self(update, context): def show_data(update, context): """Pretty print gathered data.""" + def prettyprint(user_data, level): people = user_data.get(level) if not people: @@ -106,8 +132,9 @@ def show_data(update, context): for person in user_data[level]: gender = female if person[GENDER] == FEMALE else male - text += '\n{}: Name: {}, Age: {}'.format(gender, person.get(NAME, '-'), - person.get(AGE, '-')) + text += '\n{}: Name: {}, Age: {}'.format( + gender, person.get(NAME, '-'), person.get(AGE, '-') + ) return text ud = context.user_data @@ -115,9 +142,7 @@ def show_data(update, context): text += '\n\nParents:' + prettyprint(ud, PARENTS) text += '\n\nChildren:' + prettyprint(ud, CHILDREN) - buttons = [[ - InlineKeyboardButton(text='Back', callback_data=str(END)) - ]] + buttons = [[InlineKeyboardButton(text='Back', callback_data=str(END))]] keyboard = InlineKeyboardMarkup(buttons) update.callback_query.answer() @@ -148,13 +173,16 @@ def end(update, context): def select_level(update, context): """Choose to add a parent or a child.""" text = 'You may add a parent or a child. Also you can show the gathered data or go back.' - buttons = [[ - InlineKeyboardButton(text='Add parent', callback_data=str(PARENTS)), - InlineKeyboardButton(text='Add child', callback_data=str(CHILDREN)) - ], [ - InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)), - InlineKeyboardButton(text='Back', callback_data=str(END)) - ]] + buttons = [ + [ + InlineKeyboardButton(text='Add parent', callback_data=str(PARENTS)), + InlineKeyboardButton(text='Add child', callback_data=str(CHILDREN)), + ], + [ + InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)), + InlineKeyboardButton(text='Back', callback_data=str(END)), + ], + ] keyboard = InlineKeyboardMarkup(buttons) update.callback_query.answer() @@ -172,13 +200,16 @@ def select_gender(update, context): male, female = _name_switcher(level) - buttons = [[ - InlineKeyboardButton(text='Add ' + male, callback_data=str(MALE)), - InlineKeyboardButton(text='Add ' + female, callback_data=str(FEMALE)) - ], [ - InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)), - InlineKeyboardButton(text='Back', callback_data=str(END)) - ]] + buttons = [ + [ + InlineKeyboardButton(text='Add ' + male, callback_data=str(MALE)), + InlineKeyboardButton(text='Add ' + female, callback_data=str(FEMALE)), + ], + [ + InlineKeyboardButton(text='Show data', callback_data=str(SHOWING)), + InlineKeyboardButton(text='Back', callback_data=str(END)), + ], + ] keyboard = InlineKeyboardMarkup(buttons) update.callback_query.answer() @@ -198,11 +229,13 @@ def end_second_level(update, context): # Third level callbacks def select_feature(update, context): """Select a feature to update for the person.""" - buttons = [[ - InlineKeyboardButton(text='Name', callback_data=str(NAME)), - InlineKeyboardButton(text='Age', callback_data=str(AGE)), - InlineKeyboardButton(text='Done', callback_data=str(END)), - ]] + buttons = [ + [ + InlineKeyboardButton(text='Name', callback_data=str(NAME)), + InlineKeyboardButton(text='Age', callback_data=str(AGE)), + InlineKeyboardButton(text='Done', callback_data=str(END)), + ] + ] keyboard = InlineKeyboardMarkup(buttons) # If we collect features for a new person, clear the cache and save the gender @@ -278,46 +311,45 @@ def main(): # Set up third level ConversationHandler (collecting features) description_conv = ConversationHandler( - entry_points=[CallbackQueryHandler(select_feature, - pattern='^' + str(MALE) + '$|^' + str(FEMALE) + '$')], - + entry_points=[ + CallbackQueryHandler( + select_feature, pattern='^' + str(MALE) + '$|^' + str(FEMALE) + '$' + ) + ], states={ - SELECTING_FEATURE: [CallbackQueryHandler(ask_for_input, - pattern='^(?!' + str(END) + ').*$')], + SELECTING_FEATURE: [ + CallbackQueryHandler(ask_for_input, pattern='^(?!' + str(END) + ').*$') + ], TYPING: [MessageHandler(Filters.text & ~Filters.command, save_input)], }, - fallbacks=[ CallbackQueryHandler(end_describing, pattern='^' + str(END) + '$'), - CommandHandler('stop', stop_nested) + CommandHandler('stop', stop_nested), ], - map_to_parent={ # Return to second level menu END: SELECTING_LEVEL, # End conversation alltogether STOPPING: STOPPING, - } + }, ) # Set up second level ConversationHandler (adding a person) add_member_conv = ConversationHandler( - entry_points=[CallbackQueryHandler(select_level, - pattern='^' + str(ADDING_MEMBER) + '$')], - + entry_points=[CallbackQueryHandler(select_level, pattern='^' + str(ADDING_MEMBER) + '$')], states={ - SELECTING_LEVEL: [CallbackQueryHandler(select_gender, - pattern='^{}$|^{}$'.format(str(PARENTS), - str(CHILDREN)))], - SELECTING_GENDER: [description_conv] + SELECTING_LEVEL: [ + CallbackQueryHandler( + select_gender, pattern='^{}$|^{}$'.format(str(PARENTS), str(CHILDREN)) + ) + ], + SELECTING_GENDER: [description_conv], }, - fallbacks=[ CallbackQueryHandler(show_data, pattern='^' + str(SHOWING) + '$'), CallbackQueryHandler(end_second_level, pattern='^' + str(END) + '$'), - CommandHandler('stop', stop_nested) + CommandHandler('stop', stop_nested), ], - map_to_parent={ # After showing data return to top level menu SHOWING: SHOWING, @@ -325,7 +357,7 @@ def main(): END: SELECTING_ACTION, # End conversation alltogether STOPPING: END, - } + }, ) # Set up top level ConversationHandler (selecting action) @@ -339,7 +371,6 @@ def main(): ] conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], - states={ SHOWING: [CallbackQueryHandler(start, pattern='^' + str(END) + '$')], SELECTING_ACTION: selection_handlers, @@ -347,7 +378,6 @@ def main(): DESCRIBING_SELF: [description_conv], STOPPING: [CommandHandler('start', start)], }, - fallbacks=[CommandHandler('stop', stop)], ) diff --git a/examples/passportbot.py b/examples/passportbot.py index c66a97f69..22e512608 100644 --- a/examples/passportbot.py +++ b/examples/passportbot.py @@ -15,8 +15,9 @@ import logging from telegram.ext import Updater, MessageHandler, Filters # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.DEBUG) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG +) logger = logging.getLogger(__name__) @@ -39,18 +40,28 @@ def msg(update, context): print('Phone: ', data.phone_number) elif data.type == 'email': print('Email: ', data.email) - if data.type in ('personal_details', 'passport', 'driver_license', 'identity_card', - 'internal_passport', 'address'): + if data.type in ( + 'personal_details', + 'passport', + 'driver_license', + 'identity_card', + 'internal_passport', + 'address', + ): print(data.type, data.data) - if data.type in ('utility_bill', 'bank_statement', 'rental_agreement', - 'passport_registration', 'temporary_registration'): + if data.type in ( + 'utility_bill', + 'bank_statement', + 'rental_agreement', + 'passport_registration', + 'temporary_registration', + ): print(data.type, len(data.files), 'files') for file in data.files: actual_file = file.get_file() print(actual_file) actual_file.download() - if data.type in ('passport', 'driver_license', 'identity_card', - 'internal_passport'): + if data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport'): if data.front_side: file = data.front_side.get_file() print(data.type, file) @@ -60,16 +71,22 @@ def msg(update, context): file = data.reverse_side.get_file() print(data.type, file) file.download() - if data.type in ('passport', 'driver_license', 'identity_card', - 'internal_passport'): + if data.type in ('passport', 'driver_license', 'identity_card', 'internal_passport'): if data.selfie: file = data.selfie.get_file() print(data.type, file) file.download() - if data.type in ('passport', 'driver_license', 'identity_card', - 'internal_passport', 'utility_bill', 'bank_statement', - 'rental_agreement', 'passport_registration', - 'temporary_registration'): + if data.type in ( + 'passport', + 'driver_license', + 'identity_card', + 'internal_passport', + 'utility_bill', + 'bank_statement', + 'rental_agreement', + 'passport_registration', + 'temporary_registration', + ): print(data.type, len(data.translation), 'translation') for file in data.translation: actual_file = file.get_file() diff --git a/examples/paymentbot.py b/examples/paymentbot.py index ae873c931..b6879b381 100644 --- a/examples/paymentbot.py +++ b/examples/paymentbot.py @@ -8,13 +8,20 @@ Basic example for a bot that can receive payment from user. import logging -from telegram import (LabeledPrice, ShippingOption) -from telegram.ext import (Updater, CommandHandler, MessageHandler, - Filters, PreCheckoutQueryHandler, ShippingQueryHandler) +from telegram import LabeledPrice, ShippingOption +from telegram.ext import ( + Updater, + CommandHandler, + MessageHandler, + Filters, + PreCheckoutQueryHandler, + ShippingQueryHandler, +) # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -43,10 +50,21 @@ def start_with_shipping_callback(update, context): # optionally pass need_name=True, need_phone_number=True, # need_email=True, need_shipping_address=True, is_flexible=True - context.bot.send_invoice(chat_id, title, description, payload, - provider_token, start_parameter, currency, prices, - need_name=True, need_phone_number=True, - need_email=True, need_shipping_address=True, is_flexible=True) + context.bot.send_invoice( + chat_id, + title, + description, + payload, + provider_token, + start_parameter, + currency, + prices, + need_name=True, + need_phone_number=True, + need_email=True, + need_shipping_address=True, + is_flexible=True, + ) def start_without_shipping_callback(update, context): @@ -66,8 +84,9 @@ def start_without_shipping_callback(update, context): # optionally pass need_name=True, need_phone_number=True, # need_email=True, need_shipping_address=True, is_flexible=True - context.bot.send_invoice(chat_id, title, description, payload, - provider_token, start_parameter, currency, prices) + context.bot.send_invoice( + chat_id, title, description, payload, provider_token, start_parameter, currency, prices + ) def shipping_callback(update, context): diff --git a/examples/persistentconversationbot.py b/examples/persistentconversationbot.py index 6c1ff3d07..4ea39b9da 100644 --- a/examples/persistentconversationbot.py +++ b/examples/persistentconversationbot.py @@ -15,22 +15,31 @@ bot. """ from telegram import ReplyKeyboardMarkup -from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, - ConversationHandler, PicklePersistence) +from telegram.ext import ( + Updater, + CommandHandler, + MessageHandler, + Filters, + ConversationHandler, + PicklePersistence, +) import logging # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) CHOOSING, TYPING_REPLY, TYPING_CHOICE = range(3) -reply_keyboard = [['Age', 'Favourite colour'], - ['Number of siblings', 'Something else...'], - ['Done']] +reply_keyboard = [ + ['Age', 'Favourite colour'], + ['Number of siblings', 'Something else...'], + ['Done'], +] markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True) @@ -46,12 +55,16 @@ def facts_to_str(user_data): def start(update, context): reply_text = "Hi! My name is Doctor Botter." if context.user_data: - reply_text += " You already told me your {}. Why don't you tell me something more " \ - "about yourself? Or change anything I " \ - "already know.".format(", ".join(context.user_data.keys())) + reply_text += ( + " You already told me your {}. Why don't you tell me something more " + "about yourself? Or change anything I " + "already know.".format(", ".join(context.user_data.keys())) + ) else: - reply_text += " I will hold a more complex conversation with you. Why don't you tell me " \ - "something about yourself?" + reply_text += ( + " I will hold a more complex conversation with you. Why don't you tell me " + "something about yourself?" + ) update.message.reply_text(reply_text, reply_markup=markup) return CHOOSING @@ -61,8 +74,9 @@ def regular_choice(update, context): text = update.message.text.lower() context.user_data['choice'] = text if context.user_data.get(text): - reply_text = 'Your {}, I already know the following ' \ - 'about that: {}'.format(text, context.user_data[text]) + reply_text = 'Your {}, I already know the following ' 'about that: {}'.format( + text, context.user_data[text] + ) else: reply_text = 'Your {}? Yes, I would love to hear about that!'.format(text) update.message.reply_text(reply_text) @@ -71,8 +85,9 @@ def regular_choice(update, context): def custom_choice(update, context): - update.message.reply_text('Alright, please send me the category first, ' - 'for example "Most impressive skill"') + update.message.reply_text( + 'Alright, please send me the category first, ' 'for example "Most impressive skill"' + ) return TYPING_CHOICE @@ -83,27 +98,32 @@ def received_information(update, context): context.user_data[category] = text.lower() del context.user_data['choice'] - update.message.reply_text("Neat! Just so you know, this is what you already told me:" - "{}" - "You can tell me more, or change your opinion on " - "something.".format(facts_to_str(context.user_data)), - reply_markup=markup) + update.message.reply_text( + "Neat! Just so you know, this is what you already told me:" + "{}" + "You can tell me more, or change your opinion on " + "something.".format(facts_to_str(context.user_data)), + reply_markup=markup, + ) return CHOOSING def show_data(update, context): - update.message.reply_text("This is what you already told me:" - "{}".format(facts_to_str(context.user_data))) + update.message.reply_text( + "This is what you already told me:" "{}".format(facts_to_str(context.user_data)) + ) def done(update, context): if 'choice' in context.user_data: del context.user_data['choice'] - update.message.reply_text("I learned these facts about you:" - "{}" - "Until next time!".format(facts_to_str(context.user_data))) + update.message.reply_text( + "I learned these facts about you:" + "{}" + "Until next time!".format(facts_to_str(context.user_data)) + ) return ConversationHandler.END @@ -118,26 +138,28 @@ def main(): # Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], - states={ - CHOOSING: [MessageHandler(Filters.regex('^(Age|Favourite colour|Number of siblings)$'), - regular_choice), - MessageHandler(Filters.regex('^Something else...$'), - custom_choice), - ], - + CHOOSING: [ + MessageHandler( + Filters.regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice + ), + MessageHandler(Filters.regex('^Something else...$'), custom_choice), + ], TYPING_CHOICE: [ - MessageHandler(Filters.text & ~(Filters.command | Filters.regex('^Done$')), - regular_choice)], - + MessageHandler( + Filters.text & ~(Filters.command | Filters.regex('^Done$')), regular_choice + ) + ], TYPING_REPLY: [ - MessageHandler(Filters.text & ~(Filters.command | Filters.regex('^Done$')), - received_information)], + MessageHandler( + Filters.text & ~(Filters.command | Filters.regex('^Done$')), + received_information, + ) + ], }, - fallbacks=[MessageHandler(Filters.regex('^Done$'), done)], name="my_conversation", - persistent=True + persistent=True, ) dp.add_handler(conv_handler) diff --git a/examples/pollbot.py b/examples/pollbot.py index 1560bf3b9..b31fdbe73 100644 --- a/examples/pollbot.py +++ b/examples/pollbot.py @@ -9,30 +9,56 @@ one the user sends the bot """ import logging -from telegram import (Poll, ParseMode, KeyboardButton, KeyboardButtonPollType, - ReplyKeyboardMarkup, ReplyKeyboardRemove) -from telegram.ext import (Updater, CommandHandler, PollAnswerHandler, PollHandler, MessageHandler, - Filters) +from telegram import ( + Poll, + ParseMode, + KeyboardButton, + KeyboardButtonPollType, + ReplyKeyboardMarkup, + ReplyKeyboardRemove, +) +from telegram.ext import ( + Updater, + CommandHandler, + PollAnswerHandler, + PollHandler, + MessageHandler, + Filters, +) -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) def start(update, context): """Inform user about what this bot can do""" - update.message.reply_text('Please select /poll to get a Poll, /quiz to get a Quiz or /preview' - ' to generate a preview for your poll') + update.message.reply_text( + 'Please select /poll to get a Poll, /quiz to get a Quiz or /preview' + ' to generate a preview for your poll' + ) def poll(update, context): """Sends a predefined poll""" questions = ["Good", "Really good", "Fantastic", "Great"] - message = context.bot.send_poll(update.effective_chat.id, "How are you?", questions, - is_anonymous=False, allows_multiple_answers=True) + message = context.bot.send_poll( + update.effective_chat.id, + "How are you?", + questions, + is_anonymous=False, + allows_multiple_answers=True, + ) # Save some info about the poll the bot_data for later use in receive_poll_answer - payload = {message.poll.id: {"questions": questions, "message_id": message.message_id, - "chat_id": update.effective_chat.id, "answers": 0}} + payload = { + message.poll.id: { + "questions": questions, + "message_id": message.message_id, + "chat_id": update.effective_chat.id, + "answers": 0, + } + } context.bot_data.update(payload) @@ -52,25 +78,29 @@ def receive_poll_answer(update, context): answer_string += questions[question_id] + " and " else: answer_string += questions[question_id] - context.bot.send_message(context.bot_data[poll_id]["chat_id"], - "{} feels {}!".format(update.effective_user.mention_html(), - answer_string), - parse_mode=ParseMode.HTML) + context.bot.send_message( + context.bot_data[poll_id]["chat_id"], + "{} feels {}!".format(update.effective_user.mention_html(), answer_string), + parse_mode=ParseMode.HTML, + ) context.bot_data[poll_id]["answers"] += 1 # Close poll after three participants voted if context.bot_data[poll_id]["answers"] == 3: - context.bot.stop_poll(context.bot_data[poll_id]["chat_id"], - context.bot_data[poll_id]["message_id"]) + context.bot.stop_poll( + context.bot_data[poll_id]["chat_id"], context.bot_data[poll_id]["message_id"] + ) def quiz(update, context): """Send a predefined poll""" questions = ["1", "2", "4", "20"] - message = update.effective_message.reply_poll("How many eggs do you need for a cake?", - questions, type=Poll.QUIZ, correct_option_id=2) + message = update.effective_message.reply_poll( + "How many eggs do you need for a cake?", questions, type=Poll.QUIZ, correct_option_id=2 + ) # Save some info about the poll the bot_data for later use in receive_quiz_answer - payload = {message.poll.id: {"chat_id": update.effective_chat.id, - "message_id": message.message_id}} + payload = { + message.poll.id: {"chat_id": update.effective_chat.id, "message_id": message.message_id} + } context.bot_data.update(payload) @@ -94,9 +124,9 @@ def preview(update, context): button = [[KeyboardButton("Press me!", request_poll=KeyboardButtonPollType())]] message = "Press the button to let the bot generate a preview for your poll" # using one_time_keyboard to hide the keyboard - update.effective_message.reply_text(message, - reply_markup=ReplyKeyboardMarkup(button, - one_time_keyboard=True)) + update.effective_message.reply_text( + message, reply_markup=ReplyKeyboardMarkup(button, one_time_keyboard=True) + ) def receive_poll(update, context): @@ -109,14 +139,13 @@ def receive_poll(update, context): options=[o.text for o in actual_poll.options], # with is_closed true, the poll/quiz is immediately closed is_closed=True, - reply_markup=ReplyKeyboardRemove() + reply_markup=ReplyKeyboardRemove(), ) def help_handler(update, context): """Display a help message""" - update.message.reply_text("Use /quiz, /poll or /preview to test this " - "bot.") + update.message.reply_text("Use /quiz, /poll or /preview to test this " "bot.") def main(): diff --git a/examples/timerbot.py b/examples/timerbot.py index 1baddacc5..318bbaf30 100644 --- a/examples/timerbot.py +++ b/examples/timerbot.py @@ -23,8 +23,9 @@ import logging from telegram.ext import Updater, CommandHandler # Enable logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO +) logger = logging.getLogger(__name__) @@ -90,10 +91,9 @@ def main(): # on different commands - answer in Telegram dp.add_handler(CommandHandler("start", start)) dp.add_handler(CommandHandler("help", start)) - dp.add_handler(CommandHandler("set", set_timer, - pass_args=True, - pass_job_queue=True, - pass_chat_data=True)) + dp.add_handler( + CommandHandler("set", set_timer, pass_args=True, pass_job_queue=True, pass_chat_data=True) + ) dp.add_handler(CommandHandler("unset", unset, pass_chat_data=True)) # Start the Bot diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..0e944ee55 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,6 @@ +[tool.black] +line-length = 99 +target-version = ['py36'] +include = '(telegram|examples|tests)/.*\.py$' +exclude = 'telegram/vendor' +skip-string-normalization = true \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 6cb212922..85b1ff7d4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,13 +15,9 @@ upload-dir = docs/build/html [flake8] max-line-length = 99 ignore = W503, W605 +extend-ignore = E203 exclude = setup.py, docs/source/conf.py -[yapf] -based_on_style = google -split_before_logical_operator = True -column_limit = 99 - [tool:pytest] testpaths = tests addopts = --no-success-flaky-report -rsxX diff --git a/telegram/__init__.py b/telegram/__init__.py index 1e493ab8b..a9f8d4e9b 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -102,63 +102,170 @@ from .payment.shippingquery import ShippingQuery from .webhookinfo import WebhookInfo from .games.gamehighscore import GameHighScore from .update import Update -from .files.inputmedia import (InputMedia, InputMediaVideo, InputMediaPhoto, InputMediaAnimation, - InputMediaAudio, InputMediaDocument) -from .constants import (MAX_MESSAGE_LENGTH, MAX_CAPTION_LENGTH, SUPPORTED_WEBHOOK_PORTS, - MAX_FILESIZE_DOWNLOAD, MAX_FILESIZE_UPLOAD, - MAX_MESSAGES_PER_SECOND_PER_CHAT, MAX_MESSAGES_PER_SECOND, - MAX_MESSAGES_PER_MINUTE_PER_GROUP) -from .passport.passportelementerrors import (PassportElementError, - PassportElementErrorDataField, - PassportElementErrorFile, - PassportElementErrorFiles, - PassportElementErrorFrontSide, - PassportElementErrorReverseSide, - PassportElementErrorSelfie, - PassportElementErrorTranslationFile, - PassportElementErrorTranslationFiles, - PassportElementErrorUnspecified) -from .passport.credentials import (Credentials, - DataCredentials, - SecureData, - FileCredentials, - TelegramDecryptionError) +from .files.inputmedia import ( + InputMedia, + InputMediaVideo, + InputMediaPhoto, + InputMediaAnimation, + InputMediaAudio, + InputMediaDocument, +) +from .constants import ( + MAX_MESSAGE_LENGTH, + MAX_CAPTION_LENGTH, + SUPPORTED_WEBHOOK_PORTS, + MAX_FILESIZE_DOWNLOAD, + MAX_FILESIZE_UPLOAD, + MAX_MESSAGES_PER_SECOND_PER_CHAT, + MAX_MESSAGES_PER_SECOND, + MAX_MESSAGES_PER_MINUTE_PER_GROUP, +) +from .passport.passportelementerrors import ( + PassportElementError, + PassportElementErrorDataField, + PassportElementErrorFile, + PassportElementErrorFiles, + PassportElementErrorFrontSide, + PassportElementErrorReverseSide, + PassportElementErrorSelfie, + PassportElementErrorTranslationFile, + PassportElementErrorTranslationFiles, + PassportElementErrorUnspecified, +) +from .passport.credentials import ( + Credentials, + DataCredentials, + SecureData, + FileCredentials, + TelegramDecryptionError, +) from .bot import Bot from .version import __version__ # noqa: F401 __author__ = 'devs@python-telegram-bot.org' __all__ = [ - 'Audio', 'Bot', 'Chat', 'ChatMember', 'ChatPermissions', 'ChatAction', 'ChosenInlineResult', - 'CallbackQuery', 'Contact', 'Document', 'File', 'ForceReply', 'InlineKeyboardButton', - 'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult', 'InlineQueryResult', - 'InlineQueryResultArticle', 'InlineQueryResultAudio', 'InlineQueryResultCachedAudio', - 'InlineQueryResultCachedDocument', 'InlineQueryResultCachedGif', - 'InlineQueryResultCachedMpeg4Gif', 'InlineQueryResultCachedPhoto', - 'InlineQueryResultCachedSticker', 'InlineQueryResultCachedVideo', - 'InlineQueryResultCachedVoice', 'InlineQueryResultContact', 'InlineQueryResultDocument', - 'InlineQueryResultGif', 'InlineQueryResultLocation', 'InlineQueryResultMpeg4Gif', - 'InlineQueryResultPhoto', 'InlineQueryResultVenue', 'InlineQueryResultVideo', - 'InlineQueryResultVoice', 'InlineQueryResultGame', 'InputContactMessageContent', 'InputFile', - 'InputLocationMessageContent', 'InputMessageContent', 'InputTextMessageContent', - 'InputVenueMessageContent', 'Location', 'EncryptedCredentials', - 'PassportFile', 'EncryptedPassportElement', 'PassportData', 'Message', 'MessageEntity', - 'ParseMode', 'PhotoSize', 'ReplyKeyboardRemove', 'ReplyKeyboardMarkup', 'ReplyMarkup', - 'Sticker', 'TelegramError', 'TelegramObject', 'Update', 'User', 'UserProfilePhotos', 'Venue', - 'Video', 'Voice', 'MAX_MESSAGE_LENGTH', 'MAX_CAPTION_LENGTH', 'SUPPORTED_WEBHOOK_PORTS', - 'MAX_FILESIZE_DOWNLOAD', 'MAX_FILESIZE_UPLOAD', 'MAX_MESSAGES_PER_SECOND_PER_CHAT', - 'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', 'WebhookInfo', 'Animation', - 'Game', 'GameHighScore', 'VideoNote', 'LabeledPrice', 'SuccessfulPayment', 'ShippingOption', - 'ShippingAddress', 'PreCheckoutQuery', 'OrderInfo', 'Invoice', 'ShippingQuery', 'ChatPhoto', - 'StickerSet', 'MaskPosition', 'CallbackGame', 'InputMedia', 'InputMediaPhoto', - 'InputMediaVideo', 'PassportElementError', 'PassportElementErrorFile', - 'PassportElementErrorReverseSide', 'PassportElementErrorFrontSide', - 'PassportElementErrorFiles', 'PassportElementErrorDataField', 'PassportElementErrorFile', - 'Credentials', 'DataCredentials', 'SecureData', 'FileCredentials', 'IdDocumentData', - 'PersonalDetails', 'ResidentialAddress', 'InputMediaVideo', 'InputMediaAnimation', - 'InputMediaAudio', 'InputMediaDocument', 'TelegramDecryptionError', - 'PassportElementErrorSelfie', 'PassportElementErrorTranslationFile', - 'PassportElementErrorTranslationFiles', 'PassportElementErrorUnspecified', 'Poll', - 'PollOption', 'PollAnswer', 'LoginUrl', 'KeyboardButton', 'KeyboardButtonPollType', 'Dice', - 'BotCommand' + 'Audio', + 'Bot', + 'Chat', + 'ChatMember', + 'ChatPermissions', + 'ChatAction', + 'ChosenInlineResult', + 'CallbackQuery', + 'Contact', + 'Document', + 'File', + 'ForceReply', + 'InlineKeyboardButton', + 'InlineKeyboardMarkup', + 'InlineQuery', + 'InlineQueryResult', + 'InlineQueryResult', + 'InlineQueryResultArticle', + 'InlineQueryResultAudio', + 'InlineQueryResultCachedAudio', + 'InlineQueryResultCachedDocument', + 'InlineQueryResultCachedGif', + 'InlineQueryResultCachedMpeg4Gif', + 'InlineQueryResultCachedPhoto', + 'InlineQueryResultCachedSticker', + 'InlineQueryResultCachedVideo', + 'InlineQueryResultCachedVoice', + 'InlineQueryResultContact', + 'InlineQueryResultDocument', + 'InlineQueryResultGif', + 'InlineQueryResultLocation', + 'InlineQueryResultMpeg4Gif', + 'InlineQueryResultPhoto', + 'InlineQueryResultVenue', + 'InlineQueryResultVideo', + 'InlineQueryResultVoice', + 'InlineQueryResultGame', + 'InputContactMessageContent', + 'InputFile', + 'InputLocationMessageContent', + 'InputMessageContent', + 'InputTextMessageContent', + 'InputVenueMessageContent', + 'Location', + 'EncryptedCredentials', + 'PassportFile', + 'EncryptedPassportElement', + 'PassportData', + 'Message', + 'MessageEntity', + 'ParseMode', + 'PhotoSize', + 'ReplyKeyboardRemove', + 'ReplyKeyboardMarkup', + 'ReplyMarkup', + 'Sticker', + 'TelegramError', + 'TelegramObject', + 'Update', + 'User', + 'UserProfilePhotos', + 'Venue', + 'Video', + 'Voice', + 'MAX_MESSAGE_LENGTH', + 'MAX_CAPTION_LENGTH', + 'SUPPORTED_WEBHOOK_PORTS', + 'MAX_FILESIZE_DOWNLOAD', + 'MAX_FILESIZE_UPLOAD', + 'MAX_MESSAGES_PER_SECOND_PER_CHAT', + 'MAX_MESSAGES_PER_SECOND', + 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', + 'WebhookInfo', + 'Animation', + 'Game', + 'GameHighScore', + 'VideoNote', + 'LabeledPrice', + 'SuccessfulPayment', + 'ShippingOption', + 'ShippingAddress', + 'PreCheckoutQuery', + 'OrderInfo', + 'Invoice', + 'ShippingQuery', + 'ChatPhoto', + 'StickerSet', + 'MaskPosition', + 'CallbackGame', + 'InputMedia', + 'InputMediaPhoto', + 'InputMediaVideo', + 'PassportElementError', + 'PassportElementErrorFile', + 'PassportElementErrorReverseSide', + 'PassportElementErrorFrontSide', + 'PassportElementErrorFiles', + 'PassportElementErrorDataField', + 'PassportElementErrorFile', + 'Credentials', + 'DataCredentials', + 'SecureData', + 'FileCredentials', + 'IdDocumentData', + 'PersonalDetails', + 'ResidentialAddress', + 'InputMediaVideo', + 'InputMediaAnimation', + 'InputMediaAudio', + 'InputMediaDocument', + 'TelegramDecryptionError', + 'PassportElementErrorSelfie', + 'PassportElementErrorTranslationFile', + 'PassportElementErrorTranslationFiles', + 'PassportElementErrorUnspecified', + 'Poll', + 'PollOption', + 'PollAnswer', + 'LoginUrl', + 'KeyboardButton', + 'KeyboardButtonPollType', + 'Dice', + 'BotCommand', ] diff --git a/telegram/__main__.py b/telegram/__main__.py index 831aaa046..50af21c35 100644 --- a/telegram/__main__.py +++ b/telegram/__main__.py @@ -28,8 +28,9 @@ from . import __version__ as telegram_ver def _git_revision() -> Optional[str]: try: - output = subprocess.check_output(["git", "describe", "--long", "--tags"], - stderr=subprocess.STDOUT) + output = subprocess.check_output( + ["git", "describe", "--long", "--tags"], stderr=subprocess.STDOUT + ) except (subprocess.SubprocessError, OSError): return None return output.decode().strip() @@ -37,8 +38,10 @@ def _git_revision() -> Optional[str]: def print_ver_info() -> None: git_revision = _git_revision() - print('python-telegram-bot {}'.format(telegram_ver) + (' ({})'.format(git_revision) - if git_revision else '')) + print( + 'python-telegram-bot {}'.format(telegram_ver) + + (' ({})'.format(git_revision) if git_revision else '') + ) print('certifi {}'.format(certifi.__version__)) # type: ignore[attr-defined] print('Python {}'.format(sys.version.replace('\n', ' '))) diff --git a/telegram/base.py b/telegram/base.py index 558793918..884c06d3b 100644 --- a/telegram/base.py +++ b/telegram/base.py @@ -66,9 +66,7 @@ class TelegramObject: return cls(bot=bot, **data) # type: ignore[call-arg] @classmethod - def de_list(cls: Type[TO], - data: Optional[List[JSONDict]], - bot: 'Bot') -> List[Optional[TO]]: + def de_list(cls: Type[TO], data: Optional[List[JSONDict]], bot: 'Bot') -> List[Optional[TO]]: if not data: return [] @@ -104,11 +102,15 @@ class TelegramObject: def __eq__(self, other: object) -> bool: if isinstance(other, self.__class__): if self._id_attrs == (): - warnings.warn("Objects of type {} can not be meaningfully tested for " - "equivalence.".format(self.__class__.__name__)) + warnings.warn( + "Objects of type {} can not be meaningfully tested for " + "equivalence.".format(self.__class__.__name__) + ) if other._id_attrs == (): - warnings.warn("Objects of type {} can not be meaningfully tested for " - "equivalence.".format(other.__class__.__name__)) + warnings.warn( + "Objects of type {} can not be meaningfully tested for " + "equivalence.".format(other.__class__.__name__) + ) return self._id_attrs == other._id_attrs return super().__eq__(other) # pylint: disable=no-member diff --git a/telegram/bot.py b/telegram/bot.py index 62aa89285..03e39889b 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -35,20 +35,62 @@ from datetime import datetime from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization -from telegram import (User, Message, Update, Chat, ChatMember, UserProfilePhotos, File, - ReplyMarkup, TelegramObject, WebhookInfo, GameHighScore, StickerSet, - PhotoSize, Audio, Document, Sticker, Video, Animation, Voice, VideoNote, - Location, Venue, Contact, InputFile, Poll, BotCommand, - InlineQueryResult, InputMedia, PassportElementError, MaskPosition, - ChatPermissions, ShippingOption, LabeledPrice, ChatPhoto) +from telegram import ( + User, + Message, + Update, + Chat, + ChatMember, + UserProfilePhotos, + File, + ReplyMarkup, + TelegramObject, + WebhookInfo, + GameHighScore, + StickerSet, + PhotoSize, + Audio, + Document, + Sticker, + Video, + Animation, + Voice, + VideoNote, + Location, + Venue, + Contact, + InputFile, + Poll, + BotCommand, + InlineQueryResult, + InputMedia, + PassportElementError, + MaskPosition, + ChatPermissions, + ShippingOption, + LabeledPrice, + ChatPhoto, +) from telegram.constants import MAX_INLINE_QUERY_RESULTS from telegram.error import InvalidToken, TelegramError from telegram.utils.helpers import to_timestamp, DEFAULT_NONE, DefaultValue from telegram.utils.request import Request from telegram.utils.types import JSONDict, FileLike -from typing import (Any, Callable, Optional, TypeVar, Union, TYPE_CHECKING, List, Tuple, - no_type_check, IO, cast) +from typing import ( + Any, + Callable, + Optional, + TypeVar, + Union, + TYPE_CHECKING, + List, + Tuple, + no_type_check, + IO, + cast, +) + if TYPE_CHECKING: from telegram.ext import Defaults @@ -119,16 +161,16 @@ class Bot(TelegramObject): for method_name, method in inspect.getmembers(instance, predicate=inspect.ismethod): # ... get kwargs argspec = inspect.getfullargspec(method) - kwarg_names = argspec.args[-len(argspec.defaults or []):] + kwarg_names = argspec.args[-len(argspec.defaults or []) :] # ... check if Defaults has a attribute that matches the kwarg name needs_default = [ kwarg_name for kwarg_name in kwarg_names if hasattr(defaults, kwarg_name) ] # ... make a dict of kwarg name and the default value default_kwargs = { - kwarg_name: getattr(defaults, kwarg_name) for kwarg_name in needs_default if ( - getattr(defaults, kwarg_name) is not DEFAULT_NONE - ) + kwarg_name: getattr(defaults, kwarg_name) + for kwarg_name in needs_default + if (getattr(defaults, kwarg_name) is not DEFAULT_NONE) } # ... apply the defaults using a partial if default_kwargs: @@ -136,14 +178,16 @@ class Bot(TelegramObject): return instance - def __init__(self, - token: str, - base_url: str = None, - base_file_url: str = None, - request: 'Request' = None, - private_key: bytes = None, - private_key_password: bytes = None, - defaults: 'Defaults' = None): + def __init__( + self, + token: str, + base_url: str = None, + base_file_url: str = None, + request: 'Request' = None, + private_key: bytes = None, + private_key_password: bytes = None, + defaults: 'Defaults' = None, + ): self.token = self._validate_token(token) # Gather default @@ -163,15 +207,17 @@ class Bot(TelegramObject): self.logger = logging.getLogger(__name__) if private_key: - self.private_key = serialization.load_pem_private_key(private_key, - password=private_key_password, - backend=default_backend()) + self.private_key = serialization.load_pem_private_key( + private_key, password=private_key_password, backend=default_backend() + ) - def _post(self, - endpoint: str, - data: JSONDict = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[bool, JSONDict, None]: + def _post( + self, + endpoint: str, + data: JSONDict = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[bool, JSONDict, None]: if data is None: data = {} @@ -181,17 +227,20 @@ class Bot(TelegramObject): else: data = api_kwargs - return self.request.post('{}/{}'.format(self.base_url, endpoint), data=data, - timeout=timeout) + return self.request.post( + '{}/{}'.format(self.base_url, endpoint), data=data, timeout=timeout + ) - def _message(self, - endpoint: str, - data: JSONDict, - reply_to_message_id: Union[str, int] = None, - disable_notification: bool = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[bool, Message, None]: + def _message( + self, + endpoint: str, + data: JSONDict, + reply_to_message_id: Union[str, int] = None, + disable_notification: bool = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[bool, Message, None]: if reply_to_message_id is not None: data['reply_to_message_id'] = reply_to_message_id @@ -330,16 +379,18 @@ class Bot(TelegramObject): return self.bot @log - def send_message(self, - chat_id: Union[int, str], - text: str, - parse_mode: str = None, - disable_web_page_preview: bool = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_message( + self, + chat_id: Union[int, str], + text: str, + parse_mode: str = None, + disable_web_page_preview: bool = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """Use this method to send text messages. Args: @@ -379,17 +430,24 @@ class Bot(TelegramObject): if disable_web_page_preview: data['disable_web_page_preview'] = disable_web_page_preview - return self._message('sendMessage', data, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - timeout=timeout, api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendMessage', + data, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + timeout=timeout, + api_kwargs=api_kwargs, + ) @log - def delete_message(self, - chat_id: Union[str, int], - message_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def delete_message( + self, + chat_id: Union[str, int], + message_id: Union[str, int], + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to delete a message, including service messages, with the following limitations: @@ -428,13 +486,15 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def forward_message(self, - chat_id: Union[int, str], - from_chat_id: Union[str, int], - message_id: Union[str, int], - disable_notification: bool = False, - timeout: float = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def forward_message( + self, + chat_id: Union[int, str], + from_chat_id: Union[str, int], + message_id: Union[str, int], + disable_notification: bool = False, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """Use this method to forward messages of any kind. Args: @@ -467,21 +527,27 @@ class Bot(TelegramObject): if message_id: data['message_id'] = message_id - return self._message('forwardMessage', data, # type: ignore[return-value] - disable_notification=disable_notification, - timeout=timeout, api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'forwardMessage', + data, + disable_notification=disable_notification, + timeout=timeout, + api_kwargs=api_kwargs, + ) @log - def send_photo(self, - chat_id: int, - photo: Union[str, PhotoSize, IO], - caption: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - parse_mode: str = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_photo( + self, + chat_id: int, + photo: Union[str, PhotoSize, IO], + caption: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + parse_mode: str = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """Use this method to send photos. Note: @@ -532,27 +598,33 @@ class Bot(TelegramObject): if parse_mode: data['parse_mode'] = parse_mode - return self._message('sendPhoto', data, # type: ignore[return-value] - timeout=timeout, - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendPhoto', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_audio(self, - chat_id: Union[int, str], - audio: Union[str, Audio, FileLike], - duration: int = None, - performer: str = None, - title: str = None, - caption: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - parse_mode: str = None, - thumb: FileLike = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_audio( + self, + chat_id: Union[int, str], + audio: Union[str, Audio, FileLike], + duration: int = None, + performer: str = None, + title: str = None, + caption: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + parse_mode: str = None, + thumb: FileLike = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """ Use this method to send audio files, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 or .m4a format. @@ -629,25 +701,31 @@ class Bot(TelegramObject): thumb = InputFile(thumb, attach=True) data['thumb'] = thumb - return self._message('sendAudio', data, # type: ignore[return-value] - timeout=timeout, - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendAudio', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_document(self, - chat_id: Union[int, str], - document: Union[str, Document, FileLike], - filename: str = None, - caption: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - parse_mode: str = None, - thumb: FileLike = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_document( + self, + chat_id: Union[int, str], + document: Union[str, Document, FileLike], + filename: str = None, + caption: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + parse_mode: str = None, + thumb: FileLike = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """ Use this method to send general files. @@ -714,20 +792,27 @@ class Bot(TelegramObject): thumb = InputFile(thumb, attach=True) data['thumb'] = thumb - return self._message('sendDocument', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendDocument', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_sticker(self, - chat_id: Union[int, str], - sticker: Union[str, Sticker, FileLike], - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_sticker( + self, + chat_id: Union[int, str], + sticker: Union[str, Sticker, FileLike], + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """ Use this method to send static .WEBP or animated .TGS stickers. @@ -769,27 +854,34 @@ class Bot(TelegramObject): data: JSONDict = {'chat_id': chat_id, 'sticker': sticker} - return self._message('sendSticker', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendSticker', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_video(self, - chat_id: Union[int, str], - video: Union[str, Video, FileLike], - duration: int = None, - caption: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - width: int = None, - height: int = None, - parse_mode: str = None, - supports_streaming: bool = None, - thumb: FileLike = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_video( + self, + chat_id: Union[int, str], + video: Union[str, Video, FileLike], + duration: int = None, + caption: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + width: int = None, + height: int = None, + parse_mode: str = None, + supports_streaming: bool = None, + thumb: FileLike = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """ Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). @@ -871,24 +963,30 @@ class Bot(TelegramObject): thumb = InputFile(thumb, attach=True) data['thumb'] = thumb - return self._message('sendVideo', data, # type: ignore[return-value] - timeout=timeout, - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendVideo', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_video_note(self, - chat_id: Union[int, str], - video_note: Union[str, FileLike, VideoNote], - duration: int = None, - length: int = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - thumb: FileLike = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_video_note( + self, + chat_id: Union[int, str], + video_note: Union[str, FileLike, VideoNote], + duration: int = None, + length: int = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + thumb: FileLike = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """ As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send video messages. @@ -952,26 +1050,33 @@ class Bot(TelegramObject): thumb = InputFile(thumb, attach=True) data['thumb'] = thumb - return self._message('sendVideoNote', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendVideoNote', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_animation(self, - chat_id: Union[int, str], - animation: Union[str, FileLike, Animation], - duration: int = None, - width: int = None, - height: int = None, - thumb: FileLike = None, - caption: str = None, - parse_mode: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_animation( + self, + chat_id: Union[int, str], + animation: Union[str, FileLike, Animation], + duration: int = None, + width: int = None, + height: int = None, + thumb: FileLike = None, + caption: str = None, + parse_mode: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """ Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). Bots can currently send animation files of up to 50 MB in size, this limit may be changed @@ -1045,23 +1150,30 @@ class Bot(TelegramObject): if parse_mode: data['parse_mode'] = parse_mode - return self._message('sendAnimation', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendAnimation', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_voice(self, - chat_id: Union[int, str], - voice: Union[str, FileLike, Voice], - duration: int = None, - caption: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = 20, - parse_mode: str = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_voice( + self, + chat_id: Union[int, str], + voice: Union[str, FileLike, Voice], + duration: int = None, + caption: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = 20, + parse_mode: str = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """ Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file @@ -1119,19 +1231,26 @@ class Bot(TelegramObject): if parse_mode: data['parse_mode'] = parse_mode - return self._message('sendVoice', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendVoice', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_media_group(self, - chat_id: Union[int, str], - media: List[InputMedia], - disable_notification: bool = None, - reply_to_message_id: Union[int, str] = None, - timeout: float = 20, - api_kwargs: JSONDict = None) -> List[Optional[Message]]: + def send_media_group( + self, + chat_id: Union[int, str], + media: List[InputMedia], + disable_notification: bool = None, + reply_to_message_id: Union[int, str] = None, + timeout: float = 20, + api_kwargs: JSONDict = None, + ) -> List[Optional[Message]]: """Use this method to send a group of photos or videos as an album. Args: @@ -1176,17 +1295,19 @@ class Bot(TelegramObject): return [Message.de_json(res, self) for res in result] # type: ignore @log - def send_location(self, - chat_id: Union[int, str], - latitude: float = None, - longitude: float = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - location: Location = None, - live_period: int = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_location( + self, + chat_id: Union[int, str], + latitude: float = None, + longitude: float = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + location: Location = None, + live_period: int = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """Use this method to send point on the map. Note: @@ -1221,12 +1342,14 @@ class Bot(TelegramObject): """ 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" - "argument.") + raise ValueError( + "Either location or latitude and longitude must be passed as" "argument." + ) if not ((latitude is not None or longitude is not None) ^ bool(location)): - raise ValueError("Either location or latitude and longitude must be passed as" - "argument. Not both.") + raise ValueError( + "Either location or latitude and longitude must be passed as" "argument. Not both." + ) if isinstance(location, Location): latitude = location.latitude @@ -1237,22 +1360,29 @@ class Bot(TelegramObject): if live_period: data['live_period'] = live_period - return self._message('sendLocation', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendLocation', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def edit_message_live_location(self, - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - latitude: float = None, - longitude: float = None, - location: Location = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[Optional[Message], bool]: + def edit_message_live_location( + self, + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + latitude: float = None, + longitude: float = None, + location: Location = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[Optional[Message], bool]: """Use this method to edit live location messages sent by the bot or via the bot (for inline bots). A location can be edited until its :attr:`live_period` expires or editing is explicitly disabled by a call to :attr:`stop_message_live_location`. @@ -1284,11 +1414,13 @@ class Bot(TelegramObject): edited Message is returned, otherwise :obj:`True` is returned. """ if not (all([latitude, longitude]) or location): - raise ValueError("Either location or latitude and longitude must be passed as" - "argument.") + raise ValueError( + "Either location or latitude and longitude must be passed as" "argument." + ) if not ((latitude is not None or longitude is not None) ^ bool(location)): - raise ValueError("Either location or latitude and longitude must be passed as" - "argument. Not both.") + raise ValueError( + "Either location or latitude and longitude must be passed as" "argument. Not both." + ) if isinstance(location, Location): latitude = location.latitude @@ -1303,17 +1435,24 @@ class Bot(TelegramObject): if inline_message_id: data['inline_message_id'] = inline_message_id - return self._message('editMessageLiveLocation', data, timeout=timeout, - reply_markup=reply_markup, api_kwargs=api_kwargs) + return self._message( + 'editMessageLiveLocation', + data, + timeout=timeout, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def stop_message_live_location(self, - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[Optional[Message], bool]: + def stop_message_live_location( + self, + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[Optional[Message], bool]: """Use this method to stop updating a live location message sent by the bot or via the bot (for inline bots) before live_period expires. @@ -1346,24 +1485,31 @@ class Bot(TelegramObject): if inline_message_id: data['inline_message_id'] = inline_message_id - return self._message('stopMessageLiveLocation', data, timeout=timeout, - reply_markup=reply_markup, api_kwargs=api_kwargs) + return self._message( + 'stopMessageLiveLocation', + data, + timeout=timeout, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_venue(self, - chat_id: Union[int, str], - latitude: float = None, - longitude: float = None, - title: str = None, - address: str = None, - foursquare_id: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - venue: Venue = None, - foursquare_type: str = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_venue( + self, + chat_id: Union[int, str], + latitude: float = None, + longitude: float = None, + title: str = None, + address: str = None, + foursquare_id: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + venue: Venue = None, + foursquare_type: str = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """Use this method to send information about a venue. Note: @@ -1404,8 +1550,10 @@ class Bot(TelegramObject): """ if not (venue or all([latitude, longitude, address, title])): - raise ValueError("Either venue or latitude, longitude, address and title must be" - "passed as arguments.") + raise ValueError( + "Either venue or latitude, longitude, address and title must be" + "passed as arguments." + ) if isinstance(venue, Venue): latitude = venue.location.latitude @@ -1420,7 +1568,7 @@ class Bot(TelegramObject): 'latitude': latitude, 'longitude': longitude, 'address': address, - 'title': title + 'title': title, } if foursquare_id: @@ -1428,24 +1576,31 @@ class Bot(TelegramObject): if foursquare_type: data['foursquare_type'] = foursquare_type - return self._message('sendVenue', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendVenue', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_contact(self, - chat_id: Union[int, str], - phone_number: str = None, - first_name: str = None, - last_name: str = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - contact: Contact = None, - vcard: str = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_contact( + self, + chat_id: Union[int, str], + phone_number: str = None, + first_name: str = None, + last_name: str = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + contact: Contact = None, + vcard: str = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """Use this method to send phone contacts. Note: @@ -1482,8 +1637,9 @@ class Bot(TelegramObject): """ if (not contact) and (not all([phone_number, first_name])): - raise ValueError("Either contact or phone_number and first_name must be passed as" - "arguments.") + raise ValueError( + "Either contact or phone_number and first_name must be passed as" "arguments." + ) if isinstance(contact, Contact): phone_number = contact.phone_number @@ -1491,28 +1647,38 @@ class Bot(TelegramObject): last_name = contact.last_name vcard = contact.vcard - data: JSONDict = {'chat_id': chat_id, 'phone_number': phone_number, - 'first_name': first_name} + data: JSONDict = { + 'chat_id': chat_id, + 'phone_number': phone_number, + 'first_name': first_name, + } if last_name: data['last_name'] = last_name if vcard: data['vcard'] = vcard - return self._message('sendContact', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendContact', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_game(self, - chat_id: Union[int, str], - game_short_name: str, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Optional[Message]: + def send_game( + self, + chat_id: Union[int, str], + game_short_name: str, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Optional[Message]: """Use this method to send a game. Args: @@ -1542,17 +1708,24 @@ class Bot(TelegramObject): """ data: JSONDict = {'chat_id': chat_id, 'game_short_name': game_short_name} - return self._message('sendGame', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendGame', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def send_chat_action(self, - chat_id: Union[str, int], - action: str, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def send_chat_action( + self, + chat_id: Union[str, int], + action: str, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method when you need to tell the user that something is happening on the bot's side. The status is set for 5 seconds or less (when a message arrives from your bot, @@ -1585,17 +1758,19 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def answer_inline_query(self, - inline_query_id: str, - results: List[InlineQueryResult], - cache_time: int = 300, - is_personal: bool = None, - next_offset: str = None, - switch_pm_text: str = None, - switch_pm_parameter: str = None, - timeout: float = None, - current_offset: str = None, - api_kwargs: JSONDict = None) -> bool: + def answer_inline_query( + self, + inline_query_id: str, + results: List[InlineQueryResult], + cache_time: int = 300, + is_personal: bool = None, + next_offset: str = None, + switch_pm_text: str = None, + switch_pm_parameter: str = None, + timeout: float = None, + current_offset: str = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to send answers to an inline query. No more than 50 results per query are allowed. @@ -1653,6 +1828,7 @@ class Bot(TelegramObject): :class:`telegram.TelegramError` """ + @no_type_check def _set_defaults(res): if res._has_parse_mode and res.parse_mode == DEFAULT_NONE: @@ -1661,17 +1837,22 @@ class Bot(TelegramObject): else: res.parse_mode = None if res._has_input_message_content and res.input_message_content: - if (res.input_message_content._has_parse_mode - and res.input_message_content.parse_mode == DEFAULT_NONE): + if ( + res.input_message_content._has_parse_mode + and res.input_message_content.parse_mode == DEFAULT_NONE + ): if self.defaults: res.input_message_content.parse_mode = self.defaults.parse_mode else: res.input_message_content.parse_mode = None - if (res.input_message_content._has_disable_web_page_preview - and res.input_message_content.disable_web_page_preview == DEFAULT_NONE): + if ( + res.input_message_content._has_disable_web_page_preview + and res.input_message_content.disable_web_page_preview == DEFAULT_NONE + ): if self.defaults: - res.input_message_content.disable_web_page_preview = \ + res.input_message_content.disable_web_page_preview = ( self.defaults.disable_web_page_preview + ) else: res.input_message_content.disable_web_page_preview = None @@ -1697,10 +1878,12 @@ class Bot(TelegramObject): next_offset_int = current_offset_int + 1 next_offset = str(next_offset_int) effective_results = results[ - current_offset_int * MAX_INLINE_QUERY_RESULTS: - next_offset_int * MAX_INLINE_QUERY_RESULTS] + current_offset_int + * MAX_INLINE_QUERY_RESULTS : next_offset_int + * MAX_INLINE_QUERY_RESULTS + ] else: - effective_results = results[current_offset_int * MAX_INLINE_QUERY_RESULTS:] + effective_results = results[current_offset_int * MAX_INLINE_QUERY_RESULTS :] else: effective_results = results @@ -1722,16 +1905,22 @@ class Bot(TelegramObject): if switch_pm_parameter: data['switch_pm_parameter'] = switch_pm_parameter - return self._post('answerInlineQuery', data, timeout=timeout, # type: ignore[return-value] - api_kwargs=api_kwargs) + return self._post( # type: ignore[return-value] + 'answerInlineQuery', + data, + timeout=timeout, + api_kwargs=api_kwargs, + ) @log - def get_user_profile_photos(self, - user_id: Union[str, int], - offset: int = None, - limit: int = 100, - timeout: float = None, - api_kwargs: JSONDict = None) -> Optional[UserProfilePhotos]: + def get_user_profile_photos( + self, + user_id: Union[str, int], + offset: int = None, + limit: int = 100, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Optional[UserProfilePhotos]: """Use this method to get a list of profile pictures for a user. Args: @@ -1765,11 +1954,14 @@ class Bot(TelegramObject): return UserProfilePhotos.de_json(result, self) # type: ignore @log - def get_file(self, - file_id: Union[str, Animation, Audio, ChatPhoto, Document, PhotoSize, Sticker, - Video, VideoNote, Voice], - timeout: float = None, - api_kwargs: JSONDict = None) -> File: + def get_file( + self, + file_id: Union[ + str, Animation, Audio, ChatPhoto, Document, PhotoSize, Sticker, Video, VideoNote, Voice + ], + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> File: """ Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can download files of up to 20MB in size. The file can then be downloaded @@ -1813,18 +2005,21 @@ class Bot(TelegramObject): result = self._post('getFile', data, timeout=timeout, api_kwargs=api_kwargs) if result.get('file_path'): # type: ignore - result['file_path'] = '{}/{}'.format(self.base_file_url, # type: ignore - result['file_path']) # type: ignore + result['file_path'] = '{}/{}'.format( # type: ignore + self.base_file_url, result['file_path'] # type: ignore + ) return File.de_json(result, self) # type: ignore @log - def kick_chat_member(self, - chat_id: Union[str, int], - user_id: Union[str, int], - timeout: float = None, - until_date: Union[int, datetime] = None, - api_kwargs: JSONDict = None) -> bool: + def kick_chat_member( + self, + chat_id: Union[str, int], + user_id: Union[str, int], + timeout: float = None, + until_date: Union[int, datetime] = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to kick a user from a group or a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the group on their own @@ -1857,8 +2052,9 @@ class Bot(TelegramObject): if until_date is not None: if isinstance(until_date, datetime): - until_date = to_timestamp(until_date, - tzinfo=self.defaults.tzinfo if self.defaults else None) + until_date = to_timestamp( + until_date, tzinfo=self.defaults.tzinfo if self.defaults else None + ) data['until_date'] = until_date result = self._post('kickChatMember', data, timeout=timeout, api_kwargs=api_kwargs) @@ -1866,11 +2062,13 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def unban_chat_member(self, - chat_id: Union[str, int], - user_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def unban_chat_member( + self, + chat_id: Union[str, int], + user_id: Union[str, int], + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """Use this method to unban a previously kicked user in a supergroup or channel. The user will not return to the group automatically, but will be able to join via link, @@ -1900,14 +2098,16 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def answer_callback_query(self, - callback_query_id: str, - text: str = None, - show_alert: bool = False, - url: str = None, - cache_time: int = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def answer_callback_query( + self, + callback_query_id: str, + text: str = None, + show_alert: bool = False, + url: str = None, + cache_time: int = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an @@ -1961,16 +2161,18 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def edit_message_text(self, - text: str, - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - parse_mode: str = None, - disable_web_page_preview: bool = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[Optional[Message], bool]: + def edit_message_text( + self, + text: str, + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + parse_mode: str = None, + disable_web_page_preview: bool = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[Optional[Message], bool]: """ Use this method to edit text and game messages sent by the bot or via the bot (for inline bots). @@ -2018,19 +2220,26 @@ class Bot(TelegramObject): if disable_web_page_preview: data['disable_web_page_preview'] = disable_web_page_preview - return self._message('editMessageText', data, timeout=timeout, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( + 'editMessageText', + data, + timeout=timeout, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def edit_message_caption(self, - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - caption: str = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - parse_mode: str = None, - api_kwargs: JSONDict = None) -> Union[Message, bool]: + def edit_message_caption( + self, + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + caption: str = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + parse_mode: str = None, + api_kwargs: JSONDict = None, + ) -> Union[Message, bool]: """ Use this method to edit captions of messages sent by the bot or via the bot (for inline bots). @@ -2067,7 +2276,8 @@ class Bot(TelegramObject): if inline_message_id is None and (chat_id is None or message_id is None): raise ValueError( 'edit_message_caption: Both chat_id and message_id are required when ' - 'inline_message_id is not specified') + 'inline_message_id is not specified' + ) data: JSONDict = {} @@ -2082,19 +2292,25 @@ class Bot(TelegramObject): if inline_message_id: data['inline_message_id'] = inline_message_id - return self._message('editMessageCaption', data, # type: ignore[return-value] - timeout=timeout, - reply_markup=reply_markup, api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'editMessageCaption', + data, + timeout=timeout, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def edit_message_media(self, - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - media: InputMedia = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[Message, bool]: + def edit_message_media( + self, + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + media: InputMedia = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[Message, bool]: """ Use this method to edit animation, audio, document, photo, or video messages. If a message is a part of a message album, then it can be edited only to a photo or a video. @@ -2130,7 +2346,8 @@ class Bot(TelegramObject): if inline_message_id is None and (chat_id is None or message_id is None): raise ValueError( 'edit_message_media: Both chat_id and message_id are required when ' - 'inline_message_id is not specified') + 'inline_message_id is not specified' + ) data: JSONDict = {'media': media} @@ -2141,17 +2358,24 @@ class Bot(TelegramObject): if inline_message_id: data['inline_message_id'] = inline_message_id - return self._message('editMessageMedia', data, # type: ignore[return-value] - timeout=timeout, reply_markup=reply_markup, api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'editMessageMedia', + data, + timeout=timeout, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def edit_message_reply_markup(self, - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[Message, bool]: + def edit_message_reply_markup( + self, + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[Message, bool]: """ Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). @@ -2183,7 +2407,8 @@ class Bot(TelegramObject): if inline_message_id is None and (chat_id is None or message_id is None): raise ValueError( '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' + ) data: JSONDict = {} @@ -2194,18 +2419,24 @@ class Bot(TelegramObject): if inline_message_id: data['inline_message_id'] = inline_message_id - return self._message('editMessageReplyMarkup', data, # type: ignore[return-value] - timeout=timeout, - reply_markup=reply_markup, api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'editMessageReplyMarkup', + data, + timeout=timeout, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def get_updates(self, - offset: int = None, - limit: int = 100, - timeout: float = 0, - read_latency: float = 2., - allowed_updates: List[str] = None, - api_kwargs: JSONDict = None) -> List[Update]: + def get_updates( + self, + offset: int = None, + limit: int = 100, + timeout: float = 0, + read_latency: float = 2.0, + allowed_updates: List[str] = None, + api_kwargs: JSONDict = None, + ) -> List[Update]: """Use this method to receive incoming updates using long polling. Args: @@ -2259,12 +2490,14 @@ class Bot(TelegramObject): # * Long polling poses a different problem: the connection might have been dropped while # waiting for the server to return and there's no way of knowing the connection had been # dropped in real time. - result = self._post('getUpdates', data, timeout=float(read_latency) + float(timeout), - api_kwargs=api_kwargs) + result = self._post( + 'getUpdates', data, timeout=float(read_latency) + float(timeout), api_kwargs=api_kwargs + ) if result: - self.logger.debug('Getting updates: %s', - [u['update_id'] for u in result]) # type: ignore + self.logger.debug( + 'Getting updates: %s', [u['update_id'] for u in result] # type: ignore + ) else: self.logger.debug('No new updates found.') @@ -2275,13 +2508,15 @@ class Bot(TelegramObject): return [Update.de_json(u, self) for u in result] # type: ignore @log - def set_webhook(self, - url: str = None, - certificate: FileLike = None, - timeout: float = None, - max_connections: int = 40, - allowed_updates: List[str] = None, - api_kwargs: JSONDict = None) -> bool: + def set_webhook( + self, + url: str = None, + certificate: FileLike = None, + timeout: float = None, + max_connections: int = 40, + allowed_updates: List[str] = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, Telegram will send an HTTPS POST request to the @@ -2382,10 +2617,9 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def leave_chat(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def leave_chat( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> bool: """Use this method for your bot to leave a group, supergroup or channel. Args: @@ -2411,10 +2645,9 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def get_chat(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> Chat: + def get_chat( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> Chat: """ Use this method to get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.). @@ -2445,10 +2678,9 @@ class Bot(TelegramObject): return Chat.de_json(result, self) # type: ignore @log - def get_chat_administrators(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> List[ChatMember]: + def get_chat_administrators( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> List[ChatMember]: """ Use this method to get a list of administrators in a chat. @@ -2478,10 +2710,9 @@ class Bot(TelegramObject): return [ChatMember.de_json(x, self) for x in result] # type: ignore @log - def get_chat_members_count(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> int: + def get_chat_members_count( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> int: """Use this method to get the number of members in a chat. Args: @@ -2507,11 +2738,13 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def get_chat_member(self, - chat_id: Union[str, int], - user_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> ChatMember: + def get_chat_member( + self, + chat_id: Union[str, int], + user_id: Union[str, int], + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> ChatMember: """Use this method to get information about a member of a chat. Args: @@ -2538,11 +2771,13 @@ class Bot(TelegramObject): return ChatMember.de_json(result, self) # type: ignore @log - def set_chat_sticker_set(self, - chat_id: Union[str, int], - sticker_set_name: str, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_chat_sticker_set( + self, + chat_id: Union[str, int], + sticker_set_name: str, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field :attr:`telegram.Chat.can_set_sticker_set` optionally returned @@ -2569,10 +2804,9 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def delete_chat_sticker_set(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def delete_chat_sticker_set( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> bool: """Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field :attr:`telegram.Chat.can_set_sticker_set` optionally returned in @@ -2596,9 +2830,7 @@ class Bot(TelegramObject): return result # type: ignore[return-value] - def get_webhook_info(self, - timeout: float = None, - api_kwargs: JSONDict = None) -> WebhookInfo: + def get_webhook_info(self, timeout: float = None, api_kwargs: JSONDict = None) -> WebhookInfo: """Use this method to get current webhook status. Requires no parameters. If the bot is using getUpdates, will return an object with the url field empty. @@ -2619,16 +2851,18 @@ class Bot(TelegramObject): return WebhookInfo.de_json(result, self) # type: ignore @log - def set_game_score(self, - user_id: Union[int, str], - score: int, - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - force: bool = None, - disable_edit_message: bool = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Union[Message, bool]: + def set_game_score( + self, + user_id: Union[int, str], + score: int, + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + force: bool = None, + disable_edit_message: bool = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Union[Message, bool]: """ Use this method to set the score of the specified user in a game. @@ -2673,17 +2907,23 @@ class Bot(TelegramObject): if disable_edit_message is not None: data['disable_edit_message'] = disable_edit_message - return self._message('setGameScore', data, timeout=timeout, # type: ignore[return-value] - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'setGameScore', + data, + timeout=timeout, + api_kwargs=api_kwargs, + ) @log - def get_game_high_scores(self, - user_id: Union[int, str], - chat_id: Union[str, int] = None, - message_id: Union[str, int] = None, - inline_message_id: Union[str, int] = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> List[GameHighScore]: + def get_game_high_scores( + self, + user_id: Union[int, str], + chat_id: Union[str, int] = None, + message_id: Union[str, int] = None, + inline_message_id: Union[str, int] = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> List[GameHighScore]: """ Use this method to get data for high score tables. Will return the score of the specified user and several of his neighbors in a game. @@ -2723,32 +2963,34 @@ class Bot(TelegramObject): return [GameHighScore.de_json(hs, self) for hs in result] # type: ignore @log - def send_invoice(self, - chat_id: Union[int, str], - title: str, - description: str, - payload: str, - provider_token: str, - start_parameter: str, - currency: str, - prices: List[LabeledPrice], - photo_url: str = None, - photo_size: int = None, - photo_width: int = None, - photo_height: int = None, - need_name: bool = None, - need_phone_number: bool = None, - need_email: bool = None, - need_shipping_address: bool = None, - is_flexible: bool = None, - disable_notification: bool = False, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - provider_data: Union[str, object] = None, - send_phone_number_to_provider: bool = None, - send_email_to_provider: bool = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Message: + def send_invoice( + self, + chat_id: Union[int, str], + title: str, + description: str, + payload: str, + provider_token: str, + start_parameter: str, + currency: str, + prices: List[LabeledPrice], + photo_url: str = None, + photo_size: int = None, + photo_width: int = None, + photo_height: int = None, + need_name: bool = None, + need_phone_number: bool = None, + need_email: bool = None, + need_shipping_address: bool = None, + is_flexible: bool = None, + disable_notification: bool = False, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + provider_data: Union[str, object] = None, + send_phone_number_to_provider: bool = None, + send_email_to_provider: bool = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Message: """Use this method to send invoices. Args: @@ -2817,7 +3059,7 @@ class Bot(TelegramObject): 'provider_token': provider_token, 'start_parameter': start_parameter, 'currency': currency, - 'prices': [p.to_dict() for p in prices] + 'prices': [p.to_dict() for p in prices], } if provider_data is not None: if isinstance(provider_data, str): @@ -2847,19 +3089,26 @@ class Bot(TelegramObject): if send_email_to_provider is not None: data['send_email_to_provider'] = send_email_to_provider - return self._message('sendInvoice', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendInvoice', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def answer_shipping_query(self, - shipping_query_id: str, - ok: bool, - shipping_options: List[ShippingOption] = None, - error_message: str = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def answer_shipping_query( + self, + shipping_query_id: str, + ok: bool, + shipping_options: List[ShippingOption] = None, + error_message: str = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API will send an Update with a shipping_query field to the bot. Use @@ -2894,12 +3143,14 @@ class Bot(TelegramObject): if ok and (shipping_options is None or error_message is not None): raise TelegramError( 'answerShippingQuery: If ok is True, shipping_options ' - 'should not be empty and there should not be error_message') + 'should not be empty and there should not be error_message' + ) if not ok and (shipping_options is not None or error_message is None): raise TelegramError( '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' + ) data: JSONDict = {'shipping_query_id': shipping_query_id, 'ok': ok} @@ -2914,12 +3165,14 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def answer_pre_checkout_query(self, - pre_checkout_query_id: str, - ok: bool, - error_message: str = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def answer_pre_checkout_query( + self, + pre_checkout_query_id: str, + ok: bool, + error_message: str = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of an Update with the field pre_checkout_query. Use this method to @@ -2958,7 +3211,8 @@ class Bot(TelegramObject): raise TelegramError( 'answerPreCheckoutQuery: If ok is True, there should ' 'not be error_message; if ok is False, error_message ' - 'should not be empty') + 'should not be empty' + ) data: JSONDict = {'pre_checkout_query_id': pre_checkout_query_id, 'ok': ok} @@ -2970,13 +3224,15 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def restrict_chat_member(self, - chat_id: Union[str, int], - user_id: Union[str, int], - permissions: ChatPermissions, - until_date: Union[int, datetime] = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def restrict_chat_member( + self, + chat_id: Union[str, int], + user_id: Union[str, int], + permissions: ChatPermissions, + until_date: Union[int, datetime] = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights. Pass @@ -3011,13 +3267,17 @@ class Bot(TelegramObject): Raises: :class:`telegram.TelegramError` """ - data: JSONDict = {'chat_id': chat_id, 'user_id': user_id, - 'permissions': permissions.to_dict()} + data: JSONDict = { + 'chat_id': chat_id, + 'user_id': user_id, + 'permissions': permissions.to_dict(), + } if until_date is not None: if isinstance(until_date, datetime): - until_date = to_timestamp(until_date, - tzinfo=self.defaults.tzinfo if self.defaults else None) + until_date = to_timestamp( + until_date, tzinfo=self.defaults.tzinfo if self.defaults else None + ) data['until_date'] = until_date result = self._post('restrictChatMember', data, timeout=timeout, api_kwargs=api_kwargs) @@ -3025,19 +3285,21 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def promote_chat_member(self, - chat_id: Union[str, int], - user_id: Union[str, int], - can_change_info: bool = None, - can_post_messages: bool = None, - can_edit_messages: bool = None, - can_delete_messages: bool = None, - can_invite_users: bool = None, - can_restrict_members: bool = None, - can_pin_messages: bool = None, - can_promote_members: bool = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def promote_chat_member( + self, + chat_id: Union[str, int], + user_id: Union[str, int], + can_change_info: bool = None, + can_post_messages: bool = None, + can_edit_messages: bool = None, + can_delete_messages: bool = None, + can_invite_users: bool = None, + can_restrict_members: bool = None, + can_pin_messages: bool = None, + can_promote_members: bool = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. @@ -3102,11 +3364,13 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_chat_permissions(self, - chat_id: Union[str, int], - permissions: ChatPermissions, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_chat_permissions( + self, + chat_id: Union[str, int], + permissions: ChatPermissions, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a supergroup for this to work and must have the @@ -3136,12 +3400,14 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_chat_administrator_custom_title(self, - chat_id: Union[int, str], - user_id: Union[int, str], - custom_title: str, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_chat_administrator_custom_title( + self, + chat_id: Union[int, str], + user_id: Union[int, str], + custom_title: str, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to set a custom title for administrators promoted by the bot in a supergroup. The bot must be an administrator for this to work. @@ -3165,19 +3431,18 @@ class Bot(TelegramObject): :class:`telegram.TelegramError` """ - data: JSONDict = {'chat_id': chat_id, 'user_id': user_id, - 'custom_title': custom_title} + data: JSONDict = {'chat_id': chat_id, 'user_id': user_id, 'custom_title': custom_title} - result = self._post('setChatAdministratorCustomTitle', data, timeout=timeout, - api_kwargs=api_kwargs) + result = self._post( + 'setChatAdministratorCustomTitle', data, timeout=timeout, api_kwargs=api_kwargs + ) return result # type: ignore[return-value] @log - def export_chat_invite_link(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> str: + def export_chat_invite_link( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> str: """ Use this method to generate a new invite link for a chat; any previously generated link is revoked. The bot must be an administrator in the chat for this to work and must have @@ -3206,11 +3471,13 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_chat_photo(self, - chat_id: Union[str, int], - photo: FileLike, - timeout: float = 20, - api_kwargs: JSONDict = None) -> bool: + def set_chat_photo( + self, + chat_id: Union[str, int], + photo: FileLike, + timeout: float = 20, + api_kwargs: JSONDict = None, + ) -> bool: """Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. The bot must be an administrator in the chat @@ -3244,10 +3511,9 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def delete_chat_photo(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def delete_chat_photo( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> bool: """ Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin @@ -3276,11 +3542,13 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_chat_title(self, - chat_id: Union[str, int], - title: str, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_chat_title( + self, + chat_id: Union[str, int], + title: str, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to change the title of a chat. Titles can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate @@ -3310,11 +3578,13 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_chat_description(self, - chat_id: Union[str, int], - description: str, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_chat_description( + self, + chat_id: Union[str, int], + description: str, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to change the description of a group, a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin @@ -3344,12 +3614,14 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def pin_chat_message(self, - chat_id: Union[str, int], - message_id: Union[str, int], - disable_notification: bool = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def pin_chat_message( + self, + chat_id: Union[str, int], + message_id: Union[str, int], + disable_notification: bool = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to pin a message in a group, a supergroup, or a channel. The bot must be an administrator in the chat for this to work and must have the @@ -3386,10 +3658,9 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def unpin_chat_message(self, - chat_id: Union[str, int], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def unpin_chat_message( + self, chat_id: Union[str, int], timeout: float = None, api_kwargs: JSONDict = None + ) -> bool: """ Use this method to unpin a message in a group, a supergroup, or a channel. The bot must be an administrator in the chat for this to work and must have the @@ -3419,10 +3690,9 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def get_sticker_set(self, - name: str, - timeout: float = None, - api_kwargs: JSONDict = None) -> StickerSet: + def get_sticker_set( + self, name: str, timeout: float = None, api_kwargs: JSONDict = None + ) -> StickerSet: """Use this method to get a sticker set. Args: @@ -3447,11 +3717,13 @@ class Bot(TelegramObject): return StickerSet.de_json(result, self) # type: ignore @log - def upload_sticker_file(self, - user_id: Union[str, int], - png_sticker: Union[str, FileLike], - timeout: float = 20, - api_kwargs: JSONDict = None) -> File: + def upload_sticker_file( + self, + user_id: Union[str, int], + png_sticker: Union[str, FileLike], + timeout: float = 20, + api_kwargs: JSONDict = None, + ) -> File: """ Use this method to upload a .png file with a sticker for later use in :attr:`create_new_sticker_set` and :attr:`add_sticker_to_set` methods (can be used multiple @@ -3489,17 +3761,19 @@ class Bot(TelegramObject): return File.de_json(result, self) # type: ignore @log - def create_new_sticker_set(self, - user_id: Union[str, int], - name: str, - title: str, - emojis: str, - png_sticker: Union[str, FileLike] = None, - contains_masks: bool = None, - mask_position: MaskPosition = None, - timeout: float = 20, - tgs_sticker: Union[str, FileLike] = None, - api_kwargs: JSONDict = None) -> bool: + def create_new_sticker_set( + self, + user_id: Union[str, int], + name: str, + title: str, + emojis: str, + png_sticker: Union[str, FileLike] = None, + contains_masks: bool = None, + mask_position: MaskPosition = None, + timeout: float = 20, + tgs_sticker: Union[str, FileLike] = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to create new sticker set owned by a user. The bot will be able to edit the created sticker set. @@ -3574,15 +3848,17 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def add_sticker_to_set(self, - user_id: Union[str, int], - name: str, - emojis: str, - png_sticker: Union[str, FileLike] = None, - mask_position: MaskPosition = None, - timeout: float = 20, - tgs_sticker: Union[str, FileLike] = None, - api_kwargs: JSONDict = None) -> bool: + def add_sticker_to_set( + self, + user_id: Union[str, int], + name: str, + emojis: str, + png_sticker: Union[str, FileLike] = None, + mask_position: MaskPosition = None, + timeout: float = 20, + tgs_sticker: Union[str, FileLike] = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to add a new sticker to a set created by the bot. You must use exactly one of the fields png_sticker or tgs_sticker. Animated stickers @@ -3649,11 +3925,9 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_sticker_position_in_set(self, - sticker: str, - position: int, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_sticker_position_in_set( + self, sticker: str, position: int, timeout: float = None, api_kwargs: JSONDict = None + ) -> bool: """Use this method to move a sticker in a set created by the bot to a specific position. Args: @@ -3674,16 +3948,16 @@ class Bot(TelegramObject): """ data: JSONDict = {'sticker': sticker, 'position': position} - result = self._post('setStickerPositionInSet', data, timeout=timeout, - api_kwargs=api_kwargs) + result = self._post( + 'setStickerPositionInSet', data, timeout=timeout, api_kwargs=api_kwargs + ) return result # type: ignore[return-value] @log - def delete_sticker_from_set(self, - sticker: str, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def delete_sticker_from_set( + self, sticker: str, timeout: float = None, api_kwargs: JSONDict = None + ) -> bool: """Use this method to delete a sticker from a set created by the bot. Args: @@ -3708,12 +3982,14 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_sticker_set_thumb(self, - name: str, - user_id: Union[str, int], - thumb: FileLike = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_sticker_set_thumb( + self, + name: str, + user_id: Union[str, int], + thumb: FileLike = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for animated sticker sets only. @@ -3756,11 +4032,13 @@ class Bot(TelegramObject): return result # type: ignore[return-value] @log - def set_passport_data_errors(self, - user_id: Union[str, int], - errors: List[PassportElementError], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_passport_data_errors( + self, + user_id: Union[str, int], + errors: List[PassportElementError], + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Informs a user that some of the Telegram Passport elements they provided contains errors. The user will not be able to re-submit their Passport to you until the errors are fixed @@ -3788,32 +4066,33 @@ class Bot(TelegramObject): :class:`telegram.TelegramError` """ - data: JSONDict = {'user_id': user_id, - 'errors': [error.to_dict() for error in errors]} + data: JSONDict = {'user_id': user_id, 'errors': [error.to_dict() for error in errors]} result = self._post('setPassportDataErrors', data, timeout=timeout, api_kwargs=api_kwargs) return result # type: ignore[return-value] @log - def send_poll(self, - chat_id: Union[int, str], - question: str, - options: List[str], - is_anonymous: bool = True, - type: str = Poll.REGULAR, - allows_multiple_answers: bool = False, - correct_option_id: int = None, - is_closed: bool = None, - disable_notification: bool = None, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - explanation: str = None, - explanation_parse_mode: Union[str, DefaultValue, None] = DEFAULT_NONE, - open_period: int = None, - close_date: Union[int, datetime] = None, - api_kwargs: JSONDict = None) -> Message: + def send_poll( + self, + chat_id: Union[int, str], + question: str, + options: List[str], + is_anonymous: bool = True, + type: str = Poll.REGULAR, + allows_multiple_answers: bool = False, + correct_option_id: int = None, + is_closed: bool = None, + disable_notification: bool = None, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + explanation: str = None, + explanation_parse_mode: Union[str, DefaultValue, None] = DEFAULT_NONE, + open_period: int = None, + close_date: Union[int, datetime] = None, + api_kwargs: JSONDict = None, + ) -> Message: """ Use this method to send a native poll. @@ -3866,11 +4145,7 @@ class Bot(TelegramObject): :class:`telegram.TelegramError` """ - data: JSONDict = { - 'chat_id': chat_id, - 'question': question, - 'options': options - } + data: JSONDict = {'chat_id': chat_id, 'question': question, 'options': options} if explanation_parse_mode == DEFAULT_NONE: if self.defaults: @@ -3896,22 +4171,30 @@ class Bot(TelegramObject): data['open_period'] = open_period if close_date: if isinstance(close_date, datetime): - close_date = to_timestamp(close_date, - tzinfo=self.defaults.tzinfo if self.defaults else None) + close_date = to_timestamp( + close_date, tzinfo=self.defaults.tzinfo if self.defaults else None + ) data['close_date'] = close_date - return self._message('sendPoll', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendPoll', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def stop_poll(self, - chat_id: Union[int, str], - message_id: Union[int, str], - reply_markup: ReplyMarkup = None, - timeout: float = None, - api_kwargs: JSONDict = None) -> Poll: + def stop_poll( + self, + chat_id: Union[int, str], + message_id: Union[int, str], + reply_markup: ReplyMarkup = None, + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> Poll: """ Use this method to stop a poll which was sent by the bot. @@ -3935,10 +4218,7 @@ class Bot(TelegramObject): :class:`telegram.TelegramError` """ - data: JSONDict = { - 'chat_id': chat_id, - 'message_id': message_id - } + data: JSONDict = {'chat_id': chat_id, 'message_id': message_id} if reply_markup: if isinstance(reply_markup, ReplyMarkup): @@ -3953,14 +4233,16 @@ class Bot(TelegramObject): return Poll.de_json(result, self) # type: ignore @log - def send_dice(self, - chat_id: Union[int, str], - disable_notification: bool = None, - reply_to_message_id: Union[int, str] = None, - reply_markup: ReplyMarkup = None, - timeout: float = None, - emoji: str = None, - api_kwargs: JSONDict = None) -> Message: + def send_dice( + self, + chat_id: Union[int, str], + disable_notification: bool = None, + reply_to_message_id: Union[int, str] = None, + reply_markup: ReplyMarkup = None, + timeout: float = None, + emoji: str = None, + api_kwargs: JSONDict = None, + ) -> Message: """ Use this method to send an animated emoji, which will have a random value. On success, the sent Message is returned. @@ -3997,15 +4279,20 @@ class Bot(TelegramObject): if emoji: data['emoji'] = emoji - return self._message('sendDice', data, timeout=timeout, # type: ignore[return-value] - disable_notification=disable_notification, - reply_to_message_id=reply_to_message_id, reply_markup=reply_markup, - api_kwargs=api_kwargs) + return self._message( # type: ignore[return-value] + 'sendDice', + data, + timeout=timeout, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup, + api_kwargs=api_kwargs, + ) @log - def get_my_commands(self, - timeout: float = None, - api_kwargs: JSONDict = None) -> List[BotCommand]: + def get_my_commands( + self, timeout: float = None, api_kwargs: JSONDict = None + ) -> List[BotCommand]: """ Use this method to get the current list of the bot's commands. @@ -4030,10 +4317,12 @@ class Bot(TelegramObject): return self._commands @log - def set_my_commands(self, - commands: List[Union[BotCommand, Tuple[str, str]]], - timeout: float = None, - api_kwargs: JSONDict = None) -> bool: + def set_my_commands( + self, + commands: List[Union[BotCommand, Tuple[str, str]]], + timeout: float = None, + api_kwargs: JSONDict = None, + ) -> bool: """ Use this method to change the list of the bot's commands. @@ -4067,8 +4356,7 @@ class Bot(TelegramObject): return result # type: ignore[return-value] def to_dict(self) -> JSONDict: - data: JSONDict = {'id': self.id, 'username': self.username, - 'first_name': self.first_name} + data: JSONDict = {'id': self.id, 'username': self.username, 'first_name': self.first_name} if self.last_name: data['last_name'] = self.last_name diff --git a/telegram/botcommand.py b/telegram/botcommand.py index 0b780b229..e4ec30284 100644 --- a/telegram/botcommand.py +++ b/telegram/botcommand.py @@ -38,6 +38,7 @@ class BotCommand(TelegramObject): English letters, digits and underscores. description (:obj:`str`): Description of the command, 3-256 characters. """ + def __init__(self, command: str, description: str, **kwargs: Any): self.command = command self.description = description diff --git a/telegram/callbackquery.py b/telegram/callbackquery.py index 1654e01e7..6821abc15 100644 --- a/telegram/callbackquery.py +++ b/telegram/callbackquery.py @@ -78,16 +78,18 @@ class CallbackQuery(TelegramObject): """ - def __init__(self, - id: str, - from_user: User, - chat_instance: str, - message: Message = None, - data: str = None, - inline_message_id: str = None, - game_short_name: str = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + id: str, + from_user: User, + chat_instance: str, + message: Message = None, + data: str = None, + inline_message_id: str = None, + game_short_name: str = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.id = id self.from_user = from_user @@ -143,14 +145,21 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.edit_message_text(text, inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.edit_message_text( + text, inline_message_id=self.inline_message_id, *args, **kwargs + ) else: - return self.bot.edit_message_text(text, chat_id=self.message.chat_id, - message_id=self.message.message_id, *args, **kwargs) + return self.bot.edit_message_text( + text, + chat_id=self.message.chat_id, + message_id=self.message.message_id, + *args, + **kwargs, + ) - def edit_message_caption(self, caption: str, *args: Any, - **kwargs: Any) -> Union[Message, bool]: + def edit_message_caption( + self, caption: str, *args: Any, **kwargs: Any + ) -> Union[Message, bool]: """Shortcut for either:: bot.edit_message_caption(caption=caption, @@ -170,16 +179,21 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.edit_message_caption(caption=caption, - inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.edit_message_caption( + caption=caption, inline_message_id=self.inline_message_id, *args, **kwargs + ) else: - return self.bot.edit_message_caption(caption=caption, chat_id=self.message.chat_id, - message_id=self.message.message_id, - *args, **kwargs) + return self.bot.edit_message_caption( + caption=caption, + chat_id=self.message.chat_id, + message_id=self.message.message_id, + *args, + **kwargs, + ) - def edit_message_reply_markup(self, reply_markup: 'InlineKeyboardMarkup', *args: Any, - **kwargs: Any) -> Union[Message, bool]: + def edit_message_reply_markup( + self, reply_markup: 'InlineKeyboardMarkup', *args: Any, **kwargs: Any + ) -> Union[Message, bool]: """Shortcut for either:: bot.edit_message_reply_markup(chat_id=update.callback_query.message.chat_id, @@ -199,14 +213,20 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.edit_message_reply_markup(reply_markup=reply_markup, - inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.edit_message_reply_markup( + reply_markup=reply_markup, + inline_message_id=self.inline_message_id, + *args, + **kwargs, + ) else: - return self.bot.edit_message_reply_markup(reply_markup=reply_markup, - chat_id=self.message.chat_id, - message_id=self.message.message_id, - *args, **kwargs) + return self.bot.edit_message_reply_markup( + reply_markup=reply_markup, + chat_id=self.message.chat_id, + message_id=self.message.message_id, + *args, + **kwargs, + ) def edit_message_media(self, *args: Any, **kwargs: Any) -> Union[Message, bool]: """Shortcut for either:: @@ -228,12 +248,13 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.edit_message_media(inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.edit_message_media( + inline_message_id=self.inline_message_id, *args, **kwargs + ) else: - return self.bot.edit_message_media(chat_id=self.message.chat_id, - message_id=self.message.message_id, - *args, **kwargs) + return self.bot.edit_message_media( + chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs + ) def edit_message_live_location(self, *args: Any, **kwargs: Any) -> Union[Message, bool]: """Shortcut for either:: @@ -257,12 +278,13 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.edit_message_live_location(inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.edit_message_live_location( + inline_message_id=self.inline_message_id, *args, **kwargs + ) else: - return self.bot.edit_message_live_location(chat_id=self.message.chat_id, - message_id=self.message.message_id, - *args, **kwargs) + return self.bot.edit_message_live_location( + chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs + ) def stop_message_live_location(self, *args: Any, **kwargs: Any) -> Union[Message, bool]: """Shortcut for either:: @@ -286,12 +308,13 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.stop_message_live_location(inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.stop_message_live_location( + inline_message_id=self.inline_message_id, *args, **kwargs + ) else: - return self.bot.stop_message_live_location(chat_id=self.message.chat_id, - message_id=self.message.message_id, - *args, **kwargs) + return self.bot.stop_message_live_location( + chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs + ) def set_game_score(self, *args: Any, **kwargs: Any) -> Union[Message, bool]: """Shortcut for either:: @@ -313,12 +336,13 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.set_game_score(inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.set_game_score( + inline_message_id=self.inline_message_id, *args, **kwargs + ) else: - return self.bot.set_game_score(chat_id=self.message.chat_id, - message_id=self.message.message_id, - *args, **kwargs) + return self.bot.set_game_score( + chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs + ) def get_game_high_scores(self, *args: Any, **kwargs: Any) -> List['GameHighScore']: """Shortcut for either:: @@ -339,9 +363,10 @@ class CallbackQuery(TelegramObject): """ if self.inline_message_id: - return self.bot.get_game_high_scores(inline_message_id=self.inline_message_id, - *args, **kwargs) + return self.bot.get_game_high_scores( + inline_message_id=self.inline_message_id, *args, **kwargs + ) else: - return self.bot.get_game_high_scores(chat_id=self.message.chat_id, - message_id=self.message.message_id, - *args, **kwargs) + return self.bot.get_game_high_scores( + chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs + ) diff --git a/telegram/chat.py b/telegram/chat.py index 8f7ebe277..88e38b86c 100644 --- a/telegram/chat.py +++ b/telegram/chat.py @@ -24,6 +24,7 @@ from .chatpermissions import ChatPermissions from telegram.utils.types import JSONDict from typing import Any, Optional, List, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, Message, ChatMember @@ -100,23 +101,25 @@ class Chat(TelegramObject): CHANNEL: str = 'channel' """:obj:`str`: 'channel'""" - def __init__(self, - id: int, - type: str, - title: str = None, - username: str = None, - first_name: str = None, - last_name: str = None, - bot: 'Bot' = None, - photo: ChatPhoto = None, - description: str = None, - invite_link: str = None, - pinned_message: 'Message' = None, - permissions: ChatPermissions = None, - sticker_set_name: str = None, - can_set_sticker_set: bool = None, - slow_mode_delay: int = None, - **kwargs: Any): + def __init__( + self, + id: int, + type: str, + title: str = None, + username: str = None, + first_name: str = None, + last_name: str = None, + bot: 'Bot' = None, + photo: ChatPhoto = None, + description: str = None, + invite_link: str = None, + pinned_message: 'Message' = None, + permissions: ChatPermissions = None, + sticker_set_name: str = None, + can_set_sticker_set: bool = None, + slow_mode_delay: int = None, + **kwargs: Any, + ): # Required self.id = int(id) self.type = type @@ -156,6 +159,7 @@ class Chat(TelegramObject): data['photo'] = ChatPhoto.de_json(data.get('photo'), bot) from telegram import Message + data['pinned_message'] = Message.de_json(data.get('pinned_message'), bot) data['permissions'] = ChatPermissions.de_json(data.get('permissions'), bot) @@ -243,7 +247,7 @@ class Chat(TelegramObject): Returns: :obj:`bool`: If the action was sent successfully. - """ + """ return self.bot.set_chat_permissions(self.id, *args, **kwargs) def set_administrator_custom_title(self, *args: Any, **kwargs: Any) -> bool: @@ -254,7 +258,7 @@ class Chat(TelegramObject): Returns: :obj:`bool`: If the action was sent successfully. - """ + """ return self.bot.set_chat_administrator_custom_title(self.id, *args, **kwargs) def send_message(self, *args: Any, **kwargs: Any) -> 'Message': diff --git a/telegram/chatmember.py b/telegram/chatmember.py index 36aba2edc..cd63829de 100644 --- a/telegram/chatmember.py +++ b/telegram/chatmember.py @@ -24,6 +24,7 @@ from telegram.utils.helpers import to_timestamp, from_timestamp from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -110,6 +111,7 @@ class ChatMember(TelegramObject): may add web page previews to his messages. """ + ADMINISTRATOR: str = 'administrator' """:obj:`str`: 'administrator'""" CREATOR: str = 'creator' @@ -123,27 +125,29 @@ class ChatMember(TelegramObject): RESTRICTED: str = 'restricted' """:obj:`str`: 'restricted'""" - def __init__(self, - user: User, - status: str, - until_date: datetime.datetime = None, - can_be_edited: bool = None, - can_change_info: bool = None, - can_post_messages: bool = None, - can_edit_messages: bool = None, - can_delete_messages: bool = None, - can_invite_users: bool = None, - can_restrict_members: bool = None, - can_pin_messages: bool = None, - can_promote_members: bool = None, - can_send_messages: bool = None, - can_send_media_messages: bool = None, - can_send_polls: bool = None, - can_send_other_messages: bool = None, - can_add_web_page_previews: bool = None, - is_member: bool = None, - custom_title: str = None, - **kwargs: Any): + def __init__( + self, + user: User, + status: str, + until_date: datetime.datetime = None, + can_be_edited: bool = None, + can_change_info: bool = None, + can_post_messages: bool = None, + can_edit_messages: bool = None, + can_delete_messages: bool = None, + can_invite_users: bool = None, + can_restrict_members: bool = None, + can_pin_messages: bool = None, + can_promote_members: bool = None, + can_send_messages: bool = None, + can_send_media_messages: bool = None, + can_send_polls: bool = None, + can_send_other_messages: bool = None, + can_add_web_page_previews: bool = None, + is_member: bool = None, + custom_title: str = None, + **kwargs: Any, + ): # Required self.user = user self.status = status diff --git a/telegram/chatpermissions.py b/telegram/chatpermissions.py index 835691e9c..c852aab75 100644 --- a/telegram/chatpermissions.py +++ b/telegram/chatpermissions.py @@ -77,16 +77,18 @@ class ChatPermissions(TelegramObject): """ - def __init__(self, - can_send_messages: bool = None, - can_send_media_messages: bool = None, - can_send_polls: bool = None, - can_send_other_messages: bool = None, - can_add_web_page_previews: bool = None, - can_change_info: bool = None, - can_invite_users: bool = None, - can_pin_messages: bool = None, - **kwargs: Any): + def __init__( + self, + can_send_messages: bool = None, + can_send_media_messages: bool = None, + can_send_polls: bool = None, + can_send_other_messages: bool = None, + can_add_web_page_previews: bool = None, + can_change_info: bool = None, + can_invite_users: bool = None, + can_pin_messages: bool = None, + **kwargs: Any, + ): # Required self.can_send_messages = can_send_messages self.can_send_media_messages = can_send_media_messages @@ -105,5 +107,5 @@ class ChatPermissions(TelegramObject): self.can_add_web_page_previews, self.can_change_info, self.can_invite_users, - self.can_pin_messages + self.can_pin_messages, ) diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py index 67dcbb0f3..74ea6d54f 100644 --- a/telegram/choseninlineresult.py +++ b/telegram/choseninlineresult.py @@ -22,6 +22,7 @@ from telegram import TelegramObject, User, Location from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -61,13 +62,15 @@ class ChosenInlineResult(TelegramObject): """ - def __init__(self, - result_id: str, - from_user: User, - query: str, - location: Location = None, - inline_message_id: str = None, - **kwargs: Any): + def __init__( + self, + result_id: str, + from_user: User, + query: str, + location: Location = None, + inline_message_id: str = None, + **kwargs: Any, + ): # Required self.result_id = result_id self.from_user = from_user diff --git a/telegram/constants.py b/telegram/constants.py index 675175497..6e9816cf9 100644 --- a/telegram/constants.py +++ b/telegram/constants.py @@ -48,9 +48,9 @@ MAX_CAPTION_LENGTH: int = 1024 # constants above this line are tested SUPPORTED_WEBHOOK_PORTS: List[int] = [443, 80, 88, 8443] -MAX_FILESIZE_DOWNLOAD: int = int(20E6) # (20MB) -MAX_FILESIZE_UPLOAD: int = int(50E6) # (50MB) -MAX_PHOTOSIZE_UPLOAD: int = int(10E6) # (10MB) +MAX_FILESIZE_DOWNLOAD: int = int(20e6) # (20MB) +MAX_FILESIZE_UPLOAD: int = int(50e6) # (50MB) +MAX_PHOTOSIZE_UPLOAD: int = int(10e6) # (10MB) MAX_MESSAGES_PER_SECOND_PER_CHAT: int = 1 MAX_MESSAGES_PER_SECOND: int = 30 MAX_MESSAGES_PER_MINUTE_PER_GROUP: int = 20 diff --git a/telegram/dice.py b/telegram/dice.py index 628e34a5e..36ef61555 100644 --- a/telegram/dice.py +++ b/telegram/dice.py @@ -48,6 +48,7 @@ class Dice(TelegramObject): value (:obj:`int`): Value of the dice. 1-6 for dice and darts, 1-5 for basketball. emoji (:obj:`str`): Emoji on which the dice throw animation is based. """ + def __init__(self, value: int, emoji: str, **kwargs: Any): self.value = value self.emoji = emoji diff --git a/telegram/error.py b/telegram/error.py index 3ea4da16e..3e634eb17 100644 --- a/telegram/error.py +++ b/telegram/error.py @@ -31,7 +31,7 @@ def _lstrip_str(in_s: str, lstr: str) -> str: """ if in_s.startswith(lstr): - res = in_s[len(lstr):] + res = in_s[len(lstr) :] else: res = in_s return res @@ -116,10 +116,10 @@ class RetryAfter(TelegramError): class Conflict(TelegramError): """ - Raised when a long poll or webhook conflicts with another one. + Raised when a long poll or webhook conflicts with another one. - Args: - msg (:obj:`str`): The message from telegrams server. + Args: + msg (:obj:`str`): The message from telegrams server. """ diff --git a/telegram/ext/__init__.py b/telegram/ext/__init__.py index a39b067e9..b614e292c 100644 --- a/telegram/ext/__init__.py +++ b/telegram/ext/__init__.py @@ -45,11 +45,38 @@ from .pollanswerhandler import PollAnswerHandler from .pollhandler import PollHandler from .defaults import Defaults -__all__ = ('Dispatcher', 'JobQueue', 'Job', 'Updater', 'CallbackQueryHandler', - 'ChosenInlineResultHandler', 'CommandHandler', 'Handler', 'InlineQueryHandler', - 'MessageHandler', 'BaseFilter', 'MessageFilter', 'UpdateFilter', 'Filters', - 'RegexHandler', 'StringCommandHandler', 'StringRegexHandler', 'TypeHandler', - 'ConversationHandler', 'PreCheckoutQueryHandler', 'ShippingQueryHandler', - 'MessageQueue', 'DelayQueue', 'DispatcherHandlerStop', 'run_async', 'CallbackContext', - 'BasePersistence', 'PicklePersistence', 'DictPersistence', 'PrefixHandler', - 'PollAnswerHandler', 'PollHandler', 'Defaults') +__all__ = ( + 'Dispatcher', + 'JobQueue', + 'Job', + 'Updater', + 'CallbackQueryHandler', + 'ChosenInlineResultHandler', + 'CommandHandler', + 'Handler', + 'InlineQueryHandler', + 'MessageHandler', + 'BaseFilter', + 'MessageFilter', + 'UpdateFilter', + 'Filters', + 'RegexHandler', + 'StringCommandHandler', + 'StringRegexHandler', + 'TypeHandler', + 'ConversationHandler', + 'PreCheckoutQueryHandler', + 'ShippingQueryHandler', + 'MessageQueue', + 'DelayQueue', + 'DispatcherHandlerStop', + 'run_async', + 'CallbackContext', + 'BasePersistence', + 'PicklePersistence', + 'DictPersistence', + 'PrefixHandler', + 'PollAnswerHandler', + 'PollHandler', + 'Defaults', +) diff --git a/telegram/ext/basepersistence.py b/telegram/ext/basepersistence.py index 841b83576..e7be4d7e6 100644 --- a/telegram/ext/basepersistence.py +++ b/telegram/ext/basepersistence.py @@ -108,10 +108,12 @@ class BasePersistence(ABC): instance.update_bot_data = update_bot_data_replace_bot return instance - def __init__(self, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True): + def __init__( + self, + store_user_data: bool = True, + store_chat_data: bool = True, + store_bot_data: bool = True, + ): self.store_user_data = store_user_data self.store_chat_data = store_chat_data self.store_bot_data = store_bot_data @@ -157,8 +159,11 @@ class BasePersistence(ABC): return new_obj if hasattr(obj, '__slots__'): for attr_name in new_obj.__slots__: - setattr(new_obj, attr_name, - cls.replace_bot(cls.replace_bot(getattr(new_obj, attr_name)))) + setattr( + new_obj, + attr_name, + cls.replace_bot(cls.replace_bot(getattr(new_obj, attr_name))), + ) return new_obj return obj @@ -196,14 +201,17 @@ class BasePersistence(ABC): return new_obj if hasattr(obj, '__slots__'): for attr_name in obj.__slots__: - setattr(new_obj, attr_name, - self.insert_bot(self.insert_bot(getattr(new_obj, attr_name)))) + setattr( + new_obj, + attr_name, + self.insert_bot(self.insert_bot(getattr(new_obj, attr_name))), + ) return new_obj return obj @abstractmethod def get_user_data(self) -> DefaultDict[int, Dict[Any, Any]]: - """"Will be called by :class:`telegram.ext.Dispatcher` upon creation with a + """ "Will be called by :class:`telegram.ext.Dispatcher` upon creation with a persistence object. It should return the user_data if stored, or an empty ``defaultdict(dict)``. @@ -213,7 +221,7 @@ class BasePersistence(ABC): @abstractmethod def get_chat_data(self) -> DefaultDict[int, Dict[Any, Any]]: - """"Will be called by :class:`telegram.ext.Dispatcher` upon creation with a + """ "Will be called by :class:`telegram.ext.Dispatcher` upon creation with a persistence object. It should return the chat_data if stored, or an empty ``defaultdict(dict)``. @@ -223,7 +231,7 @@ class BasePersistence(ABC): @abstractmethod def get_bot_data(self) -> Dict[Any, Any]: - """"Will be called by :class:`telegram.ext.Dispatcher` upon creation with a + """ "Will be called by :class:`telegram.ext.Dispatcher` upon creation with a persistence object. It should return the bot_data if stored, or an empty :obj:`dict`. @@ -233,7 +241,7 @@ class BasePersistence(ABC): @abstractmethod def get_conversations(self, name: str) -> ConversationDict: - """"Will be called by :class:`telegram.ext.Dispatcher` when a + """ "Will be called by :class:`telegram.ext.Dispatcher` when a :class:`telegram.ext.ConversationHandler` is added if :attr:`telegram.ext.ConversationHandler.persistent` is :obj:`True`. It should return the conversations for the handler with `name` or an empty :obj:`dict` @@ -246,9 +254,9 @@ class BasePersistence(ABC): """ @abstractmethod - def update_conversation(self, - name: str, key: Tuple[int, ...], - new_state: Optional[object]) -> None: + def update_conversation( + self, name: str, key: Tuple[int, ...], new_state: Optional[object] + ) -> None: """Will be called when a :attr:`telegram.ext.ConversationHandler.update_state` is called. This allows the storage of the new state in the persistence. diff --git a/telegram/ext/callbackcontext.py b/telegram/ext/callbackcontext.py index 16bee0aa7..665e5826a 100644 --- a/telegram/ext/callbackcontext.py +++ b/telegram/ext/callbackcontext.py @@ -21,6 +21,7 @@ from queue import Queue from typing import Dict, Any, Tuple, TYPE_CHECKING, Optional, Match, List, NoReturn, Union from telegram import Update + if TYPE_CHECKING: from telegram import Bot from telegram.ext import Dispatcher, Job, JobQueue @@ -91,8 +92,9 @@ class CallbackContext: dispatcher (:class:`telegram.ext.Dispatcher`): """ if not dispatcher.use_context: - raise ValueError('CallbackContext should not be used with a non context aware ' - 'dispatcher!') + raise ValueError( + 'CallbackContext should not be used with a non context aware ' 'dispatcher!' + ) self._dispatcher = dispatcher self._bot_data = dispatcher.bot_data self._chat_data: Optional[Dict[Any, Any]] = None @@ -115,8 +117,9 @@ class CallbackContext: @bot_data.setter def bot_data(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to bot_data, see " - "https://git.io/fjxKe") + raise AttributeError( + "You can not assign a new value to bot_data, see " "https://git.io/fjxKe" + ) @property def chat_data(self) -> Optional[Dict]: @@ -124,8 +127,9 @@ class CallbackContext: @chat_data.setter def chat_data(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to chat_data, see " - "https://git.io/fjxKe") + raise AttributeError( + "You can not assign a new value to chat_data, see " "https://git.io/fjxKe" + ) @property def user_data(self) -> Optional[Dict]: @@ -133,16 +137,19 @@ class CallbackContext: @user_data.setter def user_data(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to user_data, see " - "https://git.io/fjxKe") + raise AttributeError( + "You can not assign a new value to user_data, see " "https://git.io/fjxKe" + ) @classmethod - def from_error(cls, - update: object, - error: Exception, - dispatcher: 'Dispatcher', - async_args: Union[List, Tuple] = None, - async_kwargs: Dict[str, Any] = None) -> 'CallbackContext': + def from_error( + cls, + update: object, + error: Exception, + dispatcher: 'Dispatcher', + async_args: Union[List, Tuple] = None, + async_kwargs: Dict[str, Any] = None, + ) -> 'CallbackContext': self = cls.from_update(update, dispatcher) self.error = error self.async_args = async_args diff --git a/telegram/ext/callbackqueryhandler.py b/telegram/ext/callbackqueryhandler.py index f6f07d8f2..2fa0bbc43 100644 --- a/telegram/ext/callbackqueryhandler.py +++ b/telegram/ext/callbackqueryhandler.py @@ -24,8 +24,18 @@ from telegram import Update from .handler import Handler from telegram.utils.types import HandlerArg -from typing import Callable, TYPE_CHECKING, Any, Optional, Union, TypeVar, Pattern, Match, Dict, \ - cast +from typing import ( + Callable, + TYPE_CHECKING, + Any, + Optional, + Union, + TypeVar, + Pattern, + Match, + Dict, + cast, +) if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -110,23 +120,26 @@ class CallbackQueryHandler(Handler): """ - def __init__(self, - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pattern: Union[str, Pattern] = None, - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - run_async: bool = False): + def __init__( + self, + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + pass_update_queue: bool = False, + pass_job_queue: bool = False, + pattern: Union[str, Pattern] = None, + pass_groups: bool = False, + pass_groupdict: bool = False, + pass_user_data: bool = False, + pass_chat_data: bool = False, + run_async: bool = False, + ): super().__init__( callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue, pass_user_data=pass_user_data, pass_chat_data=pass_chat_data, - run_async=run_async) + run_async=run_async, + ) if isinstance(pattern, str): pattern = re.compile(pattern) @@ -155,10 +168,12 @@ class CallbackQueryHandler(Handler): return True return None - def collect_optional_args(self, - dispatcher: 'Dispatcher', - update: HandlerArg = None, - check_result: Union[bool, Match] = None) -> Dict[str, Any]: + def collect_optional_args( + self, + dispatcher: 'Dispatcher', + update: HandlerArg = None, + check_result: Union[bool, Match] = None, + ) -> Dict[str, Any]: optional_args = super().collect_optional_args(dispatcher, update, check_result) if self.pattern: check_result = cast(Match, check_result) @@ -168,11 +183,13 @@ class CallbackQueryHandler(Handler): optional_args['groupdict'] = check_result.groupdict() return optional_args - def collect_additional_context(self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Union[bool, Match]) -> None: + def collect_additional_context( + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Union[bool, Match], + ) -> None: if self.pattern: check_result = cast(Match, check_result) context.matches = [check_result] diff --git a/telegram/ext/choseninlineresulthandler.py b/telegram/ext/choseninlineresulthandler.py index 48957c06c..ed66d2fdf 100644 --- a/telegram/ext/choseninlineresulthandler.py +++ b/telegram/ext/choseninlineresulthandler.py @@ -23,6 +23,7 @@ from .handler import Handler from telegram.utils.types import HandlerArg from typing import Optional, Union, TypeVar + RT = TypeVar('RT') diff --git a/telegram/ext/commandhandler.py b/telegram/ext/commandhandler.py index 184128eea..a91230555 100644 --- a/telegram/ext/commandhandler.py +++ b/telegram/ext/commandhandler.py @@ -28,6 +28,7 @@ from .handler import Handler from telegram.utils.types import HandlerArg from typing import Callable, TYPE_CHECKING, Any, Optional, Union, TypeVar, Dict, List, Tuple + if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -130,24 +131,27 @@ class CommandHandler(Handler): ValueError - when command is too long or has illegal chars. """ - def __init__(self, - command: Union[str, List[str]], - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - filters: BaseFilter = None, - allow_edited: bool = None, - pass_args: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - run_async: bool = False): + def __init__( + self, + command: Union[str, List[str]], + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + filters: BaseFilter = None, + allow_edited: bool = None, + pass_args: bool = False, + pass_update_queue: bool = False, + pass_job_queue: bool = False, + pass_user_data: bool = False, + pass_chat_data: bool = False, + run_async: bool = False, + ): super().__init__( callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue, pass_user_data=pass_user_data, pass_chat_data=pass_chat_data, - run_async=run_async) + run_async=run_async, + ) if isinstance(command, str): self.command = [command.lower()] @@ -163,17 +167,18 @@ class CommandHandler(Handler): self.filters = Filters.update.messages if allow_edited is not None: - warnings.warn('allow_edited is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2) + warnings.warn( + 'allow_edited is deprecated. See https://git.io/fxJuV for more info', + TelegramDeprecationWarning, + stacklevel=2, + ) if not allow_edited: self.filters &= ~Filters.update.edited_message self.pass_args = pass_args def check_update( - self, - update: HandlerArg) -> Optional[Union[bool, Tuple[List[str], - Optional[Union[bool, Dict]]]]]: + self, update: HandlerArg + ) -> Optional[Union[bool, Tuple[List[str], Optional[Union[bool, Dict]]]]]: """Determines whether an update should be passed to this handlers :attr:`callback`. Args: @@ -186,15 +191,22 @@ class CommandHandler(Handler): if isinstance(update, Update) and update.effective_message: message = update.effective_message - if (message.entities and message.entities[0].type == MessageEntity.BOT_COMMAND - and message.entities[0].offset == 0 and message.text and message.bot): - command = message.text[1:message.entities[0].length] + if ( + message.entities + and message.entities[0].type == MessageEntity.BOT_COMMAND + and message.entities[0].offset == 0 + and message.text + and message.bot + ): + command = message.text[1 : message.entities[0].length] args = message.text.split()[1:] command_parts = command.split('@') command_parts.append(message.bot.username) - if not (command_parts[0].lower() in self.command - and command_parts[1].lower() == message.bot.username.lower()): + if not ( + command_parts[0].lower() in self.command + and command_parts[1].lower() == message.bot.username.lower() + ): return None filter_result = self.filters(update) @@ -205,22 +217,23 @@ class CommandHandler(Handler): return None def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: HandlerArg = None, - check_result: Optional[Union[bool, Tuple[List[str], - Optional[bool]]]] = None) -> Dict[str, Any]: + self, + dispatcher: 'Dispatcher', + update: HandlerArg = None, + check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]] = None, + ) -> Dict[str, Any]: optional_args = super().collect_optional_args(dispatcher, update) if self.pass_args and isinstance(check_result, tuple): optional_args['args'] = check_result[0] return optional_args def collect_additional_context( - self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]]) -> None: + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]], + ) -> None: if isinstance(check_result, tuple): context.args = check_result[0] if isinstance(check_result[1], dict): @@ -330,29 +343,36 @@ class PrefixHandler(CommandHandler): """ - def __init__(self, - prefix: Union[str, List[str]], - command: Union[str, List[str]], - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - filters: BaseFilter = None, - pass_args: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - run_async: bool = False): + def __init__( + self, + prefix: Union[str, List[str]], + command: Union[str, List[str]], + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + filters: BaseFilter = None, + pass_args: bool = False, + pass_update_queue: bool = False, + pass_job_queue: bool = False, + pass_user_data: bool = False, + pass_chat_data: bool = False, + run_async: bool = False, + ): self._prefix: List[str] = list() self._command: List[str] = list() self._commands: List[str] = list() 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_job_queue=pass_job_queue, pass_user_data=pass_user_data, pass_chat_data=pass_chat_data, - run_async=run_async) + run_async=run_async, + ) self.prefix = prefix # type: ignore[assignment] self.command = command # type: ignore[assignment] @@ -385,8 +405,9 @@ class PrefixHandler(CommandHandler): def _build_commands(self) -> None: self._commands = [x.lower() + y.lower() for x in self.prefix for y in self.command] - def check_update(self, update: HandlerArg) -> Optional[Union[bool, Tuple[List[str], - Optional[Union[bool, Dict]]]]]: + def check_update( + self, update: HandlerArg + ) -> Optional[Union[bool, Tuple[List[str], Optional[Union[bool, Dict]]]]]: """Determines whether an update should be passed to this handlers :attr:`callback`. Args: @@ -411,11 +432,12 @@ class PrefixHandler(CommandHandler): return None def collect_additional_context( - self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]]) -> None: + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]], + ) -> None: if isinstance(check_result, tuple): context.args = check_result[0] if isinstance(check_result[1], dict): diff --git a/telegram/ext/conversationhandler.py b/telegram/ext/conversationhandler.py index cbb341f62..bee391ccd 100644 --- a/telegram/ext/conversationhandler.py +++ b/telegram/ext/conversationhandler.py @@ -23,9 +23,15 @@ import warnings from threading import Lock from telegram import Update -from telegram.ext import (Handler, CallbackQueryHandler, InlineQueryHandler, - ChosenInlineResultHandler, CallbackContext, BasePersistence, - DispatcherHandlerStop) +from telegram.ext import ( + Handler, + CallbackQueryHandler, + InlineQueryHandler, + ChosenInlineResultHandler, + CallbackContext, + BasePersistence, + DispatcherHandlerStop, +) from telegram.utils.promise import Promise from telegram.utils.types import ConversationDict, HandlerArg @@ -37,11 +43,13 @@ CheckUpdateType = Optional[Tuple[Tuple[int, ...], Handler, object]] class _ConversationTimeoutContext: - def __init__(self, - conversation_key: Tuple[int, ...], - update: Update, - dispatcher: 'Dispatcher', - callback_context: Optional[CallbackContext]): + def __init__( + self, + conversation_key: Tuple[int, ...], + update: Update, + dispatcher: 'Dispatcher', + callback_context: Optional[CallbackContext], + ): self.conversation_key = conversation_key self.update = update self.dispatcher = dispatcher @@ -160,6 +168,7 @@ class ConversationHandler(Handler): ValueError """ + END = -1 """:obj:`int`: Used as a constant to return when a conversation is ended.""" TIMEOUT = -2 @@ -168,18 +177,20 @@ class ConversationHandler(Handler): """:obj:`int`: Used as a constant to handle state when a conversation is still waiting on the previous ``@run_sync`` decorated running handler to finish.""" - def __init__(self, - entry_points: List[Handler], - states: Dict[object, List[Handler]], - fallbacks: List[Handler], - allow_reentry: bool = False, - per_chat: bool = True, - per_user: bool = True, - per_message: bool = False, - conversation_timeout: int = None, - name: str = None, - persistent: bool = False, - map_to_parent: Dict[object, object] = None): + def __init__( + self, + entry_points: List[Handler], + states: Dict[object, List[Handler]], + fallbacks: List[Handler], + allow_reentry: bool = False, + per_chat: bool = True, + per_user: bool = True, + per_message: bool = False, + conversation_timeout: int = None, + name: str = None, + persistent: bool = False, + map_to_parent: Dict[object, object] = None, + ): self.run_async = False self._entry_points = entry_points @@ -211,8 +222,10 @@ class ConversationHandler(Handler): raise ValueError("'per_user', 'per_chat' and 'per_message' can't all be 'False'") if self.per_message and not self.per_chat: - warnings.warn("If 'per_message=True' is used, 'per_chat=True' should also be used, " - "since message IDs are not globally unique.") + warnings.warn( + "If 'per_message=True' is used, 'per_chat=True' should also be used, " + "since message IDs are not globally unique." + ) all_handlers = list() all_handlers.extend(entry_points) @@ -224,22 +237,28 @@ class ConversationHandler(Handler): if self.per_message: for handler in all_handlers: if not isinstance(handler, CallbackQueryHandler): - warnings.warn("If 'per_message=True', all entry points and state handlers" - " must be 'CallbackQueryHandler', since no other handlers " - "have a message context.") + warnings.warn( + "If 'per_message=True', all entry points and state handlers" + " must be 'CallbackQueryHandler', since no other handlers " + "have a message context." + ) break else: for handler in all_handlers: if isinstance(handler, CallbackQueryHandler): - warnings.warn("If 'per_message=False', 'CallbackQueryHandler' will not be " - "tracked for every message.") + warnings.warn( + "If 'per_message=False', 'CallbackQueryHandler' will not be " + "tracked for every message." + ) break if self.per_chat: for handler in all_handlers: if isinstance(handler, (InlineQueryHandler, ChosenInlineResultHandler)): - warnings.warn("If 'per_chat=True', 'InlineQueryHandler' can not be used, " - "since inline queries have no chat context.") + warnings.warn( + "If 'per_chat=True', 'InlineQueryHandler' can not be used, " + "since inline queries have no chat context." + ) break @property @@ -304,8 +323,9 @@ class ConversationHandler(Handler): @conversation_timeout.setter def conversation_timeout(self, value: Any) -> NoReturn: - raise ValueError('You can not assign a new value to conversation_timeout after ' - 'initialization.') + raise ValueError( + 'You can not assign a new value to conversation_timeout after ' 'initialization.' + ) @property def name(self) -> Optional[str]: @@ -362,8 +382,10 @@ class ConversationHandler(Handler): key.append(user.id) if self.per_message: - key.append(update.callback_query.inline_message_id # type: ignore[union-attr] - or update.callback_query.message.message_id) # type: ignore[union-attr] + key.append( + update.callback_query.inline_message_id # type: ignore[union-attr] + or update.callback_query.message.message_id # type: ignore[union-attr] + ) return tuple(key) @@ -380,11 +402,17 @@ class ConversationHandler(Handler): """ # Ignore messages in channels - if (not isinstance(update, Update) - or update.channel_post - or self.per_chat and not update.effective_chat - or self.per_message and not update.callback_query - or update.callback_query and self.per_chat and not update.callback_query.message): + if ( + not isinstance(update, Update) + or update.channel_post + or self.per_chat + and not update.effective_chat + or self.per_message + and not update.callback_query + or update.callback_query + and self.per_chat + and not update.callback_query.message + ): return None key = self._get_key(update) @@ -438,7 +466,7 @@ class ConversationHandler(Handler): if state is not None and not handler: handlers = self.states.get(state) - for candidate in (handlers or []): + for candidate in handlers or []: check = candidate.check_update(update) if check is not None and check is not False: handler = candidate @@ -457,11 +485,13 @@ class ConversationHandler(Handler): return key, handler, check # type: ignore[return-value] - def handle_update(self, # type: ignore[override] - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: CheckUpdateType, - context: CallbackContext = None) -> Optional[object]: + def handle_update( # type: ignore[override] + self, + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: CheckUpdateType, + context: CallbackContext = None, + ) -> Optional[object]: """Send the update to the callback for the current state and Handler Args: @@ -492,9 +522,12 @@ class ConversationHandler(Handler): if self.conversation_timeout and new_state != self.END and dispatcher.job_queue: # Add the new timeout job self.timeout_jobs[conversation_key] = dispatcher.job_queue.run_once( - self._trigger_timeout, self.conversation_timeout, # type: ignore[arg-type] - context=_ConversationTimeoutContext(conversation_key, update, - dispatcher, context)) + self._trigger_timeout, # type: ignore[arg-type] + self.conversation_timeout, + context=_ConversationTimeoutContext( + conversation_key, update, dispatcher, context + ), + ) if isinstance(self.map_to_parent, dict) and new_state in self.map_to_parent: self.update_state(self.END, conversation_key) @@ -510,9 +543,7 @@ class ConversationHandler(Handler): raise DispatcherHandlerStop() return None - def update_state(self, - new_state: object, - key: Tuple[int, ...]) -> None: + def update_state(self, new_state: object, key: Tuple[int, ...]) -> None: if new_state == self.END: with self._conversations_lock: if key in self.conversations: @@ -525,8 +556,9 @@ class ConversationHandler(Handler): with self._conversations_lock: self.conversations[key] = (self.conversations.get(key), new_state) if self.persistent and self.persistence and self.name: - self.persistence.update_conversation(self.name, key, - (self.conversations.get(key), new_state)) + self.persistence.update_conversation( + self.name, key, (self.conversations.get(key), new_state) + ) elif new_state is not None: with self._conversations_lock: @@ -534,9 +566,7 @@ class ConversationHandler(Handler): if self.persistent and self.persistence and self.name: self.persistence.update_conversation(self.name, key, new_state) - def _trigger_timeout(self, - context: _ConversationTimeoutContext, - job: 'Job' = None) -> None: + def _trigger_timeout(self, context: _ConversationTimeoutContext, job: 'Job' = None) -> None: self.logger.debug('conversation timeout was triggered!') # Backward compatibility with bots that do not use CallbackContext @@ -559,9 +589,12 @@ class ConversationHandler(Handler): check = handler.check_update(context.update) if check is not None and check is not False: try: - handler.handle_update(context.update, context.dispatcher, check, - callback_context) + handler.handle_update( + context.update, context.dispatcher, check, callback_context + ) except DispatcherHandlerStop: - self.logger.warning('DispatcherHandlerStop in TIMEOUT state of ' - 'ConversationHandler has no effect. Ignoring.') + self.logger.warning( + 'DispatcherHandlerStop in TIMEOUT state of ' + 'ConversationHandler has no effect. Ignoring.' + ) self.update_state(self.END, context.conversation_key) diff --git a/telegram/ext/defaults.py b/telegram/ext/defaults.py index 3ac8da5dd..6b041db71 100644 --- a/telegram/ext/defaults.py +++ b/telegram/ext/defaults.py @@ -60,15 +60,18 @@ class Defaults: somewhere, it will be assumed to be in ``tzinfo``. Must be a timezone provided by the ``pytz`` module. Defaults to UTC. """ - def __init__(self, - parse_mode: str = None, - disable_notification: bool = None, - disable_web_page_preview: bool = None, - # Timeout needs special treatment, since the bot methods have two different - # default values for timeout (None and 20s) - timeout: Union[float, DefaultValue] = DEFAULT_NONE, - quote: bool = None, - tzinfo: pytz.BaseTzInfo = pytz.utc): + + def __init__( + self, + parse_mode: str = None, + disable_notification: bool = None, + disable_web_page_preview: bool = None, + # Timeout needs special treatment, since the bot methods have two different + # default values for timeout (None and 20s) + timeout: Union[float, DefaultValue] = DEFAULT_NONE, + quote: bool = None, + tzinfo: pytz.BaseTzInfo = pytz.utc, + ): self._parse_mode = parse_mode self._disable_notification = disable_notification self._disable_web_page_preview = disable_web_page_preview @@ -82,8 +85,10 @@ class Defaults: @parse_mode.setter def parse_mode(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to defaults after because it would " - "not have any effect.") + raise AttributeError( + "You can not assign a new value to defaults after because it would " + "not have any effect." + ) @property def disable_notification(self) -> Optional[bool]: @@ -91,8 +96,10 @@ class Defaults: @disable_notification.setter def disable_notification(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to defaults after because it would " - "not have any effect.") + raise AttributeError( + "You can not assign a new value to defaults after because it would " + "not have any effect." + ) @property def disable_web_page_preview(self) -> Optional[bool]: @@ -100,8 +107,10 @@ class Defaults: @disable_web_page_preview.setter def disable_web_page_preview(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to defaults after because it would " - "not have any effect.") + raise AttributeError( + "You can not assign a new value to defaults after because it would " + "not have any effect." + ) @property def timeout(self) -> Union[float, DefaultValue]: @@ -109,8 +118,10 @@ class Defaults: @timeout.setter def timeout(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to defaults after because it would " - "not have any effect.") + raise AttributeError( + "You can not assign a new value to defaults after because it would " + "not have any effect." + ) @property def quote(self) -> Optional[bool]: @@ -118,8 +129,10 @@ class Defaults: @quote.setter def quote(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to defaults after because it would " - "not have any effect.") + raise AttributeError( + "You can not assign a new value to defaults after because it would " + "not have any effect." + ) @property def tzinfo(self) -> pytz.BaseTzInfo: @@ -127,16 +140,22 @@ class Defaults: @tzinfo.setter def tzinfo(self, value: Any) -> NoReturn: - raise AttributeError("You can not assign a new value to defaults after because it would " - "not have any effect.") + raise AttributeError( + "You can not assign a new value to defaults after because it would " + "not have any effect." + ) def __hash__(self) -> int: - return hash((self._parse_mode, - self._disable_notification, - self._disable_web_page_preview, - self._timeout, - self._quote, - self._tzinfo)) + return hash( + ( + self._parse_mode, + self._disable_notification, + self._disable_web_page_preview, + self._timeout, + self._quote, + self._tzinfo, + ) + ) def __eq__(self, other: object) -> bool: if isinstance(other, Defaults): diff --git a/telegram/ext/dictpersistence.py b/telegram/ext/dictpersistence.py index 78a69be1c..7623efe6b 100644 --- a/telegram/ext/dictpersistence.py +++ b/telegram/ext/dictpersistence.py @@ -19,8 +19,11 @@ """This module contains the DictPersistence class.""" from copy import deepcopy -from telegram.utils.helpers import decode_user_chat_data_from_json,\ - decode_conversations_from_json, encode_conversations_to_json +from telegram.utils.helpers import ( + decode_user_chat_data_from_json, + decode_conversations_from_json, + encode_conversations_to_json, +) try: import ujson as json @@ -76,17 +79,21 @@ class DictPersistence(BasePersistence): conversation on creating this persistence. Default is ``""``. """ - def __init__(self, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True, - user_data_json: str = '', - chat_data_json: str = '', - bot_data_json: str = '', - conversations_json: str = ''): - super().__init__(store_user_data=store_user_data, - store_chat_data=store_chat_data, - store_bot_data=store_bot_data) + def __init__( + self, + store_user_data: bool = True, + store_chat_data: bool = True, + store_bot_data: bool = True, + user_data_json: str = '', + chat_data_json: str = '', + bot_data_json: str = '', + conversations_json: str = '', + ): + super().__init__( + store_user_data=store_user_data, + store_chat_data=store_chat_data, + store_bot_data=store_bot_data, + ) self._user_data = None self._chat_data = None self._bot_data = None @@ -226,9 +233,9 @@ class DictPersistence(BasePersistence): self._conversations = {} return self.conversations.get(name, {}).copy() # type: ignore[union-attr] - def update_conversation(self, - name: str, key: Tuple[int, ...], - new_state: Optional[object]) -> None: + def update_conversation( + self, name: str, key: Tuple[int, ...], new_state: Optional[object] + ) -> None: """Will update the conversations for the given handler. Args: diff --git a/telegram/ext/dispatcher.py b/telegram/ext/dispatcher.py index fcf47b1a3..a4c1b48a1 100644 --- a/telegram/ext/dispatcher.py +++ b/telegram/ext/dispatcher.py @@ -47,8 +47,9 @@ if TYPE_CHECKING: DEFAULT_GROUP = 0 -def run_async(func: Callable[[Update, CallbackContext], - Any]) -> Callable[[Update, CallbackContext], Any]: +def run_async( + func: Callable[[Update, CallbackContext], Any] +) -> Callable[[Update, CallbackContext], Any]: """ Function decorator that will run the function in a new thread. @@ -67,12 +68,15 @@ def run_async(func: Callable[[Update, CallbackContext], @wraps(func) def async_func(*args: Any, **kwargs: Any) -> Any: - warnings.warn('The @run_async decorator is deprecated. Use the `run_async` parameter of' - '`Dispatcher.add_handler` or `Dispatcher.run_async` instead.', - TelegramDeprecationWarning, - stacklevel=2) - return Dispatcher.get_instance()._run_async(func, *args, update=None, error_handling=False, - **kwargs) + warnings.warn( + 'The @run_async decorator is deprecated. Use the `run_async` parameter of' + '`Dispatcher.add_handler` or `Dispatcher.run_async` instead.', + TelegramDeprecationWarning, + stacklevel=2, + ) + return Dispatcher.get_instance()._run_async( + func, *args, update=None, error_handling=False, **kwargs + ) return async_func @@ -96,6 +100,7 @@ class DispatcherHandlerStop(Exception): Args: state (:obj:`object`, optional): The next state of the conversation. """ + def __init__(self, state: object = None) -> None: super().__init__() self.state = state @@ -137,14 +142,16 @@ class Dispatcher: __singleton = None logger = logging.getLogger(__name__) - def __init__(self, - bot: 'Bot', - update_queue: Queue, - workers: int = 4, - exception_event: Event = None, - job_queue: 'JobQueue' = None, - persistence: BasePersistence = None, - use_context: bool = True): + def __init__( + self, + bot: 'Bot', + update_queue: Queue, + workers: int = 4, + exception_event: Event = None, + job_queue: 'JobQueue' = None, + persistence: BasePersistence = None, + use_context: bool = True, + ): self.bot = bot self.update_queue = update_queue self.job_queue = job_queue @@ -152,8 +159,11 @@ class Dispatcher: self.use_context = use_context if not use_context: - warnings.warn('Old Handler API is deprecated - see https://git.io/fxJuV for details', - TelegramDeprecationWarning, stacklevel=3) + warnings.warn( + 'Old Handler API is deprecated - see https://git.io/fxJuV for details', + TelegramDeprecationWarning, + stacklevel=3, + ) self.user_data: DefaultDict[int, Dict[Any, Any]] = defaultdict(dict) self.chat_data: DefaultDict[int, Dict[Any, Any]] = defaultdict(dict) @@ -211,8 +221,9 @@ class Dispatcher: base_name = '{}_'.format(base_name) if base_name else '' for i in range(workers): - thread = Thread(target=self._pooled, name='Bot:{}:worker:{}{}'.format(self.bot.id, - base_name, i)) + thread = Thread( + target=self._pooled, name='Bot:{}:worker:{}{}'.format(self.bot.id, base_name, i) + ) self.__async_threads.add(thread) thread.start() @@ -235,8 +246,9 @@ class Dispatcher: if cls.__singleton is not None: return cls.__singleton() # type: ignore[return-value] # pylint: disable=not-callable else: - raise RuntimeError('{} not initialized or multiple instances exist'.format( - cls.__name__)) + raise RuntimeError( + '{} not initialized or multiple instances exist'.format(cls.__name__) + ) def _pooled(self) -> None: thr_name = current_thread().getName() @@ -245,8 +257,9 @@ class Dispatcher: # If unpacking fails, the thread pool is being closed from Updater._join_async_threads if not isinstance(promise, Promise): - self.logger.debug("Closing run_async thread %s/%d", thr_name, - len(self.__async_threads)) + self.logger.debug( + "Closing run_async thread %s/%d", thr_name, len(self.__async_threads) + ) break promise.run() @@ -258,7 +271,8 @@ class Dispatcher: if isinstance(promise.exception, DispatcherHandlerStop): self.logger.warning( 'DispatcherHandlerStop is not supported with async functions; func: %s', - promise.pooled_function.__name__) + promise.pooled_function.__name__, + ) continue # Avoid infinite recursion of error handlers. @@ -280,11 +294,9 @@ class Dispatcher: except Exception: self.logger.exception('An uncaught error was raised while handling the error.') - def run_async(self, - func: Callable[..., Any], - *args: Any, - update: HandlerArg = None, - **kwargs: Any) -> Promise: + def run_async( + self, func: Callable[..., Any], *args: Any, update: HandlerArg = None, **kwargs: Any + ) -> Promise: """ Queue a function (with given args/kwargs) to be run asynchronously. Exceptions raised by the function will be handled by the error handlers registered with @@ -310,12 +322,14 @@ class Dispatcher: """ return self._run_async(func, *args, update=update, error_handling=True, **kwargs) - def _run_async(self, - func: Callable[..., Any], - *args: Any, - update: HandlerArg = None, - error_handling: bool = True, - **kwargs: Any) -> Promise: + def _run_async( + self, + func: Callable[..., Any], + *args: Any, + update: HandlerArg = None, + error_handling: bool = True, + **kwargs: Any, + ) -> Promise: # TODO: Remove error_handling parameter once we drop the @run_async decorator promise = Promise(func, args, kwargs, update=update, error_handling=error_handling) self.__async_queue.put(promise) @@ -482,7 +496,8 @@ class Dispatcher: if not self.persistence: raise ValueError( "ConversationHandler {} can not be persistent if dispatcher has no " - "persistence".format(handler.name)) + "persistence".format(handler.name) + ) handler.persistence = self.persistence handler.conversations = self.persistence.get_conversations(handler.name) @@ -541,9 +556,11 @@ class Dispatcher: try: self.dispatch_error(update, e) except Exception: - message = 'Saving bot data raised an error and an ' \ - 'uncaught error was raised while handling ' \ - 'the error with an error_handler' + message = ( + 'Saving bot data raised an error and an ' + 'uncaught error was raised while handling ' + 'the error with an error_handler' + ) self.logger.exception(message) if self.persistence.store_chat_data: for chat_id in chat_ids: @@ -553,9 +570,11 @@ class Dispatcher: try: self.dispatch_error(update, e) except Exception: - message = 'Saving chat data raised an error and an ' \ - 'uncaught error was raised while handling ' \ - 'the error with an error_handler' + message = ( + 'Saving chat data raised an error and an ' + 'uncaught error was raised while handling ' + 'the error with an error_handler' + ) self.logger.exception(message) if self.persistence.store_user_data: for user_id in user_ids: @@ -565,14 +584,16 @@ class Dispatcher: try: self.dispatch_error(update, e) except Exception: - message = 'Saving user data raised an error and an ' \ - 'uncaught error was raised while handling ' \ - 'the error with an error_handler' + message = ( + 'Saving user data raised an error and an ' + 'uncaught error was raised while handling ' + 'the error with an error_handler' + ) self.logger.exception(message) - def add_error_handler(self, - callback: Callable[[Any, CallbackContext], None], - run_async: bool = False) -> None: + def add_error_handler( + self, callback: Callable[[Any, CallbackContext], None], run_async: bool = False + ) -> None: """Registers an error handler in the Dispatcher. This handler will receive every error which happens in your bot. @@ -610,10 +631,9 @@ class Dispatcher: """ self.error_handlers.pop(callback, None) - def dispatch_error(self, - update: Optional[HandlerArg], - error: Exception, - promise: Promise = None) -> None: + def dispatch_error( + self, update: Optional[HandlerArg], error: Exception, promise: Promise = None + ) -> None: """Dispatches an error. Args: @@ -629,9 +649,9 @@ class Dispatcher: if self.error_handlers: for callback, run_async in self.error_handlers.items(): if self.use_context: - context = CallbackContext.from_error(update, error, self, - async_args=async_args, - async_kwargs=async_kwargs) + context = CallbackContext.from_error( + update, error, self, async_args=async_args, async_kwargs=async_kwargs + ) if run_async: self.run_async(callback, update, context, update=update) else: @@ -644,4 +664,5 @@ class Dispatcher: else: self.logger.exception( - 'No error handlers are registered, logging exception.', exc_info=error) + 'No error handlers are registered, logging exception.', exc_info=error + ) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index ee0d2309c..8cb4d2787 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -27,8 +27,14 @@ from telegram import Chat, Update, MessageEntity, Message from typing import Optional, Dict, Union, List, Pattern, Match, cast, Set, FrozenSet -__all__ = ['Filters', 'BaseFilter', 'MessageFilter', 'UpdateFilter', 'InvertedFilter', - 'MergedFilter'] +__all__ = [ + 'Filters', + 'BaseFilter', + 'MessageFilter', + 'UpdateFilter', + 'InvertedFilter', + 'MergedFilter', +] class BaseFilter(ABC): @@ -120,6 +126,7 @@ class MessageFilter(BaseFilter, ABC): (depends on the handler). """ + def __call__(self, update: Update) -> Optional[Union[bool, Dict]]: return self.filter(update.effective_message) @@ -151,12 +158,12 @@ class UpdateFilter(BaseFilter, ABC): (depends on the handler). """ + def __call__(self, update: Update) -> Optional[Union[bool, Dict]]: return self.filter(update) @abstractmethod - def filter(self, - update: Update) -> Optional[Union[bool, Dict]]: + def filter(self, update: Update) -> Optional[Union[bool, Dict]]: """This method must be overwritten. Args: @@ -175,6 +182,7 @@ class InvertedFilter(UpdateFilter): f: The filter to invert. """ + def __init__(self, f: BaseFilter): self.f = f @@ -194,22 +202,22 @@ class MergedFilter(UpdateFilter): or_filter: Optional filter to "or" with base_filter. Mutually exclusive with and_filter. """ - def __init__(self, - base_filter: BaseFilter, - and_filter: BaseFilter = None, - or_filter: BaseFilter = None): + + def __init__( + self, base_filter: BaseFilter, and_filter: BaseFilter = None, or_filter: BaseFilter = None + ): self.base_filter = base_filter if self.base_filter.data_filter: self.data_filter = True self.and_filter = and_filter - if (self.and_filter - and not isinstance(self.and_filter, bool) - and self.and_filter.data_filter): + if ( + self.and_filter + and not isinstance(self.and_filter, bool) + and self.and_filter.data_filter + ): self.data_filter = True self.or_filter = or_filter - if (self.or_filter - and not isinstance(self.and_filter, bool) - and self.or_filter.data_filter): + if self.or_filter and not isinstance(self.and_filter, bool) and self.or_filter.data_filter: self.data_filter = True def _merge(self, base_output: Union[bool, Dict], comp_output: Union[bool, Dict]) -> Dict: @@ -257,18 +265,17 @@ class MergedFilter(UpdateFilter): return False def __repr__(self) -> str: - return "<{} {} {}>".format(self.base_filter, "and" if self.and_filter else "or", - self.and_filter or self.or_filter) + return "<{} {} {}>".format( + self.base_filter, "and" if self.and_filter else "or", self.and_filter or self.or_filter + ) class _DiceEmoji(MessageFilter): - def __init__(self, emoji: str = None, name: str = None): self.name = 'Filters.dice.{}'.format(name) if name else 'Filters.dice' self.emoji = emoji class _DiceValues(MessageFilter): - def __init__(self, values: Union[int, List[int]], name: str, emoji: str = None): self.values = [values] if isinstance(values, int) else values self.emoji = emoji @@ -281,8 +288,9 @@ class _DiceEmoji(MessageFilter): return True return False - def __call__(self, # type: ignore[override] - update: Union[Update, List[int]]) -> Union[bool, '_DiceValues']: + def __call__( # type: ignore[override] + self, update: Union[Update, List[int]] + ) -> Union[bool, '_DiceValues']: if isinstance(update, Update): return self.filter(update.effective_message) else: @@ -319,7 +327,6 @@ class Filters: name = 'Filters.text' class _TextStrings(MessageFilter): - def __init__(self, strings: List[str]): self.strings = strings self.name = 'Filters.text({})'.format(strings) @@ -329,8 +336,9 @@ class Filters: return message.text in self.strings return False - def __call__(self, # type: ignore[override] - update: Union[Update, List[str]]) -> Union[bool, '_TextStrings']: + def __call__( # type: ignore[override] + self, update: Union[Update, List[str]] + ) -> Union[bool, '_TextStrings']: if isinstance(update, Update): return self.filter(update.effective_message) else: @@ -371,7 +379,6 @@ class Filters: name = 'Filters.caption' class _CaptionStrings(MessageFilter): - def __init__(self, strings: List[str]): self.strings = strings self.name = 'Filters.caption({})'.format(strings) @@ -381,8 +388,9 @@ class Filters: return message.caption in self.strings return False - def __call__(self, # type: ignore[override] - update: Union[Update, List[str]]) -> Union[bool, '_CaptionStrings']: + def __call__( # type: ignore[override] + self, update: Union[Update, List[str]] + ) -> Union[bool, '_CaptionStrings']: if isinstance(update, Update): return self.filter(update.effective_message) else: @@ -407,26 +415,30 @@ class Filters: name = 'Filters.command' class _CommandOnlyStart(MessageFilter): - def __init__(self, only_start: bool): self.only_start = only_start self.name = 'Filters.command({})'.format(only_start) def filter(self, message: Message) -> bool: - return bool(message.entities - and any([e.type == MessageEntity.BOT_COMMAND - for e in message.entities])) + return bool( + message.entities + and any([e.type == MessageEntity.BOT_COMMAND for e in message.entities]) + ) - def __call__(self, # type: ignore[override] - update: Union[bool, Update]) -> Union[bool, '_CommandOnlyStart']: + def __call__( # type: ignore[override] + self, update: Union[bool, Update] + ) -> Union[bool, '_CommandOnlyStart']: if isinstance(update, Update): return self.filter(update.effective_message) else: return self._CommandOnlyStart(update) def filter(self, message: Message) -> bool: - return bool(message.entities and message.entities[0].type == MessageEntity.BOT_COMMAND - and message.entities[0].offset == 0) + return bool( + message.entities + and message.entities[0].type == MessageEntity.BOT_COMMAND + and message.entities[0].offset == 0 + ) command = _Command() """ @@ -485,8 +497,7 @@ class Filters: self.pattern: Pattern = pattern self.name = 'Filters.regex({})'.format(self.pattern) - def filter(self, - message: Message) -> Optional[Dict[str, List[Match]]]: + def filter(self, message: Message) -> Optional[Dict[str, List[Match]]]: """""" # remove method from docs if message.text: match = self.pattern.search(message.text) @@ -739,6 +750,7 @@ officedocument.wordprocessingml.document")``- ``Filters.status_update`` for all status update messages. """ + class _NewChatMembers(MessageFilter): name = 'Filters.status_update.new_chat_members' @@ -788,8 +800,11 @@ officedocument.wordprocessingml.document")``- name = 'Filters.status_update.chat_created' def filter(self, message: Message) -> bool: - return bool(message.group_chat_created or message.supergroup_chat_created - or message.channel_chat_created) + return bool( + message.group_chat_created + or message.supergroup_chat_created + or message.channel_chat_created + ) chat_created = _ChatCreated() """Messages that contain :attr:`telegram.Message.group_chat_created`, @@ -827,11 +842,17 @@ officedocument.wordprocessingml.document")``- name = 'Filters.status_update' def filter(self, message: Update) -> bool: - return bool(self.new_chat_members(message) or self.left_chat_member(message) - or self.new_chat_title(message) or self.new_chat_photo(message) - or self.delete_chat_photo(message) or self.chat_created(message) - or self.migrate(message) or self.pinned_message(message) - or self.connected_website(message)) + return bool( + self.new_chat_members(message) + or self.left_chat_member(message) + or self.new_chat_title(message) + or self.new_chat_photo(message) + or self.delete_chat_photo(message) + or self.chat_created(message) + or self.migrate(message) + or self.pinned_message(message) + or self.connected_website(message) + ) status_update = _StatusUpdate() """Subset for messages containing a status update. @@ -976,10 +997,13 @@ officedocument.wordprocessingml.document")``- RuntimeError: If user_id and username are both present. """ - def __init__(self, - user_id: Union[int, List[int]] = None, - username: Union[str, List[str]] = None, - allow_empty: bool = False): + + def __init__( + self, + user_id: Union[int, List[int]] = None, + username: Union[str, List[str]] = None, + allow_empty: bool = False, + ): self.allow_empty = allow_empty self.__lock = Lock() @@ -1008,15 +1032,17 @@ officedocument.wordprocessingml.document")``- def _set_user_ids(self, user_id: Union[int, List[int]]) -> None: with self.__lock: if user_id and self._usernames: - raise RuntimeError("Can't set user_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set user_id in conjunction with (already set) " "usernames." + ) self._user_ids = self._parse_user_id(user_id) def _set_usernames(self, username: Union[str, List[str]]) -> None: with self.__lock: if username and self._user_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "user_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "user_ids." + ) self._usernames = self._parse_username(username) @property @@ -1047,8 +1073,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._user_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "user_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "user_ids." + ) parsed_username = self._parse_username(username) self._usernames |= parsed_username @@ -1063,8 +1090,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._usernames: - raise RuntimeError("Can't set user_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set user_id in conjunction with (already set) " "usernames." + ) parsed_user_id = self._parse_user_id(user_id) @@ -1080,8 +1108,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._user_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "user_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "user_ids." + ) parsed_username = self._parse_username(username) self._usernames -= parsed_username @@ -1096,8 +1125,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._usernames: - raise RuntimeError("Can't set user_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set user_id in conjunction with (already set) " "usernames." + ) parsed_user_id = self._parse_user_id(user_id) self._user_ids -= parsed_user_id @@ -1107,8 +1137,9 @@ officedocument.wordprocessingml.document")``- if self.user_ids: return message.from_user.id in self.user_ids if self.usernames: - return bool(message.from_user.username - and message.from_user.username in self.usernames) + return bool( + message.from_user.username and message.from_user.username in self.usernames + ) return self.allow_empty return False @@ -1145,10 +1176,13 @@ officedocument.wordprocessingml.document")``- Raises: RuntimeError: If bot_id and username are both present. """ - def __init__(self, - bot_id: Union[int, List[int]] = None, - username: Union[str, List[str]] = None, - allow_empty: bool = False): + + def __init__( + self, + bot_id: Union[int, List[int]] = None, + username: Union[str, List[str]] = None, + allow_empty: bool = False, + ): self.allow_empty = allow_empty self.__lock = Lock() @@ -1177,15 +1211,17 @@ officedocument.wordprocessingml.document")``- def _set_bot_ids(self, bot_id: Union[int, List[int]]) -> None: with self.__lock: if bot_id and self._usernames: - raise RuntimeError("Can't set bot_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set bot_id in conjunction with (already set) " "usernames." + ) self._bot_ids = self._parse_bot_id(bot_id) def _set_usernames(self, username: Union[str, List[str]]) -> None: with self.__lock: if username and self._bot_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "bot_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "bot_ids." + ) self._usernames = self._parse_username(username) @property @@ -1216,8 +1252,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._bot_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "bot_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "bot_ids." + ) parsed_username = self._parse_username(username) self._usernames |= parsed_username @@ -1233,8 +1270,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._usernames: - raise RuntimeError("Can't set bot_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set bot_id in conjunction with (already set) " "usernames." + ) parsed_bot_id = self._parse_bot_id(bot_id) @@ -1250,8 +1288,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._bot_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "bot_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "bot_ids." + ) parsed_username = self._parse_username(username) self._usernames -= parsed_username @@ -1266,8 +1305,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._usernames: - raise RuntimeError("Can't set bot_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set bot_id in conjunction with (already set) " "usernames." + ) parsed_bot_id = self._parse_bot_id(bot_id) self._bot_ids -= parsed_bot_id @@ -1277,8 +1317,9 @@ officedocument.wordprocessingml.document")``- if self.bot_ids: return message.via_bot.id in self.bot_ids if self.usernames: - return bool(message.via_bot.username - and message.via_bot.username in self.usernames) + return bool( + message.via_bot.username and message.via_bot.username in self.usernames + ) return self.allow_empty return False @@ -1316,10 +1357,12 @@ officedocument.wordprocessingml.document")``- """ - def __init__(self, - chat_id: Union[int, List[int]] = None, - username: Union[str, List[str]] = None, - allow_empty: bool = False): + def __init__( + self, + chat_id: Union[int, List[int]] = None, + username: Union[str, List[str]] = None, + allow_empty: bool = False, + ): self.allow_empty = allow_empty self.__lock = Lock() @@ -1348,15 +1391,17 @@ officedocument.wordprocessingml.document")``- def _set_chat_ids(self, chat_id: Union[int, List[int]]) -> None: with self.__lock: if chat_id and self._usernames: - raise RuntimeError("Can't set chat_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set chat_id in conjunction with (already set) " "usernames." + ) self._chat_ids = self._parse_chat_id(chat_id) def _set_usernames(self, username: Union[str, List[str]]) -> None: with self.__lock: if username and self._chat_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "chat_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "chat_ids." + ) self._usernames = self._parse_username(username) @property @@ -1387,8 +1432,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._chat_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "chat_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "chat_ids." + ) parsed_username = self._parse_username(username) self._usernames |= parsed_username @@ -1403,8 +1449,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._usernames: - raise RuntimeError("Can't set chat_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set chat_id in conjunction with (already set) " "usernames." + ) parsed_chat_id = self._parse_chat_id(chat_id) @@ -1420,8 +1467,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._chat_ids: - raise RuntimeError("Can't set username in conjunction with (already set) " - "chat_ids.") + raise RuntimeError( + "Can't set username in conjunction with (already set) " "chat_ids." + ) parsed_username = self._parse_username(username) self._usernames -= parsed_username @@ -1436,8 +1484,9 @@ officedocument.wordprocessingml.document")``- """ with self.__lock: if self._usernames: - raise RuntimeError("Can't set chat_id in conjunction with (already set) " - "usernames.") + raise RuntimeError( + "Can't set chat_id in conjunction with (already set) " "usernames." + ) parsed_chat_id = self._parse_chat_id(chat_id) self._chat_ids -= parsed_chat_id @@ -1447,8 +1496,7 @@ officedocument.wordprocessingml.document")``- if self.chat_ids: return message.chat.id in self.chat_ids if self.usernames: - return bool(message.chat.username - and message.chat.username in self.usernames) + return bool(message.chat.username and message.chat.username in self.usernames) return self.allow_empty return False @@ -1550,8 +1598,10 @@ officedocument.wordprocessingml.document")``- def filter(self, message: Message) -> bool: """""" # remove method from docs - return bool(message.from_user.language_code and any( - [message.from_user.language_code.startswith(x) for x in self.lang])) + return bool( + message.from_user.language_code + and any([message.from_user.language_code.startswith(x) for x in self.lang]) + ) class _UpdateType(UpdateFilter): name = 'Filters.update' diff --git a/telegram/ext/handler.py b/telegram/ext/handler.py index 7fd2bb589..25499ecfc 100644 --- a/telegram/ext/handler.py +++ b/telegram/ext/handler.py @@ -24,6 +24,7 @@ from telegram.utils.promise import Promise from telegram.utils.types import HandlerArg from telegram import Update from typing import Callable, TYPE_CHECKING, Any, Optional, Union, TypeVar, Dict + if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -87,13 +88,16 @@ class Handler(ABC): Defaults to :obj:`False`. """ - def __init__(self, - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - run_async: bool = False): + + def __init__( + self, + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + pass_update_queue: bool = False, + pass_job_queue: bool = False, + pass_user_data: bool = False, + pass_chat_data: bool = False, + run_async: bool = False, + ): self.callback: Callable[[HandlerArg, 'CallbackContext'], RT] = callback self.pass_update_queue = pass_update_queue self.pass_job_queue = pass_job_queue @@ -117,11 +121,13 @@ class Handler(ABC): """ - def handle_update(self, - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: object, - context: 'CallbackContext' = None) -> Union[RT, Promise]: + def handle_update( + self, + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: object, + context: 'CallbackContext' = None, + ) -> Union[RT, Promise]: """ This method is called if it was determined that an update should indeed be handled by this instance. Calls :attr:`callback` along with its respectful @@ -146,16 +152,19 @@ class Handler(ABC): else: optional_args = self.collect_optional_args(dispatcher, update, check_result) if self.run_async: - return dispatcher.run_async(self.callback, dispatcher.bot, update, update=update, - **optional_args) + return dispatcher.run_async( + self.callback, dispatcher.bot, update, update=update, **optional_args + ) else: return self.callback(dispatcher.bot, update, **optional_args) # type: ignore - def collect_additional_context(self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Any) -> None: + def collect_additional_context( + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Any, + ) -> None: """Prepares additional arguments for the context. Override if needed. Args: @@ -167,10 +176,9 @@ class Handler(ABC): """ pass - def collect_optional_args(self, - dispatcher: 'Dispatcher', - update: HandlerArg = None, - check_result: Any = None) -> Dict[str, Any]: + def collect_optional_args( + self, dispatcher: 'Dispatcher', update: HandlerArg = None, check_result: Any = None + ) -> Dict[str, Any]: """ Prepares the optional arguments. If the handler has additional optional args, it should subclass this method, but remember to call this super method. @@ -193,10 +201,12 @@ class Handler(ABC): if self.pass_user_data and isinstance(update, Update): user = update.effective_user optional_args['user_data'] = dispatcher.user_data[ - user.id if user else None] # type: ignore[index] + user.id if user else None # type: ignore[index] + ] if self.pass_chat_data and isinstance(update, Update): chat = update.effective_chat optional_args['chat_data'] = dispatcher.chat_data[ - chat.id if chat else None] # type: ignore[index] + chat.id if chat else None # type: ignore[index] + ] return optional_args diff --git a/telegram/ext/inlinequeryhandler.py b/telegram/ext/inlinequeryhandler.py index 2a49addf2..cd8be1ba8 100644 --- a/telegram/ext/inlinequeryhandler.py +++ b/telegram/ext/inlinequeryhandler.py @@ -24,8 +24,18 @@ from telegram import Update from .handler import Handler from telegram.utils.types import HandlerArg -from typing import Callable, TYPE_CHECKING, Any, Optional, Union, TypeVar, Dict, Pattern, Match, \ - cast +from typing import ( + Callable, + TYPE_CHECKING, + Any, + Optional, + Union, + TypeVar, + Dict, + Pattern, + Match, + cast, +) if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -110,23 +120,26 @@ class InlineQueryHandler(Handler): """ - def __init__(self, - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pattern: Union[str, Pattern] = None, - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - run_async: bool = False): + def __init__( + self, + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + pass_update_queue: bool = False, + pass_job_queue: bool = False, + pattern: Union[str, Pattern] = None, + pass_groups: bool = False, + pass_groupdict: bool = False, + pass_user_data: bool = False, + pass_chat_data: bool = False, + run_async: bool = False, + ): super().__init__( callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue, pass_user_data=pass_user_data, pass_chat_data=pass_chat_data, - run_async=run_async) + run_async=run_async, + ) if isinstance(pattern, str): pattern = re.compile(pattern) @@ -157,10 +170,12 @@ class InlineQueryHandler(Handler): return True return None - def collect_optional_args(self, - dispatcher: 'Dispatcher', - update: HandlerArg = None, - check_result: Optional[Union[bool, Match]] = None) -> Dict[str, Any]: + def collect_optional_args( + self, + dispatcher: 'Dispatcher', + update: HandlerArg = None, + check_result: Optional[Union[bool, Match]] = None, + ) -> Dict[str, Any]: optional_args = super().collect_optional_args(dispatcher, update, check_result) if self.pattern: check_result = cast(Match, check_result) @@ -170,11 +185,13 @@ class InlineQueryHandler(Handler): optional_args['groupdict'] = check_result.groupdict() return optional_args - def collect_additional_context(self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Optional[Union[bool, Match]]) -> None: + def collect_additional_context( + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Optional[Union[bool, Match]], + ) -> None: if self.pattern: check_result = cast(Match, check_result) context.matches = [check_result] diff --git a/telegram/ext/jobqueue.py b/telegram/ext/jobqueue.py index 908917711..224c286ed 100644 --- a/telegram/ext/jobqueue.py +++ b/telegram/ext/jobqueue.py @@ -31,6 +31,7 @@ from telegram.ext.callbackcontext import CallbackContext from typing import TYPE_CHECKING, Union, Callable, Tuple, Optional, List, Any, cast, overload from telegram.utils.types import JSONDict + if TYPE_CHECKING: from telegram.ext import Dispatcher from telegram import Bot @@ -56,8 +57,9 @@ class JobQueue: self._dispatcher: 'Dispatcher' = None # type: ignore[assignment] self.logger = logging.getLogger(self.__class__.__name__) self.scheduler = BackgroundScheduler(timezone=pytz.utc) - self.scheduler.add_listener(self._update_persistence, - mask=EVENT_JOB_EXECUTED | EVENT_JOB_ERROR) + self.scheduler.add_listener( + self._update_persistence, mask=EVENT_JOB_EXECUTED | EVENT_JOB_ERROR + ) # Dispatch errors and don't log them in the APS logger def aps_log_filter(record): # type: ignore @@ -82,25 +84,29 @@ class JobQueue: self._dispatcher.dispatch_error(None, event.exception) # Errors should not stop the thread. except Exception: - self.logger.exception('An error was raised while processing the job and an ' - 'uncaught error was raised while handling the error ' - 'with an error_handler.') + self.logger.exception( + 'An error was raised while processing the job and an ' + 'uncaught error was raised while handling the error ' + 'with an error_handler.' + ) @overload def _parse_time_input(self, time: None, shift_day: bool = False) -> None: ... @overload - def _parse_time_input(self, - time: Union[float, int, datetime.timedelta, datetime.datetime, - datetime.time], - shift_day: bool = False) -> datetime.datetime: + def _parse_time_input( + self, + time: Union[float, int, datetime.timedelta, datetime.datetime, datetime.time], + shift_day: bool = False, + ) -> datetime.datetime: ... - def _parse_time_input(self, - time: Union[float, int, datetime.timedelta, datetime.datetime, - datetime.time, None], - shift_day: bool = False) -> Optional[datetime.datetime]: + def _parse_time_input( + self, + time: Union[float, int, datetime.timedelta, datetime.datetime, datetime.time, None], + shift_day: bool = False, + ) -> Optional[datetime.datetime]: if time is None: return None if isinstance(time, (int, float)): @@ -109,7 +115,8 @@ class JobQueue: return self._tz_now() + time if isinstance(time, datetime.time): dt = datetime.datetime.combine( - datetime.datetime.now(tz=time.tzinfo or self.scheduler.timezone).date(), time) + datetime.datetime.now(tz=time.tzinfo or self.scheduler.timezone).date(), time + ) if dt.tzinfo is None: dt = self.scheduler.timezone.localize(dt) if shift_day and dt <= datetime.datetime.now(pytz.utc): @@ -131,12 +138,14 @@ class JobQueue: if dispatcher.bot.defaults: self.scheduler.configure(timezone=dispatcher.bot.defaults.tzinfo or pytz.utc) - def run_once(self, - callback: Callable[['CallbackContext'], None], - when: Union[float, datetime.timedelta, datetime.datetime, datetime.time], - context: object = None, - name: str = None, - job_kwargs: JSONDict = None) -> 'Job': + def run_once( + self, + callback: Callable[['CallbackContext'], None], + when: Union[float, datetime.timedelta, datetime.datetime, datetime.time], + context: object = None, + name: str = None, + job_kwargs: JSONDict = None, + ) -> 'Job': """Creates a new ``Job`` that runs once and adds it to the queue. Args: @@ -183,27 +192,29 @@ class JobQueue: job = Job(callback, context, name, self) dt = self._parse_time_input(when, shift_day=True) - j = self.scheduler.add_job(callback, - name=name, - trigger='date', - run_date=dt, - args=self._build_args(job), - timezone=dt.tzinfo or self.scheduler.timezone, - **job_kwargs) + j = self.scheduler.add_job( + callback, + name=name, + trigger='date', + run_date=dt, + args=self._build_args(job), + timezone=dt.tzinfo or self.scheduler.timezone, + **job_kwargs, + ) job.job = j return job - def run_repeating(self, - callback: Callable[['CallbackContext'], None], - interval: Union[float, datetime.timedelta], - first: Union[float, datetime.timedelta, datetime.datetime, - datetime.time] = None, - last: Union[float, datetime.timedelta, datetime.datetime, - datetime.time] = None, - context: object = None, - name: str = None, - job_kwargs: JSONDict = None) -> 'Job': + def run_repeating( + self, + callback: Callable[['CallbackContext'], None], + interval: Union[float, datetime.timedelta], + first: Union[float, datetime.timedelta, datetime.datetime, datetime.time] = None, + last: Union[float, datetime.timedelta, datetime.datetime, datetime.time] = None, + context: object = None, + name: str = None, + job_kwargs: JSONDict = None, + ) -> 'Job': """Creates a new ``Job`` that runs at specified intervals and adds it to the queue. Args: @@ -277,26 +288,30 @@ class JobQueue: if isinstance(interval, datetime.timedelta): interval = interval.total_seconds() - j = self.scheduler.add_job(callback, - trigger='interval', - args=self._build_args(job), - start_date=dt_first, - end_date=dt_last, - seconds=interval, - name=name, - **job_kwargs) + j = self.scheduler.add_job( + callback, + trigger='interval', + args=self._build_args(job), + start_date=dt_first, + end_date=dt_last, + seconds=interval, + name=name, + **job_kwargs, + ) job.job = j return job - def run_monthly(self, - callback: Callable[['CallbackContext'], None], - when: datetime.time, - day: int, - context: object = None, - name: str = None, - day_is_strict: bool = True, - job_kwargs: JSONDict = None) -> 'Job': + def run_monthly( + self, + callback: Callable[['CallbackContext'], None], + when: datetime.time, + day: int, + context: object = None, + name: str = None, + day_is_strict: bool = True, + job_kwargs: JSONDict = None, + ) -> 'Job': """Creates a new ``Job`` that runs on a monthly basis and adds it to the queue. Args: @@ -332,45 +347,55 @@ class JobQueue: job = Job(callback, context, name, self) if day_is_strict: - j = self.scheduler.add_job(callback, - trigger='cron', - args=self._build_args(job), - name=name, - day=day, - hour=when.hour, - minute=when.minute, - second=when.second, - timezone=when.tzinfo or self.scheduler.timezone, - **job_kwargs) + j = self.scheduler.add_job( + callback, + trigger='cron', + args=self._build_args(job), + name=name, + day=day, + hour=when.hour, + minute=when.minute, + second=when.second, + timezone=when.tzinfo or self.scheduler.timezone, + **job_kwargs, + ) else: - trigger = OrTrigger([CronTrigger(day=day, - hour=when.hour, - minute=when.minute, - second=when.second, - timezone=when.tzinfo, - **job_kwargs), - CronTrigger(day='last', - hour=when.hour, - minute=when.minute, - second=when.second, - timezone=when.tzinfo or self.scheduler.timezone, - **job_kwargs)]) - j = self.scheduler.add_job(callback, - trigger=trigger, - args=self._build_args(job), - name=name, - **job_kwargs) + trigger = OrTrigger( + [ + CronTrigger( + day=day, + hour=when.hour, + minute=when.minute, + second=when.second, + timezone=when.tzinfo, + **job_kwargs, + ), + CronTrigger( + day='last', + hour=when.hour, + minute=when.minute, + second=when.second, + timezone=when.tzinfo or self.scheduler.timezone, + **job_kwargs, + ), + ] + ) + j = self.scheduler.add_job( + callback, trigger=trigger, args=self._build_args(job), name=name, **job_kwargs + ) job.job = j return job - def run_daily(self, - callback: Callable[['CallbackContext'], None], - time: datetime.time, - days: Tuple[int, ...] = Days.EVERY_DAY, - context: object = None, - name: str = None, - job_kwargs: JSONDict = None) -> 'Job': + def run_daily( + self, + callback: Callable[['CallbackContext'], None], + time: datetime.time, + days: Tuple[int, ...] = Days.EVERY_DAY, + context: object = None, + name: str = None, + job_kwargs: JSONDict = None, + ) -> 'Job': """Creates a new ``Job`` that runs on a daily basis and adds it to the queue. Args: @@ -409,25 +434,29 @@ class JobQueue: name = name or callback.__name__ job = Job(callback, context, name, self) - j = self.scheduler.add_job(callback, - name=name, - args=self._build_args(job), - trigger='cron', - day_of_week=','.join([str(d) for d in days]), - hour=time.hour, - minute=time.minute, - second=time.second, - timezone=time.tzinfo or self.scheduler.timezone, - **job_kwargs) + j = self.scheduler.add_job( + callback, + name=name, + args=self._build_args(job), + trigger='cron', + day_of_week=','.join([str(d) for d in days]), + hour=time.hour, + minute=time.minute, + second=time.second, + timezone=time.tzinfo or self.scheduler.timezone, + **job_kwargs, + ) job.job = j return job - def run_custom(self, - callback: Callable[['CallbackContext'], None], - job_kwargs: JSONDict, - context: object = None, - name: str = None) -> 'Job': + def run_custom( + self, + callback: Callable[['CallbackContext'], None], + job_kwargs: JSONDict, + context: object = None, + name: str = None, + ) -> 'Job': """Creates a new customly defined ``Job``. Args: @@ -453,10 +482,7 @@ class JobQueue: name = name or callback.__name__ job = Job(callback, context, name, self) - j = self.scheduler.add_job(callback, - args=self._build_args(job), - name=name, - **job_kwargs) + j = self.scheduler.add_job(callback, args=self._build_args(job), name=name, **job_kwargs) job.job = j return job @@ -516,12 +542,14 @@ class Job: job (:class:`apscheduler.job.Job`, optional): The APS Job this job is a wrapper for. """ - def __init__(self, - callback: Callable[['CallbackContext'], None], - context: object = None, - name: str = None, - job_queue: JobQueue = None, - job: 'Job' = None): + def __init__( + self, + callback: Callable[['CallbackContext'], None], + context: object = None, + name: str = None, + job_queue: JobQueue = None, + job: 'Job' = None, + ): self.callback = callback self.context = context @@ -545,9 +573,11 @@ class Job: dispatcher.dispatch_error(None, e) # Errors should not stop the thread. except Exception: - dispatcher.logger.exception('An error was raised while processing the job and an ' - 'uncaught error was raised while handling the error ' - 'with an error_handler.') + dispatcher.logger.exception( + 'An error was raised while processing the job and an ' + 'uncaught error was raised while handling the error ' + 'with an error_handler.' + ) def schedule_removal(self) -> None: """ diff --git a/telegram/ext/messagehandler.py b/telegram/ext/messagehandler.py index e89daa237..5592eb5e7 100644 --- a/telegram/ext/messagehandler.py +++ b/telegram/ext/messagehandler.py @@ -28,6 +28,7 @@ from .handler import Handler from telegram.utils.types import HandlerArg from typing import Callable, TYPE_CHECKING, Any, Optional, Union, TypeVar, Dict + if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -120,17 +121,19 @@ class MessageHandler(Handler): """ - def __init__(self, - filters: BaseFilter, - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - message_updates: bool = None, - channel_post_updates: bool = None, - edited_updates: bool = None, - run_async: bool = False): + def __init__( + self, + filters: BaseFilter, + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + pass_update_queue: bool = False, + pass_job_queue: bool = False, + pass_user_data: bool = False, + pass_chat_data: bool = False, + message_updates: bool = None, + channel_post_updates: bool = None, + edited_updates: bool = None, + run_async: bool = False, + ): super().__init__( callback, @@ -138,36 +141,44 @@ class MessageHandler(Handler): pass_job_queue=pass_job_queue, pass_user_data=pass_user_data, pass_chat_data=pass_chat_data, - run_async=run_async) + run_async=run_async, + ) if message_updates is False and channel_post_updates is False and edited_updates is False: raise ValueError( - 'message_updates, channel_post_updates and edited_updates are all False') + 'message_updates, channel_post_updates and edited_updates are all False' + ) if filters is not None: self.filters = Filters.update & filters else: self.filters = Filters.update if message_updates is not None: - warnings.warn('message_updates is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2) + warnings.warn( + 'message_updates is deprecated. See https://git.io/fxJuV for more info', + TelegramDeprecationWarning, + stacklevel=2, + ) if message_updates is False: self.filters &= ~Filters.update.message if channel_post_updates is not None: - warnings.warn('channel_post_updates is deprecated. See https://git.io/fxJuV ' - 'for more info', - TelegramDeprecationWarning, - stacklevel=2) + warnings.warn( + 'channel_post_updates is deprecated. See https://git.io/fxJuV ' 'for more info', + TelegramDeprecationWarning, + stacklevel=2, + ) if channel_post_updates is False: self.filters &= ~Filters.update.channel_post if edited_updates is not None: - warnings.warn('edited_updates is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2) + warnings.warn( + 'edited_updates is deprecated. See https://git.io/fxJuV for more info', + TelegramDeprecationWarning, + stacklevel=2, + ) if edited_updates is False: - self.filters &= ~(Filters.update.edited_message - | Filters.update.edited_channel_post) + self.filters &= ~( + Filters.update.edited_message | Filters.update.edited_channel_post + ) def check_update(self, update: HandlerArg) -> Optional[Union[bool, Dict[str, Any]]]: """Determines whether an update should be passed to this handlers :attr:`callback`. @@ -183,10 +194,12 @@ class MessageHandler(Handler): return self.filters(update) return None - def collect_additional_context(self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Optional[Union[bool, Dict[str, Any]]]) -> None: + def collect_additional_context( + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Optional[Union[bool, Dict[str, Any]]], + ) -> None: if isinstance(check_result, dict): context.update(check_result) diff --git a/telegram/ext/messagequeue.py b/telegram/ext/messagequeue.py index 6274bab23..5335eeec5 100644 --- a/telegram/ext/messagequeue.py +++ b/telegram/ext/messagequeue.py @@ -38,6 +38,7 @@ curtime = time.perf_counter class DelayQueueError(RuntimeError): """Indicates processing errors.""" + pass @@ -75,17 +76,19 @@ class DelayQueue(threading.Thread): _instcnt = 0 # instance counter - def __init__(self, - queue: q.Queue = None, - burst_limit: int = 30, - time_limit_ms: int = 1000, - exc_route: Callable[[Exception], None] = None, - autostart: bool = True, - name: str = None): + def __init__( + self, + queue: q.Queue = None, + burst_limit: int = 30, + time_limit_ms: int = 1000, + exc_route: Callable[[Exception], None] = None, + autostart: bool = True, + name: str = None, + ): self._queue = queue if queue is not None else q.Queue() self.burst_limit = burst_limit self.time_limit = time_limit_ms / 1000 - self.exc_route = (exc_route if exc_route is not None else self._default_exception_handler) + self.exc_route = exc_route if exc_route is not None else self._default_exception_handler self.__exit_req = False # flag to gently exit thread self.__class__._instcnt += 1 if name is None: @@ -201,24 +204,28 @@ class MessageQueue: """ - def __init__(self, - all_burst_limit: int = 30, - all_time_limit_ms: int = 1000, - group_burst_limit: int = 20, - group_time_limit_ms: int = 60000, - exc_route: Callable[[Exception], None] = None, - autostart: bool = True): + def __init__( + self, + all_burst_limit: int = 30, + all_time_limit_ms: int = 1000, + group_burst_limit: int = 20, + group_time_limit_ms: int = 60000, + exc_route: Callable[[Exception], None] = None, + autostart: bool = True, + ): # create according delay queues, use composition self._all_delayq = DelayQueue( burst_limit=all_burst_limit, time_limit_ms=all_time_limit_ms, exc_route=exc_route, - autostart=autostart) + autostart=autostart, + ) self._group_delayq = DelayQueue( burst_limit=group_burst_limit, time_limit_ms=group_time_limit_ms, exc_route=exc_route, - autostart=autostart) + autostart=autostart, + ) def start(self) -> None: """Method is used to manually start the ``MessageQueue`` processing.""" @@ -297,11 +304,12 @@ def queuedmessage(method: Callable) -> Callable: @functools.wraps(method) def wrapped(self: 'Bot', *args: Any, **kwargs: Any) -> Any: - queued = kwargs.pop('queued', - self._is_messages_queued_default) # type: ignore[attr-defined] + queued = kwargs.pop( + 'queued', self._is_messages_queued_default # type: ignore[attr-defined] + ) isgroup = kwargs.pop('isgroup', False) if queued: - prom = promise.Promise(method, (self, ) + args, kwargs) + prom = promise.Promise(method, (self,) + args, kwargs) return self._msg_queue(prom, isgroup) # type: ignore[attr-defined] return method(self, *args, **kwargs) diff --git a/telegram/ext/picklepersistence.py b/telegram/ext/picklepersistence.py index 1e93fb142..f4c63082a 100644 --- a/telegram/ext/picklepersistence.py +++ b/telegram/ext/picklepersistence.py @@ -74,16 +74,20 @@ class PicklePersistence(BasePersistence): Default is :obj:`False`. """ - def __init__(self, - filename: str, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True, - single_file: bool = True, - on_flush: bool = False): - super().__init__(store_user_data=store_user_data, - store_chat_data=store_chat_data, - store_bot_data=store_bot_data) + def __init__( + self, + filename: str, + store_user_data: bool = True, + store_chat_data: bool = True, + store_bot_data: bool = True, + single_file: bool = True, + on_flush: bool = False, + ): + super().__init__( + store_user_data=store_user_data, + store_chat_data=store_chat_data, + store_bot_data=store_bot_data, + ) self.filename = filename self.single_file = single_file self.on_flush = on_flush @@ -125,8 +129,12 @@ class PicklePersistence(BasePersistence): def dump_singlefile(self) -> None: with open(self.filename, "wb") as f: - data = {'conversations': self.conversations, 'user_data': self.user_data, - 'chat_data': self.chat_data, 'bot_data': self.bot_data} + data = { + 'conversations': self.conversations, + 'user_data': self.user_data, + 'chat_data': self.chat_data, + 'bot_data': self.bot_data, + } pickle.dump(data, f) def dump_file(self, filename: str, data: Any) -> None: @@ -212,9 +220,9 @@ class PicklePersistence(BasePersistence): self.load_singlefile() return self.conversations.get(name, {}).copy() # type: ignore[union-attr] - def update_conversation(self, - name: str, key: Tuple[int, ...], - new_state: Optional[object]) -> None: + def update_conversation( + self, name: str, key: Tuple[int, ...], new_state: Optional[object] + ) -> None: """Will update the conversations for the given handler and depending on :attr:`on_flush` save the pickle file. @@ -290,8 +298,7 @@ class PicklePersistence(BasePersistence): self.dump_singlefile() def flush(self) -> None: - """ Will save all data in memory to pickle file(s). - """ + """Will save all data in memory to pickle file(s).""" if self.single_file: if self.user_data or self.chat_data or self.bot_data or self.conversations: self.dump_singlefile() diff --git a/telegram/ext/regexhandler.py b/telegram/ext/regexhandler.py index f39d76564..343b52133 100644 --- a/telegram/ext/regexhandler.py +++ b/telegram/ext/regexhandler.py @@ -27,6 +27,7 @@ from telegram.ext import MessageHandler, Filters from telegram.utils.types import HandlerArg from typing import Callable, TYPE_CHECKING, Any, Optional, Union, TypeVar, Dict, Pattern + if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -108,41 +109,48 @@ class RegexHandler(MessageHandler): """ - def __init__(self, - pattern: Union[str, Pattern], - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - allow_edited: bool = False, - message_updates: bool = True, - channel_post_updates: bool = False, - edited_updates: bool = False, - run_async: bool = False): - warnings.warn('RegexHandler is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2) - super().__init__(Filters.regex(pattern), - callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, - message_updates=message_updates, - channel_post_updates=channel_post_updates, - edited_updates=edited_updates, - run_async=run_async) + def __init__( + self, + pattern: Union[str, Pattern], + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + pass_groups: bool = False, + pass_groupdict: bool = False, + pass_update_queue: bool = False, + pass_job_queue: bool = False, + pass_user_data: bool = False, + pass_chat_data: bool = False, + allow_edited: bool = False, + message_updates: bool = True, + channel_post_updates: bool = False, + edited_updates: bool = False, + run_async: bool = False, + ): + warnings.warn( + 'RegexHandler is deprecated. See https://git.io/fxJuV for more info', + TelegramDeprecationWarning, + stacklevel=2, + ) + super().__init__( + Filters.regex(pattern), + callback, + pass_update_queue=pass_update_queue, + pass_job_queue=pass_job_queue, + pass_user_data=pass_user_data, + pass_chat_data=pass_chat_data, + message_updates=message_updates, + channel_post_updates=channel_post_updates, + edited_updates=edited_updates, + run_async=run_async, + ) self.pass_groups = pass_groups self.pass_groupdict = pass_groupdict def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: HandlerArg = None, - check_result: Optional[Union[bool, Dict[str, Any]]] = None) -> Dict[str, Any]: + self, + dispatcher: 'Dispatcher', + update: HandlerArg = None, + check_result: Optional[Union[bool, Dict[str, Any]]] = None, + ) -> Dict[str, Any]: optional_args = super().collect_optional_args(dispatcher, update, check_result) if isinstance(check_result, dict): if self.pass_groups: diff --git a/telegram/ext/stringcommandhandler.py b/telegram/ext/stringcommandhandler.py index 4050f16cf..bf84d979b 100644 --- a/telegram/ext/stringcommandhandler.py +++ b/telegram/ext/stringcommandhandler.py @@ -22,6 +22,7 @@ from .handler import Handler from telegram.utils.types import HandlerArg from typing import Callable, TYPE_CHECKING, Any, Optional, TypeVar, Dict, List + if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -80,18 +81,21 @@ class StringCommandHandler(Handler): """ - def __init__(self, - command: str, - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - pass_args: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - run_async: bool = False): + def __init__( + self, + command: str, + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + pass_args: bool = False, + pass_update_queue: bool = False, + pass_job_queue: bool = False, + run_async: bool = False, + ): super().__init__( callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue, - run_async=run_async) + run_async=run_async, + ) self.command = command self.pass_args = pass_args @@ -111,18 +115,22 @@ class StringCommandHandler(Handler): return args[1:] return None - def collect_optional_args(self, - dispatcher: 'Dispatcher', - update: HandlerArg = None, - check_result: Optional[List[str]] = None) -> Dict[str, Any]: + def collect_optional_args( + self, + dispatcher: 'Dispatcher', + update: HandlerArg = None, + check_result: Optional[List[str]] = None, + ) -> Dict[str, Any]: optional_args = super().collect_optional_args(dispatcher, update, check_result) if self.pass_args: optional_args['args'] = check_result return optional_args - def collect_additional_context(self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Optional[List[str]]) -> None: + def collect_additional_context( + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Optional[List[str]], + ) -> None: context.args = check_result diff --git a/telegram/ext/stringregexhandler.py b/telegram/ext/stringregexhandler.py index 0a99015ab..f959dba77 100644 --- a/telegram/ext/stringregexhandler.py +++ b/telegram/ext/stringregexhandler.py @@ -24,6 +24,7 @@ from .handler import Handler from typing import Callable, TYPE_CHECKING, Optional, TypeVar, Match, Dict, Any, Union, Pattern from telegram.utils.types import HandlerArg + if TYPE_CHECKING: from telegram.ext import CallbackContext, Dispatcher @@ -90,19 +91,22 @@ class StringRegexHandler(Handler): """ - def __init__(self, - pattern: Union[str, Pattern], - callback: Callable[[HandlerArg, 'CallbackContext'], RT], - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - run_async: bool = False): + def __init__( + self, + pattern: Union[str, Pattern], + callback: Callable[[HandlerArg, 'CallbackContext'], RT], + pass_groups: bool = False, + pass_groupdict: bool = False, + pass_update_queue: bool = False, + pass_job_queue: bool = False, + run_async: bool = False, + ): super().__init__( callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue, - run_async=run_async) + run_async=run_async, + ) if isinstance(pattern, str): pattern = re.compile(pattern) @@ -127,10 +131,12 @@ class StringRegexHandler(Handler): return match return None - def collect_optional_args(self, - dispatcher: 'Dispatcher', - update: HandlerArg = None, - check_result: Optional[Match] = None) -> Dict[str, Any]: + def collect_optional_args( + self, + dispatcher: 'Dispatcher', + update: HandlerArg = None, + check_result: Optional[Match] = None, + ) -> Dict[str, Any]: optional_args = super().collect_optional_args(dispatcher, update, check_result) if self.pattern: if self.pass_groups and check_result: @@ -139,10 +145,12 @@ class StringRegexHandler(Handler): optional_args['groupdict'] = check_result.groupdict() return optional_args - def collect_additional_context(self, - context: 'CallbackContext', - update: HandlerArg, - dispatcher: 'Dispatcher', - check_result: Optional[Match]) -> None: + def collect_additional_context( + self, + context: 'CallbackContext', + update: HandlerArg, + dispatcher: 'Dispatcher', + check_result: Optional[Match], + ) -> None: if self.pattern and check_result: context.matches = [check_result] diff --git a/telegram/ext/typehandler.py b/telegram/ext/typehandler.py index 64c73b466..457eeae0d 100644 --- a/telegram/ext/typehandler.py +++ b/telegram/ext/typehandler.py @@ -74,18 +74,21 @@ class TypeHandler(Handler): """ - def __init__(self, - type: Type, - callback: Callable[[Any, 'CallbackContext'], RT], - strict: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - run_async: bool = False): + def __init__( + self, + type: Type, + callback: Callable[[Any, 'CallbackContext'], RT], + strict: bool = False, + pass_update_queue: bool = False, + pass_job_queue: bool = False, + run_async: bool = False, + ): super().__init__( callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue, - run_async=run_async) + run_async=run_async, + ) self.type = type self.strict = strict diff --git a/telegram/ext/updater.py b/telegram/ext/updater.py index 203695e31..5fd4d936c 100644 --- a/telegram/ext/updater.py +++ b/telegram/ext/updater.py @@ -32,7 +32,7 @@ from telegram.error import Unauthorized, InvalidToken, RetryAfter, TimedOut from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.utils.helpers import get_signal_name from telegram.utils.request import Request -from telegram.utils.webhookhandler import (WebhookServer, WebhookAppClass) +from telegram.utils.webhookhandler import WebhookServer, WebhookAppClass from typing import Callable, Dict, TYPE_CHECKING, Any, List, Union, Tuple, no_type_check, Optional @@ -108,26 +108,30 @@ class Updater: _request = None - def __init__(self, - token: str = None, - base_url: str = None, - workers: int = 4, - bot: Bot = None, - private_key: bytes = None, - private_key_password: bytes = None, - user_sig_handler: Callable = None, - request_kwargs: Dict[str, Any] = None, - persistence: 'BasePersistence' = None, - defaults: 'Defaults' = None, - use_context: bool = True, - dispatcher: Dispatcher = None, - base_file_url: str = None): + def __init__( + self, + token: str = None, + base_url: str = None, + workers: int = 4, + bot: Bot = None, + private_key: bytes = None, + private_key_password: bytes = None, + user_sig_handler: Callable = None, + request_kwargs: Dict[str, Any] = None, + persistence: 'BasePersistence' = None, + defaults: 'Defaults' = None, + use_context: bool = True, + dispatcher: Dispatcher = None, + base_file_url: str = None, + ): if defaults and bot: - warnings.warn('Passing defaults to an Updater has no effect when a Bot is passed ' - 'as well. Pass them to the Bot instead.', - TelegramDeprecationWarning, - stacklevel=2) + warnings.warn( + 'Passing defaults to an Updater has no effect when a Bot is passed ' + 'as well. Pass them to the Bot instead.', + TelegramDeprecationWarning, + stacklevel=2, + ) if dispatcher is None: if (token is None) and (bot is None): @@ -156,7 +160,8 @@ class Updater: if bot.request.con_pool_size < con_pool_size: self.logger.warning( 'Connection pool of Request object is smaller than optimal value (%s)', - con_pool_size) + con_pool_size, + ) else: # we need a connection pool the size of: # * for each of the workers @@ -169,24 +174,28 @@ class Updater: if 'con_pool_size' not in request_kwargs: request_kwargs['con_pool_size'] = con_pool_size self._request = Request(**request_kwargs) - self.bot = Bot(token, # type: ignore[arg-type] - base_url, - base_file_url=base_file_url, - request=self._request, - private_key=private_key, - private_key_password=private_key_password, - defaults=defaults) + self.bot = Bot( + token, # type: ignore[arg-type] + base_url, + base_file_url=base_file_url, + request=self._request, + private_key=private_key, + private_key_password=private_key_password, + defaults=defaults, + ) self.update_queue: Queue = Queue() self.job_queue = JobQueue() self.__exception_event = Event() self.persistence = persistence - self.dispatcher = Dispatcher(self.bot, - self.update_queue, - job_queue=self.job_queue, - workers=workers, - exception_event=self.__exception_event, - persistence=persistence, - use_context=use_context) + self.dispatcher = Dispatcher( + self.bot, + self.update_queue, + job_queue=self.job_queue, + workers=workers, + exception_event=self.__exception_event, + persistence=persistence, + use_context=use_context, + ) self.job_queue.set_dispatcher(self.dispatcher) else: con_pool_size = dispatcher.workers + 4 @@ -195,7 +204,8 @@ class Updater: if self.bot.request.con_pool_size < con_pool_size: self.logger.warning( 'Connection pool of Request object is smaller than optimal value (%s)', - con_pool_size) + con_pool_size, + ) self.update_queue = dispatcher.update_queue self.__exception_event = dispatcher.exception_event self.persistence = dispatcher.persistence @@ -211,10 +221,12 @@ class Updater: self.__threads: List[Thread] = [] def _init_thread(self, target: Callable, name: str, *args: Any, **kwargs: Any) -> None: - thr = Thread(target=self._thread_wrapper, - name="Bot:{}:{}".format(self.bot.id, name), - args=(target,) + args, - kwargs=kwargs) + thr = Thread( + target=self._thread_wrapper, + name="Bot:{}:{}".format(self.bot.id, name), + args=(target,) + args, + kwargs=kwargs, + ) thr.start() self.__threads.append(thr) @@ -229,13 +241,15 @@ class Updater: raise self.logger.debug('{} - ended'.format(thr_name)) - def start_polling(self, - poll_interval: float = 0.0, - timeout: float = 10, - clean: bool = False, - bootstrap_retries: int = -1, - read_latency: float = 2., - allowed_updates: List[str] = None) -> Optional[Queue]: + def start_polling( + self, + poll_interval: float = 0.0, + timeout: float = 10, + clean: bool = False, + bootstrap_retries: int = -1, + read_latency: float = 2.0, + allowed_updates: List[str] = None, + ) -> Optional[Queue]: """Starts polling updates from Telegram. Args: @@ -270,9 +284,17 @@ class Updater: dispatcher_ready = Event() polling_ready = Event() self._init_thread(self.dispatcher.start, "dispatcher", ready=dispatcher_ready) - self._init_thread(self._start_polling, "updater", poll_interval, timeout, - read_latency, bootstrap_retries, clean, allowed_updates, - ready=polling_ready) + self._init_thread( + self._start_polling, + "updater", + poll_interval, + timeout, + read_latency, + bootstrap_retries, + clean, + allowed_updates, + ready=polling_ready, + ) self.logger.debug('Waiting for Dispatcher and polling to start') dispatcher_ready.wait() @@ -282,17 +304,19 @@ class Updater: return self.update_queue return None - def start_webhook(self, - listen: str = '127.0.0.1', - port: int = 80, - url_path: str = '', - cert: str = None, - key: str = None, - clean: bool = False, - bootstrap_retries: int = 0, - webhook_url: str = None, - allowed_updates: List[str] = None, - force_event_loop: bool = False) -> Optional[Queue]: + def start_webhook( + self, + listen: str = '127.0.0.1', + port: int = 80, + url_path: str = '', + cert: str = None, + key: str = None, + clean: bool = False, + bootstrap_retries: int = 0, + webhook_url: str = None, + allowed_updates: List[str] = None, + force_event_loop: bool = False, + ) -> Optional[Queue]: """ Starts a small http server to listen for updates via webhook. If cert and key are not provided, the webhook will be started directly on @@ -344,9 +368,21 @@ class Updater: dispatcher_ready = Event() self.job_queue.start() self._init_thread(self.dispatcher.start, "dispatcher", dispatcher_ready) - self._init_thread(self._start_webhook, "updater", listen, port, url_path, cert, - key, bootstrap_retries, clean, webhook_url, allowed_updates, - ready=webhook_ready, force_event_loop=force_event_loop) + self._init_thread( + self._start_webhook, + "updater", + listen, + port, + url_path, + cert, + key, + bootstrap_retries, + clean, + webhook_url, + allowed_updates, + ready=webhook_ready, + force_event_loop=force_event_loop, + ) self.logger.debug('Waiting for Dispatcher and Webhook to start') webhook_ready.wait() @@ -357,8 +393,16 @@ class Updater: return None @no_type_check - def _start_polling(self, poll_interval, timeout, read_latency, bootstrap_retries, clean, - allowed_updates, ready=None): # pragma: no cover + def _start_polling( + self, + poll_interval, + timeout, + read_latency, + bootstrap_retries, + clean, + allowed_updates, + ready=None, + ): # pragma: no cover # Thread target of thread 'updater'. Runs in background, pulls # updates from Telegram and inserts them in the update queue of the # Dispatcher. @@ -370,10 +414,12 @@ class Updater: self.logger.debug('Bootstrap done') def polling_action_cb(): - updates = self.bot.get_updates(self.last_update_id, - timeout=timeout, - read_latency=read_latency, - allowed_updates=allowed_updates) + updates = self.bot.get_updates( + self.last_update_id, + timeout=timeout, + read_latency=read_latency, + allowed_updates=allowed_updates, + ) if updates: if not self.running: @@ -393,8 +439,9 @@ class Updater: if ready is not None: ready.set() - self._network_loop_retry(polling_action_cb, polling_onerr_cb, 'getting Updates', - poll_interval) + self._network_loop_retry( + polling_action_cb, polling_onerr_cb, 'getting Updates', poll_interval + ) @no_type_check def _network_loop_retry(self, action_cb, onerr_cb, description, interval): @@ -450,8 +497,20 @@ class Updater: return current_interval @no_type_check - def _start_webhook(self, listen, port, url_path, cert, key, bootstrap_retries, clean, - webhook_url, allowed_updates, ready=None, force_event_loop=False): + def _start_webhook( + self, + listen, + port, + url_path, + cert, + key, + bootstrap_retries, + clean, + webhook_url, + allowed_updates, + ready=None, + force_event_loop=False, + ): self.logger.debug('Updater thread started (webhook)') use_ssl = cert is not None and key is not None if not url_path.startswith('/'): @@ -479,14 +538,18 @@ class Updater: if not webhook_url: webhook_url = self._gen_webhook_url(listen, port, url_path) - self._bootstrap(max_retries=bootstrap_retries, - clean=clean, - webhook_url=webhook_url, - cert=open(cert, 'rb'), - allowed_updates=allowed_updates) + self._bootstrap( + max_retries=bootstrap_retries, + clean=clean, + webhook_url=webhook_url, + cert=open(cert, 'rb'), + allowed_updates=allowed_updates, + ) elif clean: - self.logger.warning("cleaning updates is not supported if " - "SSL-termination happens elsewhere; skipping") + self.logger.warning( + "cleaning updates is not supported if " + "SSL-termination happens elsewhere; skipping" + ) self.httpd.serve_forever(force_event_loop=force_event_loop, ready=ready) @@ -495,13 +558,9 @@ class Updater: return 'https://{listen}:{port}{path}'.format(listen=listen, port=port, path=url_path) @no_type_check - def _bootstrap(self, - max_retries, - clean, - webhook_url, - allowed_updates, - cert=None, - bootstrap_interval=5): + def _bootstrap( + self, max_retries, clean, webhook_url, allowed_updates, cert=None, bootstrap_interval=5 + ): retries = [0] def bootstrap_del_webhook(): @@ -516,16 +575,17 @@ class Updater: return False def bootstrap_set_webhook(): - self.bot.set_webhook(url=webhook_url, - certificate=cert, - allowed_updates=allowed_updates) + self.bot.set_webhook( + url=webhook_url, certificate=cert, allowed_updates=allowed_updates + ) return False def bootstrap_onerr_cb(exc): if not isinstance(exc, Unauthorized) and (max_retries < 0 or retries[0] < max_retries): retries[0] += 1 - self.logger.warning('Failed bootstrap phase; try=%s max_retries=%s', retries[0], - max_retries) + self.logger.warning( + 'Failed bootstrap phase; try=%s max_retries=%s', retries[0], max_retries + ) else: self.logger.error('Failed bootstrap phase after %s retries (%s)', retries[0], exc) raise exc @@ -535,22 +595,34 @@ class Updater: # We also take this chance to delete pre-configured webhook if this is a polling Updater. # NOTE: We don't know ahead if a webhook is configured, so we just delete. if clean or not webhook_url: - self._network_loop_retry(bootstrap_del_webhook, bootstrap_onerr_cb, - 'bootstrap del webhook', bootstrap_interval) + self._network_loop_retry( + bootstrap_del_webhook, + bootstrap_onerr_cb, + 'bootstrap del webhook', + bootstrap_interval, + ) retries[0] = 0 # Clean pending messages, if requested. if clean: - self._network_loop_retry(bootstrap_clean_updates, bootstrap_onerr_cb, - 'bootstrap clean updates', bootstrap_interval) + self._network_loop_retry( + bootstrap_clean_updates, + bootstrap_onerr_cb, + 'bootstrap clean updates', + bootstrap_interval, + ) retries[0] = 0 sleep(1) # Restore/set webhook settings, if needed. Again, we don't know ahead if a webhook is set, # so we set it anyhow. if webhook_url: - self._network_loop_retry(bootstrap_set_webhook, bootstrap_onerr_cb, - 'bootstrap set webhook', bootstrap_interval) + self._network_loop_retry( + bootstrap_set_webhook, + bootstrap_onerr_cb, + 'bootstrap set webhook', + bootstrap_interval, + ) def stop(self) -> None: """Stops the polling/webhook thread, the dispatcher and the job queue.""" @@ -573,9 +645,11 @@ class Updater: @no_type_check def _stop_httpd(self) -> None: if self.httpd: - self.logger.debug('Waiting for current webhook connection to be ' - 'closed... Send a Telegram message to the bot to exit ' - 'immediately.') + self.logger.debug( + 'Waiting for current webhook connection to be ' + 'closed... Send a Telegram message to the bot to exit ' + 'immediately.' + ) self.httpd.shutdown() self.httpd = None @@ -596,8 +670,9 @@ class Updater: def signal_handler(self, signum, frame) -> None: self.is_idle = False if self.running: - self.logger.info('Received signal {} ({}), stopping...'.format( - signum, get_signal_name(signum))) + self.logger.info( + 'Received signal {} ({}), stopping...'.format(signum, get_signal_name(signum)) + ) if self.persistence: # Update user_data, chat_data and bot_data before flushing self.dispatcher.update_persistence() @@ -608,6 +683,7 @@ class Updater: else: self.logger.warning('Exiting immediately!') import os + os._exit(1) def idle(self, stop_signals: Union[List, Tuple] = (SIGINT, SIGTERM, SIGABRT)) -> None: diff --git a/telegram/files/animation.py b/telegram/files/animation.py index 88bcac5a4..61944118a 100644 --- a/telegram/files/animation.py +++ b/telegram/files/animation.py @@ -22,6 +22,7 @@ from telegram import TelegramObject from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -64,18 +65,20 @@ class Animation(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - width: int, - height: int, - duration: int, - thumb: PhotoSize = None, - file_name: str = None, - mime_type: str = None, - file_size: int = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + width: int, + height: int, + duration: int, + thumb: PhotoSize = None, + file_name: str = None, + mime_type: str = None, + file_size: int = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) diff --git a/telegram/files/audio.py b/telegram/files/audio.py index 273a63b5d..0ebc73074 100644 --- a/telegram/files/audio.py +++ b/telegram/files/audio.py @@ -22,6 +22,7 @@ from telegram import TelegramObject, PhotoSize from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -65,17 +66,19 @@ class Audio(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - duration: int, - performer: str = None, - title: str = None, - mime_type: str = None, - file_size: int = None, - thumb: PhotoSize = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + duration: int, + performer: str = None, + title: str = None, + mime_type: str = None, + file_size: int = None, + thumb: PhotoSize = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) diff --git a/telegram/files/chatphoto.py b/telegram/files/chatphoto.py index 3f97b4b02..0af6d246e 100644 --- a/telegram/files/chatphoto.py +++ b/telegram/files/chatphoto.py @@ -20,6 +20,7 @@ from telegram import TelegramObject from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -61,13 +62,15 @@ class ChatPhoto(TelegramObject): """ - def __init__(self, - small_file_id: str, - small_file_unique_id: str, - big_file_id: str, - big_file_unique_id: str, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + small_file_id: str, + small_file_unique_id: str, + big_file_id: str, + big_file_unique_id: str, + bot: 'Bot' = None, + **kwargs: Any, + ): self.small_file_id = small_file_id self.small_file_unique_id = small_file_unique_id self.big_file_id = big_file_id @@ -75,7 +78,10 @@ class ChatPhoto(TelegramObject): self.bot = bot - self._id_attrs = (self.small_file_unique_id, self.big_file_unique_id,) + self._id_attrs = ( + self.small_file_unique_id, + self.big_file_unique_id, + ) def get_small_file(self, timeout: int = None, **kwargs: Any) -> 'File': """Convenience wrapper over :attr:`telegram.Bot.get_file` for getting the diff --git a/telegram/files/contact.py b/telegram/files/contact.py index c17d5cd5d..aa8dacdbe 100644 --- a/telegram/files/contact.py +++ b/telegram/files/contact.py @@ -45,13 +45,15 @@ class Contact(TelegramObject): """ - def __init__(self, - phone_number: str, - first_name: str, - last_name: str = None, - user_id: int = None, - vcard: str = None, - **kwargs: Any): + def __init__( + self, + phone_number: str, + first_name: str, + last_name: str = None, + user_id: int = None, + vcard: str = None, + **kwargs: Any, + ): # Required self.phone_number = str(phone_number) self.first_name = first_name diff --git a/telegram/files/document.py b/telegram/files/document.py index 72b4abe57..15d8b6c2f 100644 --- a/telegram/files/document.py +++ b/telegram/files/document.py @@ -22,6 +22,7 @@ from telegram import PhotoSize, TelegramObject from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -57,17 +58,20 @@ class Document(TelegramObject): **kwargs (:obj:`dict`): Arbitrary keyword arguments. """ + _id_keys = ('file_id',) - def __init__(self, - file_id: str, - file_unique_id: str, - thumb: PhotoSize = None, - file_name: str = None, - mime_type: str = None, - file_size: int = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + thumb: PhotoSize = None, + file_name: str = None, + mime_type: str = None, + file_size: int = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) diff --git a/telegram/files/file.py b/telegram/files/file.py index 6b9298206..27d60fe60 100644 --- a/telegram/files/file.py +++ b/telegram/files/file.py @@ -27,6 +27,7 @@ from telegram import TelegramObject from telegram.passport.credentials import decrypt from typing import Any, Optional, IO, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, FileCredentials @@ -68,13 +69,15 @@ class File(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - bot: 'Bot' = None, - file_size: int = None, - file_path: str = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + bot: 'Bot' = None, + file_size: int = None, + file_path: str = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) @@ -86,10 +89,9 @@ class File(TelegramObject): self._id_attrs = (self.file_unique_id,) - def download(self, - custom_path: str = None, - out: IO = None, - timeout: int = None) -> Union[str, IO]: + def download( + self, custom_path: str = None, out: IO = None, timeout: int = None + ) -> Union[str, IO]: """ Download this file. By default, the file is saved in the current working directory with its original filename as reported by Telegram. If the file has no filename, it the file ID will @@ -125,9 +127,9 @@ class File(TelegramObject): if out: buf = self.bot.request.retrieve(url) if self._credentials: - buf = decrypt(b64decode(self._credentials.secret), - b64decode(self._credentials.hash), - buf) + buf = decrypt( + b64decode(self._credentials.secret), b64decode(self._credentials.hash), buf + ) out.write(buf) return out else: @@ -140,9 +142,9 @@ class File(TelegramObject): buf = self.bot.request.retrieve(url, timeout=timeout) if self._credentials: - buf = decrypt(b64decode(self._credentials.secret), - b64decode(self._credentials.hash), - buf) + buf = decrypt( + b64decode(self._credentials.secret), b64decode(self._credentials.hash), buf + ) with open(filename, 'wb') as fobj: fobj.write(buf) return filename @@ -150,8 +152,11 @@ class File(TelegramObject): def _get_encoded_url(self) -> str: """Convert any UTF-8 char in :obj:`File.file_path` into a url encoded ASCII string.""" sres = urllib_parse.urlsplit(self.file_path) - return urllib_parse.urlunsplit(urllib_parse.SplitResult( - sres.scheme, sres.netloc, urllib_parse.quote(sres.path), sres.query, sres.fragment)) + return urllib_parse.urlunsplit( + urllib_parse.SplitResult( + sres.scheme, sres.netloc, urllib_parse.quote(sres.path), sres.query, sres.fragment + ) + ) def download_as_bytearray(self, buf: bytearray = None) -> bytes: """Download this file and return it as a bytearray. diff --git a/telegram/files/inputfile.py b/telegram/files/inputfile.py index 8c57c64ef..97e4eaf0c 100644 --- a/telegram/files/inputfile.py +++ b/telegram/files/inputfile.py @@ -57,15 +57,14 @@ class InputFile: if filename: self.filename = filename - elif (hasattr(obj, 'name') and not isinstance(obj.name, int)): + elif hasattr(obj, 'name') and not isinstance(obj.name, int): self.filename = os.path.basename(obj.name) try: self.mimetype = self.is_image(self.input_file_content) except TelegramError: if self.filename: - self.mimetype = mimetypes.guess_type( - self.filename)[0] or DEFAULT_MIME_TYPE + self.mimetype = mimetypes.guess_type(self.filename)[0] or DEFAULT_MIME_TYPE else: self.mimetype = DEFAULT_MIME_TYPE if not self.filename: diff --git a/telegram/files/inputmedia.py b/telegram/files/inputmedia.py index 1aba083e5..21f3f6d5e 100644 --- a/telegram/files/inputmedia.py +++ b/telegram/files/inputmedia.py @@ -34,6 +34,7 @@ class InputMedia(TelegramObject): :class:`telegram.InputMediaVideo` for detailed use. """ + pass @@ -76,14 +77,16 @@ class InputMediaAnimation(InputMedia): arguments. """ - def __init__(self, - media: Union[str, FileLike, Animation], - thumb: FileLike = None, - caption: str = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - width: int = None, - height: int = None, - duration: int = None): + def __init__( + self, + media: Union[str, FileLike, Animation], + thumb: FileLike = None, + caption: str = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + width: int = None, + height: int = None, + duration: int = None, + ): self.type = 'animation' if isinstance(media, Animation): @@ -136,10 +139,12 @@ class InputMediaPhoto(InputMedia): in :class:`telegram.ParseMode` for the available modes. """ - def __init__(self, - media: Union[str, FileLike, PhotoSize], - caption: str = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE): + def __init__( + self, + media: Union[str, FileLike, PhotoSize], + caption: str = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + ): self.type = 'photo' if isinstance(media, PhotoSize): @@ -200,15 +205,17 @@ class InputMediaVideo(InputMedia): by Telegram. """ - def __init__(self, - media: Union[str, FileLike, Video], - caption: str = None, - width: int = None, - height: int = None, - duration: int = None, - supports_streaming: bool = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - thumb: FileLike = None): + def __init__( + self, + media: Union[str, FileLike, Video], + caption: str = None, + width: int = None, + height: int = None, + duration: int = None, + supports_streaming: bool = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + thumb: FileLike = None, + ): self.type = 'video' if isinstance(media, Video): @@ -282,14 +289,16 @@ class InputMediaAudio(InputMedia): optional arguments. """ - def __init__(self, - media: Union[str, FileLike, Audio], - thumb: FileLike = None, - caption: str = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - duration: int = None, - performer: str = None, - title: str = None): + def __init__( + self, + media: Union[str, FileLike, Audio], + thumb: FileLike = None, + caption: str = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + duration: int = None, + performer: str = None, + title: str = None, + ): self.type = 'audio' if isinstance(media, Audio): @@ -348,11 +357,13 @@ class InputMediaDocument(InputMedia): Thumbnails can't be reused and can be only uploaded as a new file. """ - def __init__(self, - media: Union[str, FileLike, Document], - thumb: FileLike = None, - caption: str = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE): + def __init__( + self, + media: Union[str, FileLike, Document], + thumb: FileLike = None, + caption: str = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + ): self.type = 'document' if isinstance(media, Document): diff --git a/telegram/files/photosize.py b/telegram/files/photosize.py index f6504b05d..7c64705e3 100644 --- a/telegram/files/photosize.py +++ b/telegram/files/photosize.py @@ -21,6 +21,7 @@ from telegram import TelegramObject from telegram.utils.types import JSONDict from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -55,14 +56,16 @@ class PhotoSize(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - width: int, - height: int, - file_size: int = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + width: int, + height: int, + file_size: int = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) diff --git a/telegram/files/sticker.py b/telegram/files/sticker.py index 4c504f574..c59251cfb 100644 --- a/telegram/files/sticker.py +++ b/telegram/files/sticker.py @@ -21,6 +21,7 @@ from telegram import PhotoSize, TelegramObject from telegram.utils.types import JSONDict from typing import Any, Optional, List, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -71,19 +72,21 @@ class Sticker(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - width: int, - height: int, - is_animated: bool, - thumb: PhotoSize = None, - emoji: str = None, - file_size: int = None, - set_name: str = None, - mask_position: 'MaskPosition' = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + width: int, + height: int, + is_animated: bool, + thumb: PhotoSize = None, + emoji: str = None, + file_size: int = None, + set_name: str = None, + mask_position: 'MaskPosition' = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) @@ -158,15 +161,17 @@ class StickerSet(TelegramObject): """ - def __init__(self, - name: str, - title: str, - is_animated: bool, - contains_masks: bool, - stickers: List[Sticker], - bot: 'Bot' = None, - thumb: PhotoSize = None, - **kwargs: Any): + def __init__( + self, + name: str, + title: str, + is_animated: bool, + contains_masks: bool, + stickers: List[Sticker], + bot: 'Bot' = None, + thumb: PhotoSize = None, + **kwargs: Any, + ): self.name = name self.title = title self.is_animated = is_animated @@ -227,6 +232,7 @@ class MaskPosition(TelegramObject): scale (:obj:`float`): Mask scaling coefficient. For example, 2.0 means double size. """ + FOREHEAD: str = 'forehead' """:obj:`str`: 'forehead'""" EYES: str = 'eyes' diff --git a/telegram/files/venue.py b/telegram/files/venue.py index 95b890d8c..df45bf0a4 100644 --- a/telegram/files/venue.py +++ b/telegram/files/venue.py @@ -21,6 +21,7 @@ from telegram import TelegramObject, Location from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -50,13 +51,15 @@ class Venue(TelegramObject): """ - def __init__(self, - location: Location, - title: str, - address: str, - foursquare_id: str = None, - foursquare_type: str = None, - **kwargs: Any): + def __init__( + self, + location: Location, + title: str, + address: str, + foursquare_id: str = None, + foursquare_type: str = None, + **kwargs: Any, + ): # Required self.location = location self.title = title diff --git a/telegram/files/video.py b/telegram/files/video.py index c2ec70b4d..1d13e5a1e 100644 --- a/telegram/files/video.py +++ b/telegram/files/video.py @@ -21,6 +21,7 @@ from telegram import PhotoSize, TelegramObject from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -61,17 +62,19 @@ class Video(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - width: int, - height: int, - duration: int, - thumb: PhotoSize = None, - mime_type: str = None, - file_size: int = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + width: int, + height: int, + duration: int, + thumb: PhotoSize = None, + mime_type: str = None, + file_size: int = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) diff --git a/telegram/files/videonote.py b/telegram/files/videonote.py index 524c40d2e..0af08a0e8 100644 --- a/telegram/files/videonote.py +++ b/telegram/files/videonote.py @@ -21,6 +21,7 @@ from telegram import PhotoSize, TelegramObject from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -58,15 +59,17 @@ class VideoNote(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - length: int, - duration: int, - thumb: PhotoSize = None, - file_size: int = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + length: int, + duration: int, + thumb: PhotoSize = None, + file_size: int = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) diff --git a/telegram/files/voice.py b/telegram/files/voice.py index c50b30ec6..f83576ce5 100644 --- a/telegram/files/voice.py +++ b/telegram/files/voice.py @@ -21,6 +21,7 @@ from telegram import TelegramObject from telegram.utils.types import JSONDict from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File @@ -55,14 +56,16 @@ class Voice(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - duration: int, - mime_type: str = None, - file_size: int = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + duration: int, + mime_type: str = None, + file_size: int = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.file_id = str(file_id) self.file_unique_id = str(file_unique_id) diff --git a/telegram/games/game.py b/telegram/games/game.py index 04f3acf04..71af004f3 100644 --- a/telegram/games/game.py +++ b/telegram/games/game.py @@ -23,6 +23,7 @@ import sys from telegram import MessageEntity, TelegramObject, Animation, PhotoSize from telegram.utils.types import JSONDict from typing import List, Any, Dict, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -66,14 +67,16 @@ class Game(TelegramObject): """ - def __init__(self, - title: str, - description: str, - photo: List[PhotoSize], - text: str = None, - text_entities: List[MessageEntity] = None, - animation: Animation = None, - **kwargs: Any): + def __init__( + self, + title: str, + description: str, + photo: List[PhotoSize], + text: str = None, + text_entities: List[MessageEntity] = None, + animation: Animation = None, + **kwargs: Any, + ): # Required self.title = title self.description = description @@ -130,11 +133,11 @@ class Game(TelegramObject): raise RuntimeError("This Game has no 'text'.") # Is it a narrow build, if so we don't need to convert - if sys.maxunicode == 0xffff: - return self.text[entity.offset:entity.offset + entity.length] + if sys.maxunicode == 0xFFFF: + return self.text[entity.offset : entity.offset + entity.length] else: entity_text = self.text.encode('utf-16-le') - entity_text = entity_text[entity.offset * 2:(entity.offset + entity.length) * 2] + entity_text = entity_text[entity.offset * 2 : (entity.offset + entity.length) * 2] return entity_text.decode('utf-16-le') @@ -164,7 +167,8 @@ class Game(TelegramObject): return { entity: self.parse_text_entity(entity) - for entity in (self.text_entities or []) if entity.type in types + for entity in (self.text_entities or []) + if entity.type in types } def __hash__(self) -> int: diff --git a/telegram/games/gamehighscore.py b/telegram/games/gamehighscore.py index 096a28c2c..be95a7e07 100644 --- a/telegram/games/gamehighscore.py +++ b/telegram/games/gamehighscore.py @@ -21,6 +21,7 @@ from telegram import TelegramObject, User from telegram.utils.types import JSONDict from typing import Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot diff --git a/telegram/inline/inlinekeyboardbutton.py b/telegram/inline/inlinekeyboardbutton.py index 09373255e..b25edb214 100644 --- a/telegram/inline/inlinekeyboardbutton.py +++ b/telegram/inline/inlinekeyboardbutton.py @@ -20,6 +20,7 @@ from telegram import TelegramObject from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import CallbackGame, LoginUrl @@ -81,16 +82,18 @@ class InlineKeyboardButton(TelegramObject): """ - def __init__(self, - text: str, - url: str = None, - callback_data: str = None, - switch_inline_query: str = None, - switch_inline_query_current_chat: str = None, - callback_game: 'CallbackGame' = None, - pay: bool = None, - login_url: 'LoginUrl' = None, - **kwargs: Any): + def __init__( + self, + text: str, + url: str = None, + callback_data: str = None, + switch_inline_query: str = None, + switch_inline_query_current_chat: str = None, + callback_game: 'CallbackGame' = None, + pay: bool = None, + login_url: 'LoginUrl' = None, + **kwargs: Any, + ): # Required self.text = text diff --git a/telegram/inline/inlinekeyboardmarkup.py b/telegram/inline/inlinekeyboardmarkup.py index 6e7bda8cb..12045e249 100644 --- a/telegram/inline/inlinekeyboardmarkup.py +++ b/telegram/inline/inlinekeyboardmarkup.py @@ -21,6 +21,7 @@ from telegram import ReplyMarkup, InlineKeyboardButton from telegram.utils.types import JSONDict from typing import Any, List, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -57,8 +58,7 @@ class InlineKeyboardMarkup(ReplyMarkup): return data @classmethod - def de_json(cls, data: Optional[JSONDict], - bot: 'Bot') -> Optional['InlineKeyboardMarkup']: + def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['InlineKeyboardMarkup']: data = cls.parse_data(data) if not data: @@ -91,8 +91,9 @@ class InlineKeyboardMarkup(ReplyMarkup): return cls([[button]], **kwargs) @classmethod - def from_row(cls, button_row: List[InlineKeyboardButton], - **kwargs: Any) -> 'InlineKeyboardMarkup': + def from_row( + cls, button_row: List[InlineKeyboardButton], **kwargs: Any + ) -> 'InlineKeyboardMarkup': """Shortcut for:: InlineKeyboardMarkup([button_row], **kwargs) @@ -108,8 +109,9 @@ class InlineKeyboardMarkup(ReplyMarkup): return cls([button_row], **kwargs) @classmethod - def from_column(cls, button_column: List[InlineKeyboardButton], - **kwargs: Any) -> 'InlineKeyboardMarkup': + def from_column( + cls, button_column: List[InlineKeyboardButton], **kwargs: Any + ) -> 'InlineKeyboardMarkup': """Shortcut for:: InlineKeyboardMarkup([[button] for button in button_column], **kwargs) diff --git a/telegram/inline/inlinequery.py b/telegram/inline/inlinequery.py index b60a0f2a5..55373fb31 100644 --- a/telegram/inline/inlinequery.py +++ b/telegram/inline/inlinequery.py @@ -22,6 +22,7 @@ from telegram import TelegramObject, User, Location from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -57,14 +58,16 @@ class InlineQuery(TelegramObject): """ - def __init__(self, - id: str, - from_user: User, - query: str, - offset: str, - location: Location = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + id: str, + from_user: User, + query: str, + offset: str, + location: Location = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.id = id self.from_user = from_user @@ -125,8 +128,5 @@ class InlineQuery(TelegramObject): """ return self.bot.answer_inline_query( - self.id, - *args, - current_offset=self.offset if auto_pagination else None, - **kwargs + self.id, *args, current_offset=self.offset if auto_pagination else None, **kwargs ) diff --git a/telegram/inline/inlinequeryresultarticle.py b/telegram/inline/inlinequeryresultarticle.py index 5f670faa2..847f60f9d 100644 --- a/telegram/inline/inlinequeryresultarticle.py +++ b/telegram/inline/inlinequeryresultarticle.py @@ -20,6 +20,7 @@ from telegram import InlineQueryResult from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -61,18 +62,20 @@ class InlineQueryResultArticle(InlineQueryResult): """ - def __init__(self, - id: str, - title: str, - input_message_content: 'InputMessageContent', - reply_markup: 'ReplyMarkup' = None, - url: str = None, - hide_url: bool = None, - description: str = None, - thumb_url: str = None, - thumb_width: int = None, - thumb_height: int = None, - **kwargs: Any): + def __init__( + self, + id: str, + title: str, + input_message_content: 'InputMessageContent', + reply_markup: 'ReplyMarkup' = None, + url: str = None, + hide_url: bool = None, + description: str = None, + thumb_url: str = None, + thumb_width: int = None, + thumb_height: int = None, + **kwargs: Any, + ): # Required super().__init__('article', id) diff --git a/telegram/inline/inlinequeryresultaudio.py b/telegram/inline/inlinequeryresultaudio.py index 8ad0d8c1b..fd85720bf 100644 --- a/telegram/inline/inlinequeryresultaudio.py +++ b/telegram/inline/inlinequeryresultaudio.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -65,17 +66,19 @@ class InlineQueryResultAudio(InlineQueryResult): """ - def __init__(self, - id: str, - audio_url: str, - title: str, - performer: str = None, - audio_duration: int = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + audio_url: str, + title: str, + performer: str = None, + audio_duration: int = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('audio', id) diff --git a/telegram/inline/inlinequeryresultcachedaudio.py b/telegram/inline/inlinequeryresultcachedaudio.py index 09ca76960..9ca1aab74 100644 --- a/telegram/inline/inlinequeryresultcachedaudio.py +++ b/telegram/inline/inlinequeryresultcachedaudio.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -59,14 +60,16 @@ class InlineQueryResultCachedAudio(InlineQueryResult): """ - def __init__(self, - id: str, - audio_file_id: str, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + audio_file_id: str, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('audio', id) self.audio_file_id = audio_file_id diff --git a/telegram/inline/inlinequeryresultcacheddocument.py b/telegram/inline/inlinequeryresultcacheddocument.py index 3a04b4991..87e3aec06 100644 --- a/telegram/inline/inlinequeryresultcacheddocument.py +++ b/telegram/inline/inlinequeryresultcacheddocument.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -65,16 +66,18 @@ class InlineQueryResultCachedDocument(InlineQueryResult): """ - def __init__(self, - id: str, - title: str, - document_file_id: str, - description: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + title: str, + document_file_id: str, + description: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('document', id) self.title = title diff --git a/telegram/inline/inlinequeryresultcachedgif.py b/telegram/inline/inlinequeryresultcachedgif.py index cb325132a..14eb8588d 100644 --- a/telegram/inline/inlinequeryresultcachedgif.py +++ b/telegram/inline/inlinequeryresultcachedgif.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -64,15 +65,17 @@ class InlineQueryResultCachedGif(InlineQueryResult): """ - def __init__(self, - id: str, - gif_file_id: str, - title: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + gif_file_id: str, + title: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('gif', id) self.gif_file_id = gif_file_id diff --git a/telegram/inline/inlinequeryresultcachedmpeg4gif.py b/telegram/inline/inlinequeryresultcachedmpeg4gif.py index f71eef5a6..604046b29 100644 --- a/telegram/inline/inlinequeryresultcachedmpeg4gif.py +++ b/telegram/inline/inlinequeryresultcachedmpeg4gif.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -64,15 +65,17 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): """ - def __init__(self, - id: str, - mpeg4_file_id: str, - title: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + mpeg4_file_id: str, + title: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('mpeg4_gif', id) self.mpeg4_file_id = mpeg4_file_id diff --git a/telegram/inline/inlinequeryresultcachedphoto.py b/telegram/inline/inlinequeryresultcachedphoto.py index 2f226d624..fe83974ad 100644 --- a/telegram/inline/inlinequeryresultcachedphoto.py +++ b/telegram/inline/inlinequeryresultcachedphoto.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -66,16 +67,18 @@ class InlineQueryResultCachedPhoto(InlineQueryResult): """ - def __init__(self, - id: str, - photo_file_id: str, - title: str = None, - description: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + photo_file_id: str, + title: str = None, + description: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('photo', id) self.photo_file_id = photo_file_id diff --git a/telegram/inline/inlinequeryresultcachedsticker.py b/telegram/inline/inlinequeryresultcachedsticker.py index 1f024b08a..3a764739e 100644 --- a/telegram/inline/inlinequeryresultcachedsticker.py +++ b/telegram/inline/inlinequeryresultcachedsticker.py @@ -20,6 +20,7 @@ from telegram import InlineQueryResult from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import ReplyMarkup, InputMessageContent @@ -50,12 +51,14 @@ class InlineQueryResultCachedSticker(InlineQueryResult): """ - def __init__(self, - id: str, - sticker_file_id: str, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - **kwargs: Any): + def __init__( + self, + id: str, + sticker_file_id: str, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + **kwargs: Any, + ): # Required super().__init__('sticker', id) self.sticker_file_id = sticker_file_id diff --git a/telegram/inline/inlinequeryresultcachedvideo.py b/telegram/inline/inlinequeryresultcachedvideo.py index b4d6f43b9..6dd2ad820 100644 --- a/telegram/inline/inlinequeryresultcachedvideo.py +++ b/telegram/inline/inlinequeryresultcachedvideo.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -66,16 +67,18 @@ class InlineQueryResultCachedVideo(InlineQueryResult): """ - def __init__(self, - id: str, - video_file_id: str, - title: str, - description: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + video_file_id: str, + title: str, + description: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('video', id) self.video_file_id = video_file_id diff --git a/telegram/inline/inlinequeryresultcachedvoice.py b/telegram/inline/inlinequeryresultcachedvoice.py index cd3c2a431..04f263d57 100644 --- a/telegram/inline/inlinequeryresultcachedvoice.py +++ b/telegram/inline/inlinequeryresultcachedvoice.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -61,15 +62,17 @@ class InlineQueryResultCachedVoice(InlineQueryResult): """ - def __init__(self, - id: str, - voice_file_id: str, - title: str, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + voice_file_id: str, + title: str, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('voice', id) self.voice_file_id = voice_file_id diff --git a/telegram/inline/inlinequeryresultcontact.py b/telegram/inline/inlinequeryresultcontact.py index ca7640feb..ef380b93e 100644 --- a/telegram/inline/inlinequeryresultcontact.py +++ b/telegram/inline/inlinequeryresultcontact.py @@ -20,6 +20,7 @@ from telegram import InlineQueryResult from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import ReplyMarkup, InputMessageContent @@ -64,18 +65,20 @@ class InlineQueryResultContact(InlineQueryResult): """ - def __init__(self, - id: str, - phone_number: str, - first_name: str, - last_name: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - thumb_url: str = None, - thumb_width: int = None, - thumb_height: int = None, - vcard: str = None, - **kwargs: Any): + def __init__( + self, + id: str, + phone_number: str, + first_name: str, + last_name: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + thumb_url: str = None, + thumb_width: int = None, + thumb_height: int = None, + vcard: str = None, + **kwargs: Any, + ): # Required super().__init__('contact', id) self.phone_number = phone_number diff --git a/telegram/inline/inlinequeryresultdocument.py b/telegram/inline/inlinequeryresultdocument.py index 815e450fe..7809d089a 100644 --- a/telegram/inline/inlinequeryresultdocument.py +++ b/telegram/inline/inlinequeryresultdocument.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -76,20 +77,22 @@ class InlineQueryResultDocument(InlineQueryResult): """ - def __init__(self, - id: str, - document_url: str, - title: str, - mime_type: str, - caption: str = None, - description: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - thumb_url: str = None, - thumb_width: int = None, - thumb_height: int = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + document_url: str, + title: str, + mime_type: str, + caption: str = None, + description: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + thumb_url: str = None, + thumb_width: int = None, + thumb_height: int = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('document', id) self.document_url = document_url diff --git a/telegram/inline/inlinequeryresultgame.py b/telegram/inline/inlinequeryresultgame.py index 8b3ae38ba..5cd5d7cdb 100644 --- a/telegram/inline/inlinequeryresultgame.py +++ b/telegram/inline/inlinequeryresultgame.py @@ -20,6 +20,7 @@ from telegram import InlineQueryResult from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import ReplyMarkup @@ -43,11 +44,9 @@ class InlineQueryResultGame(InlineQueryResult): """ - def __init__(self, - id: str, - game_short_name: str, - reply_markup: 'ReplyMarkup' = None, - **kwargs: Any): + def __init__( + self, id: str, game_short_name: str, reply_markup: 'ReplyMarkup' = None, **kwargs: Any + ): # Required super().__init__('game', id) self.id = id diff --git a/telegram/inline/inlinequeryresultgif.py b/telegram/inline/inlinequeryresultgif.py index ccd069d1e..93f058ecc 100644 --- a/telegram/inline/inlinequeryresultgif.py +++ b/telegram/inline/inlinequeryresultgif.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -76,20 +77,22 @@ class InlineQueryResultGif(InlineQueryResult): """ - def __init__(self, - id: str, - gif_url: str, - thumb_url: str, - gif_width: int = None, - gif_height: int = None, - title: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - gif_duration: int = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - thumb_mime_type: str = None, - **kwargs: Any): + def __init__( + self, + id: str, + gif_url: str, + thumb_url: str, + gif_width: int = None, + gif_height: int = None, + title: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + gif_duration: int = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + thumb_mime_type: str = None, + **kwargs: Any, + ): # Required super().__init__('gif', id) diff --git a/telegram/inline/inlinequeryresultlocation.py b/telegram/inline/inlinequeryresultlocation.py index 50e866743..772e0348e 100644 --- a/telegram/inline/inlinequeryresultlocation.py +++ b/telegram/inline/inlinequeryresultlocation.py @@ -20,6 +20,7 @@ from telegram import InlineQueryResult from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import ReplyMarkup, InputMessageContent @@ -64,18 +65,20 @@ class InlineQueryResultLocation(InlineQueryResult): """ - def __init__(self, - id: str, - latitude: float, - longitude: float, - title: str, - live_period: int = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - thumb_url: str = None, - thumb_width: int = None, - thumb_height: int = None, - **kwargs: Any): + def __init__( + self, + id: str, + latitude: float, + longitude: float, + title: str, + live_period: int = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + thumb_url: str = None, + thumb_width: int = None, + thumb_height: int = None, + **kwargs: Any, + ): # Required super().__init__('location', id) self.latitude = latitude diff --git a/telegram/inline/inlinequeryresultmpeg4gif.py b/telegram/inline/inlinequeryresultmpeg4gif.py index eb8e22f35..e5d563bc2 100644 --- a/telegram/inline/inlinequeryresultmpeg4gif.py +++ b/telegram/inline/inlinequeryresultmpeg4gif.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -76,20 +77,22 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): """ - def __init__(self, - id: str, - mpeg4_url: str, - thumb_url: str, - mpeg4_width: int = None, - mpeg4_height: int = None, - title: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - mpeg4_duration: int = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - thumb_mime_type: str = None, - **kwargs: Any): + def __init__( + self, + id: str, + mpeg4_url: str, + thumb_url: str, + mpeg4_width: int = None, + mpeg4_height: int = None, + title: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + mpeg4_duration: int = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + thumb_mime_type: str = None, + **kwargs: Any, + ): # Required super().__init__('mpeg4_gif', id) diff --git a/telegram/inline/inlinequeryresultphoto.py b/telegram/inline/inlinequeryresultphoto.py index 6c9c58aa0..58706bc96 100644 --- a/telegram/inline/inlinequeryresultphoto.py +++ b/telegram/inline/inlinequeryresultphoto.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -73,26 +74,28 @@ class InlineQueryResultPhoto(InlineQueryResult): """ - def __init__(self, - id: str, - photo_url: str, - thumb_url: str, - photo_width: int = None, - photo_height: int = None, - title: str = None, - description: str = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + photo_url: str, + thumb_url: str, + photo_width: int = None, + photo_height: int = None, + title: str = None, + description: str = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('photo', id) self.photo_url = photo_url self.thumb_url = thumb_url # Optionals - self.photo_width = int(photo_width)if photo_width is not None else None + self.photo_width = int(photo_width) if photo_width is not None else None self.photo_height = int(photo_height) if photo_height is not None else None self.title = title self.description = description diff --git a/telegram/inline/inlinequeryresultvenue.py b/telegram/inline/inlinequeryresultvenue.py index da54c2b81..cfbae6e72 100644 --- a/telegram/inline/inlinequeryresultvenue.py +++ b/telegram/inline/inlinequeryresultvenue.py @@ -20,6 +20,7 @@ from telegram import InlineQueryResult from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import ReplyMarkup, InputMessageContent @@ -70,20 +71,22 @@ class InlineQueryResultVenue(InlineQueryResult): """ - def __init__(self, - id: str, - latitude: float, - longitude: float, - title: str, - address: str, - foursquare_id: str = None, - foursquare_type: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - thumb_url: str = None, - thumb_width: int = None, - thumb_height: int = None, - **kwargs: Any): + def __init__( + self, + id: str, + latitude: float, + longitude: float, + title: str, + address: str, + foursquare_id: str = None, + foursquare_type: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + thumb_url: str = None, + thumb_width: int = None, + thumb_height: int = None, + **kwargs: Any, + ): # Required super().__init__('venue', id) diff --git a/telegram/inline/inlinequeryresultvideo.py b/telegram/inline/inlinequeryresultvideo.py index f2856a655..bfa433834 100644 --- a/telegram/inline/inlinequeryresultvideo.py +++ b/telegram/inline/inlinequeryresultvideo.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -83,21 +84,23 @@ class InlineQueryResultVideo(InlineQueryResult): """ - def __init__(self, - id: str, - video_url: str, - mime_type: str, - thumb_url: str, - title: str, - caption: str = None, - video_width: int = None, - video_height: int = None, - video_duration: int = None, - description: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + video_url: str, + mime_type: str, + thumb_url: str, + title: str, + caption: str = None, + video_width: int = None, + video_height: int = None, + video_duration: int = None, + description: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('video', id) diff --git a/telegram/inline/inlinequeryresultvoice.py b/telegram/inline/inlinequeryresultvoice.py index 795f7be00..4b61651e0 100644 --- a/telegram/inline/inlinequeryresultvoice.py +++ b/telegram/inline/inlinequeryresultvoice.py @@ -21,6 +21,7 @@ from telegram import InlineQueryResult from telegram.utils.helpers import DEFAULT_NONE, DefaultValue from typing import Any, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import InputMessageContent, ReplyMarkup @@ -64,16 +65,18 @@ class InlineQueryResultVoice(InlineQueryResult): """ - def __init__(self, - id: str, - voice_url: str, - title: str, - voice_duration: int = None, - caption: str = None, - reply_markup: 'ReplyMarkup' = None, - input_message_content: 'InputMessageContent' = None, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + id: str, + voice_url: str, + title: str, + voice_duration: int = None, + caption: str = None, + reply_markup: 'ReplyMarkup' = None, + input_message_content: 'InputMessageContent' = None, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required super().__init__('voice', id) diff --git a/telegram/inline/inputcontactmessagecontent.py b/telegram/inline/inputcontactmessagecontent.py index a5530d0b8..baca0558c 100644 --- a/telegram/inline/inputcontactmessagecontent.py +++ b/telegram/inline/inputcontactmessagecontent.py @@ -45,12 +45,14 @@ class InputContactMessageContent(InputMessageContent): """ - def __init__(self, - phone_number: str, - first_name: str, - last_name: str = None, - vcard: str = None, - **kwargs: Any): + def __init__( + self, + phone_number: str, + first_name: str, + last_name: str = None, + vcard: str = None, + **kwargs: Any, + ): # Required self.phone_number = phone_number self.first_name = first_name diff --git a/telegram/inline/inputlocationmessagecontent.py b/telegram/inline/inputlocationmessagecontent.py index b29713fdf..8e938bc70 100644 --- a/telegram/inline/inputlocationmessagecontent.py +++ b/telegram/inline/inputlocationmessagecontent.py @@ -23,6 +23,7 @@ from typing import Any class InputLocationMessageContent(InputMessageContent): + # fmt: off """ Represents the content of a location message to be sent as the result of an inline query. @@ -43,6 +44,7 @@ class InputLocationMessageContent(InputMessageContent): **kwargs (:obj:`dict`): Arbitrary keyword arguments. """ + # fmt: on def __init__(self, latitude: float, longitude: float, live_period: int = None, **kwargs: Any): # Required diff --git a/telegram/inline/inputmessagecontent.py b/telegram/inline/inputmessagecontent.py index fd5b30817..a144ff6de 100644 --- a/telegram/inline/inputmessagecontent.py +++ b/telegram/inline/inputmessagecontent.py @@ -29,6 +29,7 @@ class InputMessageContent(TelegramObject): :class:`telegram.InputVenueMessageContent` for more details. """ + @property def _has_parse_mode(self) -> bool: return hasattr(self, 'parse_mode') diff --git a/telegram/inline/inputtextmessagecontent.py b/telegram/inline/inputtextmessagecontent.py index 79236d32d..8c42a048e 100644 --- a/telegram/inline/inputtextmessagecontent.py +++ b/telegram/inline/inputtextmessagecontent.py @@ -51,11 +51,13 @@ class InputTextMessageContent(InputMessageContent): """ - def __init__(self, - message_text: str, - parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, - disable_web_page_preview: Union[bool, DefaultValue] = DEFAULT_NONE, - **kwargs: Any): + def __init__( + self, + message_text: str, + parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + disable_web_page_preview: Union[bool, DefaultValue] = DEFAULT_NONE, + **kwargs: Any, + ): # Required self.message_text = message_text # Optionals diff --git a/telegram/inline/inputvenuemessagecontent.py b/telegram/inline/inputvenuemessagecontent.py index e4b3fad5d..e36de1543 100644 --- a/telegram/inline/inputvenuemessagecontent.py +++ b/telegram/inline/inputvenuemessagecontent.py @@ -52,14 +52,16 @@ class InputVenueMessageContent(InputMessageContent): """ - def __init__(self, - latitude: float, - longitude: float, - title: str, - address: str, - foursquare_id: str = None, - foursquare_type: str = None, - **kwargs: Any): + def __init__( + self, + latitude: float, + longitude: float, + title: str, + address: str, + foursquare_id: str = None, + foursquare_type: str = None, + **kwargs: Any, + ): # Required self.latitude = latitude self.longitude = longitude diff --git a/telegram/keyboardbutton.py b/telegram/keyboardbutton.py index d0fef2b06..ecbbba232 100644 --- a/telegram/keyboardbutton.py +++ b/telegram/keyboardbutton.py @@ -60,12 +60,14 @@ class KeyboardButton(TelegramObject): """ - def __init__(self, - text: str, - request_contact: bool = None, - request_location: bool = None, - request_poll: bool = None, - **kwargs: Any): + def __init__( + self, + text: str, + request_contact: bool = None, + request_location: bool = None, + request_poll: bool = None, + **kwargs: Any, + ): # Required self.text = text # Optionals @@ -73,5 +75,9 @@ class KeyboardButton(TelegramObject): self.request_location = request_location self.request_poll = request_poll - self._id_attrs = (self.text, self.request_contact, self.request_location, - self.request_poll) + self._id_attrs = ( + self.text, + self.request_contact, + self.request_location, + self.request_poll, + ) diff --git a/telegram/keyboardbuttonpolltype.py b/telegram/keyboardbuttonpolltype.py index 3a7ca84bc..d72149def 100644 --- a/telegram/keyboardbuttonpolltype.py +++ b/telegram/keyboardbuttonpolltype.py @@ -35,6 +35,7 @@ class KeyboardButtonPollType(TelegramObject): passed, only regular polls will be allowed. Otherwise, the user will be allowed to create a poll of any type. """ + def __init__(self, type: str = None, **kwargs: Any): self.type = type diff --git a/telegram/loginurl.py b/telegram/loginurl.py index 01798761e..c8a8c5ace 100644 --- a/telegram/loginurl.py +++ b/telegram/loginurl.py @@ -67,12 +67,14 @@ class LoginUrl(TelegramObject): `Checking authorization `_ """ - def __init__(self, - url: str, - forward_text: bool = None, - bot_username: str = None, - request_write_access: bool = None, - **kwargs: Any): + def __init__( + self, + url: str, + forward_text: bool = None, + bot_username: str = None, + request_write_access: bool = None, + **kwargs: Any, + ): # Required self.url = url # Optional diff --git a/telegram/message.py b/telegram/message.py index 4149fc2c4..a45a2a439 100644 --- a/telegram/message.py +++ b/telegram/message.py @@ -22,14 +22,36 @@ import sys import datetime from html import escape -from telegram import (Animation, Audio, Contact, Document, Chat, Location, PhotoSize, Sticker, - TelegramObject, User, Video, Voice, Venue, MessageEntity, Game, Invoice, - SuccessfulPayment, VideoNote, PassportData, Poll, InlineKeyboardMarkup, Dice) +from telegram import ( + Animation, + Audio, + Contact, + Document, + Chat, + Location, + PhotoSize, + Sticker, + TelegramObject, + User, + Video, + Voice, + Venue, + MessageEntity, + Game, + Invoice, + SuccessfulPayment, + VideoNote, + PassportData, + Poll, + InlineKeyboardMarkup, + Dice, +) from telegram import ParseMode from telegram.utils.helpers import escape_markdown, to_timestamp, from_timestamp from telegram.utils.types import JSONDict from typing import Any, List, Dict, Optional, Union, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, InputMedia, GameHighScore @@ -37,6 +59,7 @@ _UNDEFINED = object() class Message(TelegramObject): + # fmt: off """This object represents a message. Objects of this class are comparable in terms of equality. Two objects of this class are @@ -232,70 +255,98 @@ class Message(TelegramObject): bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods. """ + # fmt: on _effective_attachment = _UNDEFINED - ATTACHMENT_TYPES = ['audio', 'game', 'animation', 'document', 'photo', 'sticker', 'video', - 'voice', 'video_note', 'contact', 'location', 'venue', 'invoice', - 'successful_payment'] - MESSAGE_TYPES = ['text', 'new_chat_members', 'left_chat_member', 'new_chat_title', - 'new_chat_photo', 'delete_chat_photo', 'group_chat_created', - 'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id', - 'migrate_from_chat_id', 'pinned_message', 'poll', 'dice', - 'passport_data'] + ATTACHMENT_TYPES + ATTACHMENT_TYPES = [ + 'audio', + 'game', + 'animation', + 'document', + 'photo', + 'sticker', + 'video', + 'voice', + 'video_note', + 'contact', + 'location', + 'venue', + 'invoice', + 'successful_payment', + ] + MESSAGE_TYPES = [ + 'text', + 'new_chat_members', + 'left_chat_member', + 'new_chat_title', + 'new_chat_photo', + 'delete_chat_photo', + 'group_chat_created', + 'supergroup_chat_created', + 'channel_chat_created', + 'migrate_to_chat_id', + 'migrate_from_chat_id', + 'pinned_message', + 'poll', + 'dice', + 'passport_data', + ] + ATTACHMENT_TYPES - def __init__(self, - message_id: int, - date: datetime.datetime, - chat: Chat, - from_user: User = None, - forward_from: User = None, - forward_from_chat: Chat = None, - forward_from_message_id: int = None, - forward_date: datetime.datetime = None, - reply_to_message: 'Message' = None, - edit_date: datetime.datetime = None, - text: str = None, - entities: List[MessageEntity] = None, - caption_entities: List[MessageEntity] = None, - audio: Audio = None, - document: Document = None, - game: Game = None, - photo: List[PhotoSize] = None, - sticker: Sticker = None, - video: Video = None, - voice: Voice = None, - video_note: VideoNote = None, - new_chat_members: List[User] = None, - caption: str = None, - contact: Contact = None, - location: Location = None, - venue: Venue = None, - left_chat_member: User = None, - new_chat_title: str = None, - new_chat_photo: List[PhotoSize] = None, - delete_chat_photo: bool = False, - group_chat_created: bool = False, - supergroup_chat_created: bool = False, - channel_chat_created: bool = False, - migrate_to_chat_id: int = None, - migrate_from_chat_id: int = None, - pinned_message: 'Message' = None, - invoice: Invoice = None, - successful_payment: SuccessfulPayment = None, - forward_signature: str = None, - author_signature: str = None, - media_group_id: str = None, - connected_website: str = None, - animation: Animation = None, - passport_data: PassportData = None, - poll: Poll = None, - forward_sender_name: str = None, - reply_markup: InlineKeyboardMarkup = None, - bot: 'Bot' = None, - dice: Dice = None, - via_bot: User = None, - **kwargs: Any): + def __init__( + self, + message_id: int, + date: datetime.datetime, + chat: Chat, + from_user: User = None, + forward_from: User = None, + forward_from_chat: Chat = None, + forward_from_message_id: int = None, + forward_date: datetime.datetime = None, + reply_to_message: 'Message' = None, + edit_date: datetime.datetime = None, + text: str = None, + entities: List[MessageEntity] = None, + caption_entities: List[MessageEntity] = None, + audio: Audio = None, + document: Document = None, + game: Game = None, + photo: List[PhotoSize] = None, + sticker: Sticker = None, + video: Video = None, + voice: Voice = None, + video_note: VideoNote = None, + new_chat_members: List[User] = None, + caption: str = None, + contact: Contact = None, + location: Location = None, + venue: Venue = None, + left_chat_member: User = None, + new_chat_title: str = None, + new_chat_photo: List[PhotoSize] = None, + delete_chat_photo: bool = False, + group_chat_created: bool = False, + supergroup_chat_created: bool = False, + channel_chat_created: bool = False, + migrate_to_chat_id: int = None, + migrate_from_chat_id: int = None, + pinned_message: 'Message' = None, + invoice: Invoice = None, + successful_payment: SuccessfulPayment = None, + forward_signature: str = None, + author_signature: str = None, + media_group_id: str = None, + connected_website: str = None, + animation: Animation = None, + passport_data: PassportData = None, + poll: Poll = None, + forward_sender_name: str = None, + reply_markup: InlineKeyboardMarkup = None, + bot: 'Bot' = None, + dice: Dice = None, + via_bot: User = None, + **kwargs: Any, + ): # Required self.message_id = int(message_id) self.from_user = from_user @@ -413,9 +464,24 @@ class Message(TelegramObject): return cls(bot=bot, **data) @property - def effective_attachment(self) -> Union[Contact, Document, Animation, Game, Invoice, Location, - List[PhotoSize], Sticker, SuccessfulPayment, Venue, - Video, VideoNote, Voice, None]: + def effective_attachment( + self, + ) -> Union[ + Contact, + Document, + Animation, + Game, + Invoice, + Location, + List[PhotoSize], + Sticker, + SuccessfulPayment, + Venue, + Video, + VideoNote, + Voice, + None, + ]: """ :class:`telegram.Audio` or :class:`telegram.Contact` @@ -856,11 +922,8 @@ class Message(TelegramObject): """ return self.bot.forward_message( - chat_id=chat_id, - from_chat_id=self.chat_id, - message_id=self.message_id, - *args, - **kwargs) + chat_id=chat_id, from_chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def edit_text(self, *args: Any, **kwargs: Any) -> Union['Message', bool]: """Shortcut for:: @@ -881,7 +944,8 @@ class Message(TelegramObject): """ return self.bot.edit_message_text( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def edit_caption(self, *args: Any, **kwargs: Any) -> Union['Message', bool]: """Shortcut for:: @@ -902,7 +966,8 @@ class Message(TelegramObject): """ return self.bot.edit_message_caption( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def edit_media(self, media: 'InputMedia', *args: Any, **kwargs: Any) -> Union['Message', bool]: """Shortcut for:: @@ -923,7 +988,8 @@ class Message(TelegramObject): """ return self.bot.edit_message_media( - chat_id=self.chat_id, message_id=self.message_id, media=media, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, media=media, *args, **kwargs + ) def edit_reply_markup(self, *args: Any, **kwargs: Any) -> Union['Message', bool]: """Shortcut for:: @@ -943,7 +1009,8 @@ class Message(TelegramObject): edited Message is returned, otherwise ``True`` is returned. """ return self.bot.edit_message_reply_markup( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def edit_live_location(self, *args: Any, **kwargs: Any) -> Union['Message', bool]: """Shortcut for:: @@ -963,7 +1030,8 @@ class Message(TelegramObject): edited Message is returned, otherwise :obj:`True` is returned. """ return self.bot.edit_message_live_location( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def stop_live_location(self, *args: Any, **kwargs: Any) -> Union['Message', bool]: """Shortcut for:: @@ -983,7 +1051,8 @@ class Message(TelegramObject): edited Message is returned, otherwise :obj:`True` is returned. """ return self.bot.stop_message_live_location( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def set_game_score(self, *args: Any, **kwargs: Any) -> Union['Message', bool]: """Shortcut for:: @@ -1003,7 +1072,8 @@ class Message(TelegramObject): edited Message is returned, otherwise :obj:`True` is returned. """ return self.bot.set_game_score( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def get_game_high_scores(self, *args: Any, **kwargs: Any) -> List['GameHighScore']: """Shortcut for:: @@ -1022,7 +1092,8 @@ class Message(TelegramObject): List[:class:`telegram.GameHighScore`] """ return self.bot.get_game_high_scores( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def delete(self, *args: Any, **kwargs: Any) -> bool: """Shortcut for:: @@ -1037,7 +1108,8 @@ class Message(TelegramObject): """ return self.bot.delete_message( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def stop_poll(self, *args: Any, **kwargs: Any) -> Poll: """Shortcut for:: @@ -1053,7 +1125,8 @@ class Message(TelegramObject): """ return self.bot.stop_poll( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def pin(self, *args: Any, **kwargs: Any) -> bool: """Shortcut for:: @@ -1068,7 +1141,8 @@ class Message(TelegramObject): """ return self.bot.pin_chat_message( - chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs) + chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs + ) def parse_entity(self, entity: MessageEntity) -> str: """Returns the text from a given :class:`telegram.MessageEntity`. @@ -1093,11 +1167,11 @@ class Message(TelegramObject): raise RuntimeError("This Message has no 'text'.") # Is it a narrow build, if so we don't need to convert - if sys.maxunicode == 0xffff: - return self.text[entity.offset:entity.offset + entity.length] + if sys.maxunicode == 0xFFFF: + return self.text[entity.offset : entity.offset + entity.length] else: entity_text = self.text.encode('utf-16-le') - entity_text = entity_text[entity.offset * 2:(entity.offset + entity.length) * 2] + entity_text = entity_text[entity.offset * 2 : (entity.offset + entity.length) * 2] return entity_text.decode('utf-16-le') @@ -1124,11 +1198,11 @@ class Message(TelegramObject): raise RuntimeError("This Message has no 'caption'.") # Is it a narrow build, if so we don't need to convert - if sys.maxunicode == 0xffff: - return self.caption[entity.offset:entity.offset + entity.length] + if sys.maxunicode == 0xFFFF: + return self.caption[entity.offset : entity.offset + entity.length] else: entity_text = self.caption.encode('utf-16-le') - entity_text = entity_text[entity.offset * 2:(entity.offset + entity.length) * 2] + entity_text = entity_text[entity.offset * 2 : (entity.offset + entity.length) * 2] return entity_text.decode('utf-16-le') @@ -1160,7 +1234,8 @@ class Message(TelegramObject): return { entity: self.parse_entity(entity) - for entity in (self.entities or []) if entity.type in types + for entity in (self.entities or []) + if entity.type in types } def parse_caption_entities(self, types: List[str] = None) -> Dict[MessageEntity, str]: @@ -1191,18 +1266,21 @@ class Message(TelegramObject): return { entity: self.parse_caption_entity(entity) - for entity in (self.caption_entities or []) if entity.type in types + for entity in (self.caption_entities or []) + if entity.type in types } @staticmethod - def _parse_html(message_text: Optional[str], - entities: Dict[MessageEntity, str], - urled: bool = False, - offset: int = 0) -> Optional[str]: + def _parse_html( + message_text: Optional[str], + entities: Dict[MessageEntity, str], + urled: bool = False, + offset: int = 0, + ) -> Optional[str]: if message_text is None: return None - if not sys.maxunicode == 0xffff: + if not sys.maxunicode == 0xFFFF: message_text = message_text.encode('utf-16-le') # type: ignore html_text = '' @@ -1215,7 +1293,8 @@ class Message(TelegramObject): if entity not in parsed_entities: nested_entities = { e: t - for (e, t) in sorted_entities if e.offset >= entity.offset + for (e, t) in sorted_entities + if e.offset >= entity.offset and e.offset + e.length <= entity.offset + entity.length and e != entity } @@ -1224,8 +1303,9 @@ class Message(TelegramObject): text = escape(text) if nested_entities: - text = Message._parse_html(text, nested_entities, - urled=urled, offset=entity.offset) + text = Message._parse_html( + text, nested_entities, urled=urled, offset=entity.offset + ) if entity.type == MessageEntity.TEXT_LINK: insert = '{}'.format(entity.url, text) @@ -1241,8 +1321,9 @@ class Message(TelegramObject): insert = '' + text + '' elif entity.type == MessageEntity.PRE: if entity.language: - insert = '
{}
'.format(entity.language, - text) + insert = '
{}
'.format( + entity.language, text + ) else: insert = '
' + text + '
' elif entity.type == MessageEntity.UNDERLINE: @@ -1253,34 +1334,44 @@ class Message(TelegramObject): insert = text if offset == 0: - if sys.maxunicode == 0xffff: - html_text += escape(message_text[last_offset:entity.offset - - offset]) + insert + if sys.maxunicode == 0xFFFF: + html_text += ( + escape(message_text[last_offset : entity.offset - offset]) + insert + ) else: - html_text += escape(message_text[ # type: ignore - last_offset * 2:(entity.offset - offset) * 2].decode('utf-16-le') - ) + insert + html_text += ( + escape( + message_text[ # type: ignore + last_offset * 2 : (entity.offset - offset) * 2 + ].decode('utf-16-le') + ) + + insert + ) else: - if sys.maxunicode == 0xffff: - html_text += message_text[last_offset:entity.offset - offset] + insert + if sys.maxunicode == 0xFFFF: + html_text += message_text[last_offset : entity.offset - offset] + insert else: - html_text += message_text[ # type: ignore - last_offset * 2:(entity.offset - offset) * 2 - ].decode('utf-16-le') + insert + html_text += ( + message_text[ # type: ignore + last_offset * 2 : (entity.offset - offset) * 2 + ].decode('utf-16-le') + + insert + ) last_offset = entity.offset - offset + entity.length if offset == 0: - if sys.maxunicode == 0xffff: + if sys.maxunicode == 0xFFFF: html_text += escape(message_text[last_offset:]) else: html_text += escape( - message_text[last_offset * 2:].decode('utf-16-le')) # type: ignore + message_text[last_offset * 2 :].decode('utf-16-le') # type: ignore + ) else: - if sys.maxunicode == 0xffff: + if sys.maxunicode == 0xFFFF: html_text += message_text[last_offset:] else: - html_text += message_text[last_offset * 2:].decode('utf-16-le') # type: ignore + html_text += message_text[last_offset * 2 :].decode('utf-16-le') # type: ignore return html_text @@ -1339,17 +1430,19 @@ class Message(TelegramObject): return self._parse_html(self.caption, self.parse_caption_entities(), urled=True) @staticmethod - def _parse_markdown(message_text: Optional[str], - entities: Dict[MessageEntity, str], - urled: bool = False, - version: int = 1, - offset: int = 0) -> Optional[str]: + def _parse_markdown( + message_text: Optional[str], + entities: Dict[MessageEntity, str], + urled: bool = False, + version: int = 1, + offset: int = 0, + ) -> Optional[str]: version = int(version) if message_text is None: return None - if not sys.maxunicode == 0xffff: + if not sys.maxunicode == 0xFFFF: message_text = message_text.encode('utf-16-le') # type: ignore markdown_text = '' @@ -1362,7 +1455,8 @@ class Message(TelegramObject): if entity not in parsed_entities: nested_entities = { e: t - for (e, t) in sorted_entities if e.offset >= entity.offset + for (e, t) in sorted_entities + if e.offset >= entity.offset and e.offset + e.length <= entity.offset + entity.length and e != entity } @@ -1373,20 +1467,22 @@ class Message(TelegramObject): if nested_entities: if version < 2: - raise ValueError('Nested entities are not supported for Markdown ' - 'version 1') + raise ValueError( + 'Nested entities are not supported for Markdown ' 'version 1' + ) - text = Message._parse_markdown(text, nested_entities, - urled=urled, offset=entity.offset, - version=version) + text = Message._parse_markdown( + text, nested_entities, urled=urled, offset=entity.offset, version=version + ) if entity.type == MessageEntity.TEXT_LINK: if version == 1: url = entity.url else: # Links need special escaping. Also can't have entities nested within - url = escape_markdown(entity.url, version=version, - entity_type=MessageEntity.TEXT_LINK) + url = escape_markdown( + entity.url, version=version, entity_type=MessageEntity.TEXT_LINK + ) insert = '[{}]({})'.format(text, url) elif entity.type == MessageEntity.TEXT_MENTION and entity.user: insert = '[{}](tg://user?id={})'.format(text, entity.user.id) @@ -1402,12 +1498,18 @@ class Message(TelegramObject): insert = '_' + text + '_' elif entity.type == MessageEntity.CODE: # Monospace needs special escaping. Also can't have entities nested within - insert = '`' + escape_markdown(orig_text, version=version, - entity_type=MessageEntity.CODE) + '`' + insert = ( + '`' + + escape_markdown( + orig_text, version=version, entity_type=MessageEntity.CODE + ) + + '`' + ) elif entity.type == MessageEntity.PRE: # Monospace needs special escaping. Also can't have entities nested within - code = escape_markdown(orig_text, version=version, - entity_type=MessageEntity.PRE) + code = escape_markdown( + orig_text, version=version, entity_type=MessageEntity.PRE + ) if entity.language: prefix = '```' + entity.language + '\n' else: @@ -1418,50 +1520,66 @@ class Message(TelegramObject): insert = prefix + code + '```' elif entity.type == MessageEntity.UNDERLINE: if version == 1: - raise ValueError('Underline entities are not supported for Markdown ' - 'version 1') + raise ValueError( + 'Underline entities are not supported for Markdown ' 'version 1' + ) insert = '__' + text + '__' elif entity.type == MessageEntity.STRIKETHROUGH: if version == 1: - raise ValueError('Strikethrough entities are not supported for Markdown ' - 'version 1') + raise ValueError( + 'Strikethrough entities are not supported for Markdown ' 'version 1' + ) insert = '~' + text + '~' else: insert = text if offset == 0: - if sys.maxunicode == 0xffff: - markdown_text += escape_markdown(message_text[last_offset:entity.offset - - offset], - version=version) + insert + if sys.maxunicode == 0xFFFF: + markdown_text += ( + escape_markdown( + message_text[last_offset : entity.offset - offset], version=version + ) + + insert + ) else: - markdown_text += escape_markdown( - message_text[ # type: ignore - last_offset * 2: (entity.offset - offset) * 2 - ].decode('utf-16-le'), - version=version) + insert + markdown_text += ( + escape_markdown( + message_text[ # type: ignore + last_offset * 2 : (entity.offset - offset) * 2 + ].decode('utf-16-le'), + version=version, + ) + + insert + ) else: - if sys.maxunicode == 0xffff: - markdown_text += message_text[last_offset:entity.offset - offset] + insert + if sys.maxunicode == 0xFFFF: + markdown_text += ( + message_text[last_offset : entity.offset - offset] + insert + ) else: - markdown_text += message_text[ # type: ignore - last_offset * 2:(entity.offset - offset) * 2 - ].decode('utf-16-le') + insert + markdown_text += ( + message_text[ # type: ignore + last_offset * 2 : (entity.offset - offset) * 2 + ].decode('utf-16-le') + + insert + ) last_offset = entity.offset - offset + entity.length if offset == 0: - if sys.maxunicode == 0xffff: + if sys.maxunicode == 0xFFFF: markdown_text += escape_markdown(message_text[last_offset:], version=version) else: markdown_text += escape_markdown( - message_text[last_offset * 2:] .decode('utf-16-le'), # type: ignore - version=version) + message_text[last_offset * 2 :].decode('utf-16-le'), # type: ignore + version=version, + ) else: - if sys.maxunicode == 0xffff: + if sys.maxunicode == 0xFFFF: markdown_text += message_text[last_offset:] else: - markdown_text += message_text[last_offset * 2:].decode('utf-16-le') # type: ignore + markdown_text += message_text[last_offset * 2 :].decode( # type: ignore + 'utf-16-le') return markdown_text @@ -1559,8 +1677,9 @@ class Message(TelegramObject): :obj:`str`: Message caption with caption entities formatted as Markdown. """ - return self._parse_markdown(self.caption, self.parse_caption_entities(), - urled=False, version=2) + return self._parse_markdown( + self.caption, self.parse_caption_entities(), urled=False, version=2 + ) @property def caption_markdown_urled(self) -> str: @@ -1592,5 +1711,6 @@ class Message(TelegramObject): :obj:`str`: Message caption with caption entities formatted as Markdown. """ - return self._parse_markdown(self.caption, self.parse_caption_entities(), - urled=True, version=2) + return self._parse_markdown( + self.caption, self.parse_caption_entities(), urled=True, version=2 + ) diff --git a/telegram/messageentity.py b/telegram/messageentity.py index ff1970b88..3b2119219 100644 --- a/telegram/messageentity.py +++ b/telegram/messageentity.py @@ -58,14 +58,16 @@ class MessageEntity(TelegramObject): """ - def __init__(self, - type: str, - offset: int, - length: int, - url: str = None, - user: User = None, - language: str = None, - **kwargs: Any): + def __init__( + self, + type: str, + offset: int, + length: int, + url: str = None, + user: User = None, + language: str = None, + **kwargs: Any, + ): # Required self.type = type self.offset = offset @@ -119,7 +121,20 @@ class MessageEntity(TelegramObject): STRIKETHROUGH: str = 'strikethrough' """:obj:`str`: 'strikethrough'""" ALL_TYPES: List[str] = [ - MENTION, HASHTAG, CASHTAG, PHONE_NUMBER, BOT_COMMAND, URL, - EMAIL, BOLD, ITALIC, CODE, PRE, TEXT_LINK, TEXT_MENTION, UNDERLINE, STRIKETHROUGH + MENTION, + HASHTAG, + CASHTAG, + PHONE_NUMBER, + BOT_COMMAND, + URL, + EMAIL, + BOLD, + ITALIC, + CODE, + PRE, + TEXT_LINK, + TEXT_MENTION, + UNDERLINE, + STRIKETHROUGH, ] """List[:obj:`str`]: List of all the types.""" diff --git a/telegram/passport/credentials.py b/telegram/passport/credentials.py index b48cb7c19..3fb94cb11 100644 --- a/telegram/passport/credentials.py +++ b/telegram/passport/credentials.py @@ -77,7 +77,7 @@ def decrypt(secret, hash, data): digest.update(secret + hash) secret_hash_hash = digest.finalize() # First 32 chars is our key, next 16 is the initialisation vector - key, iv = secret_hash_hash[:32], secret_hash_hash[32:32 + 16] + key, iv = secret_hash_hash[:32], secret_hash_hash[32 : 32 + 16] # Init a AES-CBC cipher and decrypt the data cipher = Cipher(AES(key), CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() @@ -91,7 +91,7 @@ def decrypt(secret, hash, data): # Raise a error that is caught inside telegram.PassportData and transformed into a warning raise TelegramDecryptionError("Hashes are not equal! {} != {}".format(data_hash, hash)) # Return data without padding - return data[data[0]:] + return data[data[0] :] @no_type_check @@ -129,12 +129,7 @@ class EncryptedCredentials(TelegramObject): """ - def __init__(self, - data: str, - hash: str, - secret: str, - bot: 'Bot' = None, - **kwargs: Any): + def __init__(self, data: str, hash: str, secret: str, bot: 'Bot' = None, **kwargs: Any): # Required self.data = data self.hash = hash @@ -163,11 +158,10 @@ class EncryptedCredentials(TelegramObject): # is the default for OAEP, the algorithm is the default for PHP which is what # Telegram's backend servers run. try: - self._decrypted_secret = self.bot.private_key.decrypt(b64decode(self.secret), OAEP( - mgf=MGF1(algorithm=SHA1()), - algorithm=SHA1(), - label=None - )) + self._decrypted_secret = self.bot.private_key.decrypt( + b64decode(self.secret), + OAEP(mgf=MGF1(algorithm=SHA1()), algorithm=SHA1(), label=None), + ) except ValueError as e: # If decryption fails raise exception raise TelegramDecryptionError(e) @@ -185,10 +179,10 @@ class EncryptedCredentials(TelegramObject): private/public key but can also suggest malformed/tampered data. """ if self._decrypted_data is None: - self._decrypted_data = Credentials.de_json(decrypt_json(self.decrypted_secret, - b64decode(self.hash), - b64decode(self.data)), - self.bot) + self._decrypted_data = Credentials.de_json( + decrypt_json(self.decrypted_secret, b64decode(self.hash), b64decode(self.data)), + self.bot, + ) return self._decrypted_data @@ -246,20 +240,22 @@ class SecureData(TelegramObject): temporary registration. """ - def __init__(self, - personal_details: 'SecureValue' = None, - passport: 'SecureValue' = None, - internal_passport: 'SecureValue' = None, - driver_license: 'SecureValue' = None, - identity_card: 'SecureValue' = None, - address: 'SecureValue' = None, - utility_bill: 'SecureValue' = None, - bank_statement: 'SecureValue' = None, - rental_agreement: 'SecureValue' = None, - passport_registration: 'SecureValue' = None, - temporary_registration: 'SecureValue' = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + personal_details: 'SecureValue' = None, + passport: 'SecureValue' = None, + internal_passport: 'SecureValue' = None, + driver_license: 'SecureValue' = None, + identity_card: 'SecureValue' = None, + address: 'SecureValue' = None, + utility_bill: 'SecureValue' = None, + bank_statement: 'SecureValue' = None, + rental_agreement: 'SecureValue' = None, + passport_registration: 'SecureValue' = None, + temporary_registration: 'SecureValue' = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Optionals self.temporary_registration = temporary_registration self.passport_registration = passport_registration @@ -282,10 +278,12 @@ class SecureData(TelegramObject): if not data: return None - data['temporary_registration'] = SecureValue.de_json(data.get('temporary_registration'), - bot=bot) - data['passport_registration'] = SecureValue.de_json(data.get('passport_registration'), - bot=bot) + data['temporary_registration'] = SecureValue.de_json( + data.get('temporary_registration'), bot=bot + ) + data['passport_registration'] = SecureValue.de_json( + data.get('passport_registration'), bot=bot + ) data['rental_agreement'] = SecureValue.de_json(data.get('rental_agreement'), bot=bot) data['bank_statement'] = SecureValue.de_json(data.get('bank_statement'), bot=bot) data['utility_bill'] = SecureValue.de_json(data.get('utility_bill'), bot=bot) @@ -326,15 +324,17 @@ class SecureValue(TelegramObject): """ - def __init__(self, - data: 'DataCredentials' = None, - front_side: 'FileCredentials' = None, - reverse_side: 'FileCredentials' = None, - selfie: 'FileCredentials' = None, - files: List['FileCredentials'] = None, - translation: List['FileCredentials'] = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + data: 'DataCredentials' = None, + front_side: 'FileCredentials' = None, + reverse_side: 'FileCredentials' = None, + selfie: 'FileCredentials' = None, + files: List['FileCredentials'] = None, + translation: List['FileCredentials'] = None, + bot: 'Bot' = None, + **kwargs: Any, + ): self.data = data self.front_side = front_side self.reverse_side = reverse_side @@ -411,17 +411,17 @@ class DataCredentials(_CredentialsBase): class FileCredentials(_CredentialsBase): """ - These credentials can be used to decrypt encrypted files from the front_side, - reverse_side, selfie and files fields in EncryptedPassportData. + These credentials can be used to decrypt encrypted files from the front_side, + reverse_side, selfie and files fields in EncryptedPassportData. - Args: - file_hash (:obj:`str`): Checksum of encrypted file - secret (:obj:`str`): Secret of encrypted file + Args: + file_hash (:obj:`str`): Checksum of encrypted file + secret (:obj:`str`): Secret of encrypted file - Attributes: - hash (:obj:`str`): Checksum of encrypted file - secret (:obj:`str`): Secret of encrypted file - """ + Attributes: + hash (:obj:`str`): Checksum of encrypted file + secret (:obj:`str`): Secret of encrypted file + """ def __init__(self, file_hash: str, secret: str, **kwargs: Any): super().__init__(file_hash, secret, **kwargs) diff --git a/telegram/passport/data.py b/telegram/passport/data.py index 5bca503d8..b692f3aae 100644 --- a/telegram/passport/data.py +++ b/telegram/passport/data.py @@ -18,6 +18,7 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. from telegram import TelegramObject from typing import Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -43,19 +44,21 @@ class PersonalDetails(TelegramObject): residence. """ - def __init__(self, - first_name: str, - last_name: str, - birth_date: str, - gender: str, - country_code: str, - residence_country_code: str, - first_name_native: str = None, - last_name_native: str = None, - middle_name: str = None, - middle_name_native: str = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + first_name: str, + last_name: str, + birth_date: str, + gender: str, + country_code: str, + residence_country_code: str, + first_name_native: str = None, + last_name_native: str = None, + middle_name: str = None, + middle_name_native: str = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.first_name = first_name self.last_name = last_name @@ -84,15 +87,17 @@ class ResidentialAddress(TelegramObject): post_code (:obj:`str`): Address post code. """ - def __init__(self, - street_line1: str, - street_line2: str, - city: str, - state: str, - country_code: str, - post_code: str, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + street_line1: str, + street_line2: str, + city: str, + state: str, + country_code: str, + post_code: str, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.street_line1 = street_line1 self.street_line2 = street_line2 diff --git a/telegram/passport/encryptedpassportelement.py b/telegram/passport/encryptedpassportelement.py index 6139526a0..f6589b529 100644 --- a/telegram/passport/encryptedpassportelement.py +++ b/telegram/passport/encryptedpassportelement.py @@ -19,12 +19,18 @@ """This module contains an object that represents a Telegram EncryptedPassportElement.""" from base64 import b64decode -from telegram import (IdDocumentData, PassportFile, PersonalDetails, - ResidentialAddress, TelegramObject) +from telegram import ( + IdDocumentData, + PassportFile, + PersonalDetails, + ResidentialAddress, + TelegramObject, +) from telegram.passport.credentials import decrypt_json from telegram.utils.types import JSONDict from typing import List, Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, Credentials @@ -110,20 +116,22 @@ class EncryptedPassportElement(TelegramObject): :obj:`telegram.PassportData.decrypted_data`. """ - def __init__(self, - type: str, - data: PersonalDetails = None, - phone_number: str = None, - email: str = None, - files: List[PassportFile] = None, - front_side: PassportFile = None, - reverse_side: PassportFile = None, - selfie: PassportFile = None, - translation: List[PassportFile] = None, - hash: str = None, - bot: 'Bot' = None, - credentials: 'Credentials' = None, - **kwargs: Any): + def __init__( + self, + type: str, + data: PersonalDetails = None, + phone_number: str = None, + email: str = None, + files: List[PassportFile] = None, + front_side: PassportFile = None, + reverse_side: PassportFile = None, + selfie: PassportFile = None, + translation: List[PassportFile] = None, + hash: str = None, + bot: 'Bot' = None, + credentials: 'Credentials' = None, + **kwargs: Any, + ): # Required self.type = type # Optionals @@ -137,15 +145,21 @@ class EncryptedPassportElement(TelegramObject): self.translation = translation self.hash = hash - self._id_attrs = (self.type, self.data, self.phone_number, self.email, self.files, - self.front_side, self.reverse_side, self.selfie) + self._id_attrs = ( + self.type, + self.data, + self.phone_number, + self.email, + self.files, + self.front_side, + self.reverse_side, + self.selfie, + ) self.bot = bot @classmethod - def de_json(cls, - data: Optional[JSONDict], - bot: 'Bot') -> Optional['EncryptedPassportElement']: + def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['EncryptedPassportElement']: data = cls.parse_data(data) if not data: @@ -160,10 +174,9 @@ class EncryptedPassportElement(TelegramObject): return cls(bot=bot, **data) @classmethod - def de_json_decrypted(cls, - data: Optional[JSONDict], - bot: 'Bot', - credentials: 'Credentials') -> Optional['EncryptedPassportElement']: + def de_json_decrypted( + cls, data: Optional[JSONDict], bot: 'Bot', credentials: 'Credentials' + ) -> Optional['EncryptedPassportElement']: if not data: return None @@ -173,27 +186,41 @@ class EncryptedPassportElement(TelegramObject): if secure_data.data is not None: # If not already decrypted if not isinstance(data['data'], dict): - data['data'] = decrypt_json(b64decode(secure_data.data.secret), - b64decode(secure_data.data.hash), - b64decode(data['data'])) + data['data'] = decrypt_json( + b64decode(secure_data.data.secret), + b64decode(secure_data.data.hash), + b64decode(data['data']), + ) if data['type'] == 'personal_details': data['data'] = PersonalDetails.de_json(data['data'], bot=bot) - elif data['type'] in ('passport', 'internal_passport', - 'driver_license', 'identity_card'): + elif data['type'] in ( + 'passport', + 'internal_passport', + 'driver_license', + 'identity_card', + ): data['data'] = IdDocumentData.de_json(data['data'], bot=bot) elif data['type'] == 'address': data['data'] = ResidentialAddress.de_json(data['data'], bot=bot) - data['files'] = PassportFile.de_list_decrypted(data.get('files'), bot, - secure_data.files) or None - data['front_side'] = PassportFile.de_json_decrypted(data.get('front_side'), bot, - secure_data.front_side) - data['reverse_side'] = PassportFile.de_json_decrypted(data.get('reverse_side'), bot, - secure_data.reverse_side) - data['selfie'] = PassportFile.de_json_decrypted(data.get('selfie'), bot, - secure_data.selfie) - data['translation'] = PassportFile.de_list_decrypted(data.get('translation'), bot, - secure_data.translation) or None + data['files'] = ( + PassportFile.de_list_decrypted(data.get('files'), bot, secure_data.files) or None + ) + data['front_side'] = PassportFile.de_json_decrypted( + data.get('front_side'), bot, secure_data.front_side + ) + data['reverse_side'] = PassportFile.de_json_decrypted( + data.get('reverse_side'), bot, secure_data.reverse_side + ) + data['selfie'] = PassportFile.de_json_decrypted( + data.get('selfie'), bot, secure_data.selfie + ) + data['translation'] = ( + PassportFile.de_list_decrypted( + data.get('translation'), bot, secure_data.translation + ) + or None + ) return cls(bot=bot, **data) diff --git a/telegram/passport/passportdata.py b/telegram/passport/passportdata.py index 4159039aa..45d6f7a25 100644 --- a/telegram/passport/passportdata.py +++ b/telegram/passport/passportdata.py @@ -22,6 +22,7 @@ from telegram import EncryptedCredentials, EncryptedPassportElement, TelegramObj from telegram.utils.types import JSONDict from typing import Any, Optional, List, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, Credentials @@ -50,11 +51,13 @@ class PassportData(TelegramObject): """ - def __init__(self, - data: List[EncryptedPassportElement], - credentials: EncryptedCredentials, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + data: List[EncryptedPassportElement], + credentials: EncryptedCredentials, + bot: 'Bot' = None, + **kwargs: Any, + ): self.data = data self.credentials = credentials @@ -93,9 +96,9 @@ class PassportData(TelegramObject): """ if self._decrypted_data is None: self._decrypted_data = [ - EncryptedPassportElement.de_json_decrypted(element.to_dict(), - self.bot, - self.decrypted_credentials) + EncryptedPassportElement.de_json_decrypted( + element.to_dict(), self.bot, self.decrypted_credentials + ) for element in self.data ] return self._decrypted_data diff --git a/telegram/passport/passportelementerrors.py b/telegram/passport/passportelementerrors.py index d71ff6d1e..cc9ab51b6 100644 --- a/telegram/passport/passportelementerrors.py +++ b/telegram/passport/passportelementerrors.py @@ -77,12 +77,7 @@ class PassportElementErrorDataField(PassportElementError): """ - def __init__(self, - type: str, - field_name: str, - data_hash: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, field_name: str, data_hash: str, message: str, **kwargs: Any): # Required super().__init__('data', type, message) self.field_name = field_name @@ -117,11 +112,7 @@ class PassportElementErrorFile(PassportElementError): """ - def __init__(self, - type: str, - file_hash: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, file_hash: str, message: str, **kwargs: Any): # Required super().__init__('file', type, message) self.file_hash = file_hash @@ -155,17 +146,14 @@ class PassportElementErrorFiles(PassportElementError): """ - def __init__(self, - type: str, - file_hashes: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, file_hashes: str, message: str, **kwargs: Any): # Required super().__init__('files', type, message) self.file_hashes = file_hashes - self._id_attrs = ((self.source, self.type, self.message) - + tuple([file_hash for file_hash in file_hashes])) + self._id_attrs = (self.source, self.type, self.message) + tuple( + [file_hash for file_hash in file_hashes] + ) class PassportElementErrorFrontSide(PassportElementError): @@ -194,11 +182,7 @@ class PassportElementErrorFrontSide(PassportElementError): """ - def __init__(self, - type: str, - file_hash: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, file_hash: str, message: str, **kwargs: Any): # Required super().__init__('front_side', type, message) self.file_hash = file_hash @@ -232,11 +216,7 @@ class PassportElementErrorReverseSide(PassportElementError): """ - def __init__(self, - type: str, - file_hash: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, file_hash: str, message: str, **kwargs: Any): # Required super().__init__('reverse_side', type, message) self.file_hash = file_hash @@ -268,11 +248,7 @@ class PassportElementErrorSelfie(PassportElementError): """ - def __init__(self, - type: str, - file_hash: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, file_hash: str, message: str, **kwargs: Any): # Required super().__init__('selfie', type, message) self.file_hash = file_hash @@ -308,11 +284,7 @@ class PassportElementErrorTranslationFile(PassportElementError): """ - def __init__(self, - type: str, - file_hash: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, file_hash: str, message: str, **kwargs: Any): # Required super().__init__('translation_file', type, message) self.file_hash = file_hash @@ -348,17 +320,14 @@ class PassportElementErrorTranslationFiles(PassportElementError): """ - def __init__(self, - type: str, - file_hashes: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, file_hashes: str, message: str, **kwargs: Any): # Required super().__init__('translation_files', type, message) self.file_hashes = file_hashes - self._id_attrs = ((self.source, self.type, self.message) - + tuple([file_hash for file_hash in file_hashes])) + self._id_attrs = (self.source, self.type, self.message) + tuple( + [file_hash for file_hash in file_hashes] + ) class PassportElementErrorUnspecified(PassportElementError): @@ -383,11 +352,7 @@ class PassportElementErrorUnspecified(PassportElementError): """ - def __init__(self, - type: str, - element_hash: str, - message: str, - **kwargs: Any): + def __init__(self, type: str, element_hash: str, message: str, **kwargs: Any): # Required super().__init__('unspecified', type, message) self.element_hash = element_hash diff --git a/telegram/passport/passportfile.py b/telegram/passport/passportfile.py index 2c892cbe6..4c8a7771d 100644 --- a/telegram/passport/passportfile.py +++ b/telegram/passport/passportfile.py @@ -21,6 +21,7 @@ from telegram import TelegramObject from telegram.utils.types import JSONDict from typing import Any, Optional, List, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot, File, FileCredentials @@ -55,14 +56,16 @@ class PassportFile(TelegramObject): """ - def __init__(self, - file_id: str, - file_unique_id: str, - file_date: int, - file_size: int = None, - bot: 'Bot' = None, - credentials: 'FileCredentials' = None, - **kwargs: Any): + def __init__( + self, + file_id: str, + file_unique_id: str, + file_date: int, + file_size: int = None, + bot: 'Bot' = None, + credentials: 'FileCredentials' = None, + **kwargs: Any, + ): # Required self.file_id = file_id self.file_unique_id = file_unique_id @@ -75,10 +78,9 @@ class PassportFile(TelegramObject): self._id_attrs = (self.file_unique_id,) @classmethod - def de_json_decrypted(cls, - data: Optional[JSONDict], - bot: 'Bot', - credentials: 'FileCredentials') -> Optional['PassportFile']: + def de_json_decrypted( + cls, data: Optional[JSONDict], bot: 'Bot', credentials: 'FileCredentials' + ) -> Optional['PassportFile']: data = cls.parse_data(data) if not data: @@ -89,15 +91,16 @@ class PassportFile(TelegramObject): return cls(bot=bot, **data) @classmethod - def de_list_decrypted(cls, - data: Optional[List[JSONDict]], - bot: 'Bot', - credentials: List['FileCredentials']) -> List[Optional['PassportFile']]: + def de_list_decrypted( + cls, data: Optional[List[JSONDict]], bot: 'Bot', credentials: List['FileCredentials'] + ) -> List[Optional['PassportFile']]: if not data: return [] - return [cls.de_json_decrypted(passport_file, bot, credentials[i]) - for i, passport_file in enumerate(data)] + return [ + cls.de_json_decrypted(passport_file, bot, credentials[i]) + for i, passport_file in enumerate(data) + ] def get_file(self, timeout: int = None, api_kwargs: JSONDict = None) -> 'File': """ diff --git a/telegram/payment/invoice.py b/telegram/payment/invoice.py index f6af09150..5e1751af5 100644 --- a/telegram/payment/invoice.py +++ b/telegram/payment/invoice.py @@ -52,13 +52,15 @@ class Invoice(TelegramObject): """ - def __init__(self, - title: str, - description: str, - start_parameter: str, - currency: str, - total_amount: int, - **kwargs: Any): + def __init__( + self, + title: str, + description: str, + start_parameter: str, + currency: str, + total_amount: int, + **kwargs: Any, + ): self.title = title self.description = description self.start_parameter = start_parameter diff --git a/telegram/payment/orderinfo.py b/telegram/payment/orderinfo.py index 9709acbc6..4512af55d 100644 --- a/telegram/payment/orderinfo.py +++ b/telegram/payment/orderinfo.py @@ -21,6 +21,7 @@ from telegram import TelegramObject, ShippingAddress from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -47,12 +48,14 @@ class OrderInfo(TelegramObject): """ - def __init__(self, - name: str = None, - phone_number: str = None, - email: str = None, - shipping_address: str = None, - **kwargs: Any): + def __init__( + self, + name: str = None, + phone_number: str = None, + email: str = None, + shipping_address: str = None, + **kwargs: Any, + ): self.name = name self.phone_number = phone_number self.email = email diff --git a/telegram/payment/precheckoutquery.py b/telegram/payment/precheckoutquery.py index eb1c1f372..bc09fe47f 100644 --- a/telegram/payment/precheckoutquery.py +++ b/telegram/payment/precheckoutquery.py @@ -21,6 +21,7 @@ from telegram import TelegramObject, User, OrderInfo from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -64,16 +65,18 @@ class PreCheckoutQuery(TelegramObject): """ - def __init__(self, - id: str, - from_user: User, - currency: str, - total_amount: int, - invoice_payload: str, - shipping_option_id: str = None, - order_info: OrderInfo = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + id: str, + from_user: User, + currency: str, + total_amount: int, + invoice_payload: str, + shipping_option_id: str = None, + order_info: OrderInfo = None, + bot: 'Bot' = None, + **kwargs: Any, + ): self.id = id self.from_user = from_user self.currency = currency diff --git a/telegram/payment/shippingaddress.py b/telegram/payment/shippingaddress.py index 91876a139..46a9262bd 100644 --- a/telegram/payment/shippingaddress.py +++ b/telegram/payment/shippingaddress.py @@ -48,14 +48,16 @@ class ShippingAddress(TelegramObject): """ - def __init__(self, - country_code: str, - state: str, - city: str, - street_line1: str, - street_line2: str, - post_code: str, - **kwargs: Any): + def __init__( + self, + country_code: str, + state: str, + city: str, + street_line1: str, + street_line2: str, + post_code: str, + **kwargs: Any, + ): self.country_code = country_code self.state = state self.city = city @@ -63,5 +65,11 @@ class ShippingAddress(TelegramObject): self.street_line2 = street_line2 self.post_code = post_code - self._id_attrs = (self.country_code, self.state, self.city, self.street_line1, - self.street_line2, self.post_code) + self._id_attrs = ( + self.country_code, + self.state, + self.city, + self.street_line1, + self.street_line2, + self.post_code, + ) diff --git a/telegram/payment/shippingoption.py b/telegram/payment/shippingoption.py index f08a8ab95..ac97a4ab7 100644 --- a/telegram/payment/shippingoption.py +++ b/telegram/payment/shippingoption.py @@ -21,6 +21,7 @@ from telegram import TelegramObject from telegram.utils.types import JSONDict from typing import List, Any, TYPE_CHECKING + if TYPE_CHECKING: from telegram import LabeledPrice # noqa diff --git a/telegram/payment/shippingquery.py b/telegram/payment/shippingquery.py index 9a5bb70df..da9e66533 100644 --- a/telegram/payment/shippingquery.py +++ b/telegram/payment/shippingquery.py @@ -21,6 +21,7 @@ from telegram import TelegramObject, User, ShippingAddress from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -51,13 +52,15 @@ class ShippingQuery(TelegramObject): """ - def __init__(self, - id: str, - from_user: User, - invoice_payload: str, - shipping_address: ShippingAddress, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + id: str, + from_user: User, + invoice_payload: str, + shipping_address: ShippingAddress, + bot: 'Bot' = None, + **kwargs: Any, + ): self.id = id self.from_user = from_user self.invoice_payload = invoice_payload diff --git a/telegram/payment/successfulpayment.py b/telegram/payment/successfulpayment.py index a388cb11b..490684b05 100644 --- a/telegram/payment/successfulpayment.py +++ b/telegram/payment/successfulpayment.py @@ -21,6 +21,7 @@ from telegram import TelegramObject, OrderInfo from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING + if TYPE_CHECKING: from telegram import Bot @@ -60,15 +61,17 @@ class SuccessfulPayment(TelegramObject): """ - def __init__(self, - currency: str, - total_amount: int, - invoice_payload: str, - telegram_payment_charge_id: str, - provider_payment_charge_id: str, - shipping_option_id: str = None, - order_info: OrderInfo = None, - **kwargs: Any): + def __init__( + self, + currency: str, + total_amount: int, + invoice_payload: str, + telegram_payment_charge_id: str, + provider_payment_charge_id: str, + shipping_option_id: str = None, + order_info: OrderInfo = None, + **kwargs: Any, + ): self.currency = currency self.total_amount = total_amount self.invoice_payload = invoice_payload diff --git a/telegram/poll.py b/telegram/poll.py index a95b16147..470cdf3cc 100644 --- a/telegram/poll.py +++ b/telegram/poll.py @@ -22,7 +22,7 @@ import sys import datetime -from telegram import (TelegramObject, User, MessageEntity) +from telegram import TelegramObject, User, MessageEntity from telegram.utils.helpers import to_timestamp, from_timestamp from telegram.utils.types import JSONDict from typing import Any, Dict, Optional, List, TYPE_CHECKING @@ -74,6 +74,7 @@ class PollAnswer(TelegramObject): May be empty if the user retracted their vote. """ + def __init__(self, poll_id: str, user: User, option_ids: List[int], **kwargs: Any): self.poll_id = poll_id self.user = user @@ -141,21 +142,23 @@ class Poll(TelegramObject): """ - def __init__(self, - id: str, - question: str, - options: List[PollOption], - total_voter_count: int, - is_closed: bool, - is_anonymous: bool, - type: str, - allows_multiple_answers: bool, - correct_option_id: int = None, - explanation: str = None, - explanation_entities: List[MessageEntity] = None, - open_period: int = None, - close_date: datetime.datetime = None, - **kwargs: Any): + def __init__( + self, + id: str, + question: str, + options: List[PollOption], + total_voter_count: int, + is_closed: bool, + is_anonymous: bool, + type: str, + allows_multiple_answers: bool, + correct_option_id: int = None, + explanation: str = None, + explanation_entities: List[MessageEntity] = None, + open_period: int = None, + close_date: datetime.datetime = None, + **kwargs: Any, + ): self.id = id self.question = question self.options = options @@ -218,11 +221,11 @@ class Poll(TelegramObject): raise RuntimeError("This Poll has no 'explanation'.") # Is it a narrow build, if so we don't need to convert - if sys.maxunicode == 0xffff: - return self.explanation[entity.offset:entity.offset + entity.length] + if sys.maxunicode == 0xFFFF: + return self.explanation[entity.offset : entity.offset + entity.length] else: entity_text = self.explanation.encode('utf-16-le') - entity_text = entity_text[entity.offset * 2:(entity.offset + entity.length) * 2] + entity_text = entity_text[entity.offset * 2 : (entity.offset + entity.length) * 2] return entity_text.decode('utf-16-le') @@ -252,7 +255,8 @@ class Poll(TelegramObject): return { entity: self.parse_explanation_entity(entity) - for entity in (self.explanation_entities or []) if entity.type in types + for entity in (self.explanation_entities or []) + if entity.type in types } REGULAR: str = "regular" diff --git a/telegram/replykeyboardmarkup.py b/telegram/replykeyboardmarkup.py index b0fd5897c..3d72f9a51 100644 --- a/telegram/replykeyboardmarkup.py +++ b/telegram/replykeyboardmarkup.py @@ -64,12 +64,14 @@ class ReplyKeyboardMarkup(ReplyMarkup): """ - def __init__(self, - keyboard: List[List[Union[str, KeyboardButton]]], - resize_keyboard: bool = False, - one_time_keyboard: bool = False, - selective: bool = False, - **kwargs: Any): + def __init__( + self, + keyboard: List[List[Union[str, KeyboardButton]]], + resize_keyboard: bool = False, + one_time_keyboard: bool = False, + selective: bool = False, + **kwargs: Any, + ): # Required self.keyboard = [] for row in keyboard: @@ -101,12 +103,14 @@ class ReplyKeyboardMarkup(ReplyMarkup): return data @classmethod - def from_button(cls, - button: Union[KeyboardButton, str], - resize_keyboard: bool = False, - one_time_keyboard: bool = False, - selective: bool = False, - **kwargs: Any) -> 'ReplyKeyboardMarkup': + def from_button( + cls, + button: Union[KeyboardButton, str], + resize_keyboard: bool = False, + one_time_keyboard: bool = False, + selective: bool = False, + **kwargs: Any, + ) -> 'ReplyKeyboardMarkup': """Shortcut for:: ReplyKeyboardMarkup([[button]], **kwargs) @@ -135,19 +139,23 @@ class ReplyKeyboardMarkup(ReplyMarkup): Defaults to :obj:`False`. **kwargs (:obj:`dict`): Arbitrary keyword arguments. """ - return cls([[button]], - resize_keyboard=resize_keyboard, - one_time_keyboard=one_time_keyboard, - selective=selective, - **kwargs) + return cls( + [[button]], + resize_keyboard=resize_keyboard, + one_time_keyboard=one_time_keyboard, + selective=selective, + **kwargs, + ) @classmethod - def from_row(cls, - button_row: List[Union[str, KeyboardButton]], - resize_keyboard: bool = False, - one_time_keyboard: bool = False, - selective: bool = False, - **kwargs: Any) -> 'ReplyKeyboardMarkup': + def from_row( + cls, + button_row: List[Union[str, KeyboardButton]], + resize_keyboard: bool = False, + one_time_keyboard: bool = False, + selective: bool = False, + **kwargs: Any, + ) -> 'ReplyKeyboardMarkup': """Shortcut for:: ReplyKeyboardMarkup([button_row], **kwargs) @@ -177,19 +185,23 @@ class ReplyKeyboardMarkup(ReplyMarkup): **kwargs (:obj:`dict`): Arbitrary keyword arguments. """ - return cls([button_row], - resize_keyboard=resize_keyboard, - one_time_keyboard=one_time_keyboard, - selective=selective, - **kwargs) + return cls( + [button_row], + resize_keyboard=resize_keyboard, + one_time_keyboard=one_time_keyboard, + selective=selective, + **kwargs, + ) @classmethod - def from_column(cls, - button_column: List[Union[str, KeyboardButton]], - resize_keyboard: bool = False, - one_time_keyboard: bool = False, - selective: bool = False, - **kwargs: Any) -> 'ReplyKeyboardMarkup': + def from_column( + cls, + button_column: List[Union[str, KeyboardButton]], + resize_keyboard: bool = False, + one_time_keyboard: bool = False, + selective: bool = False, + **kwargs: Any, + ) -> 'ReplyKeyboardMarkup': """Shortcut for:: ReplyKeyboardMarkup([[button] for button in button_column], **kwargs) @@ -220,11 +232,13 @@ class ReplyKeyboardMarkup(ReplyMarkup): """ button_grid = [[button] for button in button_column] - return cls(button_grid, - resize_keyboard=resize_keyboard, - one_time_keyboard=one_time_keyboard, - selective=selective, - **kwargs) + return cls( + button_grid, + resize_keyboard=resize_keyboard, + one_time_keyboard=one_time_keyboard, + selective=selective, + **kwargs, + ) def __eq__(self, other: object) -> bool: if isinstance(other, self.__class__): @@ -240,7 +254,11 @@ class ReplyKeyboardMarkup(ReplyMarkup): return super(ReplyKeyboardMarkup, self).__eq__(other) # pylint: disable=no-member def __hash__(self) -> int: - return hash(( - tuple(tuple(button for button in row) for row in self.keyboard), - self.resize_keyboard, self.one_time_keyboard, self.selective - )) + return hash( + ( + tuple(tuple(button for button in row) for row in self.keyboard), + self.resize_keyboard, + self.one_time_keyboard, + self.selective, + ) + ) diff --git a/telegram/replymarkup.py b/telegram/replymarkup.py index c037dd76b..8f5bf8bf1 100644 --- a/telegram/replymarkup.py +++ b/telegram/replymarkup.py @@ -28,4 +28,5 @@ class ReplyMarkup(TelegramObject): detailed use. """ + pass diff --git a/telegram/update.py b/telegram/update.py index 99c406654..c4df39bc4 100644 --- a/telegram/update.py +++ b/telegram/update.py @@ -18,8 +18,16 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains an object that represents a Telegram Update.""" -from telegram import (Message, TelegramObject, InlineQuery, ChosenInlineResult, - CallbackQuery, ShippingQuery, PreCheckoutQuery, Poll) +from telegram import ( + Message, + TelegramObject, + InlineQuery, + ChosenInlineResult, + CallbackQuery, + ShippingQuery, + PreCheckoutQuery, + Poll, +) from telegram.poll import PollAnswer from telegram.utils.types import JSONDict from typing import Any, Optional, TYPE_CHECKING @@ -88,20 +96,22 @@ class Update(TelegramObject): """ - def __init__(self, - update_id: int, - message: Message = None, - edited_message: Message = None, - channel_post: Message = None, - edited_channel_post: Message = None, - inline_query: InlineQuery = None, - chosen_inline_result: ChosenInlineResult = None, - callback_query: CallbackQuery = None, - shipping_query: ShippingQuery = None, - pre_checkout_query: PreCheckoutQuery = None, - poll: Poll = None, - poll_answer: PollAnswer = None, - **kwargs: Any): + def __init__( + self, + update_id: int, + message: Message = None, + edited_message: Message = None, + channel_post: Message = None, + edited_channel_post: Message = None, + inline_query: InlineQuery = None, + chosen_inline_result: ChosenInlineResult = None, + callback_query: CallbackQuery = None, + shipping_query: ShippingQuery = None, + pre_checkout_query: PreCheckoutQuery = None, + poll: Poll = None, + poll_answer: PollAnswer = None, + **kwargs: Any, + ): # Required self.update_id = int(update_id) # Optionals @@ -239,7 +249,8 @@ class Update(TelegramObject): data['edited_message'] = Message.de_json(data.get('edited_message'), bot) data['inline_query'] = InlineQuery.de_json(data.get('inline_query'), bot) data['chosen_inline_result'] = ChosenInlineResult.de_json( - data.get('chosen_inline_result'), bot) + data.get('chosen_inline_result'), bot + ) data['callback_query'] = CallbackQuery.de_json(data.get('callback_query'), bot) data['shipping_query'] = ShippingQuery.de_json(data.get('shipping_query'), bot) data['pre_checkout_query'] = PreCheckoutQuery.de_json(data.get('pre_checkout_query'), bot) diff --git a/telegram/user.py b/telegram/user.py index 633d0b381..d4b5c8588 100644 --- a/telegram/user.py +++ b/telegram/user.py @@ -67,18 +67,20 @@ class User(TelegramObject): """ - def __init__(self, - id: int, - first_name: str, - is_bot: bool, - last_name: str = None, - username: str = None, - language_code: str = None, - can_join_groups: bool = None, - can_read_all_group_messages: bool = None, - supports_inline_queries: bool = None, - bot: 'Bot' = None, - **kwargs: Any): + def __init__( + self, + id: int, + first_name: str, + is_bot: bool, + last_name: str = None, + username: str = None, + language_code: str = None, + can_join_groups: bool = None, + can_read_all_group_messages: bool = None, + supports_inline_queries: bool = None, + bot: 'Bot' = None, + **kwargs: Any, + ): # Required self.id = int(id) self.first_name = first_name diff --git a/telegram/utils/deprecate.py b/telegram/utils/deprecate.py index 91d704614..2d920321e 100644 --- a/telegram/utils/deprecate.py +++ b/telegram/utils/deprecate.py @@ -20,6 +20,7 @@ import warnings from typing import Callable, TypeVar, Any + RT = TypeVar('RT') @@ -34,7 +35,8 @@ def warn_deprecate_obj(old: str, new: str, stacklevel: int = 3) -> None: warnings.warn( '{} is being deprecated, please use {} from now on.'.format(old, new), category=TelegramDeprecationWarning, - stacklevel=stacklevel) + stacklevel=stacklevel, + ) def deprecate(func: Callable[..., RT], old: str, new: str) -> Callable[..., RT]: diff --git a/telegram/utils/helpers.py b/telegram/utils/helpers.py index 296ba3bfb..3d89d8279 100644 --- a/telegram/utils/helpers.py +++ b/telegram/utils/helpers.py @@ -36,13 +36,16 @@ except ImportError: from telegram.utils.types import JSONDict from typing import Union, Any, Optional, Dict, DefaultDict, Tuple, TYPE_CHECKING + if TYPE_CHECKING: from telegram import MessageEntity # From https://stackoverflow.com/questions/2549939/get-signal-names-from-numbers-in-python -_signames = {v: k - for k, v in reversed(sorted(vars(signal).items())) - if k.startswith('SIG') and not k.startswith('SIG_')} +_signames = { + v: k + for k, v in reversed(sorted(vars(signal).items())) + if k.startswith('SIG') and not k.startswith('SIG_') +} def get_signal_name(signum: int) -> str: @@ -89,8 +92,11 @@ def _datetime_to_float_timestamp(dt_obj: dtm.datetime) -> float: return dt_obj.timestamp() -def to_float_timestamp(t: Union[int, float, dtm.timedelta, dtm.datetime, dtm.time], - reference_timestamp: float = None, tzinfo: pytz.BaseTzInfo = None) -> float: +def to_float_timestamp( + t: Union[int, float, dtm.timedelta, dtm.datetime, dtm.time], + reference_timestamp: float = None, + tzinfo: pytz.BaseTzInfo = None, +) -> float: """ Converts a given time object to a float POSIX timestamp. Used to convert different time specifications to a common format. The time object @@ -171,21 +177,27 @@ def to_float_timestamp(t: Union[int, float, dtm.timedelta, dtm.datetime, dtm.tim raise TypeError('Unable to convert {} object to timestamp'.format(type(t).__name__)) -def to_timestamp(dt_obj: Union[int, float, dtm.timedelta, dtm.datetime, dtm.time, None], - reference_timestamp: float = None, - tzinfo: pytz.BaseTzInfo = None) -> Optional[int]: +def to_timestamp( + dt_obj: Union[int, float, dtm.timedelta, dtm.datetime, dtm.time, None], + reference_timestamp: float = None, + tzinfo: pytz.BaseTzInfo = None, +) -> Optional[int]: """ Wrapper over :func:`to_float_timestamp` which returns an integer (the float value truncated down to the nearest integer). See the documentation for :func:`to_float_timestamp` for more details. """ - return (int(to_float_timestamp(dt_obj, reference_timestamp, tzinfo)) - if dt_obj is not None else None) + return ( + int(to_float_timestamp(dt_obj, reference_timestamp, tzinfo)) + if dt_obj is not None + else None + ) -def from_timestamp(unixtime: Optional[int], - tzinfo: dtm.tzinfo = pytz.utc) -> Optional[dtm.datetime]: +def from_timestamp( + unixtime: Optional[int], tzinfo: dtm.tzinfo = pytz.utc +) -> Optional[dtm.datetime]: """ Converts an (integer) unix timestamp to a timezone aware datetime object. :obj:`None`s are left alone (i.e. ``from_timestamp(None)`` is :obj:`None`). @@ -207,6 +219,7 @@ def from_timestamp(unixtime: Optional[int], else: return dtm.datetime.utcfromtimestamp(unixtime) + # -------- end -------- @@ -304,19 +317,17 @@ def create_deep_linked_url(bot_username: str, payload: str = None, group: bool = raise ValueError("The deep-linking payload must not exceed 64 characters.") if not re.match(r'^[A-Za-z0-9_-]+$', payload): - raise ValueError("Only the following characters are allowed for deep-linked " - "URLs: A-Z, a-z, 0-9, _ and -") + raise ValueError( + "Only the following characters are allowed for deep-linked " + "URLs: A-Z, a-z, 0-9, _ and -" + ) if group: key = 'startgroup' else: key = 'start' - return '{}?{}={}'.format( - base_url, - key, - payload - ) + return '{}?{}={}'.format(base_url, key, payload) def encode_conversations_to_json(conversations: Dict[str, Dict[Tuple, Any]]) -> str: @@ -424,6 +435,7 @@ class DefaultValue: Args: value (:obj:`obj`): The value of the default argument """ + def __init__(self, value: Any = None): self.value = value diff --git a/telegram/utils/promise.py b/telegram/utils/promise.py index 49ebb5f18..02905ef60 100644 --- a/telegram/utils/promise.py +++ b/telegram/utils/promise.py @@ -22,6 +22,7 @@ import logging from threading import Event from telegram.utils.types import JSONDict, HandlerArg from typing import Callable, List, Tuple, Optional, Union, TypeVar + RT = TypeVar('RT') @@ -51,12 +52,14 @@ class Promise: """ # TODO: Remove error_handling parameter once we drop the @run_async decorator - def __init__(self, - pooled_function: Callable[..., RT], - args: Union[List, Tuple], - kwargs: JSONDict, - update: HandlerArg = None, - error_handling: bool = True): + def __init__( + self, + pooled_function: Callable[..., RT], + args: Union[List, Tuple], + kwargs: JSONDict, + update: HandlerArg = None, + error_handling: bool = True, + ): self.pooled_function = pooled_function self.args = args self.kwargs = kwargs diff --git a/telegram/utils/request.py b/telegram/utils/request.py index d7d8fcca3..ea45d2147 100644 --- a/telegram/utils/request.py +++ b/telegram/utils/request.py @@ -43,18 +43,30 @@ except ImportError: # pragma: no cover from urllib3.connection import HTTPConnection # type: ignore[no-redef] from urllib3.util.timeout import Timeout # type: ignore[no-redef] from urllib3.fields import RequestField # type: ignore[no-redef] - warnings.warn('python-telegram-bot is using upstream urllib3. This is allowed but not ' - 'supported by python-telegram-bot maintainers.') + + warnings.warn( + 'python-telegram-bot is using upstream urllib3. This is allowed but not ' + 'supported by python-telegram-bot maintainers.' + ) except ImportError: warnings.warn( "python-telegram-bot wasn't properly installed. Please refer to README.rst on " - "how to properly install.") + "how to properly install." + ) raise -from telegram import (InputFile, TelegramError, InputMedia) -from telegram.error import (Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated, - RetryAfter, InvalidToken, Conflict) +from telegram import InputFile, TelegramError, InputMedia +from telegram.error import ( + Unauthorized, + NetworkError, + TimedOut, + BadRequest, + ChatMigrated, + RetryAfter, + InvalidToken, + Conflict, +) from telegram.utils.types import JSONDict from typing import Any, Union @@ -98,28 +110,34 @@ class Request: """ - def __init__(self, - con_pool_size: int = 1, - proxy_url: str = None, - urllib3_proxy_kwargs: JSONDict = None, - connect_timeout: float = 5., - read_timeout: float = 5.): + def __init__( + self, + con_pool_size: int = 1, + proxy_url: str = None, + urllib3_proxy_kwargs: JSONDict = None, + connect_timeout: float = 5.0, + read_timeout: float = 5.0, + ): if urllib3_proxy_kwargs is None: urllib3_proxy_kwargs = dict() self._connect_timeout = connect_timeout sockopts = HTTPConnection.default_socket_options + [ - (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)] + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) + ] # TODO: Support other platforms like mac and windows. if 'linux' in sys.platform: - sockopts.append((socket.IPPROTO_TCP, - socket.TCP_KEEPIDLE, 120)) # pylint: disable=no-member - sockopts.append((socket.IPPROTO_TCP, - socket.TCP_KEEPINTVL, 30)) # pylint: disable=no-member - sockopts.append((socket.IPPROTO_TCP, - socket.TCP_KEEPCNT, 8)) # pylint: disable=no-member + sockopts.append( + (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 120) + ) # pylint: disable=no-member + sockopts.append( + (socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30) + ) # pylint: disable=no-member + sockopts.append( + (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 8) + ) # pylint: disable=no-member self._con_pool_size = con_pool_size @@ -128,8 +146,8 @@ class Request: cert_reqs='CERT_REQUIRED', ca_certs=certifi.where(), socket_options=sockopts, - timeout=urllib3.Timeout( - connect=self._connect_timeout, read=read_timeout, total=None)) + timeout=urllib3.Timeout(connect=self._connect_timeout, read=read_timeout, total=None), + ) # Set a proxy according to the following order: # * proxy defined in proxy_url (+ urllib3_proxy_kwargs) @@ -140,9 +158,12 @@ class Request: if not proxy_url: proxy_url = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy') - self._con_pool: Union[urllib3.PoolManager, appengine.AppEngineManager, - 'SOCKSProxyManager', # noqa: F821 - urllib3.ProxyManager] = None # type: ignore + self._con_pool: Union[ + urllib3.PoolManager, + appengine.AppEngineManager, + 'SOCKSProxyManager', # noqa: F821 + urllib3.ProxyManager, + ] = None # type: ignore if not proxy_url: if appengine.is_appengine_sandbox(): # Use URLFetch service if running in App Engine @@ -253,18 +274,17 @@ class Request: elif resp.status == 409: raise Conflict(message) elif resp.status == 413: - raise NetworkError('File too large. Check telegram api limits ' - 'https://core.telegram.org/bots/api#senddocument') + raise NetworkError( + 'File too large. Check telegram api limits ' + 'https://core.telegram.org/bots/api#senddocument' + ) elif resp.status == 502: raise NetworkError('Bad Gateway') else: raise NetworkError('{} ({})'.format(message, resp.status)) - def post(self, - url: str, - data: JSONDict, - timeout: float = None) -> Union[JSONDict, bool]: + def post(self, url: str, data: JSONDict, timeout: float = None) -> Union[JSONDict, bool]: """Request an URL. Args: @@ -322,10 +342,13 @@ class Request: if files: result = self._request_wrapper('POST', url, fields=data, **urlopen_kwargs) else: - result = self._request_wrapper('POST', url, - body=json.dumps(data).encode('utf-8'), - headers={'Content-Type': 'application/json'}, - **urlopen_kwargs) + result = self._request_wrapper( + 'POST', + url, + body=json.dumps(data).encode('utf-8'), + headers={'Content-Type': 'application/json'}, + **urlopen_kwargs, + ) return self._parse(result) diff --git a/telegram/utils/webhookhandler.py b/telegram/utils/webhookhandler.py index 9f012b9c1..0283cbd65 100644 --- a/telegram/utils/webhookhandler.py +++ b/telegram/utils/webhookhandler.py @@ -36,17 +36,15 @@ from queue import Queue from telegram.utils.types import JSONDict from typing import Any, TYPE_CHECKING from tornado import httputil + if TYPE_CHECKING: from telegram import Bot class WebhookServer: - - def __init__(self, - listen: str, - port: int, - webhook_app: 'WebhookAppClass', - ssl_ctx: SSLContext): + def __init__( + self, listen: str, port: int, webhook_app: 'WebhookAppClass', ssl_ctx: SSLContext + ): self.http_server = HTTPServer(webhook_app, ssl_options=ssl_ctx) self.listen = listen self.port = port @@ -81,17 +79,26 @@ class WebhookServer: def handle_error(self, request: Any, client_address: str) -> None: """Handle an error gracefully.""" - self.logger.debug('Exception happened during processing of request from %s', - client_address, exc_info=True) + self.logger.debug( + 'Exception happened during processing of request from %s', + client_address, + exc_info=True, + ) def _ensure_event_loop(self, force_event_loop: bool = False) -> None: """If there's no asyncio event loop set for the current thread - create one.""" try: loop = asyncio.get_event_loop() - if (not force_event_loop and os.name == 'nt' and sys.version_info >= (3, 8) - and isinstance(loop, asyncio.ProactorEventLoop)): - raise TypeError('`ProactorEventLoop` is incompatible with ' - 'Tornado. Please switch to `SelectorEventLoop`.') + if ( + not force_event_loop + and os.name == 'nt' + and sys.version_info >= (3, 8) + and isinstance(loop, asyncio.ProactorEventLoop) + ): + raise TypeError( + '`ProactorEventLoop` is incompatible with ' + 'Tornado. Please switch to `SelectorEventLoop`.' + ) except RuntimeError: # Python 3.8 changed default asyncio event loop implementation on windows # from SelectorEventLoop to ProactorEventLoop. At the time of this writing @@ -106,15 +113,20 @@ class WebhookServer: # Ideally, we would want to check that Tornado actually raises the expected # NotImplementedError, but it's not possible to cleanly recover from that # exception in current Tornado version. - if (os.name == 'nt' - and sys.version_info >= (3, 8) - # OS+version check makes hasattr check redundant, but just to be sure - and hasattr(asyncio, 'WindowsProactorEventLoopPolicy') - and (isinstance( - asyncio.get_event_loop_policy(), - asyncio.WindowsProactorEventLoopPolicy))): # pylint: disable=E1101 + if ( + os.name == 'nt' + and sys.version_info >= (3, 8) + # OS+version check makes hasattr check redundant, but just to be sure + and hasattr(asyncio, 'WindowsProactorEventLoopPolicy') + and ( + isinstance( + asyncio.get_event_loop_policy(), asyncio.WindowsProactorEventLoopPolicy + ) + ) + ): # pylint: disable=E1101 self.logger.debug( - 'Applying Tornado asyncio event loop fix for Python 3.8+ on Windows') + 'Applying Tornado asyncio event loop fix for Python 3.8+ on Windows' + ) loop = asyncio.SelectorEventLoop() else: loop = asyncio.new_event_loop() @@ -122,16 +134,9 @@ class WebhookServer: class WebhookAppClass(tornado.web.Application): - - def __init__(self, - webhook_path: str, - bot: 'Bot', - update_queue: Queue): + def __init__(self, webhook_path: str, bot: 'Bot', update_queue: Queue): self.shared_objects = {"bot": bot, "update_queue": update_queue} - handlers = [ - (r"{}/?".format(webhook_path), WebhookHandler, - self.shared_objects) - ] # noqa + handlers = [(r"{}/?".format(webhook_path), WebhookHandler, self.shared_objects)] # noqa tornado.web.Application.__init__(self, handlers) def log_request(self, handler: tornado.web.RequestHandler) -> None: @@ -142,10 +147,12 @@ class WebhookAppClass(tornado.web.Application): class WebhookHandler(tornado.web.RequestHandler): SUPPORTED_METHODS = ["POST"] - def __init__(self, - application: tornado.web.Application, - request: httputil.HTTPServerRequest, - **kwargs: JSONDict): + def __init__( + self, + application: tornado.web.Application, + request: httputil.HTTPServerRequest, + **kwargs: JSONDict, + ): super().__init__(application, request, **kwargs) self.logger = logging.getLogger(__name__) @@ -188,6 +195,7 @@ class WebhookHandler(tornado.web.RequestHandler): """ super().write_error(status_code, **kwargs) - self.logger.debug("{} - - {}".format(self.request.remote_ip, - "Exception in WebhookHandler"), - exc_info=kwargs['exc_info']) + self.logger.debug( + "{} - - {}".format(self.request.remote_ip, "Exception in WebhookHandler"), + exc_info=kwargs['exc_info'], + ) diff --git a/telegram/webhookinfo.py b/telegram/webhookinfo.py index 9dfc81bb4..9b1dd8c3a 100644 --- a/telegram/webhookinfo.py +++ b/telegram/webhookinfo.py @@ -59,15 +59,17 @@ class WebhookInfo(TelegramObject): """ - def __init__(self, - url: str, - has_custom_certificate: bool, - pending_update_count: int, - last_error_date: int = None, - last_error_message: str = None, - max_connections: int = None, - allowed_updates: List[str] = None, - **kwargs: Any): + def __init__( + self, + url: str, + has_custom_certificate: bool, + pending_update_count: int, + last_error_date: int = None, + last_error_message: str = None, + max_connections: int = None, + allowed_updates: List[str] = None, + **kwargs: Any, + ): # Required self.url = url self.has_custom_certificate = has_custom_certificate diff --git a/tests/bots.py b/tests/bots.py index 93dd2bf59..f79078a8d 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -36,16 +36,17 @@ FALLBACKS = [ 'super_group_id': '-1001310911135', 'channel_id': '@pythontelegrambottests', 'bot_name': 'PTB tests fallback 1', - 'bot_username': '@ptb_fallback_1_bot' - }, { + 'bot_username': '@ptb_fallback_1_bot', + }, + { 'token': '558194066:AAEEylntuKSLXj9odiv3TnX7Z5KY2J3zY3M', 'payment_provider_token': '284685063:TEST:YjEwODQwMTFmNDcy', 'chat_id': '675666224', 'super_group_id': '-1001221216830', 'channel_id': '@pythontelegrambottests', 'bot_name': 'PTB tests fallback 2', - 'bot_username': '@ptb_fallback_2_bot' - } + 'bot_username': '@ptb_fallback_2_bot', + }, ] GITHUB_ACTION = os.getenv('GITHUB_ACTION', None) diff --git a/tests/conftest.py b/tests/conftest.py index 4f6926b89..6afe0912a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,9 +27,19 @@ from time import sleep import pytest import pytz -from telegram import (Bot, Message, User, Chat, MessageEntity, Update, - InlineQuery, CallbackQuery, ShippingQuery, PreCheckoutQuery, - ChosenInlineResult) +from telegram import ( + Bot, + Message, + User, + Chat, + MessageEntity, + Update, + InlineQuery, + CallbackQuery, + ShippingQuery, + PreCheckoutQuery, + ChosenInlineResult, +) from telegram.ext import Dispatcher, JobQueue, Updater, MessageFilter, Defaults, UpdateFilter from telegram.error import BadRequest from tests.bots import get_bot @@ -197,13 +207,15 @@ def make_message(text, **kwargs): :param text: (str) message text :return: a (fake) ``telegram.Message`` """ - return Message(message_id=1, - from_user=kwargs.pop('user', User(id=1, first_name='', is_bot=False)), - date=kwargs.pop('date', DATE), - chat=kwargs.pop('chat', Chat(id=1, type='')), - text=text, - bot=kwargs.pop('bot', make_bot(get_bot())), - **kwargs) + return Message( + message_id=1, + from_user=kwargs.pop('user', User(id=1, first_name='', is_bot=False)), + date=kwargs.pop('date', DATE), + chat=kwargs.pop('chat', Chat(id=1, type='')), + text=text, + bot=kwargs.pop('bot', make_bot(get_bot())), + **kwargs, + ) def make_command_message(text, **kwargs): @@ -219,9 +231,15 @@ def make_command_message(text, **kwargs): """ match = re.search(CMD_PATTERN, text) - entities = [MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=match.start(0), - length=len(match.group(0)))] if match else [] + entities = ( + [ + MessageEntity( + type=MessageEntity.BOT_COMMAND, offset=match.start(0), length=len(match.group(0)) + ) + ] + if match + else [] + ) return make_message(text, entities=entities, **kwargs) @@ -253,12 +271,11 @@ def make_command_update(message, edited=False, **kwargs): return make_message_update(message, make_command_message, edited, **kwargs) -@pytest.fixture(scope='class', - params=[ - {'class': MessageFilter}, - {'class': UpdateFilter} - ], - ids=['MessageFilter', 'UpdateFilter']) +@pytest.fixture( + scope='class', + params=[{'class': MessageFilter}, {'class': UpdateFilter}], + ids=['MessageFilter', 'UpdateFilter'], +) def mock_filter(request): class MockFilter(request.param['class']): def __init__(self): @@ -280,7 +297,7 @@ def get_false_update_fixture_decorator_params(): {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] ids = tuple(key for kwargs in params for key in kwargs) return {'params': params, 'ids': ids} diff --git a/tests/plugin_github_group.py b/tests/plugin_github_group.py index c61a6eea1..a4ec14973 100644 --- a/tests/plugin_github_group.py +++ b/tests/plugin_github_group.py @@ -37,8 +37,7 @@ def terminal_summary_wrapper(original, plugin_name): def pytest_configure(config): for hookimpl in config.pluginmanager.hook.pytest_terminal_summary._nonwrappers: if hookimpl.plugin_name in fold_plugins.keys(): - hookimpl.function = terminal_summary_wrapper(hookimpl.function, - hookimpl.plugin_name) + hookimpl.function = terminal_summary_wrapper(hookimpl.function, hookimpl.plugin_name) terminal = None diff --git a/tests/test_animation.py b/tests/test_animation.py index e73d600e9..774923feb 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -35,8 +35,9 @@ def animation_file(): @pytest.fixture(scope='class') def animation(bot, chat_id): with open('tests/data/game.gif', 'rb') as f: - return bot.send_animation(chat_id, animation=f, timeout=50, - thumb=open('tests/data/thumb.jpg', 'rb')).animation + return bot.send_animation( + chat_id, animation=f, timeout=50, thumb=open('tests/data/thumb.jpg', 'rb') + ).animation class TestAnimation: @@ -69,10 +70,17 @@ class TestAnimation: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_all_args(self, bot, chat_id, animation_file, animation, thumb_file): - message = bot.send_animation(chat_id, animation_file, duration=self.duration, - width=self.width, height=self.height, caption=self.caption, - parse_mode='Markdown', disable_notification=False, - thumb=thumb_file) + message = bot.send_animation( + chat_id, + animation_file, + duration=self.duration, + width=self.width, + height=self.height, + caption=self.caption, + parse_mode='Markdown', + disable_notification=False, + thumb=thumb_file, + ) assert isinstance(message.animation, Animation) assert isinstance(message.animation.file_id, str) @@ -101,8 +109,9 @@ class TestAnimation: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_animation_url_file(self, bot, chat_id, animation): - message = bot.send_animation(chat_id=chat_id, animation=self.animation_file_url, - caption=self.caption) + message = bot.send_animation( + chat_id=chat_id, animation=self.animation_file_url, caption=self.caption + ) assert message.caption == self.caption @@ -134,8 +143,9 @@ class TestAnimation: def test_send_animation_default_parse_mode_2(self, default_bot, chat_id, animation_file): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_animation(chat_id, animation_file, caption=test_markdown_string, - parse_mode=None) + message = default_bot.send_animation( + chat_id, animation_file, caption=test_markdown_string, parse_mode=None + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -145,8 +155,9 @@ class TestAnimation: def test_send_animation_default_parse_mode_3(self, default_bot, chat_id, animation_file): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_animation(chat_id, animation_file, caption=test_markdown_string, - parse_mode='HTML') + message = default_bot.send_animation( + chat_id, animation_file, caption=test_markdown_string, parse_mode='HTML' + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -175,7 +186,7 @@ class TestAnimation: 'thumb': animation.thumb.to_dict(), 'file_name': self.file_name, 'mime_type': self.mime_type, - 'file_size': self.file_size + 'file_size': self.file_size, } animation = Animation.de_json(json_dict, bot) assert animation.file_id == self.animation_file_id @@ -225,10 +236,14 @@ class TestAnimation: assert animation.get_file() def test_equality(self): - a = Animation(self.animation_file_id, self.animation_file_unique_id, - self.height, self.width, self.duration) - b = Animation('', self.animation_file_unique_id, - self.height, self.width, self.duration) + a = Animation( + self.animation_file_id, + self.animation_file_unique_id, + self.height, + self.width, + self.duration, + ) + b = Animation('', self.animation_file_unique_id, self.height, self.width, self.duration) d = Animation('', '', 0, 0, 0) e = Voice(self.animation_file_id, self.animation_file_unique_id, 0) diff --git a/tests/test_audio.py b/tests/test_audio.py index 54deb4e5b..075d669f3 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -35,8 +35,9 @@ def audio_file(): @pytest.fixture(scope='class') def audio(bot, chat_id): with open('tests/data/telegram.mp3', 'rb') as f: - return bot.send_audio(chat_id, audio=f, timeout=50, - thumb=open('tests/data/thumb.jpg', 'rb')).audio + return bot.send_audio( + chat_id, audio=f, timeout=50, thumb=open('tests/data/thumb.jpg', 'rb') + ).audio class TestAudio: @@ -76,10 +77,17 @@ class TestAudio: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_all_args(self, bot, chat_id, audio_file, thumb_file): - message = bot.send_audio(chat_id, audio=audio_file, caption=self.caption, - duration=self.duration, performer=self.performer, - title=self.title, disable_notification=False, - parse_mode='Markdown', thumb=thumb_file) + message = bot.send_audio( + chat_id, + audio=audio_file, + caption=self.caption, + duration=self.duration, + performer=self.performer, + title=self.title, + disable_notification=False, + parse_mode='Markdown', + thumb=thumb_file, + ) assert message.caption == self.caption.replace('*', '') @@ -159,8 +167,9 @@ class TestAudio: def test_send_audio_default_parse_mode_2(self, default_bot, chat_id, audio_file, thumb_file): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_audio(chat_id, audio_file, caption=test_markdown_string, - parse_mode=None) + message = default_bot.send_audio( + chat_id, audio_file, caption=test_markdown_string, parse_mode=None + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -170,8 +179,9 @@ class TestAudio: def test_send_audio_default_parse_mode_3(self, default_bot, chat_id, audio_file, thumb_file): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_audio(chat_id, audio_file, caption=test_markdown_string, - parse_mode='HTML') + message = default_bot.send_audio( + chat_id, audio_file, caption=test_markdown_string, parse_mode='HTML' + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -185,7 +195,7 @@ class TestAudio: 'caption': self.caption, 'mime_type': self.mime_type, 'file_size': self.file_size, - 'thumb': audio.thumb.to_dict() + 'thumb': audio.thumb.to_dict(), } json_audio = Audio.de_json(json_dict, bot) diff --git a/tests/test_bot.py b/tests/test_bot.py index b6d7f6383..f12e51671 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -23,10 +23,26 @@ from platform import python_implementation import pytest from flaky import flaky -from telegram import (Bot, Update, ChatAction, TelegramError, User, InlineKeyboardMarkup, - InlineKeyboardButton, InlineQueryResultArticle, InputTextMessageContent, - ShippingOption, LabeledPrice, ChatPermissions, Poll, BotCommand, - InlineQueryResultDocument, Dice, MessageEntity, ParseMode) +from telegram import ( + Bot, + Update, + ChatAction, + TelegramError, + User, + InlineKeyboardMarkup, + InlineKeyboardButton, + InlineQueryResultArticle, + InputTextMessageContent, + ShippingOption, + LabeledPrice, + ChatPermissions, + Poll, + BotCommand, + InlineQueryResultDocument, + Dice, + MessageEntity, + ParseMode, +) from telegram.constants import MAX_INLINE_QUERY_RESULTS from telegram.error import BadRequest, InvalidToken, NetworkError, RetryAfter from telegram.utils.helpers import from_timestamp, escape_markdown, to_timestamp @@ -38,10 +54,16 @@ HIGHSCORE_DELTA = 1450000000 @pytest.fixture(scope='class') def message(bot, chat_id): - to_reply_to = bot.send_message(chat_id, 'Text', - disable_web_page_preview=True, disable_notification=True) - return bot.send_message(chat_id, 'Text', reply_to_message_id=to_reply_to.message_id, - disable_web_page_preview=True, disable_notification=True) + to_reply_to = bot.send_message( + chat_id, 'Text', disable_web_page_preview=True, disable_notification=True + ) + return bot.send_message( + chat_id, + 'Text', + reply_to_message_id=to_reply_to.message_id, + disable_web_page_preview=True, + disable_notification=True, + ) @pytest.fixture(scope='class') @@ -59,8 +81,10 @@ def inline_results_callback(page=None): if not page: return [InlineQueryResultArticle(i, str(i), None) for i in range(1, 254)] elif page <= 5: - return [InlineQueryResultArticle(i, str(i), None) - for i in range(page * 5 + 1, (page + 1) * 5 + 1)] + return [ + InlineQueryResultArticle(i, str(i), None) + for i in range(page * 5 + 1, (page + 1) * 5 + 1) + ] return None @@ -70,15 +94,18 @@ def inline_results(): class TestBot: - @pytest.mark.parametrize('token', argvalues=[ - '123', - '12a:abcd1234', - '12:abcd1234', - '1234:abcd1234\n', - ' 1234:abcd1234', - ' 1234:abcd1234\r', - '1234:abcd 1234' - ]) + @pytest.mark.parametrize( + 'token', + argvalues=[ + '123', + '12a:abcd1234', + '12:abcd1234', + '1234:abcd1234\n', + ' 1234:abcd1234', + ' 1234:abcd1234\r', + '1234:abcd 1234', + ], + ) def test_invalid_token(self, token): with pytest.raises(InvalidToken, match='Invalid token'): Bot(token) @@ -166,9 +193,15 @@ class TestBot: address = 'address' foursquare_id = 'foursquare id' foursquare_type = 'foursquare type' - message = bot.send_venue(chat_id=chat_id, title=title, address=address, latitude=latitude, - longitude=longitude, foursquare_id=foursquare_id, - foursquare_type=foursquare_type) + message = bot.send_venue( + chat_id=chat_id, + title=title, + address=address, + latitude=latitude, + longitude=longitude, + foursquare_id=foursquare_id, + foursquare_type=foursquare_type, + ) assert message.venue assert message.venue.title == title @@ -181,14 +214,16 @@ class TestBot: @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.xfail(raises=RetryAfter) - @pytest.mark.skipif(python_implementation() == 'PyPy', - reason='Unstable on pypy for some reason') + @pytest.mark.skipif( + python_implementation() == 'PyPy', reason='Unstable on pypy for some reason' + ) def test_send_contact(self, bot, chat_id): phone_number = '+11234567890' first_name = 'Leandro' last_name = 'Toledo' - message = bot.send_contact(chat_id=chat_id, phone_number=phone_number, - first_name=first_name, last_name=last_name) + message = bot.send_contact( + chat_id=chat_id, phone_number=phone_number, first_name=first_name, last_name=last_name + ) assert message.contact assert message.contact.phone_number == phone_number @@ -199,17 +234,29 @@ class TestBot: @flaky(3, 1) @pytest.mark.timeout(10) - @pytest.mark.parametrize('reply_markup', [ - None, - InlineKeyboardMarkup.from_button(InlineKeyboardButton(text='text', callback_data='data')), - InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text='text', callback_data='data')).to_dict() - ]) + @pytest.mark.parametrize( + 'reply_markup', + [ + None, + InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text='text', callback_data='data') + ), + InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text='text', callback_data='data') + ).to_dict(), + ], + ) def test_send_and_stop_poll(self, bot, super_group_id, reply_markup): question = 'Is this a test?' answers = ['Yes', 'No', 'Maybe'] - message = bot.send_poll(chat_id=super_group_id, question=question, options=answers, - is_anonymous=False, allows_multiple_answers=True, timeout=60) + message = bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + is_anonymous=False, + allows_multiple_answers=True, + timeout=60, + ) assert message.poll assert message.poll.question == question @@ -223,8 +270,12 @@ class TestBot: # Since only the poll and not the complete message is returned, we can't check that the # reply_markup is correct. So we just test that sending doesn't give an error. - poll = bot.stop_poll(chat_id=super_group_id, message_id=message.message_id, - reply_markup=reply_markup, timeout=60) + poll = bot.stop_poll( + chat_id=super_group_id, + message_id=message.message_id, + reply_markup=reply_markup, + timeout=60, + ) assert isinstance(poll, Poll) assert poll.is_closed assert poll.options[0].text == answers[0] @@ -240,10 +291,16 @@ class TestBot: explanation_entities = [ MessageEntity(MessageEntity.TEXT_LINK, 0, 14, url='https://google.com') ] - message_quiz = bot.send_poll(chat_id=super_group_id, question=question, options=answers, - type=Poll.QUIZ, correct_option_id=2, is_closed=True, - explanation=explanation, - explanation_parse_mode=ParseMode.MARKDOWN_V2) + message_quiz = bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation, + explanation_parse_mode=ParseMode.MARKDOWN_V2, + ) assert message_quiz.poll.correct_option_id == 2 assert message_quiz.poll.type == Poll.QUIZ assert message_quiz.poll.is_closed @@ -257,18 +314,29 @@ class TestBot: question = 'Is this a test?' answers = ['Yes', 'No', 'Maybe'] reply_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text='text', callback_data='data')) + InlineKeyboardButton(text='text', callback_data='data') + ) if close_date: close_date = dtm.datetime.utcnow() + dtm.timedelta(seconds=5) - message = bot.send_poll(chat_id=super_group_id, question=question, options=answers, - is_anonymous=False, allows_multiple_answers=True, timeout=60, - open_period=open_period, close_date=close_date) + message = bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + is_anonymous=False, + allows_multiple_answers=True, + timeout=60, + open_period=open_period, + close_date=close_date, + ) time.sleep(5.1) - new_message = bot.edit_message_reply_markup(chat_id=super_group_id, - message_id=message.message_id, - reply_markup=reply_markup, timeout=60) + new_message = bot.edit_message_reply_markup( + chat_id=super_group_id, + message_id=message.message_id, + reply_markup=reply_markup, + timeout=60, + ) assert new_message.poll.id == message.poll.id assert new_message.poll.is_closed @@ -278,20 +346,29 @@ class TestBot: question = 'Is this a test?' answers = ['Yes', 'No', 'Maybe'] reply_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text='text', callback_data='data')) + InlineKeyboardButton(text='text', callback_data='data') + ) aware_close_date = dtm.datetime.now(tz=tz_bot.defaults.tzinfo) + dtm.timedelta(seconds=5) close_date = aware_close_date.replace(tzinfo=None) - message = tz_bot.send_poll(chat_id=super_group_id, question=question, options=answers, - close_date=close_date, timeout=60) + message = tz_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + close_date=close_date, + timeout=60, + ) assert message.poll.close_date == aware_close_date.replace(microsecond=0) time.sleep(5.1) - new_message = tz_bot.edit_message_reply_markup(chat_id=super_group_id, - message_id=message.message_id, - reply_markup=reply_markup, timeout=60) + new_message = tz_bot.edit_message_reply_markup( + chat_id=super_group_id, + message_id=message.message_id, + reply_markup=reply_markup, + timeout=60, + ) assert new_message.poll.id == message.poll.id assert new_message.poll.is_closed @@ -304,27 +381,45 @@ class TestBot: question = 'Is this a test?' answers = ['Yes', 'No', 'Maybe'] - message = default_bot.send_poll(chat_id=super_group_id, question=question, options=answers, - type=Poll.QUIZ, correct_option_id=2, is_closed=True, - explanation=explanation_markdown) + message = default_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation_markdown, + ) assert message.poll.explanation == explanation assert message.poll.explanation_entities == [ MessageEntity(MessageEntity.ITALIC, 0, 6), MessageEntity(MessageEntity.BOLD, 7, 4), - MessageEntity(MessageEntity.CODE, 12, 4) + MessageEntity(MessageEntity.CODE, 12, 4), ] - message = default_bot.send_poll(chat_id=super_group_id, question=question, options=answers, - type=Poll.QUIZ, correct_option_id=2, is_closed=True, - explanation=explanation_markdown, - explanation_parse_mode=None) + message = default_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation_markdown, + explanation_parse_mode=None, + ) assert message.poll.explanation == explanation_markdown assert message.poll.explanation_entities == [] - message = default_bot.send_poll(chat_id=super_group_id, question=question, options=answers, - type=Poll.QUIZ, correct_option_id=2, is_closed=True, - explanation=explanation_markdown, - explanation_parse_mode='HTML') + message = default_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation_markdown, + explanation_parse_mode='HTML', + ) assert message.poll.explanation == explanation_markdown assert message.poll.explanation_entities == [] @@ -349,107 +444,161 @@ class TestBot: def test_answer_inline_query(self, monkeypatch, bot): # For now just test that our internals pass the correct data def test(url, data, *args, **kwargs): - return data == {'cache_time': 300, - 'results': [{'title': 'first', 'id': '11', 'type': 'article', - 'input_message_content': {'message_text': 'first'}}, - {'title': 'second', 'id': '12', 'type': 'article', - 'input_message_content': {'message_text': 'second'}}], - 'next_offset': '42', 'switch_pm_parameter': 'start_pm', - 'inline_query_id': 1234, 'is_personal': True, - 'switch_pm_text': 'switch pm'} + return data == { + 'cache_time': 300, + 'results': [ + { + 'title': 'first', + 'id': '11', + 'type': 'article', + 'input_message_content': {'message_text': 'first'}, + }, + { + 'title': 'second', + 'id': '12', + 'type': 'article', + 'input_message_content': {'message_text': 'second'}, + }, + ], + 'next_offset': '42', + 'switch_pm_parameter': 'start_pm', + 'inline_query_id': 1234, + 'is_personal': True, + 'switch_pm_text': 'switch pm', + } monkeypatch.setattr(bot.request, 'post', test) - results = [InlineQueryResultArticle('11', 'first', InputTextMessageContent('first')), - InlineQueryResultArticle('12', 'second', InputTextMessageContent('second'))] + results = [ + InlineQueryResultArticle('11', 'first', InputTextMessageContent('first')), + InlineQueryResultArticle('12', 'second', InputTextMessageContent('second')), + ] - assert bot.answer_inline_query(1234, - results=results, - cache_time=300, - is_personal=True, - next_offset='42', - switch_pm_text='switch pm', - switch_pm_parameter='start_pm') + assert bot.answer_inline_query( + 1234, + results=results, + cache_time=300, + is_personal=True, + next_offset='42', + switch_pm_text='switch pm', + switch_pm_parameter='start_pm', + ) def test_answer_inline_query_no_default_parse_mode(self, monkeypatch, bot): def test(url, data, *args, **kwargs): - return data == {'cache_time': 300, - 'results': [{'title': 'test_result', 'id': '123', 'type': 'document', - 'document_url': 'https://raw.githubusercontent.com/' - 'python-telegram-bot/logos/master/logo/png/' - 'ptb-logo_240.png', 'mime_type': 'image/png', - 'caption': 'ptb_logo'}], - 'next_offset': '42', 'switch_pm_parameter': 'start_pm', - 'inline_query_id': 1234, 'is_personal': True, - 'switch_pm_text': 'switch pm'} + return data == { + 'cache_time': 300, + 'results': [ + { + 'title': 'test_result', + 'id': '123', + 'type': 'document', + 'document_url': 'https://raw.githubusercontent.com/' + 'python-telegram-bot/logos/master/logo/png/' + 'ptb-logo_240.png', + 'mime_type': 'image/png', + 'caption': 'ptb_logo', + } + ], + 'next_offset': '42', + 'switch_pm_parameter': 'start_pm', + 'inline_query_id': 1234, + 'is_personal': True, + 'switch_pm_text': 'switch pm', + } monkeypatch.setattr(bot.request, 'post', test) - results = [InlineQueryResultDocument( - id='123', - document_url='https://raw.githubusercontent.com/python-telegram-bot/logos/master/' - 'logo/png/ptb-logo_240.png', - title='test_result', - mime_type='image/png', - caption='ptb_logo', - )] + results = [ + InlineQueryResultDocument( + id='123', + document_url='https://raw.githubusercontent.com/python-telegram-bot/logos/master/' + 'logo/png/ptb-logo_240.png', + title='test_result', + mime_type='image/png', + caption='ptb_logo', + ) + ] - assert bot.answer_inline_query(1234, - results=results, - cache_time=300, - is_personal=True, - next_offset='42', - switch_pm_text='switch pm', - switch_pm_parameter='start_pm') + assert bot.answer_inline_query( + 1234, + results=results, + cache_time=300, + is_personal=True, + next_offset='42', + switch_pm_text='switch pm', + switch_pm_parameter='start_pm', + ) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) def test_answer_inline_query_default_parse_mode(self, monkeypatch, default_bot): def test(url, data, *args, **kwargs): - return data == {'cache_time': 300, - 'results': [{'title': 'test_result', 'id': '123', 'type': 'document', - 'document_url': 'https://raw.githubusercontent.com/' - 'python-telegram-bot/logos/master/logo/png/' - 'ptb-logo_240.png', 'mime_type': 'image/png', - 'caption': 'ptb_logo', 'parse_mode': 'Markdown'}], - 'next_offset': '42', 'switch_pm_parameter': 'start_pm', - 'inline_query_id': 1234, 'is_personal': True, - 'switch_pm_text': 'switch pm'} + return data == { + 'cache_time': 300, + 'results': [ + { + 'title': 'test_result', + 'id': '123', + 'type': 'document', + 'document_url': 'https://raw.githubusercontent.com/' + 'python-telegram-bot/logos/master/logo/png/' + 'ptb-logo_240.png', + 'mime_type': 'image/png', + 'caption': 'ptb_logo', + 'parse_mode': 'Markdown', + } + ], + 'next_offset': '42', + 'switch_pm_parameter': 'start_pm', + 'inline_query_id': 1234, + 'is_personal': True, + 'switch_pm_text': 'switch pm', + } monkeypatch.setattr(default_bot.request, 'post', test) - results = [InlineQueryResultDocument( - id='123', - document_url='https://raw.githubusercontent.com/python-telegram-bot/logos/master/' - 'logo/png/ptb-logo_240.png', - title='test_result', - mime_type='image/png', - caption='ptb_logo', - )] + results = [ + InlineQueryResultDocument( + id='123', + document_url='https://raw.githubusercontent.com/python-telegram-bot/logos/master/' + 'logo/png/ptb-logo_240.png', + title='test_result', + mime_type='image/png', + caption='ptb_logo', + ) + ] - assert default_bot.answer_inline_query(1234, - results=results, - cache_time=300, - is_personal=True, - next_offset='42', - switch_pm_text='switch pm', - switch_pm_parameter='start_pm') + assert default_bot.answer_inline_query( + 1234, + results=results, + cache_time=300, + is_personal=True, + next_offset='42', + switch_pm_text='switch pm', + switch_pm_parameter='start_pm', + ) def test_answer_inline_query_current_offset_error(self, bot, inline_results): with pytest.raises(ValueError, match=('`current_offset` and `next_offset`')): - bot.answer_inline_query(1234, - results=inline_results, - next_offset=42, - current_offset=51) + bot.answer_inline_query( + 1234, results=inline_results, next_offset=42, current_offset=51 + ) - @pytest.mark.parametrize('current_offset,num_results,id_offset,expected_next_offset', - [('', MAX_INLINE_QUERY_RESULTS, 1, 1), - (1, MAX_INLINE_QUERY_RESULTS, 51, 2), - (5, 3, 251, '')]) - def test_answer_inline_query_current_offset_1(self, - monkeypatch, - bot, - inline_results, - current_offset, - num_results, - id_offset, - expected_next_offset): + @pytest.mark.parametrize( + 'current_offset,num_results,id_offset,expected_next_offset', + [ + ('', MAX_INLINE_QUERY_RESULTS, 1, 1), + (1, MAX_INLINE_QUERY_RESULTS, 51, 2), + (5, 3, 251, ''), + ], + ) + def test_answer_inline_query_current_offset_1( + self, + monkeypatch, + bot, + inline_results, + current_offset, + num_results, + id_offset, + expected_next_offset, + ): # For now just test that our internals pass the correct data def make_assertion(url, data, *args, **kwargs): results = data['results'] @@ -592,20 +741,30 @@ class TestBot: def test_answer_callback_query(self, monkeypatch, bot): # For now just test that our internals pass the correct data def test(url, data, *args, **kwargs): - return data == {'callback_query_id': 23, 'show_alert': True, 'url': 'no_url', - 'cache_time': 1, 'text': 'answer'} + return data == { + 'callback_query_id': 23, + 'show_alert': True, + 'url': 'no_url', + 'cache_time': 1, + 'text': 'answer', + } monkeypatch.setattr(bot.request, 'post', test) - assert bot.answer_callback_query(23, text='answer', show_alert=True, url='no_url', - cache_time=1) + assert bot.answer_callback_query( + 23, text='answer', show_alert=True, url='no_url', cache_time=1 + ) @flaky(3, 1) @pytest.mark.timeout(10) def test_edit_message_text(self, bot, message): - message = bot.edit_message_text(text='new_text', chat_id=message.chat_id, - message_id=message.message_id, parse_mode='HTML', - disable_web_page_preview=True) + message = bot.edit_message_text( + text='new_text', + chat_id=message.chat_id, + message_id=message.message_id, + parse_mode='HTML', + disable_web_page_preview=True, + ) assert message.text == 'new_text' @@ -616,24 +775,38 @@ class TestBot: test_string = 'Italic Bold Code' test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.edit_message_text(text=test_markdown_string, chat_id=message.chat_id, - message_id=message.message_id, - disable_web_page_preview=True) + message = default_bot.edit_message_text( + text=test_markdown_string, + chat_id=message.chat_id, + message_id=message.message_id, + disable_web_page_preview=True, + ) assert message.text_markdown == test_markdown_string assert message.text == test_string - message = default_bot.edit_message_text(text=test_markdown_string, chat_id=message.chat_id, - message_id=message.message_id, parse_mode=None, - disable_web_page_preview=True) + message = default_bot.edit_message_text( + text=test_markdown_string, + chat_id=message.chat_id, + message_id=message.message_id, + parse_mode=None, + disable_web_page_preview=True, + ) assert message.text == test_markdown_string assert message.text_markdown == escape_markdown(test_markdown_string) - message = default_bot.edit_message_text(text=test_markdown_string, chat_id=message.chat_id, - message_id=message.message_id, - disable_web_page_preview=True) - message = default_bot.edit_message_text(text=test_markdown_string, chat_id=message.chat_id, - message_id=message.message_id, parse_mode='HTML', - disable_web_page_preview=True) + message = default_bot.edit_message_text( + text=test_markdown_string, + chat_id=message.chat_id, + message_id=message.message_id, + disable_web_page_preview=True, + ) + message = default_bot.edit_message_text( + text=test_markdown_string, + chat_id=message.chat_id, + message_id=message.message_id, + parse_mode='HTML', + disable_web_page_preview=True, + ) assert message.text == test_markdown_string assert message.text_markdown == escape_markdown(test_markdown_string) @@ -644,8 +817,11 @@ class TestBot: @flaky(3, 1) @pytest.mark.timeout(10) def test_edit_message_caption(self, bot, media_message): - message = bot.edit_message_caption(caption='new_caption', chat_id=media_message.chat_id, - message_id=media_message.message_id) + message = bot.edit_message_caption( + caption='new_caption', + chat_id=media_message.chat_id, + message_id=media_message.message_id, + ) assert message.caption == 'new_caption' @@ -658,35 +834,46 @@ class TestBot: test_string = 'Italic Bold Code' test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.edit_message_caption(caption=test_markdown_string, - chat_id=media_message.chat_id, - message_id=media_message.message_id) + message = default_bot.edit_message_caption( + caption=test_markdown_string, + chat_id=media_message.chat_id, + message_id=media_message.message_id, + ) assert message.caption_markdown == test_markdown_string assert message.caption == test_string - message = default_bot.edit_message_caption(caption=test_markdown_string, - chat_id=media_message.chat_id, - message_id=media_message.message_id, - parse_mode=None) + message = default_bot.edit_message_caption( + caption=test_markdown_string, + chat_id=media_message.chat_id, + message_id=media_message.message_id, + parse_mode=None, + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - message = default_bot.edit_message_caption(caption=test_markdown_string, - chat_id=media_message.chat_id, - message_id=media_message.message_id) - message = default_bot.edit_message_caption(caption=test_markdown_string, - chat_id=media_message.chat_id, - message_id=media_message.message_id, - parse_mode='HTML') + message = default_bot.edit_message_caption( + caption=test_markdown_string, + chat_id=media_message.chat_id, + message_id=media_message.message_id, + ) + message = default_bot.edit_message_caption( + caption=test_markdown_string, + chat_id=media_message.chat_id, + message_id=media_message.message_id, + parse_mode='HTML', + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @flaky(3, 1) @pytest.mark.timeout(10) def test_edit_message_caption_with_parse_mode(self, bot, media_message): - message = bot.edit_message_caption(caption='new *caption*', parse_mode='Markdown', - chat_id=media_message.chat_id, - message_id=media_message.message_id) + message = bot.edit_message_caption( + caption='new *caption*', + parse_mode='Markdown', + chat_id=media_message.chat_id, + message_id=media_message.message_id, + ) assert message.caption == 'new caption' @@ -702,9 +889,9 @@ class TestBot: @pytest.mark.timeout(10) def test_edit_reply_markup(self, bot, message): new_markup = InlineKeyboardMarkup([[InlineKeyboardButton(text='test', callback_data='1')]]) - message = bot.edit_message_reply_markup(chat_id=message.chat_id, - message_id=message.message_id, - reply_markup=new_markup) + message = bot.edit_message_reply_markup( + chat_id=message.chat_id, message_id=message.message_id, reply_markup=new_markup + ) assert message is not True @@ -805,8 +992,9 @@ class TestBot: message = bot.send_game(chat_id, game_short_name) assert message.game - assert message.game.description == ('A no-op test game, for python-telegram-bot ' - 'bot framework testing.') + assert message.game.description == ( + 'A no-op test game, for python-telegram-bot ' 'bot framework testing.' + ) assert message.game.animation.file_id != '' assert message.game.photo[0].file_size == 851 @@ -823,15 +1011,15 @@ class TestBot: user_id=chat_id, score=int(BASE_TIME) - HIGHSCORE_DELTA, chat_id=game.chat_id, - message_id=game.message_id) + message_id=game.message_id, + ) assert message.game.description == game.game.description assert message.game.animation.file_id == game.game.animation.file_id assert message.game.photo[0].file_size == game.game.photo[0].file_size assert message.game.text != game.game.text - expect_bad_request(func, 'Bot_score_not_modified', - 'This test is a diva for some reason.') + expect_bad_request(func, 'Bot_score_not_modified', 'This test is a diva for some reason.') @flaky(3, 1) @pytest.mark.timeout(10) @@ -847,7 +1035,8 @@ class TestBot: score=score, chat_id=game.chat_id, message_id=game.message_id, - disable_edit_message=True) + disable_edit_message=True, + ) assert message.game.description == game.game.description assert message.game.animation.file_id == game.game.animation.file_id @@ -865,10 +1054,8 @@ class TestBot: with pytest.raises(BadRequest, match='Bot_score_not_modified'): bot.set_game_score( - user_id=chat_id, - score=score, - chat_id=game.chat_id, - message_id=game.message_id) + user_id=chat_id, score=score, chat_id=game.chat_id, message_id=game.message_id + ) @flaky(3, 1) @pytest.mark.timeout(10) @@ -884,7 +1071,8 @@ class TestBot: score=score, chat_id=game.chat_id, message_id=game.message_id, - force=True) + force=True, + ) assert message.game.description == game.game.description assert message.game.animation.file_id == game.game.animation.file_id @@ -903,8 +1091,9 @@ class TestBot: game = bot.send_game(chat_id, game_short_name) with pytest.raises(BadRequest): - bot.set_game_score(user_id=chat_id, score=100, - chat_id=game.chat_id, message_id=game.message_id) + bot.set_game_score( + user_id=chat_id, score=100, chat_id=game.chat_id, message_id=game.message_id + ) @flaky(3, 1) @pytest.mark.timeout(10) @@ -922,10 +1111,13 @@ class TestBot: def test_answer_shipping_query_ok(self, monkeypatch, bot): # For now just test that our internals pass the correct data def test(url, data, *args, **kwargs): - return data == {'shipping_query_id': 1, 'ok': True, - 'shipping_options': [{'title': 'option1', - 'prices': [{'label': 'price', 'amount': 100}], - 'id': 1}]} + return data == { + 'shipping_query_id': 1, + 'ok': True, + 'shipping_options': [ + {'title': 'option1', 'prices': [{'label': 'price', 'amount': 100}], 'id': 1} + ], + } monkeypatch.setattr(bot.request, 'post', test) shipping_options = ShippingOption(1, 'option1', [LabeledPrice('price', 100)]) @@ -934,8 +1126,11 @@ class TestBot: def test_answer_shipping_query_error_message(self, monkeypatch, bot): # For now just test that our internals pass the correct data def test(url, data, *args, **kwargs): - return data == {'shipping_query_id': 1, 'error_message': 'Not enough fish', - 'ok': False} + return data == { + 'shipping_query_id': 1, + 'error_message': 'Not enough fish', + 'ok': False, + } monkeypatch.setattr(bot.request, 'post', test) assert bot.answer_shipping_query(1, False, error_message='Not enough fish') @@ -967,8 +1162,11 @@ class TestBot: def test_answer_pre_checkout_query_error_message(self, monkeypatch, bot): # For now just test that our internals pass the correct data def test(url, data, *args, **kwargs): - return data == {'pre_checkout_query_id': 1, 'error_message': 'Not enough fish', - 'ok': False} + return data == { + 'pre_checkout_query_id': 1, + 'error_message': 'Not enough fish', + 'ok': False, + } monkeypatch.setattr(bot.request, 'post', test) assert bot.answer_pre_checkout_query(1, False, error_message='Not enough fish') @@ -985,13 +1183,13 @@ class TestBot: def test_restrict_chat_member(self, bot, channel_id, chat_permissions): # TODO: Add bot to supergroup so this can be tested properly with pytest.raises(BadRequest, match='Method is available only for supergroups'): - assert bot.restrict_chat_member(channel_id, - 95205500, - chat_permissions, - until_date=dtm.datetime.utcnow()) + assert bot.restrict_chat_member( + channel_id, 95205500, chat_permissions, until_date=dtm.datetime.utcnow() + ) - def test_restrict_chat_member_default_tz(self, monkeypatch, tz_bot, channel_id, - chat_permissions): + def test_restrict_chat_member_default_tz( + self, monkeypatch, tz_bot, channel_id, chat_permissions + ): until = dtm.datetime(2020, 1, 11, 16, 13) until_timestamp = to_timestamp(until, tzinfo=tz_bot.defaults.tzinfo) @@ -1000,33 +1198,31 @@ class TestBot: monkeypatch.setattr(tz_bot.request, 'post', test) - assert tz_bot.restrict_chat_member(channel_id, - 95205500, - chat_permissions) - assert tz_bot.restrict_chat_member(channel_id, - 95205500, - chat_permissions, - until_date=until) - assert tz_bot.restrict_chat_member(channel_id, - 95205500, - chat_permissions, - until_date=until_timestamp) + assert tz_bot.restrict_chat_member(channel_id, 95205500, chat_permissions) + assert tz_bot.restrict_chat_member( + channel_id, 95205500, chat_permissions, until_date=until + ) + assert tz_bot.restrict_chat_member( + channel_id, 95205500, chat_permissions, until_date=until_timestamp + ) @flaky(3, 1) @pytest.mark.timeout(10) def test_promote_chat_member(self, bot, channel_id): # TODO: Add bot to supergroup so this can be tested properly / give bot perms with pytest.raises(BadRequest, match='Not enough rights'): - assert bot.promote_chat_member(channel_id, - 95205500, - can_change_info=True, - can_post_messages=True, - can_edit_messages=True, - can_delete_messages=True, - can_invite_users=True, - can_restrict_members=True, - can_pin_messages=True, - can_promote_members=True) + assert bot.promote_chat_member( + channel_id, + 95205500, + can_change_info=True, + can_post_messages=True, + can_edit_messages=True, + can_delete_messages=True, + can_invite_users=True, + can_restrict_members=True, + can_pin_messages=True, + can_promote_members=True, + ) @flaky(3, 1) @pytest.mark.timeout(10) @@ -1068,8 +1264,9 @@ class TestBot: @pytest.mark.timeout(10) def test_pin_and_unpin_message(self, bot, super_group_id): message = bot.send_message(super_group_id, text="test_pin_message") - assert bot.pin_chat_message(chat_id=super_group_id, message_id=message.message_id, - disable_notification=True) + assert bot.pin_chat_message( + chat_id=super_group_id, message_id=message.message_id, disable_notification=True + ) chat = bot.get_chat(super_group_id) assert chat.pinned_message == message diff --git a/tests/test_callbackcontext.py b/tests/test_callbackcontext.py index f3806ea0f..a6b68f7d6 100644 --- a/tests/test_callbackcontext.py +++ b/tests/test_callbackcontext.py @@ -41,8 +41,9 @@ class TestCallbackContext: assert callback_context.update_queue is cdp.update_queue def test_from_update(self, cdp): - update = Update(0, message=Message(0, None, Chat(1, 'chat'), - from_user=User(1, 'user', False))) + update = Update( + 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) + ) callback_context = CallbackContext.from_update(update, cdp) @@ -63,8 +64,9 @@ class TestCallbackContext: assert callback_context_same_user_chat.chat_data is callback_context.chat_data assert callback_context_same_user_chat.user_data is callback_context.user_data - update_other_user_chat = Update(0, message=Message(0, None, Chat(2, 'chat'), - from_user=User(2, 'user', False))) + update_other_user_chat = Update( + 0, message=Message(0, None, Chat(2, 'chat'), from_user=User(2, 'user', False)) + ) callback_context_other_user_chat = CallbackContext.from_update(update_other_user_chat, cdp) @@ -94,8 +96,9 @@ class TestCallbackContext: def test_from_error(self, cdp): error = TelegramError('test') - update = Update(0, message=Message(0, None, Chat(1, 'chat'), - from_user=User(1, 'user', False))) + update = Update( + 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) + ) callback_context = CallbackContext.from_error(update, error, cdp) @@ -115,9 +118,9 @@ class TestCallbackContext: args = [1, '2'] kwargs = {'one': 1, 2: 'two'} - callback_context = CallbackContext.from_error(None, error, cdp, - async_args=args, - async_kwargs=kwargs) + callback_context = CallbackContext.from_error( + None, error, cdp, async_args=args, async_kwargs=kwargs + ) assert callback_context.error is error assert callback_context.async_args is args @@ -133,8 +136,9 @@ class TestCallbackContext: assert callback_context.match == 'test' def test_data_assignment(self, cdp): - update = Update(0, message=Message(0, None, Chat(1, 'chat'), - from_user=User(1, 'user', False))) + update = Update( + 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) + ) callback_context = CallbackContext.from_update(update, cdp) diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index be6d4afa9..277ec7038 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -24,12 +24,14 @@ from telegram import CallbackQuery, User, Message, Chat, Audio @pytest.fixture(scope='class', params=['message', 'inline']) def callback_query(bot, request): - cbq = CallbackQuery(TestCallbackQuery.id_, - TestCallbackQuery.from_user, - TestCallbackQuery.chat_instance, - data=TestCallbackQuery.data, - game_short_name=TestCallbackQuery.game_short_name, - bot=bot) + cbq = CallbackQuery( + TestCallbackQuery.id_, + TestCallbackQuery.from_user, + TestCallbackQuery.chat_instance, + data=TestCallbackQuery.data, + game_short_name=TestCallbackQuery.game_short_name, + bot=bot, + ) if request.param == 'message': cbq.message = TestCallbackQuery.message else: @@ -47,13 +49,15 @@ class TestCallbackQuery: game_short_name = 'the_game' def test_de_json(self, bot): - json_dict = {'id': self.id_, - 'from': self.from_user.to_dict(), - 'chat_instance': self.chat_instance, - 'message': self.message.to_dict(), - 'data': self.data, - 'inline_message_id': self.inline_message_id, - 'game_short_name': self.game_short_name} + json_dict = { + 'id': self.id_, + 'from': self.from_user.to_dict(), + 'chat_instance': self.chat_instance, + 'message': self.message.to_dict(), + 'data': self.data, + 'inline_message_id': self.inline_message_id, + 'game_short_name': self.game_short_name, + } callback_query = CallbackQuery.de_json(json_dict, bot) assert callback_query.id == self.id_ diff --git a/tests/test_callbackqueryhandler.py b/tests/test_callbackqueryhandler.py index d3960eb4b..087618aa2 100644 --- a/tests/test_callbackqueryhandler.py +++ b/tests/test_callbackqueryhandler.py @@ -20,8 +20,18 @@ from queue import Queue import pytest -from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, InlineQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Update, + CallbackQuery, + Bot, + Message, + User, + Chat, + InlineQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import CallbackQueryHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -34,12 +44,19 @@ params = [ {'inline_query': InlineQuery(1, User(1, '', False), '', '')}, {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, - {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')} + {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, ] -ids = ('message', 'edited_message', 'channel_post', - 'edited_channel_post', 'inline_query', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query') +ids = ( + 'message', + 'edited_message', + 'channel_post', + 'edited_channel_post', + 'inline_query', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -83,15 +100,17 @@ class TestCallbackQueryHandler: self.test_flag = groupdict == {'begin': 't', 'end': ' data'} def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and context.chat_data is None - and isinstance(context.bot_data, dict) - and isinstance(update.callback_query, CallbackQuery)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and context.chat_data is None + and isinstance(context.bot_data, dict) + and isinstance(update.callback_query, CallbackQuery) + ) def callback_context_pattern(self, update, context): if context.matches[0].groups(): @@ -117,18 +136,18 @@ class TestCallbackQueryHandler: assert not handler.check_update(callback_query) def test_with_passing_group_dict(self, dp, callback_query): - handler = CallbackQueryHandler(self.callback_group, - pattern='(?P.*)est(?P.*)', - pass_groups=True) + handler = CallbackQueryHandler( + self.callback_group, pattern='(?P.*)est(?P.*)', pass_groups=True + ) dp.add_handler(handler) dp.process_update(callback_query) assert self.test_flag dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_group, - pattern='(?P.*)est(?P.*)', - pass_groupdict=True) + handler = CallbackQueryHandler( + self.callback_group, pattern='(?P.*)est(?P.*)', pass_groupdict=True + ) dp.add_handler(handler) self.test_flag = False @@ -136,16 +155,14 @@ class TestCallbackQueryHandler: assert self.test_flag def test_pass_user_or_chat_data(self, dp, callback_query): - handler = CallbackQueryHandler(self.callback_data_1, - pass_user_data=True) + handler = CallbackQueryHandler(self.callback_data_1, pass_user_data=True) dp.add_handler(handler) dp.process_update(callback_query) assert self.test_flag dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_data_1, - pass_chat_data=True) + handler = CallbackQueryHandler(self.callback_data_1, pass_chat_data=True) dp.add_handler(handler) self.test_flag = False @@ -153,9 +170,9 @@ class TestCallbackQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_data_2, - pass_chat_data=True, - pass_user_data=True) + handler = CallbackQueryHandler( + self.callback_data_2, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(handler) self.test_flag = False @@ -163,16 +180,14 @@ class TestCallbackQueryHandler: assert self.test_flag def test_pass_job_or_update_queue(self, dp, callback_query): - handler = CallbackQueryHandler(self.callback_queue_1, - pass_job_queue=True) + handler = CallbackQueryHandler(self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update(callback_query) assert self.test_flag dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_queue_1, - pass_update_queue=True) + handler = CallbackQueryHandler(self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -180,9 +195,9 @@ class TestCallbackQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_queue_2, - pass_job_queue=True, - pass_update_queue=True) + handler = CallbackQueryHandler( + self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False @@ -201,16 +216,16 @@ class TestCallbackQueryHandler: assert self.test_flag def test_context_pattern(self, cdp, callback_query): - handler = CallbackQueryHandler(self.callback_context_pattern, - pattern=r'(?P.*)est(?P.*)') + handler = CallbackQueryHandler( + self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' + ) cdp.add_handler(handler) cdp.process_update(callback_query) assert self.test_flag cdp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_context_pattern, - pattern=r'(t)est(.*)') + handler = CallbackQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') cdp.add_handler(handler) cdp.process_update(callback_query) diff --git a/tests/test_chat.py b/tests/test_chat.py index 5ee5b9a2a..60bea2a3d 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -25,12 +25,18 @@ from telegram import User @pytest.fixture(scope='class') def chat(bot): - return Chat(TestChat.id_, TestChat.title, TestChat.type_, username=TestChat.username, - all_members_are_administrators=TestChat.all_members_are_administrators, - bot=bot, sticker_set_name=TestChat.sticker_set_name, - can_set_sticker_set=TestChat.can_set_sticker_set, - permissions=TestChat.permissions, - slow_mode_delay=TestChat.slow_mode_delay) + return Chat( + TestChat.id_, + TestChat.title, + TestChat.type_, + username=TestChat.username, + all_members_are_administrators=TestChat.all_members_are_administrators, + bot=bot, + sticker_set_name=TestChat.sticker_set_name, + can_set_sticker_set=TestChat.can_set_sticker_set, + permissions=TestChat.permissions, + slow_mode_delay=TestChat.slow_mode_delay, + ) class TestChat: @@ -58,7 +64,7 @@ class TestChat: 'sticker_set_name': self.sticker_set_name, 'can_set_sticker_set': self.can_set_sticker_set, 'permissions': self.permissions.to_dict(), - 'slow_mode_delay': self.slow_mode_delay + 'slow_mode_delay': self.slow_mode_delay, } chat = Chat.de_json(json_dict, bot) diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index 404e55a00..47c63ec45 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -49,24 +49,26 @@ class TestChatMember: time = datetime.datetime.utcnow() custom_title = 'custom_title' - json_dict = {'user': user.to_dict(), - 'status': self.status, - 'custom_title': custom_title, - 'until_date': to_timestamp(time), - 'can_be_edited': False, - 'can_change_info': True, - 'can_post_messages': False, - 'can_edit_messages': True, - 'can_delete_messages': True, - 'can_invite_users': False, - 'can_restrict_members': True, - 'can_pin_messages': False, - 'can_promote_members': True, - 'can_send_messages': False, - 'can_send_media_messages': True, - 'can_send_polls': False, - 'can_send_other_messages': True, - 'can_add_web_page_previews': False} + json_dict = { + 'user': user.to_dict(), + 'status': self.status, + 'custom_title': custom_title, + 'until_date': to_timestamp(time), + 'can_be_edited': False, + 'can_change_info': True, + 'can_post_messages': False, + 'can_edit_messages': True, + 'can_delete_messages': True, + 'can_invite_users': False, + 'can_restrict_members': True, + 'can_pin_messages': False, + 'can_promote_members': True, + 'can_send_messages': False, + 'can_send_media_messages': True, + 'can_send_polls': False, + 'can_send_other_messages': True, + 'can_add_web_page_previews': False, + } chat_member = ChatMember.de_json(json_dict, bot) diff --git a/tests/test_chatpermissions.py b/tests/test_chatpermissions.py index 15d6e8d2f..c5c25ab98 100644 --- a/tests/test_chatpermissions.py +++ b/tests/test_chatpermissions.py @@ -24,10 +24,16 @@ from telegram import ChatPermissions, User @pytest.fixture(scope="class") def chat_permissions(): - return ChatPermissions(can_send_messages=True, can_send_media_messages=True, - can_send_polls=True, can_send_other_messages=True, - can_add_web_page_previews=True, can_change_info=True, - can_invite_users=True, can_pin_messages=True) + return ChatPermissions( + can_send_messages=True, + can_send_media_messages=True, + can_send_polls=True, + can_send_other_messages=True, + can_add_web_page_previews=True, + can_change_info=True, + can_invite_users=True, + can_pin_messages=True, + ) class TestChatPermissions: @@ -49,7 +55,7 @@ class TestChatPermissions: 'can_add_web_page_previews': self.can_add_web_page_previews, 'can_change_info': self.can_change_info, 'can_invite_users': self.can_invite_users, - 'can_pin_messages': self.can_pin_messages + 'can_pin_messages': self.can_pin_messages, } permissions = ChatPermissions.de_json(json_dict, bot) @@ -67,13 +73,17 @@ class TestChatPermissions: assert isinstance(permissions_dict, dict) assert permissions_dict['can_send_messages'] == chat_permissions.can_send_messages - assert (permissions_dict['can_send_media_messages'] - == chat_permissions.can_send_media_messages) + assert ( + permissions_dict['can_send_media_messages'] == chat_permissions.can_send_media_messages + ) assert permissions_dict['can_send_polls'] == chat_permissions.can_send_polls - assert (permissions_dict['can_send_other_messages'] - == chat_permissions.can_send_other_messages) - assert (permissions_dict['can_add_web_page_previews'] - == chat_permissions.can_add_web_page_previews) + assert ( + permissions_dict['can_send_other_messages'] == chat_permissions.can_send_other_messages + ) + assert ( + permissions_dict['can_add_web_page_previews'] + == chat_permissions.can_add_web_page_previews + ) assert permissions_dict['can_change_info'] == chat_permissions.can_change_info assert permissions_dict['can_invite_users'] == chat_permissions.can_invite_users assert permissions_dict['can_pin_messages'] == chat_permissions.can_pin_messages @@ -83,7 +93,7 @@ class TestChatPermissions: can_send_messages=True, can_send_media_messages=True, can_send_polls=True, - can_send_other_messages=False + can_send_other_messages=False, ) b = ChatPermissions( can_send_polls=True, @@ -95,7 +105,7 @@ class TestChatPermissions: can_send_messages=False, can_send_media_messages=True, can_send_polls=True, - can_send_other_messages=False + can_send_other_messages=False, ) d = User(123, '', False) diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index e21cfacf9..76dd227fb 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -139,12 +139,21 @@ class TestChatPhoto: assert chat_photo.get_big_file() def test_equality(self): - a = ChatPhoto(self.chatphoto_small_file_id, self.chatphoto_big_file_id, - self.chatphoto_small_file_unique_id, self.chatphoto_big_file_unique_id) - b = ChatPhoto(self.chatphoto_small_file_id, self.chatphoto_big_file_id, - self.chatphoto_small_file_unique_id, self.chatphoto_big_file_unique_id) - c = ChatPhoto('', '', self.chatphoto_small_file_unique_id, - self.chatphoto_big_file_unique_id) + a = ChatPhoto( + self.chatphoto_small_file_id, + self.chatphoto_big_file_id, + self.chatphoto_small_file_unique_id, + self.chatphoto_big_file_unique_id, + ) + b = ChatPhoto( + self.chatphoto_small_file_id, + self.chatphoto_big_file_id, + self.chatphoto_small_file_unique_id, + self.chatphoto_big_file_unique_id, + ) + c = ChatPhoto( + '', '', self.chatphoto_small_file_unique_id, self.chatphoto_big_file_unique_id + ) d = ChatPhoto('', '', 0, 0) e = Voice(self.chatphoto_small_file_id, self.chatphoto_small_file_unique_id, 0) diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index 6511f8b32..585f9cb22 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -37,9 +37,7 @@ class TestChosenInlineResult: query = 'query text' def test_de_json_required(self, bot, user): - json_dict = {'result_id': self.result_id, - 'from': user.to_dict(), - 'query': self.query} + json_dict = {'result_id': self.result_id, 'from': user.to_dict(), 'query': self.query} result = ChosenInlineResult.de_json(json_dict, bot) assert result.result_id == self.result_id @@ -48,11 +46,13 @@ class TestChosenInlineResult: def test_de_json_all(self, bot, user): loc = Location(-42.003, 34.004) - json_dict = {'result_id': self.result_id, - 'from': user.to_dict(), - 'query': self.query, - 'location': loc.to_dict(), - 'inline_message_id': 'a random id'} + json_dict = { + 'result_id': self.result_id, + 'from': user.to_dict(), + 'query': self.query, + 'location': loc.to_dict(), + 'inline_message_id': 'a random id', + } result = ChosenInlineResult.de_json(json_dict, bot) assert result.result_id == self.result_id diff --git a/tests/test_choseninlineresulthandler.py b/tests/test_choseninlineresulthandler.py index 5a3d4d1dd..34c4a3f3b 100644 --- a/tests/test_choseninlineresulthandler.py +++ b/tests/test_choseninlineresulthandler.py @@ -20,8 +20,18 @@ from queue import Queue import pytest -from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery, - InlineQuery, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Update, + Chat, + Bot, + ChosenInlineResult, + User, + Message, + CallbackQuery, + InlineQuery, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import ChosenInlineResultHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -35,12 +45,20 @@ params = [ {'inline_query': InlineQuery(1, User(1, '', False), '', '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'inline_query', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'inline_query', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -50,9 +68,10 @@ def false_update(request): @pytest.fixture(scope='class') def chosen_inline_result(): - return Update(1, chosen_inline_result=ChosenInlineResult('result_id', - User(1, 'test_user', False), - 'query')) + return Update( + 1, + chosen_inline_result=ChosenInlineResult('result_id', User(1, 'test_user', False), 'query'), + ) class TestChosenInlineResultHandler: @@ -80,15 +99,17 @@ class TestChosenInlineResultHandler: self.test_flag = (job_queue is not None) and (update_queue is not None) def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and context.chat_data is None - and isinstance(context.bot_data, dict) - and isinstance(update.chosen_inline_result, ChosenInlineResult)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and context.chat_data is None + and isinstance(context.bot_data, dict) + and isinstance(update.chosen_inline_result, ChosenInlineResult) + ) def test_basic(self, dp, chosen_inline_result): handler = ChosenInlineResultHandler(self.callback_basic) @@ -99,16 +120,14 @@ class TestChosenInlineResultHandler: assert self.test_flag def test_pass_user_or_chat_data(self, dp, chosen_inline_result): - handler = ChosenInlineResultHandler(self.callback_data_1, - pass_user_data=True) + handler = ChosenInlineResultHandler(self.callback_data_1, pass_user_data=True) dp.add_handler(handler) dp.process_update(chosen_inline_result) assert self.test_flag dp.remove_handler(handler) - handler = ChosenInlineResultHandler(self.callback_data_1, - pass_chat_data=True) + handler = ChosenInlineResultHandler(self.callback_data_1, pass_chat_data=True) dp.add_handler(handler) self.test_flag = False @@ -116,8 +135,9 @@ class TestChosenInlineResultHandler: assert self.test_flag dp.remove_handler(handler) - handler = ChosenInlineResultHandler(self.callback_data_2, - pass_chat_data=True, pass_user_data=True) + handler = ChosenInlineResultHandler( + self.callback_data_2, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(handler) self.test_flag = False @@ -125,16 +145,14 @@ class TestChosenInlineResultHandler: assert self.test_flag def test_pass_job_or_update_queue(self, dp, chosen_inline_result): - handler = ChosenInlineResultHandler(self.callback_queue_1, - pass_job_queue=True) + handler = ChosenInlineResultHandler(self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update(chosen_inline_result) assert self.test_flag dp.remove_handler(handler) - handler = ChosenInlineResultHandler(self.callback_queue_1, - pass_update_queue=True) + handler = ChosenInlineResultHandler(self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -142,8 +160,9 @@ class TestChosenInlineResultHandler: assert self.test_flag dp.remove_handler(handler) - handler = ChosenInlineResultHandler(self.callback_queue_2, - pass_job_queue=True, pass_update_queue=True) + handler = ChosenInlineResultHandler( + self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_commandhandler.py b/tests/test_commandhandler.py index 0783e8e2a..e3d865ff1 100644 --- a/tests/test_commandhandler.py +++ b/tests/test_commandhandler.py @@ -26,8 +26,12 @@ from telegram.utils.deprecate import TelegramDeprecationWarning from telegram import Message, Update, Chat, Bot from telegram.ext import CommandHandler, Filters, CallbackContext, JobQueue, PrefixHandler -from tests.conftest import make_command_message, make_command_update, make_message, \ - make_message_update +from tests.conftest import ( + make_command_message, + make_command_update, + make_message, + make_message_update, +) def is_match(handler, update): @@ -45,6 +49,7 @@ def is_match(handler, update): class BaseTest: """Base class for command and prefix handler test classes. Contains utility methods an several callbacks used by both classes.""" + test_flag = False SRE_TYPE = type(re.match("", "")) @@ -81,15 +86,17 @@ class BaseTest: return callback def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and isinstance(context.chat_data, dict) - and isinstance(context.bot_data, dict) - and isinstance(update.message, Message)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and isinstance(context.chat_data, dict) + and isinstance(context.bot_data, dict) + and isinstance(update.message, Message) + ) def callback_context_args(self, update, context): self.test_flag = context.args == ['one', 'two'] @@ -132,6 +139,7 @@ class BaseTest: # ----------------------------- CommandHandler ----------------------------- + class TestCommandHandler(BaseTest): CMD = '/test' @@ -170,10 +178,11 @@ class TestCommandHandler(BaseTest): assert not is_match(handler, make_command_update('/not{}'.format(command[1:]))) assert not is_match(handler, make_command_update('not {} at start'.format(command))) - @pytest.mark.parametrize('cmd', - ['way_too_longcommand1234567yes_way_toooooooLong', 'ïñválídletters', - 'invalid #&* chars'], - ids=['too long', 'invalid letter', 'invalid characters']) + @pytest.mark.parametrize( + 'cmd', + ['way_too_longcommand1234567yes_way_toooooooLong', 'ïñválídletters', 'invalid #&* chars'], + ids=['too long', 'invalid letter', 'invalid characters'], + ) def test_invalid_commands(self, cmd): with pytest.raises(ValueError, match='not a valid bot command'): CommandHandler(cmd, self.callback_basic) @@ -262,19 +271,22 @@ class TestCommandHandler(BaseTest): def test_context_regex(self, cdp, command): """Test CHs with context-based callbacks and a single filter""" - handler = self.make_default_handler(self.callback_context_regex1, - filters=Filters.regex('one two')) + handler = self.make_default_handler( + self.callback_context_regex1, filters=Filters.regex('one two') + ) self._test_context_args_or_regex(cdp, handler, command) def test_context_multiple_regex(self, cdp, command): """Test CHs with context-based callbacks and filters combined""" - handler = self.make_default_handler(self.callback_context_regex2, - filters=Filters.regex('one') & Filters.regex('two')) + handler = self.make_default_handler( + self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two') + ) self._test_context_args_or_regex(cdp, handler, command) # ----------------------------- PrefixHandler ----------------------------- + def combinations(prefixes, commands): return (prefix + command for prefix in prefixes for command in commands) @@ -291,7 +303,7 @@ class TestPrefixHandler(BaseTest): @pytest.fixture(scope='class', params=[1, 2], ids=['single prefix', 'multiple prefixes']) def prefixes(self, request): - return TestPrefixHandler.PREFIXES[:request.param] + return TestPrefixHandler.PREFIXES[: request.param] @pytest.fixture(scope='class', params=COMMANDS) def command(self, request): @@ -299,7 +311,7 @@ class TestPrefixHandler(BaseTest): @pytest.fixture(scope='class', params=[1, 2], ids=['single command', 'multiple commands']) def commands(self, request): - return TestPrefixHandler.COMMANDS[:request.param] + return TestPrefixHandler.COMMANDS[: request.param] @pytest.fixture(scope='class') def prefix_message_text(self, prefix, command): @@ -363,11 +375,13 @@ class TestPrefixHandler(BaseTest): @pytest.mark.parametrize('pass_keyword', BaseTest.PASS_KEYWORDS) def test_pass_data(self, dp, pass_combination, prefix_message_update, pass_keyword): """Assert that callbacks receive data iff its corresponding ``pass_*`` kwarg is enabled""" - handler = self.make_default_handler(self.make_callback_for(pass_keyword), - **pass_combination) + handler = self.make_default_handler( + self.make_callback_for(pass_keyword), **pass_combination + ) dp.add_handler(handler) - assert self.response(dp, prefix_message_update) \ - == pass_combination.get(pass_keyword, False) + assert self.response(dp, prefix_message_update) == pass_combination.get( + pass_keyword, False + ) def test_other_update_types(self, false_update): handler = self.make_default_handler() @@ -412,12 +426,13 @@ class TestPrefixHandler(BaseTest): self._test_context_args_or_regex(cdp, handler, prefix_message_text) def test_context_regex(self, cdp, prefix_message_text): - handler = self.make_default_handler(self.callback_context_regex1, - filters=Filters.regex('one two')) + handler = self.make_default_handler( + self.callback_context_regex1, filters=Filters.regex('one two') + ) self._test_context_args_or_regex(cdp, handler, prefix_message_text) def test_context_multiple_regex(self, cdp, prefix_message_text): - handler = self.make_default_handler(self.callback_context_regex2, - filters=Filters.regex('one') & Filters.regex( - 'two')) + handler = self.make_default_handler( + self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two') + ) self._test_context_args_or_regex(cdp, handler, prefix_message_text) diff --git a/tests/test_constants.py b/tests/test_constants.py index c0a279ca0..6f7eac47e 100644 --- a/tests/test_constants.py +++ b/tests/test_constants.py @@ -29,8 +29,11 @@ class TestConstants: def test_max_message_length(self, bot, chat_id): bot.send_message(chat_id=chat_id, text='a' * constants.MAX_MESSAGE_LENGTH) - with pytest.raises(BadRequest, match='Message is too long', - message='MAX_MESSAGE_LENGTH is no longer valid'): + with pytest.raises( + BadRequest, + match='Message is too long', + message='MAX_MESSAGE_LENGTH is no longer valid', + ): bot.send_message(chat_id=chat_id, text='a' * (constants.MAX_MESSAGE_LENGTH + 1)) @flaky(3, 1) @@ -42,7 +45,10 @@ class TestConstants: assert good_msg.caption == good_caption bad_caption = good_caption + 'Z' - with pytest.raises(BadRequest, match="Media_caption_too_long", - message='MAX_CAPTION_LENGTH is no longer valid'): + with pytest.raises( + BadRequest, + match="Media_caption_too_long", + message='MAX_CAPTION_LENGTH is no longer valid', + ): with open('tests/data/telegram.png', 'rb') as f: bot.send_photo(photo=f, caption=bad_caption, chat_id=chat_id) diff --git a/tests/test_contact.py b/tests/test_contact.py index 8943ce3dd..204f63281 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -24,8 +24,12 @@ from telegram import Contact, Voice @pytest.fixture(scope='class') def contact(): - return Contact(TestContact.phone_number, TestContact.first_name, TestContact.last_name, - TestContact.user_id) + return Contact( + TestContact.phone_number, + TestContact.first_name, + TestContact.last_name, + TestContact.user_id, + ) class TestContact: @@ -42,8 +46,12 @@ class TestContact: assert contact.first_name == self.first_name def test_de_json_all(self, bot): - json_dict = {'phone_number': self.phone_number, 'first_name': self.first_name, - 'last_name': self.last_name, 'user_id': self.user_id} + json_dict = { + 'phone_number': self.phone_number, + 'first_name': self.first_name, + 'last_name': self.last_name, + 'user_id': self.user_id, + } contact = Contact.de_json(json_dict, bot) assert contact.phone_number == self.phone_number diff --git a/tests/test_conversationhandler.py b/tests/test_conversationhandler.py index e0f8650c8..06b99e42e 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -21,11 +21,30 @@ from time import sleep import pytest -from telegram import (CallbackQuery, Chat, ChosenInlineResult, InlineQuery, Message, - PreCheckoutQuery, ShippingQuery, Update, User, MessageEntity) -from telegram.ext import (ConversationHandler, CommandHandler, CallbackQueryHandler, - MessageHandler, Filters, InlineQueryHandler, CallbackContext, - DispatcherHandlerStop, TypeHandler, JobQueue) +from telegram import ( + CallbackQuery, + Chat, + ChosenInlineResult, + InlineQuery, + Message, + PreCheckoutQuery, + ShippingQuery, + Update, + User, + MessageEntity, +) +from telegram.ext import ( + ConversationHandler, + CommandHandler, + CallbackQueryHandler, + MessageHandler, + Filters, + InlineQueryHandler, + CallbackContext, + DispatcherHandlerStop, + TypeHandler, + JobQueue, +) @pytest.fixture(scope='class') @@ -83,18 +102,18 @@ class TestConversationHandler: self.current_state = dict() self.entry_points = [CommandHandler('start', self.start)] self.states = { - self.THIRSTY: [CommandHandler('brew', self.brew), - CommandHandler('wait', self.start)], + self.THIRSTY: [CommandHandler('brew', self.brew), CommandHandler('wait', self.start)], self.BREWING: [CommandHandler('pourCoffee', self.drink)], - self.DRINKING: - [CommandHandler('startCoding', self.code), - CommandHandler('drinkMore', self.drink), - CommandHandler('end', self.end)], + self.DRINKING: [ + CommandHandler('startCoding', self.code), + CommandHandler('drinkMore', self.drink), + CommandHandler('end', self.end), + ], self.CODING: [ CommandHandler('keepCoding', self.code), CommandHandler('gettingThirsty', self.start), - CommandHandler('drinkMore', self.drink) - ] + CommandHandler('drinkMore', self.drink), + ], } self.fallbacks = [CommandHandler('eat', self.start)] self.is_timeout = False @@ -106,20 +125,22 @@ class TestConversationHandler: self.CODING: [ CommandHandler('keepCoding', self.code), CommandHandler('gettingThirsty', self.start), - CommandHandler('drinkMore', self.drink) + CommandHandler('drinkMore', self.drink), ], } self.drinking_entry_points = [CommandHandler('hold', self.hold)] self.drinking_states = { self.HOLDING: [CommandHandler('sip', self.sip)], self.SIPPING: [CommandHandler('swallow', self.swallow)], - self.SWALLOWING: [CommandHandler('hold', self.hold)] + self.SWALLOWING: [CommandHandler('hold', self.hold)], } - self.drinking_fallbacks = [CommandHandler('replenish', self.replenish), - CommandHandler('stop', self.stop), - CommandHandler('end', self.end), - CommandHandler('startCoding', self.code), - CommandHandler('drinkMore', self.drink)] + self.drinking_fallbacks = [ + CommandHandler('replenish', self.replenish), + CommandHandler('stop', self.stop), + CommandHandler('end', self.end), + CommandHandler('startCoding', self.code), + CommandHandler('drinkMore', self.drink), + ] self.drinking_entry_points.extend(self.drinking_fallbacks) # Map nested states to parent states: @@ -133,7 +154,7 @@ class TestConversationHandler: # Option 4 - Map an external state to the same external parent state self.CODING: self.CODING, # Option 5 - Map an external state to the internal entry point - self.DRINKING: self.DRINKING + self.DRINKING: self.DRINKING, } # State handlers @@ -221,16 +242,34 @@ class TestConversationHandler: return self._set_state(update, self.STOPPING) # Tests - @pytest.mark.parametrize('attr', ['entry_points', 'states', 'fallbacks', 'per_chat', 'name', - 'per_user', 'allow_reentry', 'conversation_timeout', 'map_to_parent'], - indirect=False) + @pytest.mark.parametrize( + 'attr', + [ + 'entry_points', + 'states', + 'fallbacks', + 'per_chat', + 'name', + 'per_user', + 'allow_reentry', + 'conversation_timeout', + 'map_to_parent', + ], + indirect=False, + ) def test_immutable(self, attr): - ch = ConversationHandler('entry_points', {'states': ['states']}, 'fallbacks', - per_chat='per_chat', - per_user='per_user', per_message=False, - allow_reentry='allow_reentry', - conversation_timeout='conversation_timeout', - name='name', map_to_parent='map_to_parent') + ch = ConversationHandler( + 'entry_points', + {'states': ['states']}, + 'fallbacks', + per_chat='per_chat', + per_user='per_user', + per_message=False, + allow_reentry='allow_reentry', + conversation_timeout='conversation_timeout', + name='name', + map_to_parent='map_to_parent', + ) value = getattr(ch, attr) if isinstance(value, list): @@ -243,20 +282,32 @@ class TestConversationHandler: setattr(ch, attr, True) def test_immutable_per_message(self): - ch = ConversationHandler('entry_points', {'states': ['states']}, 'fallbacks', - per_chat='per_chat', - per_user='per_user', per_message=False, - allow_reentry='allow_reentry', - conversation_timeout='conversation_timeout', - name='name', map_to_parent='map_to_parent') + ch = ConversationHandler( + 'entry_points', + {'states': ['states']}, + 'fallbacks', + per_chat='per_chat', + per_user='per_user', + per_message=False, + allow_reentry='allow_reentry', + conversation_timeout='conversation_timeout', + name='name', + map_to_parent='map_to_parent', + ) assert ch.per_message is False with pytest.raises(ValueError, match='You can not assign a new value to per_message'): ch.per_message = True def test_per_all_false(self): with pytest.raises(ValueError, match="can't all be 'False'"): - ConversationHandler(self.entry_points, self.states, self.fallbacks, - per_chat=False, per_user=False, per_message=False) + ConversationHandler( + self.entry_points, + self.states, + self.fallbacks, + per_chat=False, + per_user=False, + per_message=False, + ) def test_name_and_persistent(self, dp): with pytest.raises(ValueError, match="when handler is unnamed"): @@ -265,15 +316,23 @@ class TestConversationHandler: assert c.name == "handler" def test_conversation_handler(self, dp, bot, user1, user2): - handler = ConversationHandler(entry_points=self.entry_points, states=self.states, - fallbacks=self.fallbacks) + handler = ConversationHandler( + entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks + ) dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.THIRSTY @@ -303,14 +362,22 @@ class TestConversationHandler: self.current_state[user2.id] def test_conversation_handler_end(self, caplog, dp, bot, user1): - handler = ConversationHandler(entry_points=self.entry_points, states=self.states, - fallbacks=self.fallbacks) + handler = ConversationHandler( + entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks + ) dp.add_handler(handler) - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) message.text = '/brew' message.entities[0].length = len('/brew') @@ -329,15 +396,21 @@ class TestConversationHandler: print(handler.conversations[(self.group.id, user1.id)]) def test_conversation_handler_fallback(self, dp, bot, user1, user2): - handler = ConversationHandler(entry_points=self.entry_points, states=self.states, - fallbacks=self.fallbacks) + handler = ConversationHandler( + entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks + ) dp.add_handler(handler) # first check if fallback will not trigger start when not started - message = Message(0, None, self.group, from_user=user1, text='/eat', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/eat'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/eat', + entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/eat'))], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) with pytest.raises(KeyError): self.current_state[user1.id] @@ -365,14 +438,22 @@ class TestConversationHandler: entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks, - per_user=False) + per_user=False, + ) dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) # The user is thirsty and wants to brew coffee. @@ -394,14 +475,22 @@ class TestConversationHandler: entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks, - per_chat=False) + per_chat=False, + ) dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) # The user is thirsty and wants to brew coffee. @@ -430,15 +519,16 @@ class TestConversationHandler: handler = ConversationHandler( entry_points=[CallbackQueryHandler(entry)], - states={1: [CallbackQueryHandler(one)], - 2: [CallbackQueryHandler(two)]}, + states={1: [CallbackQueryHandler(one)], 2: [CallbackQueryHandler(two)]}, fallbacks=[], - per_message=True) + per_message=True, + ) dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, None, self.group, from_user=user1, text='msg w/ inlinekeyboard', - bot=bot) + message = Message( + 0, None, self.group, from_user=user1, text='msg w/ inlinekeyboard', bot=bot + ) cbq = CallbackQuery(0, user1, None, message=message, data='data', bot=bot) dp.process_update(Update(update_id=0, callback_query=cbq)) @@ -458,15 +548,22 @@ class TestConversationHandler: def test_end_on_first_message(self, dp, bot, user1): handler = ConversationHandler( - entry_points=[CommandHandler('start', self.start_end)], states={}, - fallbacks=[]) + entry_points=[CommandHandler('start', self.start_end)], states={}, fallbacks=[] + ) dp.add_handler(handler) # User starts the state machine and immediately ends it. - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) assert len(handler.conversations) == 0 @@ -474,55 +571,72 @@ class TestConversationHandler: start_end_async = (lambda bot, update: dp.run_async(self.start_end, bot, update)) handler = ConversationHandler( - entry_points=[CommandHandler('start', start_end_async)], states={}, - fallbacks=[]) + entry_points=[CommandHandler('start', start_end_async)], states={}, fallbacks=[] + ) dp.add_handler(handler) # User starts the state machine with an async function that immediately ends the # conversation. Async results are resolved when the users state is queried next time. - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been accepted as the new state assert len(handler.conversations) == 1 message.text = 'resolve promise pls' message.entities[0].length = len('resolve promise pls') dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been resolved and the conversation ended. assert len(handler.conversations) == 0 def test_end_on_first_message_async_handler(self, dp, bot, user1): handler = ConversationHandler( - entry_points=[CommandHandler('start', self.start_end, run_async=True)], states={}, - fallbacks=[]) + entry_points=[CommandHandler('start', self.start_end, run_async=True)], + states={}, + fallbacks=[], + ) dp.add_handler(handler) # User starts the state machine with an async function that immediately ends the # conversation. Async results are resolved when the users state is queried next time. - message = Message(0, None, self.group, text='/start', from_user=user1, - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + text='/start', + from_user=user1, + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been accepted as the new state assert len(handler.conversations) == 1 message.text = 'resolve promise pls' message.entities[0].length = len('resolve promise pls') dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been resolved and the conversation ended. assert len(handler.conversations) == 0 def test_none_on_first_message(self, dp, bot, user1): handler = ConversationHandler( - entry_points=[CommandHandler('start', self.start_none)], states={}, fallbacks=[]) + entry_points=[CommandHandler('start', self.start_none)], states={}, fallbacks=[] + ) dp.add_handler(handler) # User starts the state machine and a callback function returns None @@ -534,67 +648,86 @@ class TestConversationHandler: start_none_async = (lambda bot, update: dp.run_async(self.start_none, bot, update)) handler = ConversationHandler( - entry_points=[CommandHandler('start', start_none_async)], states={}, fallbacks=[]) + entry_points=[CommandHandler('start', start_none_async)], states={}, fallbacks=[] + ) dp.add_handler(handler) # User starts the state machine with an async function that returns None # Async results are resolved when the users state is queried next time. - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been accepted as the new state assert len(handler.conversations) == 1 message.text = 'resolve promise pls' dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been resolved and the conversation ended. assert len(handler.conversations) == 0 def test_none_on_first_message_async_handler(self, dp, bot, user1): handler = ConversationHandler( - entry_points=[CommandHandler('start', self.start_none, run_async=True)], states={}, - fallbacks=[]) + entry_points=[CommandHandler('start', self.start_none, run_async=True)], + states={}, + fallbacks=[], + ) dp.add_handler(handler) # User starts the state machine with an async function that returns None # Async results are resolved when the users state is queried next time. - message = Message(0, None, self.group, text='/start', from_user=user1, - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + text='/start', + from_user=user1, + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been accepted as the new state assert len(handler.conversations) == 1 message.text = 'resolve promise pls' dp.update_queue.put(Update(update_id=0, message=message)) - sleep(.1) + sleep(0.1) # Assert that the Promise has been resolved and the conversation ended. assert len(handler.conversations) == 0 def test_per_chat_message_without_chat(self, bot, user1): handler = ConversationHandler( - entry_points=[CommandHandler('start', self.start_end)], states={}, - fallbacks=[]) + entry_points=[CommandHandler('start', self.start_end)], states={}, fallbacks=[] + ) cbq = CallbackQuery(0, user1, None, None, bot=bot) update = Update(0, callback_query=cbq) assert not handler.check_update(update) def test_channel_message_without_chat(self, bot): - handler = ConversationHandler(entry_points=[CommandHandler('start', self.start_end)], - states={}, fallbacks=[]) + handler = ConversationHandler( + entry_points=[CommandHandler('start', self.start_end)], states={}, fallbacks=[] + ) message = Message(0, None, None, Chat(0, Chat.CHANNEL, 'Misses Test'), bot=bot) update = Update(0, message=message) assert not handler.check_update(update) def test_all_update_types(self, dp, bot, user1): - handler = ConversationHandler(entry_points=[CommandHandler('start', self.start_end)], - states={}, fallbacks=[]) + handler = ConversationHandler( + entry_points=[CommandHandler('start', self.start_end)], states={}, fallbacks=[] + ) message = Message(0, None, self.group, from_user=user1, text='ignore', bot=bot) callback_query = CallbackQuery(0, user1, None, message=message, data='data', bot=bot) chosen_inline_result = ChosenInlineResult(0, user1, 'query', bot=bot) @@ -609,15 +742,26 @@ class TestConversationHandler: assert not handler.check_update(Update(0, shipping_query=shipping_query)) def test_conversation_timeout(self, dp, bot, user1): - handler = ConversationHandler(entry_points=self.entry_points, states=self.states, - fallbacks=self.fallbacks, conversation_timeout=0.5) + handler = ConversationHandler( + entry_points=self.entry_points, + states=self.states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) dp.add_handler(handler) # Start state machine, then reach timeout - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) assert handler.conversations.get((self.group.id, user1.id)) == self.THIRSTY sleep(0.65) @@ -634,8 +778,12 @@ class TestConversationHandler: assert handler.conversations.get((self.group.id, user1.id)) is None def test_conversation_timeout_dispatcher_handler_stop(self, dp, bot, user1, caplog): - handler = ConversationHandler(entry_points=self.entry_points, states=self.states, - fallbacks=self.fallbacks, conversation_timeout=0.5) + handler = ConversationHandler( + entry_points=self.entry_points, + states=self.states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) def timeout(*args, **kwargs): raise DispatcherHandlerStop() @@ -644,10 +792,17 @@ class TestConversationHandler: dp.add_handler(handler) # Start state machine, then reach timeout - message = Message(0, None, self.group, text='/start', from_user=user1, - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + text='/start', + from_user=user1, + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) with caplog.at_level(logging.WARNING): dp.process_update(Update(update_id=0, message=message)) @@ -669,16 +824,26 @@ class TestConversationHandler: states = self.states timeout_handler = CommandHandler('start', None) states.update({ConversationHandler.TIMEOUT: [timeout_handler]}) - handler = ConversationHandler(entry_points=[CommandHandler('start', start_callback)], - states=states, fallbacks=self.fallbacks, - conversation_timeout=0.5) + handler = ConversationHandler( + entry_points=[CommandHandler('start', start_callback)], + states=states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) cdp.add_handler(handler) # Start state machine, then reach timeout - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, - length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) update = Update(update_id=0, message=message) def timeout_callback(u, c): @@ -695,8 +860,12 @@ class TestConversationHandler: assert self.is_timeout def test_conversation_timeout_keeps_extending(self, dp, bot, user1): - handler = ConversationHandler(entry_points=self.entry_points, states=self.states, - fallbacks=self.fallbacks, conversation_timeout=0.5) + handler = ConversationHandler( + entry_points=self.entry_points, + states=self.states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) dp.add_handler(handler) # Start state machine, wait, do something, verify the timeout is extended. @@ -706,10 +875,17 @@ class TestConversationHandler: # t=.6 /pourCoffee (timeout=1.1) # t=.75 second timeout # t=1.1 actual timeout - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) assert handler.conversations.get((self.group.id, user1.id)) == self.THIRSTY sleep(0.25) # t=.25 @@ -724,21 +900,32 @@ class TestConversationHandler: message.entities[0].length = len('/pourCoffee') dp.process_update(Update(update_id=0, message=message)) assert handler.conversations.get((self.group.id, user1.id)) == self.DRINKING - sleep(.4) # t=1 + sleep(0.4) # t=1 assert handler.conversations.get((self.group.id, user1.id)) == self.DRINKING - sleep(.2) # t=1.2 + sleep(0.2) # t=1.2 assert handler.conversations.get((self.group.id, user1.id)) is None def test_conversation_timeout_two_users(self, dp, bot, user1, user2): - handler = ConversationHandler(entry_points=self.entry_points, states=self.states, - fallbacks=self.fallbacks, conversation_timeout=0.5) + handler = ConversationHandler( + entry_points=self.entry_points, + states=self.states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) dp.add_handler(handler) # Start state machine, do something as second user, then reach timeout - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, - length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) assert handler.conversations.get((self.group.id, user1.id)) == self.THIRSTY message.text = '/brew' @@ -757,19 +944,34 @@ class TestConversationHandler: def test_conversation_handler_timeout_state(self, dp, bot, user1): states = self.states - states.update({ConversationHandler.TIMEOUT: [ - CommandHandler('brew', self.passout), - MessageHandler(~Filters.regex('oding'), self.passout2) - ]}) - handler = ConversationHandler(entry_points=self.entry_points, states=states, - fallbacks=self.fallbacks, conversation_timeout=0.5) + states.update( + { + ConversationHandler.TIMEOUT: [ + CommandHandler('brew', self.passout), + MessageHandler(~Filters.regex('oding'), self.passout2), + ] + } + ) + handler = ConversationHandler( + entry_points=self.entry_points, + states=states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) dp.add_handler(handler) # CommandHandler timeout - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, - length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) message.text = '/brew' message.entities[0].length = len('/brew') @@ -802,19 +1004,34 @@ class TestConversationHandler: def test_conversation_handler_timeout_state_context(self, cdp, bot, user1): states = self.states - states.update({ConversationHandler.TIMEOUT: [ - CommandHandler('brew', self.passout_context), - MessageHandler(~Filters.regex('oding'), self.passout2_context) - ]}) - handler = ConversationHandler(entry_points=self.entry_points, states=states, - fallbacks=self.fallbacks, conversation_timeout=0.5) + states.update( + { + ConversationHandler.TIMEOUT: [ + CommandHandler('brew', self.passout_context), + MessageHandler(~Filters.regex('oding'), self.passout2_context), + ] + } + ) + handler = ConversationHandler( + entry_points=self.entry_points, + states=states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) cdp.add_handler(handler) # CommandHandler timeout - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, - length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) cdp.process_update(Update(update_id=0, message=message)) message.text = '/brew' message.entities[0].length = len('/brew') @@ -863,19 +1080,28 @@ class TestConversationHandler: states = self.states states[self.THIRSTY].append(CommandHandler('slowbrew', slowbrew)) - states.update({ConversationHandler.TIMEOUT: [ - MessageHandler(None, self.passout2) - ]}) + states.update({ConversationHandler.TIMEOUT: [MessageHandler(None, self.passout2)]}) - handler = ConversationHandler(entry_points=self.entry_points, states=states, - fallbacks=self.fallbacks, conversation_timeout=0.5) + handler = ConversationHandler( + entry_points=self.entry_points, + states=states, + fallbacks=self.fallbacks, + conversation_timeout=0.5, + ) dp.add_handler(handler) # CommandHandler timeout - message = Message(0, None, self.group, from_user=user1, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, - length=len('/start'))], - bot=bot) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ) dp.process_update(Update(update_id=0, message=message)) sleep(0.25) message.text = '/slowbrew' @@ -893,10 +1119,10 @@ class TestConversationHandler: entry_points=self.entry_points, states={ self.THIRSTY: [CommandHandler('pourCoffee', self.drink)], - self.BREWING: [CommandHandler('startCoding', self.code)] + self.BREWING: [CommandHandler('startCoding', self.code)], }, fallbacks=self.fallbacks, - per_message=True + per_message=True, ) assert len(recwarn) == 1 assert str(recwarn[0].message) == ( @@ -913,7 +1139,7 @@ class TestConversationHandler: self.BREWING: [CallbackQueryHandler(self.code)], }, fallbacks=self.fallbacks, - per_message=False + per_message=False, ) assert len(recwarn) == 1 assert str(recwarn[0].message) == ( @@ -932,10 +1158,10 @@ class TestConversationHandler: entry_points=self.entry_points, states={ self.THIRSTY: [InlineQueryHandler(hello)], - self.BREWING: [InlineQueryHandler(bye)] + self.BREWING: [InlineQueryHandler(bye)], }, fallbacks=self.fallbacks, - per_chat=True + per_chat=True, ) assert len(recwarn) == 1 assert str(recwarn[0].message) == ( @@ -944,20 +1170,31 @@ class TestConversationHandler: ) def test_nested_conversation_handler(self, dp, bot, user1, user2): - self.nested_states[self.DRINKING] = [ConversationHandler( - entry_points=self.drinking_entry_points, - states=self.drinking_states, - fallbacks=self.drinking_fallbacks, - map_to_parent=self.drinking_map_to_parent)] - handler = ConversationHandler(entry_points=self.entry_points, - states=self.nested_states, - fallbacks=self.fallbacks) + self.nested_states[self.DRINKING] = [ + ConversationHandler( + entry_points=self.drinking_entry_points, + states=self.drinking_states, + fallbacks=self.drinking_fallbacks, + map_to_parent=self.drinking_map_to_parent, + ) + ] + handler = ConversationHandler( + entry_points=self.entry_points, states=self.nested_states, fallbacks=self.fallbacks + ) dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, None, self.group, from_user=user1, text='/start', bot=bot, - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))]) + message = Message( + 0, + None, + self.group, + from_user=user1, + text='/start', + bot=bot, + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + ) dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.THIRSTY @@ -1049,14 +1286,17 @@ class TestConversationHandler: assert handler.conversations.get((0, user1.id)) is None def test_conversation_dispatcher_handler_stop(self, dp, bot, user1, user2): - self.nested_states[self.DRINKING] = [ConversationHandler( - entry_points=self.drinking_entry_points, - states=self.drinking_states, - fallbacks=self.drinking_fallbacks, - map_to_parent=self.drinking_map_to_parent)] - handler = ConversationHandler(entry_points=self.entry_points, - states=self.nested_states, - fallbacks=self.fallbacks) + self.nested_states[self.DRINKING] = [ + ConversationHandler( + entry_points=self.drinking_entry_points, + states=self.drinking_states, + fallbacks=self.drinking_fallbacks, + map_to_parent=self.drinking_map_to_parent, + ) + ] + handler = ConversationHandler( + entry_points=self.entry_points, states=self.nested_states, fallbacks=self.fallbacks + ) def test_callback(u, c): self.test_flag = True @@ -1066,9 +1306,17 @@ class TestConversationHandler: self.raise_dp_handler_stop = True # User one, starts the state machine. - message = Message(0, None, self.group, text='/start', bot=bot, from_user=user1, - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, length=len('/start'))]) + message = Message( + 0, + None, + self.group, + text='/start', + bot=bot, + from_user=user1, + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + ) dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.THIRSTY assert not self.test_flag diff --git a/tests/test_dice.py b/tests/test_dice.py index 1349e8e4b..6eb243c6c 100644 --- a/tests/test_dice.py +++ b/tests/test_dice.py @@ -22,8 +22,7 @@ import pytest from telegram import Dice, BotCommand -@pytest.fixture(scope="class", - params=Dice.ALL_EMOJI) +@pytest.fixture(scope="class", params=Dice.ALL_EMOJI) def dice(request): return Dice(value=5, emoji=request.param) diff --git a/tests/test_dispatcher.py b/tests/test_dispatcher.py index 3e7f75537..adb0e9a1b 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -24,8 +24,14 @@ from time import sleep import pytest from telegram import TelegramError, Message, User, Chat, Update, Bot, MessageEntity -from telegram.ext import (MessageHandler, Filters, CommandHandler, CallbackContext, - JobQueue, BasePersistence) +from telegram.ext import ( + MessageHandler, + Filters, + CommandHandler, + CallbackContext, + JobQueue, + BasePersistence, +) from telegram.ext.dispatcher import run_async, Dispatcher, DispatcherHandlerStop from telegram.utils.deprecate import TelegramDeprecationWarning from tests.conftest import create_dp @@ -39,9 +45,9 @@ def dp2(bot): class TestDispatcher: - message_update = Update(1, - message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), - text='Text')) + message_update = Update( + 1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') + ) received = None count = 0 @@ -81,11 +87,13 @@ class TestDispatcher: self.received = update.message def callback_context(self, update, context): - if (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.error, TelegramError)): + if ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.error, TelegramError) + ): self.received = context.error.message def test_one_context_per_update(self, cdp): @@ -112,7 +120,7 @@ class TestDispatcher: dp.add_error_handler(self.error_handler) error = TelegramError('Unauthorized.') dp.update_queue.put(error) - sleep(.1) + sleep(0.1) assert self.received == 'Unauthorized.' # Remove handler @@ -120,7 +128,7 @@ class TestDispatcher: self.reset() dp.update_queue.put(error) - sleep(.1) + sleep(0.1) assert self.received is None def test_double_add_error_handler(self, dp, caplog): @@ -137,8 +145,9 @@ class TestDispatcher: self.store_chat_data = False self.store_bot_data = False - with pytest.raises(TypeError, - match='persistence must be based on telegram.ext.BasePersistence'): + with pytest.raises( + TypeError, match='persistence must be based on telegram.ext.BasePersistence' + ): Dispatcher(bot, None, persistence=my_per()) def test_error_handler_that_raises_errors(self, dp): @@ -154,14 +163,14 @@ class TestDispatcher: # From errors caused by handlers dp.add_handler(handler_raise_error) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) # From errors in the update_queue dp.remove_handler(handler_raise_error) dp.add_handler(handler_increase_count) dp.update_queue.put(error) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.count == 1 @@ -175,7 +184,7 @@ class TestDispatcher: dp.run_async(get_dispatcher_name, q1) dp2.run_async(get_dispatcher_name, q2) - sleep(.1) + sleep(0.1) name1 = q1.get() name2 = q2.get() @@ -196,12 +205,14 @@ class TestDispatcher: must_raise_runtime_error() def test_run_async_with_args(self, dp): - dp.add_handler(MessageHandler(Filters.all, - run_async(self.callback_if_not_update_queue), - pass_update_queue=True)) + dp.add_handler( + MessageHandler( + Filters.all, run_async(self.callback_if_not_update_queue), pass_update_queue=True + ) + ) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.received == self.message_update.message def test_multiple_run_async_deprecation(self, dp): @@ -225,10 +236,11 @@ class TestDispatcher: with caplog.at_level(logging.WARNING): dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert len(caplog.records) == 1 - assert caplog.records[-1].msg.startswith('DispatcherHandlerStop is not supported ' - 'with async functions') + assert caplog.records[-1].msg.startswith( + 'DispatcherHandlerStop is not supported ' 'with async functions' + ) def test_async_raises_exception(self, dp, caplog): @run_async @@ -239,18 +251,22 @@ class TestDispatcher: with caplog.at_level(logging.WARNING): dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert len(caplog.records) == 1 assert caplog.records[-1].msg.startswith('A promise with deactivated error handling') def test_add_async_handler(self, dp): - dp.add_handler(MessageHandler(Filters.all, - self.callback_if_not_update_queue, - pass_update_queue=True, - run_async=True)) + dp.add_handler( + MessageHandler( + Filters.all, + self.callback_if_not_update_queue, + pass_update_queue=True, + run_async=True, + ) + ) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.received == self.message_update.message def test_run_async_no_error_handler(self, dp, caplog): @@ -259,24 +275,20 @@ class TestDispatcher: with caplog.at_level(logging.ERROR): dp.run_async(func) - sleep(.1) + sleep(0.1) assert len(caplog.records) == 1 assert caplog.records[-1].msg.startswith('No error handlers are registered') def test_async_handler_error_handler(self, dp): - dp.add_handler(MessageHandler(Filters.all, - self.callback_raise_error, - run_async=True)) + dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error, run_async=True)) dp.add_error_handler(self.error_handler) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.received == self.message_update.message.text def test_async_handler_async_error_handler_context(self, cdp): - cdp.add_handler(MessageHandler(Filters.all, - self.callback_raise_error, - run_async=True)) + cdp.add_handler(MessageHandler(Filters.all, self.callback_raise_error, run_async=True)) cdp.add_error_handler(self.error_handler_context, run_async=True) cdp.update_queue.put(self.message_update) @@ -284,47 +296,39 @@ class TestDispatcher: assert self.received == self.message_update.message.text def test_async_handler_error_handler_that_raises_error(self, dp, caplog): - handler = MessageHandler(Filters.all, - self.callback_raise_error, - run_async=True) + handler = MessageHandler(Filters.all, self.callback_raise_error, run_async=True) dp.add_handler(handler) dp.add_error_handler(self.error_handler_raise_error, run_async=False) with caplog.at_level(logging.ERROR): dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert len(caplog.records) == 1 assert caplog.records[-1].msg.startswith('An uncaught error was raised') # Make sure that the main loop still runs dp.remove_handler(handler) - dp.add_handler(MessageHandler(Filters.all, - self.callback_increase_count, - run_async=True)) + dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count, run_async=True)) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.count == 1 def test_async_handler_async_error_handler_that_raises_error(self, dp, caplog): - handler = MessageHandler(Filters.all, - self.callback_raise_error, - run_async=True) + handler = MessageHandler(Filters.all, self.callback_raise_error, run_async=True) dp.add_handler(handler) dp.add_error_handler(self.error_handler_raise_error, run_async=True) with caplog.at_level(logging.ERROR): dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert len(caplog.records) == 1 assert caplog.records[-1].msg.startswith('An uncaught error was raised') # Make sure that the main loop still runs dp.remove_handler(handler) - dp.add_handler(MessageHandler(Filters.all, - self.callback_increase_count, - run_async=True)) + dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count, run_async=True)) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.count == 1 def test_error_in_handler(self, dp): @@ -332,14 +336,14 @@ class TestDispatcher: dp.add_error_handler(self.error_handler) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.received == self.message_update.message.text def test_add_remove_handler(self, dp): handler = MessageHandler(Filters.all, self.callback_increase_count) dp.add_handler(handler) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.count == 1 dp.remove_handler(handler) dp.update_queue.put(self.message_update) @@ -361,7 +365,7 @@ class TestDispatcher: dp.add_handler(MessageHandler(Filters.all, self.callback_set_count(2))) dp.add_handler(MessageHandler(Filters.text, self.callback_set_count(3))) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.count == 2 def test_groups(self, dp): @@ -370,7 +374,7 @@ class TestDispatcher: dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=-1) dp.update_queue.put(self.message_update) - sleep(.1) + sleep(0.1) assert self.count == 3 def test_add_handler_errors(self, dp): @@ -399,11 +403,20 @@ class TestDispatcher: passed.append('error') passed.append(e) - update = Update(1, message=Message(1, None, None, None, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, - length=len('/start'))], - bot=bot)) + update = Update( + 1, + message=Message( + 1, + None, + None, + None, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ), + ) # If Stop raised handlers in other groups should not be called. passed = [] @@ -431,11 +444,20 @@ class TestDispatcher: passed.append('error') passed.append(e) - update = Update(1, message=Message(1, None, None, None, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, - length=len('/start'))], - bot=bot)) + update = Update( + 1, + message=Message( + 1, + None, + None, + None, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ), + ) # If an unhandled exception was caught, no further handlers from the same group should be # called. Also, the error handler should be called and receive the exception @@ -465,11 +487,20 @@ class TestDispatcher: passed.append('error') passed.append(e) - update = Update(1, message=Message(1, None, None, None, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, - length=len('/start'))], - bot=bot)) + update = Update( + 1, + message=Message( + 1, + None, + None, + None, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ), + ) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. @@ -524,13 +555,20 @@ class TestDispatcher: # If updating a user_data or chat_data from a persistence object throws an error, # the error handler should catch it - update = Update(1, message=Message(1, None, Chat(1, "lala"), - from_user=User(1, "Test", False), - text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, - length=len('/start'))], - bot=bot)) + update = Update( + 1, + message=Message( + 1, + None, + Chat(1, "lala"), + from_user=User(1, "Test", False), + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ), + ) my_persistence = OwnPersistence() dp = Dispatcher(bot, None, persistence=my_persistence, use_context=False) dp.add_handler(CommandHandler('start', start1)) @@ -557,11 +595,20 @@ class TestDispatcher: passed.append(e) raise DispatcherHandlerStop - update = Update(1, message=Message(1, None, None, None, text='/start', - entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, - offset=0, - length=len('/start'))], - bot=bot)) + update = Update( + 1, + message=Message( + 1, + None, + None, + None, + text='/start', + entities=[ + MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) + ], + bot=bot, + ), + ) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. @@ -578,7 +625,7 @@ class TestDispatcher: error = TelegramError('Unauthorized.') cdp.update_queue.put(error) - sleep(.1) + sleep(0.1) assert self.received == 'Unauthorized.' def test_sensible_worker_thread_names(self, dp2): @@ -589,8 +636,9 @@ class TestDispatcher: def test_non_context_deprecation(self, dp): with pytest.warns(TelegramDeprecationWarning): - Dispatcher(dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0, - use_context=False) + Dispatcher( + dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0, use_context=False + ) def test_error_while_persisting(self, cdp, monkeypatch): class OwnPersistence(BasePersistence): @@ -640,8 +688,9 @@ class TestDispatcher: def logger(message): assert 'uncaught error was raised while handling' in message - update = Update(1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), - text='Text')) + update = Update( + 1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') + ) handler = MessageHandler(Filters.all, callback) cdp.add_handler(handler) cdp.add_error_handler(error) @@ -693,8 +742,9 @@ class TestDispatcher: cdp.add_handler(handler) cdp.persistence = OwnPersistence() - update = Update(1, message=Message(1, None, None, from_user=User(1, '', False), - text='Text')) + update = Update( + 1, message=Message(1, None, None, from_user=User(1, '', False), text='Text') + ) cdp.process_update(update) assert cdp.persistence.test_flag_bot_data assert cdp.persistence.test_flag_user_data diff --git a/tests/test_document.py b/tests/test_document.py index 32d40baec..39f111560 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -68,9 +68,15 @@ class TestDocument: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_all_args(self, bot, chat_id, document_file, document, thumb_file): - message = bot.send_document(chat_id, document=document_file, caption=self.caption, - disable_notification=False, filename='telegram_custom.png', - parse_mode='Markdown', thumb=thumb_file) + message = bot.send_document( + chat_id, + document=document_file, + caption=self.caption, + disable_notification=False, + filename='telegram_custom.png', + parse_mode='Markdown', + thumb=thumb_file, + ) assert isinstance(message.document, Document) assert isinstance(message.document.file_id, str) @@ -150,8 +156,9 @@ class TestDocument: def test_send_document_default_parse_mode_2(self, default_bot, chat_id, document): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_document(chat_id, document, caption=test_markdown_string, - parse_mode=None) + message = default_bot.send_document( + chat_id, document, caption=test_markdown_string, parse_mode=None + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -161,8 +168,9 @@ class TestDocument: def test_send_document_default_parse_mode_3(self, default_bot, chat_id, document): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_document(chat_id, document, caption=test_markdown_string, - parse_mode='HTML') + message = default_bot.send_document( + chat_id, document, caption=test_markdown_string, parse_mode='HTML' + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -173,7 +181,7 @@ class TestDocument: 'thumb': document.thumb.to_dict(), 'file_name': self.file_name, 'mime_type': self.mime_type, - 'file_size': self.file_size + 'file_size': self.file_size, } test_document = Document.de_json(json_dict, bot) diff --git a/tests/test_encryptedcredentials.py b/tests/test_encryptedcredentials.py index 9528eec23..aa4563bb7 100644 --- a/tests/test_encryptedcredentials.py +++ b/tests/test_encryptedcredentials.py @@ -24,9 +24,11 @@ from telegram import EncryptedCredentials, PassportElementError @pytest.fixture(scope='class') def encrypted_credentials(): - return EncryptedCredentials(TestEncryptedCredentials.data, - TestEncryptedCredentials.hash, - TestEncryptedCredentials.secret) + return EncryptedCredentials( + TestEncryptedCredentials.data, + TestEncryptedCredentials.hash, + TestEncryptedCredentials.secret, + ) class TestEncryptedCredentials: @@ -43,12 +45,9 @@ class TestEncryptedCredentials: encrypted_credentials_dict = encrypted_credentials.to_dict() assert isinstance(encrypted_credentials_dict, dict) - assert (encrypted_credentials_dict['data'] - == encrypted_credentials.data) - assert (encrypted_credentials_dict['hash'] - == encrypted_credentials.hash) - assert (encrypted_credentials_dict['secret'] - == encrypted_credentials.secret) + assert encrypted_credentials_dict['data'] == encrypted_credentials.data + assert encrypted_credentials_dict['hash'] == encrypted_credentials.hash + assert encrypted_credentials_dict['secret'] == encrypted_credentials.secret def test_equality(self): a = EncryptedCredentials(self.data, self.hash, self.secret) diff --git a/tests/test_encryptedpassportelement.py b/tests/test_encryptedpassportelement.py index bb1076679..f28927ea1 100644 --- a/tests/test_encryptedpassportelement.py +++ b/tests/test_encryptedpassportelement.py @@ -24,14 +24,16 @@ from telegram import EncryptedPassportElement, PassportFile, PassportElementErro @pytest.fixture(scope='class') def encrypted_passport_element(): - return EncryptedPassportElement(TestEncryptedPassportElement.type_, - data=TestEncryptedPassportElement.data, - phone_number=TestEncryptedPassportElement.phone_number, - email=TestEncryptedPassportElement.email, - files=TestEncryptedPassportElement.files, - front_side=TestEncryptedPassportElement.front_side, - reverse_side=TestEncryptedPassportElement.reverse_side, - selfie=TestEncryptedPassportElement.selfie) + return EncryptedPassportElement( + TestEncryptedPassportElement.type_, + data=TestEncryptedPassportElement.data, + phone_number=TestEncryptedPassportElement.phone_number, + email=TestEncryptedPassportElement.email, + files=TestEncryptedPassportElement.files, + front_side=TestEncryptedPassportElement.front_side, + reverse_side=TestEncryptedPassportElement.reverse_side, + selfie=TestEncryptedPassportElement.selfie, + ) class TestEncryptedPassportElement: @@ -58,21 +60,26 @@ class TestEncryptedPassportElement: encrypted_passport_element_dict = encrypted_passport_element.to_dict() assert isinstance(encrypted_passport_element_dict, dict) - assert (encrypted_passport_element_dict['type'] - == encrypted_passport_element.type) - assert (encrypted_passport_element_dict['data'] - == encrypted_passport_element.data) - assert (encrypted_passport_element_dict['phone_number'] - == encrypted_passport_element.phone_number) - assert (encrypted_passport_element_dict['email'] - == encrypted_passport_element.email) + assert encrypted_passport_element_dict['type'] == encrypted_passport_element.type + assert encrypted_passport_element_dict['data'] == encrypted_passport_element.data + assert ( + encrypted_passport_element_dict['phone_number'] + == encrypted_passport_element.phone_number + ) + assert encrypted_passport_element_dict['email'] == encrypted_passport_element.email assert isinstance(encrypted_passport_element_dict['files'], list) - assert (encrypted_passport_element_dict['front_side'] - == encrypted_passport_element.front_side.to_dict()) - assert (encrypted_passport_element_dict['reverse_side'] - == encrypted_passport_element.reverse_side.to_dict()) - assert (encrypted_passport_element_dict['selfie'] - == encrypted_passport_element.selfie.to_dict()) + assert ( + encrypted_passport_element_dict['front_side'] + == encrypted_passport_element.front_side.to_dict() + ) + assert ( + encrypted_passport_element_dict['reverse_side'] + == encrypted_passport_element.reverse_side.to_dict() + ) + assert ( + encrypted_passport_element_dict['selfie'] + == encrypted_passport_element.selfie.to_dict() + ) def test_equality(self): a = EncryptedPassportElement(self.type_, data=self.data) diff --git a/tests/test_error.py b/tests/test_error.py index 791c86bb7..5f4f96090 100644 --- a/tests/test_error.py +++ b/tests/test_error.py @@ -22,8 +22,16 @@ from collections import defaultdict import pytest from telegram import TelegramError, TelegramDecryptionError -from telegram.error import Unauthorized, InvalidToken, NetworkError, BadRequest, TimedOut, \ - ChatMigrated, RetryAfter, Conflict +from telegram.error import ( + Unauthorized, + InvalidToken, + NetworkError, + BadRequest, + TimedOut, + ChatMigrated, + RetryAfter, + Conflict, +) class TestErrors: @@ -103,7 +111,7 @@ class TestErrors: (ChatMigrated(1234), ["message", "new_chat_id"]), (RetryAfter(12), ["message", "retry_after"]), (Conflict("test message"), ["message"]), - (TelegramDecryptionError("test message"), ["message"]) + (TelegramDecryptionError("test message"), ["message"]), ], ) def test_errors_pickling(self, exception, attributes): @@ -122,16 +130,26 @@ class TestErrors: Add the new error class to the below covered_subclasses dict, if it's covered in the above test_errors_pickling test. """ + def make_assertion(cls): assert {sc for sc in cls.__subclasses__()} == covered_subclasses[cls] for subcls in cls.__subclasses__(): make_assertion(subcls) covered_subclasses = defaultdict(set) - covered_subclasses.update({ - TelegramError: {Unauthorized, InvalidToken, NetworkError, ChatMigrated, RetryAfter, - Conflict, TelegramDecryptionError}, - NetworkError: {BadRequest, TimedOut} - }) + covered_subclasses.update( + { + TelegramError: { + Unauthorized, + InvalidToken, + NetworkError, + ChatMigrated, + RetryAfter, + Conflict, + TelegramDecryptionError, + }, + NetworkError: {BadRequest, TimedOut}, + } + ) make_assertion(TelegramError) diff --git a/tests/test_file.py b/tests/test_file.py index f2626ce92..a4e055604 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -28,18 +28,21 @@ from telegram import File, TelegramError, Voice @pytest.fixture(scope='class') def file(bot): - return File(TestFile.file_id, - TestFile.file_unique_id, - file_path=TestFile.file_path, - file_size=TestFile.file_size, - bot=bot) + return File( + TestFile.file_id, + TestFile.file_unique_id, + file_path=TestFile.file_path, + file_size=TestFile.file_size, + bot=bot, + ) class TestFile: file_id = 'NOTVALIDDOESNOTMATTER' file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e' file_path = ( - u'https://api.org/file/bot133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0/document/file_3') + u'https://api.org/file/bot133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0/document/file_3' + ) file_size = 28232 file_content = u'Saint-Saëns'.encode('utf-8') # Intentionally contains unicode chars. @@ -48,7 +51,7 @@ class TestFile: 'file_id': self.file_id, 'file_unique_id': self.file_unique_id, 'file_path': self.file_path, - 'file_size': self.file_size + 'file_size': self.file_size, } new_file = File.de_json(json_dict, bot) @@ -110,7 +113,7 @@ class TestFile: monkeypatch.setattr('telegram.utils.request.Request.retrieve', test) out_file = file.download() - assert out_file[-len(file.file_id):] == file.file_id + assert out_file[-len(file.file_id) :] == file.file_id try: with open(out_file, 'rb') as fobj: assert fobj.read() == self.file_content @@ -143,8 +146,8 @@ class TestFile: buf2 = buf[:] buf3 = file.download_as_bytearray(buf=buf2) assert buf3 is buf2 - assert buf2[len(buf):] == buf - assert buf2[:len(buf)] == buf + assert buf2[len(buf) :] == buf + assert buf2[: len(buf)] == buf def test_equality(self, bot): a = File(self.file_id, self.file_unique_id, bot) diff --git a/tests/test_filters.py b/tests/test_filters.py index 18555926c..969def023 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -27,23 +27,28 @@ import re @pytest.fixture(scope='function') def update(): - return Update(0, Message(0, datetime.datetime.utcnow(), - Chat(0, 'private'), from_user=User(0, 'Testuser', False), - via_bot=User(0, "Testbot", True))) + return Update( + 0, + Message( + 0, + datetime.datetime.utcnow(), + Chat(0, 'private'), + from_user=User(0, 'Testuser', False), + via_bot=User(0, "Testbot", True), + ), + ) -@pytest.fixture(scope='function', - params=MessageEntity.ALL_TYPES) +@pytest.fixture(scope='function', params=MessageEntity.ALL_TYPES) def message_entity(request): return MessageEntity(request.param, 0, 0, url='', user='') -@pytest.fixture(scope='class', - params=[ - {'class': MessageFilter}, - {'class': UpdateFilter} - ], - ids=['MessageFilter', 'UpdateFilter']) +@pytest.fixture( + scope='class', + params=[{'class': MessageFilter}, {'class': UpdateFilter}], + ids=['MessageFilter', 'UpdateFilter'], +) def base_class(request): return request.param['class'] @@ -168,8 +173,9 @@ class TestFilters: def test_regex_complex_merges(self, update): SRE_TYPE = type(re.match("", "")) update.message.text = 'test it out' - filter = (Filters.regex('test') - & ((Filters.status_update | Filters.forwarded) | Filters.regex('out'))) + filter = Filters.regex('test') & ( + (Filters.status_update | Filters.forwarded) | Filters.regex('out') + ) result = filter(update) assert result assert isinstance(result, dict) @@ -215,8 +221,9 @@ class TestFilters: update.message.text = 'test it out' update.message.forward_date = None update.message.pinned_message = None - filter = ((Filters.regex('test') | Filters.command) - & (Filters.regex('it') | Filters.status_update)) + filter = (Filters.regex('test') | Filters.command) & ( + Filters.regex('it') | Filters.status_update + ) result = filter(update) assert result assert isinstance(result, dict) @@ -263,7 +270,7 @@ class TestFilters: assert result assert isinstance(result, bool) - filter = (~Filters.regex('linked') & Filters.command) + filter = ~Filters.regex('linked') & Filters.command update.message.text = "it's linked" result = filter(update) assert not result @@ -275,7 +282,7 @@ class TestFilters: result = filter(update) assert not result - filter = (~Filters.regex('linked') | Filters.command) + filter = ~Filters.regex('linked') | Filters.command update.message.text = "it's linked" update.message.entities = [] result = filter(update) @@ -293,8 +300,12 @@ class TestFilters: assert result def test_filters_reply(self, update): - another_message = Message(1, datetime.datetime.utcnow(), Chat(0, 'private'), - from_user=User(1, 'TestOther', False)) + another_message = Message( + 1, + datetime.datetime.utcnow(), + Chat(0, 'private'), + from_user=User(1, 'TestOther', False), + ) update.message.text = 'test' assert not Filters.reply(update) update.message.reply_to_message = another_message @@ -311,8 +322,9 @@ class TestFilters: assert Filters.document(update) def test_filters_document_type(self, update): - update.message.document = Document("file_id", 'unique_id', - mime_type="application/vnd.android.package-archive") + update.message.document = Document( + "file_id", 'unique_id', mime_type="application/vnd.android.package-archive" + ) assert Filters.document.apk(update) assert Filters.document.application(update) assert not Filters.document.doc(update) @@ -324,8 +336,9 @@ class TestFilters: assert not Filters.document.docx(update) assert not Filters.document.audio(update) - update.message.document.mime_type = "application/vnd.openxmlformats-officedocument." \ - "wordprocessingml.document" + update.message.document.mime_type = ( + "application/vnd.openxmlformats-officedocument." "wordprocessingml.document" + ) assert Filters.document.docx(update) assert Filters.document.application(update) assert not Filters.document.exe(update) @@ -930,11 +943,13 @@ class TestFilters: update.message.forward_date = None assert not (Filters.text & (Filters.forwarded | Filters.status_update))(update) update.message.pinned_message = True - assert (Filters.text & (Filters.forwarded | Filters.status_update)(update)) + assert Filters.text & (Filters.forwarded | Filters.status_update)(update) - assert str(Filters.text & (Filters.forwarded | Filters.entity( - MessageEntity.MENTION))) == '>' + assert ( + str(Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION))) + == '>' + ) def test_inverted_filters(self, update): update.message.text = '/test' diff --git a/tests/test_game.py b/tests/test_game.py index ecf8affdf..809ed222e 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -24,20 +24,24 @@ from telegram import MessageEntity, Game, PhotoSize, Animation @pytest.fixture(scope='function') def game(): - return Game(TestGame.title, - TestGame.description, - TestGame.photo, - text=TestGame.text, - text_entities=TestGame.text_entities, - animation=TestGame.animation) + return Game( + TestGame.title, + TestGame.description, + TestGame.photo, + text=TestGame.text, + text_entities=TestGame.text_entities, + animation=TestGame.animation, + ) class TestGame: title = 'Python-telegram-bot Test Game' description = 'description' photo = [PhotoSize('Blah', 'ElseBlah', 640, 360, file_size=0)] - text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467' - b'\\u200d\\U0001f467\\U0001f431http://google.com').decode('unicode-escape') + text = ( + b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467' + b'\\u200d\\U0001f467\\U0001f431http://google.com' + ).decode('unicode-escape') text_entities = [MessageEntity(13, 17, MessageEntity.URL)] animation = Animation('blah', 'unique_id', 320, 180, 1) @@ -60,7 +64,7 @@ class TestGame: 'photo': [self.photo[0].to_dict()], 'text': self.text, 'text_entities': [self.text_entities[0].to_dict()], - 'animation': self.animation.to_dict() + 'animation': self.animation.to_dict(), } game = Game.de_json(json_dict, bot) @@ -98,10 +102,18 @@ class TestGame: def test_equality(self): a = Game('title', 'description', [PhotoSize('Blah', 'unique_id', 640, 360, file_size=0)]) - b = Game('title', 'description', [PhotoSize('Blah', 'unique_id', 640, 360, file_size=0)], - text='Here is a text') - c = Game('eltit', 'description', [PhotoSize('Blah', 'unique_id', 640, 360, file_size=0)], - animation=Animation('blah', 'unique_id', 320, 180, 1)) + b = Game( + 'title', + 'description', + [PhotoSize('Blah', 'unique_id', 640, 360, file_size=0)], + text='Here is a text', + ) + c = Game( + 'eltit', + 'description', + [PhotoSize('Blah', 'unique_id', 640, 360, file_size=0)], + animation=Animation('blah', 'unique_id', 320, 180, 1), + ) d = Animation('blah', 'unique_id', 320, 180, 1) assert a == b diff --git a/tests/test_gamehighscore.py b/tests/test_gamehighscore.py index 8025e754b..451f29598 100644 --- a/tests/test_gamehighscore.py +++ b/tests/test_gamehighscore.py @@ -24,9 +24,9 @@ from telegram import GameHighScore, User @pytest.fixture(scope='class') def game_highscore(): - return GameHighScore(TestGameHighScore.position, - TestGameHighScore.user, - TestGameHighScore.score) + return GameHighScore( + TestGameHighScore.position, TestGameHighScore.user, TestGameHighScore.score + ) class TestGameHighScore: @@ -35,9 +35,7 @@ class TestGameHighScore: score = 42 def test_de_json(self, bot): - json_dict = {'position': self.position, - 'user': self.user.to_dict(), - 'score': self.score} + json_dict = {'position': self.position, 'user': self.user.to_dict(), 'score': self.score} highscore = GameHighScore.de_json(json_dict, bot) assert highscore.position == self.position diff --git a/tests/test_helpers.py b/tests/test_helpers.py index e1ff5fc3b..3ef327062 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -32,11 +32,15 @@ from telegram.utils.helpers import _datetime_to_float_timestamp # sample time specification values categorised into absolute / delta / time-of-day -ABSOLUTE_TIME_SPECS = [dtm.datetime.now(tz=dtm.timezone(dtm.timedelta(hours=-7))), - dtm.datetime.utcnow()] +ABSOLUTE_TIME_SPECS = [ + dtm.datetime.now(tz=dtm.timezone(dtm.timedelta(hours=-7))), + dtm.datetime.utcnow(), +] DELTA_TIME_SPECS = [dtm.timedelta(hours=3, seconds=42, milliseconds=2), 30, 7.5] -TIME_OF_DAY_TIME_SPECS = [dtm.time(12, 42, tzinfo=dtm.timezone(dtm.timedelta(hours=-7))), - dtm.time(12, 42)] +TIME_OF_DAY_TIME_SPECS = [ + dtm.time(12, 42, tzinfo=dtm.timezone(dtm.timedelta(hours=-7))), + dtm.time(12, 42), +] RELATIVE_TIME_SPECS = DELTA_TIME_SPECS + TIME_OF_DAY_TIME_SPECS TIME_SPECS = ABSOLUTE_TIME_SPECS + RELATIVE_TIME_SPECS @@ -59,18 +63,21 @@ class TestHelpers: test_str = r'mono/pre: `abc` \int (`\some \`stuff)' expected_str = 'mono/pre: \\`abc\\` \\\\int (\\`\\\\some \\\\\\`stuff)' - assert expected_str == helpers.escape_markdown(test_str, version=2, - entity_type=MessageEntity.PRE) - assert expected_str == helpers.escape_markdown(test_str, version=2, - entity_type=MessageEntity.CODE) + assert expected_str == helpers.escape_markdown( + test_str, version=2, entity_type=MessageEntity.PRE + ) + assert expected_str == helpers.escape_markdown( + test_str, version=2, entity_type=MessageEntity.CODE + ) def test_escape_markdown_v2_text_link(self): test_str = 'https://url.containing/funny)cha)\\ra\\)cter\\s' expected_str = 'https://url.containing/funny\\)cha\\)\\\\ra\\\\\\)cter\\\\s' - assert expected_str == helpers.escape_markdown(test_str, version=2, - entity_type=MessageEntity.TEXT_LINK) + assert expected_str == helpers.escape_markdown( + test_str, version=2, entity_type=MessageEntity.TEXT_LINK + ) def test_markdown_invalid_version(self): with pytest.raises(ValueError): @@ -80,17 +87,19 @@ class TestHelpers: """Conversion from timezone-naive datetime to timestamp. Naive datetimes should be assumed to be in UTC. """ - datetime = dtm.datetime(2019, 11, 11, 0, 26, 16, 10**5) + datetime = dtm.datetime(2019, 11, 11, 0, 26, 16, 10 ** 5) assert helpers.to_float_timestamp(datetime) == 1573431976.1 def test_to_float_timestamp_absolute_aware(self, timezone): """Conversion from timezone-aware datetime to timestamp""" # we're parametrizing this with two different UTC offsets to exclude the possibility # of an xpass when the test is run in a timezone with the same UTC offset - test_datetime = dtm.datetime(2019, 11, 11, 0, 26, 16, 10**5) + test_datetime = dtm.datetime(2019, 11, 11, 0, 26, 16, 10 ** 5) datetime = timezone.localize(test_datetime) - assert (helpers.to_float_timestamp(datetime) - == 1573431976.1 - timezone.utcoffset(test_datetime).total_seconds()) + assert ( + helpers.to_float_timestamp(datetime) + == 1573431976.1 - timezone.utcoffset(test_datetime).total_seconds() + ) def test_to_float_timestamp_absolute_no_reference(self): """A reference timestamp is only relevant for relative time specifications""" @@ -126,15 +135,17 @@ class TestHelpers: # first test that naive time is assumed to be utc: assert helpers.to_float_timestamp(time_of_day, ref_t) == pytest.approx(ref_t) # test that by setting the timezone the timestamp changes accordingly: - assert (helpers.to_float_timestamp(aware_time_of_day, ref_t) - == pytest.approx(ref_t + (-utc_offset.total_seconds() % (24 * 60 * 60)))) + assert helpers.to_float_timestamp(aware_time_of_day, ref_t) == pytest.approx( + ref_t + (-utc_offset.total_seconds() % (24 * 60 * 60)) + ) @pytest.mark.parametrize('time_spec', RELATIVE_TIME_SPECS, ids=str) def test_to_float_timestamp_default_reference(self, time_spec): """The reference timestamp for relative time specifications should default to now""" now = time.time() - assert (helpers.to_float_timestamp(time_spec) - == pytest.approx(helpers.to_float_timestamp(time_spec, reference_timestamp=now))) + assert helpers.to_float_timestamp(time_spec) == pytest.approx( + helpers.to_float_timestamp(time_spec, reference_timestamp=now) + ) def test_to_float_timestamp_error(self): with pytest.raises(TypeError, match='Defaults'): @@ -161,8 +172,12 @@ class TestHelpers: # of an xpass when the test is run in a timezone with the same UTC offset test_datetime = dtm.datetime(2019, 11, 11, 0, 26, 16, 10 ** 5) datetime = timezone.localize(test_datetime) - assert (helpers.from_timestamp( - 1573431976.1 - timezone.utcoffset(test_datetime).total_seconds()) == datetime) + assert ( + helpers.from_timestamp( + 1573431976.1 - timezone.utcoffset(test_datetime).total_seconds() + ) + == datetime + ) def test_create_deep_linked_url(self): username = 'JamesTheMock' @@ -209,8 +224,9 @@ class TestHelpers: assert helpers.effective_message_type(test_message) == 'text' test_message.text = None - test_message = build_test_message(sticker=Sticker('sticker_id', 'unique_id', - 50, 50, False)) + test_message = build_test_message( + sticker=Sticker('sticker_id', 'unique_id', 50, 50, False) + ) assert helpers.effective_message_type(test_message) == 'sticker' test_message.sticker = None diff --git a/tests/test_inlinekeyboardbutton.py b/tests/test_inlinekeyboardbutton.py index 90cc17d0c..750ff2549 100644 --- a/tests/test_inlinekeyboardbutton.py +++ b/tests/test_inlinekeyboardbutton.py @@ -24,15 +24,16 @@ from telegram import InlineKeyboardButton, LoginUrl @pytest.fixture(scope='class') def inline_keyboard_button(): - return InlineKeyboardButton(TestInlineKeyboardButton.text, - url=TestInlineKeyboardButton.url, - callback_data=TestInlineKeyboardButton.callback_data, - switch_inline_query=TestInlineKeyboardButton.switch_inline_query, - switch_inline_query_current_chat=TestInlineKeyboardButton - .switch_inline_query_current_chat, - callback_game=TestInlineKeyboardButton.callback_game, - pay=TestInlineKeyboardButton.pay, - login_url=TestInlineKeyboardButton.login_url) + return InlineKeyboardButton( + TestInlineKeyboardButton.text, + url=TestInlineKeyboardButton.url, + callback_data=TestInlineKeyboardButton.callback_data, + switch_inline_query=TestInlineKeyboardButton.switch_inline_query, + switch_inline_query_current_chat=TestInlineKeyboardButton.switch_inline_query_current_chat, + callback_game=TestInlineKeyboardButton.callback_game, + pay=TestInlineKeyboardButton.pay, + login_url=TestInlineKeyboardButton.login_url, + ) class TestInlineKeyboardButton: @@ -50,8 +51,10 @@ class TestInlineKeyboardButton: assert inline_keyboard_button.url == self.url assert inline_keyboard_button.callback_data == self.callback_data assert inline_keyboard_button.switch_inline_query == self.switch_inline_query - assert (inline_keyboard_button.switch_inline_query_current_chat - == self.switch_inline_query_current_chat) + assert ( + inline_keyboard_button.switch_inline_query_current_chat + == self.switch_inline_query_current_chat + ) assert inline_keyboard_button.callback_game == self.callback_game assert inline_keyboard_button.pay == self.pay assert inline_keyboard_button.login_url == self.login_url @@ -63,14 +66,19 @@ class TestInlineKeyboardButton: assert inline_keyboard_button_dict['text'] == inline_keyboard_button.text assert inline_keyboard_button_dict['url'] == inline_keyboard_button.url assert inline_keyboard_button_dict['callback_data'] == inline_keyboard_button.callback_data - assert (inline_keyboard_button_dict['switch_inline_query'] - == inline_keyboard_button.switch_inline_query) - assert (inline_keyboard_button_dict['switch_inline_query_current_chat'] - == inline_keyboard_button.switch_inline_query_current_chat) + assert ( + inline_keyboard_button_dict['switch_inline_query'] + == inline_keyboard_button.switch_inline_query + ) + assert ( + inline_keyboard_button_dict['switch_inline_query_current_chat'] + == inline_keyboard_button.switch_inline_query_current_chat + ) assert inline_keyboard_button_dict['callback_game'] == inline_keyboard_button.callback_game assert inline_keyboard_button_dict['pay'] == inline_keyboard_button.pay - assert inline_keyboard_button_dict['login_url'] == \ - inline_keyboard_button.login_url.to_dict() # NOQA: E127 + assert ( + inline_keyboard_button_dict['login_url'] == inline_keyboard_button.login_url.to_dict() + ) # NOQA: E127 def test_de_json(self, bot): json_dict = { @@ -80,7 +88,7 @@ class TestInlineKeyboardButton: 'switch_inline_query': self.switch_inline_query, 'switch_inline_query_current_chat': self.switch_inline_query_current_chat, 'callback_game': self.callback_game, - 'pay': self.pay + 'pay': self.pay, } inline_keyboard_button = InlineKeyboardButton.de_json(json_dict, None) @@ -88,8 +96,10 @@ class TestInlineKeyboardButton: assert inline_keyboard_button.url == self.url assert inline_keyboard_button.callback_data == self.callback_data assert inline_keyboard_button.switch_inline_query == self.switch_inline_query - assert (inline_keyboard_button.switch_inline_query_current_chat - == self.switch_inline_query_current_chat) + assert ( + inline_keyboard_button.switch_inline_query_current_chat + == self.switch_inline_query_current_chat + ) assert inline_keyboard_button.callback_game == self.callback_game assert inline_keyboard_button.pay == self.pay diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index 02886fe4c..192299f9c 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -29,38 +29,46 @@ def inline_keyboard_markup(): class TestInlineKeyboardMarkup: - inline_keyboard = [[ - InlineKeyboardButton(text='button1', callback_data='data1'), - InlineKeyboardButton(text='button2', callback_data='data2') - ]] + inline_keyboard = [ + [ + InlineKeyboardButton(text='button1', callback_data='data1'), + InlineKeyboardButton(text='button2', callback_data='data2'), + ] + ] @flaky(3, 1) @pytest.mark.timeout(10) def test_send_message_with_inline_keyboard_markup(self, bot, chat_id, inline_keyboard_markup): message = bot.send_message( - chat_id, - 'Testing InlineKeyboardMarkup', - reply_markup=inline_keyboard_markup) + chat_id, 'Testing InlineKeyboardMarkup', reply_markup=inline_keyboard_markup + ) assert message.text == 'Testing InlineKeyboardMarkup' def test_from_button(self): inline_keyboard_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text='button1', callback_data='data1')).inline_keyboard + InlineKeyboardButton(text='button1', callback_data='data1') + ).inline_keyboard assert len(inline_keyboard_markup) == 1 assert len(inline_keyboard_markup[0]) == 1 def test_from_row(self): - inline_keyboard_markup = InlineKeyboardMarkup.from_row([ - InlineKeyboardButton(text='button1', callback_data='data1'), - InlineKeyboardButton(text='button1', callback_data='data1')]).inline_keyboard + inline_keyboard_markup = InlineKeyboardMarkup.from_row( + [ + InlineKeyboardButton(text='button1', callback_data='data1'), + InlineKeyboardButton(text='button1', callback_data='data1'), + ] + ).inline_keyboard assert len(inline_keyboard_markup) == 1 assert len(inline_keyboard_markup[0]) == 2 def test_from_column(self): - inline_keyboard_markup = InlineKeyboardMarkup.from_column([ - InlineKeyboardButton(text='button1', callback_data='data1'), - InlineKeyboardButton(text='button1', callback_data='data1')]).inline_keyboard + inline_keyboard_markup = InlineKeyboardMarkup.from_column( + [ + InlineKeyboardButton(text='button1', callback_data='data1'), + InlineKeyboardButton(text='button1', callback_data='data1'), + ] + ).inline_keyboard assert len(inline_keyboard_markup) == 2 assert len(inline_keyboard_markup[0]) == 1 assert len(inline_keyboard_markup[1]) == 1 @@ -69,8 +77,15 @@ class TestInlineKeyboardMarkup: assert inline_keyboard_markup.inline_keyboard == self.inline_keyboard def test_expected_values_empty_switch(self, inline_keyboard_markup, bot, monkeypatch): - def test(url, data, reply_to_message_id=None, disable_notification=None, - reply_markup=None, timeout=None, **kwargs): + def test( + url, + data, + reply_to_message_id=None, + disable_notification=None, + reply_markup=None, + timeout=None, + **kwargs, + ): if reply_markup is not None: if isinstance(reply_markup, ReplyMarkup): data['reply_markup'] = reply_markup.to_json() @@ -93,28 +108,19 @@ class TestInlineKeyboardMarkup: assert isinstance(inline_keyboard_markup_dict, dict) assert inline_keyboard_markup_dict['inline_keyboard'] == [ - [ - self.inline_keyboard[0][0].to_dict(), - self.inline_keyboard[0][1].to_dict() - ] + [self.inline_keyboard[0][0].to_dict(), self.inline_keyboard[0][1].to_dict()] ] def test_de_json(self): json_dict = { - 'inline_keyboard': [[ - { - 'text': 'start', - 'url': 'http://google.com' - }, - { - 'text': 'next', - 'callback_data': 'abcd' - }], - [{ - 'text': 'Cancel', - 'callback_data': 'Cancel' - }] - ]} + 'inline_keyboard': [ + [ + {'text': 'start', 'url': 'http://google.com'}, + {'text': 'next', 'callback_data': 'abcd'}, + ], + [{'text': 'Cancel', 'callback_data': 'Cancel'}], + ] + } inline_keyboard_markup = InlineKeyboardMarkup.de_json(json_dict, None) assert isinstance(inline_keyboard_markup, InlineKeyboardMarkup) @@ -131,34 +137,46 @@ class TestInlineKeyboardMarkup: assert keyboard[0][0].url == 'http://google.com' def test_equality(self): - a = InlineKeyboardMarkup.from_column([ - InlineKeyboardButton(label, callback_data='data') - for label in ['button1', 'button2', 'button3'] - ]) - b = InlineKeyboardMarkup.from_column([ - InlineKeyboardButton(label, callback_data='data') - for label in ['button1', 'button2', 'button3'] - ]) - c = InlineKeyboardMarkup.from_column([ - InlineKeyboardButton(label, callback_data='data') - for label in ['button1', 'button2'] - ]) - d = InlineKeyboardMarkup.from_column([ - InlineKeyboardButton(label, callback_data=label) - for label in ['button1', 'button2', 'button3'] - ]) - e = InlineKeyboardMarkup.from_column([ - InlineKeyboardButton(label, url=label) - for label in ['button1', 'button2', 'button3'] - ]) - f = InlineKeyboardMarkup([ - [InlineKeyboardButton(label, callback_data='data') - for label in ['button1', 'button2']], - [InlineKeyboardButton(label, callback_data='data') - for label in ['button1', 'button2']], - [InlineKeyboardButton(label, callback_data='data') - for label in ['button1', 'button2']] - ]) + a = InlineKeyboardMarkup.from_column( + [ + InlineKeyboardButton(label, callback_data='data') + for label in ['button1', 'button2', 'button3'] + ] + ) + b = InlineKeyboardMarkup.from_column( + [ + InlineKeyboardButton(label, callback_data='data') + for label in ['button1', 'button2', 'button3'] + ] + ) + c = InlineKeyboardMarkup.from_column( + [InlineKeyboardButton(label, callback_data='data') for label in ['button1', 'button2']] + ) + d = InlineKeyboardMarkup.from_column( + [ + InlineKeyboardButton(label, callback_data=label) + for label in ['button1', 'button2', 'button3'] + ] + ) + e = InlineKeyboardMarkup.from_column( + [InlineKeyboardButton(label, url=label) for label in ['button1', 'button2', 'button3']] + ) + f = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(label, callback_data='data') + for label in ['button1', 'button2'] + ], + [ + InlineKeyboardButton(label, callback_data='data') + for label in ['button1', 'button2'] + ], + [ + InlineKeyboardButton(label, callback_data='data') + for label in ['button1', 'button2'] + ], + ] + ) g = ReplyKeyboardMarkup.from_column(['button1', 'button2', 'button3']) assert a == b diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index 376013733..1cdd6cc85 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -24,8 +24,14 @@ from telegram import User, Location, InlineQuery, Update @pytest.fixture(scope='class') def inline_query(bot): - return InlineQuery(TestInlineQuery.id_, TestInlineQuery.from_user, TestInlineQuery.query, - TestInlineQuery.offset, location=TestInlineQuery.location, bot=bot) + return InlineQuery( + TestInlineQuery.id_, + TestInlineQuery.from_user, + TestInlineQuery.query, + TestInlineQuery.offset, + location=TestInlineQuery.location, + bot=bot, + ) class TestInlineQuery: @@ -41,7 +47,7 @@ class TestInlineQuery: 'from': self.from_user.to_dict(), 'query': self.query, 'offset': self.offset, - 'location': self.location.to_dict() + 'location': self.location.to_dict(), } inline_query_json = InlineQuery.de_json(json_dict, bot) diff --git a/tests/test_inlinequeryhandler.py b/tests/test_inlinequeryhandler.py index a647ece36..ae224ac95 100644 --- a/tests/test_inlinequeryhandler.py +++ b/tests/test_inlinequeryhandler.py @@ -20,8 +20,19 @@ from queue import Queue import pytest -from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, InlineQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery, Location) +from telegram import ( + Update, + CallbackQuery, + Bot, + Message, + User, + Chat, + InlineQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, + Location, +) from telegram.ext import InlineQueryHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -35,12 +46,20 @@ params = [ {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -50,10 +69,16 @@ def false_update(request): @pytest.fixture(scope='function') def inline_query(bot): - return Update(0, inline_query=InlineQuery('id', User(2, 'test user', False), - 'test query', offset='22', - location=Location(latitude=-23.691288, - longitude=-46.788279))) + return Update( + 0, + inline_query=InlineQuery( + 'id', + User(2, 'test user', False), + 'test query', + offset='22', + location=Location(latitude=-23.691288, longitude=-46.788279), + ), + ) class TestCallbackQueryHandler: @@ -87,15 +112,17 @@ class TestCallbackQueryHandler: self.test_flag = groupdict == {'begin': 't', 'end': ' query'} def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and context.chat_data is None - and isinstance(context.bot_data, dict) - and isinstance(update.inline_query, InlineQuery)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and context.chat_data is None + and isinstance(context.bot_data, dict) + and isinstance(update.inline_query, InlineQuery) + ) def callback_context_pattern(self, update, context): if context.matches[0].groups(): @@ -113,8 +140,7 @@ class TestCallbackQueryHandler: assert self.test_flag def test_with_pattern(self, inline_query): - handler = InlineQueryHandler(self.callback_basic, - pattern='(?P.*)est(?P.*)') + handler = InlineQueryHandler(self.callback_basic, pattern='(?P.*)est(?P.*)') assert handler.check_update(inline_query) @@ -122,18 +148,18 @@ class TestCallbackQueryHandler: assert not handler.check_update(inline_query) def test_with_passing_group_dict(self, dp, inline_query): - handler = InlineQueryHandler(self.callback_group, - pattern='(?P.*)est(?P.*)', - pass_groups=True) + handler = InlineQueryHandler( + self.callback_group, pattern='(?P.*)est(?P.*)', pass_groups=True + ) dp.add_handler(handler) dp.process_update(inline_query) assert self.test_flag dp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_group, - pattern='(?P.*)est(?P.*)', - pass_groupdict=True) + handler = InlineQueryHandler( + self.callback_group, pattern='(?P.*)est(?P.*)', pass_groupdict=True + ) dp.add_handler(handler) self.test_flag = False @@ -156,8 +182,9 @@ class TestCallbackQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_data_2, pass_chat_data=True, - pass_user_data=True) + handler = InlineQueryHandler( + self.callback_data_2, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(handler) self.test_flag = False @@ -172,8 +199,7 @@ class TestCallbackQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_queue_1, - pass_update_queue=True) + handler = InlineQueryHandler(self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -181,8 +207,9 @@ class TestCallbackQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_queue_2, pass_job_queue=True, - pass_update_queue=True) + handler = InlineQueryHandler( + self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False @@ -201,16 +228,16 @@ class TestCallbackQueryHandler: assert self.test_flag def test_context_pattern(self, cdp, inline_query): - handler = InlineQueryHandler(self.callback_context_pattern, - pattern=r'(?P.*)est(?P.*)') + handler = InlineQueryHandler( + self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' + ) cdp.add_handler(handler) cdp.process_update(inline_query) assert self.test_flag cdp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_context_pattern, - pattern=r'(t)est(.*)') + handler = InlineQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') cdp.add_handler(handler) cdp.process_update(inline_query) diff --git a/tests/test_inlinequeryresultarticle.py b/tests/test_inlinequeryresultarticle.py index 7eefe6bb4..4248ae17b 100644 --- a/tests/test_inlinequeryresultarticle.py +++ b/tests/test_inlinequeryresultarticle.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardMarkup, InlineQueryResultAudio, InlineQueryResultArticle, - InlineKeyboardButton, InputTextMessageContent) +from telegram import ( + InlineKeyboardMarkup, + InlineQueryResultAudio, + InlineQueryResultArticle, + InlineKeyboardButton, + InputTextMessageContent, +) @pytest.fixture(scope='class') @@ -35,7 +40,8 @@ def inline_query_result_article(): description=TestInlineQueryResultArticle.description, thumb_url=TestInlineQueryResultArticle.thumb_url, thumb_height=TestInlineQueryResultArticle.thumb_height, - thumb_width=TestInlineQueryResultArticle.thumb_width) + thumb_width=TestInlineQueryResultArticle.thumb_width, + ) class TestInlineQueryResultArticle: @@ -55,8 +61,10 @@ class TestInlineQueryResultArticle: assert inline_query_result_article.type == self.type_ assert inline_query_result_article.id == self.id_ assert inline_query_result_article.title == self.title - assert (inline_query_result_article.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_article.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_article.reply_markup.to_dict() == self.reply_markup.to_dict() assert inline_query_result_article.url == self.url assert inline_query_result_article.hide_url == self.hide_url @@ -72,20 +80,31 @@ class TestInlineQueryResultArticle: assert inline_query_result_article_dict['type'] == inline_query_result_article.type assert inline_query_result_article_dict['id'] == inline_query_result_article.id assert inline_query_result_article_dict['title'] == inline_query_result_article.title - assert (inline_query_result_article_dict['input_message_content'] - == inline_query_result_article.input_message_content.to_dict()) - assert (inline_query_result_article_dict['reply_markup'] - == inline_query_result_article.reply_markup.to_dict()) + assert ( + inline_query_result_article_dict['input_message_content'] + == inline_query_result_article.input_message_content.to_dict() + ) + assert ( + inline_query_result_article_dict['reply_markup'] + == inline_query_result_article.reply_markup.to_dict() + ) assert inline_query_result_article_dict['url'] == inline_query_result_article.url assert inline_query_result_article_dict['hide_url'] == inline_query_result_article.hide_url - assert (inline_query_result_article_dict['description'] - == inline_query_result_article.description) - assert (inline_query_result_article_dict['thumb_url'] - == inline_query_result_article.thumb_url) - assert (inline_query_result_article_dict['thumb_height'] - == inline_query_result_article.thumb_height) - assert (inline_query_result_article_dict['thumb_width'] - == inline_query_result_article.thumb_width) + assert ( + inline_query_result_article_dict['description'] + == inline_query_result_article.description + ) + assert ( + inline_query_result_article_dict['thumb_url'] == inline_query_result_article.thumb_url + ) + assert ( + inline_query_result_article_dict['thumb_height'] + == inline_query_result_article.thumb_height + ) + assert ( + inline_query_result_article_dict['thumb_width'] + == inline_query_result_article.thumb_width + ) def test_equality(self): a = InlineQueryResultArticle(self.id_, self.title, self.input_message_content) diff --git a/tests/test_inlinequeryresultaudio.py b/tests/test_inlinequeryresultaudio.py index 85eea687c..a560f51b5 100644 --- a/tests/test_inlinequeryresultaudio.py +++ b/tests/test_inlinequeryresultaudio.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardMarkup, InlineKeyboardButton, InlineQueryResultAudio, - InputTextMessageContent, InlineQueryResultVoice) +from telegram import ( + InlineKeyboardMarkup, + InlineKeyboardButton, + InlineQueryResultAudio, + InputTextMessageContent, + InlineQueryResultVoice, +) @pytest.fixture(scope='class') @@ -34,7 +39,8 @@ def inline_query_result_audio(): caption=TestInlineQueryResultAudio.caption, parse_mode=TestInlineQueryResultAudio.parse_mode, input_message_content=TestInlineQueryResultAudio.input_message_content, - reply_markup=TestInlineQueryResultAudio.reply_markup) + reply_markup=TestInlineQueryResultAudio.reply_markup, + ) class TestInlineQueryResultAudio: @@ -58,8 +64,10 @@ class TestInlineQueryResultAudio: assert inline_query_result_audio.audio_duration == self.audio_duration assert inline_query_result_audio.caption == self.caption assert inline_query_result_audio.parse_mode == self.parse_mode - assert (inline_query_result_audio.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_audio.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_audio.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_audio): @@ -71,14 +79,20 @@ class TestInlineQueryResultAudio: assert inline_query_result_audio_dict['audio_url'] == inline_query_result_audio.audio_url assert inline_query_result_audio_dict['title'] == inline_query_result_audio.title assert inline_query_result_audio_dict['performer'] == inline_query_result_audio.performer - assert (inline_query_result_audio_dict['audio_duration'] - == inline_query_result_audio.audio_duration) + assert ( + inline_query_result_audio_dict['audio_duration'] + == inline_query_result_audio.audio_duration + ) assert inline_query_result_audio_dict['caption'] == inline_query_result_audio.caption assert inline_query_result_audio_dict['parse_mode'] == inline_query_result_audio.parse_mode - assert (inline_query_result_audio_dict['input_message_content'] - == inline_query_result_audio.input_message_content.to_dict()) - assert (inline_query_result_audio_dict['reply_markup'] - == inline_query_result_audio.reply_markup.to_dict()) + assert ( + inline_query_result_audio_dict['input_message_content'] + == inline_query_result_audio.input_message_content.to_dict() + ) + assert ( + inline_query_result_audio_dict['reply_markup'] + == inline_query_result_audio.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultAudio(self.id_, self.audio_url, self.title) diff --git a/tests/test_inlinequeryresultcachedaudio.py b/tests/test_inlinequeryresultcachedaudio.py index ae77853dc..b98834e3f 100644 --- a/tests/test_inlinequeryresultcachedaudio.py +++ b/tests/test_inlinequeryresultcachedaudio.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InputTextMessageContent, InlineQueryResultCachedAudio, InlineKeyboardMarkup, - InlineKeyboardButton, InlineQueryResultCachedVoice) +from telegram import ( + InputTextMessageContent, + InlineQueryResultCachedAudio, + InlineKeyboardMarkup, + InlineKeyboardButton, + InlineQueryResultCachedVoice, +) @pytest.fixture(scope='class') @@ -31,7 +36,8 @@ def inline_query_result_cached_audio(): caption=TestInlineQueryResultCachedAudio.caption, parse_mode=TestInlineQueryResultCachedAudio.parse_mode, input_message_content=TestInlineQueryResultCachedAudio.input_message_content, - reply_markup=TestInlineQueryResultCachedAudio.reply_markup) + reply_markup=TestInlineQueryResultCachedAudio.reply_markup, + ) class TestInlineQueryResultCachedAudio: @@ -49,28 +55,42 @@ class TestInlineQueryResultCachedAudio: assert inline_query_result_cached_audio.audio_file_id == self.audio_file_id assert inline_query_result_cached_audio.caption == self.caption assert inline_query_result_cached_audio.parse_mode == self.parse_mode - assert (inline_query_result_cached_audio.input_message_content.to_dict() - == self.input_message_content.to_dict()) - assert (inline_query_result_cached_audio.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert ( + inline_query_result_cached_audio.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_audio.reply_markup.to_dict() == self.reply_markup.to_dict() + ) def test_to_dict(self, inline_query_result_cached_audio): inline_query_result_cached_audio_dict = inline_query_result_cached_audio.to_dict() assert isinstance(inline_query_result_cached_audio_dict, dict) - assert (inline_query_result_cached_audio_dict['type'] - == inline_query_result_cached_audio.type) + assert ( + inline_query_result_cached_audio_dict['type'] == inline_query_result_cached_audio.type + ) assert inline_query_result_cached_audio_dict['id'] == inline_query_result_cached_audio.id - assert (inline_query_result_cached_audio_dict['audio_file_id'] - == inline_query_result_cached_audio.audio_file_id) - assert (inline_query_result_cached_audio_dict['caption'] - == inline_query_result_cached_audio.caption) - assert (inline_query_result_cached_audio_dict['parse_mode'] - == inline_query_result_cached_audio.parse_mode) - assert (inline_query_result_cached_audio_dict['input_message_content'] - == inline_query_result_cached_audio.input_message_content.to_dict()) - assert (inline_query_result_cached_audio_dict['reply_markup'] - == inline_query_result_cached_audio.reply_markup.to_dict()) + assert ( + inline_query_result_cached_audio_dict['audio_file_id'] + == inline_query_result_cached_audio.audio_file_id + ) + assert ( + inline_query_result_cached_audio_dict['caption'] + == inline_query_result_cached_audio.caption + ) + assert ( + inline_query_result_cached_audio_dict['parse_mode'] + == inline_query_result_cached_audio.parse_mode + ) + assert ( + inline_query_result_cached_audio_dict['input_message_content'] + == inline_query_result_cached_audio.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_audio_dict['reply_markup'] + == inline_query_result_cached_audio.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedAudio(self.id_, self.audio_file_id) diff --git a/tests/test_inlinequeryresultcacheddocument.py b/tests/test_inlinequeryresultcacheddocument.py index 812dec3f6..611532bcb 100644 --- a/tests/test_inlinequeryresultcacheddocument.py +++ b/tests/test_inlinequeryresultcacheddocument.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineQueryResultCachedDocument, InlineKeyboardButton, InlineKeyboardMarkup, - InputTextMessageContent, InlineQueryResultCachedVoice) +from telegram import ( + InlineQueryResultCachedDocument, + InlineKeyboardButton, + InlineKeyboardMarkup, + InputTextMessageContent, + InlineQueryResultCachedVoice, +) @pytest.fixture(scope='class') @@ -33,7 +38,8 @@ def inline_query_result_cached_document(): parse_mode=TestInlineQueryResultCachedDocument.parse_mode, description=TestInlineQueryResultCachedDocument.description, input_message_content=TestInlineQueryResultCachedDocument.input_message_content, - reply_markup=TestInlineQueryResultCachedDocument.reply_markup) + reply_markup=TestInlineQueryResultCachedDocument.reply_markup, + ) class TestInlineQueryResultCachedDocument: @@ -55,33 +61,55 @@ class TestInlineQueryResultCachedDocument: assert inline_query_result_cached_document.caption == self.caption assert inline_query_result_cached_document.parse_mode == self.parse_mode assert inline_query_result_cached_document.description == self.description - assert (inline_query_result_cached_document.input_message_content.to_dict() - == self.input_message_content.to_dict()) - assert (inline_query_result_cached_document.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert ( + inline_query_result_cached_document.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_document.reply_markup.to_dict() + == self.reply_markup.to_dict() + ) def test_to_dict(self, inline_query_result_cached_document): inline_query_result_cached_document_dict = inline_query_result_cached_document.to_dict() assert isinstance(inline_query_result_cached_document_dict, dict) - assert (inline_query_result_cached_document_dict['id'] - == inline_query_result_cached_document.id) - assert (inline_query_result_cached_document_dict['type'] - == inline_query_result_cached_document.type) - assert (inline_query_result_cached_document_dict['document_file_id'] - == inline_query_result_cached_document.document_file_id) - assert (inline_query_result_cached_document_dict['title'] - == inline_query_result_cached_document.title) - assert (inline_query_result_cached_document_dict['caption'] - == inline_query_result_cached_document.caption) - assert (inline_query_result_cached_document_dict['parse_mode'] - == inline_query_result_cached_document.parse_mode) - assert (inline_query_result_cached_document_dict['description'] - == inline_query_result_cached_document.description) - assert (inline_query_result_cached_document_dict['input_message_content'] - == inline_query_result_cached_document.input_message_content.to_dict()) - assert (inline_query_result_cached_document_dict['reply_markup'] - == inline_query_result_cached_document.reply_markup.to_dict()) + assert ( + inline_query_result_cached_document_dict['id'] + == inline_query_result_cached_document.id + ) + assert ( + inline_query_result_cached_document_dict['type'] + == inline_query_result_cached_document.type + ) + assert ( + inline_query_result_cached_document_dict['document_file_id'] + == inline_query_result_cached_document.document_file_id + ) + assert ( + inline_query_result_cached_document_dict['title'] + == inline_query_result_cached_document.title + ) + assert ( + inline_query_result_cached_document_dict['caption'] + == inline_query_result_cached_document.caption + ) + assert ( + inline_query_result_cached_document_dict['parse_mode'] + == inline_query_result_cached_document.parse_mode + ) + assert ( + inline_query_result_cached_document_dict['description'] + == inline_query_result_cached_document.description + ) + assert ( + inline_query_result_cached_document_dict['input_message_content'] + == inline_query_result_cached_document.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_document_dict['reply_markup'] + == inline_query_result_cached_document.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedDocument(self.id_, self.title, self.document_file_id) diff --git a/tests/test_inlinequeryresultcachedgif.py b/tests/test_inlinequeryresultcachedgif.py index f1ec88fa0..89c2433ca 100644 --- a/tests/test_inlinequeryresultcachedgif.py +++ b/tests/test_inlinequeryresultcachedgif.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultCachedVoice, - InlineKeyboardMarkup, InlineQueryResultCachedGif) +from telegram import ( + InlineKeyboardButton, + InputTextMessageContent, + InlineQueryResultCachedVoice, + InlineKeyboardMarkup, + InlineQueryResultCachedGif, +) @pytest.fixture(scope='class') @@ -32,7 +37,8 @@ def inline_query_result_cached_gif(): caption=TestInlineQueryResultCachedGif.caption, parse_mode=TestInlineQueryResultCachedGif.parse_mode, input_message_content=TestInlineQueryResultCachedGif.input_message_content, - reply_markup=TestInlineQueryResultCachedGif.reply_markup) + reply_markup=TestInlineQueryResultCachedGif.reply_markup, + ) class TestInlineQueryResultCachedGif: @@ -52,8 +58,10 @@ class TestInlineQueryResultCachedGif: assert inline_query_result_cached_gif.title == self.title assert inline_query_result_cached_gif.caption == self.caption assert inline_query_result_cached_gif.parse_mode == self.parse_mode - assert (inline_query_result_cached_gif.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_cached_gif.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_cached_gif.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_cached_gif): @@ -62,17 +70,27 @@ class TestInlineQueryResultCachedGif: assert isinstance(inline_query_result_cached_gif_dict, dict) assert inline_query_result_cached_gif_dict['type'] == inline_query_result_cached_gif.type assert inline_query_result_cached_gif_dict['id'] == inline_query_result_cached_gif.id - assert (inline_query_result_cached_gif_dict['gif_file_id'] - == inline_query_result_cached_gif.gif_file_id) + assert ( + inline_query_result_cached_gif_dict['gif_file_id'] + == inline_query_result_cached_gif.gif_file_id + ) assert inline_query_result_cached_gif_dict['title'] == inline_query_result_cached_gif.title - assert (inline_query_result_cached_gif_dict['caption'] - == inline_query_result_cached_gif.caption) - assert (inline_query_result_cached_gif_dict['parse_mode'] - == inline_query_result_cached_gif.parse_mode) - assert (inline_query_result_cached_gif_dict['input_message_content'] - == inline_query_result_cached_gif.input_message_content.to_dict()) - assert (inline_query_result_cached_gif_dict['reply_markup'] - == inline_query_result_cached_gif.reply_markup.to_dict()) + assert ( + inline_query_result_cached_gif_dict['caption'] + == inline_query_result_cached_gif.caption + ) + assert ( + inline_query_result_cached_gif_dict['parse_mode'] + == inline_query_result_cached_gif.parse_mode + ) + assert ( + inline_query_result_cached_gif_dict['input_message_content'] + == inline_query_result_cached_gif.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_gif_dict['reply_markup'] + == inline_query_result_cached_gif.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedGif(self.id_, self.gif_file_id) diff --git a/tests/test_inlinequeryresultcachedmpeg4gif.py b/tests/test_inlinequeryresultcachedmpeg4gif.py index 95e4419d1..eb12918ad 100644 --- a/tests/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/test_inlinequeryresultcachedmpeg4gif.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineQueryResultCachedMpeg4Gif, InlineKeyboardButton, - InputTextMessageContent, InlineKeyboardMarkup, InlineQueryResultCachedVoice) +from telegram import ( + InlineQueryResultCachedMpeg4Gif, + InlineKeyboardButton, + InputTextMessageContent, + InlineKeyboardMarkup, + InlineQueryResultCachedVoice, +) @pytest.fixture(scope='class') @@ -32,7 +37,8 @@ def inline_query_result_cached_mpeg4_gif(): caption=TestInlineQueryResultCachedMpeg4Gif.caption, parse_mode=TestInlineQueryResultCachedMpeg4Gif.parse_mode, input_message_content=TestInlineQueryResultCachedMpeg4Gif.input_message_content, - reply_markup=TestInlineQueryResultCachedMpeg4Gif.reply_markup) + reply_markup=TestInlineQueryResultCachedMpeg4Gif.reply_markup, + ) class TestInlineQueryResultCachedMpeg4Gif: @@ -52,31 +58,51 @@ class TestInlineQueryResultCachedMpeg4Gif: assert inline_query_result_cached_mpeg4_gif.title == self.title assert inline_query_result_cached_mpeg4_gif.caption == self.caption assert inline_query_result_cached_mpeg4_gif.parse_mode == self.parse_mode - assert (inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() - == self.input_message_content.to_dict()) - assert (inline_query_result_cached_mpeg4_gif.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert ( + inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_mpeg4_gif.reply_markup.to_dict() + == self.reply_markup.to_dict() + ) def test_to_dict(self, inline_query_result_cached_mpeg4_gif): inline_query_result_cached_mpeg4_gif_dict = inline_query_result_cached_mpeg4_gif.to_dict() assert isinstance(inline_query_result_cached_mpeg4_gif_dict, dict) - assert (inline_query_result_cached_mpeg4_gif_dict['type'] - == inline_query_result_cached_mpeg4_gif.type) - assert (inline_query_result_cached_mpeg4_gif_dict['id'] - == inline_query_result_cached_mpeg4_gif.id) - assert (inline_query_result_cached_mpeg4_gif_dict['mpeg4_file_id'] - == inline_query_result_cached_mpeg4_gif.mpeg4_file_id) - assert (inline_query_result_cached_mpeg4_gif_dict['title'] - == inline_query_result_cached_mpeg4_gif.title) - assert (inline_query_result_cached_mpeg4_gif_dict['caption'] - == inline_query_result_cached_mpeg4_gif.caption) - assert (inline_query_result_cached_mpeg4_gif_dict['parse_mode'] - == inline_query_result_cached_mpeg4_gif.parse_mode) - assert (inline_query_result_cached_mpeg4_gif_dict['input_message_content'] - == inline_query_result_cached_mpeg4_gif.input_message_content.to_dict()) - assert (inline_query_result_cached_mpeg4_gif_dict['reply_markup'] - == inline_query_result_cached_mpeg4_gif.reply_markup.to_dict()) + assert ( + inline_query_result_cached_mpeg4_gif_dict['type'] + == inline_query_result_cached_mpeg4_gif.type + ) + assert ( + inline_query_result_cached_mpeg4_gif_dict['id'] + == inline_query_result_cached_mpeg4_gif.id + ) + assert ( + inline_query_result_cached_mpeg4_gif_dict['mpeg4_file_id'] + == inline_query_result_cached_mpeg4_gif.mpeg4_file_id + ) + assert ( + inline_query_result_cached_mpeg4_gif_dict['title'] + == inline_query_result_cached_mpeg4_gif.title + ) + assert ( + inline_query_result_cached_mpeg4_gif_dict['caption'] + == inline_query_result_cached_mpeg4_gif.caption + ) + assert ( + inline_query_result_cached_mpeg4_gif_dict['parse_mode'] + == inline_query_result_cached_mpeg4_gif.parse_mode + ) + assert ( + inline_query_result_cached_mpeg4_gif_dict['input_message_content'] + == inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_mpeg4_gif_dict['reply_markup'] + == inline_query_result_cached_mpeg4_gif.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedMpeg4Gif(self.id_, self.mpeg4_file_id) diff --git a/tests/test_inlinequeryresultcachedphoto.py b/tests/test_inlinequeryresultcachedphoto.py index 5348b740f..5898e81a1 100644 --- a/tests/test_inlinequeryresultcachedphoto.py +++ b/tests/test_inlinequeryresultcachedphoto.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InputTextMessageContent, InlineQueryResultCachedPhoto, InlineKeyboardButton, - InlineQueryResultCachedVoice, InlineKeyboardMarkup) +from telegram import ( + InputTextMessageContent, + InlineQueryResultCachedPhoto, + InlineKeyboardButton, + InlineQueryResultCachedVoice, + InlineKeyboardMarkup, +) @pytest.fixture(scope='class') @@ -33,7 +38,8 @@ def inline_query_result_cached_photo(): caption=TestInlineQueryResultCachedPhoto.caption, parse_mode=TestInlineQueryResultCachedPhoto.parse_mode, input_message_content=TestInlineQueryResultCachedPhoto.input_message_content, - reply_markup=TestInlineQueryResultCachedPhoto.reply_markup) + reply_markup=TestInlineQueryResultCachedPhoto.reply_markup, + ) class TestInlineQueryResultCachedPhoto: @@ -55,32 +61,50 @@ class TestInlineQueryResultCachedPhoto: assert inline_query_result_cached_photo.description == self.description assert inline_query_result_cached_photo.caption == self.caption assert inline_query_result_cached_photo.parse_mode == self.parse_mode - assert (inline_query_result_cached_photo.input_message_content.to_dict() - == self.input_message_content.to_dict()) - assert (inline_query_result_cached_photo.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert ( + inline_query_result_cached_photo.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_photo.reply_markup.to_dict() == self.reply_markup.to_dict() + ) def test_to_dict(self, inline_query_result_cached_photo): inline_query_result_cached_photo_dict = inline_query_result_cached_photo.to_dict() assert isinstance(inline_query_result_cached_photo_dict, dict) - assert (inline_query_result_cached_photo_dict['type'] - == inline_query_result_cached_photo.type) + assert ( + inline_query_result_cached_photo_dict['type'] == inline_query_result_cached_photo.type + ) assert inline_query_result_cached_photo_dict['id'] == inline_query_result_cached_photo.id - assert (inline_query_result_cached_photo_dict['photo_file_id'] - == inline_query_result_cached_photo.photo_file_id) - assert (inline_query_result_cached_photo_dict['title'] - == inline_query_result_cached_photo.title) - assert (inline_query_result_cached_photo_dict['description'] - == inline_query_result_cached_photo.description) - assert (inline_query_result_cached_photo_dict['caption'] - == inline_query_result_cached_photo.caption) - assert (inline_query_result_cached_photo_dict['parse_mode'] - == inline_query_result_cached_photo.parse_mode) - assert (inline_query_result_cached_photo_dict['input_message_content'] - == inline_query_result_cached_photo.input_message_content.to_dict()) - assert (inline_query_result_cached_photo_dict['reply_markup'] - == inline_query_result_cached_photo.reply_markup.to_dict()) + assert ( + inline_query_result_cached_photo_dict['photo_file_id'] + == inline_query_result_cached_photo.photo_file_id + ) + assert ( + inline_query_result_cached_photo_dict['title'] + == inline_query_result_cached_photo.title + ) + assert ( + inline_query_result_cached_photo_dict['description'] + == inline_query_result_cached_photo.description + ) + assert ( + inline_query_result_cached_photo_dict['caption'] + == inline_query_result_cached_photo.caption + ) + assert ( + inline_query_result_cached_photo_dict['parse_mode'] + == inline_query_result_cached_photo.parse_mode + ) + assert ( + inline_query_result_cached_photo_dict['input_message_content'] + == inline_query_result_cached_photo.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_photo_dict['reply_markup'] + == inline_query_result_cached_photo.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedPhoto(self.id_, self.photo_file_id) diff --git a/tests/test_inlinequeryresultcachedsticker.py b/tests/test_inlinequeryresultcachedsticker.py index 3993d9e05..b55981ad5 100644 --- a/tests/test_inlinequeryresultcachedsticker.py +++ b/tests/test_inlinequeryresultcachedsticker.py @@ -19,9 +19,13 @@ import pytest -from telegram import (InputTextMessageContent, InlineKeyboardButton, - InlineQueryResultCachedSticker, InlineQueryResultCachedVoice, - InlineKeyboardMarkup) +from telegram import ( + InputTextMessageContent, + InlineKeyboardButton, + InlineQueryResultCachedSticker, + InlineQueryResultCachedVoice, + InlineKeyboardMarkup, +) @pytest.fixture(scope='class') @@ -30,7 +34,8 @@ def inline_query_result_cached_sticker(): TestInlineQueryResultCachedSticker.id_, TestInlineQueryResultCachedSticker.sticker_file_id, input_message_content=TestInlineQueryResultCachedSticker.input_message_content, - reply_markup=TestInlineQueryResultCachedSticker.reply_markup) + reply_markup=TestInlineQueryResultCachedSticker.reply_markup, + ) class TestInlineQueryResultCachedSticker: @@ -44,25 +49,38 @@ class TestInlineQueryResultCachedSticker: assert inline_query_result_cached_sticker.type == self.type_ assert inline_query_result_cached_sticker.id == self.id_ assert inline_query_result_cached_sticker.sticker_file_id == self.sticker_file_id - assert (inline_query_result_cached_sticker.input_message_content.to_dict() - == self.input_message_content.to_dict()) - assert (inline_query_result_cached_sticker.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert ( + inline_query_result_cached_sticker.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_sticker.reply_markup.to_dict() + == self.reply_markup.to_dict() + ) def test_to_dict(self, inline_query_result_cached_sticker): inline_query_result_cached_sticker_dict = inline_query_result_cached_sticker.to_dict() assert isinstance(inline_query_result_cached_sticker_dict, dict) - assert (inline_query_result_cached_sticker_dict['type'] - == inline_query_result_cached_sticker.type) - assert (inline_query_result_cached_sticker_dict['id'] - == inline_query_result_cached_sticker.id) - assert (inline_query_result_cached_sticker_dict['sticker_file_id'] - == inline_query_result_cached_sticker.sticker_file_id) - assert (inline_query_result_cached_sticker_dict['input_message_content'] - == inline_query_result_cached_sticker.input_message_content.to_dict()) - assert (inline_query_result_cached_sticker_dict['reply_markup'] - == inline_query_result_cached_sticker.reply_markup.to_dict()) + assert ( + inline_query_result_cached_sticker_dict['type'] + == inline_query_result_cached_sticker.type + ) + assert ( + inline_query_result_cached_sticker_dict['id'] == inline_query_result_cached_sticker.id + ) + assert ( + inline_query_result_cached_sticker_dict['sticker_file_id'] + == inline_query_result_cached_sticker.sticker_file_id + ) + assert ( + inline_query_result_cached_sticker_dict['input_message_content'] + == inline_query_result_cached_sticker.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_sticker_dict['reply_markup'] + == inline_query_result_cached_sticker.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedSticker(self.id_, self.sticker_file_id) diff --git a/tests/test_inlinequeryresultcachedvideo.py b/tests/test_inlinequeryresultcachedvideo.py index 9c152643f..26ee771c7 100644 --- a/tests/test_inlinequeryresultcachedvideo.py +++ b/tests/test_inlinequeryresultcachedvideo.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardMarkup, InlineKeyboardButton, InputTextMessageContent, - InlineQueryResultCachedVideo, InlineQueryResultCachedVoice) +from telegram import ( + InlineKeyboardMarkup, + InlineKeyboardButton, + InputTextMessageContent, + InlineQueryResultCachedVideo, + InlineQueryResultCachedVoice, +) @pytest.fixture(scope='class') @@ -33,7 +38,8 @@ def inline_query_result_cached_video(): parse_mode=TestInlineQueryResultCachedVideo.parse_mode, description=TestInlineQueryResultCachedVideo.description, input_message_content=TestInlineQueryResultCachedVideo.input_message_content, - reply_markup=TestInlineQueryResultCachedVideo.reply_markup) + reply_markup=TestInlineQueryResultCachedVideo.reply_markup, + ) class TestInlineQueryResultCachedVideo: @@ -55,32 +61,50 @@ class TestInlineQueryResultCachedVideo: assert inline_query_result_cached_video.description == self.description assert inline_query_result_cached_video.caption == self.caption assert inline_query_result_cached_video.parse_mode == self.parse_mode - assert (inline_query_result_cached_video.input_message_content.to_dict() - == self.input_message_content.to_dict()) - assert (inline_query_result_cached_video.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert ( + inline_query_result_cached_video.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_video.reply_markup.to_dict() == self.reply_markup.to_dict() + ) def test_to_dict(self, inline_query_result_cached_video): inline_query_result_cached_video_dict = inline_query_result_cached_video.to_dict() assert isinstance(inline_query_result_cached_video_dict, dict) - assert (inline_query_result_cached_video_dict['type'] - == inline_query_result_cached_video.type) + assert ( + inline_query_result_cached_video_dict['type'] == inline_query_result_cached_video.type + ) assert inline_query_result_cached_video_dict['id'] == inline_query_result_cached_video.id - assert (inline_query_result_cached_video_dict['video_file_id'] - == inline_query_result_cached_video.video_file_id) - assert (inline_query_result_cached_video_dict['title'] - == inline_query_result_cached_video.title) - assert (inline_query_result_cached_video_dict['description'] - == inline_query_result_cached_video.description) - assert (inline_query_result_cached_video_dict['caption'] - == inline_query_result_cached_video.caption) - assert (inline_query_result_cached_video_dict['parse_mode'] - == inline_query_result_cached_video.parse_mode) - assert (inline_query_result_cached_video_dict['input_message_content'] - == inline_query_result_cached_video.input_message_content.to_dict()) - assert (inline_query_result_cached_video_dict['reply_markup'] - == inline_query_result_cached_video.reply_markup.to_dict()) + assert ( + inline_query_result_cached_video_dict['video_file_id'] + == inline_query_result_cached_video.video_file_id + ) + assert ( + inline_query_result_cached_video_dict['title'] + == inline_query_result_cached_video.title + ) + assert ( + inline_query_result_cached_video_dict['description'] + == inline_query_result_cached_video.description + ) + assert ( + inline_query_result_cached_video_dict['caption'] + == inline_query_result_cached_video.caption + ) + assert ( + inline_query_result_cached_video_dict['parse_mode'] + == inline_query_result_cached_video.parse_mode + ) + assert ( + inline_query_result_cached_video_dict['input_message_content'] + == inline_query_result_cached_video.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_video_dict['reply_markup'] + == inline_query_result_cached_video.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedVideo(self.id_, self.video_file_id, self.title) diff --git a/tests/test_inlinequeryresultcachedvoice.py b/tests/test_inlinequeryresultcachedvoice.py index 131c32d9c..ebeec0982 100644 --- a/tests/test_inlinequeryresultcachedvoice.py +++ b/tests/test_inlinequeryresultcachedvoice.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineQueryResultCachedVoice, InlineKeyboardButton, InlineKeyboardMarkup, - InlineQueryResultCachedAudio, InputTextMessageContent) +from telegram import ( + InlineQueryResultCachedVoice, + InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQueryResultCachedAudio, + InputTextMessageContent, +) @pytest.fixture(scope='class') @@ -32,7 +37,8 @@ def inline_query_result_cached_voice(): caption=TestInlineQueryResultCachedVoice.caption, parse_mode=TestInlineQueryResultCachedVoice.parse_mode, input_message_content=TestInlineQueryResultCachedVoice.input_message_content, - reply_markup=TestInlineQueryResultCachedVoice.reply_markup) + reply_markup=TestInlineQueryResultCachedVoice.reply_markup, + ) class TestInlineQueryResultCachedVoice: @@ -52,30 +58,46 @@ class TestInlineQueryResultCachedVoice: assert inline_query_result_cached_voice.title == self.title assert inline_query_result_cached_voice.caption == self.caption assert inline_query_result_cached_voice.parse_mode == self.parse_mode - assert (inline_query_result_cached_voice.input_message_content.to_dict() - == self.input_message_content.to_dict()) - assert (inline_query_result_cached_voice.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert ( + inline_query_result_cached_voice.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_voice.reply_markup.to_dict() == self.reply_markup.to_dict() + ) def test_to_dict(self, inline_query_result_cached_voice): inline_query_result_cached_voice_dict = inline_query_result_cached_voice.to_dict() assert isinstance(inline_query_result_cached_voice_dict, dict) - assert (inline_query_result_cached_voice_dict['type'] - == inline_query_result_cached_voice.type) + assert ( + inline_query_result_cached_voice_dict['type'] == inline_query_result_cached_voice.type + ) assert inline_query_result_cached_voice_dict['id'] == inline_query_result_cached_voice.id - assert (inline_query_result_cached_voice_dict['voice_file_id'] - == inline_query_result_cached_voice.voice_file_id) - assert (inline_query_result_cached_voice_dict['title'] - == inline_query_result_cached_voice.title) - assert (inline_query_result_cached_voice_dict['caption'] - == inline_query_result_cached_voice.caption) - assert (inline_query_result_cached_voice_dict['parse_mode'] - == inline_query_result_cached_voice.parse_mode) - assert (inline_query_result_cached_voice_dict['input_message_content'] - == inline_query_result_cached_voice.input_message_content.to_dict()) - assert (inline_query_result_cached_voice_dict['reply_markup'] - == inline_query_result_cached_voice.reply_markup.to_dict()) + assert ( + inline_query_result_cached_voice_dict['voice_file_id'] + == inline_query_result_cached_voice.voice_file_id + ) + assert ( + inline_query_result_cached_voice_dict['title'] + == inline_query_result_cached_voice.title + ) + assert ( + inline_query_result_cached_voice_dict['caption'] + == inline_query_result_cached_voice.caption + ) + assert ( + inline_query_result_cached_voice_dict['parse_mode'] + == inline_query_result_cached_voice.parse_mode + ) + assert ( + inline_query_result_cached_voice_dict['input_message_content'] + == inline_query_result_cached_voice.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_voice_dict['reply_markup'] + == inline_query_result_cached_voice.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultCachedVoice(self.id_, self.voice_file_id, self.title) diff --git a/tests/test_inlinequeryresultcontact.py b/tests/test_inlinequeryresultcontact.py index 68b0ab773..dedcc9183 100644 --- a/tests/test_inlinequeryresultcontact.py +++ b/tests/test_inlinequeryresultcontact.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineQueryResultVoice, InputTextMessageContent, InlineKeyboardButton, - InlineKeyboardMarkup, InlineQueryResultContact) +from telegram import ( + InlineQueryResultVoice, + InputTextMessageContent, + InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQueryResultContact, +) @pytest.fixture(scope='class') @@ -34,7 +39,8 @@ def inline_query_result_contact(): thumb_width=TestInlineQueryResultContact.thumb_width, thumb_height=TestInlineQueryResultContact.thumb_height, input_message_content=TestInlineQueryResultContact.input_message_content, - reply_markup=TestInlineQueryResultContact.reply_markup) + reply_markup=TestInlineQueryResultContact.reply_markup, + ) class TestInlineQueryResultContact: @@ -58,8 +64,10 @@ class TestInlineQueryResultContact: assert inline_query_result_contact.thumb_url == self.thumb_url assert inline_query_result_contact.thumb_width == self.thumb_width assert inline_query_result_contact.thumb_height == self.thumb_height - assert (inline_query_result_contact.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_contact.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_contact.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_contact): @@ -68,22 +76,36 @@ class TestInlineQueryResultContact: assert isinstance(inline_query_result_contact_dict, dict) assert inline_query_result_contact_dict['id'] == inline_query_result_contact.id assert inline_query_result_contact_dict['type'] == inline_query_result_contact.type - assert (inline_query_result_contact_dict['phone_number'] - == inline_query_result_contact.phone_number) - assert (inline_query_result_contact_dict['first_name'] - == inline_query_result_contact.first_name) - assert (inline_query_result_contact_dict['last_name'] - == inline_query_result_contact.last_name) - assert (inline_query_result_contact_dict['thumb_url'] - == inline_query_result_contact.thumb_url) - assert (inline_query_result_contact_dict['thumb_width'] - == inline_query_result_contact.thumb_width) - assert (inline_query_result_contact_dict['thumb_height'] - == inline_query_result_contact.thumb_height) - assert (inline_query_result_contact_dict['input_message_content'] - == inline_query_result_contact.input_message_content.to_dict()) - assert (inline_query_result_contact_dict['reply_markup'] - == inline_query_result_contact.reply_markup.to_dict()) + assert ( + inline_query_result_contact_dict['phone_number'] + == inline_query_result_contact.phone_number + ) + assert ( + inline_query_result_contact_dict['first_name'] + == inline_query_result_contact.first_name + ) + assert ( + inline_query_result_contact_dict['last_name'] == inline_query_result_contact.last_name + ) + assert ( + inline_query_result_contact_dict['thumb_url'] == inline_query_result_contact.thumb_url + ) + assert ( + inline_query_result_contact_dict['thumb_width'] + == inline_query_result_contact.thumb_width + ) + assert ( + inline_query_result_contact_dict['thumb_height'] + == inline_query_result_contact.thumb_height + ) + assert ( + inline_query_result_contact_dict['input_message_content'] + == inline_query_result_contact.input_message_content.to_dict() + ) + assert ( + inline_query_result_contact_dict['reply_markup'] + == inline_query_result_contact.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultContact(self.id_, self.phone_number, self.first_name) diff --git a/tests/test_inlinequeryresultdocument.py b/tests/test_inlinequeryresultdocument.py index b23e9653c..cec8b1cba 100644 --- a/tests/test_inlinequeryresultdocument.py +++ b/tests/test_inlinequeryresultdocument.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultDocument, - InlineKeyboardMarkup, InlineQueryResultVoice) +from telegram import ( + InlineKeyboardButton, + InputTextMessageContent, + InlineQueryResultDocument, + InlineKeyboardMarkup, + InlineQueryResultVoice, +) @pytest.fixture(scope='class') @@ -37,7 +42,8 @@ def inline_query_result_document(): thumb_width=TestInlineQueryResultDocument.thumb_width, thumb_height=TestInlineQueryResultDocument.thumb_height, input_message_content=TestInlineQueryResultDocument.input_message_content, - reply_markup=TestInlineQueryResultDocument.reply_markup) + reply_markup=TestInlineQueryResultDocument.reply_markup, + ) class TestInlineQueryResultDocument: @@ -67,8 +73,10 @@ class TestInlineQueryResultDocument: assert inline_query_result_document.thumb_url == self.thumb_url assert inline_query_result_document.thumb_width == self.thumb_width assert inline_query_result_document.thumb_height == self.thumb_height - assert (inline_query_result_document.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_document.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_document.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_document): @@ -77,32 +85,48 @@ class TestInlineQueryResultDocument: assert isinstance(inline_query_result_document_dict, dict) assert inline_query_result_document_dict['id'] == inline_query_result_document.id assert inline_query_result_document_dict['type'] == inline_query_result_document.type - assert (inline_query_result_document_dict['document_url'] - == inline_query_result_document.document_url) + assert ( + inline_query_result_document_dict['document_url'] + == inline_query_result_document.document_url + ) assert inline_query_result_document_dict['title'] == inline_query_result_document.title assert inline_query_result_document_dict['caption'] == inline_query_result_document.caption - assert (inline_query_result_document_dict['parse_mode'] - == inline_query_result_document.parse_mode) - assert (inline_query_result_document_dict['mime_type'] - == inline_query_result_document.mime_type) - assert (inline_query_result_document_dict['description'] - == inline_query_result_document.description) - assert (inline_query_result_document_dict['thumb_url'] - == inline_query_result_document.thumb_url) - assert (inline_query_result_document_dict['thumb_width'] - == inline_query_result_document.thumb_width) - assert (inline_query_result_document_dict['thumb_height'] - == inline_query_result_document.thumb_height) - assert (inline_query_result_document_dict['input_message_content'] - == inline_query_result_document.input_message_content.to_dict()) - assert (inline_query_result_document_dict['reply_markup'] - == inline_query_result_document.reply_markup.to_dict()) + assert ( + inline_query_result_document_dict['parse_mode'] + == inline_query_result_document.parse_mode + ) + assert ( + inline_query_result_document_dict['mime_type'] + == inline_query_result_document.mime_type + ) + assert ( + inline_query_result_document_dict['description'] + == inline_query_result_document.description + ) + assert ( + inline_query_result_document_dict['thumb_url'] + == inline_query_result_document.thumb_url + ) + assert ( + inline_query_result_document_dict['thumb_width'] + == inline_query_result_document.thumb_width + ) + assert ( + inline_query_result_document_dict['thumb_height'] + == inline_query_result_document.thumb_height + ) + assert ( + inline_query_result_document_dict['input_message_content'] + == inline_query_result_document.input_message_content.to_dict() + ) + assert ( + inline_query_result_document_dict['reply_markup'] + == inline_query_result_document.reply_markup.to_dict() + ) def test_equality(self): - a = InlineQueryResultDocument(self.id_, self.document_url, self.title, - self.mime_type) - b = InlineQueryResultDocument(self.id_, self.document_url, self.title, - self.mime_type) + a = InlineQueryResultDocument(self.id_, self.document_url, self.title, self.mime_type) + b = InlineQueryResultDocument(self.id_, self.document_url, self.title, self.mime_type) c = InlineQueryResultDocument(self.id_, '', self.title, self.mime_type) d = InlineQueryResultDocument('', self.document_url, self.title, self.mime_type) e = InlineQueryResultVoice(self.id_, '', '') diff --git a/tests/test_inlinequeryresultgame.py b/tests/test_inlinequeryresultgame.py index 2e8a24611..c2ca31928 100644 --- a/tests/test_inlinequeryresultgame.py +++ b/tests/test_inlinequeryresultgame.py @@ -19,15 +19,21 @@ import pytest -from telegram import (InlineKeyboardButton, InlineQueryResultGame, - InlineQueryResultVoice, InlineKeyboardMarkup) +from telegram import ( + InlineKeyboardButton, + InlineQueryResultGame, + InlineQueryResultVoice, + InlineKeyboardMarkup, +) @pytest.fixture(scope='class') def inline_query_result_game(): - return InlineQueryResultGame(TestInlineQueryResultGame.id_, - TestInlineQueryResultGame.game_short_name, - reply_markup=TestInlineQueryResultGame.reply_markup) + return InlineQueryResultGame( + TestInlineQueryResultGame.id_, + TestInlineQueryResultGame.game_short_name, + reply_markup=TestInlineQueryResultGame.reply_markup, + ) class TestInlineQueryResultGame: @@ -40,8 +46,7 @@ class TestInlineQueryResultGame: assert inline_query_result_game.type == self.type_ assert inline_query_result_game.id == self.id_ assert inline_query_result_game.game_short_name == self.game_short_name - assert (inline_query_result_game.reply_markup.to_dict() - == self.reply_markup.to_dict()) + assert inline_query_result_game.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_game): inline_query_result_game_dict = inline_query_result_game.to_dict() @@ -49,10 +54,14 @@ class TestInlineQueryResultGame: assert isinstance(inline_query_result_game_dict, dict) assert inline_query_result_game_dict['type'] == inline_query_result_game.type assert inline_query_result_game_dict['id'] == inline_query_result_game.id - assert (inline_query_result_game_dict['game_short_name'] - == inline_query_result_game.game_short_name) - assert (inline_query_result_game_dict['reply_markup'] - == inline_query_result_game.reply_markup.to_dict()) + assert ( + inline_query_result_game_dict['game_short_name'] + == inline_query_result_game.game_short_name + ) + assert ( + inline_query_result_game_dict['reply_markup'] + == inline_query_result_game.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultGame(self.id_, self.game_short_name) diff --git a/tests/test_inlinequeryresultgif.py b/tests/test_inlinequeryresultgif.py index 6bc889dc1..309d6efab 100644 --- a/tests/test_inlinequeryresultgif.py +++ b/tests/test_inlinequeryresultgif.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultGif, - InlineQueryResultVoice, InlineKeyboardMarkup) +from telegram import ( + InlineKeyboardButton, + InputTextMessageContent, + InlineQueryResultGif, + InlineQueryResultVoice, + InlineKeyboardMarkup, +) @pytest.fixture(scope='class') @@ -37,7 +42,8 @@ def inline_query_result_gif(): parse_mode=TestInlineQueryResultGif.parse_mode, input_message_content=TestInlineQueryResultGif.input_message_content, reply_markup=TestInlineQueryResultGif.reply_markup, - thumb_mime_type=TestInlineQueryResultGif.thumb_mime_type) + thumb_mime_type=TestInlineQueryResultGif.thumb_mime_type, + ) class TestInlineQueryResultGif: @@ -67,8 +73,10 @@ class TestInlineQueryResultGif: assert inline_query_result_gif.title == self.title assert inline_query_result_gif.caption == self.caption assert inline_query_result_gif.parse_mode == self.parse_mode - assert (inline_query_result_gif.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_gif.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_gif.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_gif): @@ -82,15 +90,21 @@ class TestInlineQueryResultGif: assert inline_query_result_gif_dict['gif_height'] == inline_query_result_gif.gif_height assert inline_query_result_gif_dict['gif_duration'] == inline_query_result_gif.gif_duration assert inline_query_result_gif_dict['thumb_url'] == inline_query_result_gif.thumb_url - assert (inline_query_result_gif_dict['thumb_mime_type'] - == inline_query_result_gif.thumb_mime_type) + assert ( + inline_query_result_gif_dict['thumb_mime_type'] + == inline_query_result_gif.thumb_mime_type + ) assert inline_query_result_gif_dict['title'] == inline_query_result_gif.title assert inline_query_result_gif_dict['caption'] == inline_query_result_gif.caption assert inline_query_result_gif_dict['parse_mode'] == inline_query_result_gif.parse_mode - assert (inline_query_result_gif_dict['input_message_content'] - == inline_query_result_gif.input_message_content.to_dict()) - assert (inline_query_result_gif_dict['reply_markup'] - == inline_query_result_gif.reply_markup.to_dict()) + assert ( + inline_query_result_gif_dict['input_message_content'] + == inline_query_result_gif.input_message_content.to_dict() + ) + assert ( + inline_query_result_gif_dict['reply_markup'] + == inline_query_result_gif.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultGif(self.id_, self.gif_url, self.thumb_url) diff --git a/tests/test_inlinequeryresultlocation.py b/tests/test_inlinequeryresultlocation.py index 860088a3f..7586f0292 100644 --- a/tests/test_inlinequeryresultlocation.py +++ b/tests/test_inlinequeryresultlocation.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InputTextMessageContent, InlineQueryResultLocation, InlineKeyboardButton, - InlineQueryResultVoice, InlineKeyboardMarkup) +from telegram import ( + InputTextMessageContent, + InlineQueryResultLocation, + InlineKeyboardButton, + InlineQueryResultVoice, + InlineKeyboardMarkup, +) @pytest.fixture(scope='class') @@ -35,7 +40,8 @@ def inline_query_result_location(): thumb_width=TestInlineQueryResultLocation.thumb_width, thumb_height=TestInlineQueryResultLocation.thumb_height, input_message_content=TestInlineQueryResultLocation.input_message_content, - reply_markup=TestInlineQueryResultLocation.reply_markup) + reply_markup=TestInlineQueryResultLocation.reply_markup, + ) class TestInlineQueryResultLocation: @@ -61,8 +67,10 @@ class TestInlineQueryResultLocation: assert inline_query_result_location.thumb_url == self.thumb_url assert inline_query_result_location.thumb_width == self.thumb_width assert inline_query_result_location.thumb_height == self.thumb_height - assert (inline_query_result_location.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_location.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_location.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_location): @@ -71,23 +79,38 @@ class TestInlineQueryResultLocation: assert isinstance(inline_query_result_location_dict, dict) assert inline_query_result_location_dict['id'] == inline_query_result_location.id assert inline_query_result_location_dict['type'] == inline_query_result_location.type - assert (inline_query_result_location_dict['latitude'] - == inline_query_result_location.latitude) - assert (inline_query_result_location_dict['longitude'] - == inline_query_result_location.longitude) + assert ( + inline_query_result_location_dict['latitude'] == inline_query_result_location.latitude + ) + assert ( + inline_query_result_location_dict['longitude'] + == inline_query_result_location.longitude + ) assert inline_query_result_location_dict['title'] == inline_query_result_location.title - assert (inline_query_result_location_dict['live_period'] - == inline_query_result_location.live_period) - assert (inline_query_result_location_dict['thumb_url'] - == inline_query_result_location.thumb_url) - assert (inline_query_result_location_dict['thumb_width'] - == inline_query_result_location.thumb_width) - assert (inline_query_result_location_dict['thumb_height'] - == inline_query_result_location.thumb_height) - assert (inline_query_result_location_dict['input_message_content'] - == inline_query_result_location.input_message_content.to_dict()) - assert (inline_query_result_location_dict['reply_markup'] - == inline_query_result_location.reply_markup.to_dict()) + assert ( + inline_query_result_location_dict['live_period'] + == inline_query_result_location.live_period + ) + assert ( + inline_query_result_location_dict['thumb_url'] + == inline_query_result_location.thumb_url + ) + assert ( + inline_query_result_location_dict['thumb_width'] + == inline_query_result_location.thumb_width + ) + assert ( + inline_query_result_location_dict['thumb_height'] + == inline_query_result_location.thumb_height + ) + assert ( + inline_query_result_location_dict['input_message_content'] + == inline_query_result_location.input_message_content.to_dict() + ) + assert ( + inline_query_result_location_dict['reply_markup'] + == inline_query_result_location.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultLocation(self.id_, self.longitude, self.latitude, self.title) diff --git a/tests/test_inlinequeryresultmpeg4gif.py b/tests/test_inlinequeryresultmpeg4gif.py index 840101b23..6312732eb 100644 --- a/tests/test_inlinequeryresultmpeg4gif.py +++ b/tests/test_inlinequeryresultmpeg4gif.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineQueryResultMpeg4Gif, InlineKeyboardButton, InlineQueryResultVoice, - InlineKeyboardMarkup, InputTextMessageContent) +from telegram import ( + InlineQueryResultMpeg4Gif, + InlineKeyboardButton, + InlineQueryResultVoice, + InlineKeyboardMarkup, + InputTextMessageContent, +) @pytest.fixture(scope='class') @@ -37,7 +42,8 @@ def inline_query_result_mpeg4_gif(): parse_mode=TestInlineQueryResultMpeg4Gif.parse_mode, input_message_content=TestInlineQueryResultMpeg4Gif.input_message_content, reply_markup=TestInlineQueryResultMpeg4Gif.reply_markup, - thumb_mime_type=TestInlineQueryResultMpeg4Gif.thumb_mime_type) + thumb_mime_type=TestInlineQueryResultMpeg4Gif.thumb_mime_type, + ) class TestInlineQueryResultMpeg4Gif: @@ -67,8 +73,10 @@ class TestInlineQueryResultMpeg4Gif: assert inline_query_result_mpeg4_gif.title == self.title assert inline_query_result_mpeg4_gif.caption == self.caption assert inline_query_result_mpeg4_gif.parse_mode == self.parse_mode - assert (inline_query_result_mpeg4_gif.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_mpeg4_gif.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_mpeg4_gif.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_mpeg4_gif): @@ -77,27 +85,46 @@ class TestInlineQueryResultMpeg4Gif: assert isinstance(inline_query_result_mpeg4_gif_dict, dict) assert inline_query_result_mpeg4_gif_dict['type'] == inline_query_result_mpeg4_gif.type assert inline_query_result_mpeg4_gif_dict['id'] == inline_query_result_mpeg4_gif.id - assert (inline_query_result_mpeg4_gif_dict['mpeg4_url'] - == inline_query_result_mpeg4_gif.mpeg4_url) - assert (inline_query_result_mpeg4_gif_dict['mpeg4_width'] - == inline_query_result_mpeg4_gif.mpeg4_width) - assert (inline_query_result_mpeg4_gif_dict['mpeg4_height'] - == inline_query_result_mpeg4_gif.mpeg4_height) - assert (inline_query_result_mpeg4_gif_dict['mpeg4_duration'] - == inline_query_result_mpeg4_gif.mpeg4_duration) - assert (inline_query_result_mpeg4_gif_dict['thumb_url'] - == inline_query_result_mpeg4_gif.thumb_url) - assert (inline_query_result_mpeg4_gif_dict['thumb_mime_type'] - == inline_query_result_mpeg4_gif.thumb_mime_type) + assert ( + inline_query_result_mpeg4_gif_dict['mpeg4_url'] + == inline_query_result_mpeg4_gif.mpeg4_url + ) + assert ( + inline_query_result_mpeg4_gif_dict['mpeg4_width'] + == inline_query_result_mpeg4_gif.mpeg4_width + ) + assert ( + inline_query_result_mpeg4_gif_dict['mpeg4_height'] + == inline_query_result_mpeg4_gif.mpeg4_height + ) + assert ( + inline_query_result_mpeg4_gif_dict['mpeg4_duration'] + == inline_query_result_mpeg4_gif.mpeg4_duration + ) + assert ( + inline_query_result_mpeg4_gif_dict['thumb_url'] + == inline_query_result_mpeg4_gif.thumb_url + ) + assert ( + inline_query_result_mpeg4_gif_dict['thumb_mime_type'] + == inline_query_result_mpeg4_gif.thumb_mime_type + ) assert inline_query_result_mpeg4_gif_dict['title'] == inline_query_result_mpeg4_gif.title - assert (inline_query_result_mpeg4_gif_dict['caption'] - == inline_query_result_mpeg4_gif.caption) - assert (inline_query_result_mpeg4_gif_dict['parse_mode'] - == inline_query_result_mpeg4_gif.parse_mode) - assert (inline_query_result_mpeg4_gif_dict['input_message_content'] - == inline_query_result_mpeg4_gif.input_message_content.to_dict()) - assert (inline_query_result_mpeg4_gif_dict['reply_markup'] - == inline_query_result_mpeg4_gif.reply_markup.to_dict()) + assert ( + inline_query_result_mpeg4_gif_dict['caption'] == inline_query_result_mpeg4_gif.caption + ) + assert ( + inline_query_result_mpeg4_gif_dict['parse_mode'] + == inline_query_result_mpeg4_gif.parse_mode + ) + assert ( + inline_query_result_mpeg4_gif_dict['input_message_content'] + == inline_query_result_mpeg4_gif.input_message_content.to_dict() + ) + assert ( + inline_query_result_mpeg4_gif_dict['reply_markup'] + == inline_query_result_mpeg4_gif.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultMpeg4Gif(self.id_, self.mpeg4_url, self.thumb_url) diff --git a/tests/test_inlinequeryresultphoto.py b/tests/test_inlinequeryresultphoto.py index 0f27c2a5c..40b0ecd3d 100644 --- a/tests/test_inlinequeryresultphoto.py +++ b/tests/test_inlinequeryresultphoto.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InputTextMessageContent, InlineKeyboardButton, InlineKeyboardMarkup, - InlineQueryResultPhoto, InlineQueryResultVoice) +from telegram import ( + InputTextMessageContent, + InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQueryResultPhoto, + InlineQueryResultVoice, +) @pytest.fixture(scope='class') @@ -36,7 +41,8 @@ def inline_query_result_photo(): caption=TestInlineQueryResultPhoto.caption, parse_mode=TestInlineQueryResultPhoto.parse_mode, input_message_content=TestInlineQueryResultPhoto.input_message_content, - reply_markup=TestInlineQueryResultPhoto.reply_markup) + reply_markup=TestInlineQueryResultPhoto.reply_markup, + ) class TestInlineQueryResultPhoto: @@ -64,8 +70,10 @@ class TestInlineQueryResultPhoto: assert inline_query_result_photo.description == self.description assert inline_query_result_photo.caption == self.caption assert inline_query_result_photo.parse_mode == self.parse_mode - assert (inline_query_result_photo.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_photo.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_photo.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_photo): @@ -75,20 +83,28 @@ class TestInlineQueryResultPhoto: assert inline_query_result_photo_dict['type'] == inline_query_result_photo.type assert inline_query_result_photo_dict['id'] == inline_query_result_photo.id assert inline_query_result_photo_dict['photo_url'] == inline_query_result_photo.photo_url - assert (inline_query_result_photo_dict['photo_width'] - == inline_query_result_photo.photo_width) - assert (inline_query_result_photo_dict['photo_height'] - == inline_query_result_photo.photo_height) + assert ( + inline_query_result_photo_dict['photo_width'] == inline_query_result_photo.photo_width + ) + assert ( + inline_query_result_photo_dict['photo_height'] + == inline_query_result_photo.photo_height + ) assert inline_query_result_photo_dict['thumb_url'] == inline_query_result_photo.thumb_url assert inline_query_result_photo_dict['title'] == inline_query_result_photo.title - assert (inline_query_result_photo_dict['description'] - == inline_query_result_photo.description) + assert ( + inline_query_result_photo_dict['description'] == inline_query_result_photo.description + ) assert inline_query_result_photo_dict['caption'] == inline_query_result_photo.caption assert inline_query_result_photo_dict['parse_mode'] == inline_query_result_photo.parse_mode - assert (inline_query_result_photo_dict['input_message_content'] - == inline_query_result_photo.input_message_content.to_dict()) - assert (inline_query_result_photo_dict['reply_markup'] - == inline_query_result_photo.reply_markup.to_dict()) + assert ( + inline_query_result_photo_dict['input_message_content'] + == inline_query_result_photo.input_message_content.to_dict() + ) + assert ( + inline_query_result_photo_dict['reply_markup'] + == inline_query_result_photo.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultPhoto(self.id_, self.photo_url, self.thumb_url) diff --git a/tests/test_inlinequeryresultvenue.py b/tests/test_inlinequeryresultvenue.py index ddb08a24d..1c8f3856a 100644 --- a/tests/test_inlinequeryresultvenue.py +++ b/tests/test_inlinequeryresultvenue.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineQueryResultVoice, InputTextMessageContent, InlineKeyboardButton, - InlineQueryResultVenue, InlineKeyboardMarkup) +from telegram import ( + InlineQueryResultVoice, + InputTextMessageContent, + InlineKeyboardButton, + InlineQueryResultVenue, + InlineKeyboardMarkup, +) @pytest.fixture(scope='class') @@ -37,7 +42,8 @@ def inline_query_result_venue(): thumb_width=TestInlineQueryResultVenue.thumb_width, thumb_height=TestInlineQueryResultVenue.thumb_height, input_message_content=TestInlineQueryResultVenue.input_message_content, - reply_markup=TestInlineQueryResultVenue.reply_markup) + reply_markup=TestInlineQueryResultVenue.reply_markup, + ) class TestInlineQueryResultVenue: @@ -67,8 +73,10 @@ class TestInlineQueryResultVenue: assert inline_query_result_venue.thumb_url == self.thumb_url assert inline_query_result_venue.thumb_width == self.thumb_width assert inline_query_result_venue.thumb_height == self.thumb_height - assert (inline_query_result_venue.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_venue.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_venue.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_venue): @@ -81,28 +89,40 @@ class TestInlineQueryResultVenue: assert inline_query_result_venue_dict['longitude'] == inline_query_result_venue.longitude assert inline_query_result_venue_dict['title'] == inline_query_result_venue.title assert inline_query_result_venue_dict['address'] == inline_query_result_venue.address - assert (inline_query_result_venue_dict['foursquare_id'] - == inline_query_result_venue.foursquare_id) - assert (inline_query_result_venue_dict['foursquare_type'] - == inline_query_result_venue.foursquare_type) + assert ( + inline_query_result_venue_dict['foursquare_id'] + == inline_query_result_venue.foursquare_id + ) + assert ( + inline_query_result_venue_dict['foursquare_type'] + == inline_query_result_venue.foursquare_type + ) assert inline_query_result_venue_dict['thumb_url'] == inline_query_result_venue.thumb_url - assert (inline_query_result_venue_dict['thumb_width'] - == inline_query_result_venue.thumb_width) - assert (inline_query_result_venue_dict['thumb_height'] - == inline_query_result_venue.thumb_height) - assert (inline_query_result_venue_dict['input_message_content'] - == inline_query_result_venue.input_message_content.to_dict()) - assert (inline_query_result_venue_dict['reply_markup'] - == inline_query_result_venue.reply_markup.to_dict()) + assert ( + inline_query_result_venue_dict['thumb_width'] == inline_query_result_venue.thumb_width + ) + assert ( + inline_query_result_venue_dict['thumb_height'] + == inline_query_result_venue.thumb_height + ) + assert ( + inline_query_result_venue_dict['input_message_content'] + == inline_query_result_venue.input_message_content.to_dict() + ) + assert ( + inline_query_result_venue_dict['reply_markup'] + == inline_query_result_venue.reply_markup.to_dict() + ) def test_equality(self): - a = InlineQueryResultVenue(self.id_, self.longitude, self.latitude, self.title, - self.address) - b = InlineQueryResultVenue(self.id_, self.longitude, self.latitude, self.title, - self.address) + a = InlineQueryResultVenue( + self.id_, self.longitude, self.latitude, self.title, self.address + ) + b = InlineQueryResultVenue( + self.id_, self.longitude, self.latitude, self.title, self.address + ) c = InlineQueryResultVenue(self.id_, '', self.latitude, self.title, self.address) - d = InlineQueryResultVenue('', self.longitude, self.latitude, self.title, - self.address) + d = InlineQueryResultVenue('', self.longitude, self.latitude, self.title, self.address) e = InlineQueryResultVoice(self.id_, '', '') assert a == b diff --git a/tests/test_inlinequeryresultvideo.py b/tests/test_inlinequeryresultvideo.py index 464803b15..6f2971d44 100644 --- a/tests/test_inlinequeryresultvideo.py +++ b/tests/test_inlinequeryresultvideo.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultVideo, - InlineKeyboardMarkup, InlineQueryResultVoice) +from telegram import ( + InlineKeyboardButton, + InputTextMessageContent, + InlineQueryResultVideo, + InlineKeyboardMarkup, + InlineQueryResultVoice, +) @pytest.fixture(scope='class') @@ -38,7 +43,8 @@ def inline_query_result_video(): parse_mode=TestInlineQueryResultVideo.parse_mode, description=TestInlineQueryResultVideo.description, input_message_content=TestInlineQueryResultVideo.input_message_content, - reply_markup=TestInlineQueryResultVideo.reply_markup) + reply_markup=TestInlineQueryResultVideo.reply_markup, + ) class TestInlineQueryResultVideo: @@ -70,8 +76,10 @@ class TestInlineQueryResultVideo: assert inline_query_result_video.description == self.description assert inline_query_result_video.caption == self.caption assert inline_query_result_video.parse_mode == self.parse_mode - assert (inline_query_result_video.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_video.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_video.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_video): @@ -82,32 +90,42 @@ class TestInlineQueryResultVideo: assert inline_query_result_video_dict['id'] == inline_query_result_video.id assert inline_query_result_video_dict['video_url'] == inline_query_result_video.video_url assert inline_query_result_video_dict['mime_type'] == inline_query_result_video.mime_type - assert (inline_query_result_video_dict['video_width'] - == inline_query_result_video.video_width) - assert (inline_query_result_video_dict['video_height'] - == inline_query_result_video.video_height) - assert (inline_query_result_video_dict['video_duration'] - == inline_query_result_video.video_duration) + assert ( + inline_query_result_video_dict['video_width'] == inline_query_result_video.video_width + ) + assert ( + inline_query_result_video_dict['video_height'] + == inline_query_result_video.video_height + ) + assert ( + inline_query_result_video_dict['video_duration'] + == inline_query_result_video.video_duration + ) assert inline_query_result_video_dict['thumb_url'] == inline_query_result_video.thumb_url assert inline_query_result_video_dict['title'] == inline_query_result_video.title - assert (inline_query_result_video_dict['description'] - == inline_query_result_video.description) + assert ( + inline_query_result_video_dict['description'] == inline_query_result_video.description + ) assert inline_query_result_video_dict['caption'] == inline_query_result_video.caption assert inline_query_result_video_dict['parse_mode'] == inline_query_result_video.parse_mode - assert (inline_query_result_video_dict['input_message_content'] - == inline_query_result_video.input_message_content.to_dict()) - assert (inline_query_result_video_dict['reply_markup'] - == inline_query_result_video.reply_markup.to_dict()) + assert ( + inline_query_result_video_dict['input_message_content'] + == inline_query_result_video.input_message_content.to_dict() + ) + assert ( + inline_query_result_video_dict['reply_markup'] + == inline_query_result_video.reply_markup.to_dict() + ) def test_equality(self): - a = InlineQueryResultVideo(self.id_, self.video_url, self.mime_type, - self.thumb_url, self.title) - b = InlineQueryResultVideo(self.id_, self.video_url, self.mime_type, - self.thumb_url, self.title) - c = InlineQueryResultVideo(self.id_, '', self.mime_type, self.thumb_url, - self.title) - d = InlineQueryResultVideo('', self.video_url, self.mime_type, self.thumb_url, - self.title) + a = InlineQueryResultVideo( + self.id_, self.video_url, self.mime_type, self.thumb_url, self.title + ) + b = InlineQueryResultVideo( + self.id_, self.video_url, self.mime_type, self.thumb_url, self.title + ) + c = InlineQueryResultVideo(self.id_, '', self.mime_type, self.thumb_url, self.title) + d = InlineQueryResultVideo('', self.video_url, self.mime_type, self.thumb_url, self.title) e = InlineQueryResultVoice(self.id_, '', '') assert a == b diff --git a/tests/test_inlinequeryresultvoice.py b/tests/test_inlinequeryresultvoice.py index 5fa5f1eeb..eece3590e 100644 --- a/tests/test_inlinequeryresultvoice.py +++ b/tests/test_inlinequeryresultvoice.py @@ -19,8 +19,13 @@ import pytest -from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultAudio, - InlineQueryResultVoice, InlineKeyboardMarkup) +from telegram import ( + InlineKeyboardButton, + InputTextMessageContent, + InlineQueryResultAudio, + InlineQueryResultVoice, + InlineKeyboardMarkup, +) @pytest.fixture(scope='class') @@ -34,7 +39,8 @@ def inline_query_result_voice(): caption=TestInlineQueryResultVoice.caption, parse_mode=TestInlineQueryResultVoice.parse_mode, input_message_content=TestInlineQueryResultVoice.input_message_content, - reply_markup=TestInlineQueryResultVoice.reply_markup) + reply_markup=TestInlineQueryResultVoice.reply_markup, + ) class TestInlineQueryResultVoice: @@ -56,8 +62,10 @@ class TestInlineQueryResultVoice: assert inline_query_result_voice.voice_duration == self.voice_duration assert inline_query_result_voice.caption == self.caption assert inline_query_result_voice.parse_mode == self.parse_mode - assert (inline_query_result_voice.input_message_content.to_dict() - == self.input_message_content.to_dict()) + assert ( + inline_query_result_voice.input_message_content.to_dict() + == self.input_message_content.to_dict() + ) assert inline_query_result_voice.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_voice): @@ -68,14 +76,20 @@ class TestInlineQueryResultVoice: assert inline_query_result_voice_dict['id'] == inline_query_result_voice.id assert inline_query_result_voice_dict['voice_url'] == inline_query_result_voice.voice_url assert inline_query_result_voice_dict['title'] == inline_query_result_voice.title - assert (inline_query_result_voice_dict['voice_duration'] - == inline_query_result_voice.voice_duration) + assert ( + inline_query_result_voice_dict['voice_duration'] + == inline_query_result_voice.voice_duration + ) assert inline_query_result_voice_dict['caption'] == inline_query_result_voice.caption assert inline_query_result_voice_dict['parse_mode'] == inline_query_result_voice.parse_mode - assert (inline_query_result_voice_dict['input_message_content'] - == inline_query_result_voice.input_message_content.to_dict()) - assert (inline_query_result_voice_dict['reply_markup'] - == inline_query_result_voice.reply_markup.to_dict()) + assert ( + inline_query_result_voice_dict['input_message_content'] + == inline_query_result_voice.input_message_content.to_dict() + ) + assert ( + inline_query_result_voice_dict['reply_markup'] + == inline_query_result_voice.reply_markup.to_dict() + ) def test_equality(self): a = InlineQueryResultVoice(self.id_, self.voice_url, self.title) diff --git a/tests/test_inputcontactmessagecontent.py b/tests/test_inputcontactmessagecontent.py index 7478b4f10..c46512251 100644 --- a/tests/test_inputcontactmessagecontent.py +++ b/tests/test_inputcontactmessagecontent.py @@ -24,9 +24,11 @@ from telegram import InputContactMessageContent, User @pytest.fixture(scope='class') def input_contact_message_content(): - return InputContactMessageContent(TestInputContactMessageContent.phone_number, - TestInputContactMessageContent.first_name, - last_name=TestInputContactMessageContent.last_name) + return InputContactMessageContent( + TestInputContactMessageContent.phone_number, + TestInputContactMessageContent.first_name, + last_name=TestInputContactMessageContent.last_name, + ) class TestInputContactMessageContent: @@ -43,12 +45,18 @@ class TestInputContactMessageContent: input_contact_message_content_dict = input_contact_message_content.to_dict() assert isinstance(input_contact_message_content_dict, dict) - assert (input_contact_message_content_dict['phone_number'] - == input_contact_message_content.phone_number) - assert (input_contact_message_content_dict['first_name'] - == input_contact_message_content.first_name) - assert (input_contact_message_content_dict['last_name'] - == input_contact_message_content.last_name) + assert ( + input_contact_message_content_dict['phone_number'] + == input_contact_message_content.phone_number + ) + assert ( + input_contact_message_content_dict['first_name'] + == input_contact_message_content.first_name + ) + assert ( + input_contact_message_content_dict['last_name'] + == input_contact_message_content.last_name + ) def test_equality(self): a = InputContactMessageContent('phone', 'first', last_name='last') diff --git a/tests/test_inputfile.py b/tests/test_inputfile.py index b961ff527..c715a2f5a 100644 --- a/tests/test_inputfile.py +++ b/tests/test_inputfile.py @@ -59,21 +59,25 @@ class TestInputFile: assert InputFile(BytesIO(b'blah'), filename='tg.mp3').mimetype == 'audio/mpeg' # Test fallback - assert (InputFile(BytesIO(b'blah'), filename='tg.notaproperext').mimetype - == 'application/octet-stream') + assert ( + InputFile(BytesIO(b'blah'), filename='tg.notaproperext').mimetype + == 'application/octet-stream' + ) assert InputFile(BytesIO(b'blah')).mimetype == 'application/octet-stream' def test_filenames(self): assert InputFile(open('tests/data/telegram.jpg', 'rb')).filename == 'telegram.jpg' - assert InputFile(open('tests/data/telegram.jpg', 'rb'), - filename='blah').filename == 'blah' - assert InputFile(open('tests/data/telegram.jpg', 'rb'), - filename='blah.jpg').filename == 'blah.jpg' + assert InputFile(open('tests/data/telegram.jpg', 'rb'), filename='blah').filename == 'blah' + assert ( + InputFile(open('tests/data/telegram.jpg', 'rb'), filename='blah.jpg').filename + == 'blah.jpg' + ) assert InputFile(open('tests/data/telegram', 'rb')).filename == 'telegram' - assert InputFile(open('tests/data/telegram', 'rb'), - filename='blah').filename == 'blah' - assert InputFile(open('tests/data/telegram', 'rb'), - filename='blah.jpg').filename == 'blah.jpg' + assert InputFile(open('tests/data/telegram', 'rb'), filename='blah').filename == 'blah' + assert ( + InputFile(open('tests/data/telegram', 'rb'), filename='blah.jpg').filename + == 'blah.jpg' + ) class MockedFileobject: # A open(?, 'rb') without a .name @@ -84,13 +88,22 @@ class TestInputFile: return self.f.read() assert InputFile(MockedFileobject('tests/data/telegram.jpg')).filename == 'image.jpeg' - assert InputFile(MockedFileobject('tests/data/telegram.jpg'), - filename='blah').filename == 'blah' - assert InputFile(MockedFileobject('tests/data/telegram.jpg'), - filename='blah.jpg').filename == 'blah.jpg' - assert InputFile( - MockedFileobject('tests/data/telegram')).filename == 'application.octet-stream' - assert InputFile(MockedFileobject('tests/data/telegram'), - filename='blah').filename == 'blah' - assert InputFile(MockedFileobject('tests/data/telegram'), - filename='blah.jpg').filename == 'blah.jpg' + assert ( + InputFile(MockedFileobject('tests/data/telegram.jpg'), filename='blah').filename + == 'blah' + ) + assert ( + InputFile(MockedFileobject('tests/data/telegram.jpg'), filename='blah.jpg').filename + == 'blah.jpg' + ) + assert ( + InputFile(MockedFileobject('tests/data/telegram')).filename + == 'application.octet-stream' + ) + assert ( + InputFile(MockedFileobject('tests/data/telegram'), filename='blah').filename == 'blah' + ) + assert ( + InputFile(MockedFileobject('tests/data/telegram'), filename='blah.jpg').filename + == 'blah.jpg' + ) diff --git a/tests/test_inputlocationmessagecontent.py b/tests/test_inputlocationmessagecontent.py index ecd886587..2dcfb9a12 100644 --- a/tests/test_inputlocationmessagecontent.py +++ b/tests/test_inputlocationmessagecontent.py @@ -24,9 +24,11 @@ from telegram import InputLocationMessageContent, Location @pytest.fixture(scope='class') def input_location_message_content(): - return InputLocationMessageContent(TestInputLocationMessageContent.latitude, - TestInputLocationMessageContent.longitude, - live_period=TestInputLocationMessageContent.live_period) + return InputLocationMessageContent( + TestInputLocationMessageContent.latitude, + TestInputLocationMessageContent.longitude, + live_period=TestInputLocationMessageContent.live_period, + ) class TestInputLocationMessageContent: @@ -43,12 +45,18 @@ class TestInputLocationMessageContent: input_location_message_content_dict = input_location_message_content.to_dict() assert isinstance(input_location_message_content_dict, dict) - assert (input_location_message_content_dict['latitude'] - == input_location_message_content.latitude) - assert (input_location_message_content_dict['longitude'] - == input_location_message_content.longitude) - assert (input_location_message_content_dict['live_period'] - == input_location_message_content.live_period) + assert ( + input_location_message_content_dict['latitude'] + == input_location_message_content.latitude + ) + assert ( + input_location_message_content_dict['longitude'] + == input_location_message_content.longitude + ) + assert ( + input_location_message_content_dict['live_period'] + == input_location_message_content.live_period + ) def test_equality(self): a = InputLocationMessageContent(123, 456, 70) diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index 2f360287e..39609faaf 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -19,16 +19,28 @@ import pytest from flaky import flaky -from telegram import (InputMediaVideo, InputMediaPhoto, InputMediaAnimation, Message, InputFile, - InputMediaAudio, InputMediaDocument) +from telegram import ( + InputMediaVideo, + InputMediaPhoto, + InputMediaAnimation, + Message, + InputFile, + InputMediaAudio, + InputMediaDocument, +) + # noinspection PyUnresolvedReferences from .test_animation import animation, animation_file # noqa: F401 + # noinspection PyUnresolvedReferences from .test_audio import audio, audio_file # noqa: F401 + # noinspection PyUnresolvedReferences from .test_document import document, document_file # noqa: F401 + # noinspection PyUnresolvedReferences from .test_photo import _photo, photo_file, photo, thumb # noqa: F401 + # noinspection PyUnresolvedReferences from .test_video import video, video_file # noqa: F401 from tests.conftest import expect_bad_request @@ -36,51 +48,61 @@ from tests.conftest import expect_bad_request @pytest.fixture(scope='class') def input_media_video(class_thumb_file): - return InputMediaVideo(media=TestInputMediaVideo.media, - caption=TestInputMediaVideo.caption, - width=TestInputMediaVideo.width, - height=TestInputMediaVideo.height, - duration=TestInputMediaVideo.duration, - parse_mode=TestInputMediaVideo.parse_mode, - thumb=class_thumb_file, - supports_streaming=TestInputMediaVideo.supports_streaming) + return InputMediaVideo( + media=TestInputMediaVideo.media, + caption=TestInputMediaVideo.caption, + width=TestInputMediaVideo.width, + height=TestInputMediaVideo.height, + duration=TestInputMediaVideo.duration, + parse_mode=TestInputMediaVideo.parse_mode, + thumb=class_thumb_file, + supports_streaming=TestInputMediaVideo.supports_streaming, + ) @pytest.fixture(scope='class') def input_media_photo(class_thumb_file): - return InputMediaPhoto(media=TestInputMediaPhoto.media, - caption=TestInputMediaPhoto.caption, - parse_mode=TestInputMediaPhoto.parse_mode) + return InputMediaPhoto( + media=TestInputMediaPhoto.media, + caption=TestInputMediaPhoto.caption, + parse_mode=TestInputMediaPhoto.parse_mode, + ) @pytest.fixture(scope='class') def input_media_animation(class_thumb_file): - return InputMediaAnimation(media=TestInputMediaAnimation.media, - caption=TestInputMediaAnimation.caption, - parse_mode=TestInputMediaAnimation.parse_mode, - width=TestInputMediaAnimation.width, - height=TestInputMediaAnimation.height, - thumb=class_thumb_file, - duration=TestInputMediaAnimation.duration) + return InputMediaAnimation( + media=TestInputMediaAnimation.media, + caption=TestInputMediaAnimation.caption, + parse_mode=TestInputMediaAnimation.parse_mode, + width=TestInputMediaAnimation.width, + height=TestInputMediaAnimation.height, + thumb=class_thumb_file, + duration=TestInputMediaAnimation.duration, + ) @pytest.fixture(scope='class') def input_media_audio(class_thumb_file): - return InputMediaAudio(media=TestInputMediaAudio.media, - caption=TestInputMediaAudio.caption, - duration=TestInputMediaAudio.duration, - performer=TestInputMediaAudio.performer, - title=TestInputMediaAudio.title, - thumb=class_thumb_file, - parse_mode=TestInputMediaAudio.parse_mode) + return InputMediaAudio( + media=TestInputMediaAudio.media, + caption=TestInputMediaAudio.caption, + duration=TestInputMediaAudio.duration, + performer=TestInputMediaAudio.performer, + title=TestInputMediaAudio.title, + thumb=class_thumb_file, + parse_mode=TestInputMediaAudio.parse_mode, + ) @pytest.fixture(scope='class') def input_media_document(class_thumb_file): - return InputMediaDocument(media=TestInputMediaDocument.media, - caption=TestInputMediaDocument.caption, - thumb=class_thumb_file, - parse_mode=TestInputMediaDocument.parse_mode) + return InputMediaDocument( + media=TestInputMediaDocument.media, + caption=TestInputMediaDocument.caption, + thumb=class_thumb_file, + parse_mode=TestInputMediaDocument.parse_mode, + ) class TestInputMediaVideo: @@ -292,8 +314,10 @@ class TestInputMediaDocument: @pytest.fixture(scope='function') # noqa: F811 def media_group(photo, thumb): # noqa: F811 - return [InputMediaPhoto(photo, caption='photo `1`', parse_mode='Markdown'), - InputMediaPhoto(thumb, caption='photo 2', parse_mode='HTML')] + return [ + InputMediaPhoto(photo, caption='photo `1`', parse_mode='Markdown'), + InputMediaPhoto(thumb, caption='photo 2', parse_mode='HTML'), + ] class TestSendMediaGroup: @@ -310,21 +334,23 @@ class TestSendMediaGroup: @pytest.mark.timeout(10) def test_send_media_group_all_args(self, bot, chat_id, media_group): m1 = bot.send_message(chat_id, text="test") - messages = bot.send_media_group(chat_id, media_group, disable_notification=True, - reply_to_message_id=m1.message_id) + messages = bot.send_media_group( + chat_id, media_group, disable_notification=True, reply_to_message_id=m1.message_id + ) assert isinstance(messages, list) assert len(messages) == 2 assert all([isinstance(mes, Message) for mes in messages]) assert all([mes.media_group_id == messages[0].media_group_id for mes in messages]) - def test_send_media_group_with_thumbs(self, bot, chat_id, video_file, photo_file, # noqa: F811 - monkeypatch): + def test_send_media_group_with_thumbs( + self, bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 + ): def test(*args, **kwargs): data = kwargs['fields'] video_check = data[input_video.media.attach] == input_video.media.field_tuple thumb_check = data[input_video.thumb.attach] == input_video.thumb.field_tuple result = video_check and thumb_check - raise(Exception('Test was {}'.format('successful' if result else 'failing'))) + raise (Exception('Test was {}'.format('successful' if result else 'failing'))) monkeypatch.setattr('telegram.utils.request.Request._request_wrapper', test) input_video = InputMediaVideo(video_file, thumb=photo_file) @@ -333,15 +359,17 @@ class TestSendMediaGroup: @flaky(3, 1) # noqa: F811 @pytest.mark.timeout(10) # noqa: F811 - def test_send_media_group_new_files(self, bot, chat_id, video_file, photo_file, # noqa: F811 - animation_file): # noqa: F811 + def test_send_media_group_new_files( + self, bot, chat_id, video_file, photo_file, animation_file # noqa: F811 + ): # noqa: F811 def func(): - return bot.send_media_group(chat_id, [ - InputMediaVideo(video_file), - InputMediaPhoto(photo_file) - ]) - messages = expect_bad_request(func, 'Type of file mismatch', - 'Telegram did not accept the file.') + return bot.send_media_group( + chat_id, [InputMediaVideo(video_file), InputMediaPhoto(photo_file)] + ) + + messages = expect_bad_request( + func, 'Type of file mismatch', 'Telegram did not accept the file.' + ) assert isinstance(messages, list) assert len(messages) == 2 @@ -363,6 +391,7 @@ class TestSendMediaGroup: messages = bot.send_media_group(chat_id, media_group) cid = messages[-1].chat.id mid = messages[-1].message_id - new_message = bot.edit_message_media(chat_id=cid, message_id=mid, - media=InputMediaPhoto(thumb_file)) + new_message = bot.edit_message_media( + chat_id=cid, message_id=mid, media=InputMediaPhoto(thumb_file) + ) assert isinstance(new_message, Message) diff --git a/tests/test_inputtextmessagecontent.py b/tests/test_inputtextmessagecontent.py index 2a29e18f2..143cd21c9 100644 --- a/tests/test_inputtextmessagecontent.py +++ b/tests/test_inputtextmessagecontent.py @@ -27,7 +27,8 @@ def input_text_message_content(): return InputTextMessageContent( TestInputTextMessageContent.message_text, parse_mode=TestInputTextMessageContent.parse_mode, - disable_web_page_preview=TestInputTextMessageContent.disable_web_page_preview) + disable_web_page_preview=TestInputTextMessageContent.disable_web_page_preview, + ) class TestInputTextMessageContent: @@ -44,12 +45,17 @@ class TestInputTextMessageContent: input_text_message_content_dict = input_text_message_content.to_dict() assert isinstance(input_text_message_content_dict, dict) - assert (input_text_message_content_dict['message_text'] - == input_text_message_content.message_text) - assert (input_text_message_content_dict['parse_mode'] - == input_text_message_content.parse_mode) - assert (input_text_message_content_dict['disable_web_page_preview'] - == input_text_message_content.disable_web_page_preview) + assert ( + input_text_message_content_dict['message_text'] + == input_text_message_content.message_text + ) + assert ( + input_text_message_content_dict['parse_mode'] == input_text_message_content.parse_mode + ) + assert ( + input_text_message_content_dict['disable_web_page_preview'] + == input_text_message_content.disable_web_page_preview + ) def test_equality(self): a = InputTextMessageContent('text') diff --git a/tests/test_inputvenuemessagecontent.py b/tests/test_inputvenuemessagecontent.py index c6e377ea7..fef242a87 100644 --- a/tests/test_inputvenuemessagecontent.py +++ b/tests/test_inputvenuemessagecontent.py @@ -24,17 +24,19 @@ from telegram import InputVenueMessageContent, Location @pytest.fixture(scope='class') def input_venue_message_content(): - return InputVenueMessageContent(TestInputVenueMessageContent.latitude, - TestInputVenueMessageContent.longitude, - TestInputVenueMessageContent.title, - TestInputVenueMessageContent.address, - foursquare_id=TestInputVenueMessageContent.foursquare_id, - foursquare_type=TestInputVenueMessageContent.foursquare_type) + return InputVenueMessageContent( + TestInputVenueMessageContent.latitude, + TestInputVenueMessageContent.longitude, + TestInputVenueMessageContent.title, + TestInputVenueMessageContent.address, + foursquare_id=TestInputVenueMessageContent.foursquare_id, + foursquare_type=TestInputVenueMessageContent.foursquare_type, + ) class TestInputVenueMessageContent: - latitude = 1. - longitude = 2. + latitude = 1.0 + longitude = 2.0 title = 'title' address = 'address' foursquare_id = 'foursquare id' @@ -52,16 +54,20 @@ class TestInputVenueMessageContent: input_venue_message_content_dict = input_venue_message_content.to_dict() assert isinstance(input_venue_message_content_dict, dict) - assert (input_venue_message_content_dict['latitude'] - == input_venue_message_content.latitude) - assert (input_venue_message_content_dict['longitude'] - == input_venue_message_content.longitude) + assert input_venue_message_content_dict['latitude'] == input_venue_message_content.latitude + assert ( + input_venue_message_content_dict['longitude'] == input_venue_message_content.longitude + ) assert input_venue_message_content_dict['title'] == input_venue_message_content.title assert input_venue_message_content_dict['address'] == input_venue_message_content.address - assert (input_venue_message_content_dict['foursquare_id'] - == input_venue_message_content.foursquare_id) - assert (input_venue_message_content_dict['foursquare_type'] - == input_venue_message_content.foursquare_type) + assert ( + input_venue_message_content_dict['foursquare_id'] + == input_venue_message_content.foursquare_id + ) + assert ( + input_venue_message_content_dict['foursquare_type'] + == input_venue_message_content.foursquare_type + ) def test_equality(self): a = InputVenueMessageContent(123, 456, 'title', 'address') diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 6ed65f8d7..9174737a7 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -25,8 +25,13 @@ from telegram import LabeledPrice, Invoice @pytest.fixture(scope='class') def invoice(): - return Invoice(TestInvoice.title, TestInvoice.description, TestInvoice.start_parameter, - TestInvoice.currency, TestInvoice.total_amount) + return Invoice( + TestInvoice.title, + TestInvoice.description, + TestInvoice.start_parameter, + TestInvoice.currency, + TestInvoice.total_amount, + ) class TestInvoice: @@ -40,13 +45,16 @@ class TestInvoice: total_amount = sum([p.amount for p in prices]) def test_de_json(self, bot): - invoice_json = Invoice.de_json({ - 'title': TestInvoice.title, - 'description': TestInvoice.description, - 'start_parameter': TestInvoice.start_parameter, - 'currency': TestInvoice.currency, - 'total_amount': TestInvoice.total_amount - }, bot) + invoice_json = Invoice.de_json( + { + 'title': TestInvoice.title, + 'description': TestInvoice.description, + 'start_parameter': TestInvoice.start_parameter, + 'currency': TestInvoice.currency, + 'total_amount': TestInvoice.total_amount, + }, + bot, + ) assert invoice_json.title == self.title assert invoice_json.description == self.description @@ -67,9 +75,16 @@ class TestInvoice: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_required_args_only(self, bot, chat_id, provider_token): - message = bot.send_invoice(chat_id, self.title, self.description, self.payload, - provider_token, self.start_parameter, self.currency, - self.prices) + message = bot.send_invoice( + chat_id, + self.title, + self.description, + self.payload, + provider_token, + self.start_parameter, + self.currency, + self.prices, + ) assert message.invoice.currency == self.currency assert message.invoice.start_parameter == self.start_parameter @@ -91,8 +106,8 @@ class TestInvoice: self.prices, provider_data=self.provider_data, photo_url='https://raw.githubusercontent.com/' - 'python-telegram-bot/logos/master/' - 'logo/png/ptb-logo_240.png', + 'python-telegram-bot/logos/master/' + 'logo/png/ptb-logo_240.png', photo_size=240, photo_width=240, photo_height=240, @@ -102,7 +117,8 @@ class TestInvoice: need_shipping_address=True, send_phone_number_to_provider=True, send_email_to_provider=True, - is_flexible=True) + is_flexible=True, + ) assert message.invoice.currency == self.currency assert message.invoice.start_parameter == self.start_parameter @@ -112,14 +128,24 @@ class TestInvoice: def test_send_object_as_provider_data(self, monkeypatch, bot, chat_id, provider_token): def test(url, data, **kwargs): - return (data['provider_data'] == '{"test_data": 123456789}' # Depends if using - or data['provider_data'] == '{"test_data":123456789}') # ujson or not + return ( + data['provider_data'] == '{"test_data": 123456789}' # Depends if using + or data['provider_data'] == '{"test_data":123456789}' + ) # ujson or not monkeypatch.setattr(bot.request, 'post', test) - assert bot.send_invoice(chat_id, self.title, self.description, self.payload, - provider_token, self.start_parameter, self.currency, - self.prices, provider_data={'test_data': 123456789}) + assert bot.send_invoice( + chat_id, + self.title, + self.description, + self.payload, + provider_token, + self.start_parameter, + self.currency, + self.prices, + provider_data={'test_data': 123456789}, + ) def test_equality(self): a = Invoice('invoice', 'desc', 'start', 'EUR', 7) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 944ba852d..556b43eec 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -40,8 +40,10 @@ def job_queue(bot, _dp): jq.stop() -@pytest.mark.skipif(os.getenv('GITHUB_ACTIONS', False) and os.name == 'nt', - reason="On windows precise timings are not accurate.") +@pytest.mark.skipif( + os.getenv('GITHUB_ACTIONS', False) and os.name == 'nt', + reason="On windows precise timings are not accurate.", +) @flaky(10, 1) # Timings aren't quite perfect class TestJobQueue: result = 0 @@ -71,14 +73,16 @@ class TestJobQueue: self.job_time = time.time() def job_context_based_callback(self, context): - if (isinstance(context, CallbackContext) - and isinstance(context.job, Job) - and isinstance(context.update_queue, Queue) - and context.job.context == 2 - and context.chat_data is None - and context.user_data is None - and isinstance(context.bot_data, dict) - and context.job_queue is not context.job.job_queue): + if ( + isinstance(context, CallbackContext) + and isinstance(context.job, Job) + and isinstance(context.update_queue, Queue) + and context.job.context == 2 + and context.chat_data is None + and context.user_data is None + and isinstance(context.bot_data, dict) + and context.job_queue is not context.job.job_queue + ): self.result += 1 def error_handler(self, bot, update, error): @@ -123,8 +127,9 @@ class TestJobQueue: def test_run_repeating_first_timezone(self, job_queue, timezone): """Test correct scheduling of job when passing a timezone-aware datetime as ``first``""" - job_queue.run_repeating(self.job_run_once, 0.1, - first=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.05)) + job_queue.run_repeating( + self.job_run_once, 0.1, first=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.05) + ) sleep(0.1) assert self.result == 1 @@ -137,8 +142,9 @@ class TestJobQueue: def test_run_repeating_last_timezone(self, job_queue, timezone): """Test correct scheduling of job when passing a timezone-aware datetime as ``first``""" - job_queue.run_repeating(self.job_run_once, 0.05, - last=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.06)) + job_queue.run_repeating( + self.job_run_once, 0.05, last=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.06) + ) sleep(0.1) assert self.result == 1 sleep(0.1) @@ -301,10 +307,12 @@ class TestJobQueue: day = now.day expected_reschedule_time = timezone.normalize( - expected_reschedule_time + dtm.timedelta(calendar.monthrange(now.year, now.month)[1])) + expected_reschedule_time + dtm.timedelta(calendar.monthrange(now.year, now.month)[1]) + ) # Adjust the hour for the special case that between now and next month a DST switch happens expected_reschedule_time += dtm.timedelta( - hours=time_of_day.hour - expected_reschedule_time.hour) + hours=time_of_day.hour - expected_reschedule_time.hour + ) expected_reschedule_time = expected_reschedule_time.timestamp() job_queue.run_monthly(self.job_run_once, time_of_day, day) @@ -318,12 +326,14 @@ class TestJobQueue: expected_reschedule_time = now + dtm.timedelta(seconds=delta) time_of_day = expected_reschedule_time.time().replace(tzinfo=timezone) - expected_reschedule_time += (dtm.timedelta(calendar.monthrange(now.year, now.month)[1]) - - dtm.timedelta(days=now.day)) + expected_reschedule_time += dtm.timedelta( + calendar.monthrange(now.year, now.month)[1] + ) - dtm.timedelta(days=now.day) # Adjust the hour for the special case that between now & end of month a DST switch happens expected_reschedule_time = timezone.normalize(expected_reschedule_time) expected_reschedule_time += dtm.timedelta( - hours=time_of_day.hour - expected_reschedule_time.hour) + hours=time_of_day.hour - expected_reschedule_time.hour + ) expected_reschedule_time = expected_reschedule_time.timestamp() job_queue.run_monthly(self.job_run_once, time_of_day, 31, day_is_strict=False) @@ -419,7 +429,7 @@ class TestJobQueue: dp.add_error_handler(self.error_handler) job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(.1) + sleep(0.1) assert self.received_error == 'Test Error' self.received_error = None job.run(dp) @@ -430,7 +440,7 @@ class TestJobQueue: self.received_error = None job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(.1) + sleep(0.1) assert self.received_error is None job.run(dp) assert self.received_error is None @@ -439,7 +449,7 @@ class TestJobQueue: cdp.add_error_handler(self.error_handler_context) job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(.1) + sleep(0.1) assert self.received_error == 'Test Error' self.received_error = None job.run(cdp) @@ -450,7 +460,7 @@ class TestJobQueue: self.received_error = None job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(.1) + sleep(0.1) assert self.received_error is None job.run(cdp) assert self.received_error is None @@ -460,7 +470,7 @@ class TestJobQueue: with caplog.at_level(logging.ERROR): job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(.1) + sleep(0.1) assert len(caplog.records) == 1 rec = caplog.records[-1] assert 'processing the job' in rec.msg @@ -481,7 +491,7 @@ class TestJobQueue: with caplog.at_level(logging.ERROR): job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(.1) + sleep(0.1) assert len(caplog.records) == 1 rec = caplog.records[-1] assert 'No error handlers are registered' in rec.msg diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index 2c8bfd792..ebf68d8c1 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -25,10 +25,12 @@ from telegram.keyboardbuttonpolltype import KeyboardButtonPollType @pytest.fixture(scope='class') def keyboard_button(): - return KeyboardButton(TestKeyboardButton.text, - request_location=TestKeyboardButton.request_location, - request_contact=TestKeyboardButton.request_contact, - request_poll=TestKeyboardButton.request_poll) + return KeyboardButton( + TestKeyboardButton.text, + request_location=TestKeyboardButton.request_location, + request_contact=TestKeyboardButton.request_contact, + request_poll=TestKeyboardButton.request_poll, + ) class TestKeyboardButton: diff --git a/tests/test_location.py b/tests/test_location.py index cc6c69f23..c111110d0 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -34,8 +34,7 @@ class TestLocation: longitude = -46.788279 def test_de_json(self, bot): - json_dict = {'latitude': TestLocation.latitude, - 'longitude': TestLocation.longitude} + json_dict = {'latitude': TestLocation.latitude, 'longitude': TestLocation.longitude} location = Location.de_json(json_dict, bot) assert location.latitude == self.latitude @@ -45,22 +44,25 @@ class TestLocation: @pytest.mark.xfail @pytest.mark.timeout(10) def test_send_live_location(self, bot, chat_id): - message = bot.send_location(chat_id=chat_id, latitude=52.223880, longitude=5.166146, - live_period=80) + message = bot.send_location( + chat_id=chat_id, latitude=52.223880, longitude=5.166146, live_period=80 + ) assert message.location assert message.location.latitude == 52.223880 assert message.location.longitude == 5.166146 - message2 = bot.edit_message_live_location(message.chat_id, message.message_id, - latitude=52.223098, longitude=5.164306) + message2 = bot.edit_message_live_location( + message.chat_id, message.message_id, latitude=52.223098, longitude=5.164306 + ) assert message2.location.latitude == 52.223098 assert message2.location.longitude == 5.164306 bot.stop_message_live_location(message.chat_id, message.message_id) with pytest.raises(BadRequest, match="Message can't be edited"): - bot.edit_message_live_location(message.chat_id, message.message_id, latitude=52.223880, - longitude=5.164306) + bot.edit_message_live_location( + message.chat_id, message.message_id, latitude=52.223880, longitude=5.164306 + ) # TODO: Needs improvement with in inline sent live location. def test_edit_live_inline_message(self, monkeypatch, bot, location): @@ -114,8 +116,9 @@ class TestLocation: def test_edit_location_with_all_args(self, bot, location): with pytest.raises(ValueError, match='Not both'): - bot.edit_message_live_location(chat_id=1, message_id=7, latitude=2.5, longitude=4.6, - location=location) + bot.edit_message_live_location( + chat_id=1, message_id=7, latitude=2.5, longitude=4.6, location=location + ) def test_to_dict(self, location): location_dict = location.to_dict() diff --git a/tests/test_loginurl.py b/tests/test_loginurl.py index dd0770d68..8fdd68e4a 100644 --- a/tests/test_loginurl.py +++ b/tests/test_loginurl.py @@ -24,9 +24,12 @@ from telegram import LoginUrl @pytest.fixture(scope='class') def login_url(): - return LoginUrl(url=TestLoginUrl.url, forward_text=TestLoginUrl.forward_text, - bot_username=TestLoginUrl.bot_username, - request_write_access=TestLoginUrl.request_write_access) + return LoginUrl( + url=TestLoginUrl.url, + forward_text=TestLoginUrl.forward_text, + bot_username=TestLoginUrl.bot_username, + request_write_access=TestLoginUrl.request_write_access, + ) class TestLoginUrl: diff --git a/tests/test_message.py b/tests/test_message.py index a2be7c4bc..ab25f4da5 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -20,102 +20,197 @@ from datetime import datetime import pytest -from telegram import (Update, Message, User, MessageEntity, Chat, Audio, Document, Animation, - Game, PhotoSize, Sticker, Video, Voice, VideoNote, Contact, Location, Venue, - Invoice, SuccessfulPayment, PassportData, ParseMode, Poll, PollOption, Dice) +from telegram import ( + Update, + Message, + User, + MessageEntity, + Chat, + Audio, + Document, + Animation, + Game, + PhotoSize, + Sticker, + Video, + Voice, + VideoNote, + Contact, + Location, + Venue, + Invoice, + SuccessfulPayment, + PassportData, + ParseMode, + Poll, + PollOption, + Dice, +) from telegram.ext import Defaults from tests.test_passport import RAW_PASSPORT_DATA @pytest.fixture(scope='class') def message(bot): - return Message(TestMessage.id_, TestMessage.date, TestMessage.chat, - from_user=TestMessage.from_user, bot=bot) + return Message( + TestMessage.id_, + TestMessage.date, + TestMessage.chat, + from_user=TestMessage.from_user, + bot=bot, + ) -@pytest.fixture(scope='function', - params=[ - {'forward_from': User(99, 'forward_user', False), - 'forward_date': datetime.utcnow()}, - {'forward_from_chat': Chat(-23, 'channel'), - 'forward_from_message_id': 101, - 'forward_date': datetime.utcnow()}, - {'reply_to_message': Message(50, None, None, None)}, - {'edit_date': datetime.utcnow()}, - {'text': 'a text message', - 'enitites': [MessageEntity('bold', 10, 4), - MessageEntity('italic', 16, 7)]}, - {'caption': 'A message caption', - 'caption_entities': [MessageEntity('bold', 1, 1), - MessageEntity('text_link', 4, 3)]}, - {'audio': Audio('audio_id', 'unique_id', 12), - 'caption': 'audio_file'}, - {'document': Document('document_id', 'unique_id'), - 'caption': 'document_file'}, - {'animation': Animation('animation_id', 'unique_id', 30, 30, 1), - 'caption': 'animation_file'}, - {'game': Game('my_game', 'just my game', - [PhotoSize('game_photo_id', 'unique_id', 30, 30), ])}, - {'photo': [PhotoSize('photo_id', 'unique_id', 50, 50)], - 'caption': 'photo_file'}, - {'sticker': Sticker('sticker_id', 'unique_id', 50, 50, True)}, - {'video': Video('video_id', 'unique_id', 12, 12, 12), - 'caption': 'video_file'}, - {'voice': Voice('voice_id', 'unique_id', 5)}, - {'video_note': VideoNote('video_note_id', 'unique_id', 20, 12)}, - {'new_chat_members': [User(55, 'new_user', False)]}, - {'contact': Contact('phone_numner', 'contact_name')}, - {'location': Location(-23.691288, 46.788279)}, - {'venue': Venue(Location(-23.691288, 46.788279), - 'some place', 'right here')}, - {'left_chat_member': User(33, 'kicked', False)}, - {'new_chat_title': 'new title'}, - {'new_chat_photo': [PhotoSize('photo_id', 'unique_id', 50, 50)]}, - {'delete_chat_photo': True}, - {'group_chat_created': True}, - {'supergroup_chat_created': True}, - {'channel_chat_created': True}, - {'migrate_to_chat_id': -12345}, - {'migrate_from_chat_id': -54321}, - {'pinned_message': Message(7, None, None, None)}, - {'invoice': Invoice('my invoice', 'invoice', 'start', 'EUR', 243)}, - {'successful_payment': SuccessfulPayment('EUR', 243, 'payload', - 'charge_id', 'provider_id', - order_info={})}, - {'connected_website': 'http://example.com/'}, - {'forward_signature': 'some_forward_sign'}, - {'author_signature': 'some_author_sign'}, - {'photo': [PhotoSize('photo_id', 'unique_id', 50, 50)], - 'caption': 'photo_file', - 'media_group_id': 1234443322222}, - {'passport_data': PassportData.de_json(RAW_PASSPORT_DATA, None)}, - {'poll': Poll(id='abc', question='What is this?', - options=[PollOption(text='a', voter_count=1), - PollOption(text='b', voter_count=2)], is_closed=False, - total_voter_count=0, is_anonymous=False, type=Poll.REGULAR, - allows_multiple_answers=True, explanation_entities=[])}, - {'text': 'a text message', 'reply_markup': {'inline_keyboard': [[{ - 'text': 'start', 'url': 'http://google.com'}, { - 'text': 'next', 'callback_data': 'abcd'}], - [{'text': 'Cancel', 'callback_data': 'Cancel'}]]}}, - {'quote': True}, - {'dice': Dice(4, '🎲')}, - {'via_bot': User(9, 'A_Bot', True)} +@pytest.fixture( + scope='function', + params=[ + {'forward_from': User(99, 'forward_user', False), 'forward_date': datetime.utcnow()}, + { + 'forward_from_chat': Chat(-23, 'channel'), + 'forward_from_message_id': 101, + 'forward_date': datetime.utcnow(), + }, + {'reply_to_message': Message(50, None, None, None)}, + {'edit_date': datetime.utcnow()}, + { + 'text': 'a text message', + 'enitites': [MessageEntity('bold', 10, 4), MessageEntity('italic', 16, 7)], + }, + { + 'caption': 'A message caption', + 'caption_entities': [MessageEntity('bold', 1, 1), MessageEntity('text_link', 4, 3)], + }, + {'audio': Audio('audio_id', 'unique_id', 12), 'caption': 'audio_file'}, + {'document': Document('document_id', 'unique_id'), 'caption': 'document_file'}, + { + 'animation': Animation('animation_id', 'unique_id', 30, 30, 1), + 'caption': 'animation_file', + }, + { + 'game': Game( + 'my_game', + 'just my game', + [ + PhotoSize('game_photo_id', 'unique_id', 30, 30), ], - ids=['forwarded_user', 'forwarded_channel', 'reply', 'edited', 'text', - 'caption_entities', 'audio', 'document', 'animation', 'game', 'photo', - 'sticker', 'video', 'voice', 'video_note', 'new_members', 'contact', - 'location', 'venue', 'left_member', 'new_title', 'new_photo', 'delete_photo', - 'group_created', 'supergroup_created', 'channel_created', 'migrated_to', - 'migrated_from', 'pinned', 'invoice', 'successful_payment', - 'connected_website', 'forward_signature', 'author_signature', - 'photo_from_media_group', 'passport_data', 'poll', 'reply_markup', - 'default_quote', 'dice', 'via_bot']) + ) + }, + {'photo': [PhotoSize('photo_id', 'unique_id', 50, 50)], 'caption': 'photo_file'}, + {'sticker': Sticker('sticker_id', 'unique_id', 50, 50, True)}, + {'video': Video('video_id', 'unique_id', 12, 12, 12), 'caption': 'video_file'}, + {'voice': Voice('voice_id', 'unique_id', 5)}, + {'video_note': VideoNote('video_note_id', 'unique_id', 20, 12)}, + {'new_chat_members': [User(55, 'new_user', False)]}, + {'contact': Contact('phone_numner', 'contact_name')}, + {'location': Location(-23.691288, 46.788279)}, + {'venue': Venue(Location(-23.691288, 46.788279), 'some place', 'right here')}, + {'left_chat_member': User(33, 'kicked', False)}, + {'new_chat_title': 'new title'}, + {'new_chat_photo': [PhotoSize('photo_id', 'unique_id', 50, 50)]}, + {'delete_chat_photo': True}, + {'group_chat_created': True}, + {'supergroup_chat_created': True}, + {'channel_chat_created': True}, + {'migrate_to_chat_id': -12345}, + {'migrate_from_chat_id': -54321}, + {'pinned_message': Message(7, None, None, None)}, + {'invoice': Invoice('my invoice', 'invoice', 'start', 'EUR', 243)}, + { + 'successful_payment': SuccessfulPayment( + 'EUR', 243, 'payload', 'charge_id', 'provider_id', order_info={} + ) + }, + {'connected_website': 'http://example.com/'}, + {'forward_signature': 'some_forward_sign'}, + {'author_signature': 'some_author_sign'}, + { + 'photo': [PhotoSize('photo_id', 'unique_id', 50, 50)], + 'caption': 'photo_file', + 'media_group_id': 1234443322222, + }, + {'passport_data': PassportData.de_json(RAW_PASSPORT_DATA, None)}, + { + 'poll': Poll( + id='abc', + question='What is this?', + options=[PollOption(text='a', voter_count=1), PollOption(text='b', voter_count=2)], + is_closed=False, + total_voter_count=0, + is_anonymous=False, + type=Poll.REGULAR, + allows_multiple_answers=True, + explanation_entities=[], + ) + }, + { + 'text': 'a text message', + 'reply_markup': { + 'inline_keyboard': [ + [ + {'text': 'start', 'url': 'http://google.com'}, + {'text': 'next', 'callback_data': 'abcd'}, + ], + [{'text': 'Cancel', 'callback_data': 'Cancel'}], + ] + }, + }, + {'quote': True}, + {'dice': Dice(4, '🎲')}, + {'via_bot': User(9, 'A_Bot', True)}, + ], + ids=[ + 'forwarded_user', + 'forwarded_channel', + 'reply', + 'edited', + 'text', + 'caption_entities', + 'audio', + 'document', + 'animation', + 'game', + 'photo', + 'sticker', + 'video', + 'voice', + 'video_note', + 'new_members', + 'contact', + 'location', + 'venue', + 'left_member', + 'new_title', + 'new_photo', + 'delete_photo', + 'group_created', + 'supergroup_created', + 'channel_created', + 'migrated_to', + 'migrated_from', + 'pinned', + 'invoice', + 'successful_payment', + 'connected_website', + 'forward_signature', + 'author_signature', + 'photo_from_media_group', + 'passport_data', + 'poll', + 'reply_markup', + 'default_quote', + 'dice', + 'via_bot', + ], +) def message_params(bot, request): - return Message(message_id=TestMessage.id_, - from_user=TestMessage.from_user, - date=TestMessage.date, - chat=TestMessage.chat, bot=bot, **request.param) + return Message( + message_id=TestMessage.id_, + from_user=TestMessage.from_user, + date=TestMessage.date, + chat=TestMessage.chat, + bot=bot, + **request.param, + ) class TestMessage: @@ -123,51 +218,65 @@ class TestMessage: from_user = User(2, 'testuser', False) date = datetime.utcnow() chat = Chat(3, 'private') - test_entities = [{'length': 4, 'offset': 10, 'type': 'bold'}, - {'length': 3, 'offset': 16, 'type': 'italic'}, - {'length': 3, 'offset': 20, 'type': 'italic'}, - {'length': 4, 'offset': 25, 'type': 'code'}, - {'length': 5, 'offset': 31, 'type': 'text_link', - 'url': 'http://github.com/ab_'}, - {'length': 12, 'offset': 38, 'type': 'text_mention', - 'user': User(123456789, 'mentioned user', False)}, - {'length': 3, 'offset': 55, 'type': 'pre', 'language': 'python'}, - {'length': 21, 'offset': 60, 'type': 'url'}] + test_entities = [ + {'length': 4, 'offset': 10, 'type': 'bold'}, + {'length': 3, 'offset': 16, 'type': 'italic'}, + {'length': 3, 'offset': 20, 'type': 'italic'}, + {'length': 4, 'offset': 25, 'type': 'code'}, + {'length': 5, 'offset': 31, 'type': 'text_link', 'url': 'http://github.com/ab_'}, + { + 'length': 12, + 'offset': 38, + 'type': 'text_mention', + 'user': User(123456789, 'mentioned user', False), + }, + {'length': 3, 'offset': 55, 'type': 'pre', 'language': 'python'}, + {'length': 21, 'offset': 60, 'type': 'url'}, + ] test_text = 'Test for Test for <bold, ita_lic, ' - r'\`code, ' - r'links, ' - 'text-mention and ' - r'
`\pre
. http://google.com ' - 'and bold nested in strk nested in italic. ' - '
Python pre
.') + test_html_string = ( + 'Test for <bold, ita_lic, ' + r'\`code, ' + r'links, ' + 'text-mention and ' + r'
`\pre
. http://google.com ' + 'and bold nested in strk nested in italic. ' + '
Python pre
.' + ) text_html = self.test_message_v2.text_html assert text_html == test_html_string @@ -231,37 +358,45 @@ class TestMessage: assert message.text_html is None def test_text_html_urled(self): - test_html_string = ('Test for <bold, ita_lic, ' - r'\`code, ' - r'links, ' - 'text-mention and ' - r'
`\pre
. http://google.com ' - 'and bold nested in strk nested in italic. ' - '
Python pre
.') + test_html_string = ( + 'Test for <bold, ita_lic, ' + r'\`code, ' + r'links, ' + 'text-mention and ' + r'
`\pre
. http://google.com ' + 'and bold nested in strk nested in italic. ' + '
Python pre
.' + ) text_html = self.test_message_v2.text_html_urled assert text_html == test_html_string def test_text_markdown_simple(self): - test_md_string = (r'Test for <*bold*, _ita_\__lic_, `code`, ' - '[links](http://github.com/ab_), ' - '[text-mention](tg://user?id=123456789) and ```python\npre```. ' - r'http://google.com/ab\_') + test_md_string = ( + r'Test for <*bold*, _ita_\__lic_, `code`, ' + '[links](http://github.com/ab_), ' + '[text-mention](tg://user?id=123456789) and ```python\npre```. ' + r'http://google.com/ab\_' + ) text_markdown = self.test_message.text_markdown assert text_markdown == test_md_string def test_text_markdown_v2_simple(self): - test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' - '[links](http://github.com/abc\\\\\\)def), ' - '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' - r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. ' - '```python\nPython pre```\\.') + test_md_string = ( + r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' + '[links](http://github.com/abc\\\\\\)def), ' + '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' + r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. ' + '```python\nPython pre```\\.' + ) text_markdown = self.test_message_v2.text_markdown_v2 assert text_markdown == test_md_string def test_text_markdown_new_in_v2(self, message): message.text = 'test' - message.entities = [MessageEntity(MessageEntity.BOLD, offset=0, length=4), - MessageEntity(MessageEntity.ITALIC, offset=0, length=4)] + message.entities = [ + MessageEntity(MessageEntity.BOLD, offset=0, length=4), + MessageEntity(MessageEntity.ITALIC, offset=0, length=4), + ] with pytest.raises(ValueError): assert message.text_markdown @@ -282,19 +417,23 @@ class TestMessage: assert message.text_markdown_v2 is None def test_text_markdown_urled(self): - test_md_string = (r'Test for <*bold*, _ita_\__lic_, `code`, ' - '[links](http://github.com/ab_), ' - '[text-mention](tg://user?id=123456789) and ```python\npre```. ' - '[http://google.com/ab_](http://google.com/ab_)') + test_md_string = ( + r'Test for <*bold*, _ita_\__lic_, `code`, ' + '[links](http://github.com/ab_), ' + '[text-mention](tg://user?id=123456789) and ```python\npre```. ' + '[http://google.com/ab_](http://google.com/ab_)' + ) text_markdown = self.test_message.text_markdown_urled assert text_markdown == test_md_string def test_text_markdown_v2_urled(self): - test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' - '[links](http://github.com/abc\\\\\\)def), ' - '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' - r'[http://google\.com](http://google.com) and _bold *nested in ~strk~ ' - 'nested in* italic_\\. ```python\nPython pre```\\.') + test_md_string = ( + r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' + '[links](http://github.com/abc\\\\\\)def), ' + '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' + r'[http://google\.com](http://google.com) and _bold *nested in ~strk~ ' + 'nested in* italic_\\. ```python\nPython pre```\\.' + ) text_markdown = self.test_message_v2.text_markdown_v2_urled assert text_markdown == test_md_string @@ -302,26 +441,30 @@ class TestMessage: text = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') expected = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) - message = Message(1, self.from_user, self.date, self.chat, - text=text, entities=[bold_entity]) + message = Message( + 1, self.from_user, self.date, self.chat, text=text, entities=[bold_entity] + ) assert expected == message.text_html def test_text_markdown_emoji(self): text = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') expected = b'\\U0001f469\\u200d\\U0001f469\\u200d *ABC*'.decode('unicode-escape') bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) - message = Message(1, self.from_user, self.date, self.chat, - text=text, entities=[bold_entity]) + message = Message( + 1, self.from_user, self.date, self.chat, text=text, entities=[bold_entity] + ) assert expected == message.text_markdown def test_caption_html_simple(self): - test_html_string = ('Test for <bold, ita_lic, ' - r'\`code, ' - r'links, ' - 'text-mention and ' - r'
`\pre
. http://google.com ' - 'and bold nested in strk nested in italic. ' - '
Python pre
.') + test_html_string = ( + 'Test for <bold, ita_lic, ' + r'\`code, ' + r'links, ' + 'text-mention and ' + r'
`\pre
. http://google.com ' + 'and bold nested in strk nested in italic. ' + '
Python pre
.' + ) caption_html = self.test_message_v2.caption_html assert caption_html == test_html_string @@ -331,30 +474,36 @@ class TestMessage: assert message.caption_html is None def test_caption_html_urled(self): - test_html_string = ('Test for <bold, ita_lic, ' - r'\`code, ' - r'links, ' - 'text-mention and ' - r'
`\pre
. http://google.com ' - 'and bold nested in strk nested in italic. ' - '
Python pre
.') + test_html_string = ( + 'Test for <bold, ita_lic, ' + r'\`code, ' + r'links, ' + 'text-mention and ' + r'
`\pre
. http://google.com ' + 'and bold nested in strk nested in italic. ' + '
Python pre
.' + ) caption_html = self.test_message_v2.caption_html_urled assert caption_html == test_html_string def test_caption_markdown_simple(self): - test_md_string = (r'Test for <*bold*, _ita_\__lic_, `code`, ' - '[links](http://github.com/ab_), ' - '[text-mention](tg://user?id=123456789) and ```python\npre```. ' - r'http://google.com/ab\_') + test_md_string = ( + r'Test for <*bold*, _ita_\__lic_, `code`, ' + '[links](http://github.com/ab_), ' + '[text-mention](tg://user?id=123456789) and ```python\npre```. ' + r'http://google.com/ab\_' + ) caption_markdown = self.test_message.caption_markdown assert caption_markdown == test_md_string def test_caption_markdown_v2_simple(self): - test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' - '[links](http://github.com/abc\\\\\\)def), ' - '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' - r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. ' - '```python\nPython pre```\\.') + test_md_string = ( + r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' + '[links](http://github.com/abc\\\\\\)def), ' + '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' + r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. ' + '```python\nPython pre```\\.' + ) caption_markdown = self.test_message_v2.caption_markdown_v2 assert caption_markdown == test_md_string @@ -365,19 +514,23 @@ class TestMessage: assert message.caption_markdown_v2 is None def test_caption_markdown_urled(self): - test_md_string = (r'Test for <*bold*, _ita_\__lic_, `code`, ' - '[links](http://github.com/ab_), ' - '[text-mention](tg://user?id=123456789) and ```python\npre```. ' - '[http://google.com/ab_](http://google.com/ab_)') + test_md_string = ( + r'Test for <*bold*, _ita_\__lic_, `code`, ' + '[links](http://github.com/ab_), ' + '[text-mention](tg://user?id=123456789) and ```python\npre```. ' + '[http://google.com/ab_](http://google.com/ab_)' + ) caption_markdown = self.test_message.caption_markdown_urled assert caption_markdown == test_md_string def test_caption_markdown_v2_urled(self): - test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' - '[links](http://github.com/abc\\\\\\)def), ' - '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' - r'[http://google\.com](http://google.com) and _bold *nested in ~strk~ ' - 'nested in* italic_\\. ```python\nPython pre```\\.') + test_md_string = ( + r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' + '[links](http://github.com/abc\\\\\\)def), ' + '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' + r'[http://google\.com](http://google.com) and _bold *nested in ~strk~ ' + 'nested in* italic_\\. ```python\nPython pre```\\.' + ) caption_markdown = self.test_message_v2.caption_markdown_v2_urled assert caption_markdown == test_md_string @@ -385,24 +538,37 @@ class TestMessage: caption = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') expected = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) - message = Message(1, self.from_user, self.date, self.chat, - caption=caption, caption_entities=[bold_entity]) + message = Message( + 1, + self.from_user, + self.date, + self.chat, + caption=caption, + caption_entities=[bold_entity], + ) assert expected == message.caption_html def test_caption_markdown_emoji(self): caption = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') expected = b'\\U0001f469\\u200d\\U0001f469\\u200d *ABC*'.decode('unicode-escape') bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) - message = Message(1, self.from_user, self.date, self.chat, - caption=caption, caption_entities=[bold_entity]) + message = Message( + 1, + self.from_user, + self.date, + self.chat, + caption=caption, + caption_entities=[bold_entity], + ) assert expected == message.caption_markdown def test_parse_entities_url_emoji(self): url = b'http://github.com/?unicode=\\u2713\\U0001f469'.decode('unicode-escape') text = 'some url' link_entity = MessageEntity(type=MessageEntity.URL, offset=0, length=8, url=url) - message = Message(1, self.from_user, self.date, self.chat, - text=text, entities=[link_entity]) + message = Message( + 1, self.from_user, self.date, self.chat, text=text, entities=[link_entity] + ) assert message.parse_entities() == {link_entity: text} assert next(iter(message.parse_entities())).url == url @@ -413,11 +579,13 @@ class TestMessage: def test_link_with_username(self, message, type): message.chat.username = 'username' message.chat.type = type - assert message.link == 'https://t.me/{}/{}'.format(message.chat.username, - message.message_id) + assert message.link == 'https://t.me/{}/{}'.format( + message.chat.username, message.message_id + ) - @pytest.mark.parametrize('type, id', argvalues=[ - (Chat.CHANNEL, -1003), (Chat.SUPERGROUP, -1003)]) + @pytest.mark.parametrize( + 'type, id', argvalues=[(Chat.CHANNEL, -1003), (Chat.SUPERGROUP, -1003)] + ) def test_link_with_id(self, message, type, id): message.chat.username = None message.chat.id = id @@ -425,9 +593,7 @@ class TestMessage: # The leading - for group ids/ -100 for supergroup ids isn't supposed to be in the link assert message.link == 'https://t.me/c/{}/{}'.format(3, message.message_id) - @pytest.mark.parametrize('id, username', argvalues=[ - (None, 'username'), (-3, None) - ]) + @pytest.mark.parametrize('id, username', argvalues=[(None, 'username'), (-3, None)]) def test_link_private_chats(self, message, id, username): message.chat.type = Chat.PRIVATE message.chat.id = id @@ -437,9 +603,23 @@ class TestMessage: assert message.link is None def test_effective_attachment(self, message_params): - for i in ('audio', 'game', 'document', 'animation', 'photo', 'sticker', 'video', 'voice', - 'video_note', 'contact', 'location', 'venue', 'invoice', 'invoice', - 'successful_payment'): + for i in ( + 'audio', + 'game', + 'document', + 'animation', + 'photo', + 'sticker', + 'video', + 'voice', + 'video_note', + 'contact', + 'location', + 'venue', + 'invoice', + 'invoice', + 'successful_payment', + ): item = getattr(message_params, i, None) if item: break @@ -463,10 +643,12 @@ class TestMessage: assert message.reply_text('test', reply_to_message_id=message.message_id, quote=True) def test_reply_markdown(self, monkeypatch, message): - test_md_string = (r'Test for <*bold*, _ita_\__lic_, `code`, ' - '[links](http://github.com/ab_), ' - '[text-mention](tg://user?id=123456789) and ```python\npre```. ' - r'http://google.com/ab\_') + test_md_string = ( + r'Test for <*bold*, _ita_\__lic_, `code`, ' + '[links](http://github.com/ab_), ' + '[text-mention](tg://user?id=123456789) and ```python\npre```. ' + r'http://google.com/ab\_' + ) def test(*args, **kwargs): cid = args[0] == message.chat_id @@ -484,16 +666,18 @@ class TestMessage: monkeypatch.setattr(message.bot, 'send_message', test) assert message.reply_markdown(self.test_message.text_markdown) assert message.reply_markdown(self.test_message.text_markdown, quote=True) - assert message.reply_markdown(self.test_message.text_markdown, - reply_to_message_id=message.message_id, - quote=True) + assert message.reply_markdown( + self.test_message.text_markdown, reply_to_message_id=message.message_id, quote=True + ) def test_reply_markdown_v2(self, monkeypatch, message): - test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' - '[links](http://github.com/abc\\\\\\)def), ' - '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' - r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. ' - '```python\nPython pre```\\.') + test_md_string = ( + r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, ' + '[links](http://github.com/abc\\\\\\)def), ' + '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. ' + r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. ' + '```python\nPython pre```\\.' + ) def test(*args, **kwargs): cid = args[0] == message.chat_id @@ -511,18 +695,22 @@ class TestMessage: monkeypatch.setattr(message.bot, 'send_message', test) assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2) assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2, quote=True) - assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2, - reply_to_message_id=message.message_id, - quote=True) + assert message.reply_markdown_v2( + self.test_message_v2.text_markdown_v2, + reply_to_message_id=message.message_id, + quote=True, + ) def test_reply_html(self, monkeypatch, message): - test_html_string = ('Test for <bold, ita_lic, ' - r'\`code, ' - r'links, ' - 'text-mention and ' - r'
`\pre
. http://google.com ' - 'and bold nested in strk nested in italic. ' - '
Python pre
.') + test_html_string = ( + 'Test for <bold, ita_lic, ' + r'\`code, ' + r'links, ' + 'text-mention and ' + r'
`\pre
. http://google.com ' + 'and bold nested in strk nested in italic. ' + '
Python pre
.' + ) def test(*args, **kwargs): cid = args[0] == message.chat_id @@ -540,9 +728,9 @@ class TestMessage: monkeypatch.setattr(message.bot, 'send_message', test) assert message.reply_html(self.test_message_v2.text_html) assert message.reply_html(self.test_message_v2.text_html, quote=True) - assert message.reply_html(self.test_message_v2.text_html, - reply_to_message_id=message.message_id, - quote=True) + assert message.reply_html( + self.test_message_v2.text_html, reply_to_message_id=message.message_id, quote=True + ) def test_reply_media_group(self, monkeypatch, message): def test(*args, **kwargs): @@ -888,8 +1076,18 @@ class TestMessage: def test_equality(self): id_ = 1 - a = Message(id_, self.date, self.chat, from_user=self.from_user,) - b = Message(id_, self.date, self.chat, from_user=self.from_user,) + a = Message( + id_, + self.date, + self.chat, + from_user=self.from_user, + ) + b = Message( + id_, + self.date, + self.chat, + from_user=self.from_user, + ) c = Message(id_, self.date, Chat(123, Chat.GROUP), from_user=User(0, '', False)) d = Message(0, self.date, self.chat, from_user=self.from_user) e = Update(id_) diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index fcf38e861..1ec1d61d3 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -22,8 +22,7 @@ import pytest from telegram import MessageEntity, User -@pytest.fixture(scope="class", - params=MessageEntity.ALL_TYPES) +@pytest.fixture(scope="class", params=MessageEntity.ALL_TYPES) def message_entity(request): type_ = request.param url = None @@ -45,11 +44,7 @@ class TestMessageEntity: url = 'url' def test_de_json(self, bot): - json_dict = { - 'type': self.type_, - 'offset': self.offset, - 'length': self.length - } + json_dict = {'type': self.type_, 'offset': self.offset, 'length': self.length} entity = MessageEntity.de_json(json_dict, bot) assert entity.type == self.type_ diff --git a/tests/test_messagehandler.py b/tests/test_messagehandler.py index ecc8293c8..d61db52a1 100644 --- a/tests/test_messagehandler.py +++ b/tests/test_messagehandler.py @@ -22,8 +22,18 @@ from queue import Queue import pytest from telegram.utils.deprecate import TelegramDeprecationWarning -from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Message, + Update, + Chat, + Bot, + User, + CallbackQuery, + InlineQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import Filters, MessageHandler, CallbackContext, JobQueue, UpdateFilter message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -34,11 +44,17 @@ params = [ {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('callback_query', 'inline_query', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'callback_query', + 'inline_query', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -77,20 +93,31 @@ class TestMessageHandler: self.test_flag = (job_queue is not None) and (update_queue is not None) def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.chat_data, dict) - and isinstance(context.bot_data, dict) - and ((isinstance(context.user_data, dict) - and (isinstance(update.message, Message) - or isinstance(update.edited_message, Message))) - or (context.user_data is None - and (isinstance(update.channel_post, Message) - or isinstance(update.edited_channel_post, Message))) - )) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.chat_data, dict) + and isinstance(context.bot_data, dict) + and ( + ( + isinstance(context.user_data, dict) + and ( + isinstance(update.message, Message) + or isinstance(update.edited_message, Message) + ) + ) + or ( + context.user_data is None + and ( + isinstance(update.channel_post, Message) + or isinstance(update.edited_channel_post, Message) + ) + ) + ) + ) def callback_context_regex1(self, update, context): if context.matches: @@ -121,8 +148,13 @@ class TestMessageHandler: MessageHandler(None, self.callback_basic, channel_post_updates=True) def test_edited_deprecated(self, message): - handler = MessageHandler(None, self.callback_basic, edited_updates=True, - message_updates=False, channel_post_updates=False) + handler = MessageHandler( + None, + self.callback_basic, + edited_updates=True, + message_updates=False, + channel_post_updates=False, + ) assert handler.check_update(Update(0, edited_message=message)) assert not handler.check_update(Update(0, message=message)) @@ -130,17 +162,26 @@ class TestMessageHandler: assert handler.check_update(Update(0, edited_channel_post=message)) def test_channel_post_deprecated(self, message): - handler = MessageHandler(None, self.callback_basic, - edited_updates=False, message_updates=False, - channel_post_updates=True) + handler = MessageHandler( + None, + self.callback_basic, + edited_updates=False, + message_updates=False, + channel_post_updates=True, + ) assert not handler.check_update(Update(0, edited_message=message)) assert not handler.check_update(Update(0, message=message)) assert handler.check_update(Update(0, channel_post=message)) assert not handler.check_update(Update(0, edited_channel_post=message)) def test_multiple_flags_deprecated(self, message): - handler = MessageHandler(None, self.callback_basic, edited_updates=True, - message_updates=True, channel_post_updates=True) + handler = MessageHandler( + None, + self.callback_basic, + edited_updates=True, + message_updates=True, + channel_post_updates=True, + ) assert handler.check_update(Update(0, edited_message=message)) assert handler.check_update(Update(0, message=message)) @@ -149,8 +190,13 @@ class TestMessageHandler: def test_none_allowed_deprecated(self): with pytest.raises(ValueError, match='are all False'): - MessageHandler(None, self.callback_basic, message_updates=False, - channel_post_updates=False, edited_updates=False) + MessageHandler( + None, + self.callback_basic, + message_updates=False, + channel_post_updates=False, + edited_updates=False, + ) def test_with_filter(self, message): handler = MessageHandler(Filters.group, self.callback_basic) @@ -162,7 +208,6 @@ class TestMessageHandler: assert not handler.check_update(Update(0, message)) def test_callback_query_with_filter(self, message): - class TestFilter(UpdateFilter): flag = False @@ -179,9 +224,11 @@ class TestMessageHandler: assert not test_filter.flag def test_specific_filters(self, message): - f = (~Filters.update.messages - & ~Filters.update.channel_post - & Filters.update.edited_channel_post) + f = ( + ~Filters.update.messages + & ~Filters.update.channel_post + & Filters.update.edited_channel_post + ) handler = MessageHandler(f, self.callback_basic) assert not handler.check_update(Update(0, edited_message=message)) @@ -190,16 +237,14 @@ class TestMessageHandler: assert handler.check_update(Update(0, edited_channel_post=message)) def test_pass_user_or_chat_data(self, dp, message): - handler = MessageHandler(None, self.callback_data_1, - pass_user_data=True) + handler = MessageHandler(None, self.callback_data_1, pass_user_data=True) dp.add_handler(handler) dp.process_update(Update(0, message=message)) assert self.test_flag dp.remove_handler(handler) - handler = MessageHandler(None, self.callback_data_1, - pass_chat_data=True) + handler = MessageHandler(None, self.callback_data_1, pass_chat_data=True) dp.add_handler(handler) self.test_flag = False @@ -207,8 +252,9 @@ class TestMessageHandler: assert self.test_flag dp.remove_handler(handler) - handler = MessageHandler(None, self.callback_data_2, - pass_chat_data=True, pass_user_data=True) + handler = MessageHandler( + None, self.callback_data_2, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(handler) self.test_flag = False @@ -216,16 +262,14 @@ class TestMessageHandler: assert self.test_flag def test_pass_job_or_update_queue(self, dp, message): - handler = MessageHandler(None, self.callback_queue_1, - pass_job_queue=True) + handler = MessageHandler(None, self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update(Update(0, message=message)) assert self.test_flag dp.remove_handler(handler) - handler = MessageHandler(None, self.callback_queue_1, - pass_update_queue=True) + handler = MessageHandler(None, self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -233,8 +277,9 @@ class TestMessageHandler: assert self.test_flag dp.remove_handler(handler) - handler = MessageHandler(None, self.callback_queue_2, - pass_job_queue=True, pass_update_queue=True) + handler = MessageHandler( + None, self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False @@ -246,8 +291,9 @@ class TestMessageHandler: assert not handler.check_update(false_update) def test_context(self, cdp, message): - handler = MessageHandler(None, self.callback_context, - edited_updates=True, channel_post_updates=True) + handler = MessageHandler( + None, self.callback_context, edited_updates=True, channel_post_updates=True + ) cdp.add_handler(handler) cdp.process_update(Update(0, message=message)) @@ -278,8 +324,9 @@ class TestMessageHandler: assert self.test_flag def test_context_multiple_regex(self, cdp, message): - handler = MessageHandler(Filters.regex('one') & Filters.regex('two'), - self.callback_context_regex2) + handler = MessageHandler( + Filters.regex('one') & Filters.regex('two'), self.callback_context_regex2 + ) cdp.add_handler(handler) message.text = 'not it' diff --git a/tests/test_messagequeue.py b/tests/test_messagequeue.py index 9ffd373e0..f9ebfc901 100644 --- a/tests/test_messagequeue.py +++ b/tests/test_messagequeue.py @@ -25,8 +25,10 @@ import pytest import telegram.ext.messagequeue as mq -@pytest.mark.skipif(os.getenv('GITHUB_ACTIONS', False) and os.name == 'nt', - reason="On windows precise timings are not accurate.") +@pytest.mark.skipif( + os.getenv('GITHUB_ACTIONS', False) and os.name == 'nt', + reason="On windows precise timings are not accurate.", +) class TestDelayQueue: N = 128 burst_limit = 30 @@ -38,8 +40,9 @@ class TestDelayQueue: self.testtimes.append(perf_counter()) def test_delayqueue_limits(self): - dsp = mq.DelayQueue(burst_limit=self.burst_limit, time_limit_ms=self.time_limit_ms, - autostart=True) + dsp = mq.DelayQueue( + burst_limit=self.burst_limit, time_limit_ms=self.time_limit_ms, autostart=True + ) assert dsp.is_alive() is True for _ in range(self.N): @@ -47,7 +50,7 @@ class TestDelayQueue: starttime = perf_counter() # wait up to 20 sec more than needed - app_endtime = ((self.N * self.burst_limit / (1000 * self.time_limit_ms)) + starttime + 20) + app_endtime = (self.N * self.burst_limit / (1000 * self.time_limit_ms)) + starttime + 20 while not dsp._queue.empty() and perf_counter() < app_endtime: sleep(1) assert dsp._queue.empty() is True # check loop exit condition diff --git a/tests/test_official.py b/tests/test_official.py index dfd461c07..39f5864e3 100644 --- a/tests/test_official.py +++ b/tests/test_official.py @@ -27,8 +27,16 @@ from telegram.vendor.ptb_urllib3 import urllib3 import telegram IGNORED_OBJECTS = ('ResponseParameters', 'CallbackGame') -IGNORED_PARAMETERS = {'self', 'args', 'kwargs', 'read_latency', 'network_delay', 'timeout', 'bot', - 'api_kwargs'} +IGNORED_PARAMETERS = { + 'self', + 'args', + 'kwargs', + 'read_latency', + 'network_delay', + 'timeout', + 'bot', + 'api_kwargs', +} def find_next_sibling_until(tag, name, until): @@ -60,8 +68,9 @@ def check_method(h4): checked = [] for parameter in table: param = sig.parameters.get(parameter[0]) - assert param is not None, "Parameter {} not found in {}".format(parameter[0], - method.__name__) + assert param is not None, "Parameter {} not found in {}".format( + parameter[0], method.__name__ + ) # TODO: Check type via docstring # TODO: Check if optional or required checked.append(parameter[0]) @@ -98,8 +107,9 @@ def check_object(h4): field = parameter[0] if field == 'from': field = 'from_user' - elif ((name.startswith('InlineQueryResult') - or name.startswith('InputMedia')) and field == 'type'): + elif ( + name.startswith('InlineQueryResult') or name.startswith('InputMedia') + ) and field == 'type': continue elif name.startswith('PassportElementError') and field == 'source': continue @@ -131,9 +141,7 @@ def check_object(h4): argvalues = [] names = [] -http = urllib3.PoolManager( - cert_reqs='CERT_REQUIRED', - ca_certs=certifi.where()) +http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where()) request = http.request('GET', 'https://core.telegram.org/bots/api') soup = BeautifulSoup(request.data.decode('utf-8'), 'html.parser') @@ -153,7 +161,6 @@ for thing in soup.select('h4 > a.anchor'): @pytest.mark.parametrize(('method', 'data'), argvalues=argvalues, ids=names) -@pytest.mark.skipif(os.getenv('TEST_OFFICIAL') != 'true', - reason='test_official is not enabled') +@pytest.mark.skipif(os.getenv('TEST_OFFICIAL') != 'true', reason='test_official is not enabled') def test_official(method, data): method(data) diff --git a/tests/test_orderinfo.py b/tests/test_orderinfo.py index 9f28d6493..971b5f354 100644 --- a/tests/test_orderinfo.py +++ b/tests/test_orderinfo.py @@ -24,8 +24,12 @@ from telegram import ShippingAddress, OrderInfo @pytest.fixture(scope='class') def order_info(): - return OrderInfo(TestOrderInfo.name, TestOrderInfo.phone_number, - TestOrderInfo.email, TestOrderInfo.shipping_address) + return OrderInfo( + TestOrderInfo.name, + TestOrderInfo.phone_number, + TestOrderInfo.email, + TestOrderInfo.shipping_address, + ) class TestOrderInfo: @@ -39,7 +43,7 @@ class TestOrderInfo: 'name': TestOrderInfo.name, 'phone_number': TestOrderInfo.phone_number, 'email': TestOrderInfo.email, - 'shipping_address': TestOrderInfo.shipping_address.to_dict() + 'shipping_address': TestOrderInfo.shipping_address.to_dict(), } order_info = OrderInfo.de_json(json_dict, bot) @@ -58,14 +62,30 @@ class TestOrderInfo: assert order_info_dict['shipping_address'] == order_info.shipping_address.to_dict() def test_equality(self): - a = OrderInfo('name', 'number', 'mail', - ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1')) - b = OrderInfo('name', 'number', 'mail', - ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1')) - c = OrderInfo('name', 'number', 'mail', - ShippingAddress('GB', '', 'London', '13 Grimmauld Place', '', 'WC1')) - d = OrderInfo('name', 'number', 'e-mail', - ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1')) + a = OrderInfo( + 'name', + 'number', + 'mail', + ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1'), + ) + b = OrderInfo( + 'name', + 'number', + 'mail', + ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1'), + ) + c = OrderInfo( + 'name', + 'number', + 'mail', + ShippingAddress('GB', '', 'London', '13 Grimmauld Place', '', 'WC1'), + ) + d = OrderInfo( + 'name', + 'number', + 'e-mail', + ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1'), + ) e = ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1') assert a == b diff --git a/tests/test_parsemode.py b/tests/test_parsemode.py index 3137fb235..a0ec872f1 100644 --- a/tests/test_parsemode.py +++ b/tests/test_parsemode.py @@ -24,22 +24,24 @@ from telegram import ParseMode class TestParseMode: markdown_text = '*bold* _italic_ [link](http://google.com) [name](tg://user?id=123456789).' - html_text = ('bold italic link ' - 'name.') + html_text = ( + 'bold italic link ' + 'name.' + ) formatted_text_formatted = u'bold italic link name.' @flaky(3, 1) @pytest.mark.timeout(10) def test_send_message_with_parse_mode_markdown(self, bot, chat_id): - message = bot.send_message(chat_id=chat_id, text=self.markdown_text, - parse_mode=ParseMode.MARKDOWN) + message = bot.send_message( + chat_id=chat_id, text=self.markdown_text, parse_mode=ParseMode.MARKDOWN + ) assert message.text == self.formatted_text_formatted @flaky(3, 1) @pytest.mark.timeout(10) def test_send_message_with_parse_mode_html(self, bot, chat_id): - message = bot.send_message(chat_id=chat_id, text=self.html_text, - parse_mode=ParseMode.HTML) + message = bot.send_message(chat_id=chat_id, text=self.html_text, parse_mode=ParseMode.HTML) assert message.text == self.formatted_text_formatted diff --git a/tests/test_passport.py b/tests/test_passport.py index 61ad9bff0..01cc66461 100644 --- a/tests/test_passport.py +++ b/tests/test_passport.py @@ -20,8 +20,16 @@ from copy import deepcopy import pytest -from telegram import (PassportData, PassportFile, Bot, File, PassportElementErrorSelfie, - PassportElementErrorDataField, Credentials, TelegramDecryptionError) +from telegram import ( + PassportData, + PassportFile, + Bot, + File, + PassportElementErrorSelfie, + PassportElementErrorDataField, + Credentials, + TelegramDecryptionError, +) # Generated using the scope: # { @@ -44,100 +52,155 @@ from telegram import (PassportData, PassportFile, Bot, File, PassportElementErro # ], # v: 1 # } -RAW_PASSPORT_DATA = {'credentials': {'hash': 'qB4hz2LMcXYhglwz6EvXMMyI3PURisWLXl/iCmCXcSk=', - 'secret': 'O6x3X2JrLO1lUIhw48os1gaenDuZLhesoZMKXehZwtM3vsxOdtxHKWQyLNwtbyy4snYpARXDwf8f1QHNmQ/M1PwBQvk1ozrZBXb4a6k/iYj+P4v8Xw2M++CRHqZv0LaxFtyHOXnNYZ6dXpNeF0ZvYYTmm0FsYvK+/3/F6VDB3Oe6xWlXFLwaCCP/jA9i2+dKp6iq8NLOo4VnxenPKWWYz20RZ50MdAbS3UR+NCx4AHM2P5DEGrHNW0tMXJ+FG3jpVrit5BuCbB/eRgKxNGRWNxEGV5hun5MChdxKCEHCimnUA97h7MZdoTgYxkrfvDSZ/V89BnFXLdr87t/NLvVE0Q==', - 'data': 'MjHCHQT277BgJMxq5PfkPUl9p9h/5GbWtR0lcEi9MvtmQ9ONW8DZ3OmddaaVDdEHwh6Lfcr/0mxyMKhttm9QyACA1+oGBdw/KHRzLKS4a0P+rMyCcgctO6Q/+P9o6xs66hPFJAsN+sOUU4d431zaQN/RuHYuGM2s14A1K4YNRvNlp5/0JiS7RrV6SH6LC/97CvgGUnBOhLISmJXiMqwyVgg+wfS5SnOy2hQ5Zt/XdzxFyuehE3W4mHyY5W09I+MB/IafM4HcEvaqfFkWPmXNTkgBk9C2EJU9Lqc0PLmrXZn4LKeHVjuY7iloes/JecYKPMWmNjXwZQg/duIXvWL5icUaNrfjEcT5oljwZsrAc6NyyZwIp4w/+cb98jFwFAJ5uF81lRkZbeC3iw84mdpSVVYEzJSWSkSRs6JydfRCOYki0BNX9RnjgGqPYT+hNtUpEix2vHvJTIyvceflLF5vu+ol/axusirRiBVgNjKMfhs+x5bwBj5nDEE1XtEVrKtRq8/Ss96p0Tlds8eKulCDtPv/YujHVIErEhgUxDCGhr7OShokAFs/RwLmj6IBYQwnVbo0zIsq5qmCn/+1ogxJK+e934cDcwJAs8pnpgp7JPeFN9wBdmXSTpkO3KZt5Lgl3V86Rv5qv8oExQoJIUH5pKoXM+H2GB3QdfHLc/KpCeedG8RjateuIXKL2EtVe3JDMGBeI56eP9bTlW8+G1zVcpUuw/YEV14q4yiPlIRuWzrxXMvC1EtSzfGeY899trZBMCI00aeSpJyanf1f7B7nlQu6UbtMyN/9/GXbnjQjdP15CCQnmUK3PEWGtGV4XmK4iXIjBJELDD3T86RJyX/JAhJbT6funMt05w0bTyKFUDXdOcMyw2upj+wCsWTVMRNkw9yM63xL5TEfOc24aNi4pc4/LARSvwaNI/iBStqZEpG3KkYBQ2KutA022jRWzQ+xHIIz3mgA8z4PmXhcAU2RrTDGjGZUfbcX9LysZ/HvCHo/EB5njRISn3Yr1Ewu1pLX+Z4mERs+PCBXbpqBrZjY6dSWJ1QhggVJTPpWHya4CTGhkpyeFIc+D35t4kgt3U5ib61IaO9ABq0fUnB6dsvTGiN/i7KM8Ie1RUvPFBoVbz9x5YU9IT/ai8ln+1kfFfhiy8Ku4MnczthOUIjdr8nGUo4r3y0iEd5JEmqEcEsNx+/ZVMb7NEhpqXG8GPUxmwFTaHekldENxqTylv6qIxodhch6SLs/+iMat86DeCk1/+0u2fGmqZpxEEd9B89iD0+Av3UZC/C1rHn5FhC+o89RQAFWnH245rOHSbrTXyAtVBu2s1R0eIGadtAZYOI8xjULkbp52XyznZKCKaMKmr3UYah4P4VnUmhddBy+Mp/Bvxh8N3Ma8VSltO1n+3lyQWeUwdlCjt/3q3UpjAmilIKwEfeXMVhyjRlae1YGi/k+vgn+9LbFogh3Pl+N/kuyNqsTqPlzei2RXgpkX2qqHdF8WfkwQJpjXRurQN5LYaBfalygrUT+fCCpyaNkByxdDljKIPq6EibqtFA5jprAVDWGTTtFCKsPDJKFf9vc2lFy+7zyJxe8kMP1Wru8GrzF5z+pbfNp1tB80NqOrqJUbRnPB2I9Fb47ab76L8RBu2MROUNGcKJ62imQtfPH2I0f8zpbqqTZQwr3AmZ+PS9df2hHp2dYR9gFpMyR9u+bJ7HbpiKbYhh7mEFYeB/pQHsQRqM2OU5Bxk8XzxrwsdnzYO6tVcn8xr3Q4P9kZNXA6X5H0vJPpzClWoCPEr3ZGGWGl5DOhfsAmmst47vdAA1Cbl5k3pUW7/T3LWnMNwRnP8OdDOnsm06/v1nxIDjH08YlzLj4GTeXphSnsXSRNKFmz+M7vsOZPhWB8Y/WQmpJpOIj6IRstLxJk0h47TfYC7/RHBr4y7HQ8MLHODoPz/FM+nZtm2MMpB+u0qFNBvZG+Tjvlia7ZhX0n0OtivLWhnqygx3jZX7Ffwt5Es03wDP39ru4IccVZ9Jly/YUriHZURS6oDGycH3+DKUn5gRAxgOyjAwxGRqJh/YKfPt14d4iur0H3VUuLwFCbwj5hSvHVIv5cNapitgINU+0qzIlhyeE0HfRKstO7nOQ9A+nclqbOikYgurYIe0z70WZyJ3qSiHbOMMqQqcoKOJ6M9v2hDdJo9MDQ13dF6bl4+BfX4mcF0m7nVUBkzCRiSOQWWFUMgLX7CxSdmotT+eawKLjrCpSPmq9sicWyrFtVlq/NYLDGhT0jUUau6Mb5ksT+/OBVeMzqoezUcly29L1/gaeWAc8zOApVEjAMT48U63NXK5o8GrANeqqAt3TB36S5yeIjMf194nXAAzsJZ+s/tXprLn2M5mA1Iag4RbVPTarEsMp10JYag=='}, - 'data': [ - { - 'data': 'QRfzWcCN4WncvRO3lASG+d+c5gzqXtoCinQ1PgtYiZMKXCksx9eB9Ic1bOt8C/un9/XaX220PjJSO7Kuba+nXXC51qTsjqP9rnLKygnEIWjKrfiDdklzgcukpRzFSjiOAvhy86xFJZ1PfPSrFATy/Gp1RydLzbrBd2ZWxZqXrxcMoA0Q2UTTFXDoCYerEAiZoD69i79tB/6nkLBcUUvN5d52gKd/GowvxWqAAmdO6l1N7jlo6aWjdYQNBAK1KHbJdbRZMJLxC1MqMuZXAYrPoYBRKr5xAnxDTmPn/LEZKLc3gwwZyEgR5x7e9jp5heM6IEMmsv3O/6SUeEQs7P0iVuRSPLMJLfDdwns8Tl3fF2M4IxKVovjCaOVW+yHKsADDAYQPzzH2RcrWVD0TP5I64mzpK64BbTOq3qm3Hn51SV9uA/+LvdGbCp7VnzHx4EdUizHsVyilJULOBwvklsrDRvXMiWmh34ZSR6zilh051tMEcRf0I+Oe7pIxVJd/KKfYA2Z/eWVQTCn5gMuAInQNXFSqDIeIqBX+wca6kvOCUOXB7J2uRjTpLaC4DM9s/sNjSBvFixcGAngt+9oap6Y45rQc8ZJaNN/ALqEJAmkphW8=', - 'type': 'personal_details' - }, { - 'reverse_side': {'file_date': 1534074942, - 'file_id': 'DgADBAADNQQAAtoagFPf4wwmFZdmyQI', - 'file_unique_id': 'adc3145fd2e84d95b64d68eaa22aa33e'}, - 'translation': [{'file_size': 28640, 'file_date': 1535630933, - 'file_id': 'DgADBAADswMAAisqQVAmooP-kVgLgAI', - 'file_unique_id': '52a90d53d6064bb58feb582acdc3a324'}, - {'file_size': 28672, 'file_date': 1535630933, - 'file_id': 'DgADBAAD1QMAAnrpQFBMZsT3HysjwwI', - 'file_unique_id': '7285f864d168441ba1f7d02146250432'}], - 'front_side': {'file_size': 28624, 'file_date': 1534074942, - 'file_id': 'DgADBAADxwMAApnQgVPK2-ckL2eXVAI', - 'file_unique_id': 'd9d52a700cbb4a189a80104aa5978133'}, - 'type': 'driver_license', - 'selfie': {'file_size': 28592, 'file_date': 1534074942, - 'file_id': 'DgADBAADEQQAAkopgFNr6oi-wISRtAI', - 'file_unique_id': 'd4e390cca57b4da5a65322b304762a12'}, - 'data': 'eJUOFuY53QKmGqmBgVWlLBAQCUQJ79n405SX6M5aGFIIodOPQqnLYvMNqTwTrXGDlW+mVLZcbu+y8luLVO8WsJB/0SB7q5WaXn/IMt1G9lz5G/KMLIZG/x9zlnimsaQLg7u8srG6L4KZzv+xkbbHjZdETrxU8j0N/DoS4HvLMRSJAgeFUrY6v2YW9vSRg+fSxIqQy1jR2VKpzAT8OhOz7A==' - }, { - 'translation': [{'file_size': 28480, 'file_date': 1535630939, - 'file_id': 'DgADBAADyQUAAqyqQVC_eoX_KwNjJwI', - 'file_unique_id': '38b2877b443542cbaf520c6e36a33ac4'}, - {'file_size': 28528, 'file_date': 1535630939, - 'file_id': 'DgADBAADsQQAAubTQVDRO_FN3lOwWwI', - 'file_unique_id': 'f008ca48c44b4a47895ddbcd2f76741e'}], - 'files': [{'file_size': 28640, 'file_date': 1534074988, - 'file_id': 'DgADBAADLAMAAhwfgVMyfGa5Nr0LvAI', - 'file_unique_id': 'b170748794834644baaa3ec57ee4ce7a'}, - {'file_size': 28480, 'file_date': 1534074988, - 'file_id': 'DgADBAADaQQAAsFxgVNVfLZuT-_3ZQI', - 'file_unique_id': '19a12ae34dca424b85e0308f706cee75'}], - 'type': 'utility_bill' - }, { - 'data': 'j9SksVkSj128DBtZA+3aNjSFNirzv+R97guZaMgae4Gi0oDVNAF7twPR7j9VSmPedfJrEwL3O889Ei+a5F1xyLLyEI/qEBljvL70GFIhYGitS0JmNabHPHSZrjOl8b4s/0Z0Px2GpLO5siusTLQonimdUvu4UPjKquYISmlKEKhtmGATy+h+JDjNCYuOkhakeNw0Rk0BHgj0C3fCb7WZNQSyVb+2GTu6caR6eXf/AFwFp0TV3sRz3h0WIVPW8bna', - 'type': 'address' - }, { - 'email': 'fb3e3i47zt@dispostable.com', 'type': 'email' - }]} +RAW_PASSPORT_DATA = { + 'credentials': { + 'hash': 'qB4hz2LMcXYhglwz6EvXMMyI3PURisWLXl/iCmCXcSk=', + 'secret': 'O6x3X2JrLO1lUIhw48os1gaenDuZLhesoZMKXehZwtM3vsxOdtxHKWQyLNwtbyy4snYpARXDwf8f1QHNmQ/M1PwBQvk1ozrZBXb4a6k/iYj+P4v8Xw2M++CRHqZv0LaxFtyHOXnNYZ6dXpNeF0ZvYYTmm0FsYvK+/3/F6VDB3Oe6xWlXFLwaCCP/jA9i2+dKp6iq8NLOo4VnxenPKWWYz20RZ50MdAbS3UR+NCx4AHM2P5DEGrHNW0tMXJ+FG3jpVrit5BuCbB/eRgKxNGRWNxEGV5hun5MChdxKCEHCimnUA97h7MZdoTgYxkrfvDSZ/V89BnFXLdr87t/NLvVE0Q==', + 'data': 'MjHCHQT277BgJMxq5PfkPUl9p9h/5GbWtR0lcEi9MvtmQ9ONW8DZ3OmddaaVDdEHwh6Lfcr/0mxyMKhttm9QyACA1+oGBdw/KHRzLKS4a0P+rMyCcgctO6Q/+P9o6xs66hPFJAsN+sOUU4d431zaQN/RuHYuGM2s14A1K4YNRvNlp5/0JiS7RrV6SH6LC/97CvgGUnBOhLISmJXiMqwyVgg+wfS5SnOy2hQ5Zt/XdzxFyuehE3W4mHyY5W09I+MB/IafM4HcEvaqfFkWPmXNTkgBk9C2EJU9Lqc0PLmrXZn4LKeHVjuY7iloes/JecYKPMWmNjXwZQg/duIXvWL5icUaNrfjEcT5oljwZsrAc6NyyZwIp4w/+cb98jFwFAJ5uF81lRkZbeC3iw84mdpSVVYEzJSWSkSRs6JydfRCOYki0BNX9RnjgGqPYT+hNtUpEix2vHvJTIyvceflLF5vu+ol/axusirRiBVgNjKMfhs+x5bwBj5nDEE1XtEVrKtRq8/Ss96p0Tlds8eKulCDtPv/YujHVIErEhgUxDCGhr7OShokAFs/RwLmj6IBYQwnVbo0zIsq5qmCn/+1ogxJK+e934cDcwJAs8pnpgp7JPeFN9wBdmXSTpkO3KZt5Lgl3V86Rv5qv8oExQoJIUH5pKoXM+H2GB3QdfHLc/KpCeedG8RjateuIXKL2EtVe3JDMGBeI56eP9bTlW8+G1zVcpUuw/YEV14q4yiPlIRuWzrxXMvC1EtSzfGeY899trZBMCI00aeSpJyanf1f7B7nlQu6UbtMyN/9/GXbnjQjdP15CCQnmUK3PEWGtGV4XmK4iXIjBJELDD3T86RJyX/JAhJbT6funMt05w0bTyKFUDXdOcMyw2upj+wCsWTVMRNkw9yM63xL5TEfOc24aNi4pc4/LARSvwaNI/iBStqZEpG3KkYBQ2KutA022jRWzQ+xHIIz3mgA8z4PmXhcAU2RrTDGjGZUfbcX9LysZ/HvCHo/EB5njRISn3Yr1Ewu1pLX+Z4mERs+PCBXbpqBrZjY6dSWJ1QhggVJTPpWHya4CTGhkpyeFIc+D35t4kgt3U5ib61IaO9ABq0fUnB6dsvTGiN/i7KM8Ie1RUvPFBoVbz9x5YU9IT/ai8ln+1kfFfhiy8Ku4MnczthOUIjdr8nGUo4r3y0iEd5JEmqEcEsNx+/ZVMb7NEhpqXG8GPUxmwFTaHekldENxqTylv6qIxodhch6SLs/+iMat86DeCk1/+0u2fGmqZpxEEd9B89iD0+Av3UZC/C1rHn5FhC+o89RQAFWnH245rOHSbrTXyAtVBu2s1R0eIGadtAZYOI8xjULkbp52XyznZKCKaMKmr3UYah4P4VnUmhddBy+Mp/Bvxh8N3Ma8VSltO1n+3lyQWeUwdlCjt/3q3UpjAmilIKwEfeXMVhyjRlae1YGi/k+vgn+9LbFogh3Pl+N/kuyNqsTqPlzei2RXgpkX2qqHdF8WfkwQJpjXRurQN5LYaBfalygrUT+fCCpyaNkByxdDljKIPq6EibqtFA5jprAVDWGTTtFCKsPDJKFf9vc2lFy+7zyJxe8kMP1Wru8GrzF5z+pbfNp1tB80NqOrqJUbRnPB2I9Fb47ab76L8RBu2MROUNGcKJ62imQtfPH2I0f8zpbqqTZQwr3AmZ+PS9df2hHp2dYR9gFpMyR9u+bJ7HbpiKbYhh7mEFYeB/pQHsQRqM2OU5Bxk8XzxrwsdnzYO6tVcn8xr3Q4P9kZNXA6X5H0vJPpzClWoCPEr3ZGGWGl5DOhfsAmmst47vdAA1Cbl5k3pUW7/T3LWnMNwRnP8OdDOnsm06/v1nxIDjH08YlzLj4GTeXphSnsXSRNKFmz+M7vsOZPhWB8Y/WQmpJpOIj6IRstLxJk0h47TfYC7/RHBr4y7HQ8MLHODoPz/FM+nZtm2MMpB+u0qFNBvZG+Tjvlia7ZhX0n0OtivLWhnqygx3jZX7Ffwt5Es03wDP39ru4IccVZ9Jly/YUriHZURS6oDGycH3+DKUn5gRAxgOyjAwxGRqJh/YKfPt14d4iur0H3VUuLwFCbwj5hSvHVIv5cNapitgINU+0qzIlhyeE0HfRKstO7nOQ9A+nclqbOikYgurYIe0z70WZyJ3qSiHbOMMqQqcoKOJ6M9v2hDdJo9MDQ13dF6bl4+BfX4mcF0m7nVUBkzCRiSOQWWFUMgLX7CxSdmotT+eawKLjrCpSPmq9sicWyrFtVlq/NYLDGhT0jUUau6Mb5ksT+/OBVeMzqoezUcly29L1/gaeWAc8zOApVEjAMT48U63NXK5o8GrANeqqAt3TB36S5yeIjMf194nXAAzsJZ+s/tXprLn2M5mA1Iag4RbVPTarEsMp10JYag==', + }, + 'data': [ + { + 'data': 'QRfzWcCN4WncvRO3lASG+d+c5gzqXtoCinQ1PgtYiZMKXCksx9eB9Ic1bOt8C/un9/XaX220PjJSO7Kuba+nXXC51qTsjqP9rnLKygnEIWjKrfiDdklzgcukpRzFSjiOAvhy86xFJZ1PfPSrFATy/Gp1RydLzbrBd2ZWxZqXrxcMoA0Q2UTTFXDoCYerEAiZoD69i79tB/6nkLBcUUvN5d52gKd/GowvxWqAAmdO6l1N7jlo6aWjdYQNBAK1KHbJdbRZMJLxC1MqMuZXAYrPoYBRKr5xAnxDTmPn/LEZKLc3gwwZyEgR5x7e9jp5heM6IEMmsv3O/6SUeEQs7P0iVuRSPLMJLfDdwns8Tl3fF2M4IxKVovjCaOVW+yHKsADDAYQPzzH2RcrWVD0TP5I64mzpK64BbTOq3qm3Hn51SV9uA/+LvdGbCp7VnzHx4EdUizHsVyilJULOBwvklsrDRvXMiWmh34ZSR6zilh051tMEcRf0I+Oe7pIxVJd/KKfYA2Z/eWVQTCn5gMuAInQNXFSqDIeIqBX+wca6kvOCUOXB7J2uRjTpLaC4DM9s/sNjSBvFixcGAngt+9oap6Y45rQc8ZJaNN/ALqEJAmkphW8=', + 'type': 'personal_details', + }, + { + 'reverse_side': { + 'file_date': 1534074942, + 'file_id': 'DgADBAADNQQAAtoagFPf4wwmFZdmyQI', + 'file_unique_id': 'adc3145fd2e84d95b64d68eaa22aa33e', + }, + 'translation': [ + { + 'file_size': 28640, + 'file_date': 1535630933, + 'file_id': 'DgADBAADswMAAisqQVAmooP-kVgLgAI', + 'file_unique_id': '52a90d53d6064bb58feb582acdc3a324', + }, + { + 'file_size': 28672, + 'file_date': 1535630933, + 'file_id': 'DgADBAAD1QMAAnrpQFBMZsT3HysjwwI', + 'file_unique_id': '7285f864d168441ba1f7d02146250432', + }, + ], + 'front_side': { + 'file_size': 28624, + 'file_date': 1534074942, + 'file_id': 'DgADBAADxwMAApnQgVPK2-ckL2eXVAI', + 'file_unique_id': 'd9d52a700cbb4a189a80104aa5978133', + }, + 'type': 'driver_license', + 'selfie': { + 'file_size': 28592, + 'file_date': 1534074942, + 'file_id': 'DgADBAADEQQAAkopgFNr6oi-wISRtAI', + 'file_unique_id': 'd4e390cca57b4da5a65322b304762a12', + }, + 'data': 'eJUOFuY53QKmGqmBgVWlLBAQCUQJ79n405SX6M5aGFIIodOPQqnLYvMNqTwTrXGDlW+mVLZcbu+y8luLVO8WsJB/0SB7q5WaXn/IMt1G9lz5G/KMLIZG/x9zlnimsaQLg7u8srG6L4KZzv+xkbbHjZdETrxU8j0N/DoS4HvLMRSJAgeFUrY6v2YW9vSRg+fSxIqQy1jR2VKpzAT8OhOz7A==', + }, + { + 'translation': [ + { + 'file_size': 28480, + 'file_date': 1535630939, + 'file_id': 'DgADBAADyQUAAqyqQVC_eoX_KwNjJwI', + 'file_unique_id': '38b2877b443542cbaf520c6e36a33ac4', + }, + { + 'file_size': 28528, + 'file_date': 1535630939, + 'file_id': 'DgADBAADsQQAAubTQVDRO_FN3lOwWwI', + 'file_unique_id': 'f008ca48c44b4a47895ddbcd2f76741e', + }, + ], + 'files': [ + { + 'file_size': 28640, + 'file_date': 1534074988, + 'file_id': 'DgADBAADLAMAAhwfgVMyfGa5Nr0LvAI', + 'file_unique_id': 'b170748794834644baaa3ec57ee4ce7a', + }, + { + 'file_size': 28480, + 'file_date': 1534074988, + 'file_id': 'DgADBAADaQQAAsFxgVNVfLZuT-_3ZQI', + 'file_unique_id': '19a12ae34dca424b85e0308f706cee75', + }, + ], + 'type': 'utility_bill', + }, + { + 'data': 'j9SksVkSj128DBtZA+3aNjSFNirzv+R97guZaMgae4Gi0oDVNAF7twPR7j9VSmPedfJrEwL3O889Ei+a5F1xyLLyEI/qEBljvL70GFIhYGitS0JmNabHPHSZrjOl8b4s/0Z0Px2GpLO5siusTLQonimdUvu4UPjKquYISmlKEKhtmGATy+h+JDjNCYuOkhakeNw0Rk0BHgj0C3fCb7WZNQSyVb+2GTu6caR6eXf/AFwFp0TV3sRz3h0WIVPW8bna', + 'type': 'address', + }, + {'email': 'fb3e3i47zt@dispostable.com', 'type': 'email'}, + ], +} @pytest.fixture(scope='function') def all_passport_data(): - return [{'type': 'personal_details', - 'data': RAW_PASSPORT_DATA['data'][0]['data']}, - {'type': 'passport', - 'data': RAW_PASSPORT_DATA['data'][1]['data'], - 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], - 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], - 'translation': RAW_PASSPORT_DATA['data'][1]['translation']}, - {'type': 'internal_passport', - 'data': RAW_PASSPORT_DATA['data'][1]['data'], - 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], - 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], - 'translation': RAW_PASSPORT_DATA['data'][1]['translation']}, - {'type': 'driver_license', - 'data': RAW_PASSPORT_DATA['data'][1]['data'], - 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], - 'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'], - 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], - 'translation': RAW_PASSPORT_DATA['data'][1]['translation']}, - {'type': 'identity_card', - 'data': RAW_PASSPORT_DATA['data'][1]['data'], - 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], - 'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'], - 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], - 'translation': RAW_PASSPORT_DATA['data'][1]['translation']}, - {'type': 'utility_bill', - 'files': RAW_PASSPORT_DATA['data'][2]['files'], - 'translation': RAW_PASSPORT_DATA['data'][2]['translation']}, - {'type': 'bank_statement', - 'files': RAW_PASSPORT_DATA['data'][2]['files'], - 'translation': RAW_PASSPORT_DATA['data'][2]['translation']}, - {'type': 'rental_agreement', - 'files': RAW_PASSPORT_DATA['data'][2]['files'], - 'translation': RAW_PASSPORT_DATA['data'][2]['translation']}, - {'type': 'passport_registration', - 'files': RAW_PASSPORT_DATA['data'][2]['files'], - 'translation': RAW_PASSPORT_DATA['data'][2]['translation']}, - {'type': 'temporary_registration', - 'files': RAW_PASSPORT_DATA['data'][2]['files'], - 'translation': RAW_PASSPORT_DATA['data'][2]['translation']}, - {'type': 'address', - 'data': RAW_PASSPORT_DATA['data'][3]['data']}, - {'type': 'email', - 'email': 'fb3e3i47zt@dispostable.com'}, - {'type': 'phone_number', - 'phone_number': 'fb3e3i47zt@dispostable.com'}] + return [ + {'type': 'personal_details', 'data': RAW_PASSPORT_DATA['data'][0]['data']}, + { + 'type': 'passport', + 'data': RAW_PASSPORT_DATA['data'][1]['data'], + 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], + 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], + 'translation': RAW_PASSPORT_DATA['data'][1]['translation'], + }, + { + 'type': 'internal_passport', + 'data': RAW_PASSPORT_DATA['data'][1]['data'], + 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], + 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], + 'translation': RAW_PASSPORT_DATA['data'][1]['translation'], + }, + { + 'type': 'driver_license', + 'data': RAW_PASSPORT_DATA['data'][1]['data'], + 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], + 'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'], + 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], + 'translation': RAW_PASSPORT_DATA['data'][1]['translation'], + }, + { + 'type': 'identity_card', + 'data': RAW_PASSPORT_DATA['data'][1]['data'], + 'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'], + 'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'], + 'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'], + 'translation': RAW_PASSPORT_DATA['data'][1]['translation'], + }, + { + 'type': 'utility_bill', + 'files': RAW_PASSPORT_DATA['data'][2]['files'], + 'translation': RAW_PASSPORT_DATA['data'][2]['translation'], + }, + { + 'type': 'bank_statement', + 'files': RAW_PASSPORT_DATA['data'][2]['files'], + 'translation': RAW_PASSPORT_DATA['data'][2]['translation'], + }, + { + 'type': 'rental_agreement', + 'files': RAW_PASSPORT_DATA['data'][2]['files'], + 'translation': RAW_PASSPORT_DATA['data'][2]['translation'], + }, + { + 'type': 'passport_registration', + 'files': RAW_PASSPORT_DATA['data'][2]['files'], + 'translation': RAW_PASSPORT_DATA['data'][2]['translation'], + }, + { + 'type': 'temporary_registration', + 'files': RAW_PASSPORT_DATA['data'][2]['files'], + 'translation': RAW_PASSPORT_DATA['data'][2]['translation'], + }, + {'type': 'address', 'data': RAW_PASSPORT_DATA['data'][3]['data']}, + {'type': 'email', 'email': 'fb3e3i47zt@dispostable.com'}, + {'type': 'phone_number', 'phone_number': 'fb3e3i47zt@dispostable.com'}, + ] @pytest.fixture(scope='function') @@ -184,19 +247,31 @@ class TestPassport: assert isinstance(driver_license.front_side, PassportFile) assert driver_license.front_side.file_id == self.driver_license_front_side_file_id - assert driver_license.front_side.file_unique_id == self.driver_license_front_side_file_unique_id + assert ( + driver_license.front_side.file_unique_id + == self.driver_license_front_side_file_unique_id + ) assert isinstance(driver_license.reverse_side, PassportFile) assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id - assert driver_license.reverse_side.file_unique_id == self.driver_license_reverse_side_file_unique_id + assert ( + driver_license.reverse_side.file_unique_id + == self.driver_license_reverse_side_file_unique_id + ) assert isinstance(driver_license.translation[0], PassportFile) assert driver_license.translation[0].file_id == self.driver_license_translation_1_file_id - assert driver_license.translation[0].file_unique_id == self.driver_license_translation_1_file_unique_id + assert ( + driver_license.translation[0].file_unique_id + == self.driver_license_translation_1_file_unique_id + ) assert isinstance(driver_license.translation[1], PassportFile) assert driver_license.translation[1].file_id == self.driver_license_translation_2_file_id - assert driver_license.translation[1].file_unique_id == self.driver_license_translation_2_file_unique_id + assert ( + driver_license.translation[1].file_unique_id + == self.driver_license_translation_2_file_unique_id + ) assert utility_bill.type == 'utility_bill' assert isinstance(utility_bill.files[0], PassportFile) @@ -209,11 +284,17 @@ class TestPassport: assert isinstance(utility_bill.translation[0], PassportFile) assert utility_bill.translation[0].file_id == self.utility_bill_translation_1_file_id - assert utility_bill.translation[0].file_unique_id == self.utility_bill_translation_1_file_unique_id + assert ( + utility_bill.translation[0].file_unique_id + == self.utility_bill_translation_1_file_unique_id + ) assert isinstance(utility_bill.translation[1], PassportFile) assert utility_bill.translation[1].file_id == self.utility_bill_translation_2_file_id - assert utility_bill.translation[1].file_unique_id == self.utility_bill_translation_2_file_unique_id + assert ( + utility_bill.translation[1].file_unique_id + == self.utility_bill_translation_2_file_unique_id + ) assert address.type == 'address' assert address.data == RAW_PASSPORT_DATA['data'][3]['data'] @@ -222,40 +303,60 @@ class TestPassport: assert email.email == 'fb3e3i47zt@dispostable.com' def test_expected_decrypted_values(self, passport_data): - (personal_details, driver_license, utility_bill, address, - email) = passport_data.decrypted_data + ( + personal_details, + driver_license, + utility_bill, + address, + email, + ) = passport_data.decrypted_data assert personal_details.type == 'personal_details' - assert personal_details.data.to_dict() == {'first_name': 'FIRSTNAME', - 'middle_name': 'MIDDLENAME', - 'first_name_native': 'FIRSTNAMENATIVE', - 'residence_country_code': 'DK', - 'birth_date': '01.01.2001', - 'last_name_native': 'LASTNAMENATIVE', - 'gender': 'female', - 'middle_name_native': 'MIDDLENAMENATIVE', - 'country_code': 'DK', - 'last_name': 'LASTNAME'} + assert personal_details.data.to_dict() == { + 'first_name': 'FIRSTNAME', + 'middle_name': 'MIDDLENAME', + 'first_name_native': 'FIRSTNAMENATIVE', + 'residence_country_code': 'DK', + 'birth_date': '01.01.2001', + 'last_name_native': 'LASTNAMENATIVE', + 'gender': 'female', + 'middle_name_native': 'MIDDLENAMENATIVE', + 'country_code': 'DK', + 'last_name': 'LASTNAME', + } assert driver_license.type == 'driver_license' - assert driver_license.data.to_dict() == {'expiry_date': '01.01.2001', - 'document_no': 'DOCUMENT_NO'} + assert driver_license.data.to_dict() == { + 'expiry_date': '01.01.2001', + 'document_no': 'DOCUMENT_NO', + } assert isinstance(driver_license.selfie, PassportFile) assert driver_license.selfie.file_id == self.driver_license_selfie_file_id assert driver_license.selfie.file_unique_id == self.driver_license_selfie_file_unique_id assert isinstance(driver_license.front_side, PassportFile) assert driver_license.front_side.file_id == self.driver_license_front_side_file_id - assert driver_license.front_side.file_unique_id == self.driver_license_front_side_file_unique_id + assert ( + driver_license.front_side.file_unique_id + == self.driver_license_front_side_file_unique_id + ) assert isinstance(driver_license.reverse_side, PassportFile) assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id - assert driver_license.reverse_side.file_unique_id == self.driver_license_reverse_side_file_unique_id + assert ( + driver_license.reverse_side.file_unique_id + == self.driver_license_reverse_side_file_unique_id + ) assert address.type == 'address' - assert address.data.to_dict() == {'city': 'CITY', 'street_line2': 'STREET_LINE2', - 'state': 'STATE', 'post_code': 'POSTCODE', - 'country_code': 'DK', 'street_line1': 'STREET_LINE1'} + assert address.data.to_dict() == { + 'city': 'CITY', + 'street_line2': 'STREET_LINE2', + 'state': 'STATE', + 'post_code': 'POSTCODE', + 'country_code': 'DK', + 'street_line1': 'STREET_LINE1', + } assert utility_bill.type == 'utility_bill' assert isinstance(utility_bill.files[0], PassportFile) @@ -288,11 +389,14 @@ class TestPassport: 'temporary_registration': sd['utility_bill'].copy(), } - new = PassportData.de_json({ - 'data': all_passport_data, - # Replaced below - 'credentials': {'data': 'data', 'hash': 'hash', 'secret': 'secret'} - }, bot=bot) + new = PassportData.de_json( + { + 'data': all_passport_data, + # Replaced below + 'credentials': {'data': 'data', 'hash': 'hash', 'secret': 'secret'}, + }, + bot=bot, + ) new.credentials._decrypted_data = Credentials.de_json(credentials, bot) @@ -350,26 +454,37 @@ class TestPassport: def test_mocked_set_passport_data_errors(self, monkeypatch, bot, chat_id, passport_data): def test(url, data, **kwargs): - return (data['user_id'] == chat_id - and data['errors'][0]['file_hash'] == (passport_data.decrypted_credentials - .secure_data.driver_license - .selfie.file_hash) - and data['errors'][1]['data_hash'] == (passport_data.decrypted_credentials - .secure_data.driver_license - .data.data_hash)) + return ( + data['user_id'] == chat_id + and data['errors'][0]['file_hash'] + == ( + passport_data.decrypted_credentials.secure_data.driver_license.selfie.file_hash + ) + and data['errors'][1]['data_hash'] + == (passport_data.decrypted_credentials.secure_data.driver_license.data.data_hash) + ) monkeypatch.setattr(bot.request, 'post', test) - message = bot.set_passport_data_errors(chat_id, [ - PassportElementErrorSelfie('driver_license', - (passport_data.decrypted_credentials - .secure_data.driver_license.selfie.file_hash), - 'You\'re not handsome enough to use this app!'), - PassportElementErrorDataField('driver_license', - 'expiry_date', - (passport_data.decrypted_credentials - .secure_data.driver_license.data.data_hash), - 'Your driver license is expired!') - ]) + message = bot.set_passport_data_errors( + chat_id, + [ + PassportElementErrorSelfie( + 'driver_license', + ( + passport_data.decrypted_credentials.secure_data.driver_license.selfie.file_hash + ), + 'You\'re not handsome enough to use this app!', + ), + PassportElementErrorDataField( + 'driver_license', + 'expiry_date', + ( + passport_data.decrypted_credentials.secure_data.driver_license.data.data_hash + ), + 'Your driver license is expired!', + ), + ], + ) assert message def test_de_json_and_to_dict(self, bot): diff --git a/tests/test_passportelementerrordatafield.py b/tests/test_passportelementerrordatafield.py index 247123dd5..0267c59db 100644 --- a/tests/test_passportelementerrordatafield.py +++ b/tests/test_passportelementerrordatafield.py @@ -24,10 +24,12 @@ from telegram import PassportElementErrorDataField, PassportElementErrorSelfie @pytest.fixture(scope='class') def passport_element_error_data_field(): - return PassportElementErrorDataField(TestPassportElementErrorDataField.type_, - TestPassportElementErrorDataField.field_name, - TestPassportElementErrorDataField.data_hash, - TestPassportElementErrorDataField.message) + return PassportElementErrorDataField( + TestPassportElementErrorDataField.type_, + TestPassportElementErrorDataField.field_name, + TestPassportElementErrorDataField.data_hash, + TestPassportElementErrorDataField.message, + ) class TestPassportElementErrorDataField: @@ -48,22 +50,34 @@ class TestPassportElementErrorDataField: passport_element_error_data_field_dict = passport_element_error_data_field.to_dict() assert isinstance(passport_element_error_data_field_dict, dict) - assert (passport_element_error_data_field_dict['source'] - == passport_element_error_data_field.source) - assert (passport_element_error_data_field_dict['type'] - == passport_element_error_data_field.type) - assert (passport_element_error_data_field_dict['field_name'] - == passport_element_error_data_field.field_name) - assert (passport_element_error_data_field_dict['data_hash'] - == passport_element_error_data_field.data_hash) - assert (passport_element_error_data_field_dict['message'] - == passport_element_error_data_field.message) + assert ( + passport_element_error_data_field_dict['source'] + == passport_element_error_data_field.source + ) + assert ( + passport_element_error_data_field_dict['type'] + == passport_element_error_data_field.type + ) + assert ( + passport_element_error_data_field_dict['field_name'] + == passport_element_error_data_field.field_name + ) + assert ( + passport_element_error_data_field_dict['data_hash'] + == passport_element_error_data_field.data_hash + ) + assert ( + passport_element_error_data_field_dict['message'] + == passport_element_error_data_field.message + ) def test_equality(self): - a = PassportElementErrorDataField(self.type_, self.field_name, self.data_hash, - self.message) - b = PassportElementErrorDataField(self.type_, self.field_name, self.data_hash, - self.message) + a = PassportElementErrorDataField( + self.type_, self.field_name, self.data_hash, self.message + ) + b = PassportElementErrorDataField( + self.type_, self.field_name, self.data_hash, self.message + ) c = PassportElementErrorDataField(self.type_, '', '', '') d = PassportElementErrorDataField('', self.field_name, '', '') e = PassportElementErrorDataField('', '', self.data_hash, '') diff --git a/tests/test_passportelementerrorfile.py b/tests/test_passportelementerrorfile.py index 821cc4811..878ed4f61 100644 --- a/tests/test_passportelementerrorfile.py +++ b/tests/test_passportelementerrorfile.py @@ -24,9 +24,11 @@ from telegram import PassportElementErrorFile, PassportElementErrorSelfie @pytest.fixture(scope='class') def passport_element_error_file(): - return PassportElementErrorFile(TestPassportElementErrorFile.type_, - TestPassportElementErrorFile.file_hash, - TestPassportElementErrorFile.message) + return PassportElementErrorFile( + TestPassportElementErrorFile.type_, + TestPassportElementErrorFile.file_hash, + TestPassportElementErrorFile.message, + ) class TestPassportElementErrorFile: @@ -45,14 +47,12 @@ class TestPassportElementErrorFile: passport_element_error_file_dict = passport_element_error_file.to_dict() assert isinstance(passport_element_error_file_dict, dict) - assert (passport_element_error_file_dict['source'] - == passport_element_error_file.source) - assert (passport_element_error_file_dict['type'] - == passport_element_error_file.type) - assert (passport_element_error_file_dict['file_hash'] - == passport_element_error_file.file_hash) - assert (passport_element_error_file_dict['message'] - == passport_element_error_file.message) + assert passport_element_error_file_dict['source'] == passport_element_error_file.source + assert passport_element_error_file_dict['type'] == passport_element_error_file.type + assert ( + passport_element_error_file_dict['file_hash'] == passport_element_error_file.file_hash + ) + assert passport_element_error_file_dict['message'] == passport_element_error_file.message def test_equality(self): a = PassportElementErrorFile(self.type_, self.file_hash, self.message) diff --git a/tests/test_passportelementerrorfiles.py b/tests/test_passportelementerrorfiles.py index 6c73ae737..a32d42720 100644 --- a/tests/test_passportelementerrorfiles.py +++ b/tests/test_passportelementerrorfiles.py @@ -24,9 +24,11 @@ from telegram import PassportElementErrorFiles, PassportElementErrorSelfie @pytest.fixture(scope='class') def passport_element_error_files(): - return PassportElementErrorFiles(TestPassportElementErrorFiles.type_, - TestPassportElementErrorFiles.file_hashes, - TestPassportElementErrorFiles.message) + return PassportElementErrorFiles( + TestPassportElementErrorFiles.type_, + TestPassportElementErrorFiles.file_hashes, + TestPassportElementErrorFiles.message, + ) class TestPassportElementErrorFiles: @@ -46,14 +48,13 @@ class TestPassportElementErrorFiles: passport_element_error_files_dict = passport_element_error_files.to_dict() assert isinstance(passport_element_error_files_dict, dict) - assert (passport_element_error_files_dict['source'] - == passport_element_error_files.source) - assert (passport_element_error_files_dict['type'] - == passport_element_error_files.type) - assert (passport_element_error_files_dict['file_hashes'] - == passport_element_error_files.file_hashes) - assert (passport_element_error_files_dict['message'] - == passport_element_error_files.message) + assert passport_element_error_files_dict['source'] == passport_element_error_files.source + assert passport_element_error_files_dict['type'] == passport_element_error_files.type + assert ( + passport_element_error_files_dict['file_hashes'] + == passport_element_error_files.file_hashes + ) + assert passport_element_error_files_dict['message'] == passport_element_error_files.message def test_equality(self): a = PassportElementErrorFiles(self.type_, self.file_hashes, self.message) diff --git a/tests/test_passportelementerrorfrontside.py b/tests/test_passportelementerrorfrontside.py index c2375e0fa..b7041339a 100644 --- a/tests/test_passportelementerrorfrontside.py +++ b/tests/test_passportelementerrorfrontside.py @@ -24,9 +24,11 @@ from telegram import PassportElementErrorFrontSide, PassportElementErrorSelfie @pytest.fixture(scope='class') def passport_element_error_front_side(): - return PassportElementErrorFrontSide(TestPassportElementErrorFrontSide.type_, - TestPassportElementErrorFrontSide.file_hash, - TestPassportElementErrorFrontSide.message) + return PassportElementErrorFrontSide( + TestPassportElementErrorFrontSide.type_, + TestPassportElementErrorFrontSide.file_hash, + TestPassportElementErrorFrontSide.message, + ) class TestPassportElementErrorFrontSide: @@ -45,14 +47,22 @@ class TestPassportElementErrorFrontSide: passport_element_error_front_side_dict = passport_element_error_front_side.to_dict() assert isinstance(passport_element_error_front_side_dict, dict) - assert (passport_element_error_front_side_dict['source'] - == passport_element_error_front_side.source) - assert (passport_element_error_front_side_dict['type'] - == passport_element_error_front_side.type) - assert (passport_element_error_front_side_dict['file_hash'] - == passport_element_error_front_side.file_hash) - assert (passport_element_error_front_side_dict['message'] - == passport_element_error_front_side.message) + assert ( + passport_element_error_front_side_dict['source'] + == passport_element_error_front_side.source + ) + assert ( + passport_element_error_front_side_dict['type'] + == passport_element_error_front_side.type + ) + assert ( + passport_element_error_front_side_dict['file_hash'] + == passport_element_error_front_side.file_hash + ) + assert ( + passport_element_error_front_side_dict['message'] + == passport_element_error_front_side.message + ) def test_equality(self): a = PassportElementErrorFrontSide(self.type_, self.file_hash, self.message) diff --git a/tests/test_passportelementerrorreverseside.py b/tests/test_passportelementerrorreverseside.py index 1d79dfcd9..90dc26f95 100644 --- a/tests/test_passportelementerrorreverseside.py +++ b/tests/test_passportelementerrorreverseside.py @@ -24,9 +24,11 @@ from telegram import PassportElementErrorReverseSide, PassportElementErrorSelfie @pytest.fixture(scope='class') def passport_element_error_reverse_side(): - return PassportElementErrorReverseSide(TestPassportElementErrorReverseSide.type_, - TestPassportElementErrorReverseSide.file_hash, - TestPassportElementErrorReverseSide.message) + return PassportElementErrorReverseSide( + TestPassportElementErrorReverseSide.type_, + TestPassportElementErrorReverseSide.file_hash, + TestPassportElementErrorReverseSide.message, + ) class TestPassportElementErrorReverseSide: @@ -45,14 +47,22 @@ class TestPassportElementErrorReverseSide: passport_element_error_reverse_side_dict = passport_element_error_reverse_side.to_dict() assert isinstance(passport_element_error_reverse_side_dict, dict) - assert (passport_element_error_reverse_side_dict['source'] - == passport_element_error_reverse_side.source) - assert (passport_element_error_reverse_side_dict['type'] - == passport_element_error_reverse_side.type) - assert (passport_element_error_reverse_side_dict['file_hash'] - == passport_element_error_reverse_side.file_hash) - assert (passport_element_error_reverse_side_dict['message'] - == passport_element_error_reverse_side.message) + assert ( + passport_element_error_reverse_side_dict['source'] + == passport_element_error_reverse_side.source + ) + assert ( + passport_element_error_reverse_side_dict['type'] + == passport_element_error_reverse_side.type + ) + assert ( + passport_element_error_reverse_side_dict['file_hash'] + == passport_element_error_reverse_side.file_hash + ) + assert ( + passport_element_error_reverse_side_dict['message'] + == passport_element_error_reverse_side.message + ) def test_equality(self): a = PassportElementErrorReverseSide(self.type_, self.file_hash, self.message) diff --git a/tests/test_passportelementerrorselfie.py b/tests/test_passportelementerrorselfie.py index 7cae0dad1..61f4177f0 100644 --- a/tests/test_passportelementerrorselfie.py +++ b/tests/test_passportelementerrorselfie.py @@ -24,9 +24,11 @@ from telegram import PassportElementErrorSelfie, PassportElementErrorDataField @pytest.fixture(scope='class') def passport_element_error_selfie(): - return PassportElementErrorSelfie(TestPassportElementErrorSelfie.type_, - TestPassportElementErrorSelfie.file_hash, - TestPassportElementErrorSelfie.message) + return PassportElementErrorSelfie( + TestPassportElementErrorSelfie.type_, + TestPassportElementErrorSelfie.file_hash, + TestPassportElementErrorSelfie.message, + ) class TestPassportElementErrorSelfie: @@ -45,14 +47,15 @@ class TestPassportElementErrorSelfie: passport_element_error_selfie_dict = passport_element_error_selfie.to_dict() assert isinstance(passport_element_error_selfie_dict, dict) - assert (passport_element_error_selfie_dict['source'] - == passport_element_error_selfie.source) - assert (passport_element_error_selfie_dict['type'] - == passport_element_error_selfie.type) - assert (passport_element_error_selfie_dict['file_hash'] - == passport_element_error_selfie.file_hash) - assert (passport_element_error_selfie_dict['message'] - == passport_element_error_selfie.message) + assert passport_element_error_selfie_dict['source'] == passport_element_error_selfie.source + assert passport_element_error_selfie_dict['type'] == passport_element_error_selfie.type + assert ( + passport_element_error_selfie_dict['file_hash'] + == passport_element_error_selfie.file_hash + ) + assert ( + passport_element_error_selfie_dict['message'] == passport_element_error_selfie.message + ) def test_equality(self): a = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) diff --git a/tests/test_passportelementerrortranslationfile.py b/tests/test_passportelementerrortranslationfile.py index 3703e7bf2..0b282034f 100644 --- a/tests/test_passportelementerrortranslationfile.py +++ b/tests/test_passportelementerrortranslationfile.py @@ -24,9 +24,11 @@ from telegram import PassportElementErrorTranslationFile, PassportElementErrorDa @pytest.fixture(scope='class') def passport_element_error_translation_file(): - return PassportElementErrorTranslationFile(TestPassportElementErrorTranslationFile.type_, - TestPassportElementErrorTranslationFile.file_hash, - TestPassportElementErrorTranslationFile.message) + return PassportElementErrorTranslationFile( + TestPassportElementErrorTranslationFile.type_, + TestPassportElementErrorTranslationFile.file_hash, + TestPassportElementErrorTranslationFile.message, + ) class TestPassportElementErrorTranslationFile: @@ -42,18 +44,27 @@ class TestPassportElementErrorTranslationFile: assert passport_element_error_translation_file.message == self.message def test_to_dict(self, passport_element_error_translation_file): - passport_element_error_translation_file_dict = \ + passport_element_error_translation_file_dict = ( passport_element_error_translation_file.to_dict() + ) assert isinstance(passport_element_error_translation_file_dict, dict) - assert (passport_element_error_translation_file_dict['source'] - == passport_element_error_translation_file.source) - assert (passport_element_error_translation_file_dict['type'] - == passport_element_error_translation_file.type) - assert (passport_element_error_translation_file_dict['file_hash'] - == passport_element_error_translation_file.file_hash) - assert (passport_element_error_translation_file_dict['message'] - == passport_element_error_translation_file.message) + assert ( + passport_element_error_translation_file_dict['source'] + == passport_element_error_translation_file.source + ) + assert ( + passport_element_error_translation_file_dict['type'] + == passport_element_error_translation_file.type + ) + assert ( + passport_element_error_translation_file_dict['file_hash'] + == passport_element_error_translation_file.file_hash + ) + assert ( + passport_element_error_translation_file_dict['message'] + == passport_element_error_translation_file.message + ) def test_equality(self): a = PassportElementErrorTranslationFile(self.type_, self.file_hash, self.message) diff --git a/tests/test_passportelementerrortranslationfiles.py b/tests/test_passportelementerrortranslationfiles.py index 0fcf0709a..b7b65ab26 100644 --- a/tests/test_passportelementerrortranslationfiles.py +++ b/tests/test_passportelementerrortranslationfiles.py @@ -27,7 +27,8 @@ def passport_element_error_translation_files(): return PassportElementErrorTranslationFiles( TestPassportElementErrorTranslationFiles.type_, TestPassportElementErrorTranslationFiles.file_hashes, - TestPassportElementErrorTranslationFiles.message) + TestPassportElementErrorTranslationFiles.message, + ) class TestPassportElementErrorTranslationFiles: @@ -44,18 +45,27 @@ class TestPassportElementErrorTranslationFiles: assert passport_element_error_translation_files.message == self.message def test_to_dict(self, passport_element_error_translation_files): - passport_element_error_translation_files_dict = \ + passport_element_error_translation_files_dict = ( passport_element_error_translation_files.to_dict() + ) assert isinstance(passport_element_error_translation_files_dict, dict) - assert (passport_element_error_translation_files_dict['source'] - == passport_element_error_translation_files.source) - assert (passport_element_error_translation_files_dict['type'] - == passport_element_error_translation_files.type) - assert (passport_element_error_translation_files_dict['file_hashes'] - == passport_element_error_translation_files.file_hashes) - assert (passport_element_error_translation_files_dict['message'] - == passport_element_error_translation_files.message) + assert ( + passport_element_error_translation_files_dict['source'] + == passport_element_error_translation_files.source + ) + assert ( + passport_element_error_translation_files_dict['type'] + == passport_element_error_translation_files.type + ) + assert ( + passport_element_error_translation_files_dict['file_hashes'] + == passport_element_error_translation_files.file_hashes + ) + assert ( + passport_element_error_translation_files_dict['message'] + == passport_element_error_translation_files.message + ) def test_equality(self): a = PassportElementErrorTranslationFiles(self.type_, self.file_hashes, self.message) diff --git a/tests/test_passportelementerrorunspecified.py b/tests/test_passportelementerrorunspecified.py index 74e99681e..aa1d3bd2d 100644 --- a/tests/test_passportelementerrorunspecified.py +++ b/tests/test_passportelementerrorunspecified.py @@ -24,9 +24,11 @@ from telegram import PassportElementErrorUnspecified, PassportElementErrorDataFi @pytest.fixture(scope='class') def passport_element_error_unspecified(): - return PassportElementErrorUnspecified(TestPassportElementErrorUnspecified.type_, - TestPassportElementErrorUnspecified.element_hash, - TestPassportElementErrorUnspecified.message) + return PassportElementErrorUnspecified( + TestPassportElementErrorUnspecified.type_, + TestPassportElementErrorUnspecified.element_hash, + TestPassportElementErrorUnspecified.message, + ) class TestPassportElementErrorUnspecified: @@ -45,14 +47,22 @@ class TestPassportElementErrorUnspecified: passport_element_error_unspecified_dict = passport_element_error_unspecified.to_dict() assert isinstance(passport_element_error_unspecified_dict, dict) - assert (passport_element_error_unspecified_dict['source'] - == passport_element_error_unspecified.source) - assert (passport_element_error_unspecified_dict['type'] - == passport_element_error_unspecified.type) - assert (passport_element_error_unspecified_dict['element_hash'] - == passport_element_error_unspecified.element_hash) - assert (passport_element_error_unspecified_dict['message'] - == passport_element_error_unspecified.message) + assert ( + passport_element_error_unspecified_dict['source'] + == passport_element_error_unspecified.source + ) + assert ( + passport_element_error_unspecified_dict['type'] + == passport_element_error_unspecified.type + ) + assert ( + passport_element_error_unspecified_dict['element_hash'] + == passport_element_error_unspecified.element_hash + ) + assert ( + passport_element_error_unspecified_dict['message'] + == passport_element_error_unspecified.message + ) def test_equality(self): a = PassportElementErrorUnspecified(self.type_, self.element_hash, self.message) diff --git a/tests/test_passportfile.py b/tests/test_passportfile.py index 347892a34..b199bd719 100644 --- a/tests/test_passportfile.py +++ b/tests/test_passportfile.py @@ -24,10 +24,12 @@ from telegram import PassportFile, PassportElementError @pytest.fixture(scope='class') def passport_file(): - return PassportFile(file_id=TestPassportFile.file_id, - file_unique_id=TestPassportFile.file_unique_id, - file_size=TestPassportFile.file_size, - file_date=TestPassportFile.file_date) + return PassportFile( + file_id=TestPassportFile.file_id, + file_unique_id=TestPassportFile.file_unique_id, + file_size=TestPassportFile.file_size, + file_date=TestPassportFile.file_date, + ) class TestPassportFile: @@ -46,14 +48,10 @@ class TestPassportFile: passport_file_dict = passport_file.to_dict() assert isinstance(passport_file_dict, dict) - assert (passport_file_dict['file_id'] - == passport_file.file_id) - assert (passport_file_dict['file_unique_id'] - == passport_file.file_unique_id) - assert (passport_file_dict['file_size'] - == passport_file.file_size) - assert (passport_file_dict['file_date'] - == passport_file.file_date) + assert passport_file_dict['file_id'] == passport_file.file_id + assert passport_file_dict['file_unique_id'] == passport_file.file_unique_id + assert passport_file_dict['file_size'] == passport_file.file_size + assert passport_file_dict['file_date'] == passport_file.file_date def test_equality(self): a = PassportFile(self.file_id, self.file_unique_id, self.file_size, self.file_date) diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 7141bf304..4975af67f 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -33,8 +33,18 @@ from time import sleep import pytest from telegram import Update, Message, User, Chat, MessageEntity -from telegram.ext import BasePersistence, Updater, ConversationHandler, MessageHandler, Filters, \ - PicklePersistence, CommandHandler, DictPersistence, TypeHandler, JobQueue +from telegram.ext import ( + BasePersistence, + Updater, + ConversationHandler, + MessageHandler, + Filters, + PicklePersistence, + CommandHandler, + DictPersistence, + TypeHandler, + JobQueue, +) @pytest.fixture(autouse=True) @@ -51,7 +61,6 @@ def change_directory(tmp_path): @pytest.fixture(scope="function") def base_persistence(): class OwnPersistence(BasePersistence): - def get_bot_data(self): raise NotImplementedError @@ -96,9 +105,11 @@ def user_data(): @pytest.fixture(scope='function') def conversations(): - return {'name1': {(123, 123): 3, (456, 654): 4}, - 'name2': {(123, 321): 1, (890, 890): 2}, - 'name3': {(123, 321): 1, (890, 890): 2}} + return { + 'name1': {(123, 123): 3, (456, 654): 4}, + 'name2': {(123, 321): 1, (890, 890): 2}, + 'name3': {(123, 321): 1, (890, 890): 2}, + } @pytest.fixture(scope="function") @@ -121,16 +132,20 @@ def job_queue(bot): class TestBasePersistence: - def test_creation(self, base_persistence): assert base_persistence.store_chat_data assert base_persistence.store_user_data assert base_persistence.store_bot_data def test_abstract_methods(self): - with pytest.raises(TypeError, match=('get_bot_data, get_chat_data, get_conversations, ' - 'get_user_data, update_bot_data, update_chat_data, ' - 'update_conversation, update_user_data')): + with pytest.raises( + TypeError, + match=( + 'get_bot_data, get_chat_data, get_conversations, ' + 'get_user_data, update_bot_data, update_chat_data, ' + 'update_conversation, update_user_data' + ), + ): BasePersistence() def test_implementation(self, updater, base_persistence): @@ -144,8 +159,9 @@ class TestBasePersistence: dp.add_handler(ConversationHandler([], {}, [], persistent=True, name="My Handler")) dp.persistence = base_persistence - def test_dispatcher_integration_init(self, bot, base_persistence, chat_data, user_data, - bot_data): + def test_dispatcher_integration_init( + self, bot, base_persistence, chat_data, user_data, bot_data + ): def get_user_data(): return "test" @@ -187,8 +203,9 @@ class TestBasePersistence: u.dispatcher.chat_data[442233]['test5'] = 'test6' assert u.dispatcher.chat_data[442233]['test5'] == 'test6' - def test_dispatcher_integration_handlers(self, caplog, bot, base_persistence, - chat_data, user_data, bot_data): + def test_dispatcher_integration_handlers( + self, caplog, bot, base_persistence, chat_data, user_data, bot_data + ): def get_user_data(): return user_data @@ -229,12 +246,21 @@ class TestBasePersistence: context.chat_data[2] = 'test8' context.bot_data['test0'] = 'test0' - known_user = MessageHandler(Filters.user(user_id=12345), callback_known_user, - pass_chat_data=True, pass_user_data=True) - known_chat = MessageHandler(Filters.chat(chat_id=-67890), callback_known_chat, - pass_chat_data=True, pass_user_data=True) - unknown = MessageHandler(Filters.all, callback_unknown_user_or_chat, pass_chat_data=True, - pass_user_data=True) + known_user = MessageHandler( + Filters.user(user_id=12345), + callback_known_user, + pass_chat_data=True, + pass_user_data=True, + ) + known_chat = MessageHandler( + Filters.chat(chat_id=-67890), + callback_known_chat, + pass_chat_data=True, + pass_user_data=True, + ) + unknown = MessageHandler( + Filters.all, callback_unknown_user_or_chat, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(known_user) dp.add_handler(known_chat) dp.add_handler(unknown) @@ -283,8 +309,9 @@ class TestBasePersistence: assert dp.chat_data[-987654][2] == 'test8' assert dp.bot_data['test0'] == 'test0' - def test_dispatcher_integration_handlers_run_async(self, cdp, caplog, bot, base_persistence, - chat_data, user_data, bot_data): + def test_dispatcher_integration_handlers_run_async( + self, cdp, caplog, bot, base_persistence, chat_data, user_data, bot_data + ): def get_user_data(): return user_data @@ -325,12 +352,27 @@ class TestBasePersistence: context.chat_data[2] = 'test8' context.bot_data['test0'] = 'test0' - known_user = MessageHandler(Filters.user(user_id=12345), callback_known_user, - pass_chat_data=True, pass_user_data=True, run_async=True) - known_chat = MessageHandler(Filters.chat(chat_id=-67890), callback_known_chat, - pass_chat_data=True, pass_user_data=True, run_async=True) - unknown = MessageHandler(Filters.all, callback_unknown_user_or_chat, pass_chat_data=True, - pass_user_data=True, run_async=True) + known_user = MessageHandler( + Filters.user(user_id=12345), + callback_known_user, + pass_chat_data=True, + pass_user_data=True, + run_async=True, + ) + known_chat = MessageHandler( + Filters.chat(chat_id=-67890), + callback_known_chat, + pass_chat_data=True, + pass_user_data=True, + run_async=True, + ) + unknown = MessageHandler( + Filters.all, + callback_unknown_user_or_chat, + pass_chat_data=True, + pass_user_data=True, + run_async=True, + ) cdp.add_handler(known_user) cdp.add_handler(known_chat) cdp.add_handler(unknown) @@ -343,7 +385,7 @@ class TestBasePersistence: with caplog.at_level(logging.ERROR): cdp.process_update(u) - sleep(.1) + sleep(0.1) rec = caplog.records[-1] assert rec.msg == 'No error handlers are registered, logging exception.' assert rec.levelname == 'ERROR' @@ -396,7 +438,6 @@ class TestBasePersistence: assert 'An uncaught error was raised while processing the update' not in caplog.text def test_bot_replace_insert_bot(self, bot): - class BotPersistence(BasePersistence): def __init__(self): super().__init__() @@ -467,14 +508,16 @@ class TestBasePersistence: if isinstance(other, CustomClass): # print(self.__dict__) # print(other.__dict__) - return (self.bot is other.bot - and self.slotted_object == other.slotted_object - and self.list_ == other.list_ - and self.tuple_ == other.tuple_ - and self.set_ == other.set_ - and self.frozenset_ == other.frozenset_ - and self.dict_ == other.dict_ - and self.defaultdict_ == other.defaultdict_) + return ( + self.bot is other.bot + and self.slotted_object == other.slotted_object + and self.list_ == other.list_ + and self.tuple_ == other.tuple_ + and self.set_ == other.set_ + and self.frozenset_ == other.frozenset_ + and self.dict_ == other.dict_ + and self.defaultdict_ == other.defaultdict_ + ) return False persistence = BotPersistence() @@ -503,48 +546,61 @@ class TestBasePersistence: @pytest.fixture(scope='function') def pickle_persistence(): - return PicklePersistence(filename='pickletest', - store_user_data=True, - store_chat_data=True, - store_bot_data=True, - single_file=False, - on_flush=False) + return PicklePersistence( + filename='pickletest', + store_user_data=True, + store_chat_data=True, + store_bot_data=True, + single_file=False, + on_flush=False, + ) @pytest.fixture(scope='function') def pickle_persistence_only_bot(): - return PicklePersistence(filename='pickletest', - store_user_data=False, - store_chat_data=False, - store_bot_data=True, - single_file=False, - on_flush=False) + return PicklePersistence( + filename='pickletest', + store_user_data=False, + store_chat_data=False, + store_bot_data=True, + single_file=False, + on_flush=False, + ) @pytest.fixture(scope='function') def pickle_persistence_only_chat(): - return PicklePersistence(filename='pickletest', - store_user_data=False, - store_chat_data=True, - store_bot_data=False, - single_file=False, - on_flush=False) + return PicklePersistence( + filename='pickletest', + store_user_data=False, + store_chat_data=True, + store_bot_data=False, + single_file=False, + on_flush=False, + ) @pytest.fixture(scope='function') def pickle_persistence_only_user(): - return PicklePersistence(filename='pickletest', - store_user_data=True, - store_chat_data=False, - store_bot_data=False, - single_file=False, - on_flush=False) + return PicklePersistence( + filename='pickletest', + store_user_data=True, + store_chat_data=False, + store_bot_data=False, + single_file=False, + on_flush=False, + ) @pytest.fixture(scope='function') def bad_pickle_files(): - for name in ['pickletest_user_data', 'pickletest_chat_data', 'pickletest_bot_data', - 'pickletest_conversations', 'pickletest']: + for name in [ + 'pickletest_user_data', + 'pickletest_chat_data', + 'pickletest_bot_data', + 'pickletest_conversations', + 'pickletest', + ]: with open(name, 'w') as f: f.write('(())') yield True @@ -552,8 +608,12 @@ def bad_pickle_files(): @pytest.fixture(scope='function') def good_pickle_files(user_data, chat_data, bot_data, conversations): - data = {'user_data': user_data, 'chat_data': chat_data, - 'bot_data': bot_data, 'conversations': conversations} + data = { + 'user_data': user_data, + 'chat_data': chat_data, + 'bot_data': bot_data, + 'conversations': conversations, + } with open('pickletest_user_data', 'wb') as f: pickle.dump(user_data, f) with open('pickletest_chat_data', 'wb') as f: @@ -970,15 +1030,17 @@ class TestPickelPersistence: h2 = MessageHandler(None, second, pass_user_data=True, pass_chat_data=True) dp.add_handler(h1) dp.process_update(update) - del (dp) - del (u) - del (pickle_persistence) - pickle_persistence_2 = PicklePersistence(filename='pickletest', - store_user_data=True, - store_chat_data=True, - store_bot_data=True, - single_file=False, - on_flush=False) + del dp + del u + del pickle_persistence + pickle_persistence_2 = PicklePersistence( + filename='pickletest', + store_user_data=True, + store_chat_data=True, + store_bot_data=True, + single_file=False, + on_flush=False, + ) u = Updater(bot=bot, persistence=pickle_persistence_2) dp = u.dispatcher dp.add_handler(h2) @@ -992,14 +1054,16 @@ class TestPickelPersistence: dp.chat_data[-4242424242]['my_test2'] = 'Working2!' dp.bot_data['test'] = 'Working3!' u.signal_handler(signal.SIGINT, None) - del (dp) - del (u) - del (pickle_persistence) - pickle_persistence_2 = PicklePersistence(filename='pickletest', - store_user_data=True, - store_chat_data=True, - single_file=False, - on_flush=False) + del dp + del u + del pickle_persistence + pickle_persistence_2 = PicklePersistence( + filename='pickletest', + store_user_data=True, + store_chat_data=True, + single_file=False, + on_flush=False, + ) assert pickle_persistence_2.get_user_data()[4242424242]['my_test'] == 'Working!' assert pickle_persistence_2.get_chat_data()[-4242424242]['my_test2'] == 'Working2!' assert pickle_persistence_2.get_bot_data()['test'] == 'Working3!' @@ -1012,15 +1076,17 @@ class TestPickelPersistence: dp.chat_data[-4242424242]['my_test2'] = 'Working2!' dp.bot_data['my_test3'] = 'Working3!' u.signal_handler(signal.SIGINT, None) - del (dp) - del (u) - del (pickle_persistence_only_bot) - pickle_persistence_2 = PicklePersistence(filename='pickletest', - store_user_data=False, - store_chat_data=False, - store_bot_data=True, - single_file=False, - on_flush=False) + del dp + del u + del pickle_persistence_only_bot + pickle_persistence_2 = PicklePersistence( + filename='pickletest', + store_user_data=False, + store_chat_data=False, + store_bot_data=True, + single_file=False, + on_flush=False, + ) assert pickle_persistence_2.get_user_data() == {} assert pickle_persistence_2.get_chat_data() == {} assert pickle_persistence_2.get_bot_data()['my_test3'] == 'Working3!' @@ -1032,15 +1098,17 @@ class TestPickelPersistence: dp.user_data[4242424242]['my_test'] = 'Working!' dp.chat_data[-4242424242]['my_test2'] = 'Working2!' u.signal_handler(signal.SIGINT, None) - del (dp) - del (u) - del (pickle_persistence_only_chat) - pickle_persistence_2 = PicklePersistence(filename='pickletest', - store_user_data=False, - store_chat_data=True, - store_bot_data=False, - single_file=False, - on_flush=False) + del dp + del u + del pickle_persistence_only_chat + pickle_persistence_2 = PicklePersistence( + filename='pickletest', + store_user_data=False, + store_chat_data=True, + store_bot_data=False, + single_file=False, + on_flush=False, + ) assert pickle_persistence_2.get_user_data() == {} assert pickle_persistence_2.get_chat_data()[-4242424242]['my_test2'] == 'Working2!' assert pickle_persistence_2.get_bot_data() == {} @@ -1052,15 +1120,17 @@ class TestPickelPersistence: dp.user_data[4242424242]['my_test'] = 'Working!' dp.chat_data[-4242424242]['my_test2'] = 'Working2!' u.signal_handler(signal.SIGINT, None) - del (dp) - del (u) - del (pickle_persistence_only_user) - pickle_persistence_2 = PicklePersistence(filename='pickletest', - store_user_data=True, - store_chat_data=False, - store_bot_data=False, - single_file=False, - on_flush=False) + del dp + del u + del pickle_persistence_only_user + pickle_persistence_2 = PicklePersistence( + filename='pickletest', + store_user_data=True, + store_chat_data=False, + store_bot_data=False, + single_file=False, + on_flush=False, + ) assert pickle_persistence_2.get_user_data()[4242424242]['my_test'] == 'Working!' assert pickle_persistence_2.get_chat_data()[-4242424242] == {} assert pickle_persistence_2.get_bot_data() == {} @@ -1085,8 +1155,9 @@ class TestPickelPersistence: next2 = MessageHandler(None, next2) - ch = ConversationHandler([start], {NEXT: [next], NEXT2: [next2]}, [], name='name2', - persistent=True) + ch = ConversationHandler( + [start], {NEXT: [next], NEXT2: [next2]}, [], name='name2', persistent=True + ) dp.add_handler(ch) assert ch.conversations[ch._get_key(update)] == 1 dp.process_update(update) @@ -1097,8 +1168,9 @@ class TestPickelPersistence: assert ch.conversations[ch._get_key(update)] == 0 assert ch.conversations == pickle_persistence.conversations['name2'] - def test_with_nested_conversationHandler(self, dp, update, good_pickle_files, - pickle_persistence): + def test_with_nested_conversationHandler( + self, dp, update, good_pickle_files, pickle_persistence + ): dp.persistence = pickle_persistence dp.use_context = True NEXT2, NEXT3 = range(1, 3) @@ -1127,8 +1199,9 @@ class TestPickelPersistence: map_to_parent={ConversationHandler.END: ConversationHandler.END}, ) - ch = ConversationHandler([start], {NEXT2: [nested_ch], NEXT3: []}, [], name='name2', - persistent=True) + ch = ConversationHandler( + [start], {NEXT2: [nested_ch], NEXT3: []}, [], name='name2', persistent=True + ) dp.add_handler(ch) assert ch.conversations[ch._get_key(update)] == 1 assert nested_ch.conversations[nested_ch._get_key(update)] == 1 @@ -1224,12 +1297,15 @@ class TestDictPersistence: with pytest.raises(TypeError, match='conversations'): DictPersistence(conversations_json=bad_conversations) - def test_good_json_input(self, user_data_json, chat_data_json, bot_data_json, - conversations_json): - dict_persistence = DictPersistence(user_data_json=user_data_json, - chat_data_json=chat_data_json, - bot_data_json=bot_data_json, - conversations_json=conversations_json) + def test_good_json_input( + self, user_data_json, chat_data_json, bot_data_json, conversations_json + ): + dict_persistence = DictPersistence( + user_data_json=user_data_json, + chat_data_json=chat_data_json, + bot_data_json=bot_data_json, + conversations_json=conversations_json, + ) user_data = dict_persistence.get_user_data() assert isinstance(user_data, defaultdict) assert user_data[12345]['test1'] == 'test2' @@ -1261,35 +1337,57 @@ class TestDictPersistence: with pytest.raises(KeyError): conversation2[(123, 123)] - def test_dict_outputs(self, user_data, user_data_json, chat_data, chat_data_json, - bot_data, bot_data_json, - conversations, conversations_json): - dict_persistence = DictPersistence(user_data_json=user_data_json, - chat_data_json=chat_data_json, - bot_data_json=bot_data_json, - conversations_json=conversations_json) + def test_dict_outputs( + self, + user_data, + user_data_json, + chat_data, + chat_data_json, + bot_data, + bot_data_json, + conversations, + conversations_json, + ): + dict_persistence = DictPersistence( + user_data_json=user_data_json, + chat_data_json=chat_data_json, + bot_data_json=bot_data_json, + conversations_json=conversations_json, + ) assert dict_persistence.user_data == user_data assert dict_persistence.chat_data == chat_data assert dict_persistence.bot_data == bot_data assert dict_persistence.conversations == conversations def test_json_outputs(self, user_data_json, chat_data_json, bot_data_json, conversations_json): - dict_persistence = DictPersistence(user_data_json=user_data_json, - chat_data_json=chat_data_json, - bot_data_json=bot_data_json, - conversations_json=conversations_json) + dict_persistence = DictPersistence( + user_data_json=user_data_json, + chat_data_json=chat_data_json, + bot_data_json=bot_data_json, + conversations_json=conversations_json, + ) assert dict_persistence.user_data_json == user_data_json assert dict_persistence.chat_data_json == chat_data_json assert dict_persistence.bot_data_json == bot_data_json assert dict_persistence.conversations_json == conversations_json - def test_json_changes(self, user_data, user_data_json, chat_data, chat_data_json, - bot_data, bot_data_json, - conversations, conversations_json): - dict_persistence = DictPersistence(user_data_json=user_data_json, - chat_data_json=chat_data_json, - bot_data_json=bot_data_json, - conversations_json=conversations_json) + def test_json_changes( + self, + user_data, + user_data_json, + chat_data, + chat_data_json, + bot_data, + bot_data_json, + conversations, + conversations_json, + ): + dict_persistence = DictPersistence( + user_data_json=user_data_json, + chat_data_json=chat_data_json, + bot_data_json=bot_data_json, + conversations_json=conversations_json, + ) user_data_two = user_data.copy() user_data_two.update({4: {5: 6}}) dict_persistence.update_user_data(4, {5: 6}) @@ -1318,7 +1416,8 @@ class TestDictPersistence: assert dict_persistence.conversations == conversations_two assert dict_persistence.conversations_json != conversations_json assert dict_persistence.conversations_json == encode_conversations_to_json( - conversations_two) + conversations_two + ) def test_with_handler(self, bot, update): dict_persistence = DictPersistence() @@ -1348,15 +1447,15 @@ class TestDictPersistence: h2 = MessageHandler(None, second, pass_user_data=True, pass_chat_data=True) dp.add_handler(h1) dp.process_update(update) - del (dp) - del (u) + del dp + del u user_data = dict_persistence.user_data_json chat_data = dict_persistence.chat_data_json bot_data = dict_persistence.bot_data_json - del (dict_persistence) - dict_persistence_2 = DictPersistence(user_data_json=user_data, - chat_data_json=chat_data, - bot_data_json=bot_data) + del dict_persistence + dict_persistence_2 = DictPersistence( + user_data_json=user_data, chat_data_json=chat_data, bot_data_json=bot_data + ) u = Updater(bot=bot, persistence=dict_persistence_2) dp = u.dispatcher @@ -1384,8 +1483,9 @@ class TestDictPersistence: next2 = MessageHandler(None, next2) - ch = ConversationHandler([start], {NEXT: [next], NEXT2: [next2]}, [], name='name2', - persistent=True) + ch = ConversationHandler( + [start], {NEXT: [next], NEXT2: [next2]}, [], name='name2', persistent=True + ) dp.add_handler(ch) assert ch.conversations[ch._get_key(update)] == 1 dp.process_update(update) @@ -1426,8 +1526,9 @@ class TestDictPersistence: map_to_parent={ConversationHandler.END: ConversationHandler.END}, ) - ch = ConversationHandler([start], {NEXT2: [nested_ch], NEXT3: []}, [], name='name2', - persistent=True) + ch = ConversationHandler( + [start], {NEXT2: [nested_ch], NEXT3: []}, [], name='name2', persistent=True + ) dp.add_handler(ch) assert ch.conversations[ch._get_key(update)] == 1 assert nested_ch.conversations[nested_ch._get_key(update)] == 1 diff --git a/tests/test_photo.py b/tests/test_photo.py index 6a7a6afe6..24c39dc36 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -85,8 +85,13 @@ class TestPhoto: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_photo_all_args(self, bot, chat_id, photo_file, thumb, photo): - message = bot.send_photo(chat_id, photo_file, caption=self.caption, - disable_notification=False, parse_mode='Markdown') + message = bot.send_photo( + chat_id, + photo_file, + caption=self.caption, + disable_notification=False, + parse_mode='Markdown', + ) assert isinstance(message.photo[0], PhotoSize) assert isinstance(message.photo[0].file_id, str) @@ -111,8 +116,7 @@ class TestPhoto: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file, thumb, photo): - message = bot.send_photo(chat_id, photo_file, caption=self.caption, - parse_mode='Markdown') + message = bot.send_photo(chat_id, photo_file, caption=self.caption, parse_mode='Markdown') assert isinstance(message.photo[0], PhotoSize) assert isinstance(message.photo[0].file_id, str) assert isinstance(message.photo[0].file_unique_id, str) @@ -137,8 +141,7 @@ class TestPhoto: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file, thumb, photo): - message = bot.send_photo(chat_id, photo_file, caption=self.caption, - parse_mode='HTML') + message = bot.send_photo(chat_id, photo_file, caption=self.caption, parse_mode='HTML') assert isinstance(message.photo[0], PhotoSize) assert isinstance(message.photo[0].file_id, str) assert isinstance(message.photo[0].file_unique_id, str) @@ -177,8 +180,9 @@ class TestPhoto: def test_send_photo_default_parse_mode_2(self, default_bot, chat_id, photo_file, thumb, photo): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_photo(chat_id, photo_file, caption=test_markdown_string, - parse_mode=None) + message = default_bot.send_photo( + chat_id, photo_file, caption=test_markdown_string, parse_mode=None + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -188,8 +192,9 @@ class TestPhoto: def test_send_photo_default_parse_mode_3(self, default_bot, chat_id, photo_file, thumb, photo): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_photo(chat_id, photo_file, caption=test_markdown_string, - parse_mode='HTML') + message = default_bot.send_photo( + chat_id, photo_file, caption=test_markdown_string, parse_mode='HTML' + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -232,8 +237,9 @@ class TestPhoto: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_url_png_file(self, bot, chat_id): - message = bot.send_photo(photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', - chat_id=chat_id) + message = bot.send_photo( + photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', chat_id=chat_id + ) photo = message.photo[-1] @@ -246,8 +252,9 @@ class TestPhoto: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_url_gif_file(self, bot, chat_id): - message = bot.send_photo(photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', - chat_id=chat_id) + message = bot.send_photo( + photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', chat_id=chat_id + ) photo = message.photo[-1] @@ -342,7 +349,7 @@ class TestPhoto: 'file_unique_id': photo.file_unique_id, 'width': self.width, 'height': self.height, - 'file_size': self.file_size + 'file_size': self.file_size, } json_photo = PhotoSize.de_json(json_dict, bot) diff --git a/tests/test_poll.py b/tests/test_poll.py index 7327cee11..62fe93567 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -28,8 +28,7 @@ from telegram.utils.helpers import to_timestamp @pytest.fixture(scope="class") def poll_option(): - return PollOption(text=TestPollOption.text, - voter_count=TestPollOption.voter_count) + return PollOption(text=TestPollOption.text, voter_count=TestPollOption.voter_count) class TestPollOption: @@ -37,10 +36,7 @@ class TestPollOption: voter_count = 3 def test_de_json(self): - json_dict = { - 'text': self.text, - 'voter_count': self.voter_count - } + json_dict = {'text': self.text, 'voter_count': self.voter_count} poll_option = PollOption.de_json(json_dict, None) assert poll_option.text == self.text @@ -75,8 +71,9 @@ class TestPollOption: @pytest.fixture(scope="class") def poll_answer(): - return PollAnswer(poll_id=TestPollAnswer.poll_id, user=TestPollAnswer.user, - option_ids=TestPollAnswer.poll_id) + return PollAnswer( + poll_id=TestPollAnswer.poll_id, user=TestPollAnswer.user, option_ids=TestPollAnswer.poll_id + ) class TestPollAnswer: @@ -88,7 +85,7 @@ class TestPollAnswer: json_dict = { 'poll_id': self.poll_id, 'user': self.user.to_dict(), - 'option_ids': self.option_ids + 'option_ids': self.option_ids, } poll_answer = PollAnswer.de_json(json_dict, None) @@ -126,19 +123,20 @@ class TestPollAnswer: @pytest.fixture(scope='class') def poll(): - return Poll(TestPoll.id_, - TestPoll.question, - TestPoll.options, - TestPoll.total_voter_count, - TestPoll.is_closed, - TestPoll.is_anonymous, - TestPoll.type, - TestPoll.allows_multiple_answers, - explanation=TestPoll.explanation, - explanation_entities=TestPoll.explanation_entities, - open_period=TestPoll.open_period, - close_date=TestPoll.close_date, - ) + return Poll( + TestPoll.id_, + TestPoll.question, + TestPoll.options, + TestPoll.total_voter_count, + TestPoll.is_closed, + TestPoll.is_anonymous, + TestPoll.type, + TestPoll.allows_multiple_answers, + explanation=TestPoll.explanation, + explanation_entities=TestPoll.explanation_entities, + open_period=TestPoll.open_period, + close_date=TestPoll.close_date, + ) class TestPoll: @@ -150,8 +148,10 @@ class TestPoll: is_anonymous = False type = Poll.REGULAR allows_multiple_answers = True - explanation = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467' - b'\\u200d\\U0001f467\\U0001f431http://google.com').decode('unicode-escape') + explanation = ( + b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467' + b'\\u200d\\U0001f467\\U0001f431http://google.com' + ).decode('unicode-escape') explanation_entities = [MessageEntity(13, 17, MessageEntity.URL)] open_period = 42 close_date = datetime.utcnow() @@ -169,7 +169,7 @@ class TestPoll: 'explanation': self.explanation, 'explanation_entities': [self.explanation_entities[0].to_dict()], 'open_period': self.open_period, - 'close_date': to_timestamp(self.close_date) + 'close_date': to_timestamp(self.close_date), } poll = Poll.de_json(json_dict, bot) diff --git a/tests/test_pollanswerhandler.py b/tests/test_pollanswerhandler.py index 1c90d7f76..154281229 100644 --- a/tests/test_pollanswerhandler.py +++ b/tests/test_pollanswerhandler.py @@ -20,8 +20,18 @@ from queue import Queue import pytest -from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, PollAnswer, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Update, + CallbackQuery, + Bot, + Message, + User, + Chat, + PollAnswer, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import PollAnswerHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -35,12 +45,20 @@ params = [ {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -78,15 +96,17 @@ class TestPollAnswerHandler: self.test_flag = (job_queue is not None) and (update_queue is not None) def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and context.chat_data is None - and isinstance(context.bot_data, dict) - and isinstance(update.poll_answer, PollAnswer)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and context.chat_data is None + and isinstance(context.bot_data, dict) + and isinstance(update.poll_answer, PollAnswer) + ) def test_basic(self, dp, poll_answer): handler = PollAnswerHandler(self.callback_basic) @@ -113,8 +133,7 @@ class TestPollAnswerHandler: assert self.test_flag dp.remove_handler(handler) - handler = PollAnswerHandler(self.callback_data_2, pass_chat_data=True, - pass_user_data=True) + handler = PollAnswerHandler(self.callback_data_2, pass_chat_data=True, pass_user_data=True) dp.add_handler(handler) self.test_flag = False @@ -129,8 +148,7 @@ class TestPollAnswerHandler: assert self.test_flag dp.remove_handler(handler) - handler = PollAnswerHandler(self.callback_queue_1, - pass_update_queue=True) + handler = PollAnswerHandler(self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -138,8 +156,9 @@ class TestPollAnswerHandler: assert self.test_flag dp.remove_handler(handler) - handler = PollAnswerHandler(self.callback_queue_2, pass_job_queue=True, - pass_update_queue=True) + handler = PollAnswerHandler( + self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_pollhandler.py b/tests/test_pollhandler.py index 033c59f56..5efa79ea1 100644 --- a/tests/test_pollhandler.py +++ b/tests/test_pollhandler.py @@ -20,8 +20,19 @@ from queue import Queue import pytest -from telegram import (Update, Poll, PollOption, Bot, Message, User, Chat, CallbackQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Update, + Poll, + PollOption, + Bot, + Message, + User, + Chat, + CallbackQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import PollHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -35,12 +46,20 @@ params = [ {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -50,8 +69,19 @@ def false_update(request): @pytest.fixture(scope='function') def poll(bot): - return Update(0, poll=Poll(1, 'question', [PollOption('1', 0), PollOption('2', 0)], 0, False, - False, Poll.REGULAR, True)) + return Update( + 0, + poll=Poll( + 1, + 'question', + [PollOption('1', 0), PollOption('2', 0)], + 0, + False, + False, + Poll.REGULAR, + True, + ), + ) class TestPollHandler: @@ -79,15 +109,17 @@ class TestPollHandler: self.test_flag = (job_queue is not None) and (update_queue is not None) def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and context.user_data is None - and context.chat_data is None - and isinstance(context.bot_data, dict) - and isinstance(update.poll, Poll)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and context.user_data is None + and context.chat_data is None + and isinstance(context.bot_data, dict) + and isinstance(update.poll, Poll) + ) def test_basic(self, dp, poll): handler = PollHandler(self.callback_basic) @@ -114,8 +146,7 @@ class TestPollHandler: assert self.test_flag dp.remove_handler(handler) - handler = PollHandler(self.callback_data_2, pass_chat_data=True, - pass_user_data=True) + handler = PollHandler(self.callback_data_2, pass_chat_data=True, pass_user_data=True) dp.add_handler(handler) self.test_flag = False @@ -130,8 +161,7 @@ class TestPollHandler: assert self.test_flag dp.remove_handler(handler) - handler = PollHandler(self.callback_queue_1, - pass_update_queue=True) + handler = PollHandler(self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -139,8 +169,7 @@ class TestPollHandler: assert self.test_flag dp.remove_handler(handler) - handler = PollHandler(self.callback_queue_2, pass_job_queue=True, - pass_update_queue=True) + handler = PollHandler(self.callback_queue_2, pass_job_queue=True, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py index b3ceb4140..64ca26780 100644 --- a/tests/test_precheckoutquery.py +++ b/tests/test_precheckoutquery.py @@ -24,14 +24,16 @@ from telegram import Update, User, PreCheckoutQuery, OrderInfo @pytest.fixture(scope='class') def pre_checkout_query(bot): - return PreCheckoutQuery(TestPreCheckoutQuery.id_, - TestPreCheckoutQuery.from_user, - TestPreCheckoutQuery.currency, - TestPreCheckoutQuery.total_amount, - TestPreCheckoutQuery.invoice_payload, - shipping_option_id=TestPreCheckoutQuery.shipping_option_id, - order_info=TestPreCheckoutQuery.order_info, - bot=bot) + return PreCheckoutQuery( + TestPreCheckoutQuery.id_, + TestPreCheckoutQuery.from_user, + TestPreCheckoutQuery.currency, + TestPreCheckoutQuery.total_amount, + TestPreCheckoutQuery.invoice_payload, + shipping_option_id=TestPreCheckoutQuery.shipping_option_id, + order_info=TestPreCheckoutQuery.order_info, + bot=bot, + ) class TestPreCheckoutQuery: @@ -51,7 +53,7 @@ class TestPreCheckoutQuery: 'currency': self.currency, 'total_amount': self.total_amount, 'from': self.from_user.to_dict(), - 'order_info': self.order_info.to_dict() + 'order_info': self.order_info.to_dict(), } pre_checkout_query = PreCheckoutQuery.de_json(json_dict, bot) @@ -69,8 +71,9 @@ class TestPreCheckoutQuery: assert isinstance(pre_checkout_query_dict, dict) assert pre_checkout_query_dict['id'] == pre_checkout_query.id assert pre_checkout_query_dict['invoice_payload'] == pre_checkout_query.invoice_payload - assert (pre_checkout_query_dict['shipping_option_id'] - == pre_checkout_query.shipping_option_id) + assert ( + pre_checkout_query_dict['shipping_option_id'] == pre_checkout_query.shipping_option_id + ) assert pre_checkout_query_dict['currency'] == pre_checkout_query.currency assert pre_checkout_query_dict['from'] == pre_checkout_query.from_user.to_dict() assert pre_checkout_query_dict['order_info'] == pre_checkout_query.order_info.to_dict() @@ -83,13 +86,16 @@ class TestPreCheckoutQuery: assert pre_checkout_query.answer() def test_equality(self): - a = PreCheckoutQuery(self.id_, self.from_user, self.currency, self.total_amount, - self.invoice_payload) - b = PreCheckoutQuery(self.id_, self.from_user, self.currency, self.total_amount, - self.invoice_payload) + a = PreCheckoutQuery( + self.id_, self.from_user, self.currency, self.total_amount, self.invoice_payload + ) + b = PreCheckoutQuery( + self.id_, self.from_user, self.currency, self.total_amount, self.invoice_payload + ) c = PreCheckoutQuery(self.id_, None, '', 0, '') - d = PreCheckoutQuery(0, self.from_user, self.currency, self.total_amount, - self.invoice_payload) + d = PreCheckoutQuery( + 0, self.from_user, self.currency, self.total_amount, self.invoice_payload + ) e = Update(self.id_) assert a == b diff --git a/tests/test_precheckoutqueryhandler.py b/tests/test_precheckoutqueryhandler.py index de1172d8e..9b862735b 100644 --- a/tests/test_precheckoutqueryhandler.py +++ b/tests/test_precheckoutqueryhandler.py @@ -20,8 +20,18 @@ from queue import Queue import pytest -from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery, - InlineQuery, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Update, + Chat, + Bot, + ChosenInlineResult, + User, + Message, + CallbackQuery, + InlineQuery, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import PreCheckoutQueryHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -35,12 +45,20 @@ params = [ {'inline_query': InlineQuery(1, User(1, '', False), '', '')}, {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'inline_query', 'chosen_inline_result', - 'shipping_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'inline_query', + 'chosen_inline_result', + 'shipping_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -50,9 +68,12 @@ def false_update(request): @pytest.fixture(scope='class') def pre_checkout_query(): - return Update(1, - pre_checkout_query=PreCheckoutQuery('id', User(1, 'test user', False), - 'EUR', 223, 'invoice_payload')) + return Update( + 1, + pre_checkout_query=PreCheckoutQuery( + 'id', User(1, 'test user', False), 'EUR', 223, 'invoice_payload' + ), + ) class TestPreCheckoutQueryHandler: @@ -80,15 +101,17 @@ class TestPreCheckoutQueryHandler: self.test_flag = (job_queue is not None) and (update_queue is not None) def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and context.chat_data is None - and isinstance(context.bot_data, dict) - and isinstance(update.pre_checkout_query, PreCheckoutQuery)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and context.chat_data is None + and isinstance(context.bot_data, dict) + and isinstance(update.pre_checkout_query, PreCheckoutQuery) + ) def test_basic(self, dp, pre_checkout_query): handler = PreCheckoutQueryHandler(self.callback_basic) @@ -99,16 +122,14 @@ class TestPreCheckoutQueryHandler: assert self.test_flag def test_pass_user_or_chat_data(self, dp, pre_checkout_query): - handler = PreCheckoutQueryHandler(self.callback_data_1, - pass_user_data=True) + handler = PreCheckoutQueryHandler(self.callback_data_1, pass_user_data=True) dp.add_handler(handler) dp.process_update(pre_checkout_query) assert self.test_flag dp.remove_handler(handler) - handler = PreCheckoutQueryHandler(self.callback_data_1, - pass_chat_data=True) + handler = PreCheckoutQueryHandler(self.callback_data_1, pass_chat_data=True) dp.add_handler(handler) self.test_flag = False @@ -116,9 +137,9 @@ class TestPreCheckoutQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = PreCheckoutQueryHandler(self.callback_data_2, - pass_chat_data=True, - pass_user_data=True) + handler = PreCheckoutQueryHandler( + self.callback_data_2, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(handler) self.test_flag = False @@ -126,16 +147,14 @@ class TestPreCheckoutQueryHandler: assert self.test_flag def test_pass_job_or_update_queue(self, dp, pre_checkout_query): - handler = PreCheckoutQueryHandler(self.callback_queue_1, - pass_job_queue=True) + handler = PreCheckoutQueryHandler(self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update(pre_checkout_query) assert self.test_flag dp.remove_handler(handler) - handler = PreCheckoutQueryHandler(self.callback_queue_1, - pass_update_queue=True) + handler = PreCheckoutQueryHandler(self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -143,9 +162,9 @@ class TestPreCheckoutQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = PreCheckoutQueryHandler(self.callback_queue_2, - pass_job_queue=True, - pass_update_queue=True) + handler = PreCheckoutQueryHandler( + self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_regexhandler.py b/tests/test_regexhandler.py index 992f87f00..b3a863ca1 100644 --- a/tests/test_regexhandler.py +++ b/tests/test_regexhandler.py @@ -21,8 +21,18 @@ from queue import Queue import pytest from telegram.utils.deprecate import TelegramDeprecationWarning -from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Message, + Update, + Chat, + Bot, + User, + CallbackQuery, + InlineQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import RegexHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -33,11 +43,17 @@ params = [ {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('callback_query', 'inline_query', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'callback_query', + 'inline_query', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -47,8 +63,9 @@ def false_update(request): @pytest.fixture(scope='class') def message(bot): - return Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='test message', - bot=bot) + return Message( + 1, None, Chat(1, ''), from_user=User(1, '', False), text='test message', bot=bot + ) class TestRegexHandler: @@ -82,15 +99,17 @@ class TestRegexHandler: self.test_flag = groupdict == {'begin': 't', 'end': ' message'} def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and isinstance(context.chat_data, dict) - and isinstance(context.bot_data, dict) - and isinstance(update.message, Message)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and isinstance(context.chat_data, dict) + and isinstance(context.bot_data, dict) + and isinstance(update.message, Message) + ) def callback_context_pattern(self, update, context): if context.matches[0].groups(): @@ -119,15 +138,17 @@ class TestRegexHandler: assert not handler.check_update(Update(0, message)) def test_with_passing_group_dict(self, dp, message): - handler = RegexHandler('(?P.*)est(?P.*)', self.callback_group, - pass_groups=True) + handler = RegexHandler( + '(?P.*)est(?P.*)', self.callback_group, pass_groups=True + ) dp.add_handler(handler) dp.process_update(Update(0, message)) assert self.test_flag dp.remove_handler(handler) - handler = RegexHandler('(?P.*)est(?P.*)', self.callback_group, - pass_groupdict=True) + handler = RegexHandler( + '(?P.*)est(?P.*)', self.callback_group, pass_groupdict=True + ) dp.add_handler(handler) self.test_flag = False @@ -135,8 +156,13 @@ class TestRegexHandler: assert self.test_flag def test_edited(self, message): - handler = RegexHandler('.*', self.callback_basic, edited_updates=True, - message_updates=False, channel_post_updates=False) + handler = RegexHandler( + '.*', + self.callback_basic, + edited_updates=True, + message_updates=False, + channel_post_updates=False, + ) assert handler.check_update(Update(0, edited_message=message)) assert not handler.check_update(Update(0, message=message)) @@ -144,8 +170,13 @@ class TestRegexHandler: assert handler.check_update(Update(0, edited_channel_post=message)) def test_channel_post(self, message): - handler = RegexHandler('.*', self.callback_basic, edited_updates=False, - message_updates=False, channel_post_updates=True) + handler = RegexHandler( + '.*', + self.callback_basic, + edited_updates=False, + message_updates=False, + channel_post_updates=True, + ) assert not handler.check_update(Update(0, edited_message=message)) assert not handler.check_update(Update(0, message=message)) @@ -153,8 +184,13 @@ class TestRegexHandler: assert not handler.check_update(Update(0, edited_channel_post=message)) def test_multiple_flags(self, message): - handler = RegexHandler('.*', self.callback_basic, edited_updates=True, - message_updates=True, channel_post_updates=True) + handler = RegexHandler( + '.*', + self.callback_basic, + edited_updates=True, + message_updates=True, + channel_post_updates=True, + ) assert handler.check_update(Update(0, edited_message=message)) assert handler.check_update(Update(0, message=message)) @@ -163,8 +199,13 @@ class TestRegexHandler: def test_none_allowed(self): with pytest.raises(ValueError, match='are all False'): - RegexHandler('.*', self.callback_basic, message_updates=False, - channel_post_updates=False, edited_updates=False) + RegexHandler( + '.*', + self.callback_basic, + message_updates=False, + channel_post_updates=False, + edited_updates=False, + ) def test_pass_user_or_chat_data(self, dp, message): handler = RegexHandler('.*', self.callback_data_1, pass_user_data=True) @@ -182,8 +223,9 @@ class TestRegexHandler: assert self.test_flag dp.remove_handler(handler) - handler = RegexHandler('.*', self.callback_data_2, pass_chat_data=True, - pass_user_data=True) + handler = RegexHandler( + '.*', self.callback_data_2, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(handler) self.test_flag = False @@ -198,8 +240,7 @@ class TestRegexHandler: assert self.test_flag dp.remove_handler(handler) - handler = RegexHandler('.*', self.callback_queue_1, - pass_update_queue=True) + handler = RegexHandler('.*', self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -207,8 +248,9 @@ class TestRegexHandler: assert self.test_flag dp.remove_handler(handler) - handler = RegexHandler('.*', self.callback_queue_2, pass_job_queue=True, - pass_update_queue=True) + handler = RegexHandler( + '.*', self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index 9fc537a95..a3d3bebf3 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -25,10 +25,12 @@ from telegram import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup @pytest.fixture(scope='class') def reply_keyboard_markup(): - return ReplyKeyboardMarkup(TestReplyKeyboardMarkup.keyboard, - resize_keyboard=TestReplyKeyboardMarkup.resize_keyboard, - one_time_keyboard=TestReplyKeyboardMarkup.one_time_keyboard, - selective=TestReplyKeyboardMarkup.selective) + return ReplyKeyboardMarkup( + TestReplyKeyboardMarkup.keyboard, + resize_keyboard=TestReplyKeyboardMarkup.resize_keyboard, + one_time_keyboard=TestReplyKeyboardMarkup.one_time_keyboard, + selective=TestReplyKeyboardMarkup.selective, + ) class TestReplyKeyboardMarkup: @@ -53,7 +55,8 @@ class TestReplyKeyboardMarkup: def test_from_button(self): reply_keyboard_markup = ReplyKeyboardMarkup.from_button( - KeyboardButton(text='button1')).keyboard + KeyboardButton(text='button1') + ).keyboard assert len(reply_keyboard_markup) == 1 assert len(reply_keyboard_markup[0]) == 1 @@ -62,9 +65,9 @@ class TestReplyKeyboardMarkup: assert len(reply_keyboard_markup[0]) == 1 def test_from_row(self): - reply_keyboard_markup = ReplyKeyboardMarkup.from_row([ - KeyboardButton(text='button1'), - KeyboardButton(text='button2')]).keyboard + reply_keyboard_markup = ReplyKeyboardMarkup.from_row( + [KeyboardButton(text='button1'), KeyboardButton(text='button2')] + ).keyboard assert len(reply_keyboard_markup) == 1 assert len(reply_keyboard_markup[0]) == 2 @@ -73,9 +76,9 @@ class TestReplyKeyboardMarkup: assert len(reply_keyboard_markup[0]) == 2 def test_from_column(self): - reply_keyboard_markup = ReplyKeyboardMarkup.from_column([ - KeyboardButton(text='button1'), - KeyboardButton(text='button2')]).keyboard + reply_keyboard_markup = ReplyKeyboardMarkup.from_column( + [KeyboardButton(text='button1'), KeyboardButton(text='button2')] + ).keyboard assert len(reply_keyboard_markup) == 2 assert len(reply_keyboard_markup[0]) == 1 assert len(reply_keyboard_markup[1]) == 1 @@ -97,21 +100,28 @@ class TestReplyKeyboardMarkup: reply_keyboard_markup_dict = reply_keyboard_markup.to_dict() assert isinstance(reply_keyboard_markup_dict, dict) - assert (reply_keyboard_markup_dict['keyboard'][0][0] - == reply_keyboard_markup.keyboard[0][0].to_dict()) - assert (reply_keyboard_markup_dict['keyboard'][0][1] - == reply_keyboard_markup.keyboard[0][1].to_dict()) - assert (reply_keyboard_markup_dict['resize_keyboard'] - == reply_keyboard_markup.resize_keyboard) - assert (reply_keyboard_markup_dict['one_time_keyboard'] - == reply_keyboard_markup.one_time_keyboard) + assert ( + reply_keyboard_markup_dict['keyboard'][0][0] + == reply_keyboard_markup.keyboard[0][0].to_dict() + ) + assert ( + reply_keyboard_markup_dict['keyboard'][0][1] + == reply_keyboard_markup.keyboard[0][1].to_dict() + ) + assert ( + reply_keyboard_markup_dict['resize_keyboard'] == reply_keyboard_markup.resize_keyboard + ) + assert ( + reply_keyboard_markup_dict['one_time_keyboard'] + == reply_keyboard_markup.one_time_keyboard + ) assert reply_keyboard_markup_dict['selective'] == reply_keyboard_markup.selective def test_equality(self): a = ReplyKeyboardMarkup.from_column(['button1', 'button2', 'button3']) - b = ReplyKeyboardMarkup.from_column([ - KeyboardButton(text) for text in ['button1', 'button2', 'button3'] - ]) + b = ReplyKeyboardMarkup.from_column( + [KeyboardButton(text) for text in ['button1', 'button2', 'button3']] + ) c = ReplyKeyboardMarkup.from_column(['button1', 'button2']) d = ReplyKeyboardMarkup.from_column(['button1', 'button2', 'button3.1']) e = ReplyKeyboardMarkup([['button1', 'button1'], ['button2'], ['button3.1']]) diff --git a/tests/test_replykeyboardremove.py b/tests/test_replykeyboardremove.py index b1d9afc52..5b8903280 100644 --- a/tests/test_replykeyboardremove.py +++ b/tests/test_replykeyboardremove.py @@ -46,6 +46,7 @@ class TestReplyKeyboardRemove: def test_to_dict(self, reply_keyboard_remove): reply_keyboard_remove_dict = reply_keyboard_remove.to_dict() - assert (reply_keyboard_remove_dict['remove_keyboard'] - == reply_keyboard_remove.remove_keyboard) + assert ( + reply_keyboard_remove_dict['remove_keyboard'] == reply_keyboard_remove.remove_keyboard + ) assert reply_keyboard_remove_dict['selective'] == reply_keyboard_remove.selective diff --git a/tests/test_shippingaddress.py b/tests/test_shippingaddress.py index 54d6aea7a..2e4af8267 100644 --- a/tests/test_shippingaddress.py +++ b/tests/test_shippingaddress.py @@ -24,12 +24,14 @@ from telegram import ShippingAddress @pytest.fixture(scope='class') def shipping_address(): - return ShippingAddress(TestShippingAddress.country_code, - TestShippingAddress.state, - TestShippingAddress.city, - TestShippingAddress.street_line1, - TestShippingAddress.street_line2, - TestShippingAddress.post_code) + return ShippingAddress( + TestShippingAddress.country_code, + TestShippingAddress.state, + TestShippingAddress.city, + TestShippingAddress.street_line1, + TestShippingAddress.street_line2, + TestShippingAddress.post_code, + ) class TestShippingAddress: @@ -47,7 +49,7 @@ class TestShippingAddress: 'city': self.city, 'street_line1': self.street_line1, 'street_line2': self.street_line2, - 'post_code': self.post_code + 'post_code': self.post_code, } shipping_address = ShippingAddress.de_json(json_dict, bot) @@ -70,22 +72,40 @@ class TestShippingAddress: assert shipping_address_dict['post_code'] == shipping_address.post_code def test_equality(self): - a = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - self.street_line2, self.post_code) - b = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - self.street_line2, self.post_code) - d = ShippingAddress('', self.state, self.city, self.street_line1, - self.street_line2, self.post_code) - d2 = ShippingAddress(self.country_code, '', self.city, self.street_line1, - self.street_line2, self.post_code) - d3 = ShippingAddress(self.country_code, self.state, '', self.street_line1, - self.street_line2, self.post_code) - d4 = ShippingAddress(self.country_code, self.state, self.city, '', - self.street_line2, self.post_code) - d5 = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - '', self.post_code) - d6 = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - self.street_line2, '') + a = ShippingAddress( + self.country_code, + self.state, + self.city, + self.street_line1, + self.street_line2, + self.post_code, + ) + b = ShippingAddress( + self.country_code, + self.state, + self.city, + self.street_line1, + self.street_line2, + self.post_code, + ) + d = ShippingAddress( + '', self.state, self.city, self.street_line1, self.street_line2, self.post_code + ) + d2 = ShippingAddress( + self.country_code, '', self.city, self.street_line1, self.street_line2, self.post_code + ) + d3 = ShippingAddress( + self.country_code, self.state, '', self.street_line1, self.street_line2, self.post_code + ) + d4 = ShippingAddress( + self.country_code, self.state, self.city, '', self.street_line2, self.post_code + ) + d5 = ShippingAddress( + self.country_code, self.state, self.city, self.street_line1, '', self.post_code + ) + d6 = ShippingAddress( + self.country_code, self.state, self.city, self.street_line1, self.street_line2, '' + ) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_shippingoption.py b/tests/test_shippingoption.py index 0d966120d..ac3187e4a 100644 --- a/tests/test_shippingoption.py +++ b/tests/test_shippingoption.py @@ -24,17 +24,15 @@ from telegram import LabeledPrice, ShippingOption, Voice @pytest.fixture(scope='class') def shipping_option(): - return ShippingOption(TestShippingOption.id_, TestShippingOption.title, - TestShippingOption.prices) + return ShippingOption( + TestShippingOption.id_, TestShippingOption.title, TestShippingOption.prices + ) class TestShippingOption: id_ = 'id' title = 'title' - prices = [ - LabeledPrice('Fish Container', 100), - LabeledPrice('Premium Fish Container', 1000) - ] + prices = [LabeledPrice('Fish Container', 100), LabeledPrice('Premium Fish Container', 1000)] def test_expected_values(self, shipping_option): assert shipping_option.id == self.id_ diff --git a/tests/test_shippingquery.py b/tests/test_shippingquery.py index 499b920aa..c0c9cfc7f 100644 --- a/tests/test_shippingquery.py +++ b/tests/test_shippingquery.py @@ -24,11 +24,13 @@ from telegram import Update, User, ShippingAddress, ShippingQuery @pytest.fixture(scope='class') def shipping_query(bot): - return ShippingQuery(TestShippingQuery.id_, - TestShippingQuery.from_user, - TestShippingQuery.invoice_payload, - TestShippingQuery.shipping_address, - bot=bot) + return ShippingQuery( + TestShippingQuery.id_, + TestShippingQuery.from_user, + TestShippingQuery.invoice_payload, + TestShippingQuery.shipping_address, + bot=bot, + ) class TestShippingQuery: @@ -42,7 +44,7 @@ class TestShippingQuery: 'id': TestShippingQuery.id_, 'invoice_payload': TestShippingQuery.invoice_payload, 'from': TestShippingQuery.from_user.to_dict(), - 'shipping_address': TestShippingQuery.shipping_address.to_dict() + 'shipping_address': TestShippingQuery.shipping_address.to_dict(), } shipping_query = ShippingQuery.de_json(json_dict, bot) diff --git a/tests/test_shippingqueryhandler.py b/tests/test_shippingqueryhandler.py index daccaa3a4..de2c23c1a 100644 --- a/tests/test_shippingqueryhandler.py +++ b/tests/test_shippingqueryhandler.py @@ -20,8 +20,19 @@ from queue import Queue import pytest -from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery, - InlineQuery, ShippingQuery, PreCheckoutQuery, ShippingAddress) +from telegram import ( + Update, + Chat, + Bot, + ChosenInlineResult, + User, + Message, + CallbackQuery, + InlineQuery, + ShippingQuery, + PreCheckoutQuery, + ShippingAddress, +) from telegram.ext import ShippingQueryHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -35,12 +46,20 @@ params = [ {'inline_query': InlineQuery(1, User(1, '', False), '', '')}, {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'inline_query', 'chosen_inline_result', - 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'inline_query', + 'chosen_inline_result', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -50,10 +69,15 @@ def false_update(request): @pytest.fixture(scope='class') def shiping_query(): - return Update(1, - shipping_query=ShippingQuery(42, User(1, 'test user', False), 'invoice_payload', - ShippingAddress('EN', 'my_state', 'my_city', - 'steer_1', '', 'post_code'))) + return Update( + 1, + shipping_query=ShippingQuery( + 42, + User(1, 'test user', False), + 'invoice_payload', + ShippingAddress('EN', 'my_state', 'my_city', 'steer_1', '', 'post_code'), + ), + ) class TestShippingQueryHandler: @@ -81,15 +105,17 @@ class TestShippingQueryHandler: self.test_flag = (job_queue is not None) and (update_queue is not None) def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and context.chat_data is None - and isinstance(context.bot_data, dict) - and isinstance(update.shipping_query, ShippingQuery)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and context.chat_data is None + and isinstance(context.bot_data, dict) + and isinstance(update.shipping_query, ShippingQuery) + ) def test_basic(self, dp, shiping_query): handler = ShippingQueryHandler(self.callback_basic) @@ -100,16 +126,14 @@ class TestShippingQueryHandler: assert self.test_flag def test_pass_user_or_chat_data(self, dp, shiping_query): - handler = ShippingQueryHandler(self.callback_data_1, - pass_user_data=True) + handler = ShippingQueryHandler(self.callback_data_1, pass_user_data=True) dp.add_handler(handler) dp.process_update(shiping_query) assert self.test_flag dp.remove_handler(handler) - handler = ShippingQueryHandler(self.callback_data_1, - pass_chat_data=True) + handler = ShippingQueryHandler(self.callback_data_1, pass_chat_data=True) dp.add_handler(handler) self.test_flag = False @@ -117,9 +141,9 @@ class TestShippingQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = ShippingQueryHandler(self.callback_data_2, - pass_chat_data=True, - pass_user_data=True) + handler = ShippingQueryHandler( + self.callback_data_2, pass_chat_data=True, pass_user_data=True + ) dp.add_handler(handler) self.test_flag = False @@ -127,16 +151,14 @@ class TestShippingQueryHandler: assert self.test_flag def test_pass_job_or_update_queue(self, dp, shiping_query): - handler = ShippingQueryHandler(self.callback_queue_1, - pass_job_queue=True) + handler = ShippingQueryHandler(self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update(shiping_query) assert self.test_flag dp.remove_handler(handler) - handler = ShippingQueryHandler(self.callback_queue_1, - pass_update_queue=True) + handler = ShippingQueryHandler(self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -144,9 +166,9 @@ class TestShippingQueryHandler: assert self.test_flag dp.remove_handler(handler) - handler = ShippingQueryHandler(self.callback_queue_2, - pass_job_queue=True, - pass_update_queue=True) + handler = ShippingQueryHandler( + self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_sticker.py b/tests/test_sticker.py index c8564ddee..047c8162e 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -56,8 +56,10 @@ def animated_sticker(bot, chat_id): class TestSticker: # sticker_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.webp' # Serving sticker from gh since our server sends wrong content_type - sticker_file_url = ('https://github.com/python-telegram-bot/python-telegram-bot/blob/master' - '/tests/data/telegram.webp?raw=true') + sticker_file_url = ( + 'https://github.com/python-telegram-bot/python-telegram-bot/blob/master' + '/tests/data/telegram.webp?raw=true' + ) emoji = '💪' width = 510 @@ -180,7 +182,7 @@ class TestSticker: 'is_animated': self.is_animated, 'thumb': sticker.thumb.to_dict(), 'emoji': self.emoji, - 'file_size': self.file_size + 'file_size': self.file_size, } json_sticker = Sticker.de_json(json_dict, bot) @@ -230,14 +232,15 @@ class TestSticker: bot.send_sticker(chat_id) def test_equality(self, sticker): - a = Sticker(sticker.file_id, sticker.file_unique_id, self.width, - self.height, self.is_animated) - b = Sticker('', sticker.file_unique_id, self.width, - self.height, self.is_animated) + a = Sticker( + sticker.file_id, sticker.file_unique_id, self.width, self.height, self.is_animated + ) + b = Sticker('', sticker.file_unique_id, self.width, self.height, self.is_animated) c = Sticker(sticker.file_id, sticker.file_unique_id, 0, 0, False) d = Sticker('', '', self.width, self.height, self.is_animated) - e = PhotoSize(sticker.file_id, sticker.file_unique_id, self.width, - self.height, self.is_animated) + e = PhotoSize( + sticker.file_id, sticker.file_unique_id, self.width, self.height, self.is_animated + ) assert a == b assert hash(a) == hash(b) @@ -299,7 +302,7 @@ class TestStickerSet: 'is_animated': self.is_animated, 'contains_masks': self.contains_masks, 'stickers': [x.to_dict() for x in self.stickers], - 'thumb': sticker.thumb.to_dict() + 'thumb': sticker.thumb.to_dict(), } sticker_set = StickerSet.de_json(json_dict, bot) @@ -316,20 +319,27 @@ class TestStickerSet: with open('tests/data/telegram_sticker.png', 'rb') as f: file = bot.upload_sticker_file(95205500, f) assert file - assert bot.add_sticker_to_set(chat_id, 'test_by_{}'.format(bot.username), - png_sticker=file.file_id, emojis='😄') + assert bot.add_sticker_to_set( + chat_id, 'test_by_{}'.format(bot.username), png_sticker=file.file_id, emojis='😄' + ) # Also test with file input and mask - assert bot.add_sticker_to_set(chat_id, 'test_by_{}'.format(bot.username), - png_sticker=sticker_file, emojis='😄', - mask_position=MaskPosition(MaskPosition.EYES, -1, 1, 2)) + assert bot.add_sticker_to_set( + chat_id, + 'test_by_{}'.format(bot.username), + png_sticker=sticker_file, + emojis='😄', + mask_position=MaskPosition(MaskPosition.EYES, -1, 1, 2), + ) @flaky(3, 1) @pytest.mark.timeout(10) def test_bot_methods_1_tgs(self, bot, chat_id): assert bot.add_sticker_to_set( - chat_id, 'animated_test_by_{}'.format(bot.username), + chat_id, + 'animated_test_by_{}'.format(bot.username), tgs_sticker=open('tests/data/telegram_animated_sticker.tgs', 'rb'), - emojis='😄') + emojis='😄', + ) def test_sticker_set_to_dict(self, sticker_set): sticker_set_dict = sticker_set.to_dict() @@ -357,19 +367,22 @@ class TestStickerSet: @pytest.mark.timeout(10) def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): sleep(1) - assert bot.set_sticker_set_thumb('test_by_{}'.format(bot.username), chat_id, - sticker_set_thumb_file) + assert bot.set_sticker_set_thumb( + 'test_by_{}'.format(bot.username), chat_id, sticker_set_thumb_file + ) @flaky(10, 1) @pytest.mark.timeout(10) def test_bot_methods_3_tgs(self, bot, chat_id, animated_sticker_file, animated_sticker_set): sleep(1) - assert bot.set_sticker_set_thumb('animated_test_by_{}'.format(bot.username), chat_id, - animated_sticker_file) + assert bot.set_sticker_set_thumb( + 'animated_test_by_{}'.format(bot.username), chat_id, animated_sticker_file + ) file_id = animated_sticker_set.stickers[-1].file_id # also test with file input and mask - assert bot.set_sticker_set_thumb('animated_test_by_{}'.format(bot.username), chat_id, - file_id) + assert bot.set_sticker_set_thumb( + 'animated_test_by_{}'.format(bot.username), chat_id, file_id + ) @flaky(10, 1) @pytest.mark.timeout(10) @@ -415,10 +428,12 @@ class TestStickerSet: @pytest.fixture(scope='class') def mask_position(): - return MaskPosition(TestMaskPosition.point, - TestMaskPosition.x_shift, - TestMaskPosition.y_shift, - TestMaskPosition.scale) + return MaskPosition( + TestMaskPosition.point, + TestMaskPosition.x_shift, + TestMaskPosition.y_shift, + TestMaskPosition.scale, + ) class TestMaskPosition: @@ -432,7 +447,7 @@ class TestMaskPosition: 'point': self.point, 'x_shift': self.x_shift, 'y_shift': self.y_shift, - 'scale': self.scale + 'scale': self.scale, } mask_position = MaskPosition.de_json(json_dict, bot) diff --git a/tests/test_stringcommandhandler.py b/tests/test_stringcommandhandler.py index e1a0e3305..9848bcdf8 100644 --- a/tests/test_stringcommandhandler.py +++ b/tests/test_stringcommandhandler.py @@ -20,8 +20,18 @@ from queue import Queue import pytest -from telegram import (Bot, Update, Message, User, Chat, CallbackQuery, InlineQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Bot, + Update, + Message, + User, + Chat, + CallbackQuery, + InlineQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import StringCommandHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -36,12 +46,21 @@ params = [ {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'inline_query', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'inline_query', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -74,14 +93,16 @@ class TestStringCommandHandler: self.test_flag = args == ['one', 'two'] def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, str) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and context.user_data is None - and context.chat_data is None - and isinstance(context.bot_data, dict)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, str) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and context.user_data is None + and context.chat_data is None + and isinstance(context.bot_data, dict) + ) def callback_context_args(self, update, context): self.test_flag = context.args == ['one', 'two'] @@ -103,8 +124,7 @@ class TestStringCommandHandler: assert check is not None and check is not False def test_pass_args(self, dp): - handler = StringCommandHandler('test', self.sch_callback_args, - pass_args=True) + handler = StringCommandHandler('test', self.sch_callback_args, pass_args=True) dp.add_handler(handler) dp.process_update('/test') @@ -115,16 +135,14 @@ class TestStringCommandHandler: assert self.test_flag def test_pass_job_or_update_queue(self, dp): - handler = StringCommandHandler('test', self.callback_queue_1, - pass_job_queue=True) + handler = StringCommandHandler('test', self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update('/test') assert self.test_flag dp.remove_handler(handler) - handler = StringCommandHandler('test', self.callback_queue_1, - pass_update_queue=True) + handler = StringCommandHandler('test', self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -132,9 +150,9 @@ class TestStringCommandHandler: assert self.test_flag dp.remove_handler(handler) - handler = StringCommandHandler('test', self.callback_queue_2, - pass_job_queue=True, - pass_update_queue=True) + handler = StringCommandHandler( + 'test', self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_stringregexhandler.py b/tests/test_stringregexhandler.py index e86bcef79..a26a6b841 100644 --- a/tests/test_stringregexhandler.py +++ b/tests/test_stringregexhandler.py @@ -20,8 +20,18 @@ from queue import Queue import pytest -from telegram import (Bot, Update, Message, User, Chat, CallbackQuery, InlineQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram import ( + Bot, + Update, + Message, + User, + Chat, + CallbackQuery, + InlineQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, +) from telegram.ext import StringRegexHandler, CallbackContext, JobQueue message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -36,12 +46,21 @@ params = [ {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')} + {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, ] -ids = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'inline_query', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') +ids = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'inline_query', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'callback_query_without_message', +) @pytest.fixture(scope='class', params=params, ids=ids) @@ -74,11 +93,13 @@ class TestStringRegexHandler: self.test_flag = groupdict == {'begin': 't', 'end': ' message'} def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, str) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, str) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + ) def callback_context_pattern(self, update, context): if context.matches[0].groups(): @@ -97,16 +118,18 @@ class TestStringRegexHandler: assert not handler.check_update('does not match') def test_with_passing_group_dict(self, dp): - handler = StringRegexHandler('(?P.*)est(?P.*)', self.callback_group, - pass_groups=True) + handler = StringRegexHandler( + '(?P.*)est(?P.*)', self.callback_group, pass_groups=True + ) dp.add_handler(handler) dp.process_update('test message') assert self.test_flag dp.remove_handler(handler) - handler = StringRegexHandler('(?P.*)est(?P.*)', self.callback_group, - pass_groupdict=True) + handler = StringRegexHandler( + '(?P.*)est(?P.*)', self.callback_group, pass_groupdict=True + ) dp.add_handler(handler) self.test_flag = False @@ -114,16 +137,14 @@ class TestStringRegexHandler: assert self.test_flag def test_pass_job_or_update_queue(self, dp): - handler = StringRegexHandler('test', self.callback_queue_1, - pass_job_queue=True) + handler = StringRegexHandler('test', self.callback_queue_1, pass_job_queue=True) dp.add_handler(handler) dp.process_update('test') assert self.test_flag dp.remove_handler(handler) - handler = StringRegexHandler('test', self.callback_queue_1, - pass_update_queue=True) + handler = StringRegexHandler('test', self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -131,8 +152,9 @@ class TestStringRegexHandler: assert self.test_flag dp.remove_handler(handler) - handler = StringRegexHandler('test', self.callback_queue_2, - pass_job_queue=True, pass_update_queue=True) + handler = StringRegexHandler( + 'test', self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_successfulpayment.py b/tests/test_successfulpayment.py index 6c2a2d099..843f3b716 100644 --- a/tests/test_successfulpayment.py +++ b/tests/test_successfulpayment.py @@ -24,13 +24,15 @@ from telegram import OrderInfo, SuccessfulPayment @pytest.fixture(scope='class') def successful_payment(): - return SuccessfulPayment(TestSuccessfulPayment.currency, - TestSuccessfulPayment.total_amount, - TestSuccessfulPayment.invoice_payload, - TestSuccessfulPayment.telegram_payment_charge_id, - TestSuccessfulPayment.provider_payment_charge_id, - shipping_option_id=TestSuccessfulPayment.shipping_option_id, - order_info=TestSuccessfulPayment.order_info) + return SuccessfulPayment( + TestSuccessfulPayment.currency, + TestSuccessfulPayment.total_amount, + TestSuccessfulPayment.invoice_payload, + TestSuccessfulPayment.telegram_payment_charge_id, + TestSuccessfulPayment.provider_payment_charge_id, + shipping_option_id=TestSuccessfulPayment.shipping_option_id, + order_info=TestSuccessfulPayment.order_info, + ) class TestSuccessfulPayment: @@ -50,7 +52,7 @@ class TestSuccessfulPayment: 'total_amount': self.total_amount, 'order_info': self.order_info.to_dict(), 'telegram_payment_charge_id': self.telegram_payment_charge_id, - 'provider_payment_charge_id': self.provider_payment_charge_id + 'provider_payment_charge_id': self.provider_payment_charge_id, } successful_payment = SuccessfulPayment.de_json(json_dict, bot) @@ -66,26 +68,45 @@ class TestSuccessfulPayment: assert isinstance(successful_payment_dict, dict) assert successful_payment_dict['invoice_payload'] == successful_payment.invoice_payload - assert (successful_payment_dict['shipping_option_id'] - == successful_payment.shipping_option_id) + assert ( + successful_payment_dict['shipping_option_id'] == successful_payment.shipping_option_id + ) assert successful_payment_dict['currency'] == successful_payment.currency assert successful_payment_dict['order_info'] == successful_payment.order_info.to_dict() - assert (successful_payment_dict['telegram_payment_charge_id'] - == successful_payment.telegram_payment_charge_id) - assert (successful_payment_dict['provider_payment_charge_id'] - == successful_payment.provider_payment_charge_id) + assert ( + successful_payment_dict['telegram_payment_charge_id'] + == successful_payment.telegram_payment_charge_id + ) + assert ( + successful_payment_dict['provider_payment_charge_id'] + == successful_payment.provider_payment_charge_id + ) def test_equality(self): - a = SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, - self.telegram_payment_charge_id, - self.provider_payment_charge_id) - b = SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, - self.telegram_payment_charge_id, - self.provider_payment_charge_id) - c = SuccessfulPayment('', 0, '', self.telegram_payment_charge_id, - self.provider_payment_charge_id) - d = SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, - self.telegram_payment_charge_id, '') + a = SuccessfulPayment( + self.currency, + self.total_amount, + self.invoice_payload, + self.telegram_payment_charge_id, + self.provider_payment_charge_id, + ) + b = SuccessfulPayment( + self.currency, + self.total_amount, + self.invoice_payload, + self.telegram_payment_charge_id, + self.provider_payment_charge_id, + ) + c = SuccessfulPayment( + '', 0, '', self.telegram_payment_charge_id, self.provider_payment_charge_id + ) + d = SuccessfulPayment( + self.currency, + self.total_amount, + self.invoice_payload, + self.telegram_payment_charge_id, + '', + ) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_typehandler.py b/tests/test_typehandler.py index 4b9c4e571..f8a746b7b 100644 --- a/tests/test_typehandler.py +++ b/tests/test_typehandler.py @@ -44,14 +44,16 @@ class TestTypeHandler: self.test_flag = (job_queue is not None) and (update_queue is not None) def callback_context(self, update, context): - self.test_flag = (isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, dict) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and context.user_data is None - and context.chat_data is None - and isinstance(context.bot_data, dict)) + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, dict) + and isinstance(context.update_queue, Queue) + and isinstance(context.job_queue, JobQueue) + and context.user_data is None + and context.chat_data is None + and isinstance(context.bot_data, dict) + ) def test_basic(self, dp): handler = TypeHandler(dict, self.callback_basic) @@ -76,8 +78,7 @@ class TestTypeHandler: assert self.test_flag dp.remove_handler(handler) - handler = TypeHandler(dict, self.callback_queue_1, - pass_update_queue=True) + handler = TypeHandler(dict, self.callback_queue_1, pass_update_queue=True) dp.add_handler(handler) self.test_flag = False @@ -85,8 +86,9 @@ class TestTypeHandler: assert self.test_flag dp.remove_handler(handler) - handler = TypeHandler(dict, self.callback_queue_2, pass_job_queue=True, - pass_update_queue=True) + handler = TypeHandler( + dict, self.callback_queue_2, pass_job_queue=True, pass_update_queue=True + ) dp.add_handler(handler) self.test_flag = False diff --git a/tests/test_update.py b/tests/test_update.py index 2b69b4db7..b247ae051 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -19,8 +19,19 @@ import pytest -from telegram import (Message, User, Update, Chat, CallbackQuery, InlineQuery, - ChosenInlineResult, ShippingQuery, PreCheckoutQuery, Poll, PollOption) +from telegram import ( + Message, + User, + Update, + Chat, + CallbackQuery, + InlineQuery, + ChosenInlineResult, + ShippingQuery, + PreCheckoutQuery, + Poll, + PollOption, +) from telegram.poll import PollAnswer message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') @@ -37,12 +48,22 @@ params = [ {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, {'poll': Poll('id', '?', [PollOption('.', 1)], False, False, False, Poll.REGULAR, True)}, - {'poll_answer': PollAnswer("id", User(1, '', False), [1])} + {'poll_answer': PollAnswer("id", User(1, '', False), [1])}, ] -all_types = ('message', 'edited_message', 'callback_query', 'channel_post', - 'edited_channel_post', 'inline_query', 'chosen_inline_result', - 'shipping_query', 'pre_checkout_query', 'poll', 'poll_answer') +all_types = ( + 'message', + 'edited_message', + 'callback_query', + 'channel_post', + 'edited_channel_post', + 'inline_query', + 'chosen_inline_result', + 'shipping_query', + 'pre_checkout_query', + 'poll', + 'poll_answer', +) ids = all_types + ('callback_query_without_message',) @@ -89,14 +110,15 @@ class TestUpdate: def test_effective_chat(self, update): # Test that it's sometimes None per docstring chat = update.effective_chat - if not (update.inline_query is not None - or update.chosen_inline_result is not None - or (update.callback_query is not None - and update.callback_query.message is None) - or update.shipping_query is not None - or update.pre_checkout_query is not None - or update.poll is not None - or update.poll_answer is not None): + if not ( + update.inline_query is not None + or update.chosen_inline_result is not None + or (update.callback_query is not None and update.callback_query.message is None) + or update.shipping_query is not None + or update.pre_checkout_query is not None + or update.poll is not None + or update.poll_answer is not None + ): assert chat.id == 1 else: assert chat is None @@ -104,9 +126,11 @@ class TestUpdate: def test_effective_user(self, update): # Test that it's sometimes None per docstring user = update.effective_user - if not (update.channel_post is not None - or update.edited_channel_post is not None - or update.poll is not None): + if not ( + update.channel_post is not None + or update.edited_channel_post is not None + or update.poll is not None + ): assert user.id == 1 else: assert user is None @@ -114,14 +138,15 @@ class TestUpdate: def test_effective_message(self, update): # Test that it's sometimes None per docstring eff_message = update.effective_message - if not (update.inline_query is not None - or update.chosen_inline_result is not None - or (update.callback_query is not None - and update.callback_query.message is None) - or update.shipping_query is not None - or update.pre_checkout_query is not None - or update.poll is not None - or update.poll_answer is not None): + if not ( + update.inline_query is not None + or update.chosen_inline_result is not None + or (update.callback_query is not None and update.callback_query.message is None) + or update.shipping_query is not None + or update.pre_checkout_query is not None + or update.poll is not None + or update.poll_answer is not None + ): assert eff_message.message_id == message.message_id else: assert eff_message is None diff --git a/tests/test_updater.py b/tests/test_updater.py index b484c802f..138752663 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -42,9 +42,10 @@ from telegram.ext import Updater, Dispatcher, DictPersistence, Defaults from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.utils.webhookhandler import WebhookServer -signalskip = pytest.mark.skipif(sys.platform == 'win32', - reason='Can\'t send signals without stopping ' - 'whole process on windows') +signalskip = pytest.mark.skipif( + sys.platform == 'win32', + reason='Can\'t send signals without stopping ' 'whole process on windows', +) ASYNCIO_LOCK = threading.Lock() @@ -88,10 +89,11 @@ class TestUpdater: self.received = update.message.text self.cb_handler_called.set() - @pytest.mark.parametrize(('error',), - argvalues=[(TelegramError('Test Error 2'),), - (Unauthorized('Test Unauthorized'),)], - ids=('TelegramError', 'Unauthorized')) + @pytest.mark.parametrize( + ('error',), + argvalues=[(TelegramError('Test Error 2'),), (Unauthorized('Test Unauthorized'),)], + ids=('TelegramError', 'Unauthorized'), + ) def test_get_updates_normal_err(self, monkeypatch, updater, error): def test(*args, **kwargs): raise error @@ -129,14 +131,16 @@ class TestUpdater: # an unhandled exception. # TODO: We should have a way to poll Updater status and decide if it's running or not. import pprint - pprint.pprint([rec.getMessage() for rec in caplog.get_records('call')]) - assert any('unhandled exception in Bot:{}:updater'.format(updater.bot.id) in - rec.getMessage() for rec in caplog.get_records('call')) - @pytest.mark.parametrize(('error',), - argvalues=[(RetryAfter(0.01),), - (TimedOut(),)], - ids=('RetryAfter', 'TimedOut')) + pprint.pprint([rec.getMessage() for rec in caplog.get_records('call')]) + assert any( + 'unhandled exception in Bot:{}:updater'.format(updater.bot.id) in rec.getMessage() + for rec in caplog.get_records('call') + ) + + @pytest.mark.parametrize( + ('error',), argvalues=[(RetryAfter(0.01),), (TimedOut(),)], ids=('RetryAfter', 'TimedOut') + ) def test_get_updates_retries(self, monkeypatch, updater, error): event = Event() @@ -167,17 +171,18 @@ class TestUpdater: ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port - updater.start_webhook( - ip, - port, - url_path='TOKEN') - sleep(.2) + updater.start_webhook(ip, port, url_path='TOKEN') + sleep(0.2) try: # Now, we send an update to the server via urlopen - update = Update(1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), - text='Webhook')) + update = Update( + 1, + message=Message( + 1, None, Chat(1, ''), from_user=User(1, '', False), text='Webhook' + ), + ) self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN') - sleep(.2) + sleep(0.2) assert q.get(False) == update # Returns 404 if path is incorrect @@ -186,15 +191,16 @@ class TestUpdater: assert excinfo.value.code == 404 with pytest.raises(HTTPError) as excinfo: - self._send_webhook_msg(ip, port, None, 'webookhandler.py', - get_method=lambda: 'HEAD') + self._send_webhook_msg( + ip, port, None, 'webookhandler.py', get_method=lambda: 'HEAD' + ) assert excinfo.value.code == 404 # Test multiple shutdown() calls updater.httpd.shutdown() finally: updater.httpd.shutdown() - sleep(.2) + sleep(0.2) assert not updater.httpd.is_running updater.stop() @@ -212,8 +218,10 @@ class TestUpdater: updater.stop() assert not caplog.records - @pytest.mark.skipif(os.name != 'nt' or sys.version_info < (3, 8), - reason='Workaround only relevant on windows with py3.8+') + @pytest.mark.skipif( + os.name != 'nt' or sys.version_info < (3, 8), + reason='Workaround only relevant on windows with py3.8+', + ) def test_start_webhook_ensure_event_loop(self, updater, monkeypatch): def serve_forever(self, force_event_loop=False, ready=None): with self.server_lock: @@ -240,12 +248,15 @@ class TestUpdater: bootstrap_retries=0, clean=False, webhook_url=None, - allowed_updates=None) + allowed_updates=None, + ) assert isinstance(asyncio.get_event_loop(), asyncio.SelectorEventLoop) - @pytest.mark.skipif(os.name != 'nt' or sys.version_info < (3, 8), - reason='Workaround only relevant on windows with py3.8+') + @pytest.mark.skipif( + os.name != 'nt' or sys.version_info < (3, 8), + reason='Workaround only relevant on windows with py3.8+', + ) def test_start_webhook_force_event_loop_false(self, updater, monkeypatch): monkeypatch.setattr(updater.bot, 'set_webhook', lambda *args, **kwargs: True) monkeypatch.setattr(updater.bot, 'delete_webhook', lambda *args, **kwargs: True) @@ -264,10 +275,13 @@ class TestUpdater: bootstrap_retries=0, clean=False, webhook_url=None, - allowed_updates=None) + allowed_updates=None, + ) - @pytest.mark.skipif(os.name != 'nt' or sys.version_info < (3, 8), - reason='Workaround only relevant on windows with py3.8+') + @pytest.mark.skipif( + os.name != 'nt' or sys.version_info < (3, 8), + reason='Workaround only relevant on windows with py3.8+', + ) def test_start_webhook_force_event_loop_true(self, updater, monkeypatch): def serve_forever(self, force_event_loop=False, ready=None): with self.server_lock: @@ -295,7 +309,8 @@ class TestUpdater: clean=False, webhook_url=None, allowed_updates=None, - force_event_loop=True) + force_event_loop=True, + ) assert isinstance(asyncio.get_event_loop(), asyncio.ProactorEventLoop) def test_webhook_ssl(self, monkeypatch, updater): @@ -314,7 +329,8 @@ class TestUpdater: bootstrap_retries=0, clean=False, webhook_url=None, - allowed_updates=None) + allowed_updates=None, + ) except TelegramError: tg_err = True assert tg_err @@ -328,19 +344,19 @@ class TestUpdater: ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port updater.start_webhook(ip, port, webhook_url=None) - sleep(.2) + sleep(0.2) # Now, we send an update to the server via urlopen - update = Update(1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), - text='Webhook 2')) + update = Update( + 1, + message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Webhook 2'), + ) self._send_webhook_msg(ip, port, update.to_json()) - sleep(.2) + sleep(0.2) assert q.get(False) == update updater.stop() - @pytest.mark.parametrize(('error',), - argvalues=[(TelegramError(''),)], - ids=('TelegramError',)) + @pytest.mark.parametrize(('error',), argvalues=[(TelegramError(''),)], ids=('TelegramError',)) def test_bootstrap_retries_success(self, monkeypatch, updater, error): retries = 2 @@ -355,11 +371,11 @@ class TestUpdater: updater._bootstrap(retries, False, 'path', None, bootstrap_interval=0) assert self.attempts == retries - @pytest.mark.parametrize(('error', 'attempts'), - argvalues=[(TelegramError(''), 2), - (Unauthorized(''), 1), - (InvalidToken(), 1)], - ids=('TelegramError', 'Unauthorized', 'InvalidToken')) + @pytest.mark.parametrize( + ('error', 'attempts'), + argvalues=[(TelegramError(''), 2), (Unauthorized(''), 1), (InvalidToken(), 1)], + ids=('TelegramError', 'Unauthorized', 'InvalidToken'), + ) def test_bootstrap_retries_error(self, monkeypatch, updater, error, attempts): retries = 1 @@ -392,7 +408,7 @@ class TestUpdater: self.offset = int(args[0]) return [] - class FakeUpdate(): + class FakeUpdate: def __init__(self, update_id): self.update_id = update_id @@ -415,16 +431,17 @@ class TestUpdater: ip = '127.0.0.1' port = randrange(1024, 49152) # select random port for travis thr = Thread( - target=updater._start_webhook, - args=(ip, port, '', None, None, 0, False, None, None)) + target=updater._start_webhook, args=(ip, port, '', None, None, 0, False, None, None) + ) thr.start() - sleep(.2) + sleep(0.2) try: with pytest.raises(HTTPError) as excinfo: - self._send_webhook_msg(ip, port, 'data', - content_type='application/xml') + self._send_webhook_msg( + ip, port, 'data', content_type='application/xml' + ) assert excinfo.value.code == 403 with pytest.raises(HTTPError) as excinfo: @@ -444,15 +461,19 @@ class TestUpdater: updater.httpd.shutdown() thr.join() - def _send_webhook_msg(self, - ip, - port, - payload_str, - url_path='', - content_len=-1, - content_type='application/json', - get_method=None): - headers = {'content-type': content_type, } + def _send_webhook_msg( + self, + ip, + port, + payload_str, + url_path='', + content_len=-1, + content_type='application/json', + get_method=None, + ): + headers = { + 'content-type': content_type, + } if not payload_str: content_len = None @@ -499,7 +520,7 @@ class TestUpdater: assert rec.levelname == 'INFO' # If we get this far, idle() ran through - sleep(.5) + sleep(0.5) assert updater.running is False @signalskip @@ -514,7 +535,7 @@ class TestUpdater: Thread(target=partial(self.signal_sender, updater=updater)).start() updater.idle() # If we get this far, idle() ran through - sleep(.5) + sleep(0.5) assert updater.running is False assert temp_var['a'] != 0 diff --git a/tests/test_user.py b/tests/test_user.py index b9df8c3f2..44bffe977 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -33,17 +33,24 @@ def json_dict(): 'language_code': TestUser.language_code, 'can_join_groups': TestUser.can_join_groups, 'can_read_all_group_messages': TestUser.can_read_all_group_messages, - 'supports_inline_queries': TestUser.supports_inline_queries + 'supports_inline_queries': TestUser.supports_inline_queries, } @pytest.fixture(scope='function') def user(bot): - return User(id=TestUser.id_, first_name=TestUser.first_name, is_bot=TestUser.is_bot, - last_name=TestUser.last_name, username=TestUser.username, - language_code=TestUser.language_code, can_join_groups=TestUser.can_join_groups, - can_read_all_group_messages=TestUser.can_read_all_group_messages, - supports_inline_queries=TestUser.supports_inline_queries, bot=bot) + return User( + id=TestUser.id_, + first_name=TestUser.first_name, + is_bot=TestUser.is_bot, + last_name=TestUser.last_name, + username=TestUser.username, + language_code=TestUser.language_code, + can_join_groups=TestUser.can_join_groups, + can_read_all_group_messages=TestUser.can_read_all_group_messages, + supports_inline_queries=TestUser.supports_inline_queries, + bot=bot, + ) class TestUser: @@ -257,16 +264,18 @@ class TestUser: expected = u'{}' assert user.mention_html() == expected.format(user.id, user.full_name) - assert user.mention_html('thename\u2022') == expected.format(user.id, - 'the<b>name\u2022') + assert user.mention_html('thename\u2022') == expected.format( + user.id, 'the<b>name\u2022' + ) assert user.mention_html(user.username) == expected.format(user.id, user.username) def test_mention_markdown(self, user): expected = u'[{}](tg://user?id={})' assert user.mention_markdown() == expected.format(user.full_name, user.id) - assert user.mention_markdown('the_name*\u2022') == expected.format('the\\_name\\*\u2022', - user.id) + assert user.mention_markdown('the_name*\u2022') == expected.format( + 'the\\_name\\*\u2022', user.id + ) assert user.mention_markdown(user.username) == expected.format(user.username, user.id) def test_mention_markdown_v2(self, user): @@ -275,10 +284,12 @@ class TestUser: expected = u'[{}](tg://user?id={})' - assert user.mention_markdown_v2() == expected.format(escape_markdown(user.full_name, - version=2), user.id) + assert user.mention_markdown_v2() == expected.format( + escape_markdown(user.full_name, version=2), user.id + ) assert user.mention_markdown_v2('the{name>\u2022') == expected.format( - 'the\\{name\\>\u2022', user.id) + 'the\\{name\\>\u2022', user.id + ) assert user.mention_markdown_v2(user.username) == expected.format(user.username, user.id) def test_equality(self): diff --git a/tests/test_userprofilephotos.py b/tests/test_userprofilephotos.py index ea1aef237..2a3d0de07 100644 --- a/tests/test_userprofilephotos.py +++ b/tests/test_userprofilephotos.py @@ -24,19 +24,16 @@ class TestUserProfilePhotos: photos = [ [ PhotoSize('file_id1', 'file_un_id1', 512, 512), - PhotoSize('file_id2', 'file_un_id1', 512, 512) + PhotoSize('file_id2', 'file_un_id1', 512, 512), ], [ PhotoSize('file_id3', 'file_un_id3', 512, 512), - PhotoSize('file_id4', 'file_un_id4', 512, 512) - ] + PhotoSize('file_id4', 'file_un_id4', 512, 512), + ], ] def test_de_json(self, bot): - json_dict = { - 'total_count': 2, - 'photos': [[y.to_dict() for y in x] for x in self.photos] - } + json_dict = {'total_count': 2, 'photos': [[y.to_dict() for y in x] for x in self.photos]} user_profile_photos = UserProfilePhotos.de_json(json_dict, bot) assert user_profile_photos.total_count == self.total_count assert user_profile_photos.photos == self.photos diff --git a/tests/test_venue.py b/tests/test_venue.py index 965d4f354..e0098fcf8 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -24,11 +24,13 @@ from telegram import Location, Venue @pytest.fixture(scope='class') def venue(): - return Venue(TestVenue.location, - TestVenue.title, - TestVenue.address, - foursquare_id=TestVenue.foursquare_id, - foursquare_type=TestVenue.foursquare_type) + return Venue( + TestVenue.location, + TestVenue.title, + TestVenue.address, + foursquare_id=TestVenue.foursquare_id, + foursquare_type=TestVenue.foursquare_type, + ) class TestVenue: @@ -44,7 +46,7 @@ class TestVenue: 'title': TestVenue.title, 'address': TestVenue.address, 'foursquare_id': TestVenue.foursquare_id, - 'foursquare_type': TestVenue.foursquare_type + 'foursquare_type': TestVenue.foursquare_type, } venue = Venue.de_json(json_dict, bot) @@ -56,12 +58,14 @@ class TestVenue: def test_send_with_venue(self, monkeypatch, bot, chat_id, venue): def test(url, data, **kwargs): - return (data['longitude'] == self.location.longitude - and data['latitude'] == self.location.latitude - and data['title'] == self.title - and data['address'] == self.address - and data['foursquare_id'] == self.foursquare_id - and data['foursquare_type'] == self.foursquare_type) + return ( + data['longitude'] == self.location.longitude + and data['latitude'] == self.location.latitude + and data['title'] == self.title + and data['address'] == self.address + and data['foursquare_id'] == self.foursquare_id + and data['foursquare_type'] == self.foursquare_type + ) monkeypatch.setattr(bot.request, 'post', test) message = bot.send_venue(chat_id, venue=venue) diff --git a/tests/test_video.py b/tests/test_video.py index 0a7653c75..6848fc84b 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -80,10 +80,18 @@ class TestVideo: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): - message = bot.send_video(chat_id, video_file, duration=self.duration, - caption=self.caption, supports_streaming=self.supports_streaming, - disable_notification=False, width=video.width, - height=video.height, parse_mode='Markdown', thumb=thumb_file) + message = bot.send_video( + chat_id, + video_file, + duration=self.duration, + caption=self.caption, + supports_streaming=self.supports_streaming, + disable_notification=False, + width=video.width, + height=video.height, + parse_mode='Markdown', + thumb=thumb_file, + ) assert isinstance(message.video, Video) assert isinstance(message.video.file_id, str) @@ -173,8 +181,9 @@ class TestVideo: def test_send_video_default_parse_mode_2(self, default_bot, chat_id, video): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_video(chat_id, video, caption=test_markdown_string, - parse_mode=None) + message = default_bot.send_video( + chat_id, video, caption=test_markdown_string, parse_mode=None + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -184,8 +193,9 @@ class TestVideo: def test_send_video_default_parse_mode_3(self, default_bot, chat_id, video): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_video(chat_id, video, caption=test_markdown_string, - parse_mode='HTML') + message = default_bot.send_video( + chat_id, video, caption=test_markdown_string, parse_mode='HTML' + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -197,7 +207,7 @@ class TestVideo: 'height': self.height, 'duration': self.duration, 'mime_type': self.mime_type, - 'file_size': self.file_size + 'file_size': self.file_size, } json_video = Video.de_json(json_dict, bot) diff --git a/tests/test_videonote.py b/tests/test_videonote.py index 5118145fd..49431f2a1 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -72,9 +72,14 @@ class TestVideoNote: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_all_args(self, bot, chat_id, video_note_file, video_note, thumb_file): - message = bot.send_video_note(chat_id, video_note_file, duration=self.duration, - length=self.length, disable_notification=False, - thumb=thumb_file) + message = bot.send_video_note( + chat_id, + video_note_file, + duration=self.duration, + length=self.length, + disable_notification=False, + thumb=thumb_file, + ) assert isinstance(message.video_note, VideoNote) assert isinstance(message.video_note.file_id, str) @@ -124,7 +129,7 @@ class TestVideoNote: 'file_unique_id': self.videonote_file_unique_id, 'length': self.length, 'duration': self.duration, - 'file_size': self.file_size + 'file_size': self.file_size, } json_video_note = VideoNote.de_json(json_dict, bot) diff --git a/tests/test_voice.py b/tests/test_voice.py index 6d5a26fa8..396284331 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -65,9 +65,14 @@ class TestVoice: @flaky(3, 1) @pytest.mark.timeout(10) def test_send_all_args(self, bot, chat_id, voice_file, voice): - message = bot.send_voice(chat_id, voice_file, duration=self.duration, - caption=self.caption, disable_notification=False, - parse_mode='Markdown') + message = bot.send_voice( + chat_id, + voice_file, + duration=self.duration, + caption=self.caption, + disable_notification=False, + parse_mode='Markdown', + ) assert isinstance(message.voice, Voice) assert isinstance(message.voice.file_id, str) @@ -139,8 +144,9 @@ class TestVoice: def test_send_voice_default_parse_mode_2(self, default_bot, chat_id, voice): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_voice(chat_id, voice, caption=test_markdown_string, - parse_mode=None) + message = default_bot.send_voice( + chat_id, voice, caption=test_markdown_string, parse_mode=None + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -150,8 +156,9 @@ class TestVoice: def test_send_voice_default_parse_mode_3(self, default_bot, chat_id, voice): test_markdown_string = '_Italic_ *Bold* `Code`' - message = default_bot.send_voice(chat_id, voice, caption=test_markdown_string, - parse_mode='HTML') + message = default_bot.send_voice( + chat_id, voice, caption=test_markdown_string, parse_mode='HTML' + ) assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) @@ -162,7 +169,7 @@ class TestVoice: 'duration': self.duration, 'caption': self.caption, 'mime_type': self.mime_type, - 'file_size': self.file_size + 'file_size': self.file_size, } json_voice = Voice.de_json(json_dict, bot)