Skip to content

Commit 247577b

Browse files
authored
Context based callbacks (python-telegram-bot#1100)
See https://github.com/python-telegram-bot/python-telegram-bot/wiki/Transition-guide-to-Version-11.0 under Context based callbacks and Filters in handlers for a good guide on the changes in this commit. * Change handlers so context is supported * Attempt to make parameter "guessing" work on py < 3.5 * Document use_context in all handlers * Add Context to docs * Minor fixes to context handling * Add tests for context stuff * Allow the signature check to work on py<3.5 with methods * Fix order of operations * Address most issues raised in CR * Make CommandHandler no longer support filter lists * Fix indent (pycharm can be an arse sometimes) * Improve readability in conversationhandler * Make context have Match instead of groups & groupdict * Remove filter list support from messagehandler too * Small fix to StringCommandHandler * More small fixes to handlers * Amend CHANGES * Fix tests and fix bugs raised by tests * Don't allow users to ignore errors without messing with the warning filters themselves * Ignore our own deprecation warnings when testing * Skipping deprecationwarning test on py2 * Forgot some changes * Handler: Improved documentation and text of deprecation warnings * HandlerContext: Keep only dispatcher and use properties; improved doc * Complete fixing the documentation. - Fixes per Eldinnie's comments. - Fixes per warnings when running sphinx. * Some small doc fixes (interlinks and optionals) * Change add_error_handler to use HandlerContext too * More context based changes Context Based Handlers -> Context Based Callbacks No longer use_context args on every single Handler Instead set dispatcher/updater .use_context=True to use Works with - Handler callbacks - Error handler callbacks - Job callbacks Change examples to context based callbacks so new users are not confused Rename and move the context object from Handlers.HandlerContext to CallbackContext, since it doesn't only apply to handlers anymore. Fix tests by adding a new fixture `cpd` which is a dispatcher with use_context=True * Forgot about conversationhandler * Forgot jobqueue * Add tests for callbackcontext & for context based callback job * Fix as per review :)
1 parent 94abf16 commit 247577b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1390
-618
lines changed

CHANGES.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
=======
22
Changes
33
=======
4+
**2018-??-??**
5+
*Released 11.0.0*
6+
7+
Context based callbacks:
8+
See https://git.io/vp113 for help.
9+
10+
- Use of `pass_` in handlers is deprecated.
11+
- Instead use `use_context=True` on `Updater` or `Dispatcher` and change callback from (bot, update, others...) to (update, context).
12+
- This also applies to error handlers `Dispatcher.add_error_handler` and JobQueue jobs (change (bot, job) to (context) here).
13+
- 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.
14+
- Passing bot to JobQueue.__init__ is deprecated. Use JobQueue.set_dispatcher with a dispatcher instead.
15+
16+
Other:
17+
- Handlers should be faster due to deduped logic.
18+
19+
Other removals:
20+
- Remove the ability to use filter lists in handlers.
21+
- Remove the last CamelCase CheckUpdate methods from the handlers we missed earlier.
22+
23+
424
**2018-05-02**
525
*Released 10.1.0*
626

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
telegram.ext.CallbackContext
2+
============================
3+
4+
.. autoclass:: telegram.ext.CallbackContext
5+
:members:

docs/source/telegram.ext.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ telegram.ext package
1010
telegram.ext.jobqueue
1111
telegram.ext.messagequeue
1212
telegram.ext.delayqueue
13+
telegram.ext.callbackcontext
1314

1415
Handlers
1516
--------

examples/conversationbot.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
bot.
1818
"""
1919

20+
import logging
21+
2022
from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove)
2123
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
2224
ConversationHandler)
2325

24-
import logging
25-
2626
# Enable logging
2727
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
2828
level=logging.INFO)
@@ -32,7 +32,7 @@
3232
GENDER, PHOTO, LOCATION, BIO = range(4)
3333

3434

35-
def start(bot, update):
35+
def start(update, context):
3636
reply_keyboard = [['Boy', 'Girl', 'Other']]
3737

3838
update.message.reply_text(
@@ -44,7 +44,7 @@ def start(bot, update):
4444
return GENDER
4545

4646

47-
def gender(bot, update):
47+
def gender(update, context):
4848
user = update.message.from_user
4949
logger.info("Gender of %s: %s", user.first_name, update.message.text)
5050
update.message.reply_text('I see! Please send me a photo of yourself, '
@@ -54,9 +54,9 @@ def gender(bot, update):
5454
return PHOTO
5555

5656

57-
def photo(bot, update):
57+
def photo(update, context):
5858
user = update.message.from_user
59-
photo_file = bot.get_file(update.message.photo[-1].file_id)
59+
photo_file = update.message.photo[-1].get_file()
6060
photo_file.download('user_photo.jpg')
6161
logger.info("Photo of %s: %s", user.first_name, 'user_photo.jpg')
6262
update.message.reply_text('Gorgeous! Now, send me your location please, '
@@ -65,7 +65,7 @@ def photo(bot, update):
6565
return LOCATION
6666

6767

68-
def skip_photo(bot, update):
68+
def skip_photo(update, context):
6969
user = update.message.from_user
7070
logger.info("User %s did not send a photo.", user.first_name)
7171
update.message.reply_text('I bet you look great! Now, send me your location please, '
@@ -74,7 +74,7 @@ def skip_photo(bot, update):
7474
return LOCATION
7575

7676

77-
def location(bot, update):
77+
def location(update, context):
7878
user = update.message.from_user
7979
user_location = update.message.location
8080
logger.info("Location of %s: %f / %f", user.first_name, user_location.latitude,
@@ -85,7 +85,7 @@ def location(bot, update):
8585
return BIO
8686

8787

88-
def skip_location(bot, update):
88+
def skip_location(update, context):
8989
user = update.message.from_user
9090
logger.info("User %s did not send a location.", user.first_name)
9191
update.message.reply_text('You seem a bit paranoid! '
@@ -94,15 +94,15 @@ def skip_location(bot, update):
9494
return BIO
9595

9696

97-
def bio(bot, update):
97+
def bio(update, context):
9898
user = update.message.from_user
9999
logger.info("Bio of %s: %s", user.first_name, update.message.text)
100100
update.message.reply_text('Thank you! I hope we can talk again some day.')
101101

102102
return ConversationHandler.END
103103

104104

105-
def cancel(bot, update):
105+
def cancel(update, context):
106106
user = update.message.from_user
107107
logger.info("User %s canceled the conversation.", user.first_name)
108108
update.message.reply_text('Bye! I hope we can talk again some day.',
@@ -111,14 +111,16 @@ def cancel(bot, update):
111111
return ConversationHandler.END
112112

113113

114-
def error(bot, update, error):
114+
def error(update, context):
115115
"""Log Errors caused by Updates."""
116-
logger.warning('Update "%s" caused error "%s"', update, error)
116+
logger.warning('Update "%s" caused error "%s"', update, context.error)
117117

118118

119119
def main():
120-
# Create the EventHandler and pass it your bot's token.
121-
updater = Updater("TOKEN")
120+
# Create the Updater and pass it your bot's token.
121+
# Make sure to set use_context=True to use the new context based callbacks
122+
# Post version 12 this will no longer be necessary
123+
updater = Updater("TOKEN", use_context=True)
122124

123125
# Get the dispatcher to register handlers
124126
dp = updater.dispatcher

examples/conversationbot2.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
bot.
1818
"""
1919

20+
import logging
21+
2022
from telegram import ReplyKeyboardMarkup
2123
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
2224
ConversationHandler)
2325

24-
import logging
25-
2626
# Enable logging
2727
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
2828
level=logging.INFO)
@@ -46,7 +46,7 @@ def facts_to_str(user_data):
4646
return "\n".join(facts).join(['\n', '\n'])
4747

4848

49-
def start(bot, update):
49+
def start(update, context):
5050
update.message.reply_text(
5151
"Hi! My name is Doctor Botter. I will hold a more complex conversation with you. "
5252
"Why don't you tell me something about yourself?",
@@ -55,23 +55,24 @@ def start(bot, update):
5555
return CHOOSING
5656

5757

58-
def regular_choice(bot, update, user_data):
58+
def regular_choice(update, context):
5959
text = update.message.text
60-
user_data['choice'] = text
60+
context.user_data['choice'] = text
6161
update.message.reply_text(
6262
'Your {}? Yes, I would love to hear about that!'.format(text.lower()))
6363

6464
return TYPING_REPLY
6565

6666

67-
def custom_choice(bot, update):
67+
def custom_choice(update, context):
6868
update.message.reply_text('Alright, please send me the category first, '
6969
'for example "Most impressive skill"')
7070

7171
return TYPING_CHOICE
7272

7373

74-
def received_information(bot, update, user_data):
74+
def received_information(update, context):
75+
user_data = context.user_data
7576
text = update.message.text
7677
category = user_data['choice']
7778
user_data[category] = text
@@ -85,7 +86,8 @@ def received_information(bot, update, user_data):
8586
return CHOOSING
8687

8788

88-
def done(bot, update, user_data):
89+
def done(update, context):
90+
user_data = context.user_data
8991
if 'choice' in user_data:
9092
del user_data['choice']
9193

@@ -97,14 +99,16 @@ def done(bot, update, user_data):
9799
return ConversationHandler.END
98100

99101

100-
def error(bot, update, error):
102+
def error(update, context):
101103
"""Log Errors caused by Updates."""
102104
logger.warning('Update "%s" caused error "%s"', update, error)
103105

104106

105107
def main():
106108
# Create the Updater and pass it your bot's token.
107-
updater = Updater("TOKEN")
109+
# Make sure to set use_context=True to use the new context based callbacks
110+
# Post version 12 this will no longer be necessary
111+
updater = Updater("TOKEN", use_context=True)
108112

109113
# Get the dispatcher to register handlers
110114
dp = updater.dispatcher

examples/echobot2.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
bot.
1818
"""
1919

20-
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
2120
import logging
2221

22+
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
23+
2324
# Enable logging
2425
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
2526
level=logging.INFO)
@@ -29,30 +30,32 @@
2930

3031
# Define a few command handlers. These usually take the two arguments bot and
3132
# update. Error handlers also receive the raised TelegramError object in error.
32-
def start(bot, update):
33+
def start(update, context):
3334
"""Send a message when the command /start is issued."""
3435
update.message.reply_text('Hi!')
3536

3637

37-
def help(bot, update):
38+
def help(update, context):
3839
"""Send a message when the command /help is issued."""
3940
update.message.reply_text('Help!')
4041

4142

42-
def echo(bot, update):
43+
def echo(update, context):
4344
"""Echo the user message."""
4445
update.message.reply_text(update.message.text)
4546

4647

47-
def error(bot, update, error):
48+
def error(update, context):
4849
"""Log Errors caused by Updates."""
49-
logger.warning('Update "%s" caused error "%s"', update, error)
50+
logger.warning('Update "%s" caused error "%s"', update, context.error)
5051

5152

5253
def main():
5354
"""Start the bot."""
54-
# Create the EventHandler and pass it your bot's token.
55-
updater = Updater("TOKEN")
55+
# Create the Updater and pass it your bot's token.
56+
# Make sure to set use_context=True to use the new context based callbacks
57+
# Post version 12 this will no longer be necessary
58+
updater = Updater("TOKEN", use_context=True)
5659

5760
# Get the dispatcher to register handlers
5861
dp = updater.dispatcher

examples/inlinebot.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616
Press Ctrl-C on the command line or send a signal to the process to stop the
1717
bot.
1818
"""
19+
import logging
1920
from uuid import uuid4
2021

21-
from telegram.utils.helpers import escape_markdown
22-
2322
from telegram import InlineQueryResultArticle, ParseMode, \
2423
InputTextMessageContent
2524
from telegram.ext import Updater, InlineQueryHandler, CommandHandler
26-
import logging
25+
from telegram.utils.helpers import escape_markdown
2726

2827
# Enable logging
2928
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
@@ -34,17 +33,17 @@
3433

3534
# Define a few command handlers. These usually take the two arguments bot and
3635
# update. Error handlers also receive the raised TelegramError object in error.
37-
def start(bot, update):
36+
def start(update, context):
3837
"""Send a message when the command /start is issued."""
3938
update.message.reply_text('Hi!')
4039

4140

42-
def help(bot, update):
41+
def help(update, context):
4342
"""Send a message when the command /help is issued."""
4443
update.message.reply_text('Help!')
4544

4645

47-
def inlinequery(bot, update):
46+
def inlinequery(update, context):
4847
"""Handle the inline query."""
4948
query = update.inline_query.query
5049
results = [
@@ -69,14 +68,16 @@ def inlinequery(bot, update):
6968
update.inline_query.answer(results)
7069

7170

72-
def error(bot, update, error):
71+
def error(update, context):
7372
"""Log Errors caused by Updates."""
74-
logger.warning('Update "%s" caused error "%s"', update, error)
73+
logger.warning('Update "%s" caused error "%s"', update, context.error)
7574

7675

7776
def main():
7877
# Create the Updater and pass it your bot's token.
79-
updater = Updater("TOKEN")
78+
# Make sure to set use_context=True to use the new context based callbacks
79+
# Post version 12 this will no longer be necessary
80+
updater = Updater("TOKEN", use_context=True)
8081

8182
# Get the dispatcher to register handlers
8283
dp = updater.dispatcher

examples/inlinekeyboard.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# This program is dedicated to the public domain under the CC0 license.
66
"""
77
import logging
8+
89
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
910
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
1011

@@ -13,7 +14,7 @@
1314
logger = logging.getLogger(__name__)
1415

1516

16-
def start(bot, update):
17+
def start(update, context):
1718
keyboard = [[InlineKeyboardButton("Option 1", callback_data='1'),
1819
InlineKeyboardButton("Option 2", callback_data='2')],
1920

@@ -24,26 +25,26 @@ def start(bot, update):
2425
update.message.reply_text('Please choose:', reply_markup=reply_markup)
2526

2627

27-
def button(bot, update):
28+
def button(update, context):
2829
query = update.callback_query
2930

30-
bot.edit_message_text(text="Selected option: {}".format(query.data),
31-
chat_id=query.message.chat_id,
32-
message_id=query.message.message_id)
31+
query.edit_message_text(text="Selected option: {}".format(query.data))
3332

3433

35-
def help(bot, update):
34+
def help(update, context):
3635
update.message.reply_text("Use /start to test this bot.")
3736

3837

39-
def error(bot, update, error):
38+
def error(update, context):
4039
"""Log Errors caused by Updates."""
41-
logger.warning('Update "%s" caused error "%s"', update, error)
40+
logger.warning('Update "%s" caused error "%s"', update, context.error)
4241

4342

4443
def main():
4544
# Create the Updater and pass it your bot's token.
46-
updater = Updater("TOKEN")
45+
# Make sure to set use_context=True to use the new context based callbacks
46+
# Post version 12 this will no longer be necessary
47+
updater = Updater("TOKEN", use_context=True)
4748

4849
updater.dispatcher.add_handler(CommandHandler('start', start))
4950
updater.dispatcher.add_handler(CallbackQueryHandler(button))

0 commit comments

Comments
 (0)