mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-11-21 22:56:38 +01:00
Revert "Revert "Context based callbacks (#1100)""
This reverts commit f8a17cd
This commit is contained in:
parent
439790375e
commit
cf95027308
45 changed files with 1404 additions and 630 deletions
19
CHANGES.rst
19
CHANGES.rst
|
@ -2,6 +2,25 @@
|
|||
Changes
|
||||
=======
|
||||
|
||||
**2018-??-??**
|
||||
*Released 11.0.0*
|
||||
|
||||
Context based callbacks:
|
||||
See https://git.io/vp113 for help.
|
||||
|
||||
- Use of `pass_` in handlers is deprecated.
|
||||
- Instead use `use_context=True` on `Updater` or `Dispatcher` and change callback from (bot, update, others...) to (update, context).
|
||||
- This also applies to error handlers `Dispatcher.add_error_handler` and JobQueue jobs (change (bot, job) to (context) here).
|
||||
- For users with custom handlers subclassing Handler, this is mostly backwards compatible, but to use the new context based callbacks you need to implement the new collect_additional_context method.
|
||||
- Passing bot to JobQueue.__init__ is deprecated. Use JobQueue.set_dispatcher with a dispatcher instead.
|
||||
|
||||
Other:
|
||||
- Handlers should be faster due to deduped logic.
|
||||
|
||||
Other removals:
|
||||
- Remove the ability to use filter lists in handlers.
|
||||
- Remove the last CamelCase CheckUpdate methods from the handlers we missed earlier.
|
||||
|
||||
**2018-09-01**
|
||||
*Released 11.1.0*
|
||||
|
||||
|
|
5
docs/source/telegram.ext.callbackcontext.rst
Normal file
5
docs/source/telegram.ext.callbackcontext.rst
Normal file
|
@ -0,0 +1,5 @@
|
|||
telegram.ext.CallbackContext
|
||||
============================
|
||||
|
||||
.. autoclass:: telegram.ext.CallbackContext
|
||||
:members:
|
|
@ -10,6 +10,7 @@ telegram.ext package
|
|||
telegram.ext.jobqueue
|
||||
telegram.ext.messagequeue
|
||||
telegram.ext.delayqueue
|
||||
telegram.ext.callbackcontext
|
||||
|
||||
Handlers
|
||||
--------
|
||||
|
|
|
@ -17,12 +17,12 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
|||
bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove)
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
|
||||
ConversationHandler)
|
||||
|
||||
import logging
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
|
@ -32,7 +32,7 @@ logger = logging.getLogger(__name__)
|
|||
GENDER, PHOTO, LOCATION, BIO = range(4)
|
||||
|
||||
|
||||
def start(bot, update):
|
||||
def start(update, context):
|
||||
reply_keyboard = [['Boy', 'Girl', 'Other']]
|
||||
|
||||
update.message.reply_text(
|
||||
|
@ -44,7 +44,7 @@ def start(bot, update):
|
|||
return GENDER
|
||||
|
||||
|
||||
def gender(bot, update):
|
||||
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, '
|
||||
|
@ -54,9 +54,9 @@ def gender(bot, update):
|
|||
return PHOTO
|
||||
|
||||
|
||||
def photo(bot, update):
|
||||
def photo(update, context):
|
||||
user = update.message.from_user
|
||||
photo_file = bot.get_file(update.message.photo[-1].file_id)
|
||||
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, '
|
||||
|
@ -65,7 +65,7 @@ def photo(bot, update):
|
|||
return LOCATION
|
||||
|
||||
|
||||
def skip_photo(bot, update):
|
||||
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, '
|
||||
|
@ -74,7 +74,7 @@ def skip_photo(bot, update):
|
|||
return LOCATION
|
||||
|
||||
|
||||
def location(bot, update):
|
||||
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,
|
||||
|
@ -85,7 +85,7 @@ def location(bot, update):
|
|||
return BIO
|
||||
|
||||
|
||||
def skip_location(bot, update):
|
||||
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! '
|
||||
|
@ -94,7 +94,7 @@ def skip_location(bot, update):
|
|||
return BIO
|
||||
|
||||
|
||||
def bio(bot, update):
|
||||
def bio(update, context):
|
||||
user = update.message.from_user
|
||||
logger.info("Bio of %s: %s", user.first_name, update.message.text)
|
||||
update.message.reply_text('Thank you! I hope we can talk again some day.')
|
||||
|
@ -102,7 +102,7 @@ def bio(bot, update):
|
|||
return ConversationHandler.END
|
||||
|
||||
|
||||
def cancel(bot, update):
|
||||
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.',
|
||||
|
@ -111,14 +111,16 @@ def cancel(bot, update):
|
|||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the EventHandler and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
|
|
@ -17,12 +17,12 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
|||
bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import ReplyKeyboardMarkup
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
|
||||
ConversationHandler)
|
||||
|
||||
import logging
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
|
@ -46,7 +46,7 @@ def facts_to_str(user_data):
|
|||
return "\n".join(facts).join(['\n', '\n'])
|
||||
|
||||
|
||||
def start(bot, update):
|
||||
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?",
|
||||
|
@ -55,23 +55,24 @@ def start(bot, update):
|
|||
return CHOOSING
|
||||
|
||||
|
||||
def regular_choice(bot, update, user_data):
|
||||
def regular_choice(update, context):
|
||||
text = update.message.text
|
||||
user_data['choice'] = text
|
||||
context.user_data['choice'] = text
|
||||
update.message.reply_text(
|
||||
'Your {}? Yes, I would love to hear about that!'.format(text.lower()))
|
||||
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
def custom_choice(bot, update):
|
||||
def custom_choice(update, context):
|
||||
update.message.reply_text('Alright, please send me the category first, '
|
||||
'for example "Most impressive skill"')
|
||||
|
||||
return TYPING_CHOICE
|
||||
|
||||
|
||||
def received_information(bot, update, user_data):
|
||||
def received_information(update, context):
|
||||
user_data = context.user_data
|
||||
text = update.message.text
|
||||
category = user_data['choice']
|
||||
user_data[category] = text
|
||||
|
@ -85,7 +86,8 @@ def received_information(bot, update, user_data):
|
|||
return CHOOSING
|
||||
|
||||
|
||||
def done(bot, update, user_data):
|
||||
def done(update, context):
|
||||
user_data = context.user_data
|
||||
if 'choice' in user_data:
|
||||
del user_data['choice']
|
||||
|
||||
|
@ -97,14 +99,16 @@ def done(bot, update, user_data):
|
|||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
|
|
@ -17,9 +17,10 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
|||
bot.
|
||||
"""
|
||||
|
||||
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
|
||||
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)
|
||||
|
@ -29,30 +30,32 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
# Define a few command handlers. These usually take the two arguments bot and
|
||||
# update. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(bot, update):
|
||||
def start(update, context):
|
||||
"""Send a message when the command /start is issued."""
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help(bot, update):
|
||||
def help(update, context):
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
|
||||
def echo(bot, update):
|
||||
def echo(update, context):
|
||||
"""Echo the user message."""
|
||||
update.message.reply_text(update.message.text)
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
"""Start the bot."""
|
||||
# Create the EventHandler and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
|
|
@ -16,14 +16,13 @@ Basic inline bot example. Applies different text transformations.
|
|||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
import logging
|
||||
from uuid import uuid4
|
||||
|
||||
from telegram.utils.helpers import escape_markdown
|
||||
|
||||
from telegram import InlineQueryResultArticle, ParseMode, \
|
||||
InputTextMessageContent
|
||||
from telegram.ext import Updater, InlineQueryHandler, CommandHandler
|
||||
import logging
|
||||
from telegram.utils.helpers import escape_markdown
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
|
@ -34,17 +33,17 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
# Define a few command handlers. These usually take the two arguments bot and
|
||||
# update. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(bot, update):
|
||||
def start(update, context):
|
||||
"""Send a message when the command /start is issued."""
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help(bot, update):
|
||||
def help(update, context):
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
|
||||
def inlinequery(bot, update):
|
||||
def inlinequery(update, context):
|
||||
"""Handle the inline query."""
|
||||
query = update.inline_query.query
|
||||
results = [
|
||||
|
@ -69,14 +68,16 @@ def inlinequery(bot, update):
|
|||
update.inline_query.answer(results)
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
|
||||
|
||||
|
@ -13,7 +14,7 @@ logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def start(bot, update):
|
||||
def start(update, context):
|
||||
keyboard = [[InlineKeyboardButton("Option 1", callback_data='1'),
|
||||
InlineKeyboardButton("Option 2", callback_data='2')],
|
||||
|
||||
|
@ -24,26 +25,26 @@ def start(bot, update):
|
|||
update.message.reply_text('Please choose:', reply_markup=reply_markup)
|
||||
|
||||
|
||||
def button(bot, update):
|
||||
def button(update, context):
|
||||
query = update.callback_query
|
||||
|
||||
bot.edit_message_text(text="Selected option: {}".format(query.data),
|
||||
chat_id=query.message.chat_id,
|
||||
message_id=query.message.message_id)
|
||||
query.edit_message_text(text="Selected option: {}".format(query.data))
|
||||
|
||||
|
||||
def help(bot, update):
|
||||
def help(update, context):
|
||||
update.message.reply_text("Use /start to test this bot.")
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
|
||||
updater.dispatcher.add_handler(CommandHandler('start', start))
|
||||
updater.dispatcher.add_handler(CallbackQueryHandler(button))
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import (LabeledPrice, ShippingOption)
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler,
|
||||
Filters, PreCheckoutQueryHandler, ShippingQueryHandler)
|
||||
import logging
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
|
@ -18,18 +19,18 @@ logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def start_callback(bot, update):
|
||||
def start_callback(update, context):
|
||||
msg = "Use /shipping to get an invoice for shipping-payment, "
|
||||
msg += "or /noshipping for an invoice without shipping."
|
||||
update.message.reply_text(msg)
|
||||
|
||||
|
||||
def start_with_shipping_callback(bot, update):
|
||||
def start_with_shipping_callback(update, context):
|
||||
chat_id = update.message.chat_id
|
||||
title = "Payment Example"
|
||||
description = "Payment Example using python-telegram-bot"
|
||||
|
@ -47,13 +48,13 @@ def start_with_shipping_callback(bot, update):
|
|||
|
||||
# optionally pass need_name=True, need_phone_number=True,
|
||||
# need_email=True, need_shipping_address=True, is_flexible=True
|
||||
bot.sendInvoice(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(bot, update):
|
||||
def start_without_shipping_callback(update, context):
|
||||
chat_id = update.message.chat_id
|
||||
title = "Payment Example"
|
||||
description = "Payment Example using python-telegram-bot"
|
||||
|
@ -70,17 +71,16 @@ def start_without_shipping_callback(bot, update):
|
|||
|
||||
# optionally pass need_name=True, need_phone_number=True,
|
||||
# need_email=True, need_shipping_address=True, is_flexible=True
|
||||
bot.sendInvoice(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(bot, update):
|
||||
def shipping_callback(update, context):
|
||||
query = update.shipping_query
|
||||
# check the payload, is this from your bot?
|
||||
if query.invoice_payload != 'Custom-Payload':
|
||||
# answer False pre_checkout_query
|
||||
bot.answer_shipping_query(shipping_query_id=query.id, ok=False,
|
||||
error_message="Something went wrong...")
|
||||
query.answer(ok=False, error_message="Something went wrong...")
|
||||
return
|
||||
else:
|
||||
options = list()
|
||||
|
@ -89,31 +89,31 @@ def shipping_callback(bot, update):
|
|||
# an array of LabeledPrice objects
|
||||
price_list = [LabeledPrice('B1', 150), LabeledPrice('B2', 200)]
|
||||
options.append(ShippingOption('2', 'Shipping Option B', price_list))
|
||||
bot.answer_shipping_query(shipping_query_id=query.id, ok=True,
|
||||
shipping_options=options)
|
||||
query.answer(ok=True, shipping_options=options)
|
||||
|
||||
|
||||
# after (optional) shipping, it's the pre-checkout
|
||||
def precheckout_callback(bot, update):
|
||||
def precheckout_callback(update, context):
|
||||
query = update.pre_checkout_query
|
||||
# check the payload, is this from your bot?
|
||||
if query.invoice_payload != 'Custom-Payload':
|
||||
# answer False pre_checkout_query
|
||||
bot.answer_pre_checkout_query(pre_checkout_query_id=query.id, ok=False,
|
||||
error_message="Something went wrong...")
|
||||
query.answer(ok=False, error_message="Something went wrong...")
|
||||
else:
|
||||
bot.answer_pre_checkout_query(pre_checkout_query_id=query.id, ok=True)
|
||||
query.answer(ok=True)
|
||||
|
||||
|
||||
# finally, after contacting to the payment provider...
|
||||
def successful_payment_callback(bot, update):
|
||||
def successful_payment_callback(update, context):
|
||||
# do something after successful receive of payment?
|
||||
update.message.reply_text("Thank you for your payment!")
|
||||
|
||||
|
||||
def main():
|
||||
# Create the EventHandler and pass it your bot's token.
|
||||
updater = Updater(token="BOT_TOKEN")
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
|
|
@ -19,9 +19,10 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
|||
bot.
|
||||
"""
|
||||
|
||||
from telegram.ext import Updater, CommandHandler
|
||||
import logging
|
||||
|
||||
from telegram.ext import Updater, CommandHandler
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
|
@ -31,28 +32,29 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
# Define a few command handlers. These usually take the two arguments bot and
|
||||
# update. Error handlers also receive the raised TelegramError object in error.
|
||||
def start(bot, update):
|
||||
def start(update, context):
|
||||
update.message.reply_text('Hi! Use /set <seconds> to set a timer')
|
||||
|
||||
|
||||
def alarm(bot, job):
|
||||
def alarm(context):
|
||||
"""Send the alarm message."""
|
||||
bot.send_message(job.context, text='Beep!')
|
||||
job = context.job
|
||||
context.bot.send_message(job.context, text='Beep!')
|
||||
|
||||
|
||||
def set_timer(bot, update, args, job_queue, chat_data):
|
||||
def set_timer(update, context):
|
||||
"""Add a job to the queue."""
|
||||
chat_id = update.message.chat_id
|
||||
try:
|
||||
# args[0] should contain the time for the timer in seconds
|
||||
due = int(args[0])
|
||||
due = int(context.args[0])
|
||||
if due < 0:
|
||||
update.message.reply_text('Sorry we can not go back to future!')
|
||||
return
|
||||
|
||||
# Add job to queue
|
||||
job = job_queue.run_once(alarm, due, context=chat_id)
|
||||
chat_data['job'] = job
|
||||
job = context.job_queue.run_once(alarm, due, context=chat_id)
|
||||
context.chat_data['job'] = job
|
||||
|
||||
update.message.reply_text('Timer successfully set!')
|
||||
|
||||
|
@ -60,27 +62,30 @@ def set_timer(bot, update, args, job_queue, chat_data):
|
|||
update.message.reply_text('Usage: /set <seconds>')
|
||||
|
||||
|
||||
def unset(bot, update, chat_data):
|
||||
def unset(update, context):
|
||||
"""Remove the job if the user changed their mind."""
|
||||
if 'job' not in chat_data:
|
||||
if 'job' not in context.chat_data:
|
||||
update.message.reply_text('You have no active timer')
|
||||
return
|
||||
|
||||
job = chat_data['job']
|
||||
job = context.chat_data['job']
|
||||
job.schedule_removal()
|
||||
del chat_data['job']
|
||||
del context.chat_data['job']
|
||||
|
||||
update.message.reply_text('Timer successfully unset!')
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
def error(update, context):
|
||||
"""Log Errors caused by Updates."""
|
||||
logger.warning('Update "%s" caused error "%s"', update, error)
|
||||
logger.warning('Update "%s" caused error "%s"', update, context.error)
|
||||
|
||||
|
||||
def main():
|
||||
"""Run bot."""
|
||||
updater = Updater("TOKEN")
|
||||
# Create the Updater and pass it your bot's token.
|
||||
# Make sure to set use_context=True to use the new context based callbacks
|
||||
# Post version 12 this will no longer be necessary
|
||||
updater = Updater("TOKEN", use_context=True)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
|
|
@ -27,6 +27,7 @@ addopts = --no-success-flaky-report -rsxX
|
|||
filterwarnings =
|
||||
error
|
||||
ignore::DeprecationWarning
|
||||
ignore::telegram.utils.deprecate.TelegramDeprecationWarning
|
||||
|
||||
[coverage:run]
|
||||
branch = True
|
||||
|
|
|
@ -21,13 +21,14 @@
|
|||
from .basepersistence import BasePersistence
|
||||
from .picklepersistence import PicklePersistence
|
||||
from .dictpersistence import DictPersistence
|
||||
from .handler import Handler
|
||||
from .callbackcontext import CallbackContext
|
||||
from .dispatcher import Dispatcher, DispatcherHandlerStop, run_async
|
||||
from .jobqueue import JobQueue, Job
|
||||
from .updater import Updater
|
||||
from .callbackqueryhandler import CallbackQueryHandler
|
||||
from .choseninlineresulthandler import ChosenInlineResultHandler
|
||||
from .commandhandler import CommandHandler
|
||||
from .handler import Handler
|
||||
from .inlinequeryhandler import InlineQueryHandler
|
||||
from .messagehandler import MessageHandler
|
||||
from .filters import BaseFilter, Filters
|
||||
|
@ -46,5 +47,5 @@ __all__ = ('Dispatcher', 'JobQueue', 'Job', 'Updater', 'CallbackQueryHandler',
|
|||
'MessageHandler', 'BaseFilter', 'Filters', 'RegexHandler', 'StringCommandHandler',
|
||||
'StringRegexHandler', 'TypeHandler', 'ConversationHandler',
|
||||
'PreCheckoutQueryHandler', 'ShippingQueryHandler', 'MessageQueue', 'DelayQueue',
|
||||
'DispatcherHandlerStop', 'run_async', 'BasePersistence', 'PicklePersistence',
|
||||
'DictPersistence')
|
||||
'DispatcherHandlerStop', 'run_async', 'CallbackContext', 'BasePersistence',
|
||||
'PicklePersistence', 'DictPersistence')
|
||||
|
|
115
telegram/ext/callbackcontext.py
Normal file
115
telegram/ext/callbackcontext.py
Normal file
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the CallbackContext class."""
|
||||
|
||||
from telegram import Update
|
||||
|
||||
|
||||
class CallbackContext(object):
|
||||
"""
|
||||
This is a context object passed to the callback called by :class:`telegram.ext.Handler`
|
||||
or by the :class:`telegram.ext.Dispatcher` in an error handler added by
|
||||
:attr:`telegram.ext.Dispatcher.add_error_handler` or to the callback of a
|
||||
:class:`telegram.ext.Job`.
|
||||
|
||||
Attributes:
|
||||
chat_data (:obj:`dict`, optional): A dict that can be used to keep any data in. For each
|
||||
update from the same chat it will be the same ``dict``.
|
||||
user_data (:obj:`dict`, optional): A dict that can be used to keep any data in. For each
|
||||
update from the same user it will be the same ``dict``.
|
||||
match (:obj:`re match object`, optional): If the associated update originated from a
|
||||
regex-supported handler, this will contain the object returned from
|
||||
``re.match(pattern, string)``.
|
||||
args (List[:obj:`str`], optional): Arguments passed to a command if the associated update
|
||||
is handled by :class:`telegram.ext.CommandHandler` or
|
||||
:class:`telegram.ext.StringCommandHandler`. It contains a list of the words in the text
|
||||
after the command, using any whitespace string as a delimiter.
|
||||
error (:class:`telegram.TelegramError`, optional): The Telegram error that was raised.
|
||||
Only present when passed to a error handler registered with
|
||||
:attr:`telegram.ext.Dispatcher.add_error_handler`.
|
||||
job (:class:`telegram.ext.Job`): The job that that originated this callback.
|
||||
Only present when passed to the callback of :class:`telegram.ext.Job`.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, dispatcher):
|
||||
"""
|
||||
Args:
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`):
|
||||
"""
|
||||
if not dispatcher.use_context:
|
||||
raise ValueError('CallbackContext should not be used with a non context aware '
|
||||
'dispatcher!')
|
||||
self._dispatcher = dispatcher
|
||||
self.chat_data = None
|
||||
self.user_data = None
|
||||
self.args = None
|
||||
self.match = None
|
||||
self.error = None
|
||||
self.job = None
|
||||
|
||||
@classmethod
|
||||
def from_error(cls, update, error, dispatcher):
|
||||
self = cls.from_update(update, dispatcher)
|
||||
self.error = error
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def from_update(cls, update, dispatcher):
|
||||
self = cls(dispatcher)
|
||||
if update is not None and isinstance(update, Update):
|
||||
chat = update.effective_chat
|
||||
user = update.effective_user
|
||||
|
||||
if chat:
|
||||
self.chat_data = dispatcher.chat_data[chat.id]
|
||||
if user:
|
||||
self.user_data = dispatcher.user_data[user.id]
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def from_job(cls, job, dispatcher):
|
||||
self = cls(dispatcher)
|
||||
self.job = job
|
||||
return self
|
||||
|
||||
@property
|
||||
def bot(self):
|
||||
""":class:`telegram.Bot`: The bot associated with this context."""
|
||||
return self._dispatcher.bot
|
||||
|
||||
@property
|
||||
def job_queue(self):
|
||||
"""
|
||||
:class:`telegram.ext.JobQueue`: The ``JobQueue`` used by the
|
||||
:class:`telegram.ext.Dispatcher` and (usually) the :class:`telegram.ext.Updater`
|
||||
associated with this context.
|
||||
|
||||
"""
|
||||
return self._dispatcher.job_queue
|
||||
|
||||
@property
|
||||
def update_queue(self):
|
||||
"""
|
||||
:class:`queue.Queue`: The ``Queue`` instance used by the
|
||||
:class:`telegram.ext.Dispatcher` and (usually) the :class:`telegram.ext.Updater`
|
||||
associated with this context.
|
||||
|
||||
"""
|
||||
return self._dispatcher.update_queue
|
|
@ -33,19 +33,19 @@ class CallbackQueryHandler(Handler):
|
|||
|
||||
Attributes:
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pattern (:obj:`str` | `Pattern`): Optional. Regex pattern to test
|
||||
:attr:`telegram.CallbackQuery.data` against.
|
||||
pass_groups (:obj:`bool`): Optional. Determines whether ``groups`` will be passed to the
|
||||
pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the
|
||||
callback function.
|
||||
pass_groupdict (:obj:`bool`): Optional. Determines whether ``groupdict``. will be passed to
|
||||
pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -54,31 +54,45 @@ class CallbackQueryHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pattern (:obj:`str` | `Pattern`, optional): Regex pattern. If not ``None``, ``re.match``
|
||||
is used on :attr:`telegram.CallbackQuery.data` to determine if an update should be
|
||||
handled by this handler.
|
||||
pass_groups (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groups()`` as a keyword argument called ``groups``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -119,25 +133,22 @@ class CallbackQueryHandler(Handler):
|
|||
if self.pattern:
|
||||
if update.callback_query.data:
|
||||
match = re.match(self.pattern, update.callback_query.data)
|
||||
return bool(match)
|
||||
if match:
|
||||
return match
|
||||
else:
|
||||
return True
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(CallbackQueryHandler, self).collect_optional_args(dispatcher,
|
||||
update,
|
||||
check_result)
|
||||
if self.pattern:
|
||||
match = re.match(self.pattern, update.callback_query.data)
|
||||
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = match.groups()
|
||||
optional_args['groups'] = check_result.groups()
|
||||
if self.pass_groupdict:
|
||||
optional_args['groupdict'] = match.groupdict()
|
||||
optional_args['groupdict'] = check_result.groupdict()
|
||||
return optional_args
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
def collect_additional_context(self, context, update, dispatcher, check_result):
|
||||
if self.pattern:
|
||||
context.match = check_result
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the ChosenInlineResultHandler class."""
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
from .handler import Handler
|
||||
|
||||
|
||||
class ChosenInlineResultHandler(Handler):
|
||||
|
@ -28,13 +27,13 @@ class ChosenInlineResultHandler(Handler):
|
|||
|
||||
Attributes:
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -43,38 +42,37 @@ class ChosenInlineResultHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
callback,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(ChosenInlineResultHandler, self).__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)
|
||||
|
||||
def check_update(self, update):
|
||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||
|
||||
|
@ -86,20 +84,3 @@ class ChosenInlineResultHandler(Handler):
|
|||
|
||||
"""
|
||||
return isinstance(update, Update) and update.chosen_inline_result
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.ChosenInlineResultHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the CommandHandler class."""
|
||||
import warnings
|
||||
|
||||
from future.utils import string_types
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from .handler import Handler
|
||||
|
||||
|
||||
class CommandHandler(Handler):
|
||||
|
@ -37,17 +35,17 @@ class CommandHandler(Handler):
|
|||
callback (:obj:`callable`): The callback function for this handler.
|
||||
filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these
|
||||
Filters.
|
||||
allow_edited (:obj:`bool`): Optional. Determines Whether the handler should also accept
|
||||
allow_edited (:obj:`bool`): Determines Whether the handler should also accept
|
||||
edited messages.
|
||||
pass_args (:obj:`bool`): Optional. Determines whether the handler should be passed
|
||||
pass_args (:obj:`bool`): Determines whether the handler should be passed
|
||||
``args``.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -56,12 +54,20 @@ class CommandHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
command (:obj:`str` | List[:obj:`str`]): The command or list of commands this handler
|
||||
should listen for.
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
filters (:class:`telegram.ext.BaseFilter`, optional): A filter inheriting from
|
||||
:class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in
|
||||
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
|
||||
|
@ -72,18 +78,23 @@ class CommandHandler(Handler):
|
|||
arguments passed to the command as a keyword argument called ``args``. It will contain
|
||||
a list of strings, which is the text following the command split on single or
|
||||
consecutive whitespace characters. Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -112,13 +123,6 @@ class CommandHandler(Handler):
|
|||
self.allow_edited = allow_edited
|
||||
self.pass_args = pass_args
|
||||
|
||||
# We put this up here instead of with the rest of checking code
|
||||
# in check_update since we don't wanna spam a ton
|
||||
if isinstance(self.filters, list):
|
||||
warnings.warn('Using a list of filters in MessageHandler is getting '
|
||||
'deprecated, please use bitwise operators (& and |) '
|
||||
'instead. More info: https://git.io/vPTbc.')
|
||||
|
||||
def check_update(self, update):
|
||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||
|
||||
|
@ -129,8 +133,8 @@ class CommandHandler(Handler):
|
|||
:obj:`bool`
|
||||
|
||||
"""
|
||||
if (isinstance(update, Update)
|
||||
and (update.message or update.edited_message and self.allow_edited)):
|
||||
if (isinstance(update, Update) and
|
||||
(update.message or update.edited_message and self.allow_edited)):
|
||||
message = update.message or update.edited_message
|
||||
|
||||
if message.text and message.text.startswith('/') and len(message.text) > 1:
|
||||
|
@ -142,32 +146,16 @@ class CommandHandler(Handler):
|
|||
|
||||
if not (command[0].lower() in self.command
|
||||
and command[1].lower() == message.bot.username.lower()):
|
||||
return False
|
||||
return None
|
||||
|
||||
if self.filters is None:
|
||||
res = True
|
||||
elif isinstance(self.filters, list):
|
||||
res = any(func(message) for func in self.filters)
|
||||
else:
|
||||
res = self.filters(message)
|
||||
|
||||
return res
|
||||
|
||||
return False
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
|
||||
message = update.message or update.edited_message
|
||||
if self.filters is None or self.filters(message):
|
||||
return message.text.split()[1:]
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(CommandHandler, self).collect_optional_args(dispatcher, update)
|
||||
if self.pass_args:
|
||||
optional_args['args'] = message.text.split()[1:]
|
||||
optional_args['args'] = check_result
|
||||
return optional_args
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
def collect_additional_context(self, context, update, dispatcher, check_result):
|
||||
context.args = check_result
|
||||
|
|
|
@ -66,15 +66,15 @@ class ConversationHandler(Handler):
|
|||
fallbacks (List[:class:`telegram.ext.Handler`]): A list of handlers that might be used if
|
||||
the user is in a conversation, but every handler for their current state returned
|
||||
``False`` on :attr:`check_update`.
|
||||
allow_reentry (:obj:`bool`): Optional. Determines if a user can restart a conversation with
|
||||
allow_reentry (:obj:`bool`): Determines if a user can restart a conversation with
|
||||
an entry point.
|
||||
run_async_timeout (:obj:`float`): Optional. The time-out for ``run_async`` decorated
|
||||
Handlers.
|
||||
timed_out_behavior (List[:class:`telegram.ext.Handler`]): Optional. A list of handlers that
|
||||
might be used if the wait for ``run_async`` timed out.
|
||||
per_chat (:obj:`bool`): Optional. If the conversationkey should contain the Chat's ID.
|
||||
per_user (:obj:`bool`): Optional. If the conversationkey should contain the User's ID.
|
||||
per_message (:obj:`bool`): Optional. If the conversationkey should contain the Message's
|
||||
per_chat (:obj:`bool`): If the conversationkey should contain the Chat's ID.
|
||||
per_user (:obj:`bool`): If the conversationkey should contain the User's ID.
|
||||
per_message (:obj:`bool`): If the conversationkey should contain the Message's
|
||||
ID.
|
||||
conversation_timeout (:obj:`float`|:obj:`datetime.timedelta`): Optional. When this handler
|
||||
is inactive more than this timeout (in seconds), it will be automatically ended. If
|
||||
|
@ -164,8 +164,6 @@ class ConversationHandler(Handler):
|
|||
|
||||
self.timeout_jobs = dict()
|
||||
self.conversations = dict()
|
||||
self.current_conversation = None
|
||||
self.current_handler = None
|
||||
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -237,7 +235,7 @@ class ConversationHandler(Handler):
|
|||
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 False
|
||||
return None
|
||||
|
||||
key = self._get_key(update)
|
||||
state = self.conversations.get(key)
|
||||
|
@ -260,15 +258,13 @@ class ConversationHandler(Handler):
|
|||
state = self.conversations.get(key)
|
||||
else:
|
||||
for candidate in (self.timed_out_behavior or []):
|
||||
if candidate.check_update(update):
|
||||
check = candidate.check_update(update)
|
||||
if check is not None and check is not False:
|
||||
# Save the current user and the selected handler for handle_update
|
||||
self.current_conversation = key
|
||||
self.current_handler = candidate
|
||||
|
||||
return True
|
||||
return key, candidate, check
|
||||
|
||||
else:
|
||||
return False
|
||||
return None
|
||||
|
||||
self.logger.debug('selecting conversation %s with state %s' % (str(key), str(state)))
|
||||
|
||||
|
@ -277,59 +273,61 @@ class ConversationHandler(Handler):
|
|||
# Search entry points for a match
|
||||
if state is None or self.allow_reentry:
|
||||
for entry_point in self.entry_points:
|
||||
if entry_point.check_update(update):
|
||||
check = entry_point.check_update(update)
|
||||
if check is not None and check is not False:
|
||||
handler = entry_point
|
||||
break
|
||||
|
||||
else:
|
||||
if state is None:
|
||||
return False
|
||||
return None
|
||||
|
||||
# Get the handler list for current state, if we didn't find one yet and we're still here
|
||||
if state is not None and not handler:
|
||||
handlers = self.states.get(state)
|
||||
|
||||
for candidate in (handlers or []):
|
||||
if candidate.check_update(update):
|
||||
check = candidate.check_update(update)
|
||||
if check is not None and check is not False:
|
||||
handler = candidate
|
||||
break
|
||||
|
||||
# Find a fallback handler if all other handlers fail
|
||||
else:
|
||||
for fallback in self.fallbacks:
|
||||
if fallback.check_update(update):
|
||||
check = fallback.check_update(update)
|
||||
if check is not None and check is not False:
|
||||
handler = fallback
|
||||
break
|
||||
|
||||
else:
|
||||
return False
|
||||
return None
|
||||
|
||||
# Save the current user and the selected handler for handle_update
|
||||
self.current_conversation = key
|
||||
self.current_handler = handler
|
||||
return key, handler, check
|
||||
|
||||
return True
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
def handle_update(self, update, dispatcher, check_result):
|
||||
"""Send the update to the callback for the current state and Handler
|
||||
|
||||
Args:
|
||||
check_result: The result from check_update. For this handler it's a tuple of key,
|
||||
handler, and the handler's check result.
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
new_state = self.current_handler.handle_update(update, dispatcher)
|
||||
timeout_job = self.timeout_jobs.pop(self.current_conversation, None)
|
||||
conversation_key, handler, check_result = check_result
|
||||
new_state = handler.handle_update(update, dispatcher, check_result)
|
||||
timeout_job = self.timeout_jobs.pop(conversation_key, None)
|
||||
|
||||
if timeout_job is not None:
|
||||
timeout_job.schedule_removal()
|
||||
if self.conversation_timeout and new_state != self.END:
|
||||
self.timeout_jobs[self.current_conversation] = dispatcher.job_queue.run_once(
|
||||
self.timeout_jobs[conversation_key] = dispatcher.job_queue.run_once(
|
||||
self._trigger_timeout, self.conversation_timeout,
|
||||
context=self.current_conversation
|
||||
context=conversation_key
|
||||
)
|
||||
|
||||
self.update_state(new_state, self.current_conversation)
|
||||
self.update_state(new_state, conversation_key)
|
||||
|
||||
def update_state(self, new_state, key):
|
||||
if new_state == self.END:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"""This module contains the Dispatcher class."""
|
||||
|
||||
import logging
|
||||
import warnings
|
||||
import weakref
|
||||
from functools import wraps
|
||||
from threading import Thread, Lock, Event, current_thread, BoundedSemaphore
|
||||
|
@ -32,6 +33,8 @@ from future.builtins import range
|
|||
|
||||
from telegram import TelegramError
|
||||
from telegram.ext.handler import Handler
|
||||
from telegram.ext.callbackcontext import CallbackContext
|
||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
from telegram.utils.promise import Promise
|
||||
from telegram.ext import BasePersistence
|
||||
|
||||
|
@ -86,6 +89,9 @@ class Dispatcher(object):
|
|||
``@run_async`` decorator. defaults to 4.
|
||||
persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to
|
||||
store data that should be persistent over restarts
|
||||
use_context (:obj:`bool`, optional): If set to ``True`` Use the context based callback API.
|
||||
During the deprecation period of the old API the default is ``False``. **New users**:
|
||||
set this to ``True``.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -94,12 +100,26 @@ class Dispatcher(object):
|
|||
__singleton = None
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def __init__(self, bot, update_queue, workers=4, exception_event=None, job_queue=None,
|
||||
persistence=None):
|
||||
def __init__(self,
|
||||
bot,
|
||||
update_queue,
|
||||
workers=4,
|
||||
exception_event=None,
|
||||
job_queue=None,
|
||||
persistence=None,
|
||||
use_context=False):
|
||||
self.bot = bot
|
||||
self.update_queue = update_queue
|
||||
self.job_queue = job_queue
|
||||
self.workers = workers
|
||||
self.use_context = use_context
|
||||
|
||||
if not use_context:
|
||||
warnings.warn('Old Handler API is deprecated - see https://git.io/vp113 for details',
|
||||
TelegramDeprecationWarning, stacklevel=3)
|
||||
|
||||
self.user_data = defaultdict(dict)
|
||||
""":obj:`dict`: A dictionary handlers can use to store data for the user."""
|
||||
self.chat_data = defaultdict(dict)
|
||||
if persistence:
|
||||
if not isinstance(persistence, BasePersistence):
|
||||
|
@ -297,22 +317,24 @@ class Dispatcher(object):
|
|||
|
||||
for group in self.groups:
|
||||
try:
|
||||
for handler in (x for x in self.handlers[group] if x.check_update(update)):
|
||||
handler.handle_update(update, self)
|
||||
if self.persistence:
|
||||
if self.persistence.store_chat_data and update.effective_chat.id:
|
||||
chat_id = update.effective_chat.id
|
||||
try:
|
||||
self.persistence.update_chat_data(chat_id, self.chat_data[chat_id])
|
||||
except Exception:
|
||||
self.logger.exception('Saving chat data raised an error')
|
||||
if self.persistence.store_user_data and update.effective_user.id:
|
||||
user_id = update.effective_user.id
|
||||
try:
|
||||
self.persistence.update_user_data(user_id, self.user_data[user_id])
|
||||
except Exception:
|
||||
self.logger.exception('Saving user data raised an error')
|
||||
break
|
||||
for handler in self.handlers[group]:
|
||||
check = handler.check_update(update)
|
||||
if check is not None and check is not False:
|
||||
handler.handle_update(update, self)
|
||||
if self.persistence:
|
||||
if self.persistence.store_chat_data and update.effective_chat.id:
|
||||
chat_id = update.effective_chat.id
|
||||
try:
|
||||
self.persistence.update_chat_data(chat_id, self.chat_data[chat_id])
|
||||
except Exception:
|
||||
self.logger.exception('Saving chat data raised an error')
|
||||
if self.persistence.store_user_data and update.effective_user.id:
|
||||
user_id = update.effective_user.id
|
||||
try:
|
||||
self.persistence.update_user_data(user_id, self.user_data[user_id])
|
||||
except Exception:
|
||||
self.logger.exception('Saving user data raised an error')
|
||||
break
|
||||
|
||||
# Stop processing with any other handler.
|
||||
except DispatcherHandlerStop:
|
||||
|
@ -399,9 +421,15 @@ class Dispatcher(object):
|
|||
"""Registers an error handler in the Dispatcher.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): A function that takes ``Bot, Update, TelegramError`` as
|
||||
arguments.
|
||||
callback (:obj:`callable`): The callback function for this error handler. Will be
|
||||
called when an error is raised Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The error that happened will be present in context.error.
|
||||
|
||||
Note:
|
||||
See https://git.io/vp113 for more info about switching to context based API.
|
||||
"""
|
||||
self.error_handlers.append(callback)
|
||||
|
||||
|
@ -425,7 +453,10 @@ class Dispatcher(object):
|
|||
"""
|
||||
if self.error_handlers:
|
||||
for callback in self.error_handlers:
|
||||
callback(self.bot, update, error)
|
||||
if self.use_context:
|
||||
callback(update, CallbackContext.from_error(update, error, self))
|
||||
else:
|
||||
callback(self.bot, update, error)
|
||||
|
||||
else:
|
||||
self.logger.exception(
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the base class for handlers as used by the Dispatcher."""
|
||||
from telegram.ext.callbackcontext import CallbackContext
|
||||
|
||||
|
||||
class Handler(object):
|
||||
|
@ -24,13 +25,13 @@ class Handler(object):
|
|||
|
||||
Attributes:
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -39,22 +40,34 @@ class Handler(object):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -79,31 +92,59 @@ class Handler(object):
|
|||
update (:obj:`str` | :class:`telegram.Update`): The update to be tested.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`
|
||||
Either ``None`` or ``False`` if the update should not be handled. Otherwise an object
|
||||
that will be passed to :attr:`handle_update` and :attr:`collect_additional_context`
|
||||
when the update gets handled.
|
||||
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
def handle_update(self, update, dispatcher, check_result):
|
||||
"""
|
||||
This method is called if it was determined that an update should indeed
|
||||
be handled by this instance. It should also be overridden, but in most
|
||||
cases call ``self.callback(dispatcher.bot, update)``, possibly along with
|
||||
optional arguments. To work with the ``ConversationHandler``, this method should return the
|
||||
value returned from ``self.callback``
|
||||
be handled by this instance. Calls :attr:`self.callback` along with its respectful
|
||||
arguments. To work with the :class:`telegram.ext.ConversationHandler`, this method
|
||||
returns the value returned from ``self.callback``.
|
||||
Note that it can be overridden if needed by the subclassing handler.
|
||||
|
||||
Args:
|
||||
update (:obj:`str` | :class:`telegram.Update`): The update to be handled.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): The dispatcher to collect optional args.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): The calling dispatcher.
|
||||
check_result: The result from :attr:`check_update`.
|
||||
|
||||
"""
|
||||
raise NotImplementedError
|
||||
if dispatcher.use_context:
|
||||
context = CallbackContext.from_update(update, dispatcher)
|
||||
self.collect_additional_context(context, update, dispatcher, check_result)
|
||||
return self.callback(update, context)
|
||||
else:
|
||||
optional_args = self.collect_optional_args(dispatcher, update, check_result)
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None):
|
||||
"""Prepares the optional arguments that are the same for all types of handlers.
|
||||
def collect_additional_context(self, context, update, dispatcher, check_result):
|
||||
"""Prepares additional arguments for the context. Override if needed.
|
||||
|
||||
Args:
|
||||
context (:class:`telegram.ext.CallbackContext`): The context object.
|
||||
update (:class:`telegram.Update`): The update to gather chat/user id from.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): The calling dispatcher.
|
||||
check_result: The result (return value) from :attr:`check_update`.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
"""
|
||||
Prepares the optional arguments. If the handler has additional optional args,
|
||||
it should subclass this method, but remember to call this super method.
|
||||
|
||||
DEPRECATED: This method is being replaced by new context based callbacks. Please see
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): The dispatcher.
|
||||
update (:class:`telegram.Update`): The update to gather chat/user id from.
|
||||
check_result: The result from check_update
|
||||
|
||||
"""
|
||||
optional_args = dict()
|
||||
|
|
|
@ -22,7 +22,6 @@ import re
|
|||
from future.utils import string_types
|
||||
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
from .handler import Handler
|
||||
|
||||
|
||||
|
@ -33,19 +32,19 @@ class InlineQueryHandler(Handler):
|
|||
|
||||
Attributes:
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pattern (:obj:`str` | :obj:`Pattern`): Optional. Regex pattern to test
|
||||
:attr:`telegram.InlineQuery.query` against.
|
||||
pass_groups (:obj:`bool`): Optional. Determines whether ``groups`` will be passed to the
|
||||
pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the
|
||||
callback function.
|
||||
pass_groupdict (:obj:`bool`): Optional. Determines whether ``groupdict``. will be passed to
|
||||
pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -54,31 +53,46 @@ class InlineQueryHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pattern (:obj:`str` | :obj:`Pattern`, optional): Regex pattern. If not ``None``,
|
||||
``re.match`` is used on :attr:`telegram.InlineQuery.query` to determine if an update
|
||||
should be handled by this handler.
|
||||
pass_groups (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groups()`` as a keyword argument called ``groups``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
|
@ -113,37 +127,28 @@ class InlineQueryHandler(Handler):
|
|||
|
||||
Returns:
|
||||
:obj:`bool`
|
||||
|
||||
"""
|
||||
|
||||
if isinstance(update, Update) and update.inline_query:
|
||||
if self.pattern:
|
||||
if update.inline_query.query:
|
||||
match = re.match(self.pattern, update.inline_query.query)
|
||||
return bool(match)
|
||||
if match:
|
||||
return match
|
||||
else:
|
||||
return True
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""
|
||||
Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
"""
|
||||
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(InlineQueryHandler, self).collect_optional_args(dispatcher,
|
||||
update, check_result)
|
||||
if self.pattern:
|
||||
match = re.match(self.pattern, update.inline_query.query)
|
||||
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = match.groups()
|
||||
optional_args['groups'] = check_result.groups()
|
||||
if self.pass_groupdict:
|
||||
optional_args['groupdict'] = match.groupdict()
|
||||
optional_args['groupdict'] = check_result.groupdict()
|
||||
return optional_args
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.InlineQueryHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
def collect_additional_context(self, context, update, dispatcher, check_result):
|
||||
if self.pattern:
|
||||
context.match = check_result
|
||||
|
|
|
@ -18,13 +18,17 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes JobQueue and Job."""
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import time
|
||||
import datetime
|
||||
import warnings
|
||||
import weakref
|
||||
from numbers import Number
|
||||
from threading import Thread, Lock, Event
|
||||
from queue import PriorityQueue, Empty
|
||||
from threading import Thread, Lock, Event
|
||||
|
||||
from telegram.ext.callbackcontext import CallbackContext
|
||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
|
||||
|
||||
class Days(object):
|
||||
|
@ -37,16 +41,24 @@ class JobQueue(object):
|
|||
|
||||
Attributes:
|
||||
_queue (:obj:`PriorityQueue`): The queue that holds the Jobs.
|
||||
bot (:class:`telegram.Bot`): Bot that's send to the handlers.
|
||||
|
||||
Args:
|
||||
bot (:class:`telegram.Bot`): The bot instance that should be passed to the jobs.
|
||||
|
||||
DEPRECATED: Use set_dispatcher instead.
|
||||
"""
|
||||
|
||||
def __init__(self, bot):
|
||||
def __init__(self, bot=None):
|
||||
self._queue = PriorityQueue()
|
||||
self.bot = bot
|
||||
if bot:
|
||||
warnings.warn("Passing bot to jobqueue is deprecated. Please use set_dispatcher "
|
||||
"instead!", TelegramDeprecationWarning, stacklevel=2)
|
||||
|
||||
class MockDispatcher(object):
|
||||
def __init__(self):
|
||||
self.bot = bot
|
||||
self.use_context = False
|
||||
|
||||
self._dispatcher = MockDispatcher()
|
||||
else:
|
||||
self._dispatcher = None
|
||||
self.logger = logging.getLogger(self.__class__.__name__)
|
||||
self.__start_lock = Lock()
|
||||
self.__next_peek_lock = Lock() # to protect self._next_peek & self.__tick
|
||||
|
@ -55,6 +67,9 @@ class JobQueue(object):
|
|||
self._next_peek = None
|
||||
self._running = False
|
||||
|
||||
def set_dispatcher(self, dispatcher):
|
||||
self._dispatcher = dispatcher
|
||||
|
||||
def _put(self, job, next_t=None, last_t=None):
|
||||
if next_t is None:
|
||||
next_t = job.interval
|
||||
|
@ -242,7 +257,7 @@ class JobQueue(object):
|
|||
current_week_day = datetime.datetime.now().weekday()
|
||||
if any(day == current_week_day for day in job.days):
|
||||
self.logger.debug('Running job %s', job.name)
|
||||
job.run(self.bot)
|
||||
job.run(self._dispatcher)
|
||||
|
||||
except Exception:
|
||||
self.logger.exception('An uncaught error was raised while executing job %s',
|
||||
|
@ -367,9 +382,12 @@ class Job(object):
|
|||
self._enabled = Event()
|
||||
self._enabled.set()
|
||||
|
||||
def run(self, bot):
|
||||
def run(self, dispatcher):
|
||||
"""Executes the callback function."""
|
||||
self.callback(bot, self)
|
||||
if dispatcher.use_context:
|
||||
self.callback(CallbackContext.from_job(self, dispatcher))
|
||||
else:
|
||||
self.callback(dispatcher.bot, self)
|
||||
|
||||
def schedule_removal(self):
|
||||
"""
|
||||
|
|
|
@ -31,21 +31,21 @@ class MessageHandler(Handler):
|
|||
filters (:obj:`Filter`): Only allow updates with these Filters. See
|
||||
:mod:`telegram.ext.filters` for a full list of all available filters.
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
message_updates (:obj:`bool`): Optional. Should "normal" message updates be handled?
|
||||
message_updates (:obj:`bool`): Should "normal" message updates be handled?
|
||||
Default is ``True``.
|
||||
channel_post_updates (:obj:`bool`): Optional. Should channel posts updates be handled?
|
||||
channel_post_updates (:obj:`bool`): Should channel posts updates be handled?
|
||||
Default is ``True``.
|
||||
edited_updates (:obj:`bool`): Optional. Should "edited" message updates be handled?
|
||||
edited_updates (:obj:`bool`): Should "edited" message updates be handled?
|
||||
Default is ``False``.
|
||||
allow_edited (:obj:`bool`): Optional. If the handler should also accept edited messages.
|
||||
allow_edited (:obj:`bool`): If the handler should also accept edited messages.
|
||||
Default is ``False`` - Deprecated. use edited_updates instead.
|
||||
|
||||
Note:
|
||||
|
@ -54,26 +54,38 @@ class MessageHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
filters (:class:`telegram.ext.BaseFilter`, optional): A filter inheriting from
|
||||
:class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in
|
||||
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
|
||||
operators (& for and, | for or, ~ for not).
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
message_updates (:obj:`bool`, optional): Should "normal" message updates be handled?
|
||||
Default is ``True``.
|
||||
channel_post_updates (:obj:`bool`, optional): Should channel posts updates be handled?
|
||||
|
@ -117,13 +129,6 @@ class MessageHandler(Handler):
|
|||
self.channel_post_updates = channel_post_updates
|
||||
self.edited_updates = edited_updates
|
||||
|
||||
# We put this up here instead of with the rest of checking code
|
||||
# in check_update since we don't wanna spam a ton
|
||||
if isinstance(self.filters, list):
|
||||
warnings.warn('Using a list of filters in MessageHandler is getting '
|
||||
'deprecated, please use bitwise operators (& and |) '
|
||||
'instead. More info: https://git.io/vPTbc.')
|
||||
|
||||
def _is_allowed_update(self, update):
|
||||
return any([self.message_updates and update.message,
|
||||
self.edited_updates and (update.edited_message or update.edited_channel_post),
|
||||
|
@ -140,30 +145,7 @@ class MessageHandler(Handler):
|
|||
|
||||
"""
|
||||
if isinstance(update, Update) and self._is_allowed_update(update):
|
||||
|
||||
if not self.filters:
|
||||
res = True
|
||||
|
||||
return True
|
||||
else:
|
||||
message = update.effective_message
|
||||
if isinstance(self.filters, list):
|
||||
res = any(func(message) for func in self.filters)
|
||||
else:
|
||||
res = self.filters(message)
|
||||
|
||||
else:
|
||||
res = False
|
||||
|
||||
return res
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
return self.filters(update.effective_message)
|
||||
|
|
|
@ -27,13 +27,13 @@ class PreCheckoutQueryHandler(Handler):
|
|||
|
||||
Attributes:
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -42,38 +42,37 @@ class PreCheckoutQueryHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
callback,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(PreCheckoutQueryHandler, self).__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)
|
||||
|
||||
def check_update(self, update):
|
||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||
|
||||
|
@ -85,14 +84,3 @@ class PreCheckoutQueryHandler(Handler):
|
|||
|
||||
"""
|
||||
return isinstance(update, Update) and update.pre_checkout_query
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
|
|
@ -38,17 +38,17 @@ class RegexHandler(Handler):
|
|||
Attributes:
|
||||
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_groups (:obj:`bool`): Optional. Determines whether ``groups`` will be passed to the
|
||||
pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the
|
||||
callback function.
|
||||
pass_groupdict (:obj:`bool`): Optional. Determines whether ``groupdict``. will be passed to
|
||||
pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to
|
||||
the callback function.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -57,29 +57,43 @@ class RegexHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_groups (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groups()`` as a keyword argument called ``groups``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
message_updates (:obj:`bool`, optional): Should "normal" message updates be handled?
|
||||
Default is ``True``.
|
||||
channel_post_updates (:obj:`bool`, optional): Should channel posts updates be handled?
|
||||
|
@ -106,8 +120,7 @@ class RegexHandler(Handler):
|
|||
allow_edited=False,
|
||||
message_updates=True,
|
||||
channel_post_updates=False,
|
||||
edited_updates=False
|
||||
):
|
||||
edited_updates=False):
|
||||
if not message_updates and not channel_post_updates and not edited_updates:
|
||||
raise ValueError(
|
||||
'message_updates, channel_post_updates and edited_updates are all False')
|
||||
|
@ -144,30 +157,23 @@ class RegexHandler(Handler):
|
|||
|
||||
"""
|
||||
if not isinstance(update, Update) and not update.effective_message:
|
||||
return False
|
||||
return None
|
||||
if any([self.message_updates and update.message,
|
||||
self.edited_updates and (update.edited_message or update.edited_channel_post),
|
||||
self.channel_post_updates and update.channel_post]) and \
|
||||
update.effective_message.text:
|
||||
match = re.match(self.pattern, update.effective_message.text)
|
||||
return bool(match)
|
||||
return False
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
match = re.match(self.pattern, update.effective_message.text)
|
||||
if match:
|
||||
return match
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(RegexHandler, self).collect_optional_args(dispatcher, update,
|
||||
check_result)
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = match.groups()
|
||||
optional_args['groups'] = check_result.groups()
|
||||
if self.pass_groupdict:
|
||||
optional_args['groupdict'] = match.groupdict()
|
||||
optional_args['groupdict'] = check_result.groupdict()
|
||||
return optional_args
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
def collect_additional_context(self, context, update, dispatcher, check_result):
|
||||
context.match = check_result
|
||||
|
|
|
@ -27,13 +27,13 @@ class ShippingQueryHandler(Handler):
|
|||
|
||||
Attributes:
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Optional. Determines whether ``user_data`` will be passed to
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Note:
|
||||
|
@ -42,38 +42,37 @@ class ShippingQueryHandler(Handler):
|
|||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/vp113 for more info.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
callback,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(ShippingQueryHandler, self).__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)
|
||||
|
||||
def check_update(self, update):
|
||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||
|
||||
|
@ -85,14 +84,3 @@ class ShippingQueryHandler(Handler):
|
|||
|
||||
"""
|
||||
return isinstance(update, Update) and update.shipping_query
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
|
|
@ -33,31 +33,37 @@ class StringCommandHandler(Handler):
|
|||
Attributes:
|
||||
command (:obj:`str`): The command this handler should listen for.
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_args (:obj:`bool`): Optional. Determines whether the handler should be passed
|
||||
pass_args (:obj:`bool`): Determines whether the handler should be passed
|
||||
``args``.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
|
||||
|
||||
Args:
|
||||
command (:obj:`str`): The command this handler should listen for.
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that a command should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_args (:obj:`bool`, optional): Determines whether the handler should be passed the
|
||||
arguments passed to the command as a keyword argument called ``args``. It will contain
|
||||
a list of strings, which is the text following the command split on single or
|
||||
consecutive whitespace characters. Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -68,7 +74,9 @@ class StringCommandHandler(Handler):
|
|||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
super(StringCommandHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue)
|
||||
self.command = command
|
||||
self.pass_args = pass_args
|
||||
|
||||
|
@ -76,28 +84,24 @@ class StringCommandHandler(Handler):
|
|||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:obj:`str`): An incomming command.
|
||||
update (:obj:`str`): An incoming command.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`
|
||||
|
||||
"""
|
||||
if isinstance(update, string_types) and update.startswith('/'):
|
||||
args = update[1:].split(' ')
|
||||
if args[0] == self.command:
|
||||
return args[1:]
|
||||
|
||||
return (isinstance(update, string_types) and update.startswith('/')
|
||||
and update[1:].split(' ')[0] == self.command)
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:obj:`str`): An incomming command.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the command.
|
||||
|
||||
"""
|
||||
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(StringCommandHandler, self).collect_optional_args(dispatcher,
|
||||
update,
|
||||
check_result)
|
||||
if self.pass_args:
|
||||
optional_args['args'] = update.split()[1:]
|
||||
optional_args['args'] = check_result
|
||||
return optional_args
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
def collect_additional_context(self, context, update, dispatcher, check_result):
|
||||
context.args = check_result
|
||||
|
|
|
@ -38,34 +38,43 @@ class StringRegexHandler(Handler):
|
|||
Attributes:
|
||||
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
pass_groups (:obj:`bool`): Optional. Determines whether ``groups`` will be passed to the
|
||||
pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the
|
||||
callback function.
|
||||
pass_groupdict (:obj:`bool`): Optional. Determines whether ``groupdict``. will be passed to
|
||||
pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to
|
||||
the callback function.
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Args:
|
||||
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
pass_groups (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groups()`` as a keyword argument called ``groups``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of
|
||||
``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``.
|
||||
Default is ``False``
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -77,7 +86,9 @@ class StringRegexHandler(Handler):
|
|||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
super(StringRegexHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
pattern = re.compile(pattern)
|
||||
|
@ -90,28 +101,27 @@ class StringRegexHandler(Handler):
|
|||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:obj:`str`): An incomming command.
|
||||
update (:obj:`str`): An incoming command.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`
|
||||
|
||||
"""
|
||||
return isinstance(update, string_types) and bool(re.match(self.pattern, update))
|
||||
if isinstance(update, string_types):
|
||||
match = re.match(self.pattern, update)
|
||||
if match:
|
||||
return match
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
def collect_optional_args(self, dispatcher, update=None, check_result=None):
|
||||
optional_args = super(StringRegexHandler, self).collect_optional_args(dispatcher,
|
||||
update, check_result)
|
||||
if self.pattern:
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = check_result.groups()
|
||||
if self.pass_groupdict:
|
||||
optional_args['groupdict'] = check_result.groupdict()
|
||||
return optional_args
|
||||
|
||||
Args:
|
||||
update (:obj:`str`): An incomming command.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the command.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
match = re.match(self.pattern, update)
|
||||
|
||||
if self.pass_groups:
|
||||
optional_args['groups'] = match.groups()
|
||||
if self.pass_groupdict:
|
||||
optional_args['groupdict'] = match.groupdict()
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
def collect_additional_context(self, context, update, dispatcher, check_result):
|
||||
if self.pattern:
|
||||
context.match = check_result
|
||||
|
|
|
@ -27,36 +27,48 @@ class TypeHandler(Handler):
|
|||
Attributes:
|
||||
type (:obj:`type`): The ``type`` of updates this handler should process.
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
strict (:obj:`bool`): Optional. Use ``type`` instead of ``isinstance``.
|
||||
Default is ``False``
|
||||
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
|
||||
strict (:obj:`bool`): Use ``type`` instead of ``isinstance``. Default is ``False``.
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
|
||||
Args:
|
||||
type (:obj:`type`): The ``type`` of updates this handler should process, as
|
||||
determined by ``isinstance``
|
||||
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
|
||||
It will be called when the :attr:`check_update` has determined that an update should be
|
||||
processed by this handler.
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
strict (:obj:`bool`, optional): Use ``type`` instead of ``isinstance``.
|
||||
Default is ``False``
|
||||
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is ``False``.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, type, callback, strict=False, pass_update_queue=False,
|
||||
def __init__(self,
|
||||
type,
|
||||
callback,
|
||||
strict=False,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
super(TypeHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue)
|
||||
self.type = type
|
||||
self.strict = strict
|
||||
|
||||
|
@ -70,20 +82,7 @@ class TypeHandler(Handler):
|
|||
:obj:`bool`
|
||||
|
||||
"""
|
||||
|
||||
if not self.strict:
|
||||
return isinstance(update, self.type)
|
||||
else:
|
||||
return type(update) is self.type
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
"""Send the update to the :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update`): Incoming telegram update.
|
||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.
|
||||
|
||||
"""
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
|
|
@ -57,6 +57,7 @@ class Updater(object):
|
|||
running (:obj:`bool`): Indicates if the updater is running.
|
||||
persistence (:class:`telegram.ext.BasePersistence`): Optional. The persistence class to
|
||||
store data that should be persistent over restarts.
|
||||
use_context (:obj:`bool`, optional): ``True`` if using context based callbacks.
|
||||
|
||||
Args:
|
||||
token (:obj:`str`, optional): The bot's token given by the @BotFather.
|
||||
|
@ -75,6 +76,9 @@ class Updater(object):
|
|||
`telegram.utils.request.Request` object (ignored if `bot` argument is used). The
|
||||
request_kwargs are very useful for the advanced users who would like to control the
|
||||
default timeouts and/or control the proxy used for http communication.
|
||||
use_context (:obj:`bool`, optional): If set to ``True`` Use the context based callback API.
|
||||
During the deprecation period of the old API the default is ``False``. **New users**:
|
||||
set this to ``True``.
|
||||
persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to
|
||||
store data that should be persistent over restarts.
|
||||
|
||||
|
@ -97,7 +101,8 @@ class Updater(object):
|
|||
private_key_password=None,
|
||||
user_sig_handler=None,
|
||||
request_kwargs=None,
|
||||
persistence=None):
|
||||
persistence=None,
|
||||
use_context=False):
|
||||
|
||||
if (token is None) and (bot is None):
|
||||
raise ValueError('`token` or `bot` must be passed')
|
||||
|
@ -132,7 +137,7 @@ class Updater(object):
|
|||
private_key_password=private_key_password)
|
||||
self.user_sig_handler = user_sig_handler
|
||||
self.update_queue = Queue()
|
||||
self.job_queue = JobQueue(self.bot)
|
||||
self.job_queue = JobQueue()
|
||||
self.__exception_event = Event()
|
||||
self.persistence = persistence
|
||||
self.dispatcher = Dispatcher(
|
||||
|
@ -141,7 +146,9 @@ class Updater(object):
|
|||
job_queue=self.job_queue,
|
||||
workers=workers,
|
||||
exception_event=self.__exception_event,
|
||||
persistence=self.persistence)
|
||||
persistence=persistence,
|
||||
use_context=use_context)
|
||||
self.job_queue.set_dispatcher(self.dispatcher)
|
||||
self.last_update_id = 0
|
||||
self.running = False
|
||||
self.is_idle = False
|
||||
|
|
|
@ -72,7 +72,8 @@ def provider_token(bot_info):
|
|||
def create_dp(bot):
|
||||
# Dispatcher is heavy to init (due to many threads and such) so we have a single session
|
||||
# scoped one here, but before each test, reset it (dp fixture below)
|
||||
dispatcher = Dispatcher(bot, Queue(), job_queue=JobQueue(bot), workers=2)
|
||||
dispatcher = Dispatcher(bot, Queue(), job_queue=JobQueue(), workers=2, use_context=False)
|
||||
dispatcher.job_queue.set_dispatcher(dispatcher)
|
||||
thr = Thread(target=dispatcher.start)
|
||||
thr.start()
|
||||
sleep(2)
|
||||
|
@ -109,6 +110,13 @@ def dp(_dp):
|
|||
Dispatcher._Dispatcher__singleton_semaphore.release()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def cdp(dp):
|
||||
dp.use_context = True
|
||||
yield dp
|
||||
dp.use_context = False
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def updater(bot):
|
||||
up = Updater(bot=bot, workers=2)
|
||||
|
|
98
tests/test_callbackcontext.py
Normal file
98
tests/test_callbackcontext.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2018
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import pytest
|
||||
|
||||
from telegram import Update, Message, Chat, User, TelegramError
|
||||
from telegram.ext import CallbackContext
|
||||
|
||||
|
||||
class TestCallbackContext(object):
|
||||
def test_non_context_dp(self, dp):
|
||||
with pytest.raises(ValueError):
|
||||
CallbackContext(dp)
|
||||
|
||||
def test_from_job(self, cdp):
|
||||
job = cdp.job_queue.run_once(lambda x: x, 10)
|
||||
|
||||
callback_context = CallbackContext.from_job(job, cdp)
|
||||
|
||||
assert callback_context.job is job
|
||||
assert callback_context.chat_data is None
|
||||
assert callback_context.user_data is None
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
||||
def test_from_update(self, cdp):
|
||||
update = Update(0, message=Message(0, User(1, 'user', False), None, Chat(1, 'chat')))
|
||||
|
||||
callback_context = CallbackContext.from_update(update, cdp)
|
||||
|
||||
assert callback_context.chat_data == {}
|
||||
assert callback_context.user_data == {}
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
||||
callback_context_same_user_chat = CallbackContext.from_update(update, cdp)
|
||||
|
||||
callback_context.chat_data['test'] = 'chat'
|
||||
callback_context.user_data['test'] = 'user'
|
||||
|
||||
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, User(2, 'user', False),
|
||||
None, Chat(2, 'chat')))
|
||||
|
||||
callback_context_other_user_chat = CallbackContext.from_update(update_other_user_chat, cdp)
|
||||
|
||||
assert callback_context_other_user_chat.chat_data is not callback_context.chat_data
|
||||
assert callback_context_other_user_chat.user_data is not callback_context.user_data
|
||||
|
||||
def test_from_update_not_update(self, cdp):
|
||||
callback_context = CallbackContext.from_update(None, cdp)
|
||||
|
||||
assert callback_context.chat_data is None
|
||||
assert callback_context.user_data is None
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
||||
callback_context = CallbackContext.from_update('', cdp)
|
||||
|
||||
assert callback_context.chat_data is None
|
||||
assert callback_context.user_data is None
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
||||
def test_from_error(self, cdp):
|
||||
error = TelegramError('test')
|
||||
|
||||
update = Update(0, message=Message(0, User(1, 'user', False), None, Chat(1, 'chat')))
|
||||
|
||||
callback_context = CallbackContext.from_error(update, error, cdp)
|
||||
|
||||
assert callback_context.error is error
|
||||
assert callback_context.chat_data == {}
|
||||
assert callback_context.user_data == {}
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
|
@ -16,11 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, InlineQuery,
|
||||
ChosenInlineResult, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import CallbackQueryHandler
|
||||
from telegram.ext import CallbackQueryHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -47,7 +49,7 @@ def false_update(request):
|
|||
|
||||
@pytest.fixture(scope='function')
|
||||
def callback_query(bot):
|
||||
return Update(0, callback_query=CallbackQuery(2, None, None, data='test data'))
|
||||
return Update(0, callback_query=CallbackQuery(2, User(1, '', False), None, data='test data'))
|
||||
|
||||
|
||||
class TestCallbackQueryHandler(object):
|
||||
|
@ -80,6 +82,22 @@ class TestCallbackQueryHandler(object):
|
|||
if groupdict is not None:
|
||||
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(update.callback_query, CallbackQuery))
|
||||
|
||||
def callback_context_pattern(self, update, context):
|
||||
if context.match.groups():
|
||||
self.test_flag = context.match.groups() == ('t', ' data')
|
||||
if context.match.groupdict():
|
||||
self.test_flag = context.match.groupdict() == {'begin': 't', 'end': ' data'}
|
||||
|
||||
def test_basic(self, dp, callback_query):
|
||||
handler = CallbackQueryHandler(self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -117,14 +135,16 @@ class TestCallbackQueryHandler(object):
|
|||
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
|
||||
|
@ -132,7 +152,8 @@ class TestCallbackQueryHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = CallbackQueryHandler(self.callback_data_2, pass_chat_data=True,
|
||||
handler = CallbackQueryHandler(self.callback_data_2,
|
||||
pass_chat_data=True,
|
||||
pass_user_data=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -141,14 +162,16 @@ class TestCallbackQueryHandler(object):
|
|||
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
|
||||
|
@ -156,7 +179,8 @@ class TestCallbackQueryHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = CallbackQueryHandler(self.callback_queue_2, pass_job_queue=True,
|
||||
handler = CallbackQueryHandler(self.callback_queue_2,
|
||||
pass_job_queue=True,
|
||||
pass_update_queue=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -167,3 +191,26 @@ class TestCallbackQueryHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = CallbackQueryHandler(self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp, callback_query):
|
||||
handler = CallbackQueryHandler(self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(callback_query)
|
||||
assert self.test_flag
|
||||
|
||||
def test_context_pattern(self, cdp, callback_query):
|
||||
handler = CallbackQueryHandler(self.callback_context_pattern,
|
||||
pattern=r'(?P<begin>.*)est(?P<end>.*)')
|
||||
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(.*)')
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(callback_query)
|
||||
assert self.test_flag
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery,
|
||||
InlineQuery, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import ChosenInlineResultHandler
|
||||
from telegram.ext import ChosenInlineResultHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -78,6 +79,16 @@ class TestChosenInlineResultHandler(object):
|
|||
def callback_queue_2(self, bot, update, job_queue=None, update_queue=None):
|
||||
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(update.chosen_inline_result, ChosenInlineResult))
|
||||
|
||||
def test_basic(self, dp, chosen_inline_result):
|
||||
handler = ChosenInlineResultHandler(self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -87,14 +98,16 @@ class TestChosenInlineResultHandler(object):
|
|||
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
|
||||
|
@ -102,8 +115,8 @@ class TestChosenInlineResultHandler(object):
|
|||
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
|
||||
|
@ -111,14 +124,16 @@ class TestChosenInlineResultHandler(object):
|
|||
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
|
||||
|
@ -126,8 +141,8 @@ class TestChosenInlineResultHandler(object):
|
|||
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
|
||||
|
@ -137,3 +152,10 @@ class TestChosenInlineResultHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = ChosenInlineResultHandler(self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp, chosen_inline_result):
|
||||
handler = ChosenInlineResultHandler(self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(chosen_inline_result)
|
||||
assert self.test_flag
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery,
|
||||
ChosenInlineResult, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import CommandHandler, Filters, BaseFilter
|
||||
from telegram.ext import CommandHandler, Filters, BaseFilter, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='test')
|
||||
|
||||
|
@ -48,7 +49,7 @@ def false_update(request):
|
|||
|
||||
@pytest.fixture(scope='function')
|
||||
def message(bot):
|
||||
return Message(1, None, None, None, bot=bot)
|
||||
return Message(1, User(1, '', False), None, Chat(1, ''), bot=bot)
|
||||
|
||||
|
||||
class TestCommandHandler(object):
|
||||
|
@ -83,51 +84,73 @@ class TestCommandHandler(object):
|
|||
else:
|
||||
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, 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(update.message, Message))
|
||||
|
||||
def callback_context_args(self, update, context):
|
||||
self.test_flag = context.args == ['one', 'two']
|
||||
|
||||
def test_basic(self, dp, message):
|
||||
handler = CommandHandler('test', self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
||||
message.text = '/test'
|
||||
assert handler.check_update(Update(0, message))
|
||||
dp.process_update(Update(0, message))
|
||||
assert self.test_flag
|
||||
|
||||
message.text = '/nottest'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
message.text = 'test'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
message.text = 'not /test at start'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
def test_command_list(self, message):
|
||||
handler = CommandHandler(['test', 'start'], self.callback_basic)
|
||||
|
||||
message.text = '/test'
|
||||
assert handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
|
||||
message.text = '/start'
|
||||
assert handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
|
||||
message.text = '/stop'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
def test_edited(self, message):
|
||||
handler = CommandHandler('test', self.callback_basic, allow_edited=False)
|
||||
handler = CommandHandler('test', self.callback_basic,
|
||||
allow_edited=False)
|
||||
|
||||
message.text = '/test'
|
||||
assert handler.check_update(Update(0, message))
|
||||
assert not handler.check_update(Update(0, edited_message=message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is not None and check is not False
|
||||
check = handler.check_update(Update(0, edited_message=message))
|
||||
assert check is None or check is False
|
||||
handler.allow_edited = True
|
||||
assert handler.check_update(Update(0, message))
|
||||
assert handler.check_update(Update(0, edited_message=message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is not None and check is not False
|
||||
check = handler.check_update(Update(0, edited_message=message))
|
||||
assert check is not None and check is not False
|
||||
|
||||
def test_directed_commands(self, message):
|
||||
handler = CommandHandler('test', self.callback_basic)
|
||||
|
||||
message.text = '/test@{}'.format(message.bot.username)
|
||||
assert handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is not None and check is not False
|
||||
|
||||
message.text = '/test@otherbot'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
|
@ -137,10 +160,12 @@ class TestCommandHandler(object):
|
|||
|
||||
message.chat = Chat(-23, 'group')
|
||||
message.text = '/test'
|
||||
assert handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is not None and check is not False
|
||||
|
||||
message.chat = Chat(23, 'private')
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
def test_pass_args(self, dp, message):
|
||||
handler = CommandHandler('test', self.ch_callback_args, pass_args=True)
|
||||
|
@ -170,7 +195,8 @@ class TestCommandHandler(object):
|
|||
dp.add_handler(handler)
|
||||
|
||||
message.text = '/test\nfoobar'
|
||||
assert handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is not None and check is not False
|
||||
dp.process_update(Update(0, message))
|
||||
assert self.test_flag
|
||||
|
||||
|
@ -180,7 +206,8 @@ class TestCommandHandler(object):
|
|||
dp.add_handler(handler)
|
||||
|
||||
message.text = 'a'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
def test_single_slash(self, dp, message):
|
||||
# Regression test for https://github.com/python-telegram-bot/python-telegram-bot/issues/871
|
||||
|
@ -188,13 +215,16 @@ class TestCommandHandler(object):
|
|||
dp.add_handler(handler)
|
||||
|
||||
message.text = '/'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
message.text = '/ test'
|
||||
assert not handler.check_update(Update(0, message))
|
||||
check = handler.check_update(Update(0, message))
|
||||
assert check is None or check is False
|
||||
|
||||
def test_pass_user_or_chat_data(self, dp, message):
|
||||
handler = CommandHandler('test', self.callback_data_1, pass_user_data=True)
|
||||
handler = CommandHandler('test', self.callback_data_1,
|
||||
pass_user_data=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
message.text = '/test'
|
||||
|
@ -202,7 +232,8 @@ class TestCommandHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = CommandHandler('test', self.callback_data_1, pass_chat_data=True)
|
||||
handler = CommandHandler('test', self.callback_data_1,
|
||||
pass_chat_data=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
self.test_flag = False
|
||||
|
@ -210,7 +241,8 @@ class TestCommandHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = CommandHandler('test', self.callback_data_2, pass_chat_data=True,
|
||||
handler = CommandHandler('test', self.callback_data_2,
|
||||
pass_chat_data=True,
|
||||
pass_user_data=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -219,7 +251,8 @@ class TestCommandHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
def test_pass_job_or_update_queue(self, dp, message):
|
||||
handler = CommandHandler('test', self.callback_queue_1, pass_job_queue=True)
|
||||
handler = CommandHandler('test', self.callback_queue_1,
|
||||
pass_job_queue=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
message.text = '/test'
|
||||
|
@ -227,7 +260,8 @@ class TestCommandHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = CommandHandler('test', self.callback_queue_1, pass_update_queue=True)
|
||||
handler = CommandHandler('test', self.callback_queue_1,
|
||||
pass_update_queue=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
self.test_flag = False
|
||||
|
@ -235,7 +269,8 @@ class TestCommandHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = CommandHandler('test', self.callback_queue_2, pass_job_queue=True,
|
||||
handler = CommandHandler('test', self.callback_queue_2,
|
||||
pass_job_queue=True,
|
||||
pass_update_queue=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -245,7 +280,8 @@ class TestCommandHandler(object):
|
|||
|
||||
def test_other_update_types(self, false_update):
|
||||
handler = CommandHandler('test', self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
check = handler.check_update(false_update)
|
||||
assert check is None or check is False
|
||||
|
||||
def test_filters_for_wrong_command(self, message):
|
||||
"""Filters should not be executed if the command does not match the handler"""
|
||||
|
@ -259,9 +295,31 @@ class TestCommandHandler(object):
|
|||
|
||||
test_filter = TestFilter()
|
||||
|
||||
handler = CommandHandler('foo', self.callback_basic, filters=test_filter)
|
||||
handler = CommandHandler('foo', self.callback_basic,
|
||||
filters=test_filter)
|
||||
message.text = '/bar'
|
||||
|
||||
handler.check_update(Update(0, message=message))
|
||||
check = handler.check_update(Update(0, message=message))
|
||||
assert check is None or check is False
|
||||
|
||||
assert not test_filter.tested
|
||||
|
||||
def test_context(self, cdp, message):
|
||||
handler = CommandHandler('test', self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
message.text = '/test'
|
||||
cdp.process_update(Update(0, message))
|
||||
assert self.test_flag
|
||||
|
||||
def test_context_args(self, cdp, message):
|
||||
handler = CommandHandler('test', self.callback_context_args)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
message.text = '/test'
|
||||
cdp.process_update(Update(0, message))
|
||||
assert not self.test_flag
|
||||
|
||||
message.text = '/test one two'
|
||||
cdp.process_update(Update(0, message))
|
||||
assert self.test_flag
|
||||
|
|
|
@ -52,7 +52,8 @@ class TestConversationHandler(object):
|
|||
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),
|
||||
|
@ -266,7 +267,8 @@ class TestConversationHandler(object):
|
|||
|
||||
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.
|
||||
|
@ -278,7 +280,8 @@ class TestConversationHandler(object):
|
|||
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
|
||||
|
@ -297,7 +300,8 @@ class TestConversationHandler(object):
|
|||
|
||||
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)
|
||||
|
|
|
@ -16,15 +16,17 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import sys
|
||||
from queue import Queue
|
||||
from threading import current_thread
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import TelegramError, Message, User, Chat, Update
|
||||
from telegram.ext import MessageHandler, Filters, CommandHandler
|
||||
from telegram import TelegramError, Message, User, Chat, Update, Bot
|
||||
from telegram.ext import MessageHandler, Filters, CommandHandler, CallbackContext, JobQueue
|
||||
from telegram.ext.dispatcher import run_async, Dispatcher, DispatcherHandlerStop
|
||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
from tests.conftest import create_dp
|
||||
|
||||
|
||||
|
@ -67,6 +69,14 @@ class TestDispatcher(object):
|
|||
if update_queue is not None:
|
||||
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)):
|
||||
self.received = context.error.message
|
||||
|
||||
def test_error_handler(self, dp):
|
||||
dp.add_error_handler(self.error_handler)
|
||||
error = TelegramError('Unauthorized.')
|
||||
|
@ -326,3 +336,17 @@ class TestDispatcher(object):
|
|||
dp.process_update(update)
|
||||
assert passed == ['start1', 'error', err]
|
||||
assert passed[2] is err
|
||||
|
||||
def test_error_handler_context(self, cdp):
|
||||
cdp.add_error_handler(self.callback_context)
|
||||
|
||||
error = TelegramError('Unauthorized.')
|
||||
cdp.update_queue.put(error)
|
||||
sleep(.1)
|
||||
assert self.received == 'Unauthorized.'
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 0), reason='pytest fails this for no reason')
|
||||
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)
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, InlineQuery,
|
||||
ChosenInlineResult, ShippingQuery, PreCheckoutQuery, Location)
|
||||
from telegram.ext import InlineQueryHandler
|
||||
from telegram.ext import InlineQueryHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -84,6 +86,22 @@ class TestCallbackQueryHandler(object):
|
|||
if groupdict is not None:
|
||||
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(update.inline_query, InlineQuery))
|
||||
|
||||
def callback_context_pattern(self, update, context):
|
||||
if context.match.groups():
|
||||
self.test_flag = context.match.groups() == ('t', ' query')
|
||||
if context.match.groupdict():
|
||||
self.test_flag = context.match.groupdict() == {'begin': 't', 'end': ' query'}
|
||||
|
||||
def test_basic(self, dp, inline_query):
|
||||
handler = InlineQueryHandler(self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -94,7 +112,8 @@ class TestCallbackQueryHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
def test_with_pattern(self, inline_query):
|
||||
handler = InlineQueryHandler(self.callback_basic, pattern='(?P<begin>.*)est(?P<end>.*)')
|
||||
handler = InlineQueryHandler(self.callback_basic,
|
||||
pattern='(?P<begin>.*)est(?P<end>.*)')
|
||||
|
||||
assert handler.check_update(inline_query)
|
||||
|
||||
|
@ -152,7 +171,8 @@ class TestCallbackQueryHandler(object):
|
|||
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
|
||||
|
@ -171,3 +191,26 @@ class TestCallbackQueryHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = InlineQueryHandler(self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp, inline_query):
|
||||
handler = InlineQueryHandler(self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(inline_query)
|
||||
assert self.test_flag
|
||||
|
||||
def test_context_pattern(self, cdp, inline_query):
|
||||
handler = InlineQueryHandler(self.callback_context_pattern,
|
||||
pattern=r'(?P<begin>.*)est(?P<end>.*)')
|
||||
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(.*)')
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(inline_query)
|
||||
assert self.test_flag
|
||||
|
|
|
@ -18,18 +18,22 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from queue import Queue
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
from flaky import flaky
|
||||
|
||||
from telegram.ext import JobQueue, Updater, Job
|
||||
from telegram.ext import JobQueue, Updater, Job, CallbackContext
|
||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def job_queue(bot):
|
||||
jq = JobQueue(bot)
|
||||
def job_queue(bot, _dp):
|
||||
jq = JobQueue()
|
||||
jq.set_dispatcher(_dp)
|
||||
jq.start()
|
||||
yield jq
|
||||
jq.stop()
|
||||
|
@ -62,6 +66,16 @@ class TestJobQueue(object):
|
|||
def job_datetime_tests(self, bot, job):
|
||||
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
|
||||
context.job_queue is context.job.job_queue):
|
||||
self.result += 1
|
||||
|
||||
def test_run_once(self, job_queue):
|
||||
job_queue.run_once(self.job_run_once, 0.01)
|
||||
sleep(0.02)
|
||||
|
@ -244,3 +258,15 @@ class TestJobQueue(object):
|
|||
assert job_queue.jobs() == (job1, job2, job3)
|
||||
assert job_queue.get_jobs_by_name('name1') == (job1, job2)
|
||||
assert job_queue.get_jobs_by_name('name2') == (job3,)
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 0), reason='pytest fails this for no reason')
|
||||
def test_bot_in_init_deprecation(self, bot):
|
||||
with pytest.warns(TelegramDeprecationWarning):
|
||||
JobQueue(bot)
|
||||
|
||||
def test_context_based_callback(self, job_queue):
|
||||
job_queue.run_once(self.job_context_based_callback, 0.01, context=2)
|
||||
|
||||
sleep(0.03)
|
||||
|
||||
assert self.result == 0
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery,
|
||||
ChosenInlineResult, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import Filters, MessageHandler
|
||||
from telegram.ext import Filters, MessageHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -45,7 +46,7 @@ def false_update(request):
|
|||
|
||||
@pytest.fixture(scope='class')
|
||||
def message(bot):
|
||||
return Message(1, None, None, None, bot=bot)
|
||||
return Message(1, User(1, '', False), None, Chat(1, ''), bot=bot)
|
||||
|
||||
|
||||
class TestMessageHandler(object):
|
||||
|
@ -72,6 +73,25 @@ class TestMessageHandler(object):
|
|||
def callback_queue_2(self, bot, update, job_queue=None, update_queue=None):
|
||||
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.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 test_basic(self, dp, message):
|
||||
handler = MessageHandler(None, self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -90,8 +110,9 @@ class TestMessageHandler(object):
|
|||
assert handler.check_update(Update(0, edited_channel_post=message))
|
||||
|
||||
def test_channel_post(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))
|
||||
|
@ -109,8 +130,9 @@ class TestMessageHandler(object):
|
|||
|
||||
def test_allow_edited(self, message):
|
||||
with pytest.warns(UserWarning):
|
||||
handler = MessageHandler(None, self.callback_basic, message_updates=True,
|
||||
allow_edited=True, channel_post_updates=False)
|
||||
handler = MessageHandler(None, self.callback_basic,
|
||||
message_updates=True, allow_edited=True,
|
||||
channel_post_updates=False)
|
||||
|
||||
assert handler.check_update(Update(0, edited_message=message))
|
||||
assert handler.check_update(Update(0, message=message))
|
||||
|
@ -132,14 +154,16 @@ class TestMessageHandler(object):
|
|||
assert not handler.check_update(Update(0, 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
|
||||
|
@ -147,8 +171,8 @@ class TestMessageHandler(object):
|
|||
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
|
||||
|
@ -156,14 +180,16 @@ class TestMessageHandler(object):
|
|||
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
|
||||
|
@ -171,8 +197,8 @@ class TestMessageHandler(object):
|
|||
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
|
||||
|
@ -182,3 +208,23 @@ class TestMessageHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = MessageHandler(None, self.callback_basic, edited_updates=True)
|
||||
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)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(Update(0, message=message))
|
||||
assert self.test_flag
|
||||
|
||||
self.test_flag = False
|
||||
cdp.process_update(Update(0, edited_message=message))
|
||||
assert self.test_flag
|
||||
|
||||
self.test_flag = False
|
||||
cdp.process_update(Update(0, channel_post=message))
|
||||
assert self.test_flag
|
||||
|
||||
self.test_flag = False
|
||||
cdp.process_update(Update(0, edited_channel_post=message))
|
||||
assert self.test_flag
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery,
|
||||
InlineQuery, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import PreCheckoutQueryHandler
|
||||
from telegram.ext import PreCheckoutQueryHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -78,6 +79,16 @@ class TestPreCheckoutQueryHandler(object):
|
|||
def callback_queue_2(self, bot, update, job_queue=None, update_queue=None):
|
||||
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(update.pre_checkout_query, PreCheckoutQuery))
|
||||
|
||||
def test_basic(self, dp, pre_checkout_query):
|
||||
handler = PreCheckoutQueryHandler(self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -87,14 +98,16 @@ class TestPreCheckoutQueryHandler(object):
|
|||
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
|
||||
|
@ -102,7 +115,8 @@ class TestPreCheckoutQueryHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = PreCheckoutQueryHandler(self.callback_data_2, pass_chat_data=True,
|
||||
handler = PreCheckoutQueryHandler(self.callback_data_2,
|
||||
pass_chat_data=True,
|
||||
pass_user_data=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -111,14 +125,16 @@ class TestPreCheckoutQueryHandler(object):
|
|||
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
|
||||
|
@ -126,7 +142,8 @@ class TestPreCheckoutQueryHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = PreCheckoutQueryHandler(self.callback_queue_2, pass_job_queue=True,
|
||||
handler = PreCheckoutQueryHandler(self.callback_queue_2,
|
||||
pass_job_queue=True,
|
||||
pass_update_queue=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -137,3 +154,10 @@ class TestPreCheckoutQueryHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = PreCheckoutQueryHandler(self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp, pre_checkout_query):
|
||||
handler = PreCheckoutQueryHandler(self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(pre_checkout_query)
|
||||
assert self.test_flag
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery,
|
||||
ChosenInlineResult, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import RegexHandler
|
||||
from telegram.ext import RegexHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -45,7 +46,7 @@ def false_update(request):
|
|||
|
||||
@pytest.fixture(scope='class')
|
||||
def message(bot):
|
||||
return Message(1, None, None, None, text='test message', bot=bot)
|
||||
return Message(1, User(1, '', False), None, Chat(1, ''), text='test message', bot=bot)
|
||||
|
||||
|
||||
class TestRegexHandler(object):
|
||||
|
@ -78,6 +79,22 @@ class TestRegexHandler(object):
|
|||
if groupdict is not None:
|
||||
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(update.message, Message))
|
||||
|
||||
def callback_context_pattern(self, update, context):
|
||||
if context.match.groups():
|
||||
self.test_flag = context.match.groups() == ('t', ' message')
|
||||
if context.match.groupdict():
|
||||
self.test_flag = context.match.groupdict() == {'begin': 't', 'end': ' message'}
|
||||
|
||||
def test_basic(self, dp, message):
|
||||
handler = RegexHandler('.*', self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -140,7 +157,8 @@ class TestRegexHandler(object):
|
|||
|
||||
def test_allow_edited(self, message):
|
||||
with pytest.warns(UserWarning):
|
||||
handler = RegexHandler('.*', self.callback_basic, message_updates=True,
|
||||
handler = RegexHandler('.*', self.callback_basic,
|
||||
message_updates=True,
|
||||
allow_edited=True)
|
||||
|
||||
assert handler.check_update(Update(0, edited_message=message))
|
||||
|
@ -185,7 +203,8 @@ class TestRegexHandler(object):
|
|||
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
|
||||
|
@ -204,3 +223,24 @@ class TestRegexHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = RegexHandler('.*', self.callback_basic, edited_updates=True)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp, message):
|
||||
handler = RegexHandler(r'(t)est(.*)', self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(Update(0, message=message))
|
||||
assert self.test_flag
|
||||
|
||||
def test_context_pattern(self, cdp, message):
|
||||
handler = RegexHandler(r'(t)est(.*)', self.callback_context_pattern)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(Update(0, message=message))
|
||||
assert self.test_flag
|
||||
|
||||
cdp.remove_handler(handler)
|
||||
handler = RegexHandler(r'(t)est(.*)', self.callback_context_pattern)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(Update(0, message=message))
|
||||
assert self.test_flag
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery,
|
||||
InlineQuery, ShippingQuery, PreCheckoutQuery, ShippingAddress)
|
||||
from telegram.ext import ShippingQueryHandler
|
||||
from telegram.ext import ShippingQueryHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -79,6 +80,16 @@ class TestShippingQueryHandler(object):
|
|||
def callback_queue_2(self, bot, update, job_queue=None, update_queue=None):
|
||||
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(update.shipping_query, ShippingQuery))
|
||||
|
||||
def test_basic(self, dp, shiping_query):
|
||||
handler = ShippingQueryHandler(self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -88,14 +99,16 @@ class TestShippingQueryHandler(object):
|
|||
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
|
||||
|
@ -103,7 +116,8 @@ class TestShippingQueryHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = ShippingQueryHandler(self.callback_data_2, pass_chat_data=True,
|
||||
handler = ShippingQueryHandler(self.callback_data_2,
|
||||
pass_chat_data=True,
|
||||
pass_user_data=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -112,14 +126,16 @@ class TestShippingQueryHandler(object):
|
|||
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
|
||||
|
@ -127,7 +143,8 @@ class TestShippingQueryHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = ShippingQueryHandler(self.callback_queue_2, pass_job_queue=True,
|
||||
handler = ShippingQueryHandler(self.callback_queue_2,
|
||||
pass_job_queue=True,
|
||||
pass_update_queue=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -138,3 +155,10 @@ class TestShippingQueryHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = ShippingQueryHandler(self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp, shiping_query):
|
||||
handler = ShippingQueryHandler(self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update(shiping_query)
|
||||
assert self.test_flag
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Bot, Update, Message, User, Chat, CallbackQuery, InlineQuery,
|
||||
ChosenInlineResult, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import StringCommandHandler
|
||||
from telegram.ext import StringCommandHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -71,20 +73,37 @@ class TestStringCommandHandler(object):
|
|||
else:
|
||||
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)
|
||||
|
||||
def callback_context_args(self, update, context):
|
||||
self.test_flag = context.args == ['one', 'two']
|
||||
|
||||
def test_basic(self, dp):
|
||||
handler = StringCommandHandler('test', self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
||||
assert handler.check_update('/test')
|
||||
check = handler.check_update('/test')
|
||||
assert check is not None and check is not False
|
||||
dp.process_update('/test')
|
||||
assert self.test_flag
|
||||
|
||||
assert not handler.check_update('/nottest')
|
||||
assert not handler.check_update('not /test in front')
|
||||
assert handler.check_update('/test followed by text')
|
||||
check = handler.check_update('/nottest')
|
||||
assert check is None or check is False
|
||||
check = handler.check_update('not /test in front')
|
||||
assert check is None or check is False
|
||||
check = handler.check_update('/test followed by text')
|
||||
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')
|
||||
|
@ -95,14 +114,16 @@ class TestStringCommandHandler(object):
|
|||
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
|
||||
|
@ -110,7 +131,8 @@ class TestStringCommandHandler(object):
|
|||
assert self.test_flag
|
||||
|
||||
dp.remove_handler(handler)
|
||||
handler = StringCommandHandler('test', self.callback_queue_2, pass_job_queue=True,
|
||||
handler = StringCommandHandler('test', self.callback_queue_2,
|
||||
pass_job_queue=True,
|
||||
pass_update_queue=True)
|
||||
dp.add_handler(handler)
|
||||
|
||||
|
@ -121,3 +143,20 @@ class TestStringCommandHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = StringCommandHandler('test', self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp):
|
||||
handler = StringCommandHandler('test', self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update('/test')
|
||||
assert self.test_flag
|
||||
|
||||
def test_context_args(self, cdp):
|
||||
handler = StringCommandHandler('test', self.callback_context_args)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update('/test')
|
||||
assert not self.test_flag
|
||||
|
||||
cdp.process_update('/test one two')
|
||||
assert self.test_flag
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import (Bot, Update, Message, User, Chat, CallbackQuery, InlineQuery,
|
||||
ChosenInlineResult, ShippingQuery, PreCheckoutQuery)
|
||||
from telegram.ext import StringRegexHandler
|
||||
from telegram.ext import StringRegexHandler, CallbackContext, JobQueue
|
||||
|
||||
message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')
|
||||
|
||||
|
@ -71,6 +73,19 @@ class TestStringRegexHandler(object):
|
|||
if groupdict is not None:
|
||||
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))
|
||||
|
||||
def callback_context_pattern(self, update, context):
|
||||
if context.match.groups():
|
||||
self.test_flag = context.match.groups() == ('t', ' message')
|
||||
if context.match.groupdict():
|
||||
self.test_flag = context.match.groupdict() == {'begin': 't', 'end': ' message'}
|
||||
|
||||
def test_basic(self, dp):
|
||||
handler = StringRegexHandler('(?P<begin>.*)est(?P<end>.*)', self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -99,14 +114,16 @@ class TestStringRegexHandler(object):
|
|||
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
|
||||
|
@ -114,8 +131,8 @@ class TestStringRegexHandler(object):
|
|||
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
|
||||
|
@ -125,3 +142,24 @@ class TestStringRegexHandler(object):
|
|||
def test_other_update_types(self, false_update):
|
||||
handler = StringRegexHandler('test', self.callback_basic)
|
||||
assert not handler.check_update(false_update)
|
||||
|
||||
def test_context(self, cdp):
|
||||
handler = StringRegexHandler(r'(t)est(.*)', self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update('test message')
|
||||
assert self.test_flag
|
||||
|
||||
def test_context_pattern(self, cdp):
|
||||
handler = StringRegexHandler(r'(t)est(.*)', self.callback_context_pattern)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update('test message')
|
||||
assert self.test_flag
|
||||
|
||||
cdp.remove_handler(handler)
|
||||
handler = StringRegexHandler(r'(t)est(.*)', self.callback_context_pattern)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update('test message')
|
||||
assert self.test_flag
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
from collections import OrderedDict
|
||||
from queue import Queue
|
||||
|
||||
import pytest
|
||||
|
||||
from telegram import Bot
|
||||
from telegram.ext import TypeHandler
|
||||
from telegram.ext import TypeHandler, CallbackContext, JobQueue
|
||||
|
||||
|
||||
class TestTypeHandler(object):
|
||||
|
@ -42,6 +43,15 @@ class TestTypeHandler(object):
|
|||
def callback_queue_2(self, bot, update, job_queue=None, update_queue=None):
|
||||
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)
|
||||
|
||||
def test_basic(self, dp):
|
||||
handler = TypeHandler(dict, self.callback_basic)
|
||||
dp.add_handler(handler)
|
||||
|
@ -65,7 +75,8 @@ class TestTypeHandler(object):
|
|||
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
|
||||
|
@ -80,3 +91,10 @@ class TestTypeHandler(object):
|
|||
self.test_flag = False
|
||||
dp.process_update({'a': 1, 'b': 2})
|
||||
assert self.test_flag
|
||||
|
||||
def test_context(self, cdp):
|
||||
handler = TypeHandler(dict, self.callback_context)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
cdp.process_update({'a': 1, 'b': 2})
|
||||
assert self.test_flag
|
||||
|
|
Loading…
Reference in a new issue