Skip to content

Commit d19af21

Browse files
committed
Initial version of autowire
1 parent 3d00ae2 commit d19af21

File tree

9 files changed

+108
-10
lines changed

9 files changed

+108
-10
lines changed

telegram/ext/callbackqueryhandler.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,18 @@ class CallbackQueryHandler(Handler):
7272
pass_groups (:obj:`bool`, optional): If the callback should be passed the result of
7373
``re.match(pattern, data).groups()`` as a keyword argument called ``groups``.
7474
Default is ``False``
75-
pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of
75+
pass_groupdict (:obj:`bool`, import inspect
76+
77+
try:
78+
def inspect_arguments(func):
79+
args, _, _, defaults = inspect.getargspec(func)
80+
# Filter out positional arguments
81+
kwargs = args[:-len(defaults)]
82+
return kwargs
83+
except Warning: # `getargspec()` is deprecated in Python3
84+
def inspect_arguments(func):
85+
_, varargs, _, _, _, _, _ = inspect.getfullargspec(func)
86+
return varargsoptional): If the callback should be passed the result of
7687
``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``.
7788
Default is ``False``
7889
pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
@@ -84,6 +95,7 @@ class CallbackQueryHandler(Handler):
8495

8596
def __init__(self,
8697
callback,
98+
autowire=False,
8799
pass_update_queue=False,
88100
pass_job_queue=False,
89101
pattern=None,
@@ -93,6 +105,7 @@ def __init__(self,
93105
pass_chat_data=False):
94106
super(CallbackQueryHandler, self).__init__(
95107
callback,
108+
autowire=autowire,
96109
pass_update_queue=pass_update_queue,
97110
pass_job_queue=pass_job_queue,
98111
pass_user_data=pass_user_data,

telegram/ext/commandhandler.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class CommandHandler(Handler):
3939
Filters.
4040
allow_edited (:obj:`bool`): Optional. Determines Whether the handler should also accept
4141
edited messages.
42+
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
43+
callback function automatically.
4244
pass_args (:obj:`bool`): Optional. Determines whether the handler should be passed
4345
``args``.
4446
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
@@ -68,6 +70,11 @@ class CommandHandler(Handler):
6870
operators (& for and, | for or, ~ for not).
6971
allow_edited (:obj:`bool`, optional): Determines whether the handler should also accept
7072
edited messages. Default is ``False``.
73+
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
74+
inspected for positional arguments and pass objects whose names match any of the
75+
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
76+
``autowire`` will yield
77+
a warning.
7178
pass_args (:obj:`bool`, optional): Determines whether the handler should be passed the
7279
arguments passed to the command as a keyword argument called ``args``. It will contain
7380
a list of strings, which is the text following the command split on single or
@@ -92,13 +99,15 @@ def __init__(self,
9299
callback,
93100
filters=None,
94101
allow_edited=False,
102+
autowire=False,
95103
pass_args=False,
96104
pass_update_queue=False,
97105
pass_job_queue=False,
98106
pass_user_data=False,
99107
pass_chat_data=False):
100108
super(CommandHandler, self).__init__(
101109
callback,
110+
autowire=autowire,
102111
pass_update_queue=pass_update_queue,
103112
pass_job_queue=pass_job_queue,
104113
pass_user_data=pass_user_data,

telegram/ext/handler.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@
1717
# You should have received a copy of the GNU Lesser Public License
1818
# along with this program. If not, see [http://www.gnu.org/licenses/].
1919
"""This module contains the base class for handlers as used by the Dispatcher."""
20+
import warnings
21+
22+
from telegram.utils.inspection import get_positional_arguments
2023

2124

2225
class Handler(object):
2326
"""The base class for all update handlers. Create custom handlers by inheriting from it.
2427
2528
Attributes:
2629
callback (:obj:`callable`): The callback function for this handler.
30+
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
31+
callback function automatically.
2732
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
2833
passed to the callback function.
2934
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
@@ -43,6 +48,11 @@ class Handler(object):
4348
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
4449
It will be called when the :attr:`check_update` has determined that an update should be
4550
processed by this handler.
51+
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
52+
inspected for positional arguments and pass objects whose names match any of the
53+
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
54+
``autowire`` will yield
55+
a warning.
4656
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
4757
``update_queue`` will be passed to the callback function. It will be the ``Queue``
4858
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
@@ -60,11 +70,15 @@ class Handler(object):
6070

6171
def __init__(self,
6272
callback,
73+
autowire=False,
6374
pass_update_queue=False,
6475
pass_job_queue=False,
6576
pass_user_data=False,
6677
pass_chat_data=False):
6778
self.callback = callback
79+
self.autowire = autowire
80+
if self.autowire and any((pass_update_queue, pass_job_queue, pass_user_data, pass_chat_data)):
81+
warnings.warn('If `autowire` is set to `True`, it is unnecessary to provide any `pass_*` flags.')
6882
self.pass_update_queue = pass_update_queue
6983
self.pass_job_queue = pass_job_queue
7084
self.pass_user_data = pass_user_data
@@ -108,18 +122,28 @@ def collect_optional_args(self, dispatcher, update=None):
108122
"""
109123
optional_args = dict()
110124

111-
if self.pass_update_queue:
112-
optional_args['update_queue'] = dispatcher.update_queue
113-
if self.pass_job_queue:
114-
optional_args['job_queue'] = dispatcher.job_queue
115-
if self.pass_user_data or self.pass_chat_data:
116-
chat = update.effective_chat
117-
user = update.effective_user
118-
125+
if self.autowire:
126+
callback_args = get_positional_arguments(self.callback)
127+
if 'update_queue' in callback_args:
128+
optional_args['update_queue'] = dispatcher.update_queue
129+
if 'job_queue' in callback_args:
130+
optional_args['job_queue'] = dispatcher.job_queue
131+
if 'user_data' in callback_args:
132+
user = update.effective_user
133+
optional_args['user_data'] = dispatcher.user_data[user.id if user else None]
134+
if 'chat_data' in callback_args:
135+
chat = update.effective_chat
136+
optional_args['chat_data'] = dispatcher.chat_data[chat.id if chat else None]
137+
else:
138+
if self.pass_update_queue:
139+
optional_args['update_queue'] = dispatcher.update_queue
140+
if self.pass_job_queue:
141+
optional_args['job_queue'] = dispatcher.job_queue
119142
if self.pass_user_data:
143+
user = update.effective_user
120144
optional_args['user_data'] = dispatcher.user_data[user.id if user else None]
121-
122145
if self.pass_chat_data:
146+
chat = update.effective_chat
123147
optional_args['chat_data'] = dispatcher.chat_data[chat.id if chat else None]
124148

125149
return optional_args

telegram/ext/inlinequeryhandler.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class InlineQueryHandler(Handler):
3333
3434
Attributes:
3535
callback (:obj:`callable`): The callback function for this handler.
36+
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
37+
callback function automatically.
3638
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
3739
passed to the callback function.
3840
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
@@ -58,6 +60,11 @@ class InlineQueryHandler(Handler):
5860
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
5961
It will be called when the :attr:`check_update` has determined that an update should be
6062
processed by this handler.
63+
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
64+
inspected for positional arguments and pass objects whose names match any of the
65+
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
66+
``autowire`` will yield
67+
a warning.
6168
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
6269
``update_queue`` will be passed to the callback function. It will be the ``Queue``
6370
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
@@ -83,6 +90,7 @@ class InlineQueryHandler(Handler):
8390

8491
def __init__(self,
8592
callback,
93+
autowire=False,
8694
pass_update_queue=False,
8795
pass_job_queue=False,
8896
pattern=None,
@@ -92,6 +100,7 @@ def __init__(self,
92100
pass_chat_data=False):
93101
super(InlineQueryHandler, self).__init__(
94102
callback,
103+
autowire=autowire,
95104
pass_update_queue=pass_update_queue,
96105
pass_job_queue=pass_job_queue,
97106
pass_user_data=pass_user_data,

telegram/ext/messagehandler.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class MessageHandler(Handler):
3131
filters (:obj:`Filter`): Only allow updates with these Filters. See
3232
:mod:`telegram.ext.filters` for a full list of all available filters.
3333
callback (:obj:`callable`): The callback function for this handler.
34+
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
35+
callback function automatically.
3436
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
3537
passed to the callback function.
3638
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
@@ -92,6 +94,7 @@ def __init__(self,
9294
filters,
9395
callback,
9496
allow_edited=False,
97+
autowire=False,
9598
pass_update_queue=False,
9699
pass_job_queue=False,
97100
pass_user_data=False,
@@ -108,6 +111,7 @@ def __init__(self,
108111

109112
super(MessageHandler, self).__init__(
110113
callback,
114+
autowire=autowire,
111115
pass_update_queue=pass_update_queue,
112116
pass_job_queue=pass_job_queue,
113117
pass_user_data=pass_user_data,

telegram/ext/precheckoutqueryhandler.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class PreCheckoutQueryHandler(Handler):
2727
2828
Attributes:
2929
callback (:obj:`callable`): The callback function for this handler.
30+
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
31+
callback function automatically.
3032
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
3133
passed to the callback function.
3234
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
@@ -46,6 +48,11 @@ class PreCheckoutQueryHandler(Handler):
4648
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
4749
It will be called when the :attr:`check_update` has determined that an update should be
4850
processed by this handler.
51+
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
52+
inspected for positional arguments and pass objects whose names match any of the
53+
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
54+
``autowire`` will yield
55+
a warning.
4956
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
5057
``update_queue`` will be passed to the callback function. It will be the ``Queue``
5158
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
@@ -63,12 +70,14 @@ class PreCheckoutQueryHandler(Handler):
6370

6471
def __init__(self,
6572
callback,
73+
autowire=False,
6674
pass_update_queue=False,
6775
pass_job_queue=False,
6876
pass_user_data=False,
6977
pass_chat_data=False):
7078
super(PreCheckoutQueryHandler, self).__init__(
7179
callback,
80+
autowire=autowire,
7281
pass_update_queue=pass_update_queue,
7382
pass_job_queue=pass_job_queue,
7483
pass_user_data=pass_user_data,

telegram/ext/regexhandler.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class RegexHandler(Handler):
3838
Attributes:
3939
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
4040
callback (:obj:`callable`): The callback function for this handler.
41+
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
42+
callback function automatically.
4143
pass_groups (:obj:`bool`): Optional. Determines whether ``groups`` will be passed to the
4244
callback function.
4345
pass_groupdict (:obj:`bool`): Optional. Determines whether ``groupdict``. will be passed to
@@ -62,6 +64,11 @@ class RegexHandler(Handler):
6264
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
6365
It will be called when the :attr:`check_update` has determined that an update should be
6466
processed by this handler.
67+
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
68+
inspected for positional arguments and pass objects whose names match any of the
69+
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
70+
``autowire`` will yield
71+
a warning.
6572
pass_groups (:obj:`bool`, optional): If the callback should be passed the result of
6673
``re.match(pattern, data).groups()`` as a keyword argument called ``groups``.
6774
Default is ``False``
@@ -97,6 +104,7 @@ class RegexHandler(Handler):
97104
def __init__(self,
98105
pattern,
99106
callback,
107+
autowire=False,
100108
pass_groups=False,
101109
pass_groupdict=False,
102110
pass_update_queue=False,
@@ -117,6 +125,7 @@ def __init__(self,
117125

118126
super(RegexHandler, self).__init__(
119127
callback,
128+
autowire=autowire,
120129
pass_update_queue=pass_update_queue,
121130
pass_job_queue=pass_job_queue,
122131
pass_user_data=pass_user_data,

telegram/ext/shippingqueryhandler.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class ShippingQueryHandler(Handler):
2727
2828
Attributes:
2929
callback (:obj:`callable`): The callback function for this handler.
30+
autowire (:obj:`bool`): Optional. Determines whether objects will be passed to the
31+
callback function automatically.
3032
pass_update_queue (:obj:`bool`): Optional. Determines whether ``update_queue`` will be
3133
passed to the callback function.
3234
pass_job_queue (:obj:`bool`): Optional. Determines whether ``job_queue`` will be passed to
@@ -46,6 +48,11 @@ class ShippingQueryHandler(Handler):
4648
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
4749
It will be called when the :attr:`check_update` has determined that an update should be
4850
processed by this handler.
51+
autowire (:obj:`bool`, optional): If set to ``True``, your callback handler will be
52+
inspected for positional arguments and pass objects whose names match any of the
53+
``pass_*`` flags of this Handler. Using any ``pass_*`` argument in conjunction with
54+
``autowire`` will yield
55+
a warning.
4956
pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
5057
``update_queue`` will be passed to the callback function. It will be the ``Queue``
5158
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
@@ -63,12 +70,14 @@ class ShippingQueryHandler(Handler):
6370

6471
def __init__(self,
6572
callback,
73+
autowire=False,
6674
pass_update_queue=False,
6775
pass_job_queue=False,
6876
pass_user_data=False,
6977
pass_chat_data=False):
7078
super(ShippingQueryHandler, self).__init__(
7179
callback,
80+
autowire=autowire,
7281
pass_update_queue=pass_update_queue,
7382
pass_job_queue=pass_job_queue,
7483
pass_user_data=pass_user_data,

telegram/utils/inspection.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import inspect
2+
3+
try:
4+
def get_positional_arguments(func):
5+
args, _, _, defaults = inspect.getargspec(func)
6+
# Filter out positional arguments
7+
kwargs = args[:-len(defaults)]
8+
return kwargs
9+
except Warning: # `getargspec()` is deprecated in Python3
10+
def get_positional_arguments(func):
11+
_, varargs, _, _, _, _, _ = inspect.getfullargspec(func)
12+
return varargs

0 commit comments

Comments
 (0)