U
    g                     @   s  d Z ddlZddlZddlmZ ddlmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZ ddlmZ ddlmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4m5Z5m6Z6 erJddl7m8Z8m9Z9m:Z: ee;e6e$ee4e;f e;f Z<ee=ddZ>eG dd de
e4 Z?eG dd dZ@G dd de$ee4e;f ZAdS )z-This module contains the ConversationHandler.    N)	dataclass)TYPE_CHECKINGAnyDictFinalGenericListNoReturnOptionalSetTupleUnioncast)Update)DEFAULT_TRUEDefaultValue)
get_logger)build_repr_with_selected_attrs)DVType)warn)ApplicationHandlerStop)ExtBot)BaseHandler)CallbackQueryHandler)ChosenInlineResultHandler)InlineQueryHandler)StringCommandHandler)StringRegexHandler)TypeHandler)TrackingDict)CCTConversationDictConversationKey)ApplicationJobJobQueueConversationHandler)
class_namec                   @   s6   e Zd ZU dZdZeed< eed< ded< eed< dS )	_ConversationTimeoutContextzUsed as a datastore for conversation timeouts. Passed in the
    :paramref:`JobQueue.run_once.data` parameter. See :meth:`_trigger_timeout`.
    )applicationcallback_contextconversation_keyupdater+   r,   .Application[Any, CCT, Any, Any, Any, JobQueue]r)   r*   N)	__name__
__module____qualname____doc__	__slots__r"   __annotations__r   r     r4   r4   N/tmp/pip-unpacked-wheel-swnnwir2/telegram/ext/_handlers/conversationhandler.pyr(   ?   s   
r(   c                   @   sD   e Zd ZU dZdZejed< eed< e	dddZ
eddd	Zd
S )PendingStatea  Thin wrapper around :class:`asyncio.Task` to handle block=False handlers. Note that this is
    a public class of this module, since :meth:`Application.update_persistence` needs to access it.
    It's still hidden from users, since this module itself is private.
    	old_statetaskr9   r8   returnc                 C   s
   | j  S N)r9   doneselfr4   r4   r5   r=   Y   s    zPendingState.donec                 C   sj   | j  std| j  }|r4td| j | jS | j  }|dkrX| jdkrXtj}n|dkrf| jS |S )a  Returns the new state of the :class:`ConversationHandler` if available. If there was an
        exception during the task execution, then return the old state. If both the new and old
        state are :obj:`None`, return `CH.END`. If only the new state is :obj:`None`, return the
        old state.

        Raises:
            :exc:`RuntimeError`: If the current task has not yet finished.
        zNew state is not yet availablez<Task function raised exception. Falling back to old state %sN)	r9   r=   RuntimeError	exception_LOGGERr8   resultr&   END)r?   excresr4   r4   r5   resolve\   s    	


zPendingState.resolveN)r.   r/   r0   r1   r2   asyncioTaskr3   objectboolr=   rG   r4   r4   r4   r5   r6   M   s   

r6   c                   @   s  e Zd ZU dZdZdZee ed< dZ	ee ed< dZ
ee ed< d	d
d
d	ddd	def	deeeeef  eeeeeeef  f eeeeef  eeeeeeeejf  ee eeeeef  ee dddZedddZeeeeeef  dddZejeedddZeeeeeeeef  f dddZ e jeedddZ eeeeeef  dddZ!e!jeedddZ!eedddZ"e"jeedddZ"eedd d!Z#e#jeedd"d!Z#eedd#d$Z$e$jeedd%d$Z$eedd&d'Z%e%jeedd(d'Z%eeeeejf  dd)d*Z&e&jeedd+d*Z&eee dd,d-Z'e'jeedd.d-Z'eedd/d0Z(e(jeedd1d0Z(eeeeef  dd2d3Z)e)jeedd4d3Z)d5eee*e+ef f d6d7d8Z,ee+d9d:d;Z-e.j/d<eee+dd=d>d?Z0ed<eee+dd=d@dAZ1eee2e  d9dBdCZ3edDe2e eee dEdFdGZ4dNee+ee ddHdIdJZ5eddKdLdMZ6dS )Or&   a#  
    A handler to hold a conversation with a single or multiple users through Telegram updates by
    managing three collections of other handlers.

    Warning:
        :class:`ConversationHandler` heavily relies on incoming updates being processed one by one.
        When using this handler, :attr:`telegram.ext.ApplicationBuilder.concurrent_updates` should
        be set to :obj:`False`.

    Note:
        :class:`ConversationHandler` will only accept updates that are (subclass-)instances of
        :class:`telegram.Update`. This is, because depending on the :attr:`per_user` and
        :attr:`per_chat`, :class:`ConversationHandler` relies on
        :attr:`telegram.Update.effective_user` and/or :attr:`telegram.Update.effective_chat` in
        order to determine which conversation an update should belong to. For
        :attr:`per_message=True <per_message>`, :class:`ConversationHandler` uses
        :attr:`update.callback_query.message.message_id <telegram.Message.message_id>` when
        :attr:`per_chat=True <per_chat>` and
        :attr:`update.callback_query.inline_message_id <.CallbackQuery.inline_message_id>` when
        :attr:`per_chat=False <per_chat>`. For a more detailed explanation, please see our `FAQ`_.

        Finally, :class:`ConversationHandler`, does *not* handle (edited) channel posts.

    .. _`FAQ`: https://github.com/python-telegram-bot/python-telegram-bot/wiki        /Frequently-Asked-Questions#what-do-the-per_-settings-in-conversation handler-do

    The first collection, a :obj:`list` named :attr:`entry_points`, is used to initiate the
    conversation, for example with a :class:`telegram.ext.CommandHandler` or
    :class:`telegram.ext.MessageHandler`.

    The second collection, a :obj:`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
    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, and a
    state for :attr:`WAITING` to define behavior when a new update is received while the previous
    :attr:`block=False <block>` handler is not finished.

    The third collection, a :obj:`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 to the state is inappropriate for the update, for example if the update contains a
    command, but a regular text message is expected. You could use this for a ``/cancel`` command
    or to let the user know their message was not recognized.

    To change the state of conversation, the callback function of a handler must return the new
    state after responding to the user. If it does not return anything (returning :obj:`None` by
    default), the state will not change. If an entry point callback function returns :obj:`None`,
    the conversation ends immediately after the execution of this callback function.
    To end the conversation, the callback function must return :attr:`END` or ``-1``. To
    handle the conversation timeout, use handler :attr:`TIMEOUT` or ``-2``.
    Finally, :class:`telegram.ext.ApplicationHandlerStop` can be used in conversations as described
    in its documentation.

    Note:
        In each of the described collections of handlers, a handler may in turn be a
        :class:`ConversationHandler`. In that case, the child :class:`ConversationHandler` should
        have the attribute :attr:`map_to_parent` which allows returning to the parent conversation
        at specified states within the child conversation.

        Note that the keys in :attr:`map_to_parent` must not appear as keys in :attr:`states`
        attribute or else the latter will be ignored. You may map :attr:`END` to one of the parents
        states to continue the parent conversation after the child conversation has ended or even
        map a state to :attr:`END` to end the *parent* conversation from within the child
        conversation. For an example on nested :class:`ConversationHandler` s, see
        :any:`examples.nestedconversationbot`.

    Examples:
        * :any:`Conversation Bot <examples.conversationbot>`
        * :any:`Conversation Bot 2 <examples.conversationbot2>`
        * :any:`Nested Conversation Bot <examples.nestedconversationbot>`
        * :any:`Persistent Conversation Bot <examples.persistentconversationbot>`

    Args:
        entry_points (List[:class:`telegram.ext.BaseHandler`]): A list of :obj:`BaseHandler`
            objects that
            can trigger the start of the conversation. The first handler whose :meth:`check_update`
            method returns :obj:`True` will be used. If all return :obj:`False`, the update is not
            handled.
        states (Dict[:obj:`object`, List[:class:`telegram.ext.BaseHandler`]]): A :obj:`dict` that
            defines the different states of conversation a user can be in and one or more
            associated :obj:`BaseHandler` objects that should be used in that state. The first
            handler whose :meth:`check_update` method returns :obj:`True` will be used.
        fallbacks (List[:class:`telegram.ext.BaseHandler`]): A list of handlers that might be used
            if the user is in a conversation, but every handler for their current state returned
            :obj:`False` on :meth:`check_update`. The first handler which :meth:`check_update`
            method returns :obj:`True` will be used. If all return :obj:`False`, the update is not
            handled.
        allow_reentry (:obj:`bool`, optional): If set to :obj:`True`, a user that is currently in a
            conversation can restart the conversation by triggering one of the entry points.
            Default is :obj:`False`.
        per_chat (:obj:`bool`, optional): If the conversation key should contain the Chat's ID.
            Default is :obj:`True`.
        per_user (:obj:`bool`, optional): If the conversation key should contain the User's ID.
            Default is :obj:`True`.
        per_message (:obj:`bool`, optional): If the conversation key should contain the Message's
            ID. Default is :obj:`False`.
        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 :obj:`None` (default), there will be no timeout. The
            last received update and the corresponding :class:`context <.CallbackContext>` will be
            handled by *ALL* the handler's whose :meth:`check_update` method returns :obj:`True`
            that are in the state :attr:`ConversationHandler.TIMEOUT`.

            Caution:
                * This feature relies on the :attr:`telegram.ext.Application.job_queue` being set
                  and hence requires that the dependencies that :class:`telegram.ext.JobQueue`
                  relies on are installed.
                * Using :paramref:`conversation_timeout` with nested conversations is currently
                  not supported. You can still try to use it, but it will likely behave
                  differently from what you expect.

        name (:obj:`str`, optional): The name for this conversation handler. Required for
            persistence.
        persistent (:obj:`bool`, optional): If the conversation's dict for this handler should be
            saved. :paramref:`name` is required and persistence has to be set in
            :attr:`Application <.Application.persistence>`.

            .. versionchanged:: 20.0
                Was previously named as ``persistence``.
        map_to_parent (Dict[:obj:`object`, :obj:`object`], optional): A :obj:`dict` that can be
            used to instruct a child conversation handler to transition into a mapped state on
            its parent conversation handler in place of a specified nested state.
        block (:obj:`bool`, optional): Pass :obj:`False` or :obj:`True` to set a default value for
            the :attr:`BaseHandler.block` setting of all handlers (in :attr:`entry_points`,
            :attr:`states` and :attr:`fallbacks`). The resolution order for checking if a handler
            should be run non-blocking is:

            1. :attr:`telegram.ext.BaseHandler.block` (if set)
            2. the value passed to this parameter (if any)
            3. :attr:`telegram.ext.Defaults.block` (if defaults are used)

            .. seealso:: :wiki:`Concurrency`

            .. versionchanged:: 20.0
                No longer overrides the handlers settings. Resolution order was changed.

    Raises:
        :exc:`ValueError`: If :paramref:`persistent` is used but :paramref:`name` was not set, or
            when :attr:`per_message`, :attr:`per_chat`, :attr:`per_user` are all :obj:`False`.

    Attributes:
        block (:obj:`bool`): Determines whether the callback will run in a blocking way. Always
            :obj:`True` since conversation handlers handle any non-blocking callbacks internally.

    )_allow_reentry_block_child_conversations_conversation_timeout_conversations_entry_points
_fallbacks_map_to_parent_name	_per_chat_per_message	_per_user_persistent_states_timeout_jobs_locktimeout_jobsrD   TIMEOUTWAITINGFTNzConversationHandler[CCT])r?   entry_pointsstates	fallbacksallow_reentryper_chatper_userper_messageconversation_timeoutname
persistentmap_to_parentblockc                 C   sJ  ddl m}m}m}m} d| _|| _|| _|| _|| _	|| _
|| _|| _|| _|| _|	| _|| _i | _t | _i | _t | _|
r| jstd|
| _t| j| j| jfstd| jr| jstddd g }| | | | |! D ]}| | q| j"d	d
 |D  d}|D ]*}t#|t$t%frHtd|j&j' ddd nt#|t(r|t)|j*t+s|td|j*j' ddd nt#||rtddd n| jrt#||t,t-||frtd|j&j' d| dd nN| jrt#|t.std| dd n&| js t#|t.r td| dd | j/rt#|| j&rtddd qd S )Nr   )PollAnswerHandlerPollHandlerPreCheckoutQueryHandlerShippingQueryHandlerTz:Conversations can't be persistent when handler is unnamed.z='per_user', 'per_chat' and 'per_message' can't all be 'False'znIf 'per_message=True' is used, 'per_chat=True' should also be used, since message IDs are not globally unique.   
stacklevelc                 s   s   | ]}t |tr|V  qd S r<   )
isinstancer&   ).0handlerr4   r4   r5   	<genexpr>q  s    
 z/ConversationHandler.__init__.<locals>.<genexpr>z Read this FAQ entry to learn more about the per_* settings: https://github.com/python-telegram-bot/python-telegram-bot/wiki/Frequently-Asked-Questions#what-do-the-per_-settings-in-conversationhandler-do.zJThe `ConversationHandler` only handles updates of type `telegram.Update`. z handles updates of type `str`.zkThe `ConversationHandler` only handles updates of type `telegram.Update`. The TypeHandler is set to handle .zPollHandler will never trigger in a conversation since it has no information about the chat or the user who voted in it. Do you mean the `PollAnswerHandler`?zUpdates handled by zb only have information about the user, so this handler won't ever be triggered if `per_chat=True`.zIf 'per_message=True', all entry points, state handlers, and fallbacks must be 'CallbackQueryHandler', since no other handlers have a message context.zUIf 'per_message=False', 'CallbackQueryHandler' will not be tracked for every message.zUsing `conversation_timeout` with nested conversations is currently not supported. You can still try to use it, but it will likely behave differently from what you expect.)0telegram.extrm   rn   ro   rp   rl   rM   rQ   rY   rR   rL   rW   rU   rV   rO   rT   rS   r[   rH   LockrZ   rP   setrN   ri   
ValueErrorrX   anyrf   re   rg   r   extendvaluesr,   rt   r   r   	__class__r.   r   
issubclasstyper   r   r   r   rh   )r?   ra   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   Zall_handlersZstate_handlersZper_faq_linkrv   r4   r4   r5   __init__*  s    	




zConversationHandler.__init__r:   c                 C   sT   d}t t| j d| }t|}t| j|krD|dd d }t| | j|dS )a  Give a string representation of the ConversationHandler in the form
        ``ConversationHandler[name=..., states={...}]``.

        If there are more than 3 states, only the first 3 states are listed.

        As this class doesn't implement :meth:`object.__str__`, the default implementation
        will be used, which is equivalent to :meth:`__repr__`.

        Returns:
            :obj:`str`
           Nr\   z, ...})ri   rb   )dictlistrb   itemsstrlenr   ri   )r?   Ztruncation_thresholdrb   Zstates_stringr4   r4   r5   __repr__  s    zConversationHandler.__repr__c                 C   s   | j S )zList[:class:`telegram.ext.BaseHandler`]: A list of :obj:`BaseHandler` objects that can
        trigger the start of the conversation.
        )rQ   r>   r4   r4   r5   ra     s    z ConversationHandler.entry_points)_r;   c                 C   s   t dd S )NzDYou can not assign a new value to entry_points after initialization.AttributeErrorr?   r   r4   r4   r5   ra     s    c                 C   s   | j S )a   Dict[:obj:`object`, List[:class:`telegram.ext.BaseHandler`]]: A :obj:`dict` that
        defines the different states of conversation a user can be in and one or more
        associated :obj:`BaseHandler` objects that should be used in that state.
        )rY   r>   r4   r4   r5   rb     s    zConversationHandler.statesc                 C   s   t dd S )Nz>You can not assign a new value to states after initialization.r   r   r4   r4   r5   rb     s    c                 C   s   | j S )zList[:class:`telegram.ext.BaseHandler`]: A list of handlers that might be used if
        the user is in a conversation, but every handler for their current state returned
        :obj:`False` on :meth:`check_update`.
        )rR   r>   r4   r4   r5   rc     s    zConversationHandler.fallbacksc                 C   s   t dd S )NzAYou can not assign a new value to fallbacks after initialization.r   r   r4   r4   r5   rc     s    c                 C   s   | j S )zQ:obj:`bool`: Determines if a user can restart a conversation with an entry point.)rL   r>   r4   r4   r5   rd     s    z!ConversationHandler.allow_reentryc                 C   s   t dd S )NzEYou can not assign a new value to allow_reentry after initialization.r   r   r4   r4   r5   rd     s    c                 C   s   | j S )zB:obj:`bool`: If the conversation key should contain the User's ID.)rW   r>   r4   r4   r5   rf     s    zConversationHandler.per_userc                 C   s   t dd S )Nz@You can not assign a new value to per_user after initialization.r   r   r4   r4   r5   rf   	  s    c                 C   s   | j S )zB:obj:`bool`: If the conversation key should contain the Chat's ID.)rU   r>   r4   r4   r5   re     s    zConversationHandler.per_chatc                 C   s   t dd S )Nz@You can not assign a new value to per_chat after initialization.r   r   r4   r4   r5   re     s    c                 C   s   | j S )zE:obj:`bool`: If the conversation key should contain the message's ID.)rV   r>   r4   r4   r5   rg     s    zConversationHandler.per_messagec                 C   s   t dd S )NzCYou can not assign a new value to per_message after initialization.r   r   r4   r4   r5   rg     s    c                 C   s   | j S )z:obj:`float` | :obj:`datetime.timedelta`: Optional. When this
        handler is inactive more than this timeout (in seconds), it will be automatically
        ended.
        )rO   r>   r4   r4   r5   rh     s    z(ConversationHandler.conversation_timeoutc                 C   s   t dd S )NzLYou can not assign a new value to conversation_timeout after initialization.r   r   r4   r4   r5   rh   )  s    c                 C   s   | j S )zE:obj:`str`: Optional. The name for this :class:`ConversationHandler`.)rT   r>   r4   r4   r5   ri   /  s    zConversationHandler.namec                 C   s   t dd S )Nz<You can not assign a new value to name after initialization.r   r   r4   r4   r5   ri   4  s    c                 C   s   | j S )z:obj:`bool`: Optional. If the conversations dict for this handler should be
        saved. :attr:`name` is required and persistence has to be set in
        :attr:`Application <.Application.persistence>`.
        )rX   r>   r4   r4   r5   rj   8  s    zConversationHandler.persistentc                 C   s   t dd S )NzBYou can not assign a new value to persistent after initialization.r   r   r4   r4   r5   rj   @  s    c                 C   s   | j S )a
  Dict[:obj:`object`, :obj:`object`]: Optional. A :obj:`dict` that can be
        used to instruct a nested :class:`ConversationHandler` to transition into a mapped state on
        its parent :class:`ConversationHandler` in place of a specified nested state.
        )rS   r>   r4   r4   r5   rk   D  s    z!ConversationHandler.map_to_parentc                 C   s   t dd S )NzEYou can not assign a new value to map_to_parent after initialization.r   r   r4   r4   r5   rk   L  s    r#   )r)   r;   c                    s   | j r| jr|jstd| j}ttttf t | _| j	| |j
| jI dH }| j| | D ]"\}}|| jkrj| j| j|d qj| j| ji}| jD ]}|	|j|dI dH  q|S )a  Initializes the persistence for this handler and its child conversations.
        While this method is marked as protected, we expect it to be called by the
        Application/parent conversations. It's just protected to hide it from users.

        Args:
            application (:class:`telegram.ext.Application`): The application.

        Returns:
            A dict {conversation.name -> TrackingDict}, which contains all dict of this
            conversation and possible child conversations.

        zRThis handler is not persistent, has no name or the application has no persistence!N)	new_statekey)r)   )rj   ri   Zpersistencer@   rP   r   r   r"   rJ   r,   Zget_conversationsZupdate_no_trackr   rD   _update_staterN   _initialize_persistence)r?   r)   Zcurrent_conversationsZstored_datar   stateoutrv   r4   r4   r5   r   R  s.    



z+ConversationHandler._initialize_persistence)r,   r;   c                 C   s   |j }|j}g }| jr2|dkr&td||j | jrT|dkrHtd||j | jr|jdkrltd|jj	r||jj	 n||jj
j t|S )z7Builds the conversation key associated with the update.Nz2Can't build key for update without effective chat!z2Can't build key for update without effective user!z1Can't build key for update without CallbackQuery!)effective_chateffective_userre   r@   appendidrf   rg   callback_queryZinline_message_idmessageZ
message_idtuple)r?   r,   Zchatuserr   r4   r4   r5   _get_key  s$    
zConversationHandler._get_keyr-   )r   r)   r,   contextr+   r;   c              
      sZ   z|I d H }W n6 t k
rD } ztjd|d W Y d S d }~X Y nX | j|||||dS )NzTNon-blocking handler callback raised exception. Not scheduling conversation timeout.exc_info)r   r)   r,   r   r+   )	ExceptionrB   debug_schedule_job)r?   r   r)   r,   r   r+   Zeffective_new_staterE   r4   r4   r5   _schedule_job_delayed  s    z)ConversationHandler._schedule_job_delayedc              
   C   sr   || j krdS z.|j}|j| j| jt||||d| j|< W n0 tk
rl } ztj	d|d W 5 d}~X Y nX dS )zRSchedules a job which executes :meth:`_trigger_timeout` upon conversation timeout.N)datazFailed to schedule timeout.r   )
rD   	job_queueZrun_once_trigger_timeoutrh   r(   r[   r   rB   rA   )r?   r   r)   r,   r   r+   Zj_queuerE   r4   r4   r5   r     s    	
z!ConversationHandler._schedule_jobc                 C   s:  t |tsdS |js|jrdS | jr.|js.dS | jr>|js>dS | jrN|j	sNdS |j	rf| jrf|j	j
sfdS | |}| j|}d}t |tr2td | r| }|jdkr|j r| j|d d}n| || | j|}nJ| j| jg }|D ]0}||}|dk	r|dk	r| j|||f  S qdS tdt|t| d}|dks^| jr| jD ].}	|	|}|dk	rd|dk	rd|	} qqd|dkrdS |dk	r.|dkr.| j|g D ].}
|
|}|dk	r|dk	r|
} q.q| jD ].}||}|dk	r|dk	r|} q.qdS ||||fS )a(  
        Determines whether an update should be handled by this conversation handler, and if so in
        which state the conversation currently is.

        Args:
            update (:class:`telegram.Update` | :obj:`object`): Incoming update.

        Returns:
            :obj:`bool`

        Nz&Waiting for asyncio Task to finish ...Fz'Selecting conversation %s with state %s)rt   r   Zchannel_postZedited_channel_postre   r   rf   r   rg   r   r   r   rP   getr6   rB   r   r=   rG   r8   r9   rA   popr   rb   r`   check_updater   rd   ra   rc   )r?   r,   r   r   checkrF   handlersZhandler_rv   Zentry_point	candidatefallbackr4   r4   r5   r     sj    












z ConversationHandler.check_updatez)Application[Any, CCT, Any, Any, Any, Any])r,   r)   check_resultr   r;   c              
      s2  |\}}}}d}	| j 4 I dH $ | j|d}
|
dk	r>|
  W 5 Q I dH R X |jtk	r`|j}nB| jtk	rr| j}n0t|jt	r|jj
dk	r|jj
j}nt|j}zF|r|||||I dH }n&|j||||||d|j dd}W n. tk
r } z|j}d}	W 5 d}~X Y nX | j 4 I dH  | jr|jdkrJtddd	 nd|jjjsdtd
dd	 nJt|tjr|j| ||||||d|j dd n| ||||| W 5 Q I dH R X t| jtr
|| jkr
| | j|| |	rt| j|| j|S || j kr$| ||| |	r.tdS )aL  Send the update to the callback for the current state and BaseHandler

        Args:
            check_result: The result from :meth:`check_update`. For this handler it's a tuple of
                the conversation state, key, handler, and the handler's check result.
            update (:class:`telegram.Update`): Incoming telegram update.
            application (:class:`telegram.ext.Application`): Application that originated the
                update.
            context (:class:`telegram.ext.CallbackContext`): The context as provided by
                the application.

        FNzConversationHandler:z:handle_update:non_blocking_cb)	coroutiner,   ri   TzHIgnoring `conversation_timeout` because the Application has no JobQueue.   rr   zQIgnoring `conversation_timeout` because the Applications JobQueue is not running.z:handle_update:timeout_job)r,   ri   )!rZ   r[   r   Zschedule_removalrl   r   rM   rt   Zbotr   defaultsr   	get_valuehandle_updateZcreate_taskZ	update_idr   r   rh   r   r   Z	schedulerZrunningrH   rI   r   r   rk   r   r   rD   r   r`   )r?   r,   r)   r   r   Zcurrent_stater+   rv   Zhandler_check_resultZraise_dp_handler_stopZtimeout_jobrl   r   rA   r4   r4   r5   r   -  s    

      
    "z!ConversationHandler.handle_update)r   r   rv   r;   c                 C   s   || j kr|| jkr| j|= nt|tjrFt| j||d| j|< nb|d k	r|| jkrt|d k	rnt	|j
jnd d| d| jd k	rd| j nd ddd	 || j|< d S )
Nr7   r   z returned state z, which is unknown to the ConversationHandler  rx   rq   rr   )rD   rP   rt   rH   rI   r6   r   rb   r   reprcallbackr.   ri   )r?   r   r   rv   r4   r4   r5   r     s    



 
<z!ConversationHandler._update_state)r   r;   c           	   
      s
  t d|j}t t|j}td|j |j}| j4 I dH : | j	
|j}||k	rfW 5 Q I dH R  dS | j	|j= W 5 Q I dH R X | j
| jg }|D ]`}||j}|dk	r|dk	rz||j|j||I dH  W q tk
r   tddd Y qX q| | j|j dS )zThis is run whenever a conversation has timed out. Also makes sure that all handlers
        which are in the :attr:`TIMEOUT` state and whose :meth:`BaseHandler.check_update` returns
        :obj:`True` is handled.
        r$   z7Conversation timeout was triggered for conversation %s!NFzWApplicationHandlerStop in TIMEOUT state of ConversationHandler has no effect. Ignoring.rq   rr   )r   jobr(   r   rB   r   r+   r*   rZ   r[   r   rb   r^   r   r,   r   r)   r   r   r   rD   )	r?   r   r   Zctxtr*   Z	found_jobr   rv   r   r4   r4   r5   r     s:        z$ConversationHandler._trigger_timeout)N)7r.   r/   r0   r1   r2   rD   r   intr3   r^   r`   r   r   r   r   r    rJ   r   rK   r
   r   floatdatetime	timedeltar   r   r   r   propertyra   setterr	   rb   rc   rd   rf   re   rg   rh   ri   rj   rk   r   r"   r   r   rH   rI   r   r   _CheckUpdateTyper   r   r   r   r4   r4   r4   r5   r&   z   s   
 
 &	4]e   )Br1   rH   r   Zdataclassesr   typingr   r   r   r   r   r   r	   r
   r   r   r   r   Ztelegramr   Ztelegram._utils.defaultvaluer   r   Ztelegram._utils.loggingr   Ztelegram._utils.reprr   Ztelegram._utils.typesr   Ztelegram._utils.warningsr   Ztelegram.ext._applicationr   Ztelegram.ext._extbotr   Z"telegram.ext._handlers.basehandlerr   Z+telegram.ext._handlers.callbackqueryhandlerr   Z0telegram.ext._handlers.choseninlineresulthandlerr   Z)telegram.ext._handlers.inlinequeryhandlerr   Z+telegram.ext._handlers.stringcommandhandlerr   Z)telegram.ext._handlers.stringregexhandlerr   Z"telegram.ext._handlers.typehandlerr   Z telegram.ext._utils.trackingdictr   Ztelegram.ext._utils.typesr    r!   r"   ry   r#   r$   r%   rJ   r   r.   rB   r(   r6   r&   r4   r4   r4   r5   <module>   s<   8,