B
    u9a8                 @   s  d Z ddlZddlZddlZddlZyddlmZ W n ek
rP   dd ZY nX ddlm	Z	 G dd dZ
G d	d
 d
e
ZG dd de
ZG dd de
ZG dd deZG dd deeZG dd dZG dd deejZG dd dZG dd deeZG dd deeZG dd deeZG dd  d eejZG d!d" d"ZG d#d$ d$eeZG d%d& d&eeZG d'd( d(eeZG d)d* d*eejZG d+d, d,eZeG d-d. d.eZeG d/d0 d0eZeG d1d2 d2eeZ e	j!G d3d4 d4eejZ"e#d5kr
e$  dS )6zB
Tests for object finalization semantics, as outlined in PEP 442.
    N)with_tp_delc             C   s   G dd dt }|S )Nc               @   s   e Zd Zdd ZdS )zwith_tp_del.<locals>.Cc             _   s   t dd S )Nzrequires _testcapi.with_tp_del)	TypeError)clsargskwargs r   '/usr/lib/python3.7/test_finalization.py__new__   s    zwith_tp_del.<locals>.C.__new__N)__name__
__module____qualname__r	   r   r   r   r   C   s   r   )object)r   r   r   r   r   r      s    r   )supportc               @   s^   e Zd ZdZg Zg Zg Zg ZdZdZ	e
dd Ze
ejdd Zdd	 Zd
d Zdd ZdS )NonGCSimpleBasezd
    The base class for all the objects under test, equipped with various
    testing features.
    Fr   c             C   s>   | j   | j  tj  t  | j  | j  d S )N)	survivorsclearerrorsgcgarbagecollect	del_callstp_del_calls)r   r   r   r   _cleanup%   s    



zNonGCSimpleBase._cleanupc          	   c   s^   t  L | j  | j  dt_zdV  | jr<| jd W ddt_|   X W dQ R X dS )zI
        A context manager to use around all finalization tests.
        FNr   T)	r   Z
disable_gcr   r   r   r   	_cleaningr   r   )r   r   r   r   test.   s    


zNonGCSimpleBase.testc             C   s   dS )z8
        Check the object is sane (non-broken).
        Nr   )selfr   r   r   check_sanity@   s    zNonGCSimpleBase.check_sanityc          
   C   s^   y*| j s(| jt|  |   |   W n. tk
rX } z| j| W dd}~X Y nX dS )z
        PEP 442 finalizer.  Record that this was called, check the
        object is in a sane state, and invoke a side effect.
        N)r   r   appendidr   side_effect	Exceptionr   )r   er   r   r   __del__E   s    zNonGCSimpleBase.__del__c             C   s   dS )z6
        A side effect called on destruction.
        Nr   )r   r   r   r   r    R   s    zNonGCSimpleBase.side_effectN)r
   r   r   __doc__r   r   r   r   r   	__slots__classmethodr   
contextlibcontextmanagerr   r   r#   r    r   r   r   r   r      s   	r   c               @   s   e Zd Zdd Zdd ZdS )
SimpleBasec             C   s   t | | _d S )N)r   Zid_)r   r   r   r   __init__Z   s    zSimpleBase.__init__c             C   s   d S )Nr   )r   r   r   r   r   ]   s    zSimpleBase.check_sanityN)r
   r   r   r*   r   r   r   r   r   r)   X   s   r)   c               @   s   e Zd ZdZdS )NonGCr   N)r
   r   r   r%   r   r   r   r   r+   a   s   r+   c               @   s   e Zd ZdZdd ZdS )NonGCResurrectorr   c             C   s   | j |  dS )zF
        Resurrect self by storing self in a class-wide list.
        N)r   r   )r   r   r   r   r    g   s    zNonGCResurrector.side_effectN)r
   r   r   r%   r    r   r   r   r   r,   d   s   r,   c               @   s   e Zd ZdS )SimpleN)r
   r   r   r   r   r   r   r-   m   s   r-   c               @   s   e Zd ZdS )SimpleResurrectorN)r
   r   r   r   r   r   r   r.   p   s   r.   c               @   sD   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S )TestBasec             C   s"   t jd d  | _g t jd d < d S )N)r   r   old_garbage)r   r   r   r   setUpv   s    zTestBase.setUpc             C   s&   z|  tjg  W d | `t  X d S )N)assertEqualr   r   r0   r   )r   r   r   r   tearDownz   s    zTestBase.tearDownc             C   s   |  ttjt| d S )N)r2   sortedr)   r   )r   idsr   r   r   assert_del_calls   s    zTestBase.assert_del_callsc             C   s   |  ttjt| d S )N)r2   r4   r)   r   )r   r5   r   r   r   assert_tp_del_calls   s    zTestBase.assert_tp_del_callsc             C   s$   |  tdd tjD t| d S )Nc             s   s   | ]}t |V  qd S )N)r   ).0xr   r   r   	<genexpr>   s    z,TestBase.assert_survivors.<locals>.<genexpr>)r2   r4   r)   r   )r   r5   r   r   r   assert_survivors   s    zTestBase.assert_survivorsc             C   s$   |  tdd tjD t| d S )Nc             s   s   | ]}t |V  qd S )N)r   )r8   r9   r   r   r   r:      s    z*TestBase.assert_garbage.<locals>.<genexpr>)r2   r4   r   r   )r   r5   r   r   r   assert_garbage   s    zTestBase.assert_garbagec             C   s   t j  d S )N)r)   r   r   )r   r   r   r   clear_survivors   s    zTestBase.clear_survivorsN)
r
   r   r   r1   r3   r6   r7   r;   r<   r=   r   r   r   r   r/   t   s   r/   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )SimpleFinalizationTestz.
    Test finalization without refcycles.
    c          	   C   sz   t  h t }t|g}t|}~t  | | | 	g  | 
| d  t  | | | 	g  W d Q R X d S )N)r)   r   r-   r   weakrefrefr   r   r6   r;   assertIs)r   sr5   wrr   r   r   test_simple   s    





z"SimpleFinalizationTest.test_simplec          	   C   s   t  p t }t|g}t|}~t  | | | 	| | 
| d  |   t  | | | 	g  W d Q R X | | d  d S )N)r)   r   r.   r   r?   r@   r   r   r6   r;   assertIsNotr=   rA   )r   rB   r5   rC   r   r   r   test_simple_resurrect   s    





z,SimpleFinalizationTest.test_simple_resurrectc          	   C   sr   t  ` t }| t| t|g}~t  | | | 	g  t  | | | 	g  W d Q R X d S )N)
r)   r   r+   assertFalser   
is_trackedr   r   r6   r;   )r   rB   r5   r   r   r   test_non_gc   s    




z"SimpleFinalizationTest.test_non_gcc          	   C   s~   t  l t }| t| t|g}~t  | | | 	| | 
  t  | |d  | 	| W d Q R X d S )N   )r)   r   r,   rG   r   rH   r   r   r6   r;   r=   )r   rB   r5   r   r   r   test_non_gc_resurrect   s    



z,SimpleFinalizationTest.test_non_gc_resurrectN)r
   r   r   r$   rD   rF   rI   rK   r   r   r   r   r>      s
   r>   c                   s(   e Zd Z fddZ fddZ  ZS )SelfCycleBasec                s   t    | | _d S )N)superr*   r@   )r   )	__class__r   r   r*      s    
zSelfCycleBase.__init__c                s   t    d S )N)rM   r   )r   )rN   r   r   r      s    
zSelfCycleBase.check_sanity)r
   r   r   r*   r   __classcell__r   r   )rN   r   rL      s   rL   c               @   s   e Zd ZdS )SimpleSelfCycleN)r
   r   r   r   r   r   r   rP      s   rP   c               @   s   e Zd ZdS )SelfCycleResurrectorN)r
   r   r   r   r   r   r   rQ      s   rQ   c               @   s   e Zd Zdd ZdS )SuicidalSelfCyclec             C   s
   d| _ dS )z7
        Explicitly break the reference cycle.
        N)r@   )r   r   r   r   r       s    zSuicidalSelfCycle.side_effectN)r
   r   r   r    r   r   r   r   rR      s   rR   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	SelfCycleFinalizationTestzX
    Test finalization of an object having a single cyclic reference to
    itself.
    c          	   C   sz   t  h t }t|g}t|}~t  | | | 	g  | 
| d  t  | | | 	g  W d Q R X d S )N)r)   r   rP   r   r?   r@   r   r   r6   r;   rA   )r   rB   r5   rC   r   r   r   rD      s    





z%SelfCycleFinalizationTest.test_simplec          	   C   s   t  ~ t }t|g}t|}~t  | | | 	| | 
| d  |   t  | | | 	g  | 
| d  W d Q R X d S )N)r)   r   rQ   r   r?   r@   r   r   r6   r;   rA   r=   )r   rB   r5   rC   r   r   r   rF      s    






z/SelfCycleFinalizationTest.test_simple_resurrectc          	   C   s   t  v t }t|g}t|}~t  | | | 	g  | 
| d  t  | | | 	g  | 
| d  W d Q R X d S )N)r)   r   rR   r   r?   r@   r   r   r6   r;   rA   )r   rB   r5   rC   r   r   r   test_simple_suicide  s    






z-SelfCycleFinalizationTest.test_simple_suicideN)r
   r   r   r$   rD   rF   rT   r   r   r   r   rS      s   rS   c                   s$   e Zd Zdd Z fddZ  ZS )ChainedBasec             C   s   d| _ || _| |_d S )NF)suicidedleftright)r   rW   r   r   r   chain&  s    zChainedBase.chainc                s2   t    | jrn| j}|jr n | j}|jr.n d S )N)rM   r   rV   rW   rX   )r   rW   rX   )rN   r   r   r   +  s    
zChainedBase.check_sanity)r
   r   r   rY   r   rO   r   r   )rN   r   rU   $  s   rU   c               @   s   e Zd ZdS )SimpleChainedN)r
   r   r   r   r   r   r   rZ   <  s   rZ   c               @   s   e Zd ZdS )ChainedResurrectorN)r
   r   r   r   r   r   r   r[   ?  s   r[   c               @   s   e Zd Zdd ZdS )SuicidalChainedc             C   s   d| _ d| _d| _dS )z7
        Explicitly break the reference cycle.
        TN)rV   rW   rX   )r   r   r   r   r    D  s    zSuicidalChained.side_effectN)r
   r   r   r    r   r   r   r   r\   B  s   r\   c               @   sh   e Zd 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d Zdd ZdS )CycleChainFinalizationTestz
    Test finalization of a cyclic chain.  These tests are similar in
    spirit to the self-cycle tests above, but the collectable object
    graph isn't trivial anymore.
    c             C   s>   dd |D }x*t t|D ]}|| ||d   qW |S )Nc             S   s   g | ]
}| qS r   r   )r8   r   r   r   r   
<listcomp>U  s    z:CycleChainFinalizationTest.build_chain.<locals>.<listcomp>   )rangelenrY   )r   classesnodesir   r   r   build_chainT  s    z&CycleChainFinalizationTest.build_chainc          	   C   s   t |}t x | |}dd |D }dd |D }~t  | | | g  | dd |D d g|  t  | | W d Q R X d S )Nc             S   s   g | ]}t |qS r   )r   )r8   rB   r   r   r   r^   ^  s    zKCycleChainFinalizationTest.check_non_resurrecting_chain.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )r?   r@   )r8   rB   r   r   r   r^   _  s    c             S   s   g | ]
}| qS r   r   )r8   rC   r   r   r   r^   d  s    )	ra   r)   r   re   r   r   r6   r;   r2   )r   rb   Nrc   r5   wrsr   r   r   check_non_resurrecting_chainZ  s    



z7CycleChainFinalizationTest.check_non_resurrecting_chainc          	   C   s   t |}t  | |}t |}dd |D }dd |D }dd |D }~t  | | | | | dd |D d g|  | 	  t  | | | g  W d Q R X d S )Nc             S   s   g | ]}t |qS r   )r   )r8   rB   r   r   r   r^   m  s    zGCycleChainFinalizationTest.check_resurrecting_chain.<locals>.<listcomp>c             S   s   g | ]}t |trt|qS r   )
isinstancer.   r   )r8   rB   r   r   r   r^   n  s    c             S   s   g | ]}t |qS r   )r?   r@   )r8   rB   r   r   r   r^   o  s    c             S   s   g | ]
}| qS r   r   )r8   rC   r   r   r   r^   u  s    )
ra   r)   r   re   r   r   r6   r;   r2   r=   )r   rb   rf   rc   r5   Zsurvivor_idsrg   r   r   r   check_resurrecting_chainh  s     




z3CycleChainFinalizationTest.check_resurrecting_chainc             C   s   |  tgd  d S )N   )rh   rZ   )r   r   r   r   test_homogenous{  s    z*CycleChainFinalizationTest.test_homogenousc             C   s   |  tgd  d S )Nrk   )rj   r[   )r   r   r   r   test_homogenous_resurrect~  s    z4CycleChainFinalizationTest.test_homogenous_resurrectc             C   s   |  tgd  d S )Nrk   )rh   r\   )r   r   r   r   test_homogenous_suicidal  s    z3CycleChainFinalizationTest.test_homogenous_suicidalc             C   s   |  ttgd  d S )NrJ   )rh   r\   rZ   )r   r   r   r   test_heterogenous_suicidal_one  s    z9CycleChainFinalizationTest.test_heterogenous_suicidal_onec             C   s   |  tgd tgd   d S )NrJ   )rh   r\   rZ   )r   r   r   r   test_heterogenous_suicidal_two  s    z9CycleChainFinalizationTest.test_heterogenous_suicidal_twoc             C   s   |  ttgd  d S )NrJ   )rj   r[   rZ   )r   r   r   r   test_heterogenous_resurrect_one  s    z:CycleChainFinalizationTest.test_heterogenous_resurrect_onec             C   s   |  tttgd  d S )NrJ   )rj   r[   rZ   r\   )r   r   r   r   test_heterogenous_resurrect_two  s    z:CycleChainFinalizationTest.test_heterogenous_resurrect_twoc             C   s(   |  tgd tgd  tgd   d S )NrJ   )rj   r[   rZ   r\   )r   r   r   r   !test_heterogenous_resurrect_three  s    z<CycleChainFinalizationTest.test_heterogenous_resurrect_threeN)r
   r   r   r$   re   rh   rj   rl   rm   rn   ro   rp   rq   rr   rs   r   r   r   r   r]   M  s   r]   c               @   s   e Zd Zdd Zdd ZdS )
LegacyBasec          
   C   sV   y"| j s | jt|  |   W n. tk
rP } z| j| W d d }~X Y nX d S )N)r   r   r   r   r   r!   r   )r   r"   r   r   r   r#     s    zLegacyBase.__del__c          
   C   s^   y*| j s(| jt|  |   |   W n. tk
rX } z| j| W dd}~X Y nX dS )zJ
        Legacy (pre-PEP 442) finalizer, mapped to a tp_del slot.
        N)r   r   r   r   r   r    r!   r   )r   r"   r   r   r   
__tp_del__  s    zLegacyBase.__tp_del__N)r
   r   r   r#   ru   r   r   r   r   rt     s   
rt   c               @   s   e Zd ZdS )LegacyN)r
   r   r   r   r   r   r   rv     s   rv   c               @   s   e Zd Zdd ZdS )LegacyResurrectorc             C   s   | j |  dS )zF
        Resurrect self by storing self in a class-wide list.
        N)r   r   )r   r   r   r   r      s    zLegacyResurrector.side_effectN)r
   r   r   r    r   r   r   r   rw     s   rw   c               @   s   e Zd ZdS )LegacySelfCycleN)r
   r   r   r   r   r   r   rx     s   rx   c                   s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
LegacyFinalizationTestz5
    Test finalization of objects with a tp_del.
    c                s    t j  t   t   d S )N)r   r   r   r   rM   r3   )r   )rN   r   r   r3     s    
zLegacyFinalizationTest.tearDownc          	   C   s   t  r t }t|g}t|}~t  | | | 	| | 
g  | | d  t  | | | 	| W d Q R X d S )N)r)   r   rv   r   r?   r@   r   r   r6   r7   r;   rA   )r   rB   r5   rC   r   r   r   test_legacy  s    






z"LegacyFinalizationTest.test_legacyc          	   C   s   t   t }t|g}t|}~t  | | | 	| | 
| | | d  |   t  | | | 	|d  | 
| W d Q R X | | d  d S )NrJ   )r)   r   rw   r   r?   r@   r   r   r6   r7   r;   rA   r=   )r   rB   r5   rC   r   r   r   test_legacy_resurrect  s     






z,LegacyFinalizationTest.test_legacy_resurrectc          	   C   s   t  l t }t|g}t|}~t  | g  | 	g  | 
g  | | | | d  d tjd _W d Q R X | g  | | d  d S )Nr   )r)   r   rx   r   r?   r@   r   r   r6   r7   r;   r<   rE   r   rA   )r   rB   r5   rC   r   r   r   test_legacy_self_cycle  s    







z-LegacyFinalizationTest.test_legacy_self_cycle)	r
   r   r   r$   r3   rz   r{   r|   rO   r   r   )rN   r   ry     s
   ry   __main__)%r$   r'   r   Zunittestr?   Z	_testcapir   ImportErrorr   r   r   r)   r+   r,   r-   r.   r/   ZTestCaser>   rL   rP   rQ   rR   rS   rU   rZ   r[   r\   r]   rt   rv   rw   rx   Zcpython_onlyry   r
   mainr   r   r   r   <module>   sL   B		?
	:M
A
