
    \d1                        U d Z ddlZddlZddlZddlZddlZddlmZ	 ddl
mZ ddlmZmZ ddlmZ i Zeeej        f         ed<   ej        Zd Zd	 Zd
 Z ej        ej        e           d Zd Z ej        ej        e           d Zd Z ej        ej        e           d Z d Z!d Z"d Z# G d d          Z$i a%ee&df         ed<   i a'd Z(d Z)d Z* G d d          Z+dS )z(
Different styles of persisted objects.
    N)StringIO)Dict)logreflect)_PYPY
oldModulesc                 B    t           | j        | j        | j        j        ffS )z3support function for copy_reg to pickle method refs)unpickleMethod__name____self__	__class__)methods    8lib/python3.11/site-packages/twisted/persisted/styles.pypickleMethodr      s$     		&/6?+DE     c                 &    t          | |          }|S )a  
    Retrieve the function object implementing a method name given the class
    it's on and a method name.

    @param classObject: A class to retrieve the method's function from.
    @type classObject: L{type}

    @param methodName: The name of the method whose function to retrieve.
    @type methodName: native L{str}

    @return: the function object corresponding to the given method name.
    @rtype: L{types.FunctionType}
    )getattr)classObject
methodNamemethodObjects      r   _methodFunctionr   "   s     ;
33Lr   c                    |t          ||           S 	 t          ||           }d}t          j        ||g|R  }|S # t          $ rF t          j        d| d|           |
J d            |j        |u r t          | ||j                  cY S w xY w)aS  
    Support function for copy_reg to unpickle method refs.

    @param im_name: The name of the method.
    @type im_name: native L{str}

    @param im_self: The instance that the method was present on.
    @type im_self: L{object}

    @param im_class: The class where the method was declared.
    @type im_class: L{type} or L{None}
    N Methodznot on classz'No recourse: no instance to guess from.)	r   r   types
MethodTypeAttributeErrorr   msgr   r
   )im_nameim_selfim_classmethodFunction
maybeClassbounds         r   r
   r
   4   s     x)))(7;; 
 F:FFF  C C C'>8<<<""$M""" ((gw0ABBBBBCs   ; AB
Bc                     | j         dk    rt          d|            t          t          d                    | j        | j        g          g          fS )a  
    Reduce, in the sense of L{pickle}'s C{object.__reduce__} special method, a
    function object into its constituent parts.

    @param f: The function to reduce.
    @type f: L{types.FunctionType}

    @return: a 2-tuple of a reference to L{_unpickleFunction} and a tuple of
        its arguments, a 1-tuple of the function's fully qualified name.
    @rtype: 2-tuple of C{callable, native string}
    z<lambda>zCannot pickle lambda function: .)r   _UniversalPicklingError_unpickleFunctiontuplejoin
__module____qualname__)fs    r   _pickleFunctionr.   W   sS     	zZ%&K&K&KLLLuchhan/M&N&N%OPPQQr   c                 $    ddl m}  ||           S )a  
    Convert a function name into a function by importing it.

    This is a synonym for L{twisted.python.reflect.namedAny}, but imported
    locally to avoid circular imports, and also to provide a persistent name
    that can be stored (and deprecated) independently of C{namedAny}.

    @param fullyQualifiedName: The fully qualified name of a function.
    @type fullyQualifiedName: native C{str}

    @return: A function object imported from the given location.
    @rtype: L{types.FunctionType}
    r   )namedAny)twisted.python.reflectr0   )fullyQualifiedNamer0   s     r   r(   r(   h   s'     0/////8&'''r   c                      t           | j        ffS )z3support function for copy_reg to pickle module refs)unpickleModuler   )modules    r   pickleModuler6   ~   s    FO---r   c                     | t           v r8t          j        d| z             t           |          } t          j        |            t          | i i d          S )z5support function for copy_reg to unpickle module refszModule has moved: %sx)r   r   r   
__import__)names    r   r4   r4      sN    z&-...$dBC(((r   c                 b    	 t           |                                 |                                 ffS )z
    Reduce the given cStringO.

    This is only called on Python 2, because the cStringIO module only exists
    on Python 2.

    @param stringo: The string output to pickle.
    @type stringo: C{cStringIO.OutputType}
    )unpickleStringOgetvaluetell)stringos    r   pickleStringOr@      s,     CW--//@@@r   c                 v    t                      }|                    |            |                    |           |S )a  
    Convert the output of L{pickleStringO} into an appropriate type for the
    current python version.  This may be called on Python 3 and will convert a
    cStringIO into an L{io.StringIO}.

    @param val: The content of the file.
    @type val: L{bytes}

    @param sek: The seek position of the file.
    @type sek: L{int}

    @return: a file-like object which you can write bytes to.
    @rtype: C{cStringIO.OutputType} on Python 2, L{io.StringIO} on Python 3.
    )
_cStringIOwriteseekvalsekr8   s      r   r<   r<      s0     	AGGCLLLFF3KKKHr   c                 `    t           |                                 |                                 ffS )aQ  
    Reduce the given cStringI.

    This is only called on Python 2, because the cStringIO module only exists
    on Python 2.

    @param stringi: The string input to pickle.
    @type stringi: C{cStringIO.InputType}

    @return: a 2-tuple of (C{unpickleStringI}, (bytes, pointer))
    @rtype: 2-tuple of (function, (bytes, int))
    )unpickleStringIr=   r>   )stringis    r   pickleStringIrK      s(     W--//@@@r   c                 N    t          |           }|                    |           |S )a  
    Convert the output of L{pickleStringI} into an appropriate type for the
    current Python version.

    This may be called on Python 3 and will convert a cStringIO into an
    L{io.StringIO}.

    @param val: The content of the file.
    @type val: L{bytes}

    @param sek: The seek position of the file.
    @type sek: L{int}

    @return: a file-like object which you can read bytes from.
    @rtype: C{cStringIO.OutputType} on Python 2, L{io.StringIO} on Python 3.
    )rB   rD   rE   s      r   rI   rI      s#    " 	3AFF3KKKHr   c                   $    e Zd ZdZd Zd Zd ZdS )	Ephemeralzh
    This type of object is never persisted; if possible, even references to it
    are eliminated.
    c                     t           dfS )zu
        Serialize any subclass of L{Ephemeral} in a way which replaces it with
        L{Ephemeral} itself.
        r   )rN   )selfs    r   
__reduce__zEphemeral.__reduce__   s    
 2r   c                     t          j        d| z             t          sDdd l}t	          |dd           r/|                    |           D ]}t          j        d|            d S )Nz!WARNING: serializing ephemeral %sr   get_referrersz referred to by )r   r   r   gcr   rS   )rP   rT   rs      r   __getstate__zEphemeral.__getstate__   s{    3d:;;; 	4IIIr?D11 4))$// 4 4AG2q223333tr   c                 V    t          j        d| j        z             t          | _        d S )Nz#WARNING: unserializing ephemeral %s)r   r   r   rN   rP   states     r   __setstate__zEphemeral.__setstate__   s%    5FGGG"r   N)r   r+   r,   __doc__rQ   rV   rZ   r   r   r   rN   rN      sK         
    # # # # #r   rN   	VersionedversionedsToUpgradec                  ~    t          t                                                    D ]} t          |            i ai ad S N)listr]   valuesrequireUpgradeupgraded)	versioneds    r   	doUpgradere      sF    -446677 " "	y!!!!HHHr   c                     t          |           }|t          v r)|t          vr"dt          |<   |                                  | S dS dS )z?Require that a Versioned instance be upgraded completely first.   N)idr]   rc   versionUpgrade)objobjIDs     r   rb   rb      sQ    sGGE###X(=(=
 $#(=(=r   c                     | t           g}t          j        |           D ]0}||vr*t          |t                     r|                    |           1|dd         S )z
    Get all of the parent classes of C{c}, not including C{c} itself, which are
    strict subclasses of L{Versioned}.

    @param c: a class
    @returns: list of classes
       N)r\   inspectgetmro
issubclassappend)clbs      r   _aybabturu   	  sZ     
IA^A  A::*Q	22:HHQKKKQRR5Lr   c                   .    e Zd ZdZdZdZd ZddZd ZdS )	r\   a  
    This type of object is persisted with versioning information.

    I have a single class attribute, the int persistenceVersion.  After I am
    unserialized (and styles.doUpgrade() is called), self.upgradeToVersionX()
    will be called for each version upgrade I must undergo.

    For example, if I serialize an instance of a Foo(Versioned) at version 4
    and then unserialize it when the code is at version 9, the calls::

      self.upgradeToVersion5()
      self.upgradeToVersion6()
      self.upgradeToVersion7()
      self.upgradeToVersion8()
      self.upgradeToVersion9()

    will be made.  If any of these methods are undefined, a warning message
    will be printed.
    r   r   c                 B    | t           t          |           <   || _        d S r_   )r]   rh   __dict__rX   s     r   rZ   zVersioned.__setstate__3  s    (,BtHH%r   Nc                 N   t          j         |p| j                  }t          | j                  }|                                 |                    | j                   |D ]D}d|j        v r|j        D ]	}||v r||= 
d|j        v r|j        |t          j	        |           d<   E|S )z8Get state, adding a version number to it on its way out.persistenceForgetspersistenceVersionz.persistenceVersion)
copyrx   ru   r   reverserq   rz   r{   r   qual)rP   dictdctbasesbaseslots         r   rV   zVersioned.__getstate__7  s    i-..((T^$$$ 	, 	,D#t}44 3 & &Ds{{I#t}44 + |D))>>> 
r   c                    t          | j                  }|                                 |                    | j                   d| j        v r]| j        d         }| j        d= d}d}|D ] }d|j        vr|j        |k    r	|}|j        }!|r|| j        dt          j        |          z  <   |D ]*}t          |j	        vr
d|j        vr|j        }dt          j        |          z  }| j        
                    |          pd}|r| j        |= ||k    s
J d            ||k     r|dz   }|j        
                    d|z  d          }	|	rbt          j        dt          j        |          d	t          j        | j                  d
t          |           d|            |	|            n(t          j        d                    ||                     ||k     ,dS )z (internal) Do a version upgrade.r{   r   Nz%s.persistenceVersionz"Sorry, can't go backwards in time.rg   zupgradeToVersion%sz
Upgrading z (of z @ z) to version z(Warning: cannot upgrade {} to version {})ru   r   r}   rq   rx   r{   r   r~   r\   	__bases__getr   r   rh   format)
rP   r   pverhighestVersionhighestBaser   currentVerspverNamepersistVersr   s
             r   ri   zVersioned.versionUpgradeH  sB   (( 	T^$$$4=00 =!56D23NK = ='t}<<*^;;"&K%)%<N   +gl;.G.GG   	  	D //(==1K.d1C1CCH-++H55:K ,M(++---/S---++)Ao**+?++MtTT GG $L....#L8888tHHHH'K   F4LLLLGBII +    ++ 	  	r   r_   )	r   r+   r,   r[   r{   rz   rZ   rV   ri   r   r   r   r\   r\     sc         (      "@ @ @ @ @r   ),r[   r|   copyregcopy_regrn   pickler   ior   rB   typingr   twisted.pythonr   r   twisted.python.compatr   r   str
ModuleType__annotations__PicklingErrorr'   r   r   r
   r   r.   r(   FunctionTyper6   r4   r@   r<   rK   rI   rN   r]   intrc   re   rb   ru   r\   r   r   r   <module>r      si  
           % % % % % %       ' ' ' ' ' ' ' ' ' ' ' ' ' '*,
De&&' , , , !.     $  @  , / / /R R R"( ( (& "O 4 4 4. . .
) ) )  , / / /A A A  *A A A   ,# # # # # # # #8 /1 T#{*+ 0 0 0      $m m m m m m m m m mr   