mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-26 16:38:53 +01:00
Add WAITING state and behavior (#1344)
* Add WAITING state and behavior * Remove `run_async_timeout` and `timed_out_behavior` arguments * replace with `WAITING` constant and behavior from states * never wait for promise to resolve (will hang up entire update queue * see #1250 for discussion * Fixing pytest version to 4.2.0 Pytest 4.2.1 has a weird bug on top level collect in 4.2.1 Fixing version to 4.2.0
This commit is contained in:
parent
7e2dbdd4b3
commit
cd7c642f49
2 changed files with 13 additions and 25 deletions
|
@ -5,6 +5,6 @@ flaky
|
||||||
yapf
|
yapf
|
||||||
pre-commit
|
pre-commit
|
||||||
beautifulsoup4
|
beautifulsoup4
|
||||||
pytest>=3.8.1
|
pytest==4.2.0
|
||||||
pytest-timeout
|
pytest-timeout
|
||||||
wheel
|
wheel
|
||||||
|
|
|
@ -46,7 +46,9 @@ class ConversationHandler(Handler):
|
||||||
The second collection, a ``dict`` named :attr:`states`, contains the different conversation
|
The second collection, a ``dict`` named :attr:`states`, contains the different conversation
|
||||||
steps and one or more associated handlers that should be used if the user sends a message when
|
steps and one or more associated handlers that should be used if the user sends a message when
|
||||||
the conversation with them is currently in that state. Here you can also define a state for
|
the conversation with them is currently in that state. Here you can also define a state for
|
||||||
:attr:`TIMEOUT` to define the behavior when :attr:`conversation_timeout` is exceeded.
|
:attr:`TIMEOUT` to define the behavior when :attr:`conversation_timeout` is exceeded, and a
|
||||||
|
state for :attr:`WAITING` to define behavior when a new update is received while the previous
|
||||||
|
``@run_async`` decorated handler is not finished.
|
||||||
|
|
||||||
The third collection, a ``list`` named :attr:`fallbacks`, is used if the user is currently in a
|
The third collection, a ``list`` named :attr:`fallbacks`, is used if the user is currently in a
|
||||||
conversation but the state has either no associated handler or the handler that is associated
|
conversation but the state has either no associated handler or the handler that is associated
|
||||||
|
@ -76,10 +78,6 @@ class ConversationHandler(Handler):
|
||||||
``False`` on :attr:`check_update`.
|
``False`` on :attr:`check_update`.
|
||||||
allow_reentry (:obj:`bool`): 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.
|
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`): If the conversationkey should contain the Chat's ID.
|
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_user (:obj:`bool`): If the conversationkey should contain the User's ID.
|
||||||
per_message (:obj:`bool`): If the conversationkey should contain the Message's
|
per_message (:obj:`bool`): If the conversationkey should contain the Message's
|
||||||
|
@ -109,15 +107,6 @@ class ConversationHandler(Handler):
|
||||||
returns ``True`` will be used. If all return ``False``, the update is not handled.
|
returns ``True`` will be used. If all return ``False``, the update is not handled.
|
||||||
allow_reentry (:obj:`bool`, optional): If set to ``True``, a user that is currently in a
|
allow_reentry (:obj:`bool`, optional): If set to ``True``, a user that is currently in a
|
||||||
conversation can restart the conversation by triggering one of the entry points.
|
conversation can restart the conversation by triggering one of the entry points.
|
||||||
run_async_timeout (:obj:`float`, optional): If the previous handler for this user was
|
|
||||||
running asynchronously using the ``run_async`` decorator, it might not be finished when
|
|
||||||
the next message arrives. This timeout defines how long the conversation handler should
|
|
||||||
wait for the next state to be computed. The default is ``None`` which means it will
|
|
||||||
wait indefinitely.
|
|
||||||
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. The first handler which
|
|
||||||
:attr:`check_update` method returns ``True`` will be used. If all return ``False``,
|
|
||||||
the update is not handled.
|
|
||||||
per_chat (:obj:`bool`, optional): If the conversationkey should contain the Chat's ID.
|
per_chat (:obj:`bool`, optional): If the conversationkey should contain the Chat's ID.
|
||||||
Default is ``True``.
|
Default is ``True``.
|
||||||
per_user (:obj:`bool`, optional): If the conversationkey should contain the User's ID.
|
per_user (:obj:`bool`, optional): If the conversationkey should contain the User's ID.
|
||||||
|
@ -142,14 +131,15 @@ class ConversationHandler(Handler):
|
||||||
""":obj:`int`: Used as a constant to return when a conversation is ended."""
|
""":obj:`int`: Used as a constant to return when a conversation is ended."""
|
||||||
TIMEOUT = -2
|
TIMEOUT = -2
|
||||||
""":obj:`int`: Used as a constant to handle state when a conversation is timed out."""
|
""":obj:`int`: Used as a constant to handle state when a conversation is timed out."""
|
||||||
|
WAITING = -3
|
||||||
|
""":obj:`int`: Used as a constant to handle state when a conversation is still waiting on the
|
||||||
|
previous ``@run_sync`` decorated running handler to finish."""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
entry_points,
|
entry_points,
|
||||||
states,
|
states,
|
||||||
fallbacks,
|
fallbacks,
|
||||||
allow_reentry=False,
|
allow_reentry=False,
|
||||||
run_async_timeout=None,
|
|
||||||
timed_out_behavior=None,
|
|
||||||
per_chat=True,
|
per_chat=True,
|
||||||
per_user=True,
|
per_user=True,
|
||||||
per_message=False,
|
per_message=False,
|
||||||
|
@ -162,8 +152,6 @@ class ConversationHandler(Handler):
|
||||||
self.fallbacks = fallbacks
|
self.fallbacks = fallbacks
|
||||||
|
|
||||||
self.allow_reentry = allow_reentry
|
self.allow_reentry = allow_reentry
|
||||||
self.run_async_timeout = run_async_timeout
|
|
||||||
self.timed_out_behavior = timed_out_behavior
|
|
||||||
self.per_user = per_user
|
self.per_user = per_user
|
||||||
self.per_chat = per_chat
|
self.per_chat = per_chat
|
||||||
self.per_message = per_message
|
self.per_message = per_message
|
||||||
|
@ -259,9 +247,9 @@ class ConversationHandler(Handler):
|
||||||
self.logger.debug('waiting for promise...')
|
self.logger.debug('waiting for promise...')
|
||||||
|
|
||||||
old_state, new_state = state
|
old_state, new_state = state
|
||||||
if new_state.done.wait(timeout=self.run_async_timeout):
|
if new_state.done.wait(0):
|
||||||
try:
|
try:
|
||||||
res = new_state.result(timeout=0)
|
res = new_state.result(0)
|
||||||
res = res if res is not None else old_state
|
res = res if res is not None else old_state
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.logger.exception("Promise function raised exception")
|
self.logger.exception("Promise function raised exception")
|
||||||
|
@ -271,11 +259,11 @@ class ConversationHandler(Handler):
|
||||||
self.update_state(res, key)
|
self.update_state(res, key)
|
||||||
state = self.conversations.get(key)
|
state = self.conversations.get(key)
|
||||||
else:
|
else:
|
||||||
for candidate in (self.timed_out_behavior or []):
|
handlers = self.states.get(self.WAITING, [])
|
||||||
check = candidate.check_update(update)
|
for handler in handlers:
|
||||||
|
check = handler.check_update(update)
|
||||||
if check is not None and check is not False:
|
if check is not None and check is not False:
|
||||||
# Save the current user and the selected handler for handle_update
|
return key, handler, check
|
||||||
return key, candidate, check
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
self.logger.debug('selecting conversation %s with state %s' % (str(key), str(state)))
|
self.logger.debug('selecting conversation %s with state %s' % (str(key), str(state)))
|
||||||
|
|
Loading…
Add table
Reference in a new issue