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   sJ   t  ¡ st‚| j |  jd7  _W d Q R X | j}t d¡ |d | _d S )Nr   g{®Gáz„?)ÚimpÚ	lock_heldÚAssertionErrorr)   r(   r   ÚtimeZsleep)r*   ÚnameÚpathÚtargetr   r   r   r   Ú	find_specL   s    
zFinder.find_spec)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r+   r3   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*   r0   r1   r2   r   r   r   r3   [   s    zFlushingFinder.find_spec)NN)r4   r5   r6   r7   r3   r   r   r   r   r8   W   s   r8   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   )r9   Ú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?   r9   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   rB   rC   rB   rC   ZTryingzthreads ...ú )Úend)r   r   c             3   s$   | ]}t jtˆ ˆˆˆfd V  qdS ))r2   Ú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)ÚflushrE   zdone: %s/%szOK.)r,   r-   ÚunittestZSkipTestr   ZEventr   Úprintr9   r=   ÚKeyErrorr;   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)rT   )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'   r9   Ú	meta_pathÚinsertrT   Ú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Ú )r3   ÚImportError)r1   )r[   r   r   Ú	path_hook¢   s    
z?ThreadedImportTests.test_parallel_path_hooks.<locals>.path_hookr   r]   )r'   r8   r9   Ú
path_hooksrW   rV   r   r3   rT   rX   r(   rY   r   rZ   )r*   Zflushing_finderr_   Znumtestsr   )r[   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   )r9   r=   rN   Ztest.threaded_import_hangersrQ   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   re   )r$   )rf   r   r   Ú	import_baÖ   s    z<ThreadedImportTests.test_circular_imports.<locals>.import_ba)r2   ÚaÚb)ÚosÚmkdirr   Ú
addCleanupÚshutilr
   r9   r1   rW   rZ   Úcircular_imports_modulesÚitemsÚopenÚjoinÚwriteÚencoder   Ú	importlibÚinvalidate_cachesr   rG   ÚstartrY   r   )	r*   rc   r0   ÚcontentsÚfrg   rh   Zt1Zt2r   )rf   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.pyrd   zutf-8Ú__pycache__)r9   r1   rW   rk   Úcurdirrm   rZ   r   rq   rs   rt   r	   r   r
   ru   rv   Ú
__import__r=   )r*   rR   ÚcodeÚfilenamery   r   r   r   Útest_side_effect_importá   s    	z+ThreadedImportTests.test_side_effect_importN)r4   r5   r6   r@   rA   r"   rT   rU   r\   ra   rb   rz   r€   r   r   r   r   r<   _   s   "

&r<   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ãˆµøä>)r9   ÚgetswitchintervalÚsetswitchintervalÚAttributeErrorr   r<   )Zold_switchintervalr   r   r   Ú	test_mainø   s    r„   Ú__main__)Ú_impr,   rk   ru   r9   r/   rn   r   rL   r   Ztest.supportr   r   r   r   r   r   r	   r
   r   r    r"   ro   r'   r8   ZTestCaser<   r„   r4   r   r   r   r   Ú<module>   s,   , 