U
    d.                     @   s   d dl mZ d dlZd dlZd dlZd dlmZ d dlZd dlZej	
dZej	
dpZeZej	
dZepneZej	
dZepej	
dZej	
d	Zej	
d
Zdd Zdd ZG dd deZeedrG dd deZe e_eZndd ZG dd deZG dd deZdd ZdS )    )print_functionN)wrapsZGITHUB_ACTIONSZTRAVISZAPPVEYORZGREENLET_MANYLINUXZGREENLET_SKIP_LEAKCHECKSZ GREENLET_SKIP_FAILING_LEAKCHECKSZ GREENLET_ONLY_FAILING_LEAKCHECKSc                 C   s
   d| _ | S )a  
    Ignore the given object during leakchecks.

    Can be applied to a method, in which case the method will run, but
    will not be subject to leak checks.

    If applied to a class, the entire class will be skipped during leakchecks. This
    is intended to be used for classes that are very slow and cause problems such as
    test timeouts; typically it will be used for classes that are subclasses of a base
    class and specify variants of behaviour (such as pool sizes).
    T)ignore_leakcheckfunc r   </tmp/pip-unpacked-wheel-b5mayakg/greenlet/tests/leakcheck.pyignores_leakcheckL   s    r	   c                 C   s   d| _ trtd| } | S )z2
    Mark that the function is known to leak.
    TzSkipping known failures)fails_leakcheckSKIP_FAILING_LEAKCHECKSunittestskipr   r   r   r   r
   [   s    r
   c                   @   s   e Zd ZdS )LeakCheckErrorN)__name__
__module____qualname__r   r   r   r   r   d   s   r   
getobjectsc                   @   s   e Zd Zdd Zdd ZdS )_MockGCc                 C   s
   t dS )Nr   )sysr   selfr   r   r   get_objectsl   s    z_MockGC.get_objectsc                 C   s
   t t|S N)getattrgc)r   namer   r   r   __getattr__n   s    z_MockGC.__getattr__N)r   r   r   r   r   r   r   r   r   r   k   s   r   c                 C   s   | S )a  
        Decorator for a function that is known to fail when running
        strict (``sys.getobjects()``) leakchecks.

        This type of leakcheck finds all objects, even those, such as
        strings, which are not tracked by the garbage collector.
        r   r   r   r   r   fails_strict_leakchecks   s    r   c                   @   s   e Zd Zdd Zdd ZdS )!ignores_types_in_strict_leakcheckc                 C   s
   || _ d S r   )types)r   r   r   r   r   __init__~   s    z*ignores_types_in_strict_leakcheck.__init__c                 C   s   | j |_|S r   )r   leakcheck_ignore_types)r   r   r   r   r   __call__   s    z*ignores_types_in_strict_leakcheck.__call__N)r   r   r   r    r"   r   r   r   r   r   }   s   r   c                   @   sP   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S )_RefCountCheckerr   c                 C   s(   || _ || _g | _i | _d| _d| _d S )Nr   F)testcasefunctiondeltas
peak_statsignored_typesneeds_setUp)r   r$   r%   r   r   r   r       s    z_RefCountChecker.__init__c                 C   s   || krdS t |}|t | jkrhz| j|}W n$ tk
rV   | j|dk}Y nX |tk	rh|rhdS | j D ]}||krr dS qr|| jks|| j	krdS dS )NFr   T)
type_include_object_p__eq__AttributeErrorZ__cmp__NotImplemented__dict__valuesr(   IGNORED_TYPES)r   objkindZexact_method_equalsxr   r   r   r+      s     z"_RefCountChecker._include_object_pc                 C   s   t jd | j| jdS )N)limitr'   filter)objgraphgrowthr'   r+   r   r   r   r   _growth   s    
z_RefCountChecker._growthc                 C   sR   |sdS g }t dd |D }|D ] \}}}|d||||f  q"d|}|S )Nz<Unable to calculate growth>c                 s   s   | ]\}}}t |V  qd S r   )len).0r   _r   r   r   	<genexpr>   s     z0_RefCountChecker._report_diff.<locals>.<genexpr>z%-*s%9d %+9d
)maxappendjoin)r   r8   lineswidthr   countdeltadiffr   r   r   _report_diff   s    
z_RefCountChecker._report_diffc                 C   sv   t  }t   | jr(| j  d| j_z| j
| jf|| W 5 | j  | j  d| j_d| _|rpt 	  X d S )NFT)r   	isenableddisabler)   r$   ZsetUpZskipTearDownZtearDownZ
doCleanupsenabler%   )r   argskwargsZ
gc_enabledr   r   r   	_run_test   s    


z_RefCountChecker._run_testc                 C   s8   dt jkrt jd   dt jkr0t jd   |  S )Nurlparsezurllib.parse)r   modulesclear_cacher9   r   r   r   r   _growth_after   s
    

z_RefCountChecker._growth_afterc                 C   sN  | j }|sdS tjr$tdtjf |dd  ddgkrHt|dkrHdS |dd  dddgkrbdS t|dkrt|d	d  dkrdS t|d
kr|d dkr|d |d kr|d |d kr| |}td||f t|dd  dkst|d	d  dks|d	d  ddkr"d}nd}t||krJtd|| |f dS )NTz"Generated uncollectable garbage %rr   )      F   rT   zrefcount increased by %r
%srS         )r&   r   garbager   r:   sumrG   rD   )r   r8   r&   rF   r5   r   r   r   _check_deltas   s0      8
Dz_RefCountChecker._check_deltasc                 C   s   t dD ]}t  qt| jdd}|r0d| j_t| jdd| _|  }z>| 	|r| 
|| |  }| jtdd |D  qJW n tk
r   |s Y nX |rtd	| jf d S )
NrT   r
   FTr!   r   c                 s   s   | ]}|d  V  qdS )rS   Nr   )r;   statr   r   r   r=   *  s     z,_RefCountChecker.__call__.<locals>.<genexpr>z#Expected %s to leak but it did not.)ranger   Zcollectr   r%   r$   Zexpect_greenlet_leakr(   r9   r]   rM   rQ   r&   r@   r\   r   )r   rK   rL   r<   Zexpect_failurer8   r   r   r   r"     s"    

 z_RefCountChecker.__call__N)r   r   r   r1   r    r+   r9   rG   rM   rQ   r]   r"   r   r   r   r   r#      s   %	1r#   c                    s,   t  ddstr S t  fdd}|S )Nr   Fc                    s@   t | ddrtdtr0t  dds0tdt|  ||S )Nr   Fz$This class ignored during leakchecksr
   z(Only running tests that fail leakchecks.)r   r   ZSkipTestONLY_FAILING_LEAKCHECKSr#   )r   rK   rL   methodr   r   wrapper6  s
    

zwrap_refcount.<locals>.wrapper)r   SKIP_LEAKCHECKSr   )rb   rc   r   ra   r   wrap_refcount2  s
    re   )
__future__r   osr   r   	functoolsr   r   r7   environgetZRUNNING_ON_GITHUB_ACTIONSZRUNNING_ON_TRAVISZRUNNING_ON_APPVEYORZRUNNING_ON_CIZRUNNING_ON_MANYLINUXrd   r   r`   r	   r
   AssertionErrorr   hasattrobjectr   r   r   r#   re   r   r   r   r   <module>   s4   !	

 /