U
    W[ 9                     @   s<  d dl mZmZ d dlZd dlmZ zd dlZW n ek
rL   d dlZY nX d dl	Z	zd dl
mZ W n ek
r~   dZY nX dZzd dlZW n   d dlZY nX d dlmZmZmZ d dlmZ G dd	 d	ejZG d
d dejZG dd dejZG dd deZG dd deeZG dd dejZG dd dejZG dd dejZ G dd dZ!G dd de"Z#G dd de"Z$G dd de"Z%d d! Z&ee$e& G d"d# d#Z'G d$d% d%Z(d&d' Z)G d(d) d)ejZ*G d*d+ d+ejZ+G d,d- d-Z,G d.d/ d/Z-G d0d1 d1ejZ.G d2d3 d3ejZ/ee e*gZ0dS )4    )divisionabsolute_importN)unittest)StringIOzNo cStringIO available.)stylesaotcrefutil)_PY3c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
VersionTestsc                 C   sT   G dd dt att }G dd dtjt at|}t  |jsPt	dd S )Nc                   @   s   e Zd Zdd ZdS )NullVersionedc                 S   s
   d| _ d S )Nr   okself r   =/usr/lib/python3/dist-packages/twisted/test/test_persisted.py__init__(   s    zNullVersioned.__init__N__name__
__module____qualname__r   r   r   r   r   r   '   s   r   c                   @   s   e Zd ZdZdd ZdS )r      c                 S   s
   d| _ d S Nr   r   r   r   r   r   upgradeToVersion1-   s    zNullVersioned.upgradeToVersion1N)r   r   r   persistenceVersionr   r   r   r   r   r   +   s   zinitial upgrade not run!)
objectr   pickledumpsr   	Versionedloads	doUpgrader   AssertionError)r   ZpkclZmnvr   r   r   test_nullVersionUpgrade%   s    
z$VersionTests.test_nullVersionUpgradec                 C   s   G dd dt jat }|js$|jr,tdt|}dt_t	|}t 
  |js\td|jsjtdt|}t	|}t 
  |jdkstd|jdkstdd S )	Nc                   @   s6   e Zd ZdZdgZdZdZdd Zdd Zdd	 Z	d
S )MyVersioned   garbagedatar   c                 S   s   d| _ dd | _d S )NZxxxc                 S   s   dS )Nzcant persistr   )qr   r   r   <lambda>=       z&MyVersioned.__init__.<locals>.<lambda>)Zsomedatar%   r   r   r   r   r   ;   s    zMyVersioned.__init__c                 S   s   |  j d7  _ d S r   )v3r   r   r   r   upgradeToVersion3?   s    zMyVersioned.upgradeToVersion3c                 S   s   |  j d7  _ d S r   )v4r   r   r   r   upgradeToVersion4B   s    zMyVersioned.upgradeToVersion4N)
r   r   r   r   ZpersistenceForgetsr)   r+   r   r*   r,   r   r   r   r   r#   5   s   r#   zhasn't been upgraded yet   zdidn't do version 3 upgradezdidn't do version 4 upgrader   zupgraded unnecessarily)r   r   r#   r)   r+   r!   r   r   r   r   r    )r   Zmvpicklobjr   r   r   test_versionUpgrade3   s    



z VersionTests.test_versionUpgradec                 C   s   G dd dt jatdd}tdd}t||f}~~dt_dd t_t|\}}t   | 	|j
d | 	|j
d | |j | |j d S )	Nc                   @   s   e Zd Zdd Zdd ZdS )ClassWithCustomHashc                 S   s   || _ || _d S N)uniquehash)r   r3   r4   r   r   r   r   U   s    zClassWithCustomHash.__init__c                 S   s   | j S r2   )r4   r   r   r   r   __hash__X   s    zClassWithCustomHash.__hash__N)r   r   r   r   r5   r   r   r   r   r1   T   s   r1   v1r   v2r   c                 S   s   t | ddS NupgradedTsetattrr   r   r   r   r'   a   r(   z3VersionTests.test_nonIdentityHash.<locals>.<lambda>)r   r   r1   r   r   r   r   r   r    assertEqualr3   
assertTruer9   )r   r6   r7   Zpklr   r   r   test_nonIdentityHashR   s    


z!VersionTests.test_nonIdentityHashc                    s   G dd dt jaG dd dt jat }t }t|t| } ~~dt_ fdd}|t_dt_dd	 t_t|}t 	  | 
|jj d S )
Nc                   @   s   e Zd ZdS )	ToyClassANr   r   r   r   r   r   r   r?   k   s   r?   c                   @   s   e Zd ZdS )	ToyClassBNr@   r   r   r   r   rA   m   s   rA   r   c                    s   t  | _t  d S r2   )r   r   yr   r    r   ZpklBr   r   r   t   s    zWVersionTests.test_upgradeDeserializesObjectsRequiringUpgrade.<locals>.upgradeToVersion1c                 S   s   t | ddS r8   r:   r   r   r   r   r'   y   r(   zNVersionTests.test_upgradeDeserializesObjectsRequiringUpgrade.<locals>.<lambda>)r   r   r?   rA   r   r   r   r   r   r    r=   rB   r9   )r   xrB   ZpklAr   r   rC   r   /test_upgradeDeserializesObjectsRequiringUpgradei   s    

z<VersionTests.test_upgradeDeserializesObjectsRequiringUpgradeN)r   r   r   r"   r0   r>   rE   r   r   r   r   r
   $   s   r
   c                   @   s   e Zd ZdS )VersionedSubClassNr@   r   r   r   r   rF      s   rF   c                   @   s   e Zd ZdS )SecondVersionedSubClassNr@   r   r   r   r   rG      s   rG   c                   @   s   e Zd ZdS )VersionedSubSubClassNr@   r   r   r   r   rH      s   rH   c                   @   s   e Zd ZdS )VersionedDiamondSubClassNr@   r   r   r   r   rI      s   rI   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )AybabtuTestsz
    L{styles._aybabtu} gets all of classes in the inheritance hierarchy of its
    argument that are strictly between L{Versioned} and the class itself.
    c                 C   s   |  ttjg  dS )zM
        L{styles._aybabtu} of L{Versioned} itself is an empty list.
        N)r<   r   _aybabtur   r   r   r   r   test_aybabtuStrictEmpty   s    z$AybabtuTests.test_aybabtuStrictEmptyc                 C   s   |  ttg  dS )z
        There are no classes I{between} L{VersionedSubClass} and L{Versioned},
        so L{styles._aybabtu} returns an empty list.
        N)r<   r   rK   rF   r   r   r   r   test_aybabtuStrictSubclass   s    z'AybabtuTests.test_aybabtuStrictSubclassc                 C   s   |  tttg dS )z
        With a sub-sub-class of L{Versioned}, L{styles._aybabtu} returns a list
        containing the intervening subclass.
        N)r<   r   rK   rH   rF   r   r   r   r   test_aybabtuSubsubclass   s    z$AybabtuTests.test_aybabtuSubsubclassc                 C   s   |  tttttg dS )z
        For a diamond-shaped inheritance graph, L{styles._aybabtu} returns a
        list containing I{both} intermediate subclasses.
        N)r<   r   rK   rI   rH   rF   rG   r   r   r   r   test_aybabtuStrict   s    zAybabtuTests.test_aybabtuStrictN)r   r   r   __doc__rL   rM   rN   rO   r   r   r   r   rJ      s
   	rJ   c                   @   s   e Zd Zdd ZdS )MyEphemeralc                 C   s
   || _ d S r2   rD   r   rD   r   r   r   r      s    zMyEphemeral.__init__Nr   r   r   r   r   rQ      s   rQ   c                   @   s   e Zd Zdd ZdS )EphemeralTestsc                 C   s\   t d}| |jt  | |jd t|}t|}| |jtj | 	t
|d d S )N   rD   )rQ   r<   	__class__rD   r   r   r   r   	EphemeralZassertFalsehasattr)r   or.   r   r   r   test_ephemeral   s    

zEphemeralTests.test_ephemeralN)r   r   r   rZ   r   r   r   r   rT      s   rT   c                   @   s   e Zd Zdd Zdd ZdS )
Pickleablec                 C   s
   || _ d S r2   rR   rS   r   r   r   r      s    zPickleable.__init__c                 C   s   | j S r2   rR   r   r   r   r   getX   s    zPickleable.getXN)r   r   r   r   r\   r   r   r   r   r[      s   r[   c                   @   s   e Zd ZdZdd ZdS )NotPickleablez)
    A class that is not pickleable.
    c                 C   s   t ddS )z9
        Raise an exception instead of pickling.
        zNot serializable.N)	TypeErrorr   r   r   r   
__reduce__   s    zNotPickleable.__reduce__N)r   r   r   rP   r_   r   r   r   r   r]      s   r]   c                   @   s   e Zd ZdZdd ZdS )CopyRegisteredzb
    A class that is pickleable only because it is registered with the
    C{copyreg} module.
    c                 C   s   t  | _dS )zE
        Ensure that this object is normally not pickleable.
        N)r]   ZnotPickleabler   r   r   r   r      s    zCopyRegistered.__init__N)r   r   r   rP   r   r   r   r   r   r`      s   r`   c                   @   s   e Zd ZdZdS )CopyRegisteredLoadedz2
    L{CopyRegistered} after unserialization.
    N)r   r   r   rP   r   r   r   r   ra      s   ra   c                 C   s   t dfS )z
    Externally implement C{__reduce__} for L{CopyRegistered}.

    @param cr: The L{CopyRegistered} instance.

    @return: a 2-tuple of callable and argument list, in this case
        L{CopyRegisteredLoaded} and no arguments.
    r   )ra   )Zcrr   r   r   reduceCopyRegistered   s    	rb   c                   @   s   e Zd ZdZdd ZdS )A
    dummy class
    c                 C   s   d S r2   r   r   r   r   r   amethod  s    z	A.amethodN)r   r   r   rP   re   r   r   r   r   rc     s   rc   c                   @   s   e Zd ZdZdd ZdS )Brd   c                 C   s   d S r2   r   r   r   r   r   bmethod  s    z	B.bmethodN)r   r   r   rP   rg   r   r   r   r   rf     s   rf   c                   C   s   d S r2   r   r   r   r   r   funktion  s    rh   c                   @   sJ   e Zd ZdZdd Zdd Zejdkr,de_dd	 Z	d
d Z
erFee
_dS )PicklingTestsz$Test pickling of extra object types.c                 C   s$   t t}t |}| |t d S r2   )r   r   r   r   r<   r   r.   rY   r   r   r   test_module!  s    

zPicklingTests.test_modulec                 C   s(   t tj}t |}| |tj dS )zt
        After importing L{twisted.persisted.styles}, it is possible to pickle
        classmethod objects.
        N)r   r   r[   r\   r   r<   rj   r   r   r   test_classMethod'  s    
zPicklingTests.test_classMethod)rU   r-   z_As of Python 3.4 it is no longer possible to globally change the behavior of function pickling.c                 C   sF   t d}t|j}t|}| | d | t|t|j d S )Nr-   )r[   r   r   r\   r   r<   type)r   r/   r.   rY   r   r   r   test_instanceMethod7  s
    
z!PicklingTests.test_instanceMethodc                 C   sL   t  }|d t|}t|}| t|t| | | d d S )Nabc)_oldStyleCStringIOwriter   r   r   r<   rm   getvalue)r   fr.   rY   r   r   r   test_stringIO>  s    


zPicklingTests.test_stringION)r   r   r   rP   rk   rl   sysversion_infoskiprn   rt   skipStringIOr   r   r   r   ri     s   	
ri   c                   @   s    e Zd ZdZesdZdd ZdS )StringIOTransitionTestsz
    When pickling a cStringIO in Python 2, it should unpickle as a BytesIO or a
    StringIO in Python 3, depending on the type of its contents.
    z4In Python 2 we can still unpickle cStringIO as such.c                 C   s0   d}t |}| |tj | | d dS )zg
        A cStringIO pickled with bytes in it will yield an L{io.BytesIO} on
        python 3.
        sE   ctwisted.persisted.styles
unpickleStringI
p0
(S'test'
p1
I0
tp2
Rp3
.ZtestN)r   r   assertIsInstanceior   r<   rr   )r   ZpickledStringIWithTextZloadedr   r   r   test_unpickleBytesIOU  s
    
z,StringIOTransitionTests.test_unpickleBytesION)r   r   r   rP   r	   rw   r|   r   r   r   r   ry   K  s   ry   c                   @   s   e Zd Zdd ZdS )EvilSourcerorc                 C   s   | | _ | | j _|| j j_d S r2   )abcrS   r   r   r   r   e  s    zEvilSourceror.__init__Nr   r   r   r   r   r}   d  s   r}   c                   @   s   e Zd Zdd Zdd ZdS )NonDictStatec                 C   s   | j S r2   stater   r   r   r   __getstate__k  s    zNonDictState.__getstate__c                 C   s
   || _ d S r2   r   )r   r   r   r   r   __setstate__m  s    zNonDictState.__setstate__N)r   r   r   r   r   r   r   r   r   r   j  s   r   c                   @   sT   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )AOTTestsc              
   C   sF   ddddt dddddtjd d tf
}tt|}| || d S )	Nr   g       @y              @Tr$   rU   helloworld)sliceru   maxsizeEllipsisr   unjellyFromSourcejellyToSourcer<   )r   r/   ZrtObjr   r   r   test_simpleTypesq  s      zAOTTests.test_simpleTypesc                 C   sL   t  }t }|j|_||_tt|jj}| t|j	t
| d S r2   )rc   rf   rg   r~   r   r   r   r<   Z_selfOfMethodrV   Z_classOfMethod)r   r~   r   Zim_r   r   r   test_methodSelfIdentityx  s    z AOTTests.test_methodSelfIdentityc                 C   sL   t  }t }|j|_||_tj}t`z| ttjt| W 5 |t_X dS )z
        If a class change after an instance has been created,
        L{aot.unjellyFromSource} shoud raise a C{TypeError} when trying to
        unjelly the instance.
        N)	rc   rf   rg   r~   assertRaisesr^   r   r   r   )r   r~   r   Zsavedbmethodr   r   r   test_methodNotSelfIdentity  s    
z#AOTTests.test_methodNotSelfIdentityc                 C   s&   G dd dt }| ttj|  dS )z
        L{aot.jellyToSource} should raise a C{TypeError} when trying to jelly
        an unknown type without a C{__dict__} property or C{__getstate__}
        method.
        c                   @   s   e Zd Zedd ZdS )z2AOTTests.test_unsupportedType.<locals>.UnknownTypec                 S   s
   t  d S r2   )AttributeErrorr   r   r   r   __dict__  s    z;AOTTests.test_unsupportedType.<locals>.UnknownType.__dict__N)r   r   r   propertyr   r   r   r   r   UnknownType  s   r   N)r   r   r^   r   r   )r   r   r   r   r   test_unsupportedType  s    zAOTTests.test_unsupportedTypec                 C   s   t  j}d|d}dddddddd	d	 tt j|tg}t|}|| || || t t ||g}|d
 |d kst	|d d
d |d
d kst	d S )Nr   )r   methodr   r$   rU   zhe	llo

"x world!u   goodbye 
	တ world!g      ?d   r      )
r   Z
AOTJellierZ	jellyToAOr   rh   tupleappendr   r   r!   )r   Zajdltujr   r   r   test_basicIdentity  s(    

     


zAOTTests.test_basicIdentityc                 C   s,   t  }d|_tt|j|jks(td S )Nz	meringue!)r   r   r   r   r   r!   )r   r~   r   r   r   test_nonDictState  s    zAOTTests.test_nonDictStatec                 C   s"   t t t }| |t dS )z
        L{aot.jellyToSource} and L{aot.unjellyFromSource} honor functions
        registered in the pickle copy registry.
        N)r   r   r   r`   rz   ra   )r   r   r   r   r   test_copyReg  s    zAOTTests.test_copyRegc                 C   sV   t t g }t|}t|}|j|ks.t|jj|jks@t|j|jjk	sRtd S r2   )r}   r   
jellyToAOTunjellyFromAOTr~   r!   r   r   )r   rY   j1ojr   r   r   test_funkyReferences  s    

zAOTTests.test_funkyReferencesc                 C   sf   g }|df}| | t|}t|}| |d t | |d d | | |d d d dS )zS
        L{aot.jellyToAOT} can persist circular references through tuples.
        i  r   r   N)r   r   r   r   rz   r   ZassertIsr<   )r   r   r   r   r   r   r   r   test_circularTuple  s    


zAOTTests.test_circularTupleN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   p  s   
	
r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )CrefUtilTestsz 
    Tests for L{crefutil}.
    c                 C   s    t i }| t|jdd dS )zO
        L{crefutil._DictKeyAndValue} only support keys C{0} and C{1}.
        r$   rU   N)r   Z_DictKeyAndValuer   RuntimeError__setitem__r   r   r   r   r   test_dictUnknownKey  s    
z!CrefUtilTests.test_dictUnknownKeyc                 C   s&   t  }d|d< | t|jdd dS )zI
        L{crefutil._Defer} can be assigned a key only one time.
        r   r   N)r   Z_Deferr   r   r   r   r   r   r   test_deferSetMultipleTimes  s    z(CrefUtilTests.test_deferSetMultipleTimesc                 C   s(   t dddgt}| t|ji d dS )z
        A L{crefutil._Container} where all of its elements are known at
        construction time is nonsensical and will result in errors in any call
        to addDependant.
        r   r$   rU   z	ignore-meN)r   Z
_Containerlistr   r!   ZaddDependant)r   Z	containerr   r   r   &test_containerWhereAllElementsAreKnown  s      z4CrefUtilTests.test_containerWhereAllElementsAreKnownc                 C   s   |  tt jt d dS )z
        If a dictionary key contains a circular reference (which is probably a
        bad practice anyway) it will be resolved by a
        L{crefutil._DictKeyAndValue}, not by placing a L{crefutil.NotKnown}
        into a dictionary key.
        valueN)r   r!   dictr   r   NotKnownr   r   r   r   .test_dontPutCircularReferencesInDictionaryKeys  s
      z<CrefUtilTests.test_dontPutCircularReferencesInDictionaryKeysc                 C   s   |  ttdt t dS )z
        L{crefutil._InstanceMethod} raises L{AssertionError} to indicate it
        should not be called.  This should not be possible with any of its API
        clients, but is provided for helping to debug.
        Zno_nameN)r   r!   r   Z_InstanceMethodr   rm   r   r   r   r   *test_dontCallInstanceMethodsThatArentReady
  s      z8CrefUtilTests.test_dontCallInstanceMethodsThatArentReadyN)	r   r   r   rP   r   r   r   r   r   r   r   r   r   r     s   	r   )1Z
__future__r   r   ru   Ztwisted.trialr   ZcPickler   ImportErrorr{   	cStringIOr   rp   rx   copyregZcopy_regZtwisted.persistedr   r   r   Ztwisted.python.compatr	   ZTestCaser
   r   rF   rG   rH   rI   rJ   rW   rQ   rT   r[   r   r]   r`   ra   rb   rc   rf   rh   ri   ry   r}   r   r   r   Z	testCasesr   r   r   r   <module>   sT   
])
-n8