U
    ª€ljú:  ã                   @  s  d dl m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m	Z	m
Z
mZ d dlmZ d dlmZmZmZ d dlmZ d dlmZ G dd	„ d	eƒ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ƒZG dd„ dejƒZG dd„ deƒZG dd„ dƒZ G dd„ dƒZ!G dd„ dƒZ"G dd„ dƒZ#d d!d"œd#d$„Z$e e"e$¡ G d%d&„ d&ƒZ%G d'd(„ d(ƒZ&d)d*œd+d,„Z'G d-d.„ d.eƒZ(G d/d0„ d0eƒZ)G d1d2„ d2ƒZ*G d3d4„ d4ƒZ+e
ed5e,f  Z-G d6d7„ d7eƒZ.G d8d9„ d9eƒZ/eee(gZ0dS ):é    )ÚannotationsN)ÚAnyÚCallableÚListÚTuple)ÚNoReturn)ÚaotÚcrefutilÚstyles)Úunittest)ÚTestCasec                   @  sD   e Zd Zddœdd„Zddœdd„Zddœdd„Zddœd	d
„ZdS )ÚVersionTestsÚNone©Úreturnc                 C  sP   G dd„ dƒa t t ƒ ¡}G dd„ dtjƒa t |¡}t ¡  |jsLtdƒ‚d S )Nc                   @  s   e Zd Zddœdd„ZdS )ÚNullVersionedr   r   c                 S  s
   d| _ d S )Nr   ©Úok©Úself© r   ú?/tmp/pip-unpacked-wheel-aghyhbke/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œdd„ZdS )r   é   r   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!)	r   Ú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s˜tdƒ‚|jdksªtdƒ‚d S )	Nc                   @  sH   e Zd ZdZdgZdZdZddœdd„Zddœdd	„Zddœd
d„Z	dS )ÚMyVersionedé   Úgarbagedatar   r   r   c                 S  s   d| _ dd„ | _d S )NZxxxc                 S  s   dS )Nzcant persistr   )Úqr   r   r   Ú<lambda>5   ó    z&MyVersioned.__init__.<locals>.<lambda>)Zsomedatar*   r   r   r   r   r   3   s    zMyVersioned.__init__c                 S  s   |  j d7  _ d S r   )Úv3r   r   r   r   ÚupgradeToVersion37   s    zMyVersioned.upgradeToVersion3c                 S  s   |  j d7  _ d S r   )Úv4r   r   r   r   ÚupgradeToVersion4:   s    zMyVersioned.upgradeToVersion4N)
r   r   r   r    ZpersistenceForgetsr.   r0   r   r/   r1   r   r   r   r   r(   ,   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.   r0   r&   r!   r"   r    r$   r%   )r   ÚmvÚpicklÚobjr   r   r   Útest_versionUpgrade)   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ddœdd„Zddœdd	„Zd
S )ÚClassWithCustomHashÚstrÚintr   )ÚuniqueÚhashr   c                 S  s   || _ || _d S ©N)r:   r;   )r   r:   r;   r   r   r   r   O   s    zClassWithCustomHash.__init__r   c                 S  s   | j S r<   )r;   r   r   r   r   Ú__hash__S   s    zClassWithCustomHash.__hash__N)r   r   r   r   r=   r   r   r   r   r7   N   s   r7   Úv1r   Úv2r   c                 S  s   t | ddƒS ©NÚupgradedT©Úsetattrr   r   r   r   r,   \   s     ÿz3VersionTests.test_nonIdentityHash.<locals>.<lambda>)r
   r#   r7   r!   r"   r    r   r$   r%   ÚassertEqualr:   Ú
assertTruerA   )r   r>   r?   Zpklr   r   r   Útest_nonIdentityHashK   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_dddœ‡ fd	d
„}|t_dt_dddœ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   rG   i   s   rG   c                   @  s   e Zd ZdS )Ú	ToyClassBNrH   r   r   r   r   rI   l   s   rI   r   r   r   )r   r   c                   s   t  ˆ ¡| _t ¡  d S r<   )r!   r$   Úyr
   r%   r   ©ZpklBr   r   r   u   s    zWVersionTests.test_upgradeDeserializesObjectsRequiringUpgrade.<locals>.upgradeToVersion1Úobjectc                 S  s   t | ddƒ d S r@   rB   r   r   r   r   ÚsetUpgraded|   s    zQVersionTests.test_upgradeDeserializesObjectsRequiringUpgrade.<locals>.setUpgraded)r
   r#   rG   rI   r!   r"   r    r   r$   r%   rE   rJ   rA   )r   ÚxrJ   ZpklAr   rM   r   rK   r   Ú/test_upgradeDeserializesObjectsRequiringUpgradef   s    
z<VersionTests.test_upgradeDeserializesObjectsRequiringUpgradeN)r   r   r   r'   r6   rF   rO   r   r   r   r   r      s   "r   c                   @  s   e Zd ZdS )ÚVersionedSubClassNrH   r   r   r   r   rP   †   s   rP   c                   @  s   e Zd ZdS )ÚSecondVersionedSubClassNrH   r   r   r   r   rQ   Š   s   rQ   c                   @  s   e Zd ZdS )ÚVersionedSubSubClassNrH   r   r   r   r   rR   Ž   s   rR   c                   @  s   e Zd ZdS )ÚVersionedDiamondSubClassNrH   r   r   r   r   rS   ’   s   rS   c                   @  sH   e Zd ZdZddœdd„Zddœdd„Zddœdd	„Zddœ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.
    r   r   c                 C  s   |   t tj¡g ¡ dS )zM
        L{styles._aybabtu} of L{Versioned} itself is an empty list.
        N)rD   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)rD   r
   rU   rP   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)rD   r
   rU   rR   rP   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)rD   r
   rU   rS   rR   rP   rQ   r   r   r   r   Útest_aybabtuStrict°   s    þzAybabtuTests.test_aybabtuStrictN)r   r   r   Ú__doc__rV   rW   rX   rY   r   r   r   r   rT   –   s
   rT   c                   @  s   e Zd Zdddœdd„ZdS )ÚMyEphemeralr9   r   ©rN   r   c                 C  s
   || _ d S r<   ©rN   ©r   rN   r   r   r   r   ¼   s    zMyEphemeral.__init__Nr   r   r   r   r   r[   »   s   r[   c                   @  s   e Zd Zddœdd„ZdS )ÚEphemeralTestsr   r   c                 C  s\   t dƒ}|  |jt ¡ |  |jd¡ t |¡}t |¡}|  |jtj¡ |  	t
|dƒ¡ d S )Né   rN   )r[   rD   Ú	__class__rN   r!   r"   r$   r
   Ú	EphemeralZassertFalseÚhasattr)r   Úor4   r   r   r   Útest_ephemeralÁ   s    

zEphemeralTests.test_ephemeralN)r   r   r   re   r   r   r   r   r_   À   s   r_   c                   @  s*   e Zd Zdddœdd„Zddœdd„Zd	S )
Ú
Pickleabler9   r   r\   c                 C  s
   || _ d S r<   r]   r^   r   r   r   r   Î   s    zPickleable.__init__r   c                 C  s   | j S r<   r]   r   r   r   r   ÚgetXÑ   s    zPickleable.getXN)r   r   r   r   rg   r   r   r   r   rf   Í   s   rf   c                   @  s   e Zd ZdZddœdd„ZdS )ÚNotPickleablez)
    A class that is not pickleable.
    r   r   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   rZ   rj   r   r   r   r   rh   Õ   s   rh   c                   @  s   e Zd ZdZddœdd„ZdS )ÚCopyRegisteredzb
    A class that is pickleable only because it is registered with the
    C{copyreg} module.
    r   r   c                 C  s   t ƒ | _dS )zE
        Ensure that this object is normally not pickleable.
        N)rh   ZnotPickleabler   r   r   r   r   ç   s    zCopyRegistered.__init__N)r   r   r   rZ   r   r   r   r   r   rk   á   s   rk   c                   @  s   e Zd ZdZdS )ÚCopyRegisteredLoadedz2
    L{CopyRegistered} after unserialization.
    N)r   r   r   rZ   r   r   r   r   rl   î   s   rl   rL   z,tuple[type[CopyRegisteredLoaded], tuple[()]])Úcrr   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   )rl   )rm   r   r   r   ÚreduceCopyRegisteredô   s    	rn   c                   @  s(   e Zd ZU dZded< ddœdd„ZdS )	ÚAú
    dummy class
    zCallable[[], None]Úbmethodr   r   c                 C  s   d S r<   r   r   r   r   r   Úamethod
  s    z	A.amethodN)r   r   r   rZ   Ú__annotations__rr   r   r   r   r   ro     s   
ro   c                   @  s(   e Zd ZU dZded< ddœdd„ZdS )	ÚBrp   ro   Úar   r   c                 C  s   d S r<   r   r   r   r   r   rq     s    z	B.bmethodN)r   r   r   rZ   rs   rq   r   r   r   r   rt     s   
rt   r   r   c                   C  s   d S r<   r   r   r   r   r   Úfunktion  s    rv   c                   @  s,   e Zd ZdZddœdd„Zddœdd„ZdS )	ÚPicklingTestsz$Test pickling of extra object types.r   r   c                 C  s$   t  t¡}t  |¡}|  |t¡ d S r<   )r!   r"   r
   r$   rD   )r   r4   rd   r   r   r   Útest_module   s    

zPicklingTests.test_modulec                 C  sF   t dƒ}t |j¡}t |¡}|  |ƒ d¡ |  t|ƒt|jƒ¡ d S )Nr2   )rf   r!   r"   rg   r$   rD   Útype)r   r5   r4   rd   r   r   r   Útest_instanceMethod%  s
    
z!PicklingTests.test_instanceMethodN)r   r   r   rZ   rx   rz   r   r   r   r   rw     s   rw   c                   @  s   e Zd ZdZddœ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.
    r   r   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
.ÚtestN)r!   r$   ÚassertIsInstanceÚioÚStringIOrD   Úgetvalue)r   ZpickledStringIWithTextZloadedr   r   r   Útest_unpickleBytesIO3  s
    ÿ
z,StringIOTransitionTests.test_unpickleBytesION)r   r   r   rZ   r�   r   r   r   r   r{   -  s   r{   c                   @  s6   e Zd ZU d ed< d ed< ded< dddœdd„Zd	S )
ÚEvilSourcerorru   ÚbrL   Úcr   r\   c                 C  s   | | _ | | j _|| j j_d S r<   )ru   rƒ   r„   r^   r   r   r   r   F  s    zEvilSourceror.__init__N)r   r   r   rs   r   r   r   r   r   r‚   A  s   
r‚   c                   @  s4   e Zd ZU ded< ddœdd„Zdddœdd	„Zd
S )ÚNonDictStater8   Ústater   c                 C  s   | j S r<   ©r†   r   r   r   r   Ú__getstate__O  s    zNonDictState.__getstate__r   )r†   r   c                 C  s
   || _ d S r<   r‡   )r   r†   r   r   r   Ú__setstate__R  s    zNonDictState.__setstate__N)r   r   r   rs   rˆ   r‰   r   r   r   r   r…   L  s   
r…   Ú_CircularTupleTypec                   @  s˜   e Zd Zddœdd„Zddœdd„Zddœdd„Zddœd	d
„Zddœdd„Zddœdd„Zddœdd„Z	ddœdd„Z
ddœdd„Zddœdd„ZdS )ÚAOTTestsr   r   c              
   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)   r`   ÚhelloÚworld)ÚsliceÚsysÚmaxsizeÚEllipsisr   ÚunjellyFromSourceÚjellyToSourcerD   )r   r5   ZrtObjr   r   r   Útest_simpleTypesZ  s    
özAOTTests.test_simpleTypesc                 C  sL   t ƒ }tƒ }|j|_||_t t |¡¡jj}|  t |¡j	t 
|¡¡ d S r<   )ro   rt   rq   ru   r   r’   r“   rD   Z_selfOfMethodra   Z_classOfMethod)r   ru   rƒ   Zim_r   r   r   Útest_methodSelfIdentityj  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)	ro   rt   rq   ru   ÚassertRaisesri   r   r’   r“   )r   ru   rƒ   Zsavedbmethodr   r   r   Útest_methodNotSelfIdentityr  s    z#AOTTests.test_methodNotSelfIdentityc                 C  s$   G dd„ dƒ}|   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                   @  s0   e Zd Zeddœdd„ƒZeddœdd„ƒZdS )z2AOTTests.test_unsupportedType.<locals>.UnknownTyper   r   c                 S  s
   t ƒ ‚d S r<   ©ÚAttributeErrorr   r   r   r   Ú__dict__‹  s    z;AOTTests.test_unsupportedType.<locals>.UnknownType.__dict__c                 S  s
   t ƒ ‚d S r<   r˜   r   r   r   r   rˆ   �  s    z?AOTTests.test_unsupportedType.<locals>.UnknownType.__getstate__N)r   r   r   Úpropertyrš   rˆ   r   r   r   r   ÚUnknownTypeŠ  s   rœ   N)r–   ri   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s„t	‚|d d
d… |d
d… ks¤t	‚d S )Nr�   )rŒ   Úmethodr   r)   r`   zhe	llo

"x world!u   goodbye 
	á€� world!g      ð?éd   r   é   )
r   Z
AOTJellierZ	jellyToAOr   rv   Ú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   ru   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“   rk   r}   rl   )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 r<   )r‚   r   Ú
jellyToAOTÚunjellyFromAOTru   r&   rƒ   r„   )r   rd   Ú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«   r}   r¡   ZassertIsrD   )r   r¤   r¥   r¬   r­   r   r   r   Útest_circularTupleÆ  s    


zAOTTests.test_circularTuplec                 C  s$   |   t ddg ii¡t d¡¡ dS )z:
        The generated serialization is indented.
        rŒ   r�   z|                app={
                  'hello':{
                    'world':[],
                    },
                  }N)rD   r   r“   ÚtextwrapÚdedentr   r   r   r   ÚtestIndentifyÓ  s    ÿþzAOTTests.testIndentifyN)r   r   r   r”   r•   r—   r�   r§   r¨   r©   r®   r¯   r²   r   r   r   r   r‹   Y  s   	r‹   c                   @  sV   e Zd ZdZddœdd„Zddœdd„Zddœdd	„Zddœd
d„Zddœdd„ZdS )ÚCrefUtilTestsz 
    Tests for L{crefutil}.
    r   r   c                 C  s    t  i ¡}|  t|jdd¡ dS )zO
        L{crefutil._DictKeyAndValue} only support keys C{0} and C{1}.
        r)   r`   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)   r`   z	ignore-meN)r	   Z
_ContainerÚlistr–   r&   ZaddDependant)r   Ú	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¾   ry   r   r   r   r   Ú*test_dontCallInstanceMethodsThatArentReady  s    þz8CrefUtilTests.test_dontCallInstanceMethodsThatArentReadyN)	r   r   r   rZ   r·   r¸   r»   r¿   rÀ   r   r   r   r   r³   ä  s   	r³   )1Ú
__future__r   Úcopyregr~   r!   r�   r°   Útypingr   r   r   r   Ztyping_extensionsr   Ztwisted.persistedr   r	   r
   Ztwisted.trialr   Ztwisted.trial.unittestr   r   r#   rP   rQ   rR   rS   rT   rb   r[   r_   rf   rh   rk   rl   rn   ro   rt   rv   rw   r{   r‚   r…   r9   rŠ   r‹   r³   Z	testCasesr   r   r   r   Ú<module>   sH   q%
 4