
    R3j-5                     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                  j                  d      Z	e j                  j                  d      xs e	Z
e j                  j                  d      Ze
xs eZe j                  j                  d      Zexs e j                  j                  d      Ze j                  j                  d      Ze j                  j                  d	      Zd
 Zd Zd Zd Z G d de      Z eed      r G d de      Z e       e_        eZnd Z G d de      Z G d de      Zd Zy)    N)wrapsGITHUB_ACTIONSTRAVISAPPVEYORGREENLET_MANYLINUXGREENLET_SKIP_LEAKCHECKS GREENLET_SKIP_FAILING_LEAKCHECKS GREENLET_ONLY_FAILING_LEAKCHECKSc                     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funcs    E/DATA/.local/lib/python3.12/site-packages/greenlet/tests/leakcheck.pyignores_leakcheckr   J   s     !DK    c                       fd}|S )a  
    Return a decorator that marks the function to be ignored during
    leakchecks (see `ignores_leakcheck`) when *condition* is true.

    *message* describes why the leakcheck is ignored. When *condition*
    is false, the function is returned unchanged.
    c                 0    rt        |       } | _        | S N)r   ignore_leakcheck_reason)r   	conditionmessages    r   	decoratorz'ignores_leakcheck_if.<locals>.decoratora   s    $T*D+2D(r    )r   r   r   s   `` r   ignores_leakcheck_ifr   Y   s    
 r   c                 V    d| _         t        r t        j                  d      |       } | S )z2
    Mark that the function is known to leak.
    TzSkipping known failures)fails_leakcheckSKIP_FAILING_LEAKCHECKSunittestskipr   s    r   r   r   h   s*      D7x}}67=Kr   c                 H    t         j                  dd dk  rt        |       S | S )z`
    Mark the function as known to leak (fails refcount leakchecks) on Python 3.14 or less.
    N   )      )sysversion_infor   r   s    r    fails_leakcheck_on_py314_or_lessr&   q   s)     w&t$$Kr   c                       e Zd Zy)LeakCheckErrorN)__name__
__module____qualname__r   r   r   r(   r(   y   s    r   r(   
getobjectsc                       e Zd Zd Zd Zy)_MockGCc                 ,    t        j                  d      S )Nr   )r$   r,   selfs    r   get_objectsz_MockGC.get_objects   s    >>!$$r   c                 "    t        t        |      S r   )getattrgc)r1   names     r   __getattr__z_MockGC.__getattr__   s    2t$$r   N)r)   r*   r+   r2   r7   r   r   r   r.   r.      s    	%	%r   r.   c                     | 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   s    r   fails_strict_leakcheckr9      s	     r   c                       e Zd Zd Zd Zy)!ignores_types_in_strict_leakcheckc                     || _         y r   )types)r1   r=   s     r   __init__z*ignores_types_in_strict_leakcheck.__init__   s	    
r   c                 (    | j                   |_        |S r   )r=   leakcheck_ignore_types)r1   r   s     r   __call__z*ignores_types_in_strict_leakcheck.__call__   s    &*jj#r   N)r)   r*   r+   r>   rA   r   r   r   r;   r;      s    r   r;   c                   D    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)_RefCountCheckerr   )uop_executorc                 X    || _         || _        g | _        i | _        d| _        d| _        y )Nr   F)testcasefunctiondeltas
peak_statsignored_typesneeds_setUp)r1   rF   rG   s      r   r>   z_RefCountChecker.__init__   s0       !r   c                    || u ryt        |      }|t        | j                        k(  r'	 | j                  j                  |      }|t
        ur|ry| j                  j                         D ]  }||u s y || j                  v s&|| j                  v s|j                  | j                  v ryy# t        $ r! | j                  j	                  |      dk(  }Y w xY w)NFr   T)type_include_object_p__eq__AttributeError__cmp__NotImplemented__dict__valuesrJ   IGNORED_TYPESr)   IGNORED_TYPE_NAMES)r1   objkindexact_method_equalsxs        r   rN   z"_RefCountChecker._include_object_p   s    
 $;Cy 4..//O&*&<&<&C&CC&H# #.8=P %%'Aax ( D&&&t)))}} 7 77 / " O '+&<&<&D&DS&IQ&N#	Os   B+ +'CCc                 Z    t        j                  d | j                  | j                        S )N)limitrI   filter)objgraphgrowthrI   rN   r0   s    r   _growthz_RefCountChecker._growth   s$    Tdoo&*&<&<> 	>r   c                     |syg }t        d |D              }|D ]  \  }}}|j                  d||||fz           dj                  |      }|S )Nz<Unable to calculate growth>c              3   :   K   | ]  \  }}}t        |        y wr   )len).0r6   _s      r   	<genexpr>z0_RefCountChecker._report_diff.<locals>.<genexpr>   s     7*$1CIs   z%-*s%9d %+9d
)maxappendjoin)r1   r_   lineswidthr6   countdeltadiffs           r   _report_diffz_RefCountChecker._report_diff   s]    1777"(D%LL5$u*EEF #) yyr   c                    t        j                         }t        j                          | j                  r+| j                  j                          d| j                  _        	  | j                  | j                  g|i | | j                  j                          | j                  j                          d| j                  _        d| _        |rt        j                          y y # | j                  j                          | j                  j                          d| j                  _        d| _        |rt        j                          w w xY w)NFT)r5   	isenableddisablerK   rF   setUpskipTearDownrG   tearDown
doCleanupsenable)r1   argskwargs
gc_enableds       r   	_run_testz_RefCountChecker._run_test   s    \\^



MM!).DMM&	DMM$--9$9&9MM""$MM$$&)-DMM&#D		 	 MM""$MM$$&)-DMM&#D		 s   ! C% %A%E
c                     dt         j                  v r!t         j                  d   j                          dt         j                  v r!t         j                  d   j                          | j                         S )Nurlparsezurllib.parse)r$   modulesclear_cacher`   r0   s    r   _growth_afterz_RefCountChecker._growth_after  sR     $KK
#//1S[[(KK'335||~r   c                 t   | j                   }|syt        j                  rt        dt        j                        |dd  ddgk(  rt	        |      dv ry|dd  g dk(  ryt	        |      d	k\  rt        |d
d        dk(  ryt	        |      dk\  r@|d   dkD  r8|d   |d   k(  r-|d   |d   k(  r"| j                  |      }t        d|d|      t        |dd        dk  s(t        |d
d        dk  s|d
d  j                  d      dk\  rd}nd}t	        |      |k\  r t        d|d| j                  |            y)NTz Generated uncollectable garbage r   )r!   r"   F)r   r   r      r"   zrefcount increased by rg   r!         )rH   r5   garbager(   rc   sumrp   rm   )r1   r_   rH   ro   r\   s        r   _check_deltasz_RefCountChecker._check_deltas  sZ   
 :: !UVV "#;1a& S[F%:"#;)#v;!F23K 0A 5v;!r
Q6":3KPVWYPZ^deg^hPh$$V,D 64!PQQ vbc{q Crs$4$9VBC[=N=Nq=QUV=VEEv;% $*$($5$5f$="? @ @
 r   c                 4   t        d      D ]  }t        j                           t        | j                  dd      }|rd| j
                  _        t        | j                  dd      | _        | j                         }	 | j                  |      r_| j                  ||       | j                         }| j                  j                  t        d |D                     | j                  |      r_|rt        d| j                  d	      y # t        $ r |s Y y w xY w)
Nr"   r   FTr@   r   c              3   &   K   | ]	  }|d      yw)r!   Nr   )rd   stats     r   rf   z,_RefCountChecker.__call__.<locals>.<genexpr>Q  s     'CFDQFs   z	Expected z to leak but it did not.)ranger5   collectr4   rG   rF   expect_greenlet_leakrJ   r`   r   r|   r   rH   ri   r   r(   )r1   ry   rz   re   expect_failurer_   s         r   rA   z_RefCountChecker.__call__>  s    qAJJL  !0A5I15DMM.$T]]4LbQ 	_$$V,tV,++-""3'CF'C#DE $$V, $dmm%]^^ 	  	! "	s   <A/D DDN)r)   r*   r+   rU   rV   r>   rN   r`   rp   r|   r   r   rA   r   r   r   rC   rC      s<    
 M	!(T>
"/b_r   rC   c                      t         dd      st        rBt         dd       }|r1t        s+t        d j                  d|t        j
                          S t                fd       }|S )Nr   Fr   zIgnoring leakchecks for z: )filec                     t        | dd      rt        j                  d      t        r"t        dd      st        j                  d       t	        |       ||      S )Nr   Fz$This class ignored during leakchecksr   z(Only running tests that fail leakchecks.)r4   r   SkipTestONLY_FAILING_LEAKCHECKSrC   )r1   ry   rz   methods      r   wrapperzwrap_refcount.<locals>.wrapperc  sZ    4+U3##$JKK"76;Le+T##$NOO-f-dF;;r   )r4   SKIP_LEAKCHECKSprintr)   r$   stderrr   )r   reasonr   s   `  r   wrap_refcountr   Y  se    v)51_!:DA/4:OOVLZZ 
6]< < Nr   )osr$   r5   	functoolsr   r   r^   environgetRUNNING_ON_GITHUB_ACTIONSRUNNING_ON_TRAVISRUNNING_ON_APPVEYORRUNNING_ON_CIRUNNING_ON_MANYLINUXr   r   r   r   r   r   r&   AssertionErrorr(   hasattrobjectr.   r9   r;   rC   r   r   r   r   <module>r      s-  0 
 
 	   B JJNN+;< JJNN8,I0I jjnnZ0 !8%8zz~~&:; &T"**..9S*T**..)KL **..)KL 	^ 	 3%& %
 )HK, ~_v ~_@r   