
    Ϫf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j4                  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+y)z(
Different styles of persisted objects.
    N)StringIO)Dict)logreflect)_PYPY
oldModulesc                 h    t         | j                  | j                  | j                  j                  ffS )z3support function for copy_reg to pickle method refs)unpickleMethod__name____self__	__class__)methods    :/usr/lib/python3/dist-packages/twisted/persisted/styles.pypickleMethodr      s-     		&//6??+D+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     ;
3Lr   c                    |t        ||       S 	 t        ||       }d}t        j                  ||g| }|S # t        $ rJ 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}
     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  C'>8<"M$MM" (gw0A0ABBCs   7 AB
	B
c                     | j                   dk(  rt        d|        t        t        dj	                  | 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   sL     	zzZ%(Gs&KLLuchhann/M&N%O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&''r   c                 (    t         | j                  ffS )z3support function for copy_reg to pickle module refs)unpickleModuler   )modules    r   pickleModuler6   ~   s    FOO---r   c                     | t         v r6t        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      sB    z&-.$dBC((r   c                 P    	 t         | j                         | j                         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                 ^    t               }|j                  |        |j                  |       |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<      s&     	AGGCLFF3KHr   c                 N    t         | j                         | j                         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                 >    t        |       }|j                  |       |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FF3KHr   c                   "    e Zd ZdZd Zd Zd Zy)	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        s?dd l}t	        |dd       r.|j                  |       D ]  }t        j                  d|         y )Nz!WARNING: serializing ephemeral %sr   get_referrersz referred to by )r   r   r   gcr   rS   )rP   rT   rs      r   __getstate__zEphemeral.__getstate__   sW    3d:;r?D1))$/ 4AGG.qc234r   c                 ^    t        j                  d| j                  z         t        | _        y )Nz#WARNING: unserializing ephemeral %s)r   r   r   rN   rP   states     r   __setstate__zEphemeral.__setstate__   s    5FG"r   N)r   r+   r,   __doc__rQ   rV   rZ   r   r   r   rN   rN      s    
#r   rN   	VersionedversionedsToUpgradec                  f    t        t        j                               D ]  } t        |         i ai ay N)listr]   valuesrequireUpgradeupgraded)	versioneds    r   	doUpgradere      s3    -4467 "	y!"Hr   c                 r    t        |       }|t        v r$|t        vrdt        |<   | j                          | S yy)z?Require that a Versioned instance be upgraded completely first.   N)idr]   rc   versionUpgrade)objobjIDs     r   rb   rb      s=    sGE##X(=
 )>#r   c                     | t         g}t        j                  |       D ])  }||vst        |t               s|j	                  |       + |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   	  sM     
IA^^A A:*Q	2HHQK QR5Lr   c                   ,    e Zd ZdZdZdZd ZddZd Zy)	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                 6    | t         t        |       <   || _        y r_   )r]   rh   __dict__rX   s     r   rZ   zVersioned.__setstate__3  s    (,BtH%r   Nc                    t        j                   |xs | j                        }t        | j                        }|j	                          |j                  | j                         |D ]]  }d|j                  v r|j                  D ]
  }||v s||=  d|j                  v s9|j                  |t        j                  |       d<   _ |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    ii-.(T^^$ 	,D#t}}4 33 &Ds{I& $t}}4 ++ ||D)**=>	, 
r   c                    t        | j                        }|j                          |j                  | j                         d| j                  v r{| j                  d   }| j                  d= d}d}|D ]/  }d|j                  vr|j
                  |kD  s"|}|j
                  }1 |r%|| j                  dt        j                  |      z  <   |D ]<  }t        |j                  vrd|j                  vr%|j
                  }dt        j                  |      z  }| j                  j                  |      xs d}|r| j                  |= ||k  sJ d       ||k  s|dz   }|j                  j                  d|z  d      }	|	rct        j                  dt        j                  |      d	t        j                  | j                        d
t        |       d|        |	|        n%t        j                  dj                  ||             ||k  r? y)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  s   ( 	T^^$4==0 ==!56D23NK ='t}}<**^;"&K%)%<%<N=   +gll;.GG   	D /(=11K.d1CCH--++H5:KMM(++-S/SS-+)Ao**+?++MtTGG $LL.#LL8tH' 4LGGBII + + 	r   r_   )	r   r+   r,   r[   r{   rz   rZ   rV   ri   r   r   r   r\   r\     s$    ( "?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      s  
      %  ' '*,
De&&&' , !.. $@   , /R"(& ""O 4.
)   , /A*A ,# #8 /1 T#{*+ 0$l lr   