o
    b1                     @   sP  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d	 Zd
d Zdd Zeeje dd Zdd Zeeje dd Zdd Zeeje dd Z dd Z!dd Z"dd Z#G dd dZ$i a%ee&d f ed!< i a'd"d# Z(d$d% Z)d&d' Z*G d(d  d Z+dS ))z(
Different styles of persisted objects.
    N)StringIO)Dict)logreflect)_PYPY
oldModulesc                 C   s   t | j| j| jjffS )z3support function for copy_reg to pickle method refs)unpickleMethod__name____self__	__class__)method r   :/usr/lib/python3/dist-packages/twisted/persisted/styles.pypickleMethod   s   r   c                 C   s   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methodObjectr   r   r   _methodFunction"   s   
r   c              	   C   s   |du r	t || S zt|| }W n& ty6   td| d| |dus'J d|j|u r- t| ||j Y S w d}tj||g|R  }|S )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   r   AttributeErrorr   msgr   r   types
MethodType)im_nameim_selfim_classmethodFunction
maybeClassboundr   r   r   r   4   s   


r   c                 C   s4   | 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__)fr   r   r   _pickleFunctionW   s   
r(   c                 C   s   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.reflectr)   )fullyQualifiedNamer)   r   r   r   r"   h   s   r"   c                 C   s   t | jffS )z3support function for copy_reg to pickle module refs)unpickleModuler	   )moduler   r   r   pickleModule~   s   r.   c                 C   s6   | t v rtd|   t |  } t|  t| i i dS )z5support function for copy_reg to unpickle module refszModule has moved: %sx)r   r   r   
__import__)namer   r   r   r,      s
   
r,   c                 C   s   	 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)stringor   r   r   pickleStringO   s   
r6   c                 C   s   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sekr/   r   r   r   r2      s   

r2   c                 C   s   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))
    )unpickleStringIr3   r4   )stringir   r   r   pickleStringI   s   r?   c                 C   s   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.
    )r7   r9   r:   r   r   r   r=      s   
r=   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )		Ephemeralzh
    This type of object is never persisted; if possible, even references to it
    are eliminated.
    c                 C   s   t dfS )zu
        Serialize any subclass of L{Ephemeral} in a way which replaces it with
        L{Ephemeral} itself.
        r   )r@   )selfr   r   r   
__reduce__   s   zEphemeral.__reduce__c                 C   sJ   t d|   ts#dd l}t|dd r#|| D ]
}t d|  qd S )Nz!WARNING: serializing ephemeral %sr   get_referrersz referred to by )r   r   r   gcr   rC   )rA   rD   rr   r   r   __getstate__   s   zEphemeral.__getstate__c                 C   s   t d| j  t| _d S )Nz#WARNING: unserializing ephemeral %s)r   r   r   r@   rA   stater   r   r   __setstate__   s   
zEphemeral.__setstate__N)r	   r%   r&   __doc__rB   rF   rI   r   r   r   r   r@      s
    
r@   	VersionedversionedsToUpgradec                  C   s&   t t D ]} t|  qi ai ad S N)listrL   valuesrequireUpgradeupgraded)	versionedr   r   r   	doUpgrade   s   
rS   c                 C   s4   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)idrL   rQ   versionUpgrade)objobjIDr   r   r   rP      s   rP   c                 C   s@   | t g}t| D ]}||vrt|t r|| q	|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)rK   inspectgetmro
issubclassappend)clbr   r   r   _aybabtu	  s   

ra   c                   @   s2   e Zd ZdZdZdZdd ZdddZd	d
 ZdS )rK   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                 C   s   | t t| < || _d S rM   )rL   rU   __dict__rG   r   r   r   rI   3  s   
zVersioned.__setstate__Nc                 C   s   t  |p| j}t| j}|  || j |D ]$}d|jv r-|jD ]	}||v r,||= q#d|jv r=|j|t	| d< q|S )z8Get state, adding a version number to it on its way out.persistenceForgetspersistenceVersionz.persistenceVersion)
copyrb   ra   r   reverser]   rc   rd   r   qual)rA   dictdctbasesbaseslotr   r   r   rF   7  s"   



zVersioned.__getstate__c           
      C   sZ  t | j}|  || j d| jv rB| jd }| jd= d}d}|D ]}d|jvr+q#|j|kr5|}|j}q#|rB|| jdt| < |D ]f}t|j	vrQd|jvrQqD|j}dt| }| j
|pbd}|ri| j|= ||ksqJ d||k r|d }|j
d| d}	|	rtdt|t| jt| |f  |	|  n	td	|| ||k suqDdS )
z (internal) Do a version upgrade.rd   r   Nz%s.persistenceVersionz"Sorry, can't go backwards in time.rT   zupgradeToVersion%sz'Upgrading %s (of %s @ %s) to version %sz(Warning: cannot upgrade {} to version {})ra   r   rf   r]   rb   rd   r   rg   rK   	__bases__getr   r   rU   format)
rA   rj   pverhighestVersionhighestBaserk   currentVerspverNamepersistVersr   r   r   r   rV   H  sh   









	zVersioned.versionUpgraderM   )	r	   r%   r&   rJ   rd   rc   rI   rF   rV   r   r   r   r   rK     s    
),rJ   re   copyregcopy_regrZ   pickler   ior   r7   typingr   twisted.pythonr   r   twisted.python.compatr   r   str
ModuleType__annotations__PicklingErrorr!   r   r   r   r   r(   r"   FunctionTyper.   r,   r6   r2   r?   r=   r@   rL   intrQ   rS   rP   ra   rK   r   r   r   r   <module>   sB    		