U
    .d/                     @   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mZ ddl	m
Z
 ddlmZ ddlmZ ddlm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 dd
lmZ ddlmZmZ ddlmZ ddlmZmZmZmZm Z  edk	rddl!m"Z" ddl#m$Z$ zddl%Z%W n e&k
r8   dZ%Y nX zddl'm(Z( W n e&k
rd   dZ(Y nX zddl)Z)W n e&k
r   dZ)Y nX ddl*m+Z+ ddl*m,Z, ddl*m-Z- ddl*m.Z. ddl*m/Z/ ddl*m0Z0 ddl1m2Z2m3Z3 ddl1m4Z4m5Z5 ddl1m6Z6m7Z7 ddl1mZm8Z8m9Z9m:Z: ddl;m<Z< ddl;m=Z= dge>e8?  Z@e@dd e8D 7 Z@edkrjg ZAnd d!gZAeAd"g ZBeCed#re@DeEd$ e8e9 ZFd%d& ZGd'd( ZHd)d* ZIG d+d, d,eJZKd=d.d/ZLd0d1 ZMd>d2d3ZNd4d5 ZOd6d7 ZPd8d9 ZQd:d; ZRejSjd<d=d>e6d>d?fd@gdAdBdCgdDedEdF ZTedGe@edHddId>dJgedKdIdLdMgdNdO ZUedGe@dPdQ ZVdRdS ZWeedTdUdVdWdXdYdZgd[d\ ZXeedGd!d d"gd]d^ ZYd_d` ZZedae8edbe8dcdd Z[dedf Z\edgdh Z]didj Z^edHddIdkgdldm Z_edGeBdndo Z`edpdq ZaedGeBdrds ZbeedGeBdtdu ZceedGeAdvdw Zddxdy ZeedGe8edzdd{d|d}d~ddddddddgfdd{d}ddd|d~ddddddgfgdd ZfeedGeBdd Zgdd ZheedGeAdd Zidd Zjdd Zkdd ZleedGeBejSjmdddd ZnG dd de+Zodd ZpedGe@dd Zqdd Zrdd Zseedk	dddd Ztdd ZueBdd Zvevwdd exdkD  eedGevdd ZyG dd de+Zzdd Z{dd Z|dd Z}dd Z~G dd dejj/Ze4de eedGd"d!d dgdd ZeedHdId>dgedGeBdd Zdd ZeedeBedeBdd ZeddĄ ZddƄ ZddȄ Zeddd>dgdd̄ Zeddddddddddddgddل Zeddۄ ZeeedGeAdd݄ ZdZeedGeAdd ZdZdZdZdZeedGeAedkr\g nd$g edeeegeddddgdd ZdjejejejdZedd ZdjejejejdZedd Zdd Zdd ZeeedGeAdd Zdd Zeedd Zdd ZedGe@edHddIdJd>gdd  ZeeedGeAdd ZedGedkrdd"gndd!d"gdd ZeedGeAdd Zedd Zd	d
 Zdd Zdd Zdd Zd?ddZeedGd!d"gdd Zeee)dkdddd Zd@ddZedGedk	rnd"gnd!d"gdd Zdd ZedGedk		rdd!gndgee(dkdddd  Zee)dk	d!dd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- ZeeedHdIddJd>gd.d/ Zeeed0ddIddgedHdId>gd1d2 ZeedHdId>ged3d4d5d6gd7d8 ZeeedGd d"e- e, gd9d: ZeedHdIdd>gd;d< ZdS (A  z
Test the parallel module.
    N)format_exceptionsqrt)sleep)PicklingErrorTimeoutErrorparallel)dumpload)mp)np
with_numpy)with_multiprocessing)parametrizeraisescheck_subprocess_callskipifwarns)get_reusable_executor)Queue   )parallel_sum)SequentialBackend)ThreadingBackend)MultiprocessingBackend)ParallelBackendBase)LokyBackend)SafeFunction)Paralleldelayed)register_parallel_backendparallel_backend)effective_n_jobs	cpu_count)r   BACKENDSDEFAULT_BACKENDEXTERNAL_BACKENDS)JoblibException)WorkerInterruptc                 C   s   g | ]}t |  qS  )r&   ).0Zbackend_strr+   r+   =/tmp/pip-unpacked-wheel-ho8k9mhl/joblib/test/test_parallel.py
<listcomp>J   s     r.   multiprocessingloky	threadingget_contextspawnc                 C   s   t | dt | dd S )N_poolZ_workers)getattrbackendr+   r+   r-   get_workersX   s    r8   c                 C   s   | | S Nr+   )xyr+   r+   r-   division\   s    r<   c                 C   s   | d S N   r+   r:   r+   r+   r-   square`   s    r@   c                   @   s   e Zd ZdZdd ZdS )MyExceptionWithFinickyInitz1An exception class with non trivial __init__
    c                 C   s   d S r9   r+   )selfabcdr+   r+   r-   __init__g   s    z#MyExceptionWithFinickyInit.__init__N__name__
__module____qualname____doc__rG   r+   r+   r+   r-   rA   d   s   rA   Fc                 C   s"   | dkr|rt ddddnt| S )N   rC   rD   rE   rF   )rA   
ValueError)r:   custom_exceptionr+   r+   r-   exception_raiserk   s    rP   c                 C   s   t d td S )Ng?)timer   KeyboardInterruptr?   r+   r+   r-   interrupt_raiserr   s    
rS   c                 C   s   | d | | S )zO A module-level function so that it can be spawn with
    multiprocessing.
    r>   r+   )r:   r;   zr+   r+   r-   fw   s    rU   c                   C   s   t t d S Nr   )typer
   get_active_backendr+   r+   r+   r-   _active_backend_type~   s    rY   c                 C   s   t | |ddd tdD S )Nn_jobsr7   c                 s   s   | ]}t t|V  qd S r9   r!   r@   r,   ir+   r+   r-   	<genexpr>   s    z parallel_func.<locals>.<genexpr>   r    range)inner_n_jobsr7   r+   r+   r-   parallel_func   s    rd   c                   C   s   t  dkstd S rV   )r%   AssertionErrorr+   r+   r+   r-   test_cpu_count   s    rf   c                   C   s   t  dkstd S rV   )r$   re   r+   r+   r+   r-   test_effective_n_jobs   s    rg   zbackend_n_jobs, expected_n_jobs)r`   r`   r[   Nr   zpositive-intznegative-intNone)idsc              	   C   s@   t d| d td d|ks tW 5 Q R X td ddks<td S )Nr1   ri   r   )r#   r$   re   )Zbackend_n_jobsZexpected_n_jobsr+   r+   r-   test_effective_n_jobs_None   s    	rm   r7   r[   r>   verbose   d   c                 C   s:   dd t dD t|| |ddd t dD ks6td S )Nc                 S   s   g | ]}t |qS r+   r@   r,   r:   r+   r+   r-   r.      s     z(test_simple_parallel.<locals>.<listcomp>   )r[   r7   ro   c                 s   s   | ]}t t|V  qd S r9   r\   rs   r+   r+   r-   r_      s    z'test_simple_parallel.<locals>.<genexpr>rb   r    re   )r7   r[   ro   r+   r+   r-   test_simple_parallel   s    rv   c              	   C   s~   |j t ddd tjdd6}td| ddd	 td
D }|dddgksRtW 5 Q R X dd |D }t|dksztd S )NnameZ!some_new_name_for_the_main_thread)targetrw   valueTrecordr>   rZ   c                 s   s   | ]}t t|V  qd S r9   r\   rs   r+   r+   r-   r_      s    z6test_main_thread_renamed_no_warning.<locals>.<genexpr>r`   r   r      c                 S   s   g | ]}d t |jkr|qS )zworker timeout)strmessager,   wr+   r+   r-   r.      s      z7test_main_thread_renamed_no_warning.<locals>.<listcomp>)	setattrr1   current_threadwarningscatch_warningsr    rb   re   len)r7   monkeypatchwarninforesultsr+   r+   r-   #test_main_thread_renamed_no_warning   s    r   c              	   C   sv   t jdd}t d t| |d W 5 Q R X dd |D }|rf|rbt|dko`d|d	 jd	 kS d
S |rntdS d S )NTrz   always)r7   rc   c                 S   s   g | ]
}|j qS r+   )r~   r   r+   r+   r-   r.      s     z*_assert_warning_nested.<locals>.<listcomp>r   zbacked parallel loops cannotr   F)r   r   simplefilterrd   r   argsre   )r7   rc   expectedr   r+   r+   r-   _assert_warning_nested   s    
r   z%parent_backend,child_backend,expected)r0   r/   T)r0   r0   F)r/   r/   T)r/   r0   T)r1   r/   T)r1   r0   Tc                    sl   t d| d fddtdD  t d| d fddtdD }| dkr\t|shtnt|shtd S )Nr>   rZ   c                 3   s    | ]}t t d ddV  qdS )r   Fr7   rc   r   Nr!   r   r,   _child_backendr+   r-   r_      s    z0test_nested_parallel_warnings.<locals>.<genexpr>rt   c                 3   s    | ]}t t d dV  qdS )r>   r   Nr   r   r   r   r+   r-   r_      s    r1   )r    rb   anyre   all)parent_backendr   r   resr+   r   r-   test_nested_parallel_warnings   s    r   c                 C   s>   dg}dd }t j||fd}|  |  |d s:td S )NFc              	   S   sT   t jdd"}tdddd tdD  W 5 Q R X tt| t|dk| d< d S )	NTrz   r>   ri   c                 s   s   | ]}t td V  qdS )皙?Nr!   r   r   r+   r+   r-   r_     s    zPtest_background_thread_parallelism.<locals>.background_thread.<locals>.<genexpr>r|   r   )r   r   r    rb   printr   )is_run_parallelr   r+   r+   r-   background_thread   s    z=test_background_thread_parallelism.<locals>.background_thread)rx   r   r   )r1   Threadstartjoinre   )r7   r   r   tr+   r+   r-   "test_background_thread_parallelism   s    r   c                 C   s"   t d| ddd tdD  d S )Nr>   rZ   c                 s   s   | ]}t td V  qdS ){Gz?Nr\   r   r+   r+   r-   r_     s    znested_loop.<locals>.<genexpr>ra   r6   r+   r+   r-   nested_loop  s    r   r   r   c                    s&   t d| d fddtdD  d S )Nr>   rZ   c                 3   s   | ]}t t V  qd S r9   )r!   r   r   r   r+   r-   r_     s    z#test_nested_loop.<locals>.<genexpr>ra   )r   r   r+   r   r-   test_nested_loop  s    r   c                 C   s   t d S r9   )rN   r6   r+   r+   r-   raise_exception  s    r   c               
   C   sL   t t: tddd"} | ttdttdg W 5 Q R X W 5 Q R X d S )Nr>   r0   rZ   )r   rN   r    r!   r   r   r	   r+   r+   r-   )test_nested_loop_with_exception_with_loky  s
    

r   c                      s<   t dd tddd fddtdD    s8tdS )	z1Input is mutable when using the threading backendrt   )maxsizer>   r1   rZ   c                 3   s   | ]}t  jd V  qdS r   N)r!   putr   qr+   r-   r_   '  s    z1test_mutate_input_with_threads.<locals>.<genexpr>N)r   r    rb   fullre   r+   r+   r   r-   test_mutate_input_with_threads$  s
    
r   r`   c                 C   s6   t d}dd |D t| ddd |D ks2tdS )z.Check the keyword argument processing of pmap.
   c                 S   s   g | ]}t |d dqS r   r;   rU   rs   r+   r+   r-   r.   0  s     z(test_parallel_kwargs.<locals>.<listcomp>ri   c                 s   s   | ]}t t|d dV  qdS r   r   Nr!   rU   rs   r+   r+   r-   r_   1  s     z'test_parallel_kwargs.<locals>.<genexpr>Nru   )r[   lstr+   r+   r-   test_parallel_kwargs,  s    r   c              	   C   s   t d}dd |D }td| d^}|j}||dd |D ksDt||dd |D ks^ttd k	r|t|t|jks|tW 5 Q R X td k	rt|jd kst||d	d |D ksttd k	rt|jd kstd S )
Nr   c                 S   s   g | ]}t |d dqS r   r   rs   r+   r+   r-   r.   7  s     z4test_parallel_as_context_manager.<locals>.<listcomp>r|   rZ   c                 s   s   | ]}t t|d dV  qdS r   r   rs   r+   r+   r-   r_   @  s     z3test_parallel_as_context_manager.<locals>.<genexpr>c                 s   s   | ]}t t|d dV  qdS r   r   rs   r+   r+   r-   r_   A  s     c                 s   s   | ]}t t|d dV  qdS r   r   rs   r+   r+   r-   r_   M  s     )rb   r    _backendre   r   r8   )r7   r   r   pZmanaged_backendr+   r+   r-    test_parallel_as_context_manager4  s     r   c                	      sL   G dd dt  ttdd& tdd fddtd	D  W 5 Q R X d
S )ze Check that pmap captures the errors when it is passed an object
        that cannot be pickled.
    c                   @   s   e Zd Zdd ZdS )z1test_parallel_pickling.<locals>.UnpicklableObjectc                 S   s   t dd S )NZ123)RuntimeErrorrB   r+   r+   r-   
__reduce__X  s    z<test_parallel_pickling.<locals>.UnpicklableObject.__reduce__N)rI   rJ   rK   r   r+   r+   r+   r-   UnpicklableObjectW  s   r   zthe task to sendmatchr>   ri   c                 3   s   | ]}t t  V  qd S r9   r!   idr   r   r+   r-   r_   \  s     z)test_parallel_pickling.<locals>.<genexpr>r   N)objectr   r   r    rb   r+   r+   r   r-   test_parallel_picklingR  s    r   c                 C   s0   t td| dddd tdD dks,td S )Nr>   r   r[   r7   timeoutc                 s   s   | ]}t td V  qdS )gMbP?Nr   rs   r+   r+   r-   r_   b  s    z0test_parallel_timeout_success.<locals>.<genexpr>)r   r    rb   re   r6   r+   r+   r-   test_parallel_timeout_success_  s
    r   c              	   C   s8   t t& td| dddd tdD  W 5 Q R X d S )Nr>   r   r   c                 s   s   | ]}t td V  qdS )r   Nr   rs   r+   r+   r-   r_   k  s    z-test_parallel_timeout_fail.<locals>.<genexpr>r   )r   r   r    rb   r6   r+   r+   r-   test_parallel_timeout_failf  s    
r   c              
   C   s  t d k	rtt& td| ddd tddD  W 5 Q R X tt  td| ddd dD  W 5 Q R X td| d&}t|jd k	stt|j}tt |dd tddD  W 5 Q R X t|jd k	stt|j|k	std	d t	d
D |dd t	d
D kstt|j}tt |dd dD  W 5 Q R X t|jd k	sZtt|j|k	sntdd t	d
D |dd t	d
D kstW 5 Q R X t|jd kstn,tt
 tdddd dD  W 5 Q R X tt$ tdddd tddD  W 5 Q R X tt$ tddddd t	dD  W 5 Q R X z"tdddd tddD  W n4 tk
r } zt|trtW 5 d }~X Y n
X tdd S )Nr>   rZ   c                 S   s   g | ]\}}t t||qS r+   r!   r<   r,   r:   r;   r+   r+   r-   r.   w  s   z&test_error_capture.<locals>.<listcomp>)r   r   )r   r   c                 S   s   g | ]}t t|qS r+   r!   rS   rs   r+   r+   r-   r.   {  s     c                 S   s   g | ]\}}t t||qS r+   r   r   r+   r+   r-   r.     s   c                 S   s   g | ]}t |d dqS r   r   rs   r+   r+   r-   r.     s     r   c                 s   s   | ]}t t|d dV  qdS r   r   rs   r+   r+   r-   r_     s     z%test_error_capture.<locals>.<genexpr>c                 S   s   g | ]}t t|qS r+   r   rs   r+   r+   r-   r.     s     c                 S   s   g | ]}t |d dqS r   r   rs   r+   r+   r-   r.     s     c                 s   s   | ]}t t|d dV  qdS r   r   rs   r+   r+   r-   r_     s     ri   c                 S   s   g | ]}t t|qS r+   r   rs   r+   r+   r-   r.     s     c                 S   s   g | ]\}}t t||qS r+   r   r   r+   r+   r-   r.     s     r   )r[   ro   c                 s   s   | ]}t t|d dV  qdS )T)rO   Nr!   rP   r]   r+   r+   r-   r_     s      r   c                 s   s    | ]\}}t t||V  qd S r9   r   r   r+   r+   r-   r_     s    z'The excepted error has not been raised.)r   r   ZeroDivisionErrorr    zipr*   r8   r   re   rb   rR   rA   	Exception
isinstancer)   rN   )r7   r
   Zoriginal_workersexr+   r+   r-   test_error_captureo  sj    













"r   c                 C   s   |  d|  d S )NzConsumed %s)append)queueitemr+   r+   r-   consumer  s    r   zbatch_size, expected_queue
Produced 0z
Consumed 0z
Produced 1z
Consumed 1z
Produced 2z
Consumed 2
Produced 3z
Consumed 3z
Produced 4z
Consumed 4z
Produced 5z
Consumed 5r|   c                    sT   t    fdd}td|| d fdd| D   |ks@tt dksPtdS )	zC Test that with only one job, Parallel does act as a iterator.
    c                  3   s&   t dD ]}  d|   | V  qd S N   zProduced %irb   r   r^   r   r+   r-   producer  s    z'test_dispatch_one_job.<locals>.producerr   r[   
batch_sizer7   c                 3   s   | ]}t t |V  qd S r9   r!   r   rs   r   r+   r-   r_     s    z(test_dispatch_one_job.<locals>.<genexpr>   N)listr    re   r   )r7   r   Zexpected_queuer   r+   r   r-   test_dispatch_one_job  s    r   c                    s   t  }|   fdd}tddd| d fdd| D  t }|d	 d
ksXt|dd d}|dksvt|d}||kstt dkstdS )zW Check that using pre_dispatch Parallel does indeed dispatch items
        lazily.
    c                  3   s&   t dD ]}  d|   | V  qd S r   r   r   r   r+   r-   r     s    z/test_dispatch_multiprocessing.<locals>.producerr>   r   r`   )r[   r   pre_dispatchr7   c                 3   s   | ]}t t d V  qdS )r   Nr   r   r   r+   r-   r_     s    z0test_dispatch_multiprocessing.<locals>.<genexpr>r   r   Nr|   zConsumed anyrh   r   r   )r   Managerr   r    re   indexr   )r7   managerr   Zqueue_contentsZfirst_consumption_indexZproduced_3_indexr+   r   r-   test_dispatch_multiprocessing  s    
r   c               	   C   sF   t dddd.} | dd tdD  | j dks8tW 5 Q R X d S )	Nr>   autor1   r   c                 s   s   | ]}t t|V  qd S r9   r   r]   r+   r+   r-   r_      s     z/test_batching_auto_threading.<locals>.<genexpr>  r   r    rb   r   Zcompute_batch_sizere   )r   r+   r+   r-   test_batching_auto_threading  s    r   c              	   C   sF   t dd| d.}|dd tdD  |j dks8tW 5 Q R X d S )Nr>   r   r   c                 s   s   | ]}t t|V  qd S r9   r   r]   r+   r+   r-   r_     s     z2test_batching_auto_subprocesses.<locals>.<genexpr>r   r   r   )r7   r   r+   r+   r-   test_batching_auto_subprocesses  s    r   c                	   C   s8   t t& tdddddd tdD  W 5 Q R X dS )	zCMake sure that exception raised during dispatch are indeed capturedr>      r   )r[   r   ro   c                 s   s   | ]}t t|V  qd S r9   r   r]   r+   r+   r-   r_     s    z*test_exception_dispatch.<locals>.<genexpr>r   N)r   rN   r    rb   r+   r+   r+   r-   test_exception_dispatch  s    
r   c                 C   s    t dddd tdD  d S )Nr>   ri   c                 s   s   | ]}t t|V  qd S r9   r   r,   jr+   r+   r-   r_     s    z(nested_function_inner.<locals>.<genexpr>r   ra   r   r+   r+   r-   nested_function_inner  s    r   c                 C   s    t dddd tdD  d S )Nr>   ri   c                 s   s   | ]}t t|V  qd S r9   )r!   r   r   r+   r+   r-   r_     s    z(nested_function_outer.<locals>.<genexpr>r   ra   r   r+   r+   r-   nested_function_outer  s    r   z'https://github.com/joblib/loky/pull/255)reasonc              	   C   s   t t$}td| ddd tdD  W 5 Q R X t|j|j|j}d|}d|ksZt	d|ksft	d	|ksrt	t|jtkst	d
S )zEnsure errors for nested joblib cases gets propagated

    We rely on the Python 3 built-in __cause__ system that already
    report this kind of information to the user.
    r>   rZ   c                 s   s   | ]}t t|V  qd S r9   )r!   r   r]   r+   r+   r-   r_   +  s    z1test_nested_exception_dispatch.<locals>.<genexpr>r    r   r   rP   N)
r   rN   r    rb   r   rW   ry   tbr   re   )r7   excinfoZreport_linesreportr+   r+   r-   test_nested_exception_dispatch!  s    	

r   c                   @   s$   e Zd ZdZdddZd	ddZdS )
FakeParallelBackendz8Pretends to run concurrently while running sequentially.r   Nc                 K   s   |  || _|| _|S r9   )r$   r[   r
   )rB   r[   r
   Zbackend_argsr+   r+   r-   	configure<  s    zFakeParallelBackend.configurec                 C   s"   |dk rt t d | d}|S )Nr   r   )maxr   r%   rB   r[   r+   r+   r-   r$   A  s    z$FakeParallelBackend.effective_n_jobs)r   N)r   )rI   rJ   rK   rL   r   r$   r+   r+   r+   r-   r   9  s   
r   c               
   C   sn   t t} tdd W 5 Q R X dt| jks0tt t} td W 5 Q R X W 5 Q R X dt| jksjtd S )Nzunit-testingr6   zInvalid backend:)r   rN   r    r}   ry   re   r#   )r   r+   r+   r-   test_invalid_backendG  s    


r  c              	   C   s:   t t}td| d  W 5 Q R X dt|jks6td S )Nr   rZ   z&n_jobs == 0 in Parallel has no meaning)r   rN   r    Z_initialize_backendr}   ry   re   )r7   r   r+   r+   r-   test_invalid_njobsR  s    
r  c                   C   s8   z*tdt dt kstt d tks(tW 5 t d= X d S )NZtest_backend)r&   r"   r   re   r+   r+   r+   r-   test_register_parallel_backendY  s
    
r  c                   C   sN   t  tkstz$tdtd dd t  tks0tW 5 tt_X t  tksJtd S )Nr1   T)Zmake_default)rY   DefaultBackendre   r'   r
   r"   r&   r   r+   r+   r+   r-   test_overwrite_default_backendb  s    
r  zOnly without multiprocessingc                	   C   sd   t tdd" tdddd tdD  W 5 Q R X td t dd tdD  W 5 Q R X d S )	Nz)joblib backend '.*' is not available on.*r   r0   r6   c                 s   s   | ]}t t|V  qd S r9   r\   r]   r+   r+   r-   r_   r  s     z2test_backend_no_multiprocessing.<locals>.<genexpr>r`   c                 s   s   | ]}t t|V  qd S r9   r\   r]   r+   r+   r-   r_   v  s     )r   UserWarningr    rb   r#   r+   r+   r+   r-   test_backend_no_multiprocessingn  s    &
r  c              	   C   s  t | dd t \}}|dks&ttddks6tt }|jdksJt| dkrvt|tksbtt|j	tkstn| dkrt|t
kstt|j	t
kstnX| dkrt|tkstt|j	tkstn,| drt|tkstt|j	tkstW 5 Q R X d S )Nr`   ri   r/   r0   r1   Ztest_)r#   r
   rX   re   r$   r    r[   rW   r   r   r   r   
startswithr   )backend_nameactive_backendactive_n_jobsr   r+   r+   r-   check_backend_context_managery  s$    
r  c                 C   s   g | ]}d | qS )ztest_backend_%dr+   r]   r+   r+   r-   r.     s     c                 C   sf   |t kr| t |t t tks$tt| t tks:ttddddd tD  t tksbtd S )Nr>   r1   rZ   c                 s   s   | ]}|st t|V  qd S r9   )r!   r  )r,   rD   r+   r+   r-   r_     s    z/test_backend_context_manager.<locals>.<genexpr>)	r&   setitemr   rY   r  re   r  r     all_backends_for_context_manager)r   r7   r+   r+   r-   test_backend_context_manager  s    r  c                   @   s   e Zd ZdZdddZdS )ParameterizedParallelBackendz9Pretends to run conncurrently while running sequentially.Nc                 C   s   |d krt d|| _d S )Nzparam should not be None)rN   param)rB   r  r+   r+   r-   rG     s    z%ParameterizedParallelBackend.__init__)NrH   r+   r+   r+   r-   r    s   r  c              	   C   s   |  tdt t tksttddddt t \}}t	|tksHt|j
dksVt|dksbtt }|jdksvt|j|kst|dd tdD }W 5 Q R X |dd	 tdD kstt tkstd S )
NZparam_backend*   r`   )r  r[   c                 s   s   | ]}t t|V  qd S r9   r!   r   r]   r+   r+   r-   r_     s     z=test_parameterized_backend_context_manager.<locals>.<genexpr>rt   c                 S   s   g | ]}t |qS r+   r   r]   r+   r+   r-   r.     s     z>test_parameterized_backend_context_manager.<locals>.<listcomp>)r  r&   r  rY   r  re   r#   r
   rX   rW   r  r    r[   r   rb   )r   r  r  r   r   r+   r+   r-   *test_parameterized_backend_context_manager  s     r  c               	   C   s   t  tkstttddddt t \} }t| tks>t| jdksLt|dksXtt	 }|j
dkslt|j| kszt|dd tdD }W 5 Q R X |dd tdD kstt  tkstd S )	N+   )r  rt   ri   c                 s   s   | ]}t t|V  qd S r9   r  r]   r+   r+   r-   r_     s     zFtest_directly_parameterized_backend_context_manager.<locals>.<genexpr>c                 S   s   g | ]}t |qS r+   r   r]   r+   r+   r-   r.     s     zGtest_directly_parameterized_backend_context_manager.<locals>.<listcomp>)rY   r  re   r#   r  r
   rX   rW   r  r    r[   r   rb   )r  r  r   r   r+   r+   r-   3test_directly_parameterized_backend_context_manager  s     r  c                   C   s   t d t S )Nr   )r   osgetpidr+   r+   r+   r-   sleep_and_return_pid  s    r  c                   C   s<   t  tkstt  dks ttdddd tdD S )Nr   r>   ri   c                 s   s   | ]}t t V  qd S r9   )r!   r  r   r+   r+   r-   r_     s   z"get_nested_pids.<locals>.<genexpr>)rY   r   re   r    _effective_n_jobsrb   r+   r+   r+   r-   get_nested_pids  s
    r  c                       s    e Zd ZdZ fddZ  ZS )	MyBackendz:Backend to test backward compatibility with older backendsc                    s   t t|  d S rV   )superr  get_nested_backendr   	__class__r+   r-   r    s    zMyBackend.get_nested_backend)rI   rJ   rK   rL   r  __classcell__r+   r+   r   r-   r    s   r  Zback_compat_backendc              	   C   sR   t | @ tdddd tdD }|D ]}tt|dks*tq*W 5 Q R X d S )Nr>   ri   c                 s   s   | ]}t t V  qd S r9   )r!   r  r   r+   r+   r-   r_     s   z6test_nested_backend_context_manager.<locals>.<genexpr>r   r   )r#   r    rb   r   setre   )r7   Z
pid_groupsZ	pid_groupr+   r+   r-   #test_nested_backend_context_manager  s    
r$  c              	      sh   dd t ddfddtdD  t d* t dd fddtdD  W 5 Q R X d S )	Nc                 S   s0   t  t|  kstt|}t  |ks,td S r9   )rY   r&   re   r$   r    r  )Zexpected_backend_typeZexpected_n_jobr+   r+   r-   check_nested_backend  s    z?test_nested_backend_in_sequential.<locals>.check_nested_backendr   ri   c                 3   s   | ]}t  d dV  qdS )r0   r   Nr!   r   )r%  r+   r-   r_     s   z4test_nested_backend_in_sequential.<locals>.<genexpr>r   c                 3   s   | ]}t  V  qd S r9   r&  r   r7   r%  r[   r+   r-   r_     s   )r    rb   r#   )r7   r[   r+   r'  r-   !test_nested_backend_in_sequential  s    
r(  c              	   C   s*   t | \}}|j|kstW 5 Q R X d S r9   )r#   nesting_levelre   )inner_backendZexpected_levelr7   r[   r+   r+   r-   check_nesting_level"  s    r+  outer_backendr*  c              	      sd   t | d td| d fddtdD  t dd" t  fddtdD  W 5 Q R X d S )	Nr   r>   rZ   c                 3   s   | ]}t t d V  qdS r   r!   r+  r   r*  r+   r-   r_   .  s   z-test_backend_nesting_level.<locals>.<genexpr>r   ri   c                 3   s   | ]}t t d V  qdS r   r-  r   r.  r+   r-   r_   4  s   )r+  r    rb   r#   )r,  r*  r+   r.  r-   test_backend_nesting_level'  s    
r/  c               	      sx   dd l  G  fdddt} td|  dd td8\}}tddfd	d
tdD  |jdksjtW 5 Q R X d S )Nr   c                       s   e Zd ZdZ jdd ZdS )z)test_retrieval_context.<locals>.MyBackendr   c                 s   s   |  j d7  _ d V  d S rj   r   r   r+   r+   r-   retrieval_context?  s    z;test_retrieval_context.<locals>.MyBackend.retrieval_contextN)rI   rJ   rK   r^   contextmanagerr0  r+   )
contextlibr+   r-   r  <  s   r  Z	retrievalc                 S   s   t dddd t| D S )Nr>   ri   c                 s   s   | ]}t t|V  qd S r9   r   r]   r+   r+   r-   r_   G  s     z>test_retrieval_context.<locals>.nested_call.<locals>.<genexpr>ra   )nr+   r+   r-   nested_callF  s    z+test_retrieval_context.<locals>.nested_callr>   ri   c                 3   s   | ]}t  |V  qd S r9   r&  r]   )r4  r+   r-   r_   J  s   z)test_retrieval_context.<locals>.<genexpr>rt   r   )r2  r   r"   r#   r    rb   r^   re   )r  bar   r+   )r2  r4  r-   test_retrieval_context8  s    
r6  c                  C   s   t d} t|  t|  d S )NZfoobar)r)   reprpickledumps)er+   r+   r-   test_joblib_exceptionS  s    r;  c               	   C   sN   t t} tt | dd W 5 Q R X t t}tt |d W 5 Q R X d S )Nr   r   r:   )r   r<   r   r   rS   r*   )Zsafe_divisionZsafe_interruptr+   r+   r-   test_safe_function\  s    

r<  r   gQ?c              	   C   s"   t t t| d W 5 Q R X d S )Nr   )r   rN   r    r=  r+   r+   r-   test_invalid_batch_sizef  s    
r>  z)n_tasks, n_jobs, pre_dispatch, batch_size)r>   r>   r   r   )r>   r>   r[   r   )r   r>   r[   r   )i  r>   r[   r   )r   r|   r[   r   )   r   r[   r   )   r   
2 * n_jobsr   )   r   r   r   )rB  r   rA  rM   )r?  r   rA  r   c                 C   sJ   |||d}dd t | D }tf |dd t | D }||ksFtd S )N)r[   r   r   c                 S   s   g | ]}t |qS r+   rr   r]   r+   r+   r-   r.   ~  s     z0test_dispatch_race_condition.<locals>.<listcomp>c                 s   s   | ]}t t|V  qd S r9   r\   r]   r+   r+   r-   r_     s     z/test_dispatch_race_condition.<locals>.<genexpr>ru   )Zn_tasksr[   r   r   paramsr   r   r+   r+   r-   test_dispatch_race_conditionl  s    rD  c                  C   s8   t  } tddd}|jd}| }|| ks4td S )Nr>   r/   rZ   context)r   get_start_methodr    Z_backend_argsgetre   )Zmp_start_methodr   rE  Zstart_methodr+   r+   r-   test_default_mp_context  s
    rH  c                    s^   | dkrt d} tjd}|dd t  j td| d fddt	dD  d S )	Nr/   r3   r  i  r>   rZ   c                 3   s    | ]}t tj  jV  qd S r9   )r!   r   dotTr]   rC   r+   r-   r_     s    zAtest_no_blas_crash_or_freeze_with_subprocesses.<locals>.<genexpr>)
r   r2   r   randomZRandomStaterandnrI  rJ  r    rb   )r7   rngr+   rK  r-   .test_no_blas_crash_or_freeze_with_subprocesses  s    
rO  a  from joblib import Parallel, delayed

def square(x):
    return x ** 2

backend = "{}"
if backend == "spawn":
    from multiprocessing import get_context
    backend = get_context(backend)

print(Parallel(n_jobs=2, backend=backend)(
      delayed(square)(i) for i in range(5)))
c                 C   sB   | dkrt  dkrtd t| }ttjd|gddd d S )Nr/   forkzVRequire fork start method to use interactively defined functions with multiprocessing.z-cr   \[0, 1, 4, 9, 16\]r   stdout_regex)	r   rF  pytestskip,UNPICKLABLE_CALLABLE_SCRIPT_TEMPLATE_NO_MAINformatr   sys
executable)r7   coder+   r+   r-   2test_parallel_with_interactively_defined_functions  s    


 r[  a  import sys
# Make sure that joblib is importable in the subprocess launching this
# script. This is needed in case we run the tests from the joblib root
# folder without having installed joblib
sys.path.insert(0, {joblib_root_folder!r})

from joblib import Parallel, delayed

def run(f, x):
    return f(x)

{define_func}

if __name__ == "__main__":
    backend = "{backend}"
    if backend == "spawn":
        from multiprocessing import get_context
        backend = get_context(backend)

    callable_position = "{callable_position}"
    if callable_position == "delayed":
        print(Parallel(n_jobs=2, backend=backend)(
                delayed(square)(i) for i in range(5)))
    elif callable_position == "args":
        print(Parallel(n_jobs=2, backend=backend)(
                delayed(run)(square, i) for i in range(5)))
    else:
        print(Parallel(n_jobs=2, backend=backend)(
                delayed(run)(f=square, x=i) for i in range(5)))
z!def square(x):
    return x ** 2
zcdef gen_square():
    def square(x):
        return x ** 2
    return square
square = gen_square()
zsquare = lambda x: x ** 2
define_funccallable_positionr!   r   kwargsc              	   C   sv   | dkr$|t kstjdkr$td tj|| |tj	tj	t
jd}|d}|| ttj|jgddd d S )	N)r/   r3   win32zNot picklable with pickle)r\  r7   r]  joblib_root_folderzunpicklable_func_script.pyr   rQ  rR  )SQUARE_MAINrX  platformrT  rU  )UNPICKLABLE_CALLABLE_SCRIPT_TEMPLATE_MAINrW  r  pathdirnamejoblib__file__r   writer   rY  strpath)r7   r\  r]  tmpdirrZ  Z	code_filer+   r+   r-   0test_parallel_with_unpicklable_functions_in_args  s&    
 


 rk  a  import sys
import faulthandler
# Make sure that joblib is importable in the subprocess launching this
# script. This is needed in case we run the tests from the joblib root
# folder without having installed joblib
sys.path.insert(0, {joblib_root_folder!r})

from joblib import Parallel, delayed
from functools import partial

class MyClass:
    '''Class defined in the __main__ namespace'''
    def __init__(self, value):
        self.value = value


def square(x, ignored=None, ignored2=None):
    '''Function defined in the __main__ namespace'''
    return x.value ** 2


square2 = partial(square, ignored2='something')

# Here, we do not need the `if __name__ == "__main__":` safeguard when
# using the default `loky` backend (even on Windows).

# To make debugging easier
faulthandler.dump_traceback_later(30, exit=True)

# The following baroque function call is meant to check that joblib
# introspection rightfully uses cloudpickle instead of the (faster) pickle
# module of the standard library when necessary. In particular cloudpickle is
# necessary for functions and instances of classes interactively defined in the
# __main__ module.

print(Parallel(n_jobs=2)(
    delayed(square2)(MyClass(i), ignored=[dict(a=MyClass(1))])
    for i in range(5)
))
)r`  c                 C   s.   |  d}|t ttj|jgdd d d S )Nz(joblib_interactively_defined_function.pyrQ  )rS  r   )r   rh  5INTERACTIVE_DEFINED_FUNCTION_AND_CLASS_SCRIPT_CONTENTr   rX  rY  ri  rj  scriptr+   r+   r-   Btest_parallel_with_interactively_defined_functions_default_backend4  s    


ro  au  import sys
# Make sure that joblib is importable in the subprocess launching this
# script. This is needed in case we run the tests from the joblib root
# folder without having installed joblib
sys.path.insert(0, {joblib_root_folder!r})

from joblib import Parallel, delayed, hash
import multiprocessing as mp
mp.util.log_to_stderr(5)

class MyList(list):
    '''MyList is interactively defined by MyList.append is a built-in'''
    def __hash__(self):
        # XXX: workaround limitation in cloudpickle
        return hash(self).__hash__()

l = MyList()

print(Parallel(n_jobs=2)(
    delayed(l.append)(i) for i in range(3)
))
c                 C   s0   |  d}|t ttj|jgdddd d S )Nz)joblib_interactive_bound_method_script.pyz\[None, None, None\]ZLokyProcess   )rS  Zstderr_regexr   )r   rh  9INTERACTIVELY_DEFINED_SUBCLASS_WITH_METHOD_SCRIPT_CONTENTr   rX  rY  ri  rm  r+   r+   r-   5test_parallel_with_interactively_defined_bound_method]  s    

rr  c                  C   s"   t g } tdd| g kstd S )Nr>   ri   )iterr    re   )Zexhausted_iteratorr+   r+   r-   %test_parallel_with_exhausted_iteratorg  s    rt  c                 C   s"   t | tjstdt| |  S )Nz#Expected np.memmap instance, got %r)r   r   memmap	TypeErrorrW   copyrK  r+   r+   r-   check_memmapl  s
    rx  c                 C   s   dd }t dd| ddd |dD }t||t|D ]\}}tj|| q:t d	d| dd
d |dD }t||t|D ]\}}tj|| qd S )Nc                 s   s(   t | D ]}tjdtjd| V  qd S )Nr   Zdtype)rb   r   onesZfloat32)r3  r^   r+   r+   r-   generate_arrays{  s    zBtest_auto_memmap_on_arrays_from_generator.<locals>.generate_arraysr>   r   r[   
max_nbytesr7   c                 s   s   | ]}t t|V  qd S r9   r!   rx  r,   rC   r+   r+   r-   r_     s    z<test_auto_memmap_on_arrays_from_generator.<locals>.<genexpr>rq   r|   c                 s   s   | ]}t t|V  qd S r9   r~  r  r+   r+   r-   r_     s    )r    r   r   r   testingassert_array_equal)r7   r{  r   resultr   r+   r+   r-   )test_auto_memmap_on_arrays_from_generators  s    r  c                 C   s   | S r9   r+   )argr+   r+   r-   identity  s    r  c                    s   |  dj}tj}tj|ddtj|ddg}t|| t|dd t	dd fdd	d
D \}t
 d tjsvt d j|ksttj|| d S )Nz	test.mmapuint8ry  r)Z	mmap_moder>   ri   c                 3   s   | ]}t t V  qd S r9   )r!   r  r   ru  r+   r-   r_     s     z.test_memmap_with_big_offset.<locals>.<genexpr>)r   r   )r   ri  mmapZALLOCATIONGRANULARITYr   zerosrz  r   r   r    r   ru  re   offsetr  r  )rj  fnamesizeobjr  r+   r  r-   test_memmap_with_big_offset  s    
r  c               	   C   sr   t jdd"} tdddd tdD  W 5 Q R X t| dksDt| d }t|jts\tt	|jd	ksntd S )
NTrz   r   )r   c                 s   s   | ]}t t|V  qd S r9   r\   r]   r+   r+   r-   r_     s     zFtest_warning_about_timeout_not_supported_by_backend.<locals>.<genexpr>2   r   zThe backend class 'SequentialBackend' does not support timeout. You have set 'timeout=1' in Parallel but the 'timeout' parameter will not be used.)
r   r   r    rb   r   re   r   r~   r  r}   )r   r   r+   r+   r-   3test_warning_about_timeout_not_supported_by_backend  s    &r  c              	   C   sb   dgdgd  }t t( t }t| |ddd |D  W 5 Q R X t | }|dk s^td S )NrC   r   rq   rZ   c                 s   s   | ]}t tj|V  qd S r9   r!   rQ   r   r]   r+   r+   r-   r_     s    z%test_abort_backend.<locals>.<genexpr>   )r   rv  rQ   r    re   )r[   r7   ZdelaysZt_startdtr+   r+   r-   test_abort_backend  s    
r  c              	   C   s   |j }tdd| |d<}|dd tjdgd D  tt|dksNtW 5 Q R X tdD ]}t|sr qt	d	 q`td
tdd| d}|dd tjdgd D  tdD ]}t|s qt	d	 qtd
d S )Nr>   r   )r[   r}  r7   Ztemp_folderc                 s   s   | ]}t t|V  qd S r9   r~  r  r+   r+   r-   r_     s     z(test_memmapping_leaks.<locals>.<genexpr>r   r   rq   r   z/temporary directory of Parallel was not removedr|  c                 s   s   | ]}t t|V  qd S r9   r~  r  r+   r+   r-   r_     s     )
ri  r    r   rL  r   r  listdirre   rb   r   )r7   rj  r   r   r+   r+   r-   test_memmapping_leaks  s&      

 

r  c                 C   s<   t d| ddd tdD }|dd tdD ks8td S )Nr>   rZ   c                 s   s   | ]}t d d |V  qdS )c                 S   s   | d S r=   r+   r?   r+   r+   r-   <lambda>      z2test_lambda_expression.<locals>.<genexpr>.<lambda>Nr&  r]   r+   r+   r-   r_     s    z)test_lambda_expression.<locals>.<genexpr>r   c                 S   s   g | ]}|d  qS )r>   r+   r]   r+   r+   r-   r.     s     z*test_lambda_expression.<locals>.<listcomp>)r    rb   re   )r7   r   r+   r+   r-   test_lambda_expression  s    r  c                    s   d}d}d|  t d|| d}| fddt|D  |jj|jjksLt|jj|jjks`t| fddt|D  |jj|jjkst|jj|jjkstd	S )
zCTest that a parallel backend correctly resets its batch statistics.r>   i  g       @r   )ro   r[   r7   c                 3   s   | ]}t tj V  qd S r9   r  r]   Z	task_timer+   r-   r_     s     z6test_backend_batch_statistics_reset.<locals>.<genexpr>c                 3   s   | ]}t tj V  qd S r9   r  r]   r  r+   r-   r_     s     N)r    rb   r   Z_effective_batch_sizeZ_DEFAULT_EFFECTIVE_BATCH_SIZEre   Z_smoothed_batch_durationZ _DEFAULT_SMOOTHED_BATCH_DURATION)r7   r[   Zn_inputsr   r+   r  r-   #test_backend_batch_statistics_reset  s$    r  c               	   C   s  dD ]v} t t| djtks tt| dd}t |jtks>tt| dd}t |jtks\tt| dd}t |jtkstqtdd	dd
}t |jtksttd	dd0 tdd}t |jtkst|jdkstW 5 Q R X td	dd6 tddd}t |jtkst|jdkstW 5 Q R X td	dd4 tdd}t |jtksRt|jdksbtW 5 Q R X td	dd6 tddd}t |jtkst|jdkstW 5 Q R X d S )N)r   r>   rh   ri   threadsr[   prefer	processes	sharedmemr[   requirer>   r0   )r[   r7   r  r  r`   r  r   )rW   r    r   r   re   r   r#   r[   )r[   r   r+   r+   r-   $test_backend_hinting_and_constraints  s4    

r  c              	   C   s@  G dd dt }t| B tddd}t|j|ks:ttddd}t|j|ksXtW 5 Q R X G dd	 d	t }t|  tddd}t|j|kst|  \}}|d
kst|d
ksttdddd}t|jtkst|  \}}d}| |kst|d
kstW 5 Q R X t	t
 t| dd W 5 Q R X d S )Nc                   @   s$   e Zd ZdZdZdd Zdd ZdS )z[test_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomThreadingBackendTc                 S   s   d S r9   r+   r   r+   r+   r-   apply_async5  s    zgtest_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomThreadingBackend.apply_asyncc                 S   s   |S r9   r+   r  r+   r+   r-   r$   8  s    zltest_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomThreadingBackend.effective_n_jobsNrI   rJ   rK   Zsupports_sharedmemZuse_threadsr  r$   r+   r+   r+   r-   MyCustomThreadingBackend1  s   r  r>   r  r  r  r  c                   @   s$   e Zd ZdZdZdd Zdd ZdS )z\test_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomProcessingBackendFc                 S   s   d S r9   r+   r   r+   r+   r-   r  F  s    zhtest_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomProcessingBackend.apply_asyncc                 S   s   |S r9   r+   r  r+   r+   r-   r$   I  s    zmtest_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomProcessingBackend.effective_n_jobsNr  r+   r+   r+   r-   MyCustomProcessingBackendB  s   r  r   r   )r[   r  ro   zUsing ThreadingBackend as joblib.Parallel backend instead of MyCustomProcessingBackend as the latter does not provide shared memory semantics.r7   r  )r   r#   r    rW   r   re   Z
readouterrr   stripr   rN   )Zcapsysr  r   r  outerrr   r+   r+   r-   9test_backend_hinting_and_constraints_with_custom_backends.  s*    


r  c                	   C   s   t t tdd W 5 Q R X t t tdd W 5 Q R X t t tddd W 5 Q R X td k	rt t tddd W 5 Q R X t t td	dd W 5 Q R X d S )
Ninvalidr  r  r  r  )r  r  r0   r  r/   )r   rN   r    r   r+   r+   r+   r-   ,test_invalid_backend_hinting_and_constraintsb  s    




r  c                  C   sF   t  j} td}tt  jts"t|  tt  jt| ksBtd S )Nr1   )r    r   r#   r   r   re   
unregisterrW   )defaultZpbr+   r+   r-   test_global_parallel_backendw  s
    r  c               	   C   s:   dd } | t d< td tt jts,tW 5 Q R X d S )Nc                   S   s   t td< d S )Nfoo)r   r&   r+   r+   r+   r-   register_foo  s    z,test_external_backends.<locals>.register_foor  )r(   r#   r   r    r   r   re   )r  r+   r+   r-   test_external_backends  s    
r  c              
      sx   t ddd}t|jj|jjfg}dkr:|W  5 Q R  S | fddtdD }||d  W  5 Q R  S Q R X dS )zCPerform nested parallel calls and introspect the backend on the wayr>   ri   r   c                 3   s(   | ] }t tf d d i V  qdS )limitr   N)r!   _recursive_backend_infor]   r^  r  r+   r-   r_     s   z*_recursive_backend_info.<locals>.<genexpr>r   N)r    rW   r   rI   r)  rb   )r  r^  r   Z
this_levelr   r+   r  r-   r    s    r  c              	   C   sr   t | dd t }W 5 Q R X t dkr2d}d}nd}d}|  d }|df|dfd|fd|fg}||ksntd S )Nr>   ri   r   r   r   ZBackendr   )r#   r  r%   titlere   )r7   backend_types_and_levelsZsecond_level_backend_typeZ	max_levelZtop_level_backend_typeZexpected_types_and_levelsr+   r+   r-   test_nested_parallelism_limit  s    
r  zThis test requires daskc               
   C   s   t jddd} tjtdtjd}tdD ]H}td t|d}W 5 Q R X t	|dks\t
tdd	 |D s*t
q*td t }W 5 Q R X t	|dkst
td
d	 |D st
d S )Nr>   )Z	n_workersZthreads_per_workerg    cAry  dask)datar|   c                 s   s   | ]\}}|d kV  qdS ZDaskDistributedBackendNr+   r,   rw   r   r+   r+   r-   r_     s   z4test_nested_parallelism_with_dask.<locals>.<genexpr>c                 s   s   | ]\}}|d kV  qdS r  r+   r  r+   r+   r-   r_     s   )distributedZClientr   rz  intr  rb   r#   r  r   re   r   )clientr  r^   r  r+   r+   r-   !test_nested_parallelism_with_dask  s    

r  c                 C   s   t  dd tdD S )z6A horrible function that does recursive parallel callsc                 s   s   | ]}t t V  qd S r9   )r!   _recursive_parallelr]   r+   r+   r-   r_     s     z&_recursive_parallel.<locals>.<genexpr>r>   ra   )Znesting_limitr+   r+   r-   r    s    r  c              
   C   st   t | dd  tt}t  W 5 Q R X W 5 Q R X |j}| dkrbddlm} t||rpt	d nt|t
sptd S )Nr>   ri   r0   r   )TerminatedWorkerErrorz1Loky worker crash when serializing RecursionError)r#   r   BaseExceptionr  ry   Z&joblib.externals.loky.process_executorr  r   rT  xfailRecursionErrorre   )r7   r   excr  r+   r+   r-   test_thread_bomb_mitigation  s    

r  c                  C   s*   i } dD ]}t j|| |< q| tdfS )N)OMP_NUM_THREADSOPENBLAS_NUM_THREADSMKL_NUM_THREADSZVECLIB_MAXIMUM_THREADSZNUMEXPR_NUM_THREADSZNUMBA_NUM_THREADS
ENABLE_IPCrq   )r  environrG  r   )Zenv_varsvarr+   r+   r-   _run_parallel_sum  s    r  zNeed OpenMP helper compiledc                 C   s   t d| ddd tdD }tt d d}|D ]Z\}}||ksFt| D ]<\}}|drr|t|kstqN|dks~t|dksNtqNq2d S )	Nr>   rZ   c                 s   s   | ]}t t V  qd S r9   )r!   r  r   r+   r+   r-   r_     s    z-test_parallel_thread_limit.<locals>.<genexpr>r   Z_THREADSr  1)r    rb   r   r%   re   itemsendswithr}   )r7   r   Zexpected_num_threadsZworker_env_varsZomp_num_threadsrw   ry   r+   r+   r-   test_parallel_thread_limit  s    
r  z%This test requires dask NOT installedc                	   C   s$   t tdd td W 5 Q R X d S )NzPlease install daskr   r  )r   rN   r#   r+   r+   r+   r-   )test_dask_backend_when_dask_not_installed  s    r  c               
   C   sd   G dd dt } d}t|  < tjt|d" tdddd tdD  W 5 Q R X W 5 Q R X d S )	Nc                   @   s&   e Zd Zdd ZdddZdd ZdS )	z3test_zero_worker_backend.<locals>.ZeroWorkerBackendc                 _   s   dS rV   r+   )rB   r   r^  r+   r+   r-   r     s    z=test_zero_worker_backend.<locals>.ZeroWorkerBackend.configureNc                 S   s   t dd S )NzNo worker availabler   )rB   funccallbackr+   r+   r-   r    s    z?test_zero_worker_backend.<locals>.ZeroWorkerBackend.apply_asyncc                 S   s   dS rV   r+   r  r+   r+   r-   r$     s    zDtest_zero_worker_backend.<locals>.ZeroWorkerBackend.effective_n_jobs)N)rI   rJ   rK   r   r  r$   r+   r+   r+   r-   ZeroWorkerBackend  s   
r  z&ZeroWorkerBackend has no active workerr   r>   ri   c                 s   s   | ]}t t|V  qd S r9   r   r]   r+   r+   r-   r_     s     z+test_zero_worker_backend.<locals>.<genexpr>)r   r#   rT  r   r   r    rb   )r  Zexpected_msgr+   r+   r-   test_zero_worker_backend  s
    
r  c                     s   da dd    dksttdd fddtdD } t| dhksLtda   dks^ttdd fd	dtdD } t| dhkstd S )
Nzoriginal valuec                   S   s   t S r9   )MY_GLOBAL_VARIABLEr+   r+   r+   r-   check_globals  s    z@test_globals_update_at_each_parallel_call.<locals>.check_globalsr>   ri   c                 3   s   | ]}t   V  qd S r9   r&  r]   r  r+   r-   r_   %  s    z<test_globals_update_at_each_parallel_call.<locals>.<genexpr>zchanged valuec                 3   s   | ]}t   V  qd S r9   r&  r]   r  r+   r-   r_   .  s    )r  re   r    rb   r#  )Zworkers_global_variabler+   r  r-   )test_globals_update_at_each_parallel_call  s    r  c                  C   s4   dd l } | jdd}| || ddlm} | S )Nr   rq   )threadpool_info)ZnumpyrL  rM  rI  Zthreadpoolctlr  )r   rC   r  r+   r+   r-   _check_numpy_threadpool_limits8  s
    r  c                 C   s8   |D ] }|d | d kr|d   S qt d| d S )Nfilepathnum_threadsz,An unexpected module was loaded in child:
{})rN   rW  )child_moduleparent_infoparent_moduler+   r+   r-   _parent_max_num_threads_forC  s    r  c                 C   s@   | D ]6}|D ],}t ||}t|||h}|d |kstqqd S )Nr  )r  minre   )Zworkers_infor  r  Zchild_threadpool_infor  Zparent_max_num_threadsr   r+   r+   r-   check_child_num_threadsK  s     r  c                 C   sb   t  }t|dkrtjdd t| ddd tdD }t| } tt |  d}t	||| d S )	Nr   &Need a version of numpy linked to BLASmsgri   c                 s   s   | ]}t t V  qd S r9   r!   r  r]   r+   r+   r-   r_   c  s    z6test_threadpool_limitation_in_child.<locals>.<genexpr>r>   r   )
r  r   rT  rU  r    rb   r$   r   r%   r  )r[   r  workers_threadpool_infosexpected_child_num_threadsr+   r+   r-   #test_threadpool_limitation_in_childW  s    r  inner_max_num_threadsc              	   C   s   t  }t|dkrtjdd td|d" t| ddd td	D }W 5 Q R X t| } |d krttt	 |  d
}n|}t
||| d S )Nr   r  r  r0   r  ri   c                 s   s   | ]}t t V  qd S r9   r  r]   r+   r+   r-   r_   {  s    z>test_threadpool_limitation_in_child_context.<locals>.<genexpr>r>   r   )r  r   rT  rU  r#   r    rb   r$   r   r%   r  )r[   r  r  r  r  r+   r+   r-   +test_threadpool_limitation_in_child_contextm  s    	r  var_namer  r  r  c              	      s   t dd  dd  tj}zdtj< t| d fddtd	D }|ddgks`ttd
dd( t| d fddtd	D }W 5 Q R X |ddgkstW 5 |d krtj= n
|tj< X d S )NTZreusec                 S   s   t j| S r9   )r  r  rG  )r  r+   r+   r-   _get_env  s    z>test_threadpool_limitation_in_child_override.<locals>._get_env4ri   c                 3   s   | ]}t  V  qd S r9   r&  r]   r  r  r+   r-   r_     s    z?test_threadpool_limitation_in_child_override.<locals>.<genexpr>r>   r0   r   r  c                 3   s   | ]}t  V  qd S r9   r&  r]   r  r+   r-   r_     s    r  )	r   shutdownr  r  rG  r    rb   re   r#   )r[   r  Zoriginal_var_valuer   r+   r  r-   ,test_threadpool_limitation_in_child_override  s"    

r  c              	   C   s(   t tdd t| dd W 5 Q R X d S )Nz#does not acc.*inner_max_num_threadsr   r   r  )r   re   r#   r6   r+   r+   r-   1test_threadpool_limitation_in_child_context_error  s    r  c                 C   sJ   dd }||  t dd}tdD ]"}||  t dd}||ks"tq"d S )Nc                    s,   t d t| d fddt dD  d S )Nr   ri   c                 3   s   | ]}t t V  qd S r9   )r!   sumr]   r?   r+   r-   r_     s     zAtest_loky_reuse_workers.<locals>.parallel_call.<locals>.<genexpr>)rb   r    ri   r+   r?   r-   parallel_call  s    z.test_loky_reuse_workers.<locals>.parallel_callTr  r   )r   rb   re   )r[   r  Zfirst_executorr   executorr+   r+   r-   test_loky_reuse_workers  s    

r   )F)r   r   )r`   )N)rL   r  rX  rQ   r  r   r1   	tracebackr   mathr   r   r8  r   r/   r   rT  rf  r
   r   r   Zjoblib._multiprocessing_helpersr   Zjoblib.test.commonr   r   r   Zjoblib.testingr   r   r   r   r   Zjoblib.externals.lokyr   r   r   posixImportErrorZ _openmp_test_helper.parallel_sumr   r  Zjoblib._parallel_backendsr   r   r   r   r   r   Zjoblib.parallelr    r!   r"   r#   r$   r%   r&   r'   r(   Zjoblib.my_exceptionsr)   r*   sortedkeysZALL_VALID_BACKENDSZPROCESS_BACKENDSZPARALLEL_BACKENDShasattrr   r2   r  r8   r<   r@   r   rA   rP   rS   rU   rY   rd   rf   rg   markrm   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r  r  r  r  r  r  r  extendrb   r  r  r  r  r  r  Z_parallel_backendsr  r$  r(  r+  r/  r6  r;  r<  r>  rD  rH  rO  rV  r[  rc  ra  ZSQUARE_LOCALZSQUARE_LAMBDArk  rW  rd  re  rg  rl  ro  rq  rr  rt  rx  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r+   r+   r+   r-   <module>   s  











I              


	

	


	



 (,

	
#.4

	!
 