B
    u9a§#  ã               @   sâ   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	 d dl
mZmZmZmZmZmZmZmZmZ dd„ Zdd„ Zdd	d
ddœZG dd„ dƒZG dd„ dƒZG dd„ dejƒZedd„ ƒZedkrÞeƒ  dS )é    N)Úmock)	ÚverboseÚimport_moduleÚrun_unittestÚTESTFNÚreap_threadsÚforgetÚunlinkÚrmtreeÚstart_threadsc       	   
   C   s¤   zvy>t |ƒd r"dd l}dd l}ndd l}dd l}| dd¡}W n2 tk
rr } z| | d ¡¡ W d d }~X Y nX W d | t ¡ ¡ t |ƒ| k}|rž| 	¡  X d S )Né   r   é   é   )
ÚlenÚmodulefinderÚrandomZ	randrangeÚ	ExceptionÚappendÚwith_tracebackÚ	threadingÚ	get_identÚset)	ÚNÚdoneÚ
done_tasksÚerrorsr   r   ÚxÚeZfinished© r   ú*/usr/lib/python3.7/test_threaded_import.pyÚtask   s    
&r    c             C   s   t jddd| ƒS )Nzos.register_at_forkT)Zcreate)r   Zpatch)Úfuncr   r   r   Úmock_register_at_fork)   s    r"   zaif 1:
        import time
        time.sleep(%(delay)s)
        x = 'a'
        import C
        zaif 1:
        import time
        time.sleep(%(delay)s)
        x = 'b'
        import D
        zimport Bzimport A)ÚAÚBÚCÚDc               @   s"   e Zd ZdZdd„ Zddd„ZdS )ÚFinderzIA dummy finder to detect concurrent access to its find_spec()
    method.c             C   s   d| _ d| _t ¡ | _d S )Nr   )Únumcallsr   r   ZLockÚlock)Úselfr   r   r   Ú__init__G   s    zFinder.__init__Nc          	   C   s>   | j  |  jd7  _W d Q R X | j}t d¡ |d | _d S )Nr   g{®Gáz„?)r)   r(   r   ÚtimeZsleep)r*   ÚnameÚpathÚtargetr   r   r   r   Ú	find_specL   s
    
zFinder.find_spec)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r+   r0   r   r   r   r   r'   C   s   r'   c               @   s   e Zd ZdZddd„ZdS )ÚFlushingFinderzMA dummy finder which flushes sys.path_importer_cache when it gets
    called.Nc             C   s   t j ¡  d S )N)ÚsysÚpath_importer_cacheÚclear)r*   r-   r.   r/   r   r   r   r0   [   s    zFlushingFinder.find_spec)NN)r1   r2   r3   r4   r0   r   r   r   r   r5   W   s   r5   c               @   s\   e Zd Zdd„ Zdd„ Zedd„ ƒZdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zedd„ ƒZdS )ÚThreadedImportTestsc             C   s   t j dd ¡| _d S )Nr   )r6   ÚmodulesÚpopÚ
old_random)r*   r   r   r   ÚsetUpa   s    zThreadedImportTests.setUpc             C   s   | j d k	r| j tjd< d S )Nr   )r<   r6   r:   )r*   r   r   r   ÚtearDownd   s    
zThreadedImportTests.tearDownc          
      s  t  ¡ rt d¡‚t ¡ ‰xødD ]ð‰ tr8tdˆ ddd x.dD ]&}ytj	|= W q> t
k
rb   Y q>X q>W g ‰g ‰ˆ ¡  t ¡ }t‡ ‡‡‡fdd	„tˆ ƒD ƒƒ W d Q R X ˆ d
¡}t ¡ | }trÜtd|d  ddd dtˆƒˆ f }|  ˆ|¡ |  ||¡ tr tdƒ q W d S )Nz"can't run when import lock is held)é   é2   r?   r@   r?   r@   ZTryingzthreads ...ú )Úend)r   r   c             3   s$   | ]}t jtˆ ˆˆˆfd V  qdS ))r/   ÚargsN)r   ÚThreadr    )Ú.0Úi)r   r   r   r   r   r   ú	<genexpr>   s   zAThreadedImportTests.check_parallel_module_init.<locals>.<genexpr>iX  z%.1f msg     @@T)ÚflushrB   zdone: %s/%szOK.)ÚimpÚ	lock_heldÚunittestZSkipTestr   ZEventr   Úprintr6   r:   ÚKeyErrorr8   r,   Z	monotonicr   ÚrangeÚwaitr   ÚassertFalseZ
assertTrue)r*   Úmock_osÚmodnameZt0Z	completedZdtZdbg_infor   )r   r   r   r   r   Úcheck_parallel_module_initk   s6    





z.ThreadedImportTests.check_parallel_module_initc             C   s   |   ¡  d S )N)rS   )r*   r   r   r   Útest_parallel_module_init   s    z-ThreadedImportTests.test_parallel_module_initc          	   C   sR   t ƒ }tj d|¡ z*|  ¡  |  |jd¡ |  |j|j¡ W d tj 	|¡ X d S )Nr   )
r'   r6   Ú	meta_pathÚinsertrS   ÚassertGreaterr(   ÚassertEqualr   Úremove)r*   Úfinderr   r   r   Útest_parallel_meta_path   s    z+ThreadedImportTests.test_parallel_meta_pathc          	      s†   t ƒ ‰ tƒ }‡ fdd„}tj d|¡ tj |¡ z4| d¡ |  ¡ }|  	ˆ j
d¡ |  ˆ jˆ j
¡ W d tj |¡ tj |¡ X d S )Nc                s   ˆ   d¡ t‚d S )NÚ )r0   ÚImportError)r.   )rZ   r   r   Ú	path_hook¢   s    
z?ThreadedImportTests.test_parallel_path_hooks.<locals>.path_hookr   r\   )r'   r5   r6   Ú
path_hooksrV   rU   r   r0   rS   rW   r(   rX   r   rY   )r*   Zflushing_finderr^   Znumtestsr   )rZ   r   Útest_parallel_path_hooksš   s    
z,ThreadedImportTests.test_parallel_path_hooksc             C   s<   yt jd= W n tk
r    Y nX dd l}|  |jj¡ d S )Nztest.threaded_import_hangersr   )r6   r:   rM   Ztest.threaded_import_hangersrP   Zthreaded_import_hangersr   )r*   Ztestr   r   r   Útest_import_hangers±   s    z'ThreadedImportTests.test_import_hangersc       	   
      s  d}t  t¡ |  tjt¡ tj dt¡ |  tjj	t¡ x`t
 ¡ D ]T\}}|d|i }tt j t|d ¡dƒ}| | d¡¡ W d Q R X |  t|¡ qDW t ¡  g ‰ ‡ fdd„}‡ fd	d
„}tj|d}tj|d}| ¡  | ¡  | ¡  | ¡  |  tˆ ƒddh¡ d S )Ng      à?r   Údelayz.pyÚwbzutf-8c                 s   dd l } ˆ  t| dd ƒ¡ d S )Nr   r   )r#   r   Úgetattr)r#   )Úresultsr   r   Ú	import_abÓ   s    z<ThreadedImportTests.test_circular_imports.<locals>.import_abc                 s   dd l } ˆ  t| dd ƒ¡ d S )Nr   r   )r$   r   rd   )r$   )re   r   r   Ú	import_baÖ   s    z<ThreadedImportTests.test_circular_imports.<locals>.import_ba)r/   ÚaÚb)ÚosÚmkdirr   Ú
addCleanupÚshutilr
   r6   r.   rV   rY   Úcircular_imports_modulesÚitemsÚopenÚjoinÚwriteÚencoder   Ú	importlibÚinvalidate_cachesr   rD   ÚstartrX   r   )	r*   rb   r-   ÚcontentsÚfrf   rg   Zt1Zt2r   )re   r   Útest_circular_imports»   s*    
z)ThreadedImportTests.test_circular_importsc          	   C   s”   d}t j dtj¡ |  t jjtj¡ td }t|dƒ}| 	| 
d¡¡ W d Q R X |  t|¡ |  tt¡ |  td¡ t ¡  ttƒ t jt= d S )NzÊif 1:
            import threading
            def target():
                import random
            t = threading.Thread(target=target)
            t.start()
            t.join()
            t = Noner   z.pyrc   zutf-8Ú__pycache__)r6   r.   rV   rj   Úcurdirrl   rY   r   rp   rr   rs   r	   r   r
   rt   ru   Ú
__import__r:   )r*   rQ   ÚcodeÚfilenamerx   r   r   r   Útest_side_effect_importá   s    	z+ThreadedImportTests.test_side_effect_importN)r1   r2   r3   r=   r>   r"   rS   rT   r[   r`   ra   ry   r   r   r   r   r   r9   _   s   "

&r9   c           	   C   sV   d } yt  ¡ } t  d¡ W n tk
r.   Y nX zttƒ W d | d k	rPt  | ¡ X d S )Ngñhãˆµøä>)r6   ÚgetswitchintervalÚsetswitchintervalÚAttributeErrorr   r9   )Zold_switchintervalr   r   r   Ú	test_mainø   s    rƒ   Ú__main__)Ú_imprI   rj   rt   r6   r,   rm   r   rK   r   Ztest.supportr   r   r   r   r   r   r	   r
   r   r    r"   rn   r'   r5   ZTestCaser9   rƒ   r1   r   r   r   r   Ú<module>   s,   , 