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   id_)r   r   r   r   __init__Z   s    zSimpleBase.__init__c             C   s   | j t| kstd S )N)r*   r   AssertionError)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   r0   p   s   r0   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   r2   r   )r   r   r   r   tearDownz   s    zTestBase.tearDownc             C   s   |  ttjt| d S )N)r4   sortedr)   r   )r   idsr   r   r   assert_del_calls   s    zTestBase.assert_del_callsc             C   s   |  ttjt| d S )N)r4   r6   r)   r   )r   r7   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>)r4   r6   r)   r   )r   r7   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   )r:   r;   r   r   r   r<      s    z*TestBase.assert_garbage.<locals>.<genexpr>)r4   r6   r   r   )r   r7   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   r3   r5   r8   r9   r=   r>   r?   r   r   r   r   r1   t   s   r1   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   r8   r=   assertIs)r   sr7   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   r0   r   rA   rB   r   r   r8   r=   assertIsNotr?   rC   )r   rD   r7   rE   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   r8   r=   )r   rD   r7   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.   rI   r   rJ   r   r   r8   r=   r?   )r   rD   r7   r   r   r   test_non_gc_resurrect   s    



z,SimpleFinalizationTest.test_non_gc_resurrectN)r
   r   r   r$   rF   rH   rK   rM   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+   rB   )r   )	__class__r   r   r+      s    
zSelfCycleBase.__init__c                s   t    | j| kstd S )N)rO   r   rB   r,   )r   )rP   r   r   r      s    
zSelfCycleBase.check_sanity)r
   r   r   r+   r   __classcell__r   r   )rP   r   rN      s   rN   c               @   s   e Zd ZdS )SimpleSelfCycleN)r
   r   r   r   r   r   r   rR      s   rR   c               @   s   e Zd ZdS )SelfCycleResurrectorN)r
   r   r   r   r   r   r   rS      s   rS   c               @   s   e Zd Zdd ZdS )SuicidalSelfCyclec             C   s
   d| _ dS )z7
        Explicitly break the reference cycle.
        N)rB   )r   r   r   r   r       s    zSuicidalSelfCycle.side_effectN)r
   r   r   r    r   r   r   r   rT      s   rT   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   rR   r   rA   rB   r   r   r8   r=   rC   )r   rD   r7   rE   r   r   r   rF      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   rS   r   rA   rB   r   r   r8   r=   rC   r?   )r   rD   r7   rE   r   r   r   rH      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   rT   r   rA   rB   r   r   r8   r=   rC   )r   rD   r7   rE   r   r   r   test_simple_suicide  s    






z-SelfCycleFinalizationTest.test_simple_suicideN)r
   r   r   r$   rF   rH   rV   r   r   r   r   rU      s   rU   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   rY   r   r   r   chain&  s    zChainedBase.chainc                s   t    | jr.| jd kst| jd kstnT| j}|jrJ|jd ksXtn|j| ksXt| j}|jrt|jd kstn|j| kstd S )N)rO   r   rX   rY   r,   rZ   )r   rY   rZ   )rP   r   r   r   +  s    
zChainedBase.check_sanity)r
   r   r   r[   r   rQ   r   r   )rP   r   rW   $  s   rW   c               @   s   e Zd ZdS )SimpleChainedN)r
   r   r   r   r   r   r   r\   <  s   r\   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)rX   rY   rZ   )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   )r:   r   r   r   r   
<listcomp>U  s    z:CycleChainFinalizationTest.build_chain.<locals>.<listcomp>   )rangelenr[   )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   )r:   rD   r   r   r   r`   ^  s    zKCycleChainFinalizationTest.check_non_resurrecting_chain.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )rA   rB   )r:   rD   r   r   r   r`   _  s    c             S   s   g | ]
}| qS r   r   )r:   rE   r   r   r   r`   d  s    )	rc   r)   r   rg   r   r   r8   r=   r4   )r   rd   Nre   r7   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   )r:   rD   r   r   r   r`   m  s    zGCycleChainFinalizationTest.check_resurrecting_chain.<locals>.<listcomp>c             S   s   g | ]}t |trt|qS r   )
isinstancer0   r   )r:   rD   r   r   r   r`   n  s    c             S   s   g | ]}t |qS r   )rA   rB   )r:   rD   r   r   r   r`   o  s    c             S   s   g | ]
}| qS r   r   )r:   rE   r   r   r   r`   u  s    )
rc   r)   r   rg   r   r   r8   r=   r4   r?   )r   rd   rh   re   r7   Zsurvivor_idsri   r   r   r   check_resurrecting_chainh  s     




z3CycleChainFinalizationTest.check_resurrecting_chainc             C   s   |  tgd  d S )N   )rj   r\   )r   r   r   r   test_homogenous{  s    z*CycleChainFinalizationTest.test_homogenousc             C   s   |  tgd  d S )Nrm   )rl   r]   )r   r   r   r   test_homogenous_resurrect~  s    z4CycleChainFinalizationTest.test_homogenous_resurrectc             C   s   |  tgd  d S )Nrm   )rj   r^   )r   r   r   r   test_homogenous_suicidal  s    z3CycleChainFinalizationTest.test_homogenous_suicidalc             C   s   |  ttgd  d S )NrL   )rj   r^   r\   )r   r   r   r   test_heterogenous_suicidal_one  s    z9CycleChainFinalizationTest.test_heterogenous_suicidal_onec             C   s   |  tgd tgd   d S )NrL   )rj   r^   r\   )r   r   r   r   test_heterogenous_suicidal_two  s    z9CycleChainFinalizationTest.test_heterogenous_suicidal_twoc             C   s   |  ttgd  d S )NrL   )rl   r]   r\   )r   r   r   r   test_heterogenous_resurrect_one  s    z:CycleChainFinalizationTest.test_heterogenous_resurrect_onec             C   s   |  tttgd  d S )NrL   )rl   r]   r\   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 )NrL   )rl   r]   r\   r^   )r   r   r   r   !test_heterogenous_resurrect_three  s    z<CycleChainFinalizationTest.test_heterogenous_resurrect_threeN)r
   r   r   r$   rg   rj   rl   rn   ro   rp   rq   rr   rs   rt   ru   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#   rw   r   r   r   r   rv     s   
rv   c               @   s   e Zd ZdS )LegacyN)r
   r   r   r   r   r   r   rx     s   rx   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   ry     s   ry   c               @   s   e Zd ZdS )LegacySelfCycleN)r
   r   r   r   r   r   r   rz     s   rz   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   rO   r5   )r   )rP   r   r   r5     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   rx   r   rA   rB   r   r   r8   r9   r=   rC   )r   rD   r7   rE   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 )NrL   )r)   r   ry   r   rA   rB   r   r   r8   r9   r=   rC   r?   )r   rD   r7   rE   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   rz   r   rA   rB   r   r   r8   r9   r=   r>   rG   r   rC   )r   rD   r7   rE   r   r   r   test_legacy_self_cycle  s    







z-LegacyFinalizationTest.test_legacy_self_cycle)	r
   r   r   r$   r5   r|   r}   r~   rQ   r   r   )rP   r   r{     s
   r{   __main__)%r$   r'   r   ZunittestrA   Z	_testcapir   ImportErrorr   r   r   r)   r-   r.   r/   r0   r1   ZTestCaser@   rN   rR   rS   rT   rU   rW   r\   r]   r^   r_   rv   rx   ry   rz   Zcpython_onlyr{   r
   mainr   r   r   r   <module>   sL   B		?
	:M
A
