o
    ih                     @   s  d Z ddlmZ ddlZddlZddlZddlZddlmZm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
 Zdd Zdd Zejddddddddddddfddddddddddddddddddfdd did!dddidddddfd"i dd#diddd#didfd$dd#didi dd#didfd%dddd!d#diidd#didfd&dd#didd!didddfd'd ddd(dd)idd*d+d,d-d.d/ddd*d0dd,d1d.d/fd2d3d4d5id6d7d8g d9id:d;d7d5g d9d<d:d;fd=d d!diid i id d!diifd>d i id d!diid d!diifd?d@dAdBidCdDdEdFdGdHdDdEdFdGdCfgdIedJedKedLefdMdNZejdOdPd did did didQdRfdSd d!diid d!diid d!diidQdRfdTd did dUid dUid:dVfdWd d!diid d5id d5id:dXfdYd d5id d!diid d!diid:dZfd[d did!d\idd\ddQdRfgd]d^ Zejd_d`d@dadbdDdadcdDdadbfddd@dadcdDdadbdDdadcfdedfdgdAdRiiidhdidjdkiiidfdgdAdkiiifdldmddRdngidoddpdqgidmddpdqgifdrdmddRdngidoddpdsgidmddpdsgifdtdudvdigidwdxdiddydzgidudxdiddydzgifd{duddRd|dvdigidwdxdigidudxdigifd}d~diddddddfdd@dddDddddDdddfdi ddddddfdddii i fddd7idddiidddiifddddiiddiddifddddRddgiidddd5ddddgiidddd5ddddgiifgdIededKedefddZG dd dejZG dd dejZe  G dd dejZe  G dd dejZG dd dZ G dd deZ!G dd dejZ"dd Z#dd Z$dd Z%dd Z&dd Z'dd Z(dd Z)dd Z*ddÄ Z+ddń Z,ddǄ Z-ddɄ Z.dd˄ Z/dd̈́ Z0ddτ Z1ddф Z2ddӄ Z3ddՄ Z4ddׄ Z5ddل Z6ddۄ Z7dd݄ Z8dd߄ Z9dd Z:dd Z;dd Z<dd Z=dd Z>dd Z?dS )z"Tests tools in the _common module.    )EnumN)ListOptional   )_common)types)errorsc                  C   sr   t ddd } tjdd}|   |   W d    n1 s w   Y  t|dks-J |d jtjks7J d S )NWarning!c                   S      d S N r   r   r   Y/home/ubuntu/.local/lib/python3.10/site-packages/google/genai/tests/common/test_common.pyfunc$      ztest_warn_once.<locals>.funcTrecord   r   )r   experimental_warningwarningscatch_warningslencategoryr   ExperimentalWarning)r   wr   r   r   test_warn_once#   s   
r   c                  C   sh   t ddd } tjdd}t jd }|   W d    n1 s$w   Y  |d j|ks2J d S )Nr	   c                   S   r
   r   r   r   r   r   r   r   0   r   z$test_warn_at_call_line.<locals>.funcTr   r   r   )r   r   r   r   inspectcurrentframef_linenolineno)r   captured_warnings	call_liner   r   r   test_warn_at_call_line/   s   
r!   c                   C   s  t ttttjf  sJ t tjtjttjf  sJ t tttt	f  r+J t ttt	tjf  r9J t tt rBJ t tttjf rNJ t tjtjtt	f  r]J t tjtjt	tjf  rmJ t tjt rwJ t tjttjf rJ d S r   )
r   _is_struct_typelistdictstrtypingAnyr   Dictintr   r   r   r   test_is_struct_type;   s     r*   z5test_id, initial_target, update_dict, expected_targetsimple_updater      ab   )r/   c)r.   r/   r1   nested_update
      )xy   (   )r6   z)r5   r6   r9   add_new_nested_dictr.   r/   empty_targetr5   empty_updateoverwrite_non_dict_with_dictoverwrite_dict_with_non_dictdeeper_nesting)r1   d)r/   e   )r@   f   )r/   g   )r.   h)r1   r@   rC   )r/   rA   rE   different_value_types
string_val
nested_intd   )key1key2{   nested_list)r   r,   r   T)rL   rM   key3)rJ   rO   update_with_empty_nested_dicttarget_with_empty_nested_dictkey_case_alignment_checkJohnemail_addresszjohn@example.com)
first_namecontact_infoJanezjane@example.com123)rU   phone_number)	firstNamerW   test_idinitial_targetupdate_dictexpected_targetc                 C   s   t || ||ksJ d S r   )r   recursive_dict_update)r\   r]   r^   r_   r   r   r   test_recursive_dict_updateI   s   Tra   z`test_id, initial_target, update_dict, expected_target, expect_warning, expected_log_message_parttype_match_intF type_match_dicttype_mismatch_int_to_strhelloz^Type mismatch for key 'a'. Existing type: <class 'int'>, new type: <class 'str'>. Overwriting.type_mismatch_dict_to_intz_Type mismatch for key 'a'. Existing type: <class 'dict'>, new type: <class 'int'>. Overwriting.type_mismatch_int_to_dictz_Type mismatch for key 'a'. Existing type: <class 'int'>, new type: <class 'dict'>. Overwriting.add_new_keynewc                 C   s   t || ||ksJ |r-t|jdksJ |jd jdks!J ||jd jv s+J d S |jD ]}|jdkrH||jv rHtd|  d|j  q0d S )Nr   r   WARNINGzUnexpected warning logged for z: )r   r`   r   records	levelnamemessagepytestfail)r\   r]   r^   r_   expect_warningexpected_log_message_partcaplogr   r   r   r   (test_recursive_dict_update_type_warnings   s   /
rt   z8test_id, target_dict, update_dict, expected_aligned_dictsimple_snake_to_camelDoe)rV   	last_name)r[   lastNamesimple_camel_to_snakenested_dict_alignment	user_infocontact_detailsuserInfocontactDetailsemailAddressztest@example.comlist_of_dicts_alignment
users_list)user_id	user_name	usersListAlice)userIduserName,list_of_dicts_alignment_mixed_case_in_update)r   UserName-list_of_dicts_different_lengths_update_longer
items_dataitem_id	itemsDataitemIdExtra)r   itemName-list_of_dicts_different_lengths_target_longer)r   	item_name&no_matching_keys_preserves_update_casekey_one)KEY_TWOkeyThreemixed_match_and_no_match)rV   	age_years   Engineer)r[   	AGE_YEARSoccupation_title)rV   r   r   empty_target_dict	new_valueanotherValue)new_key
anotherKeyempty_update_dictexisting_keyvalue(target_has_non_dict_value_for_nested_keyconfig_settingsconfigSettings	themeNamedark(update_has_non_dict_value_for_nested_key
theme_namelightdark_theme_stringdeeply_nested_with_lists	level_one
list_items)r   
item_valuelevelOne	listItemsTest)r   	itemValueTest2   target_dictexpected_aligned_dictc                 C   s&   t ||}||ksJ d|  d S )NzTest failed for: )r   align_key_case)r\   r   r^   r   aligned_dictr   r   r   test_align_key_case   s   \r   c                   @   s:   e Zd ZU eed< eed< dZeed< dZe	e ed< dS )SimpleModelnamer   T	is_activeN
none_field)
__name__
__module____qualname__r%   __annotations__r)   r   boolr   r   r   r   r   r   r   =  s
   
 r   c                   @   s&   e Zd ZU eed< dZed  ed< dS )ChainidNchild)r   r   r   r)   r   r   r   r   r   r   r   r   D  s   
 r   c                   @   s.   e Zd ZU eed< ejedZe	d  ed< dS )Treer   )default_factorychildrenN)
r   r   r   r)   r   pydanticFieldr#   r   r   r   r   r   r   r   L  s   
 r   c                   @   s,   e Zd ZU eed< ejdddZeed< dS )ReprFalseModelvisiblesecretF)reprhiddenN)r   r   r   r%   r   r   r   r   r   r   r   r   r   T  s   
 r   c                   @   s   e Zd Zdd ZdS )NonPydanticc                 C   s   dS )NzNonPydantic(
  attr='value'
)r   )selfr   r   r   __repr__[  s   zNonPydantic.__repr__N)r   r   r   r   r   r   r   r   r   Y  s    r   c                   @   s   e Zd ZdZdZdS )MyEnumr   r,   N)r   r   r   ONETWOr   r   r   r   r   _  s    r   c                   @   s   e Zd ZdS )
EmptyModelN)r   r   r   r   r   r   r   r   d  s    r   c                  C   s.   t ddd} td }t| |ksJ d S )Nz	Test NamerN   r   r   zZ
    SimpleModel(
      is_active=True,
      name='Test Name',
      value=123
    )
    )r   textwrapdedentstripr   objexpectedr   r   r   +test_repr_simple_model_defaults_and_no_noneh  s
   r   c                  C   s   t  } d}t| |ksJ d S )NzEmptyModel())r   r   r   r   r   r   test_repr_empty_modelt  s   r   c                  C   s4   t dt ddd} td }t| |ksJ d S )Nr   r,   r   )r   r   zJ
    Chain(
      child=Chain(
        id=2
      ),
      id=1
    )
    )r   r   r   r   r   r   r   r   r   test_repr_nested_modelz  s
   r   c                  C   sB   t dd} t dd}|| _| |_td }t| |ksJ d S )Nr   r   r,   zv
    Chain(
      child=Chain(
        child=<... Circular reference ...>,
        id=2
      ),
      id=1
    )
    )r   r   r   r   r   r   )obj1obj2r   r   r   r   test_repr_circular_model  s   


r   c                  C   s6   ddg} |  |  td }t| |ksJ d S )Nr   r,   zG
    [
      1,
      2,
      <... Circular reference ...>,
    ]
    )appendr   r   r   r   _pretty_repr)my_listr   r   r   r   test_repr_circular_list  s   
r   c                  C   s4   ddi} | | d< t d }t| |ksJ d S )Nr.   r   r   zJ
    {
      'a': 1,
      'self': <... Circular reference ...>
    }
    r   r   r   r   r   )my_dictr   r   r   r   test_repr_circular_dict  s   r   c                  C   s   t td} dd tdD }ttd}ttd}dtj| ddv s&J dtj|ddv s1J dtj|ddv s<J dtj|ddv sGJ d S )Nr3   c                 S   s   i | ]}||qS r   r   ).0ir   r   r   
<dictcomp>  s    z'test_repr_max_items.<locals>.<dictcomp>z<... 5 more items ...>rB   )	max_itemsz<dict len=10>)r#   rangesettupler   r   )lstdctsttplr   r   r   test_repr_max_items  s   r   c                  C   s<   d} t tj| dddksJ t| tj| ddksJ d S )Nsd   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZ   )max_len]   r   )r   r   r   r   )b_datar   r   r   test_repr_max_len_bytes  s   r   c                  C   s0   ddddddiii} dt j| ddv sJ d S )Nr.   r/   r-   z {<... 2 items at Max depth ...>}r   depthr   r   nestedr   r   r   test_repr_max_depth_dict  s   r  c                  C   s(   g dggg} dt j| ddv sJ d S )N)r@   rA   rA   pz [<... 4 items at Max depth ...>]r   r   r  r  r   r   r   test_repr_max_depth_list  s   r  c                  C   s@   h dddddg dd} t d }t| |ksJ d S )	N>   r   r,   r   )r0   rB   rD   r,   r   )r/   r.   )rF      	   )r   r   r$   r#   z
    {
      'dict': {
        'a': 1,
        'b': 2
      },
      'list': [
        7,
        8,
        9,
      ],
      'set': {
        1,
        2,
        3,
      },
      'tuple': (
        4,
        5,
        6,
      )
    }
    r   r   r   r   r   test_repr_collections  s   r
  c                  C   s0   dddd} t d }t| |ksJ d S )Nr   )r   )r   r,   )tuple0tuple1tuple2z{
    {
      'tuple0': (),
      'tuple1': (
        1,
      ),
      'tuple2': (
        1,
        2,
      )
    }
    r   r   r   r   r   test_tuple_collections  s   r  c                   C   sr   t g dks	J t i dksJ t t dksJ t t dks&J t dt itd ks7J d S )Nz[]z{}zset()z()	empty_setz8
        {
          'empty_set': set()
        }
      )r   r   r   r   r   r   r   r   r   r   r   test_repr_empty_collections  s   r  c                  C   sR   d} d}t | |ksJ d}d}t ||ksJ d}d}t ||ks'J d S )Nzline onez
'line one'z!line one
line two with """ insidez*"""line one
line two with \"\"\" inside"""zA string with """ insidez'A string with """ inside'r  )s1exp1s2exp2s3exp3r   r   r   test_repr_strings  s   r  c                  C   sJ   t ddd} t| }d|v sJ d|vsJ td }||ks#J d S )Nshowhide)r   r   zvisible='show'r   z4
    ReprFalseModel(
      visible='show'
    )
    )r   r   r   r   r   r   resultr   r   r   r   test_repr_repr_false+  s   r  c                  C   s@   t ddd d} t| }d|vsJ td }||ksJ d S )Nz	Only Namer   )r   r   r   r   zX
    SimpleModel(
      is_active=True,
      name='Only Name',
      value=0
    )
    )r   r   r   r   r   r  r   r   r   test_repr_none_fields8  s   r  c                  C   s:   t  } tj}| |d}td }t||ksJ d S )N)npenzh
    {
      'en': <MyEnum.TWO: 2>,
      'np': NonPydantic(
          attr='value'
        )
    }
    )r   r   r   r   r   r   r   r   )r  r  r   r   r   r   r   test_repr_other_typesF  s   
r   c                  C   s4   t ddd} td }tj| dd|ksJ d S )NzIndent Testr   r   z`
    SimpleModel(
        is_active=True,
        name='Indent Test',
        value=1
    )
    r0   )indent_delta)r   r   r   r   r   r   r   r   r   r   test_repr_indent_deltaU  s
   r"  c                  C   sz   t jg t jt jt jddgddt jjddgdt jdd	t jt j	j
d	d
gdddd} td }t| |ks;J d S )NaA  There isn't a single "best" LLM, as the ideal choice highly depends on your specific needs, use case, budget, and priorities. The field is evolving incredibly fast, with new models and improvements being released constantly.

However, we can talk about the **leading contenders** and what they are generally known for:...)textmodel)partsroler   )contentfinish_reasonindexz%models/gemini-2.5-flash-preview-05-20i>  rF   )modalitytoken_counti\  i  )candidates_token_countprompt_token_countprompt_tokens_detailsthoughts_token_counttotal_token_count)"automatic_function_calling_history
candidatesmodel_versionusage_metadataa  
      GenerateContentResponse(
        automatic_function_calling_history=[],
        candidates=[
          Candidate(
            content=Content(
              parts=[
                Part(
                  text="""There isn't a single "best" LLM, as the ideal choice highly depends on your specific needs, use case, budget, and priorities. The field is evolving incredibly fast, with new models and improvements being released constantly.

      However, we can talk about the **leading contenders** and what they are generally known for:..."""
                ),
              ],
              role='model'
            ),
            finish_reason=<FinishReason.STOP: 'STOP'>,
            index=0
          ),
        ],
        model_version='models/gemini-2.5-flash-preview-05-20',
        usage_metadata=GenerateContentResponseUsageMetadata(
          candidates_token_count=1086,
          prompt_token_count=7,
          prompt_tokens_details=[
            ModalityTokenCount(
              modality=<MediaModality.TEXT: 'TEXT'>,
              token_count=7
            ),
          ],
          thoughts_token_count=860,
          total_token_count=1953
        )
      )
  )r   GenerateContentResponse	CandidateContentPartFinishReasonSTOP$GenerateContentResponseUsageMetadataModalityTokenCountMediaModalityTEXTr   r   r   r   r   r   r   r   test_repr_complex_objecta  s>   
!!"r?  c                  C   s   dddddigiiddddddigiidddddd	igiiddgi} d
di}t | | dddddigiddiddddigiddidddd	igiddigi}| |ksZJ dS )z>Test move_value_by_path function with array wildcard notation.requestsr'  r%  r#  1@   )requestoutputDimensionality23zrequests[].*zrequests[].request.*rC  )r'  rD  N)r   move_value_by_path)datapathsr   r   r   r   test_move_value_by_path  s~   			))rJ  c                    s   G dd dt j G  fdddt j}dddii}| jtjdd	 ||}W d
   n1 s2w   Y  |jjdks?J t| j	dksHJ d
S )z0Test that no warning is logged when types match.c                   @      e Zd ZU eed< dS )zMtest_check_field_type_mismatches_no_warning_for_correct_types.<locals>.ModelAr   Nr   r   r   r)   r   r   r   r   r   ModelA     
 rM  c                          e Zd ZU  ed< dS )zPtest_check_field_type_mismatches_no_warning_for_correct_types.<locals>.TestModelmodel_aNr   r   r   r   r   rM  r   r   	TestModel  rN  rS  rP  r   rN   google_genai._commonloggerNr   )
r   	BaseModelat_levelloggingrk   model_validaterP  r   r   rl   rs   rS  rH  r  r   rR  r   =test_check_field_type_mismatches_no_warning_for_correct_types  s   r\  c                    s   G dd dt j G dd dt j}G  fdddt j}|dd}d	|i}| jtjd
d || W d   n1 s>w   Y  t| jdksLJ d| jd jv sVJ d| jd jv s`J dS )z?Test that warning is logged when Pydantic model types mismatch.c                   @   rK  )zPtest_check_field_type_mismatches_warns_on_pydantic_type_mismatch.<locals>.ModelAr   NrL  r   r   r   r   rM    rN  rM  c                   @   rK  )zPtest_check_field_type_mismatches_warns_on_pydantic_type_mismatch.<locals>.ModelBr   Nr   r   r   r%   r   r   r   r   r   ModelB  rN  r^  c                       rO  )zStest_check_field_type_mismatches_warns_on_pydantic_type_mismatch.<locals>.TestModelmodel_fieldNrQ  r   rR  r   r   rS    rN  rS  testr   r_  rT  rU  Nr   z&Type mismatch in TestModel.model_fieldr   expected ModelA, got ModelB	r   rW  rX  rY  rk   _check_field_type_mismatchesr   rl   rn   rs   r^  rS  model_b_instancerH  r   rR  r   @test_check_field_type_mismatches_warns_on_pydantic_type_mismatch  s   
rg  c                    s   G dd dt j G  fdddt j}ddi}| jtjdd ||}W d   n1 s0w   Y  |jdu s<J t| jd	ksEJ dS )
z/Test that no warning is logged for None values.c                   @   rK  )zKtest_check_field_type_mismatches_no_warning_for_none_values.<locals>.ModelAr   NrL  r   r   r   r   rM  2  rN  rM  c                          e Zd ZU dZe  ed< dS )zNtest_check_field_type_mismatches_no_warning_for_none_values.<locals>.TestModelNr_  r   r   r   r_  r   r   r   rR  r   r   rS  5     
 rS  r_  NrT  rU  r   	r   rW  rX  rY  rk   rZ  r_  r   rl   r[  r   rR  r   ;test_check_field_type_mismatches_no_warning_for_none_values/  s   rl  c                    s   G dd dt j G  fdddt j}i }| jtjdd ||}W d   n1 s.w   Y  |jdu s:J t| jdksCJ dS )	z2Test that no warning is logged for missing fields.c                   @   rK  )zNtest_check_field_type_mismatches_no_warning_for_missing_fields.<locals>.ModelAr   NrL  r   r   r   r   rM  D  rN  rM  c                       rh  )zQtest_check_field_type_mismatches_no_warning_for_missing_fields.<locals>.TestModelNr_  ri  r   rR  r   r   rS  G  rj  rS  rT  rU  Nr   rk  r[  r   rR  r   >test_check_field_type_mismatches_no_warning_for_missing_fieldsA  s   rm  c                 C   s   G dd dt j}ddd}| jtjdd ||}W d   n1 s&w   Y  |jd	ks2J |jdks9J t| j	d
ksBJ dS )z=Test that no warning is logged for primitive type mismatches.c                   @   s   e Zd ZU eed< eed< dS )zRtest_check_field_type_mismatches_no_warning_for_primitive_types.<locals>.TestModel	int_field	str_fieldN)r   r   r   r)   r   r%   r   r   r   r   rS  V  s   
 rS  rY   r`  )rn  ro  rT  rU  NrN   r   )
r   rW  rX  rY  rk   rZ  rn  ro  r   rl   r[  r   r   r   ?test_check_field_type_mismatches_no_warning_for_primitive_typesS  s   
rp  c                    s   G dd dt j G dd dt j}G  fdddt j}|dd}d	|i}| jtjd
d || W d   n1 s>w   Y  t| jdksLJ d| jd jv sVJ dS )z@Test that Optional types are properly unwrapped before checking.c                   @   rK  )zLtest_check_field_type_mismatches_handles_optional_unwrapping.<locals>.ModelAr   NrL  r   r   r   r   rM  j  rN  rM  c                   @   rK  )zLtest_check_field_type_mismatches_handles_optional_unwrapping.<locals>.ModelBr   Nr]  r   r   r   r   r^  m  rN  r^  c                       rh  )zOtest_check_field_type_mismatches_handles_optional_unwrapping.<locals>.TestModelNr_  ri  r   rR  r   r   rS  p  rj  rS  r`  ra  r_  rT  rU  Nr   rb  r   rc  re  r   rR  r   <test_check_field_type_mismatches_handles_optional_unwrappingg  s   
rq  c                    s   G dd dt j G  fdddt j} dd}d|i}| jtjdd	 ||}W d
   n1 s5w   Y  |jjdksBJ t| j	dksKJ d
S )zJTest that no warning is logged when correct Pydantic instance is provided.c                   @   rK  )zYtest_check_field_type_mismatches_no_warning_for_correct_pydantic_instance.<locals>.ModelAr   NrL  r   r   r   r   rM    rN  rM  c                       rO  )z\test_check_field_type_mismatches_no_warning_for_correct_pydantic_instance.<locals>.TestModelr_  NrQ  r   rR  r   r   rS    rN  rS  *   ra  r_  rT  rU  Nr   )
r   rW  rX  rY  rk   rZ  r_  r   r   rl   )rs   rS  model_a_instancerH  r  r   rR  r   Itest_check_field_type_mismatches_no_warning_for_correct_pydantic_instance~  s   
rt  c                    s   G dd dt j G dd dt j}G  fdddt j}|dd}|d	d
d}| jtjdd || W d	   n1 s@w   Y  t| jdksNJ d| jd jv sXJ d| jd jv sbJ d	S )z3Test checking multiple fields with mixed scenarios.c                   @   rK  )zEtest_check_field_type_mismatches_with_multiple_fields.<locals>.ModelAr   NrL  r   r   r   r   rM    rN  rM  c                   @   rK  )zEtest_check_field_type_mismatches_with_multiple_fields.<locals>.ModelBr   Nr]  r   r   r   r   r^    rN  r^  c                       s.   e Zd ZU  ed< dZe  ed< eed< dS )zHtest_check_field_type_mismatches_with_multiple_fields.<locals>.TestModelfield_aNfield_bfield_c)r   r   r   r   rv  r   r%   r   rR  r   r   rS    s   
 rS  wrongra  Nr`  )ru  rv  rw  rT  rU  r   ru  r   rb  rc  re  r   rR  r   5test_check_field_type_mismatches_with_multiple_fields  s   
ry  c                 C   sn   G dd dt j}dddgi}| jtjdd || W d   n1 s'w   Y  t| jd	ks5J dS )
zCTest that validation doesn't crash on generic types like list[str].c                   @   s   e Zd ZU ee ed< dS )zItest_check_field_type_mismatches_generic_type_no_error.<locals>.TestModeltagsN)r   r   r   r#   r%   r   r   r   r   r   rS    s   
 rS  rz  r.   r/   rT  rU  Nr   )r   rW  rX  rY  rk   rZ  r   rl   )rs   rS  rH  r   r   r   6test_check_field_type_mismatches_generic_type_no_error  s   r{  )@__doc__enumr   r   rY  r   r&   r   r   r   r   ro   rc   r   r   r   r   r!   r*   markparametrizer%   r$   ra   rt   r   rW  r   r   model_rebuildr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r
  r  r  r  r  r  r   r"  r?  rJ  r\  rg  rl  rm  rp  rq  rt  ry  r{  r   r   r   r   <module>   s  





Q	


		
	


.




Y!GZ