Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Automatic pass_* for Handlers using reflection: Autowiring#859

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
JosXa wants to merge18 commits intomasterfrommagic-arg-passing
Closed
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
18 commits
Select commitHold shift + click to select a range
d19af21
Initial version of autowire
JosXaOct 6, 2017
bf15f54
Changed order of keyword arguments in the hope that no user has treat…
JosXaOct 6, 2017
1243680
Stable autowiring functionality
JosXaOct 6, 2017
cafd9f8
Added autowiring example
JosXaOct 6, 2017
10e4aee
Extended autowiring example
JosXaOct 6, 2017
44b922e
Added tests and more elaborate documentation for autowire
JosXaOct 6, 2017
9c6efb8
Fixed StringCommandHandler pass-flags
JosXaOct 6, 2017
6f02143
Comment changed
JosXaOct 6, 2017
284e606
Fixing tests that only fail on Travis
JosXaOct 6, 2017
cd4aded
Reduced method complexity
JosXaOct 6, 2017
05c16a1
Fixed small test problems
JosXaOct 6, 2017
b388d1a
Implemented test for base class `Handler` and fixed order of instruct…
JosXaOct 6, 2017
5da1bb1
Switched to setattr() to reduce cyclomatic complexity
JosXaOct 7, 2017
1216fa3
Making flake8 happy
JosXaOct 7, 2017
6f308e8
Making flake8 happy
JosXaOct 7, 2017
9403113
Removed unneeded tuple return values
JosXaOct 7, 2017
2339606
Added erroneous parameter definition callback
JosXaOct 7, 2017
287007f
Added erroneous parameter definition callback
JosXaOct 7, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletionsexamples/autowiring.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Bot that displays the autowiring functionality
# This program is dedicated to the public domain under the CC0 license.
"""
This bot shows how to use `autowire=True` in Handler definitions to save a lot of effort typing
the explicit pass_* flags.

Usage:
Autowiring example: Try sending /start, /data, "My name is Leandro", or some random text.
Press Ctrl-C on the command line or send a signal to the process to stop the
bot.
"""

import logging

from telegram.ext import Updater, CommandHandler, RegexHandler

# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)

logger = logging.getLogger(__name__)


def error(bot, update, error):
logger.warning('Update "%s" caused error "%s"' % (update, error))


def start(bot, update, args):
query = ' '.join(args) # `args` is magically defined
if query:
update.message.reply_text(query)
else:
update.message.reply_text("Example: /start here I am")


def simple_update_only(update):
"""
A simple handler that only needs an `update` object.
Useful e.g. for basic commands like /help that need to do nothing but reply with some text.
"""
update.message.reply_text("This should have produced an error "
"for the MessageHandler in group=1.")


def callback_with_data(bot, update, chat_data, user_data):
msg = 'Adding something to chat_data...\n'
chat_data['value'] = "I'm a chat_data value"
msg += chat_data['value']

msg += '\n\n'

msg += 'Adding something to user_data...\n'
user_data['value'] = "I'm a user_data value"
msg += user_data['value']

update.message.reply_text(msg, quote=True)


def regex_with_groups(bot, update, groups, groupdict):
update.message.reply_text("Nice, your {} is {}.".format(groups[0], groups[1]))
update.message.reply_text('Groupdict: {}'.format(groupdict))


def callback_undefined_arguments(bot, update, chat_data, groups):
pass


def main():
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")

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

# Inject the `args` parameter automagically
dp.add_handler(CommandHandler("start", start, autowire=True))

# A RegexHandler example where `groups` and `groupdict` are passed automagically
# Examples: Send "My name is Leandro" or "My cat is blue".
dp.add_handler(RegexHandler(r'[Mm]y (?P<object>.*) is (?P<value>.*)',
regex_with_groups,
autowire=True))

# This will raise an error because the bot argument is missing...
dp.add_handler(CommandHandler('help', simple_update_only), group=1)
# ... but with the autowiring capability, you can have callbacks with only an `update` argument.
dp.add_handler(CommandHandler('help', simple_update_only, autowire=True), group=2)

# Passing `chat_data` and `user_data` explicitly...
dp.add_handler(CommandHandler("data", callback_with_data,
pass_chat_data=True,
pass_user_data=True))
# ... is equivalent to passing them automagically.
dp.add_handler(CommandHandler("data", callback_with_data, autowire=True))

# An example of using the `groups` parameter which is not defined for a CommandHandler.
# Uncomment the line below and you will see a warning.
# dp.add_handler(CommandHandler("erroneous", callback_undefined_arguments, autowire=True))

dp.add_error_handler(error)
updater.start_polling()

# Run the bot until you press Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT. This should be used most of the time, since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()


if __name__ == '__main__':
main()
17 changes: 15 additions & 2 deletionstelegram/ext/callbackqueryhandler.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,8 @@ class CallbackQueryHandler(Handler):

Attributes:
callback (:obj:`callable`): The callback function for this handler.
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
callback function automatically.
pass_update_queue (:obj:`bool`): Optional. 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
Expand All@@ -58,6 +60,10 @@ class CallbackQueryHandler(Handler):
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.
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
inspected for positional arguments and be passed objects whose names match any of the
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
``autowire`` will yield a warning.
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`
Expand All@@ -79,11 +85,11 @@ class CallbackQueryHandler(Handler):
``user_data`` will be passed to the callback function. Default is ``False``.
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``.

"""

def __init__(self,
callback,
autowire=False,
pass_update_queue=False,
pass_job_queue=False,
pattern=None,
Expand All@@ -93,6 +99,7 @@ def __init__(self,
pass_chat_data=False):
super(CallbackQueryHandler, self).__init__(
callback,
autowire=autowire,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
Expand All@@ -105,6 +112,10 @@ def __init__(self,
self.pass_groups = pass_groups
self.pass_groupdict = pass_groupdict

if self.autowire:
self.set_autowired_flags(passable={'groups', 'groupdict', 'user_data',
'chat_data', 'update_queue', 'job_queue'})

def check_update(self, update):
"""Determines whether an update should be passed to this handlers :attr:`callback`.

Expand All@@ -131,7 +142,9 @@ def handle_update(self, update, dispatcher):
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.

"""
positional_args = self.collect_bot_update_args(dispatcher, update)
optional_args = self.collect_optional_args(dispatcher, update)

if self.pattern:
match = re.match(self.pattern, update.callback_query.data)

Expand All@@ -140,4 +153,4 @@ def handle_update(self, update, dispatcher):
if self.pass_groupdict:
optional_args['groupdict'] = match.groupdict()

return self.callback(dispatcher.bot, update, **optional_args)
return self.callback(*positional_args, **optional_args)
13 changes: 12 additions & 1 deletiontelegram/ext/choseninlineresulthandler.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,6 +28,8 @@ class ChosenInlineResultHandler(Handler):

Attributes:
callback (:obj:`callable`): The callback function for this handler.
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
callback function automatically.
pass_update_queue (:obj:`bool`): Optional. 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
Expand All@@ -47,6 +49,10 @@ class ChosenInlineResultHandler(Handler):
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.
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
inspected for positional arguments and be passed objects whose names match any of the
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
``autowire`` will yield a warning.
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`
Expand All@@ -64,16 +70,20 @@ class ChosenInlineResultHandler(Handler):

def __init__(self,
callback,
autowire=False,
pass_update_queue=False,
pass_job_queue=False,
pass_user_data=False,
pass_chat_data=False):
super(ChosenInlineResultHandler, self).__init__(
callback,
autowire=autowire,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
if self.autowire:
self.set_autowired_flags()

def check_update(self, update):
"""Determines whether an update should be passed to this handlers :attr:`callback`.
Expand All@@ -95,9 +105,10 @@ def handle_update(self, update, dispatcher):
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.

"""
positional_args = self.collect_bot_update_args(dispatcher, update)
optional_args = self.collect_optional_args(dispatcher, update)

return self.callback(dispatcher.bot, update, **optional_args)
return self.callback(*positional_args, **optional_args)

# old non-PEP8 Handler methods
m = "telegram.ChosenInlineResultHandler."
Expand Down
23 changes: 18 additions & 5 deletionstelegram/ext/commandhandler.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,8 +21,8 @@

from future.utils import string_types

from .handler import Handler
from telegram import Update
from .handler import Handler


class CommandHandler(Handler):
Expand All@@ -39,6 +39,8 @@ class CommandHandler(Handler):
Filters.
allow_edited (:obj:`bool`): Optional. Determines Whether the handler should also accept
edited messages.
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
callback function automatically.
pass_args (:obj:`bool`): Optional. Determines whether the handler should be passed
``args``.
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
Expand DownExpand Up@@ -68,6 +70,10 @@ class CommandHandler(Handler):
operators (& for and, | for or, ~ for not).
allow_edited (:obj:`bool`, optional): Determines whether the handler should also accept
edited messages. Default is ``False``.
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
inspected for positional arguments and be passed objects whose names match any of the
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
``autowire`` will yield a warning.
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
Expand All@@ -92,25 +98,31 @@ def __init__(self,
callback,
filters=None,
allow_edited=False,
autowire=False,
pass_args=False,
pass_update_queue=False,
pass_job_queue=False,
pass_user_data=False,
pass_chat_data=False):
super(CommandHandler, self).__init__(
callback,
autowire=autowire,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)

self.pass_args = pass_args
if self.autowire:
self.set_autowired_flags(
{'update_queue', 'job_queue', 'user_data', 'chat_data', 'args'})

if isinstance(command, string_types):
self.command = [command.lower()]
else:
self.command = [x.lower() for x in command]
self.filters = filters
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
Expand All@@ -129,8 +141,8 @@ def check_update(self, update):
: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:
Expand DownExpand Up@@ -161,11 +173,12 @@ def handle_update(self, update, dispatcher):
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update.

"""
positional_args = self.collect_bot_update_args(dispatcher, update)
optional_args = self.collect_optional_args(dispatcher, update)

message = update.message or update.edited_message

if self.pass_args:
optional_args['args'] = message.text.split()[1:]

return self.callback(dispatcher.bot, update, **optional_args)
return self.callback(*positional_args, **optional_args)
Loading

[8]ページ先頭

©2009-2025 Movatter.jp