
    YiY                        S r SSKrSSKJr  SSKJr  SSKJrJrJ	r	J
r
JrJrJr  SSKJrJr  SSKJr  SSKJr  SS	KJrJr  SS
KJr  SSKJrJrJrJrJrJ r   Sr!Sr"\
" S\S9r#S\$\#   S\%\$\#      4S jr&S\$\#   S\'S\#4S jr(S\#S\)\\)\$\#   \'4   4   4S jr* " S S\RV                  5      r, " S S\RZ                  5      r. " S S\\\\4   5      r/g)z1This module contains the PicklePersistence class.    N)deepcopy)Path)AnyCallableOptionalTypeVarUnioncastoverload)BotTelegramObject)FilePathInput)warn)BasePersistencePersistenceInput)ContextTypes)BDCDUDCDCDataConversationDictConversationKeyz/a known bot replaced by PTB's PicklePersistencez2an unknown bot replaced by PTB's PicklePersistenceTelegramObj)boundclsreturnc           	          U R                  5       n[        U5      R                  U VVs/ s H  n[        U5        H  o3PM     M     snn5      $ s  snnf )zkGets all subclasses of the specified object, recursively. from
https://stackoverflow.com/a/3862957/9706202
)__subclasses__setunion_all_subclasses)r   
subclassescss       J/app/.venv/lib/python3.13/site-packages/telegram/ext/_picklepersistence.pyr!   r!   &   sH     ##%Jz?  Z!TZQRASA!AS!Z!TUU!Ts   A
kwargsc                 J    U R                  U 5      nUR                  U5        U$ )am  
This method is used for unpickling. The data, which is in the form a dictionary, is
converted back into a class. Works mostly the same as :meth:`TelegramObject.__setstate__`.
This function should be kept in place for backwards compatibility even if the pickling logic
is changed, since `_custom_reduction` places references to this function into the pickled data.
)__new____setstate__)r   r&   objs      r%   _reconstruct_tor+   .   s%     ++c
CVJ    c                 j    U R                  SS9n[        US   5      US'   [        U R                  U44$ )zt
This method is used for pickling. The bot attribute is preserved so _BotPickler().persistent_id
works as intended.
T)include_private
api_kwargs)
_get_attrsdictr+   	__class__)r   datas     r%   _custom_reductionr4   :   s>    
 >>$>/D d<01DS]]D111r,   c                      ^  \ rS rSrSrS\S\S\4U 4S jjrS\S\	\
\	\\   \4   4   4S	 jrS\S\\   4S
 jrSrU =r$ )_BotPicklerF   _botbotargsr&   c                 2   > Xl         [        TU ]  " U0 UD6  g Nr9   super__init__selfr:   r;   r&   r2   s       r%   r@   _BotPickler.__init__I       	$)&)r,   r*   r   c                 N    [        U[        5      (       d  [        $ [        U5      $ )zt
This method is used for pickling. The bot attribute is preserved so
_BotPickler().persistent_id works as intended.
)
isinstancer   NotImplementedr4   rB   r*   s     r%   reducer_override_BotPickler.reducer_overrideM   s"     #~..!! %%r,   c                 v    XR                   L a  [        $ [        U[        5      (       a  [	        SSS9  [
        $ g)zUsed to 'mark' the Bot, so it can be replaced later. See
https://docs.python.org/3/library/pickle.html#pickle.Pickler.persistent_id for more info
zHUnknown bot instance found. Will be replaced by `None` during unpickling   )
stacklevelN)r9   _REPLACED_KNOWN_BOTrF   r   r   _REPLACED_UNKNOWN_BOTrH   s     r%   persistent_id_BotPickler.persistent_idY   s:     ))&&c3Z )(r,   )__name__
__module____qualname____firstlineno__	__slots__r   r   r@   r   tupler   typer1   rI   objectr   strrP   __static_attributes____classcell__r2   s   @r%   r6   r6   F   sl    I*C * *s *
&
&	xtK0$677	8
& HSM  r,   r6   c                   T   ^  \ rS rSrSrS\S\S\4U 4S jjrS\S\	\   4S	 jr
SrU =r$ )
_BotUnpicklerh   r8   r:   r;   r&   c                 2   > Xl         [        TU ]  " U0 UD6  g r=   r>   rA   s       r%   r@   _BotUnpickler.__init__k   rD   r,   pidr   c                 p    U[         :X  a  U R                  $ U[        :X  a  g[        R                  " S5      e)zSReplaces the bot with the current bot if known, else it is replaced by :obj:`None`.Nz,Found unknown persistent id when unpickling!)rN   r9   rO   pickleUnpicklingError)rB   rc   s     r%   persistent_load_BotUnpickler.persistent_loado   s3    %%99''$$%STTr,   )rR   rS   rT   rU   rV   r   r   r@   rZ   r   rg   r[   r\   r]   s   @r%   r_   r_   h   sB    I*C * *s *U3 U8C= U Ur,   r_   c                     ^  \ rS rSrSrSr\    S/SSS\S\\	   S	\
S
\
S\4S jj5       r\     S0SSS\S\\	   S	\
S
\
S\S\\\\\\4      4S jj5       r     S0S\S\\	   S	\
S
\
S\S\\\\\\4      4U 4S jjjrS1S jrS\S\4S jrS1S jrS\S\SS4S jrS\\\4   4S jrS\\\4   4S jrS\4S jrS\\   4S jrS\S\ 4S jr!S\S\"S\\   SS4S jr#S \S\SS4S! jr$S"\S\SS4S# jr%S\SS4S$ jr&S\SS4S% jr'S"\SS4S& jr(S \SS4S' jr)S \S(\SS4S) jr*S"\S*\SS4S+ jr+S,\SS4S- jr,S1S. jr-Sr.U =r/$ )2PicklePersistencex   a  Using python's builtin :mod:`pickle` for making your bot persistent.

Attention:
    The interface provided by this class is intended to be accessed exclusively by
    :class:`~telegram.ext.Application`. Calling any of the methods below manually might
    interfere with the integration of persistence into :class:`~telegram.ext.Application`.

Note:
    This implementation of :class:`BasePersistence` uses the functionality of the pickle module
    to support serialization of bot instances. Specifically any reference to
    :attr:`~BasePersistence.bot` will be replaced by a placeholder before pickling and
    :attr:`~BasePersistence.bot` will be inserted back when loading the data.

Examples:
    :any:`Persistent Conversation Bot <examples.persistentconversationbot>`

.. seealso:: :wiki:`Making Your Bot Persistent <Making-your-bot-persistent>`

.. versionchanged:: 20.0

    * The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`.
    * The parameter and attribute ``filename`` were replaced by :attr:`filepath`.
    * :attr:`filepath` now also accepts :obj:`pathlib.Path` as argument.

Args:
    filepath (:obj:`str` | :obj:`pathlib.Path`): The filepath for storing the pickle files.
        When :attr:`single_file` is :obj:`False` this will be used as a prefix.
    store_data (:class:`~telegram.ext.PersistenceInput`, optional): Specifies which kinds of
        data will be saved by this persistence instance. By default, all available kinds of
        data will be saved.
    single_file (:obj:`bool`, optional): When :obj:`False` will store 5 separate files of
        `filename_user_data`, `filename_bot_data`, `filename_chat_data`,
        `filename_callback_data` and `filename_conversations`. Default is :obj:`True`.
    on_flush (:obj:`bool`, optional): When :obj:`True` will only save to file when
        :meth:`flush` is called and keep data in memory until that happens. When
        :obj:`False` will store data on any transaction *and* on call to :meth:`flush`.
        Default is :obj:`False`.
    context_types (:class:`telegram.ext.ContextTypes`, optional): Pass an instance
        of :class:`telegram.ext.ContextTypes` to customize the types used in the
        ``context`` interface. If not passed, the defaults documented in
        :class:`telegram.ext.ContextTypes` will be used.

        .. versionadded:: 13.6
    update_interval (:obj:`int` | :obj:`float`, optional): The
        :class:`~telegram.ext.Application` will update
        the persistence in regular intervals. This parameter specifies the time (in seconds) to
        wait between two consecutive runs of updating the persistence. Defaults to 60 seconds.

        .. versionadded:: 20.0
Attributes:
    filepath (:obj:`str` | :obj:`pathlib.Path`): The filepath for storing the pickle files.
        When :attr:`single_file` is :obj:`False` this will be used as a prefix.
    store_data (:class:`~telegram.ext.PersistenceInput`): Specifies which kinds of data will
        be saved by this persistence instance.
    single_file (:obj:`bool`): Optional. When :obj:`False` will store 5 separate files of
        `filename_user_data`, `filename_bot_data`, `filename_chat_data`,
        `filename_callback_data` and `filename_conversations`. Default is :obj:`True`.
    on_flush (:obj:`bool`): Optional. When :obj:`True` will only save to file when
        :meth:`flush` is called and keep data in memory until that happens. When
        :obj:`False` will store data on any transaction *and* on call to :meth:`flush`.
        Default is :obj:`False`.
    context_types (:class:`telegram.ext.ContextTypes`): Container for the types used
        in the ``context`` interface.

        .. versionadded:: 13.6
)	bot_datacallback_data	chat_datacontext_typesconversationsfilepathon_flushsingle_file	user_dataNrB   zAPicklePersistence[dict[Any, Any], dict[Any, Any], dict[Any, Any]]rq   
store_datars   rr   update_intervalc                     g r=    )rB   rq   ru   rs   rr   rv   s         r%   r@   PicklePersistence.__init__   s     r,   zPicklePersistence[UD, CD, BD]ro   c                     g r=   rx   )rB   rq   ru   rs   rr   rv   ro   s          r%   r@   ry      s     r,   c                   > [         TU ]  X%S9  [        U5      U l        X0l        X@l        S U l        S U l        S U l        S U l	        S U l
        [        [        [        [        [        [         4   U=(       d
    [        5       5      U l        g )N)ru   rv   )r?   r@   r   rq   rs   rr   rt   rn   rl   rm   rp   r
   r   r   r   r   r   ro   )rB   rq   ru   rs   rr   rv   ro   r2   s          r%   r@   ry      sv     	JP"8n+6(02626&*04]a<@b"b)=+JLN=
r,   r   c                     U R                   R                  S5       n[        U R                  U5      R	                  5       nS S S 5        WS   U l        US   U l        UR                  SU R                  R                  5       5      U l	        UR                  S0 5      U l
        US   U l        g ! , (       d  f       Ns= f! [         a>    0 U l        0 U l        0 U l        U R                  R                  5       U l	        S U l
         g [        R                   a+  nU R                   R                  n[!        SU S35      UeS nAf["         a(  n[!        S	U R                   R                   35      UeS nAff = f)
Nrbrt   rn   rl   rm   rp   File # does not contain valid pickle data Something went wrong unpickling )rq   openr_   r:   loadrt   rn   getro   rl   rm   rp   OSErrorre   rf   name	TypeError	Exception)rB   filer3   excfilenames        r%   _load_singlefile"PicklePersistence._load_singlefile   sE   	^##D)T$TXXt499; * "+.DN!+.DN HHZ1C1C1L1L1NODM!%/2!>D!%o!6D *)  	&!#DDNDN ..779DM!%D%% 	\}}))HeH:-PQRX[[ 	^>t}}?Q?Q>RSTZ]]	^sB   C  %B/A,C  /
B=9C   AE5E5&E  E5#E00E5c                 r    UR                  S5       n[        U R                  U5      R                  5       sS S S 5        $ ! , (       d  f       g = f! [         a     g [
        R                   a  n[        SUR                   S35      UeS nAf[         a  n[        SUR                   35      UeS nAff = f)Nr}   r~   r   r   )
r   r_   r:   r   r   re   rf   r   r   r   )rB   rq   r   r   s       r%   
_load_filePicklePersistence._load_file
  s    		Yt$$TXXt499; %$$  	%% 	aeHMM?2UVW]`` 	Y>x}}oNOUXX	YsE   A $A	A 
AA A 
B6B61BB6B11B6c                 F   U R                   U R                  U R                  U R                  U R                  S.nU R
                  R                  S5       n[        U R                  U[        R                  S9R                  U5        S S S 5        g ! , (       d  f       g = f)N)rp   rt   rn   rl   rm   wbprotocol)rp   rt   rn   rl   rm   rq   r   r6   r:   re   HIGHEST_PROTOCOLdump)rB   r3   r   s      r%   _dump_singlefile"PicklePersistence._dump_singlefile  ss    !//!//
 ]]%$1H1HINNtT &%%s   3B
B r3   c                     UR                  S5       n[        U R                  U[        R                  S9R                  U5        S S S 5        g ! , (       d  f       g = f)Nr   r   )r   r6   r:   re   r   r   )rB   rq   r3   r   s       r%   
_dump_filePicklePersistence._dump_file!  s=    ]]4 D$1H1HINNtT !  s   3A
Ac                   #    U R                   (       a  OXU R                  (       d7  U R                  [        U R                   S35      5      nU(       d  0 nXl         OU R                  5         [        U R                   5      $ 7f)zReturns the user_data from the pickle file if it exists or an empty :obj:`dict`.

Returns:
    dict[:obj:`int`, :obj:`dict`]: The restored user data.

_user_data)rt   rs   r   r   rq   r   r   rB   r3   s     r%   get_user_dataPicklePersistence.get_user_data%  `      >>!!??44==/(D#EFD!N!!#''   B Bc                   #    U R                   (       a  OXU R                  (       d7  U R                  [        U R                   S35      5      nU(       d  0 nXl         OU R                  5         [        U R                   5      $ 7f)zReturns the chat_data from the pickle file if it exists or an empty :obj:`dict`.

Returns:
    dict[:obj:`int`, :obj:`dict`]: The restored chat data.

_chat_data)rn   rs   r   r   rq   r   r   r   s     r%   get_chat_dataPicklePersistence.get_chat_data6  r   r   c                 8  #    U R                   (       a  OpU R                  (       dO  U R                  [        U R                   S35      5      nU(       d  U R
                  R                  5       nXl         OU R                  5         [        U R                   5      $ 7f)zReturns the bot_data from the pickle file if it exists or an empty object of type
:obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`.

Returns:
    :obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`: The restored bot data.
	_bot_data)rl   rs   r   r   rq   ro   r   r   r   s     r%   get_bot_dataPicklePersistence.get_bot_dataG  so      ==!!??44==/(C#DED))224 M!!#&&s   BBc                 $  #    U R                   (       a  OXU R                  (       d7  U R                  [        U R                   S35      5      nU(       d  SnXl         OU R                  5         U R                   c  g[        U R                   5      $ 7f)a4  Returns the callback data from the pickle file if it exists or :obj:`None`.

.. versionadded:: 13.6

Returns:
    tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]],
    dict[:obj:`str`, :obj:`str`]] | :obj:`None`: The restored metadata or :obj:`None`,
    if no data was stored.
_callback_dataN)rm   rs   r   r   rq   r   r   r   s     r%   get_callback_data#PicklePersistence.get_callback_dataY  st      !!??44==/(H#IJD!%!!#%**++s   BBr   c                 6  #    U R                   (       a  OZU R                  (       d9  U R                  [        U R                   S35      5      nU(       d  U0 0nX l         OU R                  5         U R                   R                  U0 5      R                  5       $ 7f)zReturns the conversations from the pickle file if it exists or an empty dict.

Args:
    name (:obj:`str`): The handlers name.

Returns:
    :obj:`dict`: The restored conversations for the handler.
_conversations)rp   rs   r   r   rq   r   r   copy)rB   r   r3   s      r%   get_conversations#PicklePersistence.get_conversationsp  sz      !!??44==/(H#IJDbz!%!!#!!%%dB/4466s   BBkey	new_statec                   #    U R                   (       d  0 U l         U R                   R                  U0 5      R                  U5      U:X  a  gX0R                   U   U'   U R                  (       dU  U R                  (       d3  U R                  [        U R                   S35      U R                   5        gU R                  5         gg7f)a  Will update the conversations for the given handler and depending on :attr:`on_flush`
save the pickle file.

Args:
    name (:obj:`str`): The handler's name.
    key (:obj:`tuple`): The key the state is changed for.
    new_state (:class:`object`): The new state for the given key.
Nr   )	rp   
setdefaultr   rr   rs   r   r   rq   r   )rB   r   r   r   s       r%   update_conversation%PicklePersistence.update_conversation  s      !!!#D((r266s;yH(14 %}}##n%E FHZHZ[%%'	 s   CCuser_idc                 \  #    U R                   c  0 U l         U R                   R                  U5      U:X  a  gX R                   U'   U R                  (       dU  U R                  (       d3  U R	                  [        U R                   S35      U R                   5        gU R                  5         gg7f)zWill update the user_data and depending on :attr:`on_flush` save the pickle file.

Args:
    user_id (:obj:`int`): The user the data might have been changed for.
    data (:obj:`dict`): The :attr:`telegram.ext.Application.user_data` ``[user_id]``.
Nr   )rt   r   rr   rs   r   r   rq   r   )rB   r   r3   s      r%   update_user_data"PicklePersistence.update_user_data        >>!DN>>g&$."&w}}##j%A BDNNS%%'	    B*B,chat_idc                 \  #    U R                   c  0 U l         U R                   R                  U5      U:X  a  gX R                   U'   U R                  (       dU  U R                  (       d3  U R	                  [        U R                   S35      U R                   5        gU R                  5         gg7f)zWill update the chat_data and depending on :attr:`on_flush` save the pickle file.

Args:
    chat_id (:obj:`int`): The chat the data might have been changed for.
    data (:obj:`dict`): The :attr:`telegram.ext.Application.chat_data` ``[chat_id]``.
Nr   )rn   r   rr   rs   r   r   rq   r   )rB   r   r3   s      r%   update_chat_data"PicklePersistence.update_chat_data  r   r   c                   #    U R                   U:X  a  gXl         U R                  (       dU  U R                  (       d3  U R                  [	        U R
                   S35      U R                   5        gU R                  5         gg7f)zWill update the bot_data and depending on :attr:`on_flush` save the pickle file.

Args:
    data (:obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`): The
        :attr:`telegram.ext.Application.bot_data`.
Nr   )rl   rr   rs   r   r   rq   r   r   s     r%   update_bot_data!PicklePersistence.update_bot_data  s^      ==D }}##i%@ A4==Q%%'	    A?Bc                   #    U R                   U:X  a  gXl         U R                  (       dU  U R                  (       d3  U R                  [	        U R
                   S35      U R                   5        gU R                  5         gg7f)aZ  Will update the callback_data (if changed) and depending on :attr:`on_flush` save the
pickle file.

.. versionadded:: 13.6

Args:
    data (tuple[list[tuple[:obj:`str`, :obj:`float`,                 dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]]):
        The relevant data to restore :class:`telegram.ext.CallbackDataCache`.
Nr   )rm   rr   rs   r   r   rq   r   r   s     r%   update_callback_data&PicklePersistence.update_callback_data  sc      %!}}##n%E FHZHZ[%%'	 r   c                 ,  #    U R                   c  gU R                   R                  US5        U R                  (       dU  U R                  (       d3  U R	                  [        U R                   S35      U R                   5        gU R                  5         gg7f)zWill delete the specified key from the ``chat_data`` and depending on
:attr:`on_flush` save the pickle file.

.. versionadded:: 20.0

Args:
    chat_id (:obj:`int`): The chat id to delete from the persistence.
Nr   )rn   poprr   rs   r   r   rq   r   )rB   r   s     r%   drop_chat_data PicklePersistence.drop_chat_data  k      >>!7D)}}##j%A BDNNS%%'	    BBc                 ,  #    U R                   c  gU R                   R                  US5        U R                  (       dU  U R                  (       d3  U R	                  [        U R                   S35      U R                   5        gU R                  5         gg7f)zWill delete the specified key from the ``user_data`` and depending on
:attr:`on_flush` save the pickle file.

.. versionadded:: 20.0

Args:
    user_id (:obj:`int`): The user id to delete from the persistence.
Nr   )rt   r   rr   rs   r   r   rq   r   )rB   r   s     r%   drop_user_data PicklePersistence.drop_user_data  r   r   rt   c                    #    g7f)zjDoes nothing.

.. versionadded:: 13.6
.. seealso:: :meth:`telegram.ext.BasePersistence.refresh_user_data`
Nrx   )rB   r   rt   s      r%   refresh_user_data#PicklePersistence.refresh_user_data          rn   c                    #    g7f)zjDoes nothing.

.. versionadded:: 13.6
.. seealso:: :meth:`telegram.ext.BasePersistence.refresh_chat_data`
Nrx   )rB   r   rn   s      r%   refresh_chat_data#PicklePersistence.refresh_chat_data  r   r   rl   c                    #    g7f)ziDoes nothing.

.. versionadded:: 13.6
.. seealso:: :meth:`telegram.ext.BasePersistence.refresh_bot_data`
Nrx   )rB   rl   s     r%   refresh_bot_data"PicklePersistence.refresh_bot_data  r   r   c                   #    U R                   (       ag  U R                  (       dD  U R                  (       d3  U R                  (       d"  U R                  (       d  U R
                  (       a  U R                  5         ggU R                  (       a2  U R                  [        U R                   S35      U R                  5        U R                  (       a2  U R                  [        U R                   S35      U R                  5        U R                  (       a2  U R                  [        U R                   S35      U R                  5        U R                  (       a2  U R                  [        U R                   S35      U R                  5        U R
                  (       a3  U R                  [        U R                   S35      U R
                  5        gg7f)z/Will save all data in memory to pickle file(s).r   r   r   r   r   N)
rs   rt   rn   rl   rm   rp   r   r   r   rq   )rB   s    r%   flushPicklePersistence.flush  s"    >>==%%%%%%' & ~~j%A BDNNS~~j%A BDNNS}}i%@ A4==Q!!n%E FHZHZ[!!n%E FHZHZ[ "s   G
G)NTF<   )NTFr   N)r   N)0rR   rS   rT   rU   __doc__rV   r   r   r   r   boolfloatr@   r   r   r   r   r   r   r   r   r   rY   r   r1   intr   r   r   r   r   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r[   r\   r]   s   @r%   rj   rj   x   s   AF
I  26 !#Q -. 	
     26 !#AE- -. 	
    S"b"_ =>  26 !#AE

 -.
 	

 
 
  S"b"_ =>
 
,^.
Y4 
YC 
Y	UU4 Uv U$ U(T#r'] ("(T#r'] ("'B '$,'): ,.7C 74D 7(((-(:B6:J(	(,(c ( ( ($(c ( ( ($(" ( ( (w (4 (((C (D (&(C (D (&s r d s r d r d \ \r,   rj   )0r   re   r   r   pathlibr   typingr   r   r   r   r	   r
   r   telegramr   r   telegram._utils.typesr   telegram._utils.warningsr   telegram.extr   r   telegram.ext._contexttypesr   telegram.ext._utils.typesr   r   r   r   r   r   rN   rO   r   rX   r   r!   r1   r+   rW   r4   Picklerr6   	Unpicklerr_   rj   rx   r,   r%   <module>r      s   & 8    J J J ( / ) : 3 \ \G L m>:Vk* Vs43D/E V	k* 	D 	[ 		2; 	255kARTXAX;Y1Y+Z 	2&.. DUF$$ U z\B
3 z\r,   