o
    M“©i©  ã                   @   s¤   d Z ddlZddlZddlZddlZddl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 ddlmZ dd„ Zejdd„ ƒZeG d	d
„ d
e	jƒƒZdS )ao  Test script to find circular references.

Circular references are not leaks per se, because they will eventually
be GC'd. However, on CPython, they prevent the reference-counting fast
path from being used and instead rely on the slower full GC. This
increases memory footprint and CPU overhead, so we try to eliminate
circular references created by normal operation.
é    N)ÚwebÚgenÚ
httpclient)ÚskipNotCPythonc                    sD   ‡ ‡‡‡‡‡fdd„‰g ‰ g ‰t ƒ ‰t tt| ƒƒ‰t ƒ ‰ˆ| ƒ ˆ S )a  Find circular references in a list of objects.

    The garbage list contains objects that participate in a cycle,
    but also the larger set of objects kept alive by that cycle.
    This function finds subsets of those objects that make up
    the cycle(s).
    c                    s˜   | D ]G}t |ƒ}|ˆvrq|ˆv rq|ˆv r*ˆˆ |¡d … }| |¡ ˆ  |¡ qˆ |¡ ˆ |¡ ˆt |¡ƒ ˆ ¡  ˆ |¡ ˆ |¡ qd S ©N)ÚidÚindexÚappendÚaddÚgcÚget_referentsÚpopÚremove)ÚlevelÚitemÚitem_idÚ	candidate©ÚfoundÚgarbage_idsÚinnerÚstackÚ	stack_idsÚvisited_ids© úP/home/ubuntu/.local/lib/python3.10/site-packages/tornado/test/circlerefs_test.pyr   "   s$   




ïz'find_circular_references.<locals>.inner)ÚsetÚmapr   )Úgarbager   r   r   Úfind_circular_references   s   	r   c               	   c   s:   t  ¡  t  ¡  t  t jt jB ¡ dV  z}t ¡ } tj	}| t_	z	t  ¡  W |t_	n|t_	w t j
dd… }g t j
dd…< t|ƒdkrNW t  d¡ t  ¡  dS t|ƒD ]9}|  d¡ |D ]}|  dt|ƒ› ¡ q[|D ] }t|tjƒrŠ|  d|j› ¡ |  dt|ƒ› ¡ t |¡ qjqR~t|  ¡ ƒ‚t  d¡ t  ¡  w )zERaise AssertionError if the wrapped code creates garbage with cycles.Nr   z!
==========
 Circular 
==========z
    z	
Locals: z
Traceback: )r   ÚdisableÚcollectÚ	set_debugÚDEBUG_STATSÚDEBUG_SAVEALLÚioÚStringIOÚsysÚstderrr   ÚlenÚenabler   ÚwriteÚreprÚ
isinstanceÚtypesÚ	FrameTypeÚf_localsÚ	tracebackÚprint_stackÚAssertionErrorÚgetvalue)ÚfÚ
old_stderrr   Úcircularr   r   r   r   Úassert_no_cycle_garbage@   sB   €

ó

€ü

r8   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 )ÚCircleRefsTestc              	      sä   G ‡ fdd„dt ƒ‰ |  t¡5}tƒ " ˆ dƒ}ˆ dƒ}ˆ dƒ}||_||_||_||_~~W d   ƒ n1 s8w   Y  W d   ƒ n1 sGw   Y  |  dt|j	ƒ¡ |  dt|j	ƒ¡ |  dt|j	ƒ¡ |  
d	t|j	ƒ¡ d S )
Nc                       s    e Zd Z‡ fdd„Zdd„ ZdS )z)CircleRefsTest.test_known_leak.<locals>.Cc                    s   || _ d | _d | _d | _d S r   )ÚnameÚaÚbÚc)Úselfr:   ©ÚCr   r   Ú__init__m   s   
z2CircleRefsTest.test_known_leak.<locals>.C.__init__c                 S   s   d| j › S )Nzname=)r:   ©r>   r   r   r   Ú__repr__s   s   z2CircleRefsTest.test_known_leak.<locals>.C.__repr__N)Ú__name__Ú
__module__Ú__qualname__rA   rC   r   r?   r   r   r@   l   s    r@   r;   r<   r=   ÚCircularz
    name=az
    name=bz
    name=c)ÚobjectÚassertRaisesr3   r8   r<   r=   r;   ÚassertInÚstrÚ	exceptionÚassertNotIn)r>   Úcmr;   r<   r=   r   r?   r   Útest_known_leakj   s$   
ö€ÿzCircleRefsTest.test_known_leakc                 Ã   s˜   t  d|fg¡}tj ¡ \}}tj |¡}| |¡ t 	¡ }t
ƒ  | d|› d¡I d H  W d   ƒ n1 s9w   Y  | ¡  | ¡  | ¡  d S )Nú/zhttp://127.0.0.1:)r   ÚApplicationÚtornadoÚtestingÚbind_unused_portÚ
httpserverÚ
HTTPServerÚ
add_socketr   ÚAsyncHTTPClientr8   ÚfetchÚcloseÚstop)r>   Úhandler_classÚappÚsocketÚportÚserverÚclientr   r   r   Úrun_handlerŒ   s   €ÿÿ
úzCircleRefsTest.run_handlerc                 C   ó&   G dd„ dt jƒ}t |  |¡¡ d S )Nc                   @   ó   e Zd Zdd„ ZdS )z1CircleRefsTest.test_sync_handler.<locals>.Handlerc                 S   s   |   d¡ d S ©Núok
)r+   rB   r   r   r   Úget¤   s   z5CircleRefsTest.test_sync_handler.<locals>.Handler.getN©rD   rE   rF   rg   r   r   r   r   ÚHandler£   ó    ri   ©r   ÚRequestHandlerÚasyncioÚrunrb   ©r>   ri   r   r   r   Útest_sync_handler¢   ó   z CircleRefsTest.test_sync_handlerc                 C   rc   )Nc                   @   rd   )z=CircleRefsTest.test_finish_exception_handler.<locals>.Handlerc                 S   s
   t  d¡‚re   )r   ÚFinishrB   r   r   r   rg   «   s   
zACircleRefsTest.test_finish_exception_handler.<locals>.Handler.getNrh   r   r   r   r   ri   ª   rj   ri   rk   ro   r   r   r   Útest_finish_exception_handler©   rq   z,CircleRefsTest.test_finish_exception_handlerc                 C   rc   )Nc                   @   s   e Zd Zejdd„ ƒZdS )z1CircleRefsTest.test_coro_handler.<locals>.Handlerc                 s   s    t  d¡V  |  d¡ d S ©Ng{®Gáz„?rf   ©rm   Úsleepr+   rB   r   r   r   rg   ²   s   €z5CircleRefsTest.test_coro_handler.<locals>.Handler.getN)rD   rE   rF   r   Ú	coroutinerg   r   r   r   r   ri   ±   s    ri   rk   ro   r   r   r   Útest_coro_handler°   s   z CircleRefsTest.test_coro_handlerc                 C   rc   )Nc                   @   rd   )z2CircleRefsTest.test_async_handler.<locals>.Handlerc                 Ó   s    t  d¡I d H  |  d¡ d S rt   ru   rB   r   r   r   rg   »   s   €z6CircleRefsTest.test_async_handler.<locals>.Handler.getNrh   r   r   r   r   ri   º   rj   ri   rk   ro   r   r   r   Útest_async_handler¹   s   z!CircleRefsTest.test_async_handlerc              	      s¢   dd l }|j d¡=‰G ‡fdd„dtƒ}|ƒ ‰ ‡ fdd„}tƒ  t |ƒ ¡ W d   ƒ n1 s2w   Y  W d   ƒ d S W d   ƒ d S 1 sJw   Y  d S )Nr   é   c                       s    e Zd Z” Zejjdd„ ƒZdS )z4CircleRefsTest.test_run_on_executor.<locals>.Factoryc                 S   s   d S r   r   rB   r   r   r   rn   Í   s   z8CircleRefsTest.test_run_on_executor.<locals>.Factory.runN)rD   rE   rF   ÚexecutorrR   Ú
concurrentÚrun_on_executorrn   r   )Úthread_poolr   r   ÚFactoryÊ   s    r   c                  “   s"   t dƒD ]	} ˆ  ¡ I d H  qd S )Né   )Úrangern   )Úi)Úfactoryr   r   ÚmainÓ   s   €ÿz1CircleRefsTest.test_run_on_executor.<locals>.main)Úconcurrent.futuresÚfuturesÚThreadPoolExecutorrH   r8   rm   rn   )r>   r|   r   r„   r   )rƒ   r~   r   Útest_run_on_executorÁ   s   ÿð"ðz#CircleRefsTest.test_run_on_executorN)
rD   rE   rF   rO   rb   rp   rs   rx   ry   rˆ   r   r   r   r   r9   h   s    "	r9   )Ú__doc__rm   Ú
contextlibr   r%   r'   r1   r.   ÚtypingÚunittestrR   r   r   r   Útornado.test.utilr   r   Úcontextmanagerr8   ÚTestCaser9   r   r   r   r   Ú<module>   s$    	'
'