o
    i^                     @   s  d dl Z d dlmZ d dl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mZ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 d d	lmZmZmZmZm Z m!Z!m"Z" d dl#Z#d dl$Z$d dl%Z%G d
d de&Z'dd Z(dd Z)dd Z*dd Z+dd Z,ee(Z-dd Z.dd Z/dd Z0dd Z1dd Z2d d! Z3d"d# Z4G d$d% d%eZ5G d&d' d'eeZ6G d(d) d)eeZ7G d*d+ d+ee%jZ8G d,d- d-ee%jZ9G d.d/ d/ee%jZ:G d0d1 d1ee%jZ;e<d2kre%=  dS dS )3    N)StringIO)njit	vectorizetypeof)utilstypestypingircompilercpucgutils)CompilerFlags)
cpu_target)MemoryLeakMixinTestCasetemp_directorycreate_temp_module)overloadmodelslower_builtinregister_modelmake_attribute_wrappertype_callabletypeof_implc                       s   e Zd Z fddZ  ZS )	Namespacec                    s    || v r| | S t t| |S N)superr   __getattr__)sk	__class__ Z/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/numba/tests/test_array_exprs.pyr      s    zNamespace.__getattr__)__name__
__module____qualname__r   __classcell__r$   r$   r"   r%   r      s    r   c                 C      | | | S r   r$   axyr$   r$   r%   axy       r/   c                 C   r*   r   r$   r+   r$   r$   r%   ax2#   r0   r1   c                 C   s&   | |d d|  |  d  d|   S )N       @g      @      ?r$   AsBsCsr$   r$   r%   pos_root&   s   &r8   c                 C   s2   d|  }d| | }|d | }| |d  | S )Nr2   r3   r$   r5   r6   r7   _2As_4AsCs
_Bs2_4AsCsr$   r$   r%   neg_root_common_subexpr)   s   r=   c                 C   s6   d|  }d| | }|d | d }| |d  | S )Nr2   y                r3   r$   r9   r$   r$   r%   neg_root_complex_subexpr/   s   r>   c                 C   s   t t| t |d dS )N      ?)npcosvaxysin)a0a1r$   r$   r%   
call_stuff7   s   rF   c                 C   s   |d d|  |  dk S )N      r   r$   r4   r$   r$   r%   are_roots_imaginary:   s   rI   c                 C   s   | | | S r   r$   r4   r$   r$   r%   div_add=   r0   rJ   c                 C   s   | d S )N   r$   )r5   r$   r$   r%   cube@   s   rL   c                 C   s   t | | t |||S r   )r@   rA   add)r,   boutr$   r$   r%   explicit_outputC   s   rP   c                 C   s$   | | }|| |  }|| | }|S r   r$   )r,   rN   cdur$   r$   r%   variable_name_reuseG   s   rT   c                 C   sr   | j d }tj||ftjd}t|D ]#}t||D ]}t| | | |  d d  |||f< |||f< qq|S )Nr   dtyperG   r3   )shaper@   emptyfloat64rangesum)vectors	n_vectorsresultijr$   r$   r%   distance_matrixO   s   
ra   c                   @   s0   e Zd Ze		dddZe		dddZdS )RewritesTesterNc                 C   sL   |d u ri }|st  }d|_|d u rtj}|d u rtj}| |||||||S NT)r   nrtr   typing_contexttarget_context)clsargsreturn_typeflagslocalslibraryre   rf   r$   r$   r%   mk_pipeline\   s   zRewritesTester.mk_pipelinec                 K   s6   |d u ri }|st  }d|_| j|||||fi |S rc   )r   no_rewritesrm   )rg   rh   ri   rj   rk   rl   kwsr$   r$   r%   mk_no_rw_pipelinek   s   z RewritesTester.mk_no_rw_pipeline)NNNNNN)NNNN)r&   r'   r(   classmethodrm   rp   r$   r$   r$   r%   rb   [   s    rb   c                   @   s   e Zd Zdd Zdd Zdd Zd%dd	Zefd
dZe	fddZ
dd Zdd Zd&ddZdd Zdd Zdd ZefddZdd Zdd  Zd!d" Zd#d$ ZdS )'TestArrayExpressionsc           	      C   s@   t |}||}|j}t |}||}|j}||||fS )zT
        Compile the given function both without and with rewrites enabled.
        )rb   rp   compile_extraentry_pointrm   )	selffnarg_tyscontrol_pipelinecres_0control_cfunctest_pipelinecres_1
test_cfuncr$   r$   r%   _compile_functionx   s   



z&TestArrayExpressions._compile_functionc                 C   s6  t ddd}t ddd}t ddd}dd |||fD }| t|\}}}}t|}	|	t}
|
j}||||}||||}||||}t j	
|| t j	
|| |jjj}|jjj}|	jjj}| t|t| | t|t| | t|d jt|d j | t|d jt|d j dS )zv
        Using a simple array expression, verify that rewriting is taking
        place, and is fusing loops.
        r      
   rG   c                 S      g | ]}t |qS r$   r   .0argr$   r$   r%   
<listcomp>       z9TestArrayExpressions.test_simple_expr.<locals>.<listcomp>N)r@   linspacer~   r/   rb   rp   rs   r1   rt   testingassert_array_equalstatefunc_irblocksassertEquallenassertGreaterbody)ru   AXYrw   rx   nb_axy_0r{   nb_axy_1control_pipeline2cres_2nb_ctlexpectedactualcontrolir0ir1ir2r$   r$   r%   test_simple_expr   s*   






 $z%TestArrayExpressions.test_simple_exprc                 c   s<    |D ]}t |tjrt |jtjr|jjdkr|V  qd S )N	arrayexpr)
isinstancer
   AssignvalueExprop)ru   blockinstrr$   r$   r%   _get_array_exprs   s   z%TestArrayExpressions._get_array_exprsNc           	      C   s~   |du rt  }t|tstd||\}}g }|D ]}t|tr*| ||\}}|| q|t|f}|| ||fS )zK
        Convert an array expression tree into a set of operators.
        Nz{0} not a tuple)setr   tuple
ValueErrorformat_array_expr_to_setappendrM   )	ru   exprrO   	operationoperandsprocessed_operandsoperand_processed_exprr$   r$   r%   r      s   


z'TestArrayExpressions._array_expr_to_setc                 C   s   t jd}t jdd }t jd}dd |||fD }t|}||}|j}t|}	|	|}
|
j}||||}||||}||||}t j|| t j|| t	t
 S )Nr   r?   c                 S   r   r$   r   r   r$   r$   r%   r      r   z<TestArrayExpressions._test_root_function.<locals>.<listcomp>)r@   randomrb   rp   rs   rt   rm   r   assert_array_almost_equalr   rk   )ru   rv   r   BCrw   rx   control_cresnb_fn_0r{   	test_cresnb_fn_1	np_resultnb_result_0nb_result_1r$   r$   r%   _test_root_function   s    




z(TestArrayExpressions._test_root_functionc                 C   s   t jdt jd}t|f}t|}||}|j}t|}||}|j}	|d }
| 	|
|| | 	|
|	| t
t S )Nr   rU   rK   )r@   arangerY   r   rb   rp   rs   rt   rm   assertPreciseEqualr   rk   )ru   rv   r   rw   rx   r   r   r{   r   r   r   r$   r$   r%   _test_cube_function   s   





z(TestArrayExpressions._test_cube_functionc           	         sz   t jdt jd  d t fd }| ||\}}}} fdd}||}| ||| | ||| tt S )z
        Test function having a (a, b, out) signature where *out* is
        an output array the function writes into.
        r   rU   r   rK   c                    s   t  }|  | |S r   )r@   
zeros_like)rv   rO   r   r   r$   r%   run_func   s   
zETestArrayExpressions._test_explicit_output_function.<locals>.run_func)r@   r   rY   r   r~   r   r   rk   )	ru   rv   rw   rx   rz   r{   r}   r   r   r$   r   r%   _test_explicit_output_function   s   


z3TestArrayExpressions._test_explicit_output_functionc                 C   s"   t t| |}| || dS )z`
        Assert the *block* has the expected number of array expressions
        in it.
        N)r   listr   r   )ru   r   expected_countrewrite_countr$   r$   r%   _assert_array_exprs   s   z(TestArrayExpressions._assert_array_exprsFc                 C   s`   |  t|t| |d j}|d j}| |d | |d |s.| t|t| dS dS )z
        Given two dictionaries of Numba IR blocks, check to make sure the
        control IR has no array expressions, while the test IR
        contains one and only one.
        r   r   N)r   r   r   r   r   )ru   
control_irtest_irtrivialcontrol_block
test_blockr$   r$   r%   _assert_total_rewrite  s   

z*TestArrayExpressions._assert_total_rewritec                 C   sf   |  t|t| | D ]"\}}|j}|| j}|  t|t| | |d | |d qdS )z
        Given two dictionaries of Numba IR blocks, check to make sure
        the control IR and the test IR both have no array expressions.
        r   N)r   r   itemsr   r   )ru   r   r   r!   vr   r   r$   r$   r%   _assert_no_rewrite  s   
z'TestArrayExpressions._assert_no_rewritec                 C   s,   |   }| j|jjjj|jjjjdd dS )z
        Ensure even a non-nested expression is rewritten, as it can enable
        scalar optimizations such as rewriting `x ** 2`.
        T)r   N)r   r   rx   r   r   r   r{   ru   nsr$   r$   r%   test_trivial_expr(  s
   

z&TestArrayExpressions.test_trivial_exprc                 C   s(   |   }| |jjjj|jjjj dS )z
        Using the polynomial root function, ensure the full expression is
        being put in the same kernel with no remnants of intermediate
        array expressions.
        N)r   r   rx   r   r   r   r{   r   r$   r$   r%   test_complicated_expr2  s   
z*TestArrayExpressions.test_complicated_exprc           
         s     |}|jjjj}|jjjj} t|t|  t|d j	t|d j	  tt
 |d j	d t
 |d j	} t|d t
 fdd|D }t|dd |dd D ]\}}||}	|	rx d|	 qedS )zp
        Attempt to verify that rewriting will incorporate user common
        subexpressions properly.
        r   r   c                 3   s"    | ]}  |jjd  V  qdS )r   N)r   r   r   )r   r   ru   r$   r%   	<genexpr>O  s    zBTestArrayExpressions.test_common_subexpressions.<locals>.<genexpr>Nz9Common subexpressions detected in array expressions ({0}))r   rx   r   r   r   r{   r   r   r   r   r   r   zipintersectionfailr   )
ru   rv   r   r   r   array_expr_instrs
array_sets
expr_set_0
expr_set_1intersectionsr$   r   r%   test_common_subexpressions<  s&   
  "
z/TestArrayExpressions.test_common_subexpressionsc                 C   s
   |  tS r   )r   r>   r   r$   r$   r%   test_complex_subexpressionW     
z/TestArrayExpressions.test_complex_subexpressionc                 C   s   t jd}t jd}dd ||fD }tjj}tj||j|jd}|	t
}|j}tj||j|jd}|	t
}	|	j}
t
||}|||}|
||}t j|| t j|| | |jjj|jjj dS )zn
        Verify that ufunc and DUFunc calls are being properly included in
        array expressions.
        r   c                 S   r   r$   r   r   r$   r$   r%   r   a  r   zDTestArrayExpressions.test_ufunc_and_dufunc_calls.<locals>.<listcomp>)re   rf   N)r@   r   rB   _dispatchertargetdescrrb   rp   re   rf   rs   rF   rt   rm   r   r   r   r   r   r   )ru   r   r   rw   
vaxy_descrrx   ry   nb_call_stuff_0r{   r|   nb_call_stuff_1r   r   r   r$   r$   r%   test_ufunc_and_dufunc_callsZ  s4   




z0TestArrayExpressions.test_ufunc_and_dufunc_callsc                 C   *   |  t}| |jjjj|jjjj dS )zQ
        Verify that comparison operators are supported by the rewriter.
        N)r   rI   r   rx   r   r   r   r{   r   r$   r$   r%   test_cmp_op{     

z TestArrayExpressions.test_cmp_opc                 C   r   )zQ
        Check that ufunc calls with explicit outputs are not rewritten.
        N)r   rP   r   rx   r   r   r   r{   r   r$   r$   r%   test_explicit_output  r   z)TestArrayExpressions.test_explicit_outputr   )F)r&   r'   r(   r~   r   r   r   r8   r   rL   r   r   r   r   r   r   r   r=   r   r   r   r   r   r$   r$   r$   r%   rr   v   s$     



!rr   c                   @   sD   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dS )TestRewriteIssuesc                    sn   ddl m} dd l}|dddd  |dd fdd}|d	}||\}}| || | || d S )
Nr   )jitT)nopythonc                 S   s   | S r   r$   )arrr$   r$   r%   foo  s   z.TestRewriteIssues.test_issue_1184.<locals>.fooc                    s    | } | }||fS r   r$   )r   rQ   rR   r   r$   r%   bar  s   z.TestRewriteIssues.test_issue_1184.<locals>.barr   )numbar   numpyr   assertIs)ru   r   r@   r   r   out_cout_dr$   r   r%   test_issue_1184  s   

z!TestRewriteIssues.test_issue_1184c                 C   sN   d}t jj|d d|df}t|}tt|}t j|| t	  d S )Nd   rK   )size)
r@   r   uniformreshapera   r   r   r   gccollect)ru   nr-   r   r   r$   r$   r%   test_issue_1264  s   z!TestRewriteIssues.test_issue_1264c                 C   sX   ddl m} |dd }tjd}tjd}|||}|||}tj|| dS )z*Test array expression with duplicated termr   )r   c                 S   s   t |}|| |  S r   )r@   rC   r,   rN   r$   r$   r%   r     s   
z.TestRewriteIssues.test_issue_1372.<locals>.foor   N)r   r   r@   r   r  py_funcr   assert_allclose)ru   r   r   r,   rN   expectgotr$   r$   r%   test_issue_1372  s   

z!TestRewriteIssues.test_issue_1372c                 C   sF   t dd }d}tjdtjd}|||}|||}| || dS )zP
        Typing of unary array expression (np.negate) can be incorrect.
        c                 S   s   ||  |   S r   r$   r  r$   r$   r%   r     s   z3TestRewriteIssues.test_unary_arrayexpr.<locals>.foog      ?r   rU   N)r   r@   r   int32r  r   )ru   r   rN   r,   r
  r  r$   r$   r%   test_unary_arrayexpr  s   

z&TestRewriteIssues.test_unary_arrayexprc                 C   sN   t dd }tg d}tg d}|||}|||}| || dS )zd
        Typing of bitwise boolean array expression can be incorrect
        (issue #1813).
        c                 S   s   | | @  S r   r$   r  r$   r$   r%   r     s   z5TestRewriteIssues.test_bitwise_arrayexpr.<locals>.foo)TTFF)FTFTN)r   r@   arrayr  r   )ru   r   r,   rN   r
  r  r$   r$   r%   test_bitwise_arrayexpr  s   

z(TestRewriteIssues.test_bitwise_arrayexprc                 C   sX   t t}tddd}||||| t }|| | }| d| | d| dS )zo
        Type annotation of array expressions with disambiguated
        variable names (issue #1466).
        r   r   r   z
#   u.1 = z
#   u.2 = N)r   rT   r@   r   r   inspect_typesgetvalueassertIn)ru   cfuncr,   bufresr$   r$   r%   test_annotations  s   
z"TestRewriteIssues.test_annotationsc                 C   s0   t dd }|d}|d}tj|| d S )Nc                 S   s,   t | }tdD ]
}|| }| }q	|S )NrG   )r@   onesrZ   copy)r-   r   r   valr$   r$   r%   f  s
   

z;TestRewriteIssues.test_issue_5599_name_collision.<locals>.f   )r   r  r@   r   r   )ru   r  r  r
  r$   r$   r%   test_issue_5599_name_collision  s
   

z0TestRewriteIssues.test_issue_5599_name_collisionN)
r&   r'   r(   r   r  r  r  r  r  r  r$   r$   r$   r%   r     s    	r   c                   @      e Zd Zdd ZdS )TestSemanticsc                 C   sb   t }t|}tddtdg}tg d}t|}||||}||||}tj|| d S )N        r?   inf)r   r   r?   )rJ   r   r@   rY   float	ones_liker   r   )ru   pyfuncr  r,   rN   rQ   r
  r  r$   r$   r%   test_division_by_zero  s   
z#TestSemantics.test_division_by_zeroN)r&   r'   r(   r%  r$   r$   r$   r%   r        r  c                   @   s    e Zd ZdZdd Zdd ZdS )TestOptionalsze Tests the arrival and correct lowering of Optional types at a arrayexpr
    derived ufunc, see #3972c                    s   t dd  t  fdd}tddf}|| }|j| }tj||  j}|d d }| t|t	j
 | t|jt	j d S )	Nc                 S      | | S r   r$   r-   r.   r$   r$   r%   arr_expr     z9TestOptionals.test_optional_scalar_type.<locals>.arr_exprc                       |dkrd }n|} | |S Nr   r$   r-   r.   zr*  r$   r%   do_call     
z8TestOptionals.test_optional_scalar_type.<locals>.do_callr  g333333r   r   )r   r@   r   r  r   r	  
signatures
assertTruer   r   OptionaltypeFloatru   r1  rh   r  r   r    otyr$   r0  r%   test_optional_scalar_type  s   

z'TestOptionals.test_optional_scalar_typec                    s   t dd  t  fdd}tdtdf}|| }|j| }tj||  j}|d d }| t|t	j
 | t|jt	j | t|jjt	j d S )	Nc                 S   r(  r   r$   r)  r$   r$   r%   r*  *  r+  z8TestOptionals.test_optional_array_type.<locals>.arr_exprc                        |d dkr	d }n|} | |S r-  r$   r.  r0  r$   r%   r1  .     
z7TestOptionals.test_optional_array_type.<locals>.do_callr        @r   r   )r   r@   r   r  r   r	  r3  r4  r   r   r5  r6  ArrayrV   r7  r8  r$   r0  r%   test_optional_array_type(  s   

z&TestOptionals.test_optional_array_typeN)r&   r'   r(   __doc__r:  r?  r$   r$   r$   r%   r'  	  s    r'  c                   @   s   e Zd Zdd Zdd ZdS )TestOptionalsExceptionsc                    s   |    tdd  t fdd}tddf}| t}||  W d    n1 s-w   Y  | dt|j  j	}|d d	 }| 
t|tj | 
t|jtj d S )
Nc                 S   r(  r   r$   r)  r$   r$   r%   r*  L  r+  zUTestOptionalsExceptions.test_optional_scalar_type_exception_on_none.<locals>.arr_exprc                    r,  r-  r$   r.  r0  r$   r%   r1  P  r2  zTTestOptionalsExceptions.test_optional_scalar_type_exception_on_none.<locals>.do_callr  r?   zexpected float64, got Noner   r   )disable_leak_checkr   r@   r   assertRaises	TypeErrorr  str	exceptionr3  r4  r   r   r5  r6  r7  )ru   r1  rh   raisesr    r9  r$   r0  r%   +test_optional_scalar_type_exception_on_noneH  s   

zCTestOptionalsExceptions.test_optional_scalar_type_exception_on_nonec                    s   |    tdd  t fdd}tdtddf}| t}||  W d    n1 s1w   Y  t|j}| d| | d	|  j	}|d
 d }| 
t|tj | 
t|jtj | 
t|jjtj d S )Nc                 S   r(  r   r$   r)  r$   r$   r%   r*  j  r+  zTTestOptionalsExceptions.test_optional_array_type_exception_on_none.<locals>.arr_exprc                    r;  r-  r$   r.  r0  r$   r%   r1  n  r<  zSTestOptionalsExceptions.test_optional_array_type_exception_on_none.<locals>.do_callr  r?   r=  zexpected array(float64,zgot Noner   r   )rB  r   r@   r   rC  rD  rE  rF  r  r3  r4  r   r   r5  r6  r>  rV   r7  )ru   r1  rh   rG  excstrr    r9  r$   r0  r%   *test_optional_array_type_exception_on_nonef  s"   


zBTestOptionalsExceptions.test_optional_array_type_exception_on_noneN)r&   r'   r(   rH  rJ  r$   r$   r$   r%   rA  E  s    rA  c                   @   s*   e Zd ZdZedZdd Zdd ZdS )TestExternalTypeszJ Tests RewriteArrayExprs with external (user defined) types,
    see #5157z
        from numba.core import types

        class FooType(types.Type):
            def __init__(self):
                super(FooType, self).__init__(name='Foo')
        c                    s|   G dd dt }t G dd dtj}t dd t| fdd}t|tjdd	 }t	
| fd
d}| fS )Nc                   @   r  )z,TestExternalTypes.make_foo_type.<locals>.Fooc                 S   s
   || _ d S r   r   )ru   r   r$   r$   r%   __init__  r   z5TestExternalTypes.make_foo_type.<locals>.Foo.__init__Nr&   r'   r(   rM  r$   r$   r$   r%   Foo  s    rO  c                   @   r  )z1TestExternalTypes.make_foo_type.<locals>.FooModelc                 S   s"   dt jfg}tj| ||| d S )Nr   )r   intpr   StructModelrM  )ru   dmmfe_typemembersr$   r$   r%   rM    s   z:TestExternalTypes.make_foo_type.<locals>.FooModel.__init__NrN  r$   r$   r$   r%   FooModel  r&  rU  r   c                    s    fdd}|S )Nc                         S r   r$   rL  FooTyper$   r%   typer  s   z@TestExternalTypes.make_foo_type.<locals>.type_foo.<locals>.typerr$   )contextrY  rW  r$   r%   type_foo  s   z1TestExternalTypes.make_foo_type.<locals>.type_fooc                 S   s*   |j }|\}t|| |}||_| S r   )ri   r   create_struct_proxyr   	_getvalue)rZ  buildersigrh   typr   r   r$   r$   r%   impl_foo  s
   z1TestExternalTypes.make_foo_type.<locals>.impl_fooc                    rV  r   r$   )r  rQ   rW  r$   r%   
typeof_foo  s   z3TestExternalTypes.make_foo_type.<locals>.typeof_foo)objectr   r   rQ  r   r   r   r   rP  r   register)ru   rX  rO  rU  r[  ra  rb  r$   rW  r%   make_foo_type  s   

zTestExternalTypes.make_foo_typec                    s  t | ju}| |j\ ttjfdd}ttjfdd}ttjfdd}t fdd}t fdd	}t fd
d}t	j
|ddt	ddg t	j
|ddt	ddg t	j
|dt	dg W d    d S 1 s}w   Y  d S )Nc                    s*   t |  rt |tjrdd }|S d S d S )Nc                 S   s   t | j|d gS r-  r@   r  r   lhsrhsr$   r$   r%   imp  s   KTestExternalTypes.test_external_type.<locals>.overload_foo_add.<locals>.imp)r   r   r>  rh  ri  rj  rW  r$   r%   overload_foo_add  s   z>TestExternalTypes.test_external_type.<locals>.overload_foo_addc                    s(   t |  rt | rdd }|S d S d S )Nc                 S   s   t | j|jgS r   rf  rg  r$   r$   r%   rj    s   rk  r   rl  rW  r$   r%   rm    s   c                    s   t |  rdd }|S d S )Nc                 S   s   t | j gS r   rf  r-   r$   r$   r%   rj    s   zKTestExternalTypes.test_external_type.<locals>.overload_foo_neg.<locals>.imprn  )r-   rj  rW  r$   r%   overload_foo_neg  s   
z>TestExternalTypes.test_external_type.<locals>.overload_foo_negc                    s    | t |g S r   )r@   r  r)  rO  r$   r%   arr_expr_sum1  s   z;TestExternalTypes.test_external_type.<locals>.arr_expr_sum1c                    s    |  | S r   r$   r)  rq  r$   r%   arr_expr_sum2  s   z;TestExternalTypes.test_external_type.<locals>.arr_expr_sum2c                    s
    |  S r   r$   ro  rq  r$   r%   arr_expr_neg  s   
z:TestExternalTypes.test_external_type.<locals>.arr_expr_negr   r   rG   rK   rH   )r   source_linesre  rX  r   operatorrM   negr   r@   r   r   r  )ru   test_modulerm  rp  rr  rs  rt  r$   )rO  rX  r%   test_external_type  s$   		"z$TestExternalTypes.test_external_typeN)	r&   r'   r(   r@  textwrapdedentrv  re  rz  r$   r$   r$   r%   rK    s
    
"rK  __main__)>r  ior   r   r@   r   r   r   r   
numba.corer   r   r	   r
   r   r   r   numba.core.compilerr   r   numba.core.registryr   numba.tests.supportr   r   r   r   numba.extendingr   r   r   r   r   r   r   rw  r{  unittestdictr   r/   r1   r8   r=   r>   rB   rF   rI   rJ   rL   rP   rT   ra   rb   rr   r   r  r'  rA  rK  r&   mainr$   r$   r$   r%   <module>   sN    $$	  l<Ca