mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-17 04:39:55 +01:00
Pass last valid context to TIMEOUT handlers (#1826)
This commit is contained in:
parent
3101ea8432
commit
bdf0cb91f3
2 changed files with 48 additions and 7 deletions
|
@ -29,10 +29,11 @@ from telegram.utils.promise import Promise
|
|||
|
||||
|
||||
class _ConversationTimeoutContext(object):
|
||||
def __init__(self, conversation_key, update, dispatcher):
|
||||
def __init__(self, conversation_key, update, dispatcher, callback_context):
|
||||
self.conversation_key = conversation_key
|
||||
self.update = update
|
||||
self.dispatcher = dispatcher
|
||||
self.callback_context = callback_context
|
||||
|
||||
|
||||
class ConversationHandler(Handler):
|
||||
|
@ -96,8 +97,9 @@ class ConversationHandler(Handler):
|
|||
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 this value is 0 (default), there will be no timeout. When it's triggered, the
|
||||
last received update will be handled by ALL the handler's who's `check_update` method
|
||||
returns True that are in the state :attr:`ConversationHandler.TIMEOUT`.
|
||||
last received update and the corresponding ``context`` will be handled by ALL the
|
||||
handler's who's `check_update` method returns True that are in the state
|
||||
:attr:`ConversationHandler.TIMEOUT`.
|
||||
name (:obj:`str`): Optional. The name for this conversationhandler. Required for
|
||||
persistence
|
||||
persistent (:obj:`bool`): Optional. If the conversations dict for this handler should be
|
||||
|
@ -130,8 +132,9 @@ class ConversationHandler(Handler):
|
|||
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 this value is 0 or None (default), there will be no timeout. The last
|
||||
received update will be handled by ALL the handler's who's `check_update` method
|
||||
returns True that are in the state :attr:`ConversationHandler.TIMEOUT`.
|
||||
received update and the corresponding ``context`` will be handled by ALL the handler's
|
||||
who's `check_update` method returns True that are in the state
|
||||
:attr:`ConversationHandler.TIMEOUT`.
|
||||
name (:obj:`str`, optional): The name for this conversationhandler. Required for
|
||||
persistence
|
||||
persistent (:obj:`bool`, optional): If the conversations dict for this handler should be
|
||||
|
@ -466,7 +469,8 @@ class ConversationHandler(Handler):
|
|||
# Add the new timeout job
|
||||
self.timeout_jobs[conversation_key] = dispatcher.job_queue.run_once(
|
||||
self._trigger_timeout, self.conversation_timeout,
|
||||
context=_ConversationTimeoutContext(conversation_key, update, dispatcher))
|
||||
context=_ConversationTimeoutContext(conversation_key, update,
|
||||
dispatcher, context))
|
||||
|
||||
if isinstance(self.map_to_parent, dict) and new_state in self.map_to_parent:
|
||||
self.update_state(self.END, conversation_key)
|
||||
|
@ -503,9 +507,9 @@ class ConversationHandler(Handler):
|
|||
callback_context = None
|
||||
if isinstance(context, CallbackContext):
|
||||
job = context.job
|
||||
callback_context = context
|
||||
|
||||
context = job.context
|
||||
callback_context = context.callback_context
|
||||
|
||||
with self._timeout_jobs_lock:
|
||||
found_job = self.timeout_jobs[context.conversation_key]
|
||||
|
|
|
@ -546,6 +546,43 @@ class TestConversationHandler(object):
|
|||
dp.job_queue.tick()
|
||||
assert handler.conversations.get((self.group.id, user1.id)) is None
|
||||
|
||||
def test_conversation_handler_timeout_update_and_context(self, cdp, bot, user1):
|
||||
context = None
|
||||
|
||||
def start_callback(u, c):
|
||||
nonlocal context, self
|
||||
context = c
|
||||
return self.start(u, c)
|
||||
|
||||
states = self.states
|
||||
timeout_handler = CommandHandler('start', None)
|
||||
states.update({ConversationHandler.TIMEOUT: [timeout_handler]})
|
||||
handler = ConversationHandler(entry_points=[CommandHandler('start', start_callback)],
|
||||
states=states, fallbacks=self.fallbacks,
|
||||
conversation_timeout=0.5)
|
||||
cdp.add_handler(handler)
|
||||
|
||||
# Start state machine, then reach timeout
|
||||
message = Message(0, user1, None, self.group, text='/start',
|
||||
entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0,
|
||||
length=len('/start'))],
|
||||
bot=bot)
|
||||
update = Update(update_id=0, message=message)
|
||||
|
||||
def timeout_callback(u, c):
|
||||
nonlocal update, context, self
|
||||
self.is_timeout = True
|
||||
assert u is update
|
||||
assert c is context
|
||||
|
||||
timeout_handler.callback = timeout_callback
|
||||
|
||||
cdp.process_update(update)
|
||||
sleep(0.5)
|
||||
cdp.job_queue.tick()
|
||||
assert handler.conversations.get((self.group.id, user1.id)) is None
|
||||
assert self.is_timeout
|
||||
|
||||
def test_conversation_timeout_keeps_extending(self, dp, bot, user1):
|
||||
handler = ConversationHandler(entry_points=self.entry_points, states=self.states,
|
||||
fallbacks=self.fallbacks, conversation_timeout=0.5)
|
||||
|
|
Loading…
Add table
Reference in a new issue