U
    Nvf                    @   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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m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 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
rL   dZ*Y nX zddl,m-Z- W n e+k
rx   dZ-Y nX zddl.Z.W n e+k
r   dZ.Y nX ddl/m0Z0 ddl/m1Z1 ddl/m2Z2 ddl/m3Z3 ddl/m4Z4 ddl5m6Z6m7Z7 ddl5m8Z8 ddl5m9Z9 ddl5m:Z: ddl5m;Z;m<Z< ddl5mZm=Z=m>Z> e=? Z@e@Add dgeBe=C  ZDeDd d! e=D 7 ZDedkr~g ZEndd"gZEeEd#g ZFeGed$reDHeId% e=e> ZJd&d' ZKd(d) ZLd*d+ ZMG d,d- d-eNZOdMd/d0ZPd1d2 ZQdNd3d4ZRd5d6 ZSd7d8 ZTd9d: ZUd;d< ZVe!d=e8e9gejWj!d>d?d@e;d@dAfdBgdCdDdEgdFedGdH ZXe!dIeDe!dJddKd@dLge!dMdKdNdOgdPdQ ZYe!dIeDdRdS ZZdTdU Z[ee!dVdWdXdYdZd[d\gd]d^ Z\ee!dId"dd#gd_d` Z]dadb Z^e!dce=e!dde=dedf Z_dgdh Z`edidj Zadkdl Zbe!dJddKdmgdndo Zce!dIeFdpdq Zdedrds Zee!dIeFdtdu Zfee!dIeFdvdw Zgee!dIeEdxdy Zhdzd{ Zie!dIe=e!d|dd}d~ddddddddddgfdd}dddd~dddddddgfgdd Zjee!dIeFdd Zkdd Zlee!dIeEdd Zmdd Zndd Zodd Zpee!dIeFejWjqdddd ZrG dd de0Zsdd Zte!dIeDdd Zudd Zvdd Zwe$edk	dddd Zxdd ZyeFdd Zzez{dd! e|dmD  ee!dIeze!d=e9e8gdd Z}G dd de0Z~e!d=e8e9gdd Ze!d=e8e9gdd Zdd Zdd ZG dd dejj4Ze:de ee!dId#d"ddge!d=e8e9gdd Zee!dJdKd@dge!dIeFe!d=e8e9gdd Zdd Zee!deFe!deFe!d=e8e9gddĄ Zee!d=e8e9ge!ddd.gddȄ Ze!ddd@dgdd̄ Ze!ddddddddddddgddل Zeddۄ Zeee!dIeEdd݄ ZdZee!dIeEdd ZdZdZdZdZee!dIeEedkrg nd%g e!deeege!ddddgdd ZdjejejejdZedd ZdjejejejdZedd Zdd Zdd Zdd Zeee!dIeEdd Zdd Zeedd Zdd  Zdd ZejW!dJddKdgdd Ze!dIeDe!dJddKdLd@gdd Zdd Zee!dIe@e!dJddKdLd@gd	d
 Ze!dIe@e!dJddKdLd@gdd Ze!dIe@e!dJddKdLd@gdd Ze!dIe@e!dJddKdLd@gdd Ze!ddddgdd Zeee!dIeEdd Ze!dIedk
rdd#gndd"d#gdd Zee!dIeEdd Zee!d=e8e9gdd Ze!d=e8e9gdd  Zd!d" ZdOd#d$Zee!dId"d#ge!d=e8e9gd%d& Zee$e.dkd'de!d=e8e9gd(d) ZdPd*d+ZejWje!d=e8e9ge!dIedkr.d#gnd"d#gd,d- Zd.d/ Ze!dIedk	rjdd"gndge$e-dkd0dd1d2 Ze$e.dk	d3de!d=e8e9gd4d5 Ze!d=e8e9gd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zeee!dJdKddLd@gd@dA Zeee!dBddKddge!dJdKd@ge!d=e8e9gdCdD Zee!dJdKd@ge!dEdFdGdHge!d=e8e9gdIdJ Zee!dJdKdd@gdKdL ZdS (Q  z
Test the parallel module.
    N)format_exceptionsqrt)sleep)PicklingError)nullcontextTimeoutErrorparallel)dumpload)mp)np
with_numpy)with_multiprocessing)IS_PYPYforce_gc_pypy)parametrizeraisescheck_subprocess_callskipifwarns)get_reusable_executor)Queue   )parallel_sum)SequentialBackend)ThreadingBackend)MultiprocessingBackend)ParallelBackendBase)LokyBackend)Paralleldelayed)parallel_config)parallel_backend)register_parallel_backend)effective_n_jobs	cpu_count)r   BACKENDSDEFAULT_BACKENDmultiprocessingc                 C   s   g | ]}t |  qS  )r)   ).0Zbackend_strr,   r,   =/tmp/pip-unpacked-wheel-dylwa62s/joblib/test/test_parallel.py
<listcomp>M   s     r/   loky	threadingget_contextspawnc                 C   s   t | dt | dd S )N_poolZ_workers)getattrbackendr,   r,   r.   get_workers[   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.   squarec   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__j   s    z#MyExceptionWithFinickyInit.__init__N__name__
__module____qualname____doc__rG   r,   r,   r,   r.   rA   g   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_raisern   s    rP   c                 C   s   t d td S )Ng?)timer   KeyboardInterruptr?   r,   r,   r.   interrupt_raiseru   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.   fz   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    rh   contextzbackend_n_jobs, expected_n_jobs)r`   r`   r[   Nr   zpositive-intznegative-intNone)idsc              	   C   s@   | d|d t d d|ks tW 5 Q R X t d ddks<td S )Nr1   rk   r   rg   )ri   Zbackend_n_jobsZexpected_n_jobsr,   r,   r.   test_effective_n_jobs_None   s    
ro   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   rq   c                 s   s   | ]}t t|V  qd S r9   r\   ru   r,   r,   r.   r_      s    z'test_simple_parallel.<locals>.<genexpr>rb   r"   re   )r7   r[   rq   r,   r,   r.   test_simple_parallel   s    rx   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)targetry   valueTrecordr>   rZ   c                 s   s   | ]}t t|V  qd S r9   r\   ru   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   s   t jdd}t d t| |d W 5 Q R X dd |D }|r|rtdd |D }ttjd	d
rpt|dkn
t|dk}|o|S d
S |rt	dS d S )NTr|   always)r7   rc   c                 S   s   g | ]
}|j qS r,   )r   r   r,   r,   r.   r/      s     z*_assert_warning_nested.<locals>.<listcomp>c                 s   s   | ]}d |j d kV  qdS )zbacked parallel loops cannotr   N)args)r-   Zeachr,   r,   r.   r_      s   z)_assert_warning_nested.<locals>.<genexpr>ZnogilFr   )
r   r   simplefilterrd   allr5   sysflagsr   re   )r7   rc   expectedr   Zwarnings_are_correctZwarnings_have_the_right_lengthr,   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                    s   t d| d fddtdD  t d| d fddtdD }| dkrttrft|sftjdd	 t|stnt|st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>rv   c                 3   s    | ]}t t d dV  qdS )r>   r   Nr   r   r   r   r,   r.   r_      s    r1   zThis test often fails in PyPy.reason)r"   rb   r   anypytestxfailre   r   )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 )	NTr|   r>   rk   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)rz   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 backendrv   )maxsizer>   r1   rZ   c                 3   s   | ]}t  jd V  qdS r   N)r#   putr   qr,   r.   r_   4  s    z1test_mutate_input_with_threads.<locals>.<genexpr>N)r   r"   rb   fullre   r,   r,   r   r.   test_mutate_input_with_threads1  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   ru   r,   r,   r.   r/   =  s     z(test_parallel_kwargs.<locals>.<listcomp>rk   c                 s   s   | ]}t t|d dV  qdS r   r   Nr#   rU   ru   r,   r,   r.   r_   >  s     z'test_parallel_kwargs.<locals>.<genexpr>Nrw   )r[   lstr,   r,   r.   test_parallel_kwargs9  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   ru   r,   r,   r.   r/   D  s     z4test_parallel_as_context_manager.<locals>.<listcomp>r~   rZ   c                 s   s   | ]}t t|d dV  qdS r   r   ru   r,   r,   r.   r_   M  s     z3test_parallel_as_context_manager.<locals>.<genexpr>c                 s   s   | ]}t t|d dV  qdS r   r   ru   r,   r,   r.   r_   N  s     c                 s   s   | ]}t t|d dV  qdS r   r   ru   r,   r,   r.   r_   Z  s     )rb   r"   _backendre   r   r8   )r7   r   r   pZmanaged_backendr,   r,   r.    test_parallel_as_context_managerA  s     r   c                	      sN   G dd dt  ttdd( td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__e  s    z<test_parallel_pickling.<locals>.UnpicklableObject.__reduce__N)rI   rJ   rK   r   r,   r,   r,   r.   UnpicklableObjectd  s   r   zthe task to sendmatchr>   r0   rZ   c                 3   s   | ]}t t  V  qd S r9   r#   idr   r   r,   r.   r_   i  s   z)test_parallel_pickling.<locals>.<genexpr>r   N)objectr   r   r"   rb   r,   r,   r   r.   test_parallel_pickling_  s
    r   c                 C   s0   t td| dddd tdD dks,td S )Nr>      r[   r7   timeoutc                 s   s   | ]}t td V  qdS )gMbP?Nr   ru   r,   r,   r.   r_   p  s    z0test_parallel_timeout_success.<locals>.<genexpr>r   )r   r"   rb   re   r6   r,   r,   r.   test_parallel_timeout_successm  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   ru   r,   r,   r.   r_   y  s    z-test_parallel_timeout_fail.<locals>.<genexpr>r   )r   r	   r"   rb   r6   r,   r,   r.   test_parallel_timeout_failt  s    
r   c              
   C   sd  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|j
|j|j|jf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 d S )Nr>   rZ   c                 S   s   g | ]\}}t t||qS r,   r#   r<   r-   r:   r;   r,   r,   r.   r/     s   z&test_error_capture.<locals>.<listcomp>)r   r   )r   r   c                 S   s   g | ]}t t|qS r,   r#   rS   ru   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   ru   r,   r,   r.   r/     s     r   c                 s   s   | ]}t t|d dV  qdS r   r   ru   r,   r,   r.   r_     s     z%test_error_capture.<locals>.<genexpr>c                 S   s   g | ]}t t|qS r,   r   ru   r,   r,   r.   r/     s     c                 S   s   g | ]}t |d dqS r   r   ru   r,   r,   r.   r/     s     c                 s   s   | ]}t t|d dV  qdS r   r   ru   r,   r,   r.   r_     s     rk   c                 S   s   g | ]}t t|qS r,   r   ru   r,   r,   r.   r/     s     c                 S   s   g | ]\}}t t||qS r,   r   r   r,   r,   r.   r/     s     r   )r[   rq   c                 s   s   | ]}t t|d dV  qdS )T)rO   Nr#   rP   r]   r,   r,   r.   r_     s   r   )r   r   ZeroDivisionErrorr"   ziprR   r8   r   re   rb   
_iteratingZn_completed_tasksZn_dispatched_tasks	_abortingrA   )r7   r   Zoriginal_workersr,   r,   r.   test_error_capture}  sh    









  



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   ru   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 anyrj   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   rq   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>   rk   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>   rk   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/255r   c              	   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_   4  s    z1test_nested_exception_dispatch.<locals>.<genexpr>r    r   r   rP   N)
r   rN   r"   rb   r   rW   r{   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.   	configureE  s    zFakeParallelBackend.configurec                 C   s"   |dk rt t d | d}|S )Nr   r   )maxr   r(   rB   r[   r,   r,   r.   r'   J  s    z$FakeParallelBackend.effective_n_jobs)r   N)r   )rI   rJ   rK   rL   r  r'   r,   r,   r,   r.   r  B  s   
r  c                
   C   s   t tdd tdd W 5 Q R X t tdd tdd W 5 Q R X W 5 Q R X t tdd tdd W 5 Q R X W 5 Q R X d S )NzInvalid backend:r   zunit-testingr6   )r   rN   r"   r$   r,   r,   r,   r.   test_invalid_backendP  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   r{   re   )r7   r  r,   r,   r.   test_invalid_njobs]  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_backendd  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_backendm  s    
r  zOnly without multiprocessingc                	   C   sf   t tdd" tdddd tdD  W 5 Q R X td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_   }  s     z2test_backend_no_multiprocessing.<locals>.<genexpr>r`   c                 s   s   | ]}t t|V  qd S r9   r\   r]   r,   r,   r.   r_     s     )r   UserWarningr"   rb   r$   r,   r,   r,   r.   test_backend_no_multiprocessingy  s    &r  c              	   C   s  | |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`   rk   r+   r0   r1   Ztest_)r   rX   re   r'   r"   r[   rW   r   r   r!   r   
startswithr  )ri   backend_nameactive_backendactive_n_jobsr   r,   r,   r.   check_backend_context_manager  s$    
r  c                 C   s   g | ]}d | qS )ztest_backend_%dr,   r]   r,   r,   r.   r/     s     c                    sl   |t kr| t |t t tks$tt | t tks<ttddd fddtD  t tkshtd S )Nr>   r1   rZ   c                 3   s    | ]}|st t |V  qd S r9   )r#   r  )r-   rD   ri   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   ri   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|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>rv   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   rX   rW   r  r"   r[   r   rb   )r   ri   r  r  r   r   r,   r,   r.   *test_parameterized_backend_context_manager  s     r  c              	   C   s   t  tks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  rv   rk   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   rX   rW   r  r"   r[   r   rb   )ri   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>   rk   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 dddd tdD }|D ]}tt|dks*tq*W 5 Q R X d S )Nr>   rk   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"   rb   r   setre   )ri   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  | 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   rk   c                 3   s   | ]}t  td V  qdS r   )r#   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   ra   )r7   r[   ri   r,   r/  r.   !test_nested_backend_in_sequential  s    
r0  c              	   C   sF   | |4}| t kr|d }| tkr*|d }|j|ks8tW 5 Q R X d S )Nr7   r   )r$   r%   nesting_levelre   )ri   inner_backendZexpected_levelctxr7   r,   r,   r.   check_nesting_level2  s    
r4  outer_backendr2  c              	      sj   t  |d td|d fddtdD   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#   r4  r   ri   r2  r,   r.   r_   C  s   z-test_backend_nesting_level.<locals>.<genexpr>r   rk   c                 3   s   | ]}t t d V  qdS r   r6  r   r7  r,   r.   r_   I  s   )r4  r"   rb   )ri   r5  r2  r,   r7  r.   test_backend_nesting_level;  s    r8  with_retrieve_callbackTc              	      s   dd l  G  fdddt}td| dd | dZ}tddfd	d
tdD  | tkrt|d jdkstt| tkr|d jdkstW 5 Q R X d S )Nr   c                       s"   e Zd ZdZZ jdd ZdS )z)test_retrieval_context.<locals>.MyBackendr   c                 s   s   |  j d7  _ d V  d S rl   r   r   r,   r,   r.   retrieval_contextW  s    z;test_retrieval_context.<locals>.MyBackend.retrieval_contextN)rI   rJ   rK   r^   Zsupports_retrieve_callbackcontextmanagerr:  r,   )
contextlibr9  r,   r.   r%  S  s   r%  Z	retrievalc                 S   s   t dddd t| D S )Nr>   rk   c                 s   s   | ]}t t|V  qd S r9   r   r]   r,   r,   r.   r_   _  s     z>test_retrieval_context.<locals>.nested_call.<locals>.<genexpr>ra   )nr,   r,   r.   nested_call^  s    z+test_retrieval_context.<locals>.nested_callr>   rk   c                 3   s   | ]}t  |V  qd S r9   r.  r]   )r>  r,   r.   r_   b  s   z)test_retrieval_context.<locals>.<genexpr>rv   r7   r   )	r<  r   r&   r"   rb   r$   r^   re   r%   )ri   r9  r%  r3  r,   )r<  r>  r9  r.   test_retrieval_contextM  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_sizeo  s    
rA  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   )rE  r   rD  rM   )rB  r   rD  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,   rt   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>rw   )Zn_tasksr[   r   r   paramsr   r   r,   r,   r.   test_dispatch_race_conditionu  s    rG  c                  C   s8   t  } tddd}|jd}| }|| ks4td S )Nr>   r+   rZ   ri   )r   get_start_methodr"   Z_backend_argsgetre   )Zmp_start_methodr   ri   Zstart_methodr,   r,   r.   test_default_mp_context  s
    rJ  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randnrK  rL  r"   rb   )r7   rngr,   rM  r.   .test_no_blas_crash_or_freeze_with_subprocesses  s    
rQ  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   rH  r   skip,UNPICKLABLE_CALLABLE_SCRIPT_TEMPLATE_NO_MAINformatr   r   
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   rS  rT  )SQUARE_MAINr   platformr   rV  )UNPICKLABLE_CALLABLE_SCRIPT_TEMPLATE_MAINrX  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(backend="loky", 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.pyrS  )rU  r   )r   rh  5INTERACTIVE_DEFINED_FUNCTION_AND_CLASS_SCRIPT_CONTENTr   r   rY  ri  rj  scriptr,   r,   r.   7test_parallel_with_interactively_defined_functions_loky=  s    


ro  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, 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(backend="loky", 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   )rU  Zstderr_regexr   )r   rh  9INTERACTIVELY_DEFINED_SUBCLASS_WITH_METHOD_SCRIPT_CONTENTr   r   rY  ri  rm  r,   r,   r.   :test_parallel_with_interactively_defined_bound_method_lokye  s    

rr  c                  C   s"   t g } tdd| g kstd S )Nr>   rk   )iterr"   re   )Zexhausted_iteratorr,   r,   r.   %test_parallel_with_exhausted_iteratoro  s    rt  c                   C   s   t   td dS )z+Helper function to force gc in each worker.r   N)r   rQ   r   r,   r,   r,   r.   _cleanup_workert  s    ru  c                 C   s"   t | tjstdt| |  S )Nz#Expected np.memmap instance, got %r)
isinstancer   memmap	TypeErrorrW   copyrM  r,   r,   r.   check_memmapz  s
    rz  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)r=  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#   rz  r-   rC   r,   r,   r.   r_     s    z<test_auto_memmap_on_arrays_from_generator.<locals>.<genexpr>rs   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_generator  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uint8r{  r)Z	mmap_moder>   rk   c                 3   s   | ]}t t V  qd S r9   )r#   r  r   rw  r,   r.   r_     s     z.test_memmap_with_big_offset.<locals>.<genexpr>)r   r   )r   ri  mmapZALLOCATIONGRANULARITYr   zerosr|  r   r   r"   rv  rw  re   offsetr  r  )rj  fnamesizeobjr  r,   r  r.   test_memmap_with_big_offset  s    
r  c               	   C   st   t jdd$} tddddd tdD  W 5 Q R X t| dksFt| d }t|jts^tt	|jd	ksptd S )
NTr|   r   )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   rv  r   r  r   )r   r   r,   r,   r.   3test_warning_about_timeout_not_supported_by_backend  s    (r  c                 C   s   || |< |S r9   r,   )
input_listr   r{   r,   r,   r.   set_list_value  s    r  c                    sV   dgd  t | ddd fddtdD }t|}tdd t |D sRtd S )	Nr   rv   	generatorr1   )r[   	return_asr7   c                 3   s   | ]}t t ||V  qd S r9   )r#   r  r]   r  r,   r.   r_     s    zPtest_parallel_return_order_with_return_as_generator_parameter.<locals>.<genexpr>c                 s   s   | ]\}}||kV  qd S r9   r,   )r-   vr  r,   r,   r.   r_     s     )r"   rb   r   r   r   re   )r[   r  r,   r  r.   =test_parallel_return_order_with_return_as_generator_parameter  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   rs   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   rx  rQ   r"   re   )r[   r7   Zdelayst_startdtr,   r,   r.   test_abort_backend  s    
r  c                 C   s   t jtdtd}d|d< |S )Ng    Ar{  Fr   )r   r|  intbool)r  r  r,   r,   r.   get_large_object  s    r  c              	   C   sL   t || dd4}|dd tdD }t| t| ~t  W 5 Q R X d S )Nr  )r[   r7   r  c                 s   s   | ]}t t|V  qd S r9   )r#   r  r]   r,   r,   r.   r_     s     z/test_deadlock_with_generator.<locals>.<genexpr>r   )r"   rb   nextr   )r7   r[   r   r  r,   r,   r.   test_deadlock_with_generator  s    r  c              	   C   s~   t tddH t|| dd}|dd tdD }t }|dd td	D }W 5 Q R X t | d
k srtd~t  d S )N)This Parallel instance is already runningr   r  r7   r  c                 s   s   | ]}t td V  qdS r   r   r   r,   r,   r.   r_     s     z/test_multiple_generator_call.<locals>.<genexpr>r   c                 s   s   | ]}t t|V  qd S r9   r   r]   r,   r,   r.   r_     s     rs   r>   ZThe error should be raised immediatly when submitting a new task but it took more than 2s.)r   r   r"   rb   rQ   re   r   )r7   r[   r   gr  Zgen2r,   r,   r.   test_multiple_generator_call  s     r  c              
   C   s   t || ddj}|dd tdD }t }ttdd |dd td	D }W 5 Q R X t | d
k sttdW 5 Q R X ~t  d S )Nr  r  c                 s   s   | ]}t td V  qdS r   r   r   r,   r,   r.   r_     s     z7test_multiple_generator_call_managed.<locals>.<genexpr>r   r  r   c                 s   s   | ]}t t|V  qd S r9   r   r]   r,   r,   r.   r_     s     rs   r>   r  )r"   rb   rQ   r   r   re   r   )r7   r[   r   r  r  g2r,   r,   r.   $test_multiple_generator_call_managed  s     r  c                 C   s   t || dddd tdD }t || dddd tddD }tdd t|tdD sbttd	d t|tddD std S )
Nr  r  c                 s   s   | ]}t t|d  V  qdS r>   Nr  r]   r,   r,   r.   r_   )  s    z9test_multiple_generator_call_separated.<locals>.<genexpr>r   c                 s   s   | ]}t t|d  V  qdS r  r  r]   r,   r,   r.   r_   ,  s    r  c                 s   s   | ]\}}||kV  qd S r9   r,   r-   r   r^   r,   r,   r.   r_   0  s     c                 s   s   | ]\}}||kV  qd S r9   r,   r  r,   r,   r.   r_   1  s     )r"   rb   r   r   re   )r7   r[   r  r  r,   r,   r.   &test_multiple_generator_call_separated%  s     r  zbackend, error)r0   T)r1   F)
sequentialFc              	   C   s8  | dkrt d krtd td| dd}|dd tdD }t|d	d
 }|r^ttddnt	 }|X t

 }td| dddd tddD }t  tdd t|tddD stW 5 Q R X t

 | dk std}|jr|dk r|d7 }t
d qt

 | dk st| dkr4|js4td S )Nr0   zRequires multiprocessingr>   r  r  c                 s   s   | ]}t td V  qdS r   r   r]   r,   r,   r.   r_   A  s     z<test_multiple_generator_call_separated_gc.<locals>.<genexpr>r   c                   S   s   t dS )NzGenerator collected)r   r,   r,   r,   r.   <lambda>B      z;test_multiple_generator_call_separated_gc.<locals>.<lambda>z The executor underlying Parallelr   c                 s   s   | ]}t t|d  V  qdS r  r  r]   r,   r,   r.   r_   M  s    r  c                 s   s   | ]\}}||kV  qd S r9   r,   r  r,   r,   r.   r_   T  s     rv   r   r`   r   g      ?)r   r   rV  r"   rb   weakreffinalizer   r   r   rQ   r   r   r   re   aliver   r#  r   )r7   errorr   r  Zg_wrr3  r  retryr,   r,   r.   )test_multiple_generator_call_separated_gc4  s0    
,r  c              	   C   s  |j }tdd| |dR}|dd tjdgd D  tt|dksNt|dd tdD  W 5 Q R X td	D ]}t|s qt	d
 qvtdtdd| d}|dd tjdgd D  |dd tdD  td	D ]}t|s qt	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_   q  s     z(test_memmapping_leaks.<locals>.<genexpr>r   r   c                 s   s   | ]}t t V  qd S r9   r#   ru  r   r,   r,   r.   r_   {  s     rs   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     c                 s   s   | ]}t t V  qd S r9   r  r   r,   r,   r.   r_     s     )
ri  r"   r   rN  r   r   listdirre   rb   r   )r7   rj  r   r   r,   r,   r.   test_memmapping_leakse  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.   r    r  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   )rq   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| d	dd0 tdd}t |jtkst|jdkstW 5 Q R X | d	dd6 tddd}t |jtkst|jdkstW 5 Q R X | d	dd4 tdd}t |jtksRt|jdksbtW 5 Q R X | 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>   rj   rk   threadsr[   prefer	processes	sharedmemr[   requirer>   r0   )r[   r7   r  r  r`   r  r   )rW   r"   r   r  re   r   r!   r[   )ri   r[   r   r,   r,   r.   $test_backend_hinting_and_constraints  s4    

r  c              	   C   s@  G dd d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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_async  s    zgtest_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomThreadingBackend.apply_asyncc                 S   s   |S r9   r,   r  r,   r,   r.   r'     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.   MyCustomThreadingBackend  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    s    zhtest_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomProcessingBackend.apply_asyncc                 S   s   |S r9   r,   r  r,   r,   r.   r'     s    zmtest_backend_hinting_and_constraints_with_custom_backends.<locals>.MyCustomProcessingBackend.effective_n_jobsNr  r,   r,   r,   r.   MyCustomProcessingBackend  s   r  r   r   )r[   r  rq   zUsing ThreadingBackend as joblib backend instead of MyCustomProcessingBackend as the latter does not provide shared memory semantics.r7   r  )
r    r"   rW   r   re   Z
readouterrr   stripr   rN   )Zcapsysri   r  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_constraints  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>   rk   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_   7  s   z*_recursive_backend_info.<locals>.<genexpr>r   N)r"   rW   r   rI   r1  rb   )r  r^  r   Z
this_levelr   r,   r  r.   r  0  s    r  c              	   C   sr   | |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>   rk   r   r   r   ZBackendr   )r  r(   titlere   )ri   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}| d t|d}W 5 Q R X t|dks\t	t
dd	 |D s*t	q*| 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    cAr{  dask)datar~   c                 s   s   | ]\}}|d kV  qdS ZDaskDistributedBackendNr,   r-   ry   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_   g  s   )distributedZClientr   r|  r  r  rb   r  r   re   r   )ri   clientr  r^   r  r,   r,   r.   !test_nested_parallelism_with_daskT  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_   m  s     z&_recursive_parallel.<locals>.<genexpr>r>   ra   )Znesting_limitr,   r,   r.   r  k  s    r  c              
   C   sv   | |dd  t t}t  W 5 Q R X W 5 Q R X |j}|dkrdddlm} t||tfrdt	d t|t
srtd S )Nr>   rk   r0   r   )TerminatedWorkerErrorz1Loky worker crash when serializing RecursionError)r   BaseExceptionr  r{   Z&joblib.externals.loky.process_executorr  rv  r   r   r   RecursionErrorre   )ri   r7   r  excr  r,   r,   r.   test_thread_bomb_mitigationp  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_IPCrs   )r   environrI  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_threadsry   r{   r,   r,   r.   test_parallel_thread_limit  s    
r  z%This test requires dask NOT installedc              	   C   s$   t tdd | d W 5 Q R X d S )NzPlease install daskr   r  )r   rN   r  r,   r,   r.   )test_dask_backend_when_dask_not_installed  s    r  c              
   C   sd   G dd dt }d}| | < 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>   rk   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   r   r   r"   rb   )ri   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>   rk   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   rs   )threadpool_info)ZnumpyrN  rO  rK  Zthreadpoolctlr  )r   rC   r  r,   r,   r.   _check_numpy_threadpool_limits  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   rX  )child_moduleparent_infoparent_moduler,   r,   r.   _parent_max_num_threads_for  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_threads  s     r  c                 C   sd   t  }t|dkrtjdd td| ddd tdD }t| } tt |  d	}t	||| d S )
Nr   &Need a version of numpy linked to BLASmsgr0   )r7   r[   c                 s   s   | ]}t t V  qd S r9   r#   r  r]   r,   r,   r.   r_     s    z;test_threadpool_limitation_in_child_loky.<locals>.<genexpr>r>   r   
r  r   r   rV  r"   rb   r'   r  r(   r  )r[   r  workers_threadpool_infosexpected_child_num_threadsr,   r,   r.   (test_threadpool_limitation_in_child_loky  s    r  inner_max_num_threadsc              	   C   s   t  }t|dkrtjdd | 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  rk   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  )ri   r[   r  r  r	  r
  r,   r,   r.   +test_threadpool_limitation_in_child_context  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| 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  rI  )r  r,   r,   r.   _get_envE  s    z>test_threadpool_limitation_in_child_override.<locals>._get_env4rk   c                 3   s   | ]}t  V  qd S r9   r.  r]   r  r  r,   r.   r_   L  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_   Q  s    r  )r   shutdownr   r  rI  r"   rb   re   )ri   r[   r  Zoriginal_var_valuer   r,   r  r.   ,test_threadpool_limitation_in_child_override7  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   rk   c                 3   s   | ]}t t V  qd S r9   )r#   sumr]   r?   r,   r.   r_   d  s     zAtest_loky_reuse_workers.<locals>.parallel_call.<locals>.<genexpr>)rb   r"   rk   r,   r?   r.   parallel_callb  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   r   rQ   r  r  r   r1   	tracebackr   mathr   r   pickler   r<  r   r+   r	   r   rf  r   r   r   Zjoblib._multiprocessing_helpersr   Zjoblib.test.commonr   r   r   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!   Zjoblib.parallelr"   r#   r$   r%   r&   r'   r(   r)   r*   ry  ZRETURN_GENERATOR_BACKENDSpopsortedkeysZALL_VALID_BACKENDSZPROCESS_BACKENDSZPARALLEL_BACKENDShasattrr   r2   r  r8   r<   r@   	ExceptionrA   rP   rS   rU   rY   rd   rf   rh   markro   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  extendrb   r  r  r  r  r"  r$  Z_parallel_backendsr%  r,  r0  r4  r8  r?  rA  rG  rJ  rQ  rW  r[  rc  ra  ZSQUARE_LOCALZSQUARE_LAMBDArk  rX  rd  re  rg  rl  ro  rq  rr  rt  ru  rz  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  Zno_coverr  r  r  r  r  r  r  r  r  r  r  r  r  r,   r,   r,   r.   <module>   s  











D              


	

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