o
    ,wÖiý   ã                   @   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mZmZm	Z	m
Z
 ddlmZ ddlmZ ddlZddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlZG dd„ dejƒZG dd„ dejƒZG dd„ dƒZd6deeef fdd„Zddœdd„Z d7dd„Z!ddœdd„Z"dd„ Z#d8ddœdd„Z$dej%e fd d!„Z&dej%fd"d#„Z'G d$d%„ d%ƒZ(e(ƒ fd&d'„Z)ej*G d(d)„ d)ƒƒZ+ej*G d*d+„ d+ƒƒZ,d,d-„ Z-e
d.ƒZ.ej*G d/d0„ d0e	e. ƒƒZ/G d1d2„ d2ej0ƒZ1G d3d4„ d4ej0ƒZ2e3d5krýe 4¡  dS dS )9z*Tests for the `fiddle._src.config` module.é    N)ÚAnyÚDictÚGenericÚTypeVar)Úabsltest)Úparameterized)Údaglish)Úhistory)Úconfig)Údaglish_legacy)Údemo_configsc                   @   ó   e Zd ZdZdS )ÚTag1zOne tag.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úT/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/fiddle/_src/config_test.pyr   #   ó    r   c                   @   r   )ÚTag2zAnother tag.Nr   r   r   r   r   r   '   r   r   c                   @   sL   e Zd ZU eed< eed< eed< eed< ddd„Zdd	„ Zed
d„ ƒZdS )ÚSampleClassÚarg1Úarg2Úkwarg1Úkwarg2Nc                 C   s   | j  tƒ ¡ d S ©N)Ú__dict__ÚupdateÚlocals)Úselfr   r   r   r   r   r   r   Ú__init__1   s   zSampleClass.__init__c                 C   ó   dS )Né   r   ©r!   r   r   r   Úa_method4   ó   zSampleClass.a_methodc                 C   s
   | ddƒS ©Né   é   r   )Úclsr   r   r   Úa_classmethod7   s   
zSampleClass.a_classmethod©NN)	r   r   r   r   Ú__annotations__r"   r&   Úclassmethodr,   r   r   r   r   r   +   s   
 
r   Úreturnc                 C   ó   t ƒ S r   ©r    ©r   r   r   r   r   r   r   Úbasic_fn<   ó   r4   ©r   c                G   r1   r   r2   )r   r   Úargsr   r   r   Úfn_with_var_args@   r5   r8   c                 K   r1   r   r2   )r   r   Úkwargsr   r   r   Úfn_with_var_kwargsD   r5   r:   c                O   r1   r   r2   )r   r   r7   r9   r   r   r   Úfn_with_var_args_and_kwargsH   r5   r;   c                  O   r1   r   r2   )r7   r9   r   r   r   Úfn_with_args_and_kwargs_onlyL   r5   r<   r)   c               O   r1   r   r2   ©ÚaÚbÚcr   r7   r9   r   r   r   Úfn_with_position_argsP   r5   rA   c                   C   s   t jtdddS )z?Helper function which returns a fdl.Config whose type is known.r)   r*   ©r   r   )ÚfdlÚConfigr   r   r   r   r   Úmake_typed_configT   s   rE   c                 K   s   t j| fi |¤ŽS )z4Helper function which returns an untyped fdl.Config.)rC   rD   )Úarg_to_configurer9   r   r   r   Úmake_untyped_configY   s   rG   c                   @   ó   e Zd Zdd„ ZdS )ÚUnserializablec                 C   ó   t ƒ ‚r   ©ÚNotImplementedErrorr%   r   r   r   Ú__getstate__`   r5   zUnserializable.__getstate__N)r   r   r   rM   r   r   r   r   rI   ^   s    rI   c                 C   s   | S r   r   ©Úxr   r   r   Ú_test_fn_unserializable_defaultd   r'   rP   c                   @   ó   e Zd ZU dZeed< dS )ÚDataclassChildr   rO   N)r   r   r   rO   Úintr.   r   r   r   r   rR   h   ó   
 rR   c                   @   s"   e Zd ZU ejedZeed< dS )ÚDataclassParent)Údefault_factoryÚchildN)r   r   r   ÚdataclassesÚfieldrR   rW   r.   r   r   r   r   rU   m   s   
 rU   c                   C   s   t dƒ‚)NzMy fancy exception)Ú
ValueErrorr   r   r   r   Úraise_errorr   ó   r[   Ú_Tc                   @   rQ   )ÚGenericClassr)   rO   N)r   r   r   rO   r]   r.   r   r   r   r   r^   y   rT   r^   c                   @   sl  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d„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Zd;d<„ Z d=d>„ Z!d?d@„ Z"dAdB„ Z#dCdD„ Z$dEdF„ Z%dGdH„ Z&dIdJ„ Z'dKdL„ Z(dMdN„ Z)dOdP„ Z*dQdR„ Z+dSdT„ Z,dUdV„ Z-dWdX„ Z.dYdZ„ Z/d[d\„ Z0d]d^„ Z1d_d`„ Z2dadb„ Z3dcdd„ Z4dedf„ Z5dgdh„ Z6didj„ Z7dkdl„ Z8dmdn„ Z9dodp„ Z:dqdr„ Z;dsdt„ Z<dudv„ Z=dwdx„ Z>dydz„ Z?d{d|„ Z@d}d~„ ZAdd€„ ZBdd‚„ ZCdƒd„„ ZDd…d†„ ZEd‡dˆ„ ZFd‰dŠ„ ZGd‹dŒ„ ZHddŽ„ ZIdd„ ZJd‘d’„ ZKd“d”„ ZLd•d–„ ZMd—d˜„ ZNd™S )šÚ
ConfigTestc                 C   s°   t jtddd}t |t jt ¡ |  |jd¡ |  |jd¡ d|_|  |jd¡ d|_d|_	t  
|¡}t |t¡ |  |jd¡ |  |jd¡ |  |j	d¡ |  |jd¡ d S )Nr)   r   ©r   r   r   r   )rC   rD   r   Úpytype_extensionsÚassert_typeÚassertEqualr   r   r   r   Úbuild©r!   Úclass_configÚinstancer   r   r   Útest_config_for_classes€   s   
z"ConfigTest.test_config_for_classesc                 C   sž   t jtddd}t |t jtttf  ¡ |  |j	d¡ |  |j
d¡ d|_	|  |j	d¡ d|_d|_t  |¡}t |tttf ¡ |  |dddddœ¡ d S )Nr)   r   r`   r   r   r   r3   )rC   rD   r4   ra   rb   r   Ústrr   rc   r   r   r   r   rd   )r!   Ú	fn_configÚresultr   r   r   Útest_config_for_functions‘   s$   ÿ
üz$ConfigTest.test_config_for_functionsc                 C   sŽ   t jtddd}t |t j¡ t  |¡}|  |d d¡ |  |d d¡ d|_d|_t  |¡}t |t	¡ |  |d d¡ |  |d d¡ d S )Nr   r   r6   Únew_arg1Ú
new_kwarg1)
rC   rD   r8   ra   rb   rd   rc   r   r   r   ©r!   rj   Úfn_argsr   r   r   Ú'test_config_for_functions_with_var_args¦   s   

z2ConfigTest.test_config_for_functions_with_var_argsc                 C   s”   t jtddddd}t  |¡}|  |d d¡ |  |d d¡ |  |d dddœ¡ d|_d	|_t  |¡}|  |d d¡ |  |d dd	dœ¡ d S )
Nr   r   r   Úkwarg3)r   r   rr   r9   )r   rr   rn   Ú
new_kwarg3)rC   rD   r:   rd   rc   r   rr   ro   r   r   r   Ú)test_config_for_functions_with_var_kwargs´   s,   û

þ

þz4ConfigTest.test_config_for_functions_with_var_kwargsc                 C   sP   t jtdd}t  |¡}|  |d d¡ d|_t  |¡}|  |d ddi¡ d S )Nr   )r   Úkwarg_called_kwargr9   )rC   rD   r;   rd   rc   r9   ro   r   r   r   Ú2test_config_for_functions_with_var_args_and_kwargsÌ   s   



ÿz=ConfigTest.test_config_for_functions_with_var_args_and_kwargsc                 C   sh   t  tddddd¡}|  |d d¡ |  |d d¡ |  |dd … ddg¡ |  |d d … g d¢¡ d S )	Nr)   r*   é   r$   é   r   éÿÿÿÿ)r)   r*   rw   r$   rx   )rC   rD   rA   rc   ÚassertSequenceEqual©r!   rj   r   r   r   Útest_positional_args_access×   s
   z&ConfigTest.test_positional_args_accessc              	   C   sf  |   d¡^ t tddddd¡}d|d< |  |d d … g d¢¡ g d	¢|d d…< |  |d d … g d
¢¡ g d¢|dd …< |  |d d … g d¢¡ g d¢|d d …< |  |d d … g d¢¡ W d   ƒ n1 sfw   Y  |   d¡9 dd„ }t |ddd¡}d|d< |  |d d … g d¢¡ ddg|d d…< |  |d d … g d¢¡ W d   ƒ d S 1 s¬w   Y  d S )NÚwith_var_positionalr)   r*   rw   r$   rx   r   )r   r*   rw   r$   rx   )rx   é   é   )rx   r~   r   r$   rx   )é   é	   é
   )rx   r~   r   r€   r   r‚   )r)   r*   rw   r$   rx   r~   Úwo_var_positionalc                S   ó
   | ||fS r   r   ©r>   r?   r@   r   r   r   Úfooì   ó   
z9ConfigTest.test_positional_args_modification.<locals>.foo)r   r*   rw   )r$   rx   rw   )ÚsubTestrC   rD   rA   rz   )r!   rj   r†   r   r   r   Ú!test_positional_args_modificationÞ   s&   ÷"÷z,ConfigTest.test_positional_args_modificationc              	   C   sŽ   t  tdddddd¡}|d= |  |d d … tjdddddg¡ |d= |  |d d … tjddddg¡ |dd …= |  |d d … tjddg¡ d S )	Nr)   r*   rw   r$   rx   r~   r   ry   )rC   rD   rA   rc   Ú
config_libÚNO_VALUEr{   r   r   r   Útest_positional_args_deleteõ   s   " 
 z&ConfigTest.test_positional_args_deletec              	   C   sV   t  tdddddd¡}|`|  |d d … g d¢¡ |  |d d¡ |  |d	 d¡ d S )
Nr   r)   r*   rw   r$   rx   ©r   r)   r)   rw   r$   rx   ry   éúÿÿÿ©rC   rD   rA   r@   rc   r{   r   r   r   Útest_negative_index_accessþ   s
   z%ConfigTest.test_negative_index_accessc              	   C   sv   t  tdddddd¡}|`|  |d d … g d¢¡ d|d	< |  |d d … g d
¢¡ d|d< |  |d d … g d¢¡ d S )Nr   r)   r*   rw   r$   rx   r   éûÿÿÿry   )r   r)   r)   rw   r$   r‘   r~   rŽ   )r~   r)   r)   rw   r$   r‘   r   r{   r   r   r   Útest_negative_index_modify  s   z%ConfigTest.test_negative_index_modifyc                 C   s<   dd„ }t  |¡}d|d< |  |d d … tjtjdg¡ d S )Nc                S   r„   r   r   r…   r   r   r   r†     r‡   z8ConfigTest.test_modify_positional_only_args.<locals>.foorx   r*   )rC   rD   rc   rŠ   r‹   )r!   r†   rj   r   r   r   Ú test_modify_positional_only_args  s   
ÿz+ConfigTest.test_modify_positional_only_argsc              	   C   sz   t  tdddddd¡}|`|  |d d … g d¢¡ |d= |  |d d … g d	¢¡ |d
= |  |d d … tjddddg¡ d S )Nr   r)   r*   rw   r$   rx   r   ry   )r   r)   r)   rw   r$   r‘   )rC   rD   rA   r@   rc   rŠ   r‹   r{   r   r   r   Útest_negative_index_delete  s   
þz%ConfigTest.test_negative_index_deletec                 C   sD   t  tddddd¡}|  |t j d¡ |  |t jd … ddg¡ d S )Nr)   r*   rw   r$   rx   )rC   rD   rA   rc   ÚVARARGSrz   r{   r   r   r   Ú test_varargs_index_handle_access$  s   z+ConfigTest.test_varargs_index_handle_accessc                 C   sŠ   t  tddddd¡}g |t jd …< |  |d d … g d¢¡ g d¢|t jd …< |  |d d … g d¢¡ d	|t j< |  |d d … g d
¢¡ d S )Nr)   r*   rw   r$   rx   ©r)   r*   rw   ©r   r€   r   )r)   r*   rw   r   r€   r   r   )r)   r*   rw   r   r€   r   ©rC   rD   rA   r•   rz   r{   r   r   r   Ú test_varargs_index_handle_modify)  s   
z+ConfigTest.test_varargs_index_handle_modifyc                 C   s\   t  tddddd¡}|t j= |  |d d … g d¢¡ |t jd …= |  |d d … g d¢¡ d S )Nr)   r*   rw   r$   rx   )r)   r*   rw   rx   r—   r™   r{   r   r   r   Ú test_varargs_index_handle_delete2  s
   z+ConfigTest.test_varargs_index_handle_deletec                 C   sR   t  tddd¡}|  |t jd … ¡ g d¢|t jd …< |  |d d … g d¢¡ d S )Nr)   r*   rw   r…   )r)   r*   rw   r>   r?   r@   )rC   rD   rA   ÚassertEmptyr•   rz   r{   r   r   r   Ú)test_modification_when_var_args_are_empty9  s   z4ConfigTest.test_modification_when_var_args_are_emptyc                 C   sP   t  td¡}|  |d d … g d¢¡ ddg|d d…< |  |d d … g d¢¡ d S )Nr   )r   r   r)   rx   r~   r*   )rx   r~   r)   )rŠ   rD   rA   rc   )r!   Úfn_cfgr   r   r   Ú*test_only_some_positional_args_are_defined?  s   z5ConfigTest.test_only_some_positional_args_are_definedc                 C   s~   t  tddddd¡}|  td¡ |j}W d   ƒ n1 sw   Y  |  td¡ |j}W d   ƒ d S 1 s8w   Y  d S )Nr)   r*   rw   r$   rx   z>Cannot access positional-only or variadic positional arguments©rC   rD   rA   ÚassertRaisesRegexÚAttributeErrorr7   r>   ©r!   rj   Ú_r   r   r   Ú/test_positional_args_direct_access_is_forbiddenE  s   þüþ"üz:ConfigTest.test_positional_args_direct_access_is_forbiddenc                 C   s€   t  tddddd¡}|  td¡ dg|_W d   ƒ n1 sw   Y  |  td¡ d|_W d   ƒ d S 1 s9w   Y  d S )	Nr)   r*   rw   r$   rx   z&Cannot access VAR_POSITIONAL parameterr   z'Cannot access POSITIONAL_ONLY parameterr    r{   r   r   r   Ú5test_positional_args_direct_modification_is_forbiddenS  s   ÿ
ýÿ"ýz@ConfigTest.test_positional_args_direct_modification_is_forbiddenc                 C   sD   t  tddddd¡}d|d< |  |jd¡ d|_|  |d d¡ d S )Nr)   r*   rw   r$   rx   zarg-cúindex-2)rC   rD   rA   rc   r@   r{   r   r   r   Ú6test_positional_or_keyword_args_have_consistent_values_  s
   zAConfigTest.test_positional_or_keyword_args_have_consistent_valuesc                 C   sV   t  t¡}g d¢}g d¢}||d d…< ||dd …< ||dd …< |  |d d … |¡ d S )Nr—   r˜   rw   r‚   )rŠ   rD   rA   rz   )r!   rj   ÚarrÚaddedr   r   r   Útest_set_out_of_range_indexf  s   
z&ConfigTest.test_set_out_of_range_indexc                 C   s   t  tdd¡}|  |d d … d¡ |  td¡ d|d< W d   ƒ n1 s&w   Y  |  td¡ |d }W d   ƒ d S 1 sAw   Y  d S )Nr)   r*   zindex out of ranger§   )rC   rD   r8   Ú	assertLenr¡   Ú
IndexErrorr£   r   r   r   Útest_index_out_of_rangeo  s   
ÿ
"ÿz"ConfigTest.test_index_out_of_rangec                 C   s\   t  tdd¡}|  |d d … d¡ |d d … }| d¡ |  |d d … d¡ |  |d¡ d S )Nr)   r*   Ú3rw   )rC   rD   r8   r¬   Úappend)r!   rj   Úa_copyr   r   r   Útest_args_config_shallow_copyw  s   
z(ConfigTest.test_args_config_shallow_copyc              
   C   s8   t  tddddd¡}|  t  |¡ddddd i dœ¡ d S )Nr)   r*   rw   r$   rx   ©r$   rx   ©r>   r?   r@   r7   r   r9   )rC   rD   rA   rc   rd   r{   r   r   r   Útest_args_config_build  s
   þz!ConfigTest.test_args_config_buildc                 C   s`   t jtdddddt jtdddd	d
d}|  t  |¡ddddddddtƒ d	d	idœi dœ¡ d S )Nr)   r*   rw   r$   rx   r>   r?   r   r   ©r   r   r6   r³   r=   r´   )rC   rD   rA   rc   rd   Útupler{   r   r   r   Ú(test_nested_positional_args_config_build†  s6   
ÿùúóþz3ConfigTest.test_nested_positional_args_config_buildc                 C   s8   t jtddd}d|_t  |¡}|  |ddddœ¡ d S )Nr)   r*   ©r>   r?   rw   r…   )rC   rD   Údictr@   rd   rc   )r!   Údict_configrg   r   r   r   Útest_config_for_dicts¥  s   
z ConfigTest.test_config_for_dictsc                 C   s˜   ddt dtfdd„}t |¡}|  d|j¡ |  d|j¡ t |¡}|  d|d ¡ |  d|d ¡ d|_t |¡}|  d|d ¡ |  d|d ¡ d S )	Nr*   ÚabcrO   Úyc                 S   r1   r   r2   )rO   r¾   r   r   r   Úmy_func­  r5   z9ConfigTest.test_config_with_default_args.<locals>.my_funcÚxyz)r*   r½   )rS   ri   rC   rD   rc   rO   r¾   rd   )r!   r¿   ÚcfgÚobjr   r   r   Útest_config_with_default_args«  s   


z(ConfigTest.test_config_with_default_argsc                 C   sf   d
dt dtdtfdd„}t |¡}|  d|j¡ |  i |j¡ d|_t 	|¡}|  dddd	œ|¡ d S )Nr½   ç       @rO   r¾   Úzc                 S   r1   r   r2   ©rO   r¾   rÅ   r   r   r   r¿   ¿  r5   zAConfigTest.test_config_defaults_not_materialized.<locals>.my_funcé*   rÆ   )r½   rÄ   )
rS   ri   ÚfloatrC   rD   rc   r¾   Ú__arguments__rO   rd   )r!   r¿   rÁ   Úoutputr   r   r   Ú%test_config_defaults_not_materialized½  s   

z0ConfigTest.test_config_defaults_not_materializedc                 C   sØ   dddddœ}t jtg| ¡ ¢R Ž }t jtt  t j|¡|d}t jtt  t j|¡|d}t  |¡}|d }|ƒ }|  t	|ƒt¡ |  | 
¡ |¡ |  |j|¡ |d }|  t	|ƒt¡ |  | 
¡ |¡ |  |j|¡ d S )	NÚ
innermost1Ú
innermost2Úkw1Úkw2r3   rB   r   r   )rC   rD   r4   Úvaluesr   ÚcastÚPartialrd   rc   Útyper   r   )r!   Úfn_config1_argsÚ
fn_config1rf   Ú
fn_config2Úfn_config2_argsÚtest_class_partialÚtest_class_instancer   r   r   Útest_nested_configsÌ  s,   üÿÿ
zConfigTest.test_nested_configsc                 C   sÞ   t jtddddd}t |¡}d|_|  |jd¡ t  t|||g|fdœ¡}t  |¡}|d }|d d d	 }|d }|  ||¡ |  	|d d	 |¡ |  	|d d
 |¡ |  	|d d	 |¡ |  |jd¡ |  |jd¡ d S )Nr   r   r   r   r¶   Úseparate_arg1)Úkey1Úkey2rÜ   r   r)   rÝ   )
rC   rD   r   Úcopyr   rc   r4   rd   ÚassertIsNotÚassertIs)r!   rf   Úclass_config_copyrj   rp   Úseparate_instanceÚshared_instanceÚ	structurer   r   r   Útest_instance_sharingç  s(   
ÿ
þ
z ConfigTest.test_instance_sharingc                 C   sŒ   t  tdd¡t  tdd¡g}t  t¡}||_||_t  |¡}|  |t¡ |  |j|j¡ |  |jd |jd ¡ |  |jd |jd ¡ d S )Nr)   r>   r*   r?   r   )	rC   rD   r4   r   r   r   rd   ÚassertIsInstancerà   )r!   Úchild_configsrÁ   rÂ   r   r   r   Ú!test_instance_sharing_collections  s   

z,ConfigTest.test_instance_sharing_collectionsc                 C   sV   t  tdd¡}t  t|d¡}t |¡}d|_|  |jd¡ d|j_|  |jjd¡ d S ©Nr   r   Úfn_arg2Úfn_arg2_copyÚmutated)rC   rD   r   r4   rÞ   r   rc   r   ©r!   rf   rj   Úfn_config_copyr   r   r   Útest_shallow_copy  ó   
zConfigTest.test_shallow_copyc           	      C   sT  G dd„ dt jƒ}|ddƒ}|d|ƒ}|  d¡# t |¡}|  ||¡ |  |j|¡ d|_|  ||¡ W d   ƒ n1 s>w   Y  |  d¡$ t 	|¡}|  ||¡ |  
|j|¡ d|j_|  ||¡ W d   ƒ n1 sow   Y  |  d	¡' tj|d
d}dd„ | ¡ D ƒ}|d|dddœ}|  ||¡ W d   ƒ d S 1 s£w   Y  d S )Nc                       s(   e Zd Z‡ fdd„Zedd„ ƒZ‡  ZS )z=ConfigTest.test_buildable_subclass.<locals>.SampleClassConfigc                    s   t ƒ jtg|¢R i |¤Ž d S r   )Úsuperr"   r   )r!   r7   r9   ©Ú	__class__r   r   r"     s   zFConfigTest.test_buildable_subclass.<locals>.SampleClassConfig.__init__c                 S   s   | di |  |¡¤ŽS )Nr   )Ú	arguments)r+   rÐ   Úmetadatar   r   r   Ú__unflatten__   s   zKConfigTest.test_buildable_subclass.<locals>.SampleClassConfig.__unflatten__)r   r   r   r"   r/   rö   Ú__classcell__r   r   rò   r   ÚSampleClassConfig  s    rø   r)   r*   r†   rÞ   ÚblahÚdeepcopyÚtraverseF)Úmemoizable_onlyc                 S   s   i | ]
\}}t  |¡|“qS r   )r   Úpath_str)Ú.0ÚpathÚvaluer   r   r   Ú
<dictcomp>8  s    
ÿÿz6ConfigTest.test_buildable_subclass.<locals>.<dictcomp>)Ú z.arg1z.arg2z
.arg2.arg1z
.arg2.arg2)rC   rD   rˆ   rÞ   rc   rà   r   r   ÚassertNotEqualrú   rß   r   Úcollect_value_by_pathÚitems)	r!   rø   Úsub_cfgrÁ   Úcfg_copyÚcfg_deepcopyÚvalues_by_pathÚvalues_by_path_strÚexpectedr   r   r   Útest_buildable_subclass  s@   
	

û
ûÿþû"òz"ConfigTest.test_buildable_subclassc                 C   sV   t  tdd¡}t  t|d¡}t |¡}d|_|  |jd¡ d|j_|  |jjd¡ d S ré   )	rC   rD   r   r4   rÞ   rú   r   rc   r   rí   r   r   r   Útest_deep_copyE  rð   zConfigTest.test_deep_copyc                 C   s\   t  tdd¡}t jt||d}|  |j|j¡ t |¡}|  	|j|j¡ |  |j|j¡ d S )Nr   r   rB   )
rC   rD   r   r4   rà   r   r   rÞ   rú   rß   rí   r   r   r   Ú)test_deep_copy_preserves_instance_sharingP  s   
z4ConfigTest.test_deep_copy_preserves_instance_sharingc                 C   s0   |   tjt tj¡¡ |   tjt tj¡¡ d S r   )rà   rC   r‹   rÞ   rú   r%   r   r   r   Útest_deep_copy_no_valueX  s   z"ConfigTest.test_deep_copy_no_valuec                 C   s:   t  td¡}t  td¡}|  ||¡ d|_|  ||¡ d S )Nr   r   )rC   rD   r   rc   r   r  ©r!   Úcfg1Úcfg2r   r   r   Útest_equality_arguments\  s
   z"ConfigTest.test_equality_argumentsc                 C   sP   dd„ }|ƒ }|ƒ }|   ||¡ d|jj_|  ||¡ d|jj_|   ||¡ d S )Nc                  S   sL   t jtddddd} t jtt  t j| ¡| d}t jtt  t j|¡|d}|S )NrÌ   rÍ   rÎ   rÏ   r3   rB   )rC   rD   r4   r   rÑ   rÒ   )rÕ   rf   rÖ   r   r   r   Úmake_nested_confige  s   ûÿÿzEConfigTest.test_equality_arguments_nested.<locals>.make_nested_configzanother value)rc   r   r   r   r  )r!   r  r  r  r   r   r   Útest_equality_arguments_nestedc  s   

z)ConfigTest.test_equality_arguments_nestedc                 C   s(   t  td¡}t  td¡}|  ||¡ d S )Nr   )rC   rD   r   r4   r  )r!   Úcls_cfgrž   r   r   r   Ú test_equality_fn_or_cls_mismatchz  ó   z+ConfigTest.test_equality_fn_or_cls_mismatchc                 C   s€   t  td¡}|  |d¡ t  t j|¡}|  ||¡ G dd„ dt jƒ}t  ||¡}|  ||¡ |  | |¡¡ |  | |¡¡ d S )Nr   rx   c                   @   s   e Zd ZdS )zHConfigTest.test_equality_buildable_type_mismatch.<locals>.ConfigSubClassN)r   r   r   r   r   r   r   ÚConfigSubClassŠ  s    r  )rC   rD   r   r  rÑ   rÒ   ÚassertFalseÚ__eq__)r!   rÁ   Úpartialr  Úcfg_subclassr   r   r   Ú%test_equality_buildable_type_mismatch  s   z0ConfigTest.test_equality_buildable_type_mismatchc                 C   s(   t  tj¡}t  tj¡}|  ||¡ d S r   )rC   rD   r   r,   rc   )r!   Úcfg_aÚcfg_br   r   r   Útest_equality_classmethods•  r  z%ConfigTest.test_equality_classmethodsc              
   C   sj   t  td¡}t  tdd¡}t jtddd}t  tddddddd¡}|  ||¡ |  ||¡ |  ||¡ d S )	Nr>   r   r)   ©r@   r*   rw   r$   rx   )rC   rD   rA   rc   r  )r!   r  r   Úcfg_cÚcfg_dr   r   r   Ú+test_equality_positional_args_default_valueš  s   z6ConfigTest.test_equality_positional_args_default_valuec                 C   s`   t  tdd¡}t jtddd d d}|  ||¡ t  tdd¡}t jtddd d d}|  ||¡ d S )Nr)   r*   r`   )rC   rD   r   rc   r4   r  r   r   r   Útest_default_value_equality£  s   z&ConfigTest.test_default_value_equalityc                 C   s\   t jdkrt td¡}|  t |¡tdƒ¡ |  t t¡jd¡ |  t tt ¡jd¡ d S )N)rw   r   r)   )	ÚsysÚversion_inforC   rD   r^   rc   rd   rO   rS   ©r!   rÁ   r   r   r   Útest_generic_classes¬  s
   
zConfigTest.test_generic_classesc                 C   sf   t jdddG dd„ dƒƒ}|ƒ fdd„}t |¡}|ƒ |_t |¡\}}|  ||¡ |  ||¡ d S )NTF)ÚfrozenÚeqc                   @   rH   )zTConfigTest.test_config_with_non_comparable_values.<locals>.ClassWithDisabledEqualityc                 S   rJ   r   rK   ©r!   r¤   r   r   r   r  ¾  r5   z[ConfigTest.test_config_with_non_comparable_values.<locals>.ClassWithDisabledEquality.__eq__N)r   r   r   r  r   r   r   r   ÚClassWithDisabledEquality»  s    r.  c                 S   s   | |fS r   r   )Úvalue1Úvalue2r   r   r   Úfn_with_non_comparable_defaultÁ  s   zYConfigTest.test_config_with_non_comparable_values.<locals>.fn_with_non_comparable_default)rX   Ú	dataclassrC   rD   r/  rd   ræ   )r!   r.  r1  rÁ   r/  r0  r   r   r   Ú&test_config_with_non_comparable_values´  s   
ÿ
z1ConfigTest.test_config_with_non_comparable_valuesc                 C   s  t  tdd¡}t  tdd¡}|  d¡ ||g}||g}|  ||¡ W d   ƒ n1 s,w   Y  |  d¡ t  t||¡}t  t||¡}|  ||¡ W d   ƒ n1 sUw   Y  |  d¡ t  t|||¡}t  t|||¡}|  ||¡ W d   ƒ d S 1 sw   Y  d S )Nr)   r*   Úpython_listÚnode_sharing_detectionÚnode_sharing_difference)rC   rD   r   rˆ   rc   r  )r!   r>   r?   rO   r¾   r   r   r   Ú$test_config_dag_structure_comparisonÌ  s"   ýý"ýz/ConfigTest.test_config_dag_structure_comparisonc                 C   ó   t  ¡ \}}|  ||¡ d S r   ©r   Ú1get_equal_but_not_object_identical_string_configsrc   ©r!   rO   r¾   r   r   r   Ú"test_config_internables_comparisonÞ  ó   z-ConfigTest.test_config_internables_comparisonc                 C   r8  r   r9  r;  r   r   r   Ú)test_dict_with_different_order_comparisonâ  r=  z4ConfigTest.test_dict_with_different_order_comparisonc                 C   s¾   t  t¡}d|_d|_|`|  td¡ |j}W d   ƒ n1 s!w   Y  |  td¡
 |`W d   ƒ n1 s9w   Y  |  td¡
 |`W d   ƒ n1 sQw   Y  |  d|j¡ d S )Nrw   r$   z No parameter 'arg1' has been setz'arg1'z'unknown_arg')	rC   rD   r4   r   r   r¡   r¢   Úunknown_argrc   r£   r   r   r   Útest_unsetting_argumentæ  s    
ÿþÿÿz"ConfigTest.test_unsetting_argumentc                 C   s¨   t  t¡}d|_d|_| ¡ \}}t j ||¡}|  |jd d jj	|jd d jj	¡ |  |jd d j
d¡ |  |jd d j
d¡ |  |jd d jtjj¡ d S )Nr$   rx   r   ry   r   r)   )rC   rD   r   r   Ú__flatten__rö   rc   Ú__argument_history__ÚlocationÚline_numberÚ	new_valueÚkindr	   Ú
ChangeKindÚ	NEW_VALUE)r!   rÁ   rÐ   rõ   Úcopiedr   r   r   Ú test_flatten_unflatten_historiesù  s   
þÿz+ConfigTest.test_flatten_unflatten_historiesc                 C   ó"   t  t¡}|  g d¢t|ƒ¡ d S ©Nr3   )rC   rD   r4   rc   Údirr{   r   r   r   Útest_dir_simple  ó   
zConfigTest.test_dir_simplec                 C   rK  rL  )rC   rD   r   rc   rM  r)  r   r   r   Útest_dir_cls  rO  zConfigTest.test_dir_clsc                 C   s(   t  t¡}d|_|  g d¢t|ƒ¡ d S )NÚ123)r½   r   r   )rC   rD   r;   r½   rc   rM  )r!   Úvarargs_configr   r   r   Útest_dir_var_args_and_kwargs  s   
z'ConfigTest.test_dir_var_args_and_kwargsc                 C   sN   t ƒ }t |tjt ¡ t |¡}t |t¡ |  |jd¡ |  |j	d¡ d S r(   )
rE   ra   rb   rC   rD   r   rd   rc   r   r   re   r   r   r   Útest_typed_config  s   
zConfigTest.test_typed_configc                 C   sR   t tddd}t |tj¡ t |¡}t |t¡ |  |j	d¡ |  |j
d¡ d S )Nr*   rw   rB   )rG   r   ra   rb   rC   rD   rd   r   rc   r   r   re   r   r   r   Útest_untyped_config  s   
zConfigTest.test_untyped_configc                 C   ó*   t jtdddd}d}|  t|ƒ|¡ d S )Nr)   r*   r   r6   z6<Config[SampleClass(arg1=1, arg2=2, kwarg1='kwarg1')]>)rC   rD   r   rc   Úrepr)r!   rf   Úexpected_reprr   r   r   Útest_repr_class_config$  ó   z!ConfigTest.test_repr_class_configc                 C   s8   t  tdt  tdt  td¡¡¡}d}|  t|ƒ|¡ d S )Nr)   Ú2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz<Config[basic_fn(
  arg1=1,
  arg2=<Config[basic_fn(
    arg1='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    arg2=<Config[basic_fn(arg1=1)]>)]>)]>©rC   rD   r4   rc   rW  )r!   r
   rX  r   r   r   Útest_repr_nested_indentation)  s
   ÿz'ConfigTest.test_repr_nested_indentationc                 C   rV  )Nr)   r*   r   r6   z3<Config[basic_fn(arg1=1, arg2=2, kwarg1='kwarg1')]>r\  )r!   rj   rX  r   r   r   Útest_repr_fn_config3  rZ  zConfigTest.test_repr_fn_configc                 C   s.   t jtdddddd}d}|  t|ƒ|¡ d S )Nr)   r*   rw   r$   rx   )rO   rÅ   r¾   r   z=<Config[fn_with_var_kwargs(arg1=1, kwarg1=5, x=2, z=3, y=4)]>)rC   rD   r:   rc   rW  )r!   rÁ   rX  r   r   r   Útest_repr_varkwargs8  s   ÿzConfigTest.test_repr_varkwargsc                 C   sL   t  td¡}d}|  t|¡ t|dƒ W d   ƒ d S 1 sw   Y  d S )Nr)   zRNo parameter 'nonexistent_arg' has been set on <Config\[SampleClass\(arg1=1\)\]>\.Únonexistent_arg)rC   rD   r   r¡   r¢   Úgetattr©r!   rf   Úexpected_msgr   r   r   Ú test_nonexistent_attribute_error@  s
   "ÿz+ConfigTest.test_nonexistent_attribute_errorc                 C   sF   t  t¡}d}|  t|¡ d|_W d   ƒ d S 1 sw   Y  d S )Nz~No parameter named 'nonexistent_arg' exists for <class '.*\.SampleClass'>; valid parameter names: arg1, arg2, kwarg1, kwarg2\.zerror!)rC   rD   r   r¡   r¢   r`  rb  r   r   r   Ú test_nonexistent_parameter_errorG  s
   
"ÿz+ConfigTest.test_nonexistent_parameter_errorc                    st   dt dtfdd„‰ dt dtf‡ fdd„}t |d¡}d}|  t|¡ t |¡ W d   ƒ d S 1 s3w   Y  d S )	NrO   r0   c                 S   s   t | ƒS r   )ri   rN   r   r   r   Úinner_buildQ  r\   z7ConfigTest.test_build_inside_build.<locals>.inner_buildc                    s   t  ˆ | ¡}t  |¡S r   ©rC   rD   rd   )rO   rÁ   ©rf  r   r   Ú	nest_callT  s   
z5ConfigTest.test_build_inside_build.<locals>.nest_callrw   z8forbidden to call `fdl.build` inside another `fdl.build`)rS   ri   rC   rD   r¡   Ú	Exceptionrd   )r!   ri  Úouterrc  r   rh  r   Útest_build_inside_buildO  s   "ÿz"ConfigTest.test_build_inside_buildc                 C   s’  t  td¡}d|_|`|  tg d¢ƒt|j ¡ ƒ¡ |  	|jd d¡ |  	|jd d¡ |  d|jd d j
¡ |  d|jd d j¡ |  t|jd d jƒd	¡ |  d|jd d j
¡ |  d|jd d j¡ |  t|jd d jƒd	¡ |  d|jd d j
¡ |  tj|jd d j¡ |  t|jd d jƒd	¡ |  |jd d jd |jd d j¡ |  |jd d jd |jd d j¡ d S )
NÚ
arg1_valueÚ
arg2_value©r   r   Ú__fn_or_cls__r   r*   r   r)   r   z(config_test.py:\d+:test_history_tracking)rC   rD   r   r   r   rc   ÚsetrB  Úkeysr¬   Ú
param_namerE  ÚassertRegexri   rC  r	   ÚDELETEDÚsequence_idr)  r   r   r   Útest_history_tracking]  sN   
þÿþÿþÿþÿÿz ConfigTest.test_history_trackingc                 C   s  t  dd„ ¡ t td¡}W d   ƒ n1 sw   Y  d|_|  tg d¢ƒt|j 	¡ ƒ¡ |  
|jd d¡ |  
|jd d¡ |  d|jd d j¡ |  t|jd d jƒd¡ |  d|jd d j¡ |  t|jd d jƒd	¡ |  |jd d jd |jd d j¡ d S )
Nc                   S   r#   )Núabc:123r   r   r   r   r   Ú<lambda>€  s    zBConfigTest.test_custom_location_history_tracking.<locals>.<lambda>r   r   ro  r)   r   rx  z8config_test.py:\d+:test_custom_location_history_tracking)r	   Úcustom_locationrC   rD   r   r   rc   rq  rB  rr  r¬   rs  rt  ri   rC  rv  r)  r   r   r   Ú%test_custom_location_history_tracking  s,   ÿ
þÿþÿz0ConfigTest.test_custom_location_history_trackingc                 C   sz   t  t¡}d}|  t|¡ | ¡  W d  ƒ n1 sw   Y  |  t|¡ |j}W d  ƒ dS 1 s6w   Y  dS )zÑTest helpful error messages when users hold them wrong!

    Config objects should provide a helpful error message when users attempt
    to use them as if they were the actual built (underlying) objects.
    z;a_method.*Note: .*SampleClass has an attribute/method with N)rC   rD   r   r¡   r¢   r&   )r!   rÁ   rc  r¤   r   r   r   Ú"test_accessing_functions_on_config’  s   

ÿ"ÿz-ConfigTest.test_accessing_functions_on_configc                 C   sz   |   td¡ t t¡i v }W d  ƒ n1 sw   Y  |   td¡ t t¡i v }W d  ƒ dS 1 s6w   Y  dS )zCAll Buildable's should be unhashable: mutability and custom __eq__.Ú
unhashableN)r¡   Ú	TypeErrorrC   rD   r   rÒ   r-  r   r   r   Útest_unhashable   s   ÿ"ÿzConfigTest.test_unhashablec                 C   sL   t  tdd¡}|  |t t |¡¡¡ t t |¡¡}d|_|  ||¡ dS )z&Bulidable types should be pickle-able.r)   r½   rw   N)	rC   rD   r   rc   ÚpickleÚloadsÚdumpsr   r  )r!   rÁ   Úreloadedr   r   r   Útest_pickling_config§  s
   zConfigTest.test_pickling_configc                 C   s   t  t t¡¡ d S r   )r€  r‚  rC   rD   rP   r%   r   r   r   Ú&test_pickling_non_serializable_default¯  s   z1ConfigTest.test_pickling_non_serializable_defaultc                 C   sp   t  tdd¡}t  |d|ig¡}|  |d t¡ |  |d jd¡ |  |d jd¡ |  |d |d d ¡ d S )Nr   r   rW   r   r)   )	rC   rD   r   rd   ræ   rc   r   r   rà   )r!   rf   Úbuiltr   r   r   Útest_build_nested_structure²  s   z&ConfigTest.test_build_nested_structurec                 C   s^   t  tt  td¡d¡}|  t¡}t  |¡ W d   ƒ n1 s w   Y  |  |jj	d¡ d S )Nr)   r*   z„

Fiddle context: failed to construct or call SampleClass at <root>.arg1 with positional arguments: (), keyword arguments: (arg1=1).)
rC   rD   r4   r   ÚassertRaisesr~  rd   rc   Ú	exceptionÚproxy_message)r!   rÁ   Úer   r   r   Ú)test_build_raises_nice_error_too_few_argsº  s   ÿþz4ConfigTest.test_build_raises_nice_error_too_few_argsc                 C   sJ   t  t¡}d}|  t|¡ t  |¡ W d   ƒ d S 1 sw   Y  d S )Nz‹My fancy exception

Fiddle context: failed to construct or call raise_error at <root> with positional arguments: (), keyword arguments: ().)rC   rD   r[   ÚassertRaisesWithLiteralMatchrZ   rd   )r!   rÁ   Úmsgr   r   r   Ú#test_build_raises_exception_on_callÅ  s   
ÿ"ÿz.ConfigTest.test_build_raises_exception_on_callc                 C   sr   t  td¡}dd|ddœ}t  td|g¡}|  t¡}t  |¡ W d   ƒ n1 s*w   Y  |  |jj	d¡ d S )Nr)   r   r*   r‚   )r>   r?   r@   Údz‰

Fiddle context: failed to construct or call basic_fn at <root>.arg1[1]['c'] with positional arguments: (), keyword arguments: (arg1=1).)
rC   rD   r4   r:   rˆ  r~  rd   rc   r‰  rŠ  )r!   r  Úsub_dictrÁ   r‹  r   r   r   Útest_build_error_pathÏ  s   ÿþz ConfigTest.test_build_error_pathc                    s€   d‰t  ¡ ‰ t  ¡ ‰‡ ‡‡fdd„}‡ ‡fdd„}t |d¡}t j|d}| ¡  t |¡}| ¡  |  d|¡ |  dˆ¡ dS )	z<Two threads can each invoke build.build without interfering.Nc                     s(   ‡ ‡fdd„} t  | d¡}t  |¡‰d S )Nc                    s   ˆ   ¡  ˆ ¡  | S r   ©rq  ÚwaitrN   ©Úbackground_entered_buildÚforeground_entered_buildr   r   Úblocking_functionè  ó   zTConfigTest.test_multithreaded_build.<locals>.other_thread.<locals>.blocking_functionrw   rg  )r˜  rÁ   ©r–  r—  rÊ   r   r   Úother_threadå  s   z9ConfigTest.test_multithreaded_build.<locals>.other_threadc                    s   ˆ  ¡  ˆ  ¡  | S r   r“  rN   r•  r   r   r˜  ð  r™  z>ConfigTest.test_multithreaded_build.<locals>.blocking_functionr)   )Útargetrw   )	Ú	threadingÚEventrC   rD   ÚThreadÚstartrd   Újoinrc   )r!   r›  r˜  rÁ   ÚthreadrÂ   r   rš  r   Útest_multithreaded_buildß  s   
z#ConfigTest.test_multithreaded_buildc                 C   sV   t  tdd¡}t  |dt¡ |  t¡ t  |¡ W d   ƒ d S 1 s$w   Y  d S )Nr)   r*   r   ©rC   rD   r:   Úadd_tagr   rˆ  rZ   rÒ   ©r!   r  r   r   r   Útest_copy_constructor_errorsý  s
   "ÿz'ConfigTest.test_copy_constructor_errorsc                 C   sb   t jtddg d}t  |dt¡ |  t¡ t j|dddd W d   ƒ d S 1 s*w   Y  d S )	Nr)   r*   r"  r   rx   r>   r?   r¹   r¤  r¦  r   r   r   Ú)test_copy_constructor_with_updates_errors  s
   "ÿz4ConfigTest.test_copy_constructor_with_updates_errorsc              	   C   sÊ   t  t¡}|  d¡$ d}|  t|¡ d|j_W d   ƒ n1 s"w   Y  W d   ƒ n1 s1w   Y  |  d¡  t  t¡|_d|j_|  	t  
|¡ttdƒƒ¡ W d   ƒ d S 1 s^w   Y  d S )NÚread_default_is_errorzdCan't get default value for dataclass field DataclassParent\.child since it uses a default_factory\.rx   Úread_ok_after_override)rC   rD   rU   rˆ   r¡   rZ   rW   rO   rR   rc   rd   )r!   rÁ   Úexpected_errorr   r   r   Útest_dataclass_default_factory	  s   
ÿ
ÿ€ü"ýz)ConfigTest.test_dataclass_default_factoryN)Or   r   r   rh   rl   rq   rt   rv   r|   r‰   rŒ   r   r’   r“   r”   r–   rš   r›   r   rŸ   r¥   r¦   r¨   r«   r®   r²   rµ   r¸   r¼   rÃ   rË   rÚ   rå   rè   rï   r  r  r  r  r  r  r  r  r!  r%  r&  r*  r3  r7  r<  r>  r@  rJ  rN  rP  rS  rT  rU  rY  r]  r^  r_  rd  re  rl  rw  r{  r|  r  r„  r…  r‡  rŒ  r  r’  r£  r§  r¨  r¬  r   r   r   r   r_   ~   sš    		
		,		
"
r_   c                   @   sô   e Zd Zdd„ Ze ddddddgfddddg d¢fdddddejfddgfdddddejfdd	dgfddddg d
¢fddddg d¢fdddddejfdddgfdddddejfdd	ddgfdddddgfddddddgfg
¡dd„ ƒZdd„ Z	dS )ÚOrderedArgumentsTestc                 C   s  t  tddddd¡}d|_d|_d|_d	|_|  t|j	 
¡ ƒg d
¢¡ |  tt |¡ 
¡ ƒg d¢¡ |  d¡A | ¡ \}}| ¡ }g }|D ] }t|tjƒrU| |j¡ qFt|tjƒrb| |j¡ qFtd|ƒ‚|  |jt|ƒ¡ W d   ƒ d S 1 s{w   Y  d S )Nr   r)   r*   rw   r$   rx   Úhir~   éþÿÿÿ)©r@   r¯  ©r   r   ©r)   r)   ©rw   rw   ©r$   r$   ©Ú
var_kwarg1rx   ©r   r®  ©Ú
var_kwarg2r~   )r±  r²  r°  r³  r´  r·  rµ  r¸  zpath element and keys match upz)No other path element should exists, got:)rC   rD   rA   r¶  r   r¹  r@   rc   ÚlistrÉ   r  rŠ   Úordered_argumentsrˆ   rA  Ú__path_elements__Ú
isinstancer   ÚAttrr°   ÚnameÚIndexÚindexrZ   Úargument_namesr·   )r!   rÁ   r¤   rõ   Úpath_elementsÚnamesÚpath_elementr   r   r   Útest_ordered_arguments  s<   þþÿþ"óz+OrderedArgumentsTest.test_ordered_argumentsFT©r   rx   ©r   éc   )rÇ  ©r   NrÈ  r   rÊ  )rÇ  rÈ  ©r†   é   )rÇ  rÊ  rÈ  rË  rË  c           	      C   sH   ddd„}t j|dddd}t j|||||d}|  t| ¡ ƒ|¡ d S )	NrÉ  c                 [   s   | ||||fS r   r   )r   r   r   r   r9   r   r   r   Úfn“  s   z?OrderedArgumentsTest.test_ordered_arguments_options.<locals>.fnrx   rÌ  )r   r   r†   )Úinclude_var_keywordÚinclude_defaultsÚinclude_unsetÚinclude_equal_to_default)NrÉ  )rC   rD   r»  rc   rº  r  )	r!   rÎ  rÏ  rÐ  rÑ  r  rÍ  rÁ   r7   r   r   r   Útest_ordered_arguments_optionsO  s   
D	ûz3OrderedArgumentsTest.test_ordered_arguments_optionsc              
   C   s:   t jtdddddddd}|  tj|d	d
dddœ¡ d S )Nr   r)   r*   rw   r$   rx   r®  )ÚkwargF)Úinclude_positional)r@   rÓ  )rC   rD   rA   rc   rŠ   r»  r)  r   r   r   Útest_include_positional§  s
   þz,OrderedArgumentsTest.test_include_positionalN)
r   r   r   rÆ  r   Ú
parametersrC   r‹   rÒ  rÕ  r   r   r   r   r­    sn    3ûûüûûûûûÆ
<r­  Ú__main__r-   r   )r   r)   )5r   rÞ   rX   r€  r'  r  Útypingr   r   r   r   Úabsl.testingr   r   ÚfiddlerC   r   r	   Úfiddle._srcr
   rŠ   Úfiddle._src.experimentalr   Úfiddle._src.testing.exampler   ra   ÚTagr   r   r   ri   r4   r8   r:   r;   r<   rA   rD   rE   rG   rI   rP   r2  rR   rU   r[   r]   r^   ÚTestCaser_   r­  r   Úmainr   r   r   r   Ú<module>   sd   
       # ÿ