U
    /ee                     @   s,  d dl Z e d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mZmZmZmZmZ d dlZd dlmZ d dlmZmZmZ d d	lmZ d d
lmZ d dlm Z  d dl!m"Z"m#Z# d dl$m%Z%m&Z& d dl'm(Z(m)Z)m*Z* d dl+m,Z, de(ekr,eeddZeeddZe j-j.ej/dkddZ0dd Z1dd Z2edddd Z3dd Z4dd  Z5d!d" Z6e j-7d#ddgd$d% Z8d&d' Z9d(d) Z:e j-;d*eddd+d, Z<d-d. Z=e j-;d*e j-7d/d0e j>d1e j-j?d2dd3d4e j>d5e j-j?d2dd3d4gd6d7 Z@eddd8d9 ZAd:d; ZBd<d= ZCd>d? ZDd@dA ZEedddBdC ZFdDdE ZGedddFdG ZHe j-7dHdIdJdKge j-7d#dddgdLdM ZIe j-;d*e j-7dHdNdOdPdQge j-7d#dddge j-7dRddgdSdT ZJdUdV ZKedddWdX ZLedddYdZ ZMd[d\ ZNd]d^ ZOeddd_d` ZPdadb ZQedddcdd ZRedddedf ZSe j-jTdgdgdhedddidj ZUedddkdl ZVdmdn ZWedddodp ZXedddqdr ZYe j-;d*edddsdt ZZedddudv Z[dwdx Z\dydz Z]d{d| Z^d}d~ Z_dS )    Ndistributed)partial)add)cleanup)client)clustercluster_fixturegen_clusterlooploop_in_threadvarying)computedelayedpersist)get_scheduler)	Blockwise)Delayed)
futures_ofwait)HighLevelGraphMaterializedLayer)get_named_argstmpdirtmpfile)incshould_check_stateF)r   win32zTThe teardown of distributed.utils_test.cluster_fixture fails on windows CI currently)reasonc                  C   s   ddl m}  d S )Nr   Client)dask.distributedr   r    r!   ?/tmp/pip-unpacked-wheel-dbjnr7gq/dask/tests/test_distributed.pytest_can_import_client5   s    r#   c                  C   s   ddl m}  d S )Nr   dumps)Zdask.distributed.protocolr%   r$   r!   r!   r"   test_can_import_nested_things9   s    r&   Tc           	         s   t td}t|\}t|I d H  |j|jks@|j|jks@tt td}t|d\}}t|I d H  |j|jks|j|jkstd S )N   
   )r   r   r   r   keydataAssertionError)	csabxZx2yy2oner!   r!   r"   test_persist=   s    
r4   c                 C   s"  t dd }|d }|d } t|dd|gd| dfddg}t|d d tsRtt|d d d tsltt|d d tstd	ddd
gddddgf}t| |kstt||g| ddgdd}|d d |kst|d d |kst|d  dkst|dd  ddgfkstd S )Nr'         r.   r/      r   r.   r/         )   r6   F)Ztraverser;   )r   r   
isinstancer   r+   r   )r,   r.   r/   resultZsolresr!   r!   r"   test_persist_nestedL   s     r?   c              	   C   s   t d}t d}|ddddgi}| ||g}||}|j| |j||gdd t	|j
j|j tsxtt t |ddg}W 5 Q R X d S )	Npandasdask.dataframer0   r'   r6      r   Zaxis)pytestimportorskip	DataFramescatterfrom_delayedutils	assert_eqr   concatr<   dasklayers_namer   r+   raises	TypeError)r,   pddddffuturesddfr!   r!   r"   !test_futures_to_delayed_dataframe_   s    


 rV   c                 C   sX   t d}t d}|dtdi}|j|dd}|| }|jj||| d d S )Nr@   rA   r0      r6   npartitionsZ	scheduler)	rD   rE   rF   rangefrom_pandasrH   
to_delayedrI   rJ   )r,   rQ   rR   rS   rU   r!   r!   r"   test_from_delayed_dataframep   s    

r^   fusec              	   C   s   t d}t d}d}|t|t|d}|t|t|d}|j||dd }|j|ddd }|d7 }|d7 }tjd	|i. |j|d
gdd}	|		  |	
 d
}
W 5 Q R X |jj|
|j|d
gddd
dd d S )Nr@   rA   #   r0   r1   )r0   zrX   r(   r5   optimization.fuse.activer0   left)onhowFZcheck_index)rD   rE   rF   r[   r\   rL   configsetmergeheadr   Zsort_valuesrI   rJ   )r,   r_   rQ   rR   sizeZdf1Zdf2Zddf1ddf2ZddfmZdfmr!   r!   r"   $test_fused_blockwise_dataframe_merge|   s$    

  rn   c                 C   s:   dddg}|  ||g}t|}t||| ks6td S )Nr'   r6   rB   )rG   dbrH   listr+   )r,   LrT   r/   r!   r!   r"   test_futures_to_delayed_bag   s    

rr   c                    sv   t d ddlm} t d}|d| g} j fdd|D dd}|| |jgdd d S )	N
dask.arrayr   rJ   numpyr5   c                    s    g | ]} j |jjd qS ))shapedtype)rH   rv   rw   .0fdar0   r!   r"   
<listcomp>   s     z1test_futures_to_delayed_array.<locals>.<listcomp>rC   )rD   rE   dask.array.utilsrJ   arangerG   concatenater   )r,   rJ   nprT   Ar!   r{   r"   test_futures_to_delayed_array   s    


 r   zrignore:Running on a single-machine scheduler when a distributed client is active might lead to unexpected results.c              	      sv   t jjdd ttd }W 5 Q R X tdI d H  |jrDt	ttdjdd}tdI d H  |jrrt	d S )NsyncrZ   r'   g{Gz?r6   )
rL   rh   ri   r   r   r   asynciosleeptasksr+   r,   r-   r.   r/   r0   r!   r!   r"   &test_local_get_with_distributed_active   s    
r   c                 C   s*   t d t d ddlm} |  d S )Nru   r@   r   )test_to_hdf)rD   rE    dask.dataframe.io.tests.test_hdfr   )r,   r   r!   r!   r"   test_to_hdf_distributed   s    

r   rY   r'   r8   zHDF not multi-process safe)r   strict)Zmarksr(   c                 C   s.   t d t d ddlm} |d |  d S )Nru   r@   r   )test_to_hdf_schedulers)rD   rE   r   r   )rY   r,   r   r!   r!   r"   !test_to_hdf_scheduler_distributed   s    

r   c                    s   t d}t d}|ddddgddddgd}|j|dd	}|jd
ddjddd}| |jd I d H }	| |jd I d H }
|j	|
|	|
g|ddgddgdd
 d S )Nr@   rA   r'   r6   rB   r8   r   ra   rX   r1   F)sortcount)Z	split_out)rD   rE   rF   r\   groupbyZaggr   Z
partitionsrI   rJ   rK   	set_index)r,   r-   r.   r/   rQ   rR   rS   rU   r=   Zagg0Zagg1r!   r!   r"   test_serializable_groupby_agg   s    

 r   c                 C   sl   t dt d }}t t||}t t||}t t||}| |}t t|d}|jdddkshtd S )Nr'   r6   r(   dask.distributedrZ      )r   r   r   r   r+   )r,   r0   r1   ZxxyyZxxyyZxxyy2Zxxyy3r!   r!   r"   test_futures_in_graph   s    
r   c              	   C   sl   t d}t d t H}|jddd}|| ||}|j||| d |j|jks^tW 5 Q R X d S )Nrs   zarrrB   rB   r'   r'   chunksrZ   )	rD   rE   r   zerosto_zarrZ	from_zarrrJ   r   r+   )r,   r|   dr.   Za2r!   r!   r"   test_zarr_distributed_roundtrip   s    



r   c              	   C   sX   t d}t d}d}|jd|d}|j||d}t t || W 5 Q R X d S )Nrs   r   r   r   r   )rD   rE   onesZ
zeros_likerO   RuntimeErrorr   )r,   r|   r   r   r.   rb   r!   r!   r"   #test_zarr_in_memory_distributed_err  s    

r   c                    s<   t dd    j| ddks"t|  fdds8td S )Nc                   S   s   dS Nr'   r!   r!   r!   r!   r"   <lambda>      z.test_scheduler_equals_client.<locals>.<lambda>rZ   r'   c                    s   |   jS N)Zstoryr)   )Zdask_schedulerr0   r!   r"   r     r   )r   r   r+   Zrun_on_schedulerr,   r!   r   r"   test_scheduler_equals_client  s    r   c                    sZ   t td}| I d H }|j|jks,t|js<|js<ttdd t	|D sVtd S )Nr'   c                 s   s   | ]}|  V  qd S r   )donerx   r!   r!   r"   	<genexpr>$  s     ztest_await.<locals>.<genexpr>)
rL   r   r   r   r)   r   r+   r*   allr   r   r!   r!   r"   
test_await  s
    r   c                  C   s   dd } t |   d S )Nc                     s:   t td} | d }| I d H }t|j dks6td S r   )rL   r   r   r   lenr+   r0   r1   rb   r!   r!   r"   rz   (  s    ztest_local_scheduler.<locals>.f)r   run)rz   r!   r!   r"   test_local_scheduler'  s    r   c              	      s   t d}t d}ddlm} ttdtdddg  fdd	}d
d }|jddd}	tjdd  |	j	||j
d|jdd}
W 5 Q R X tjdd  |
j	||j
d|jdd}W 5 Q R X tjjdd | |I d H }W 5 Q R X |||dd  d S )Nrs   ru   r   rt   r3   Ztwor6   c                    s
     |  S r   r!   r   Zscaler!   r"   flaky_double;  s    z7test_annotations_blockwise_unpack.<locals>.flaky_doublec                 S   s   d|  S )Nr6   r!   r   r!   r!   r"   reliable_double?  s    z:test_annotations_blockwise_unpack.<locals>.reliable_doubler(   )r5   r   )retriesr!   rw   metaF)Zoptimization__fuse__activeg      @)rD   rE   r~   rJ   r   ZeroDivisionErrorr   rL   ZannotateZ
map_blocksarrayZfloat_rh   ri   r   )r,   r-   r.   r/   r|   r   rJ   r   r   r0   r1   rb   r!   r   r"   !test_annotations_blockwise_unpack1  s    

$$r   ior   r   fullc           
   	   C   s   t d}t d}d}d}|dkr>|j||d}||}nF|dkr`|j||d}||}n$|dkr|j|d	|d}||d	}|d
7 }|d
7 }tjd|iH |  tj	
|j| }	t|	t|dk	kst|j||| d W 5 Q R X d S )Nru   rs   )r5   r6   )r(   r8   r   r   r   r   r(   r6   rc   FrZ   )rD   rE   r   r   r   rL   rh   ri   r   r   optimize__dask_keys__r<   dictr+   rJ   )
r,   r   r_   r   r|   r   rv   darrZnarrdskr!   r!   r"   test_blockwise_array_creationP  s(    


r   parquet-pyarrowzparquet-fastparquetcsvhdffrom_futuresc              	   C   s  t d}t d}|dddgd tdd}|r||jd d |jdd	 |jd	d g}| |}	|j|	|d
 d}
n|j|dd}
|dr|dkrt d d}nt d d}|
j	t
||d |jt
||d}np|dkr|
jt
|dd |tjt
|d}n:|dkrPt d t
|d}|
|d ||d}|dg d	 }|dg d	 }tjd|iJ |  tj|j| }t|tt|kst|j||dd W 5 Q R X d S )Nr@   rA   r'   r6   rB   r5      ra   r(   r   r   rX   Zparquetr   zpyarrow.parquetZpyarrowZfastparquet)enginer   F)index*r   Ztablesh5z/data*r0   rc   rg   )rD   rE   rF   r[   ZilocrG   rH   r\   
startswithZ
to_parquetstrZread_parquetZto_csvZread_csvospathjoinZto_hdfZread_hdfrL   rh   ri   r   Z	dataframer   r   r<   r   boolr+   rJ   )r,   r   r   r_   r   rQ   rR   rS   partsZfutsZddf0r   rU   fnr   r!   r!   r"   test_blockwise_dataframe_iot  s>    

(






r   c                 C   sx   t d}t d}|ddddgd i}|j|ddd }|dk }t|}|d	ksZt|j|   d	ksttd S )
Nr@   rA   r0   r'   r6   rB   r5   rX   r   )	rD   rE   rF   r\   r   r+   r0   r   sum)r,   rQ   rR   rS   seriesr=   Z
series_lenr!   r!   r"   #test_blockwise_fusion_after_compute  s    

r   c              	      sn   t d}t d  fdd}|j|d|dd dd jd	}| j| d
dI dH }|dksjtdS )zDTest pack/unpack of blockwise that includes a NumPy literal argumentrs   ru   c                    s   t | jkst| |S r   typeuint16r+   astyper0   dtr   r!   r"   r     s    z%test_blockwise_numpy_args.<locals>.fnr0     *   Nr   FZoptimize_graphrD   rE   	blockwiser   r   r   r   r+   r,   r-   r.   r/   r|   r   arrr>   r!   r   r"   test_blockwise_numpy_args  s    

      r   c              	      sn   t d}t d d fdd	}|j|d|dd j dd	}| j| d
dI dH }|dksjtdS )zLTest pack/unpack of blockwise that includes a NumPy literal keyword argumentrs   ru   Nc                    s   t | jkst| |S r   r   r   r   r!   r"   r     s    z'test_blockwise_numpy_kwargs.<locals>.fnr0   r   r   )rw   r   Fr   )Nr   r   r!   r   r"   test_blockwise_numpy_kwargs  s    

$r   c              	   C   s   t d}t d}||d}||dddg}| }|| }t|\}|| }|ddd	g}tj	d
di |
 }	|
 }
W 5 Q R X |j|	| |j|
| d S )Nrs   ru   rB   y      $@       @y      @      y       @      ?y                y      @      @y      0@       rc   F)rD   rE   
from_arrayr   r   ZconjrL   r   rh   ri   r   ZtestingZassert_equal)r,   r|   r   uvZcvr0   r1   expectedZx_valueZy_valuer!   r!   r"   %test_blockwise_different_optimization  s    

r   c              	   C   s   t d}t d}|jddd}tt|jj}d||d|dfi}t	d	||g}|j
|d	d
|jd}tjddi |j|d|| d W 5 Q R X d S )Nrs   ru   )d   r   )r(   r(   r   )blockr   r   r   r'   r   )r(   r   r   rc   FrZ   )rD   rE   r   nextiterrL   rM   Zint64r   Zfrom_collectionsArrayrw   rh   ri   rJ   )r,   r|   r   r0   namer   r   r   r!   r!   r"   +test_blockwise_cull_allows_numpy_dtype_keys  s    

r   c                    s   t d}t d}t d}t d}dd }| dd d	}	| d
d d}
|j|d|jdddd|jdddd|	ddt|
d}|j|d|	didd}|j
ddd}|d  }| |  }| j|ddI dH }|dkstdS )z9Check pack/unpack of a HLG that has every type of Layers!rs   rA   ru   r@   c                 S   s   | | | | S r   r!   )r0   r1   rb   	extra_argr!   r!   r"   r     s    z&test_combo_of_layer_types.<locals>.addc                 S   s   | S r   r!   r   r!   r!   r"   r     r   z+test_combo_of_layer_types.<locals>.<lambda>r6   c                 S   s   | S r   r!   r   r!   r!   r"   r     r   rB   r0   )rB   r'   r   NF)r   rw   r   r.   rX   r   )shuffler      )rD   rE   submitr   r   r   intr\   rF   r   r   Zto_dask_arrayr   r   r+   )r,   r-   r.   r/   r|   rR   r   rQ   r   r1   rb   r0   rS   r>   r!   r!   r"   test_combo_of_layer_types  s4    



r   c              
      s   t d t d} fdd} |dddg} |dddgg} j|d|d|d	|jd
d}| j|dd  j||| d dS )z1Test a blockwise operation with concatenated axesrs   ru   c                    s     |dddgg | S )Nr   r'   r6   rt   ra   r|   r!   r"   rz   1  s    z%test_blockwise_concatenate.<locals>.fr   r'   r6   iZijT)rw   r   Fr   rZ   N)rD   rE   r   r   r   rw   r   rJ   )r,   r   rz   r0   r1   rb   r!   r   r"   test_blockwise_concatenate,  s"    


r  c                    s|   t d}t d}|j|dtdidd}| |dddI d H }|d	 d	d	d
ksbt|d ddd
ksxtd S )NrA   r@   r.   r(   r6   rX   c                 S   s   |S r   r!   )r0   Zpartition_infor!   r!   r"   r   L  r   z4test_map_partitions_partition_info.<locals>.<lambda>r   )numberdivisionr'   r5   )N)rD   rE   r\   rF   r[   r   map_partitionsr+   )r,   r-   r.   r/   rR   rQ   rU   r>   r!   r!   r"   "test_map_partitions_partition_infoE  s    


r  c                    s   t d}t d}|j|ttd|jddddddd	d
}||jtd 	 }|j
j |d< | j|jj|dgddI dH }dS )z.Copied from distributed (tests/test_client.py)rA   r@   2   z
2020-01-01z
2020-09-01UTC)startendZperiodstz)uid
enter_timer'   rX      dayF)columnsr   N)rD   rE   r\   rF   r   r[   Z
date_ranger  isinr   r  r   day_namer   ZcategoricalZ
categorize)r,   r-   r.   r/   rR   rQ   rU   r!   r!   r"   test_futures_in_subgraphsR  s&    

   r  r5   )ZrerunsZreruns_delayc                    s   t d}t d}t d}|dtdi}|j|dd}|jddd	d
}	| |	I d H  dd |jD }
|dd t	|
D d}|dd t	|
D d}||k st
d S )Nr@   ru   rA   r.   r   r(   rX   r       )r   Z
max_branchc                 S   s4   g | ],}|d  dkrd|d krt |d d qS )r'   
processingzsimple-shuffle-r   )eval)ry   lr!   r!   r"   r}   |  s    z)test_shuffle_priority.<locals>.<listcomp>c                 S   s   g | ]\}}| d r|qS )splitr   ry   r   str!   r!   r"   r}     s     
 g      ?c                 S   s   g | ]\}}| d r|qS )simpler  r  r!   r!   r"   r}     s     
 g      ?)rD   rE   rF   r[   r\   r   r   Ztransition_logZquantile	enumerater+   )r,   r-   r.   r/   rQ   r   rR   rS   rU   rm   logZ
late_splitZearly_combiner!   r!   r"   test_shuffle_priorityj  s&    


  r  c           	         sz   t d t dt d}t d} fdd}|jdd }|jd	d
d }| |j|||jdI dH  dS )z7Check that map_partitions can handle a dask array inputru   r@   rs   zdask.datasetsc                    s$   t | jstt | js t| S r   )r<   rF   r+   Zndarrayr   r.   r   rQ   r!   r"   rz     s    z'test_map_partitions_da_input.<locals>.fZ1d)freqr   r'   r   r   N)rD   rE   
timeseriesr   r   r   r  Z_meta)	r,   r-   r.   r/   r|   datasetsrz   rS   r   r!   r   r"   test_map_partitions_da_input  s    



r$  c               
      s|   t dt d fdd fdd} tjddd	d
id
ddd
d&}tj|d
d |   W 5 Q R X W 5 Q R X dS )z[
    Check that map_partitions can handle a delayed
    partition of a dataframe input
    r@   rA   c                    s$   t |  jstt | js t| S r   )r<   rF   r+   r  )rQ   r!   r"   rz     s    z'test_map_partitions_df_input.<locals>.fc                     sn    j dtdidd} |  d  } j dtdidd}|jdd}|j||dd	  d S )
Nr.   r(   r'   rX   r   r/   )re   F)r   Zenforce_metadata)r\   rF   r[   r]   r   r   r  r   )Zitem_dfrU   Z	merged_dfrR   rz   rQ   r!   r"   main  s       z*test_map_partitions_df_input.<locals>.mainr   z:0Z	dashboardFr'   )Zscheduler_portZdashboard_addressZscheduler_kwargsasynchronousZ	n_workersZnthreadsZ	processes)r'  N)rD   rE   r   ZLocalClusterr   )r&  r   r!   r%  r"   test_map_partitions_df_input  s     

r(  c                    s^   t dtddiidt i}ddi}|| dg|}t |}|d }|dddiiksZtd S )Nl1nr   workers)Zaliceannotations)r   r   ri   __dask_distributed_pack____dask_distributed_unpack__r+   )r,   r-   r.   r/   hlgr,  Z
packed_hlgZunpacked_hlgr!   r!   r"   test_annotation_pack_unpack  s    
r0  c                    s|   |  td}tdt|tdftdfdidt i}|  || dgi }t|}|d |jh|jhdhdksxt	d S )Nr'   r)  r0   r1   r   rb   deps)
r   r   r   r   ri   Zget_all_dependenciesr-  r.  r)   r+   )r,   r-   r.   r/   Zfutr/  packedunpackedr!   r!   r"   =test_pack_MaterializedLayer_handles_futures_in_graph_properly  s    
r4  c              	      s   t d}t d}t d |tdtdd}d|j_|j|dd}t T}d	| }	|jd
|	dddidd}
| 	|
I d H  |j
j||d
|	ddd W 5 Q R X d S )Nr@   rA   Z
sqlalchemyr(   r7   r   r'   rX   z
sqlite:///testTZechoF)r   Zengine_kwargsr   )Zcheck_divisions)rD   rE   rF   r[   r   r   r\   r   Zto_sqlr   rI   rJ   Zread_sql_table)r,   r-   r.   r/   rQ   rR   rS   rU   rz   urir=   r!   r!   r"   test_to_sql_engine_kwargs  s*    



    r7  c           
         s   t d}t d}G dd d d}|jdg| td|d d}|j|d	d
}|jdd  fddddtd}	| |	I d H jdkst	d S )NrA   r@   c                   @   s   e Zd Zdd ZdS )z0test_non_recursive_df_reduce.<locals>.SomeObjectc                 S   s
   || _ d S r   )val)selfr8  r!   r!   r"   __init__
  s    z9test_non_recursive_df_reduce.<locals>.SomeObject.__init__N)__name__
__module____qualname__r:  r!   r!   r!   r"   
SomeObject	  s   r>     r'   r6   )r*   r   "   rX   c                 S   s   | S r   r!   r   r!   r!   r"   r     r   z.test_non_recursive_df_reduce.<locals>.<lambda>c                    s    |     S r   )r   r   r>  r!   r"   r     r   Fzcommit-dataset)chunkZ	aggregateZsplit_everytokenr   )
rD   rE   ZSeriesr[   r\   Z	reductionobjectr   r8  r+   )
r,   r-   r.   r/   rR   rQ   Nr   Zdask_seriesr=   r!   rA  r"   test_non_recursive_df_reduce  s    


rF  c                 C   sh   t d z:tjjdddd dti}|jddd}|	  W n t
k
rb   t d	 Y nX d S )
NrA   z
2000-01-01z
2000-07-01Z12h)r  r	  r!  	timestampT)sortedz(dd.set_index triggered a recursion error)rD   rE   rL   r#  r"  Zreset_indexr   r   r   r   RecursionErrorZfail)r,   rU   r!   r!   r"   !test_set_index_no_resursion_error  s    
rJ  c               	   C   sP   d} t jt| d tdd W 5 Q R X t jt| d tdd W 5 Q R X d S )Nz	no Clientmatchr   rZ   r   )rD   rO   r   r   )msgr!   r!   r"   -test_get_scheduler_without_distributed_raises*  s
    rN  c              	   C   sV   t  | jkstd}tjt|d}t dd t dd W 5 Q R X t|dksRtd S )NzkRunning on a single-machine scheduler when a distributed client is active might lead to unexpected results.rK  threadsrZ   r   r6   )r   getr+   rD   warnsUserWarningr   )r,   Zwarning_messageZuser_warnings_ar!   r!   r"   *test_get_scheduler_with_distributed_active3  s    
rS  c              
   C   s~   t  | jksttjjddV tt t  | jks<tW 5 Q R X tjjd d t  | jksftW 5 Q R X W 5 Q R X d S )NrO  rZ   )	r   rP  r+   rL   rh   ri   rD   rQ  rR  r   r!   r!   r"   7test_get_scheduler_with_distributed_active_reset_config?  s    rT  )`rD   rE   r   r   r   sys	functoolsr   operatorr   Zdistributed.utils_testr   r   r,   r   r   r	   r
   r   r   rL   Zdask.bagZbagro   r   r   r   Z	dask.baser   Zdask.blockwiser   Zdask.delayedr   r    r   r   Zdask.highlevelgraphr   r   Z
dask.utilsr   r   r   Zdask.utils_testr   markZskipifplatformZ
pytestmarkr#   r&   r4   r?   rV   r^   Zparametrizern   rr   r   filterwarningsr   r   paramZxfailr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  Zflakyr  r$  r(  r0  r4  r7  rF  rJ  rN  rS  rT  r!   r!   r!   r"   <module>   s   
 			

		




*


$

!
*


	