o
    2guE                     @  s4  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 ddl	Z	ddl
mZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ dZ,G dd de"Z-dddZ.G dd dej/Z0dS )a  Test cases for fine-grained incremental checking.

Each test cases runs a batch build followed by one or more fine-grained
incremental steps. We verify that each step produces the expected output.

See the comment at the top of test-data/unit/fine-grained.test for more
information.

N.B.: Unlike most of the other test suites, testfinegrained does not
rely on an alt_lib_path for finding source files. This means that they
can test interactions with the lib_path that is built implicitly based
on specified sources.
    )annotationsN)Any)build)parse_config_file)Server)DEFAULT_STATUS_FILE)CompileError)create_source_list)BuildSource)Options)check_consistency#sort_messages_preserving_file_order)test_temp_dir)DataDrivenTestCase	DataSuite
DeleteFile
UpdateFile)assert_module_equivalenceassert_string_arrays_equalassert_target_equivalencefind_test_filesparse_optionsperform_file_operationsFc                   @  s   e Zd ZeddgdZdZd>d	d
Zd?ddZd@ddZdAddZ	dBddZ
dCd d!ZdDd$d%ZdEd-d.ZdFd0d1ZdGd4d5ZdHd6d7ZdId9d:ZdId;d<Zd=S )JFineGrainedSuitezfine-grained*.testz#fine-grained-cache-incremental.test)patternexcludeFtestcaser   returnboolc                 C  sB   | j r|jdkr
dS |jr|jd dkrdS dS |jdkrdS dS )Nz-only_when_nocacheTr   ==z-only_when_cacheF)	use_cache	only_whenoutput)selfr    r%   Q/home/garg/my-data/venv/lib/python3.10/site-packages/mypy/test/testfinegrained.pyshould_skip;   s   

zFineGrainedSuite.should_skipNonec                 C  s  |  |rt  d S d|j}tjtd}t|ddd}|	| W d    n1 s/w   Y  | j
||dd}|jtjkrGtd | j
||d	d}t|t}| |}d
}	| ||	|}
|	|krm| ||
}n| ||
}g }|r~|t| |jsJ || |	|||jj || |	|| |jrtrt|j | }g }|D ]#}|	d
7 }	| |||||||	|\}}|d || || qdd |D }t |j!|d|j" d|j# d |j$rt |j$| %|d|j" d|j# d d S d S )N
mainwutf8)encodingF)build_cachez)Test case requires a newer Python versionT   r    c                 S  s   g | ]}| d dqS )\/)replace).0liner%   r%   r&   
<listcomp>   s    z-FineGrainedSuite.run_case.<locals>.<listcomp>zInvalid output (z, line )zInvalid active triggers ()&r'   pytestskipjoininputospathr   openwriteget_optionspython_versionsysversion_infor   r   get_build_stepsparse_sourcesr   	run_checkextendnormalize_messagestmpdirmaybe_suggestnamemaybe_inspectfine_grained_managerCHECK_CONSISTENCYr   
find_stepsperform_stepappendr   r#   filer4   	triggeredformat_triggered)r$   r   main_src	main_pathfoptionsbuild_optionsservernum_regular_incremental_stepsstepsourcesmessagesastepsall_triggered
operationsr#   rR   r%   r%   r&   run_caseK   sp   








zFineGrainedSuite.run_casesourcestrr.   r   c                 C  s   t ||dd}d|_d|_d|_d|_| |_| jo| |_| j|_d|_	d|j
v |_|jd |_td|d u r>d|_|jD ]\}}d	|v sMd
|v rXt|dd |  |S qA|S )Nr/   )incremental_stepTFinspect	_no_emptyzflags:.*--follow-importserrorzmypy.inizpyproject.tomlc                   S  s   d S )Nr%   r%   r%   r%   r&   <lambda>   s    z.FineGrainedSuite.get_options.<locals>.<lambda>)r   incrementaluse_builtins_fixturesshow_tracebackerror_summaryfine_grained_incrementalr!   use_fine_grained_cachecache_fine_grainedlocal_partial_typesrQ   export_typesrJ   endswithallow_empty_bodiesresearchfollow_importsfilesr   )r$   rc   r   r.   rW   rJ   _r%   r%   r&   r?      s(   zFineGrainedSuite.get_optionsrY   r   r\   list[BuildSource]	list[str]c                 C  s8   |j |dddd}|d p|d }t|tsJ | S )NF)rr   is_ttyterminal_widthouterr)check
isinstancerd   
splitlines)r$   rY   r\   responser   r%   r%   r&   rE      s   zFineGrainedSuite.run_checkrW   c              
   C  sB   zt j ||d}W |jS  ty  } z	|jW  Y d }~S d }~ww )N)r\   rW   )r   r   r]   errors)r$   rW   r\   resulter%   r%   r&   r      s   zFineGrainedSuite.buildrR   list[list[str]]c                 C  sP   g }t |D ]\}}dd |D }t|}|d|d d|f   q|S )Nc                 S  s   g | ]	}| d s|qS )z__>)rs   )r3   triggerr%   r%   r&   r5          z5FineGrainedSuite.format_triggered.<locals>.<listcomp>z%d: %s   z, )	enumeratesortedrP   r9   strip)r$   rR   r   ntriggersfilteredr%   r%   r&   rS      s   "z!FineGrainedSuite.format_triggeredprogram_textintc                 C  s6   | j sdS tjd|tjd}|durt|dS dS )zHGet the number of regular incremental steps to run, from the test sourcer   z# num_build_steps: ([0-9]+)$flagsNr/   )r!   ru   rv   	MULTILINEr   group)r$   r   mr%   r%   r&   rC      s   z FineGrainedSuite.get_build_stepsra   list[UpdateFile | DeleteFile]rX   rT   r[   rZ   !tuple[list[str], list[list[str]]]c	                 C  s\  t | | |||}	||kr| ||	}
n| ||	}
g }g }g }g }|jrFtr.t|j ||jj |jj	}dd |jj
D }|jj}|j|d }|dur^tdt|d  || |j|d }|durvtdt|d  || |j|}|rtdt| || t|
}
|
}|jsJ || ||||jj || ||| ||fS )zPerform one fine-grained incremental build step (after some file updates/deletions).

        Return (mypy output, triggered targets).
        c                 S  s   g | ]\}}|qS r%   r%   )r3   modrQ   r%   r%   r&   r5      s    z1FineGrainedSuite.perform_step.<locals>.<listcomp>r/   Nstale	recheckedtargets)r   rD   r   rE   rL   rM   r   rP   rR   updated_moduleschanged_modulesprocessed_targetsexpected_stale_modulesgetr   rd   expected_rechecked_modulesexpected_fine_grained_targetsr   rG   rH   rF   rI   rJ   rK   )r$   ra   rY   rW   rX   r   rT   r[   rZ   r\   new_messagesupdatedchangedr   rR   expected_staleexpected_recheckedexpectedr^   r%   r%   r&   rO      s>   

zFineGrainedSuite.perform_stepre   c           	      C  s   t jd|t jd}d| d}t j||t jd}|dur|}|r3dd |d  D }t||S ttj	
td	d
d}|gttg|dd S )a!  Return target BuildSources for a test case.

        Normally, the unit tests will check all files included in the test
        case. This differs from how testcheck works by default, as dmypy
        doesn't currently support following imports.

        You can override this behavior and instruct the tests to check
        multiple modules by using a comment like this in the test case
        input:

          # cmd: main a.py

        You can also use `# cmdN:` to have a different cmd for incremental
        step N (2, 3, ...).

        z# cmd: mypy ([a-zA-Z0-9_./ ]+)$r   z# cmdz: mypy ([a-zA-Z0-9_./ ]+)$Nc                 S  s   g | ]	}t jt|qS r%   )r;   r<   r9   r   )r3   r<   r%   r%   r&   r5     r   z2FineGrainedSuite.parse_sources.<locals>.<listcomp>r/   r*   __main__T)allow_empty_dir)ru   rv   r   r   r   splitr	   r
   r;   r<   r9   r   )	r$   r   re   rW   r   regexalt_mpathsbaser%   r%   r&   rD     s   
zFineGrainedSuite.parse_sourcessrctmp_dirc                 C  sB  g }|  ||}|D ]\}}d|v }	d|v }
d|v }d|v }td|}|r-t|dnd }td|}|r<|dnd }td|}|rMt|dnd }|j| |	|||||
|d	}d
|v rf|d
 n|d |d  }|	r|dd}|t	j
|t	j
j d}|t	j
|t	j
j d}|| d q
t|S )Nz--jsonz--callsitesz--no-anyz--no-errorsz--flex-any=([0-9.]+)r/   z--use-fixme=(\w+)z--max-guesses=([0-9]+))jsonno_any	no_errorsflex_any	use_fixme	callsitesmax_guessesrh   r   r   z\\r0    r)   )get_suggestru   matchfloatr   r   cmd_suggestr   r2   r;   r<   realpathsepabspathrF   r   rG   )r$   r[   rY   r   r   r#   r   r   targetr   r   r   r   r   r   r   r   resvalr%   r%   r&   rI   '  s<    
zFineGrainedSuite.maybe_suggestc                 C  s   g }|  ||}|D ]n\}}td|}|r|dnd}	d}
d|v r%d}
d|v r+d}
td|}|r:t|dnd}d	|v }d
|v }d|v }d|v }d|v }|j|	||
||||||d	}d|v rf|d n|d |d  }|| d q
|S )Nz--show=(\w+)r/   typer   z-vz-vvr   z--limit=([0-9]+)z--include-spanz--include-kindz--include-object-attrsz--union-attrsz--force-reload)	verbositylimitinclude_spaninclude_kindinclude_object_attrsunion_attrsforce_reloadrh   r   r   r)   )	get_inspectru   r   r   r   cmd_inspectrF   r   r   )r$   r[   rY   r   r#   r   r   locationr   showr   r   r   r   r   r   r   r   r   r%   r%   r&   rK   H  s>    zFineGrainedSuite.maybe_inspectlist[tuple[str, str]]c                 C  6   |dkrdnt |}d| d}tj||tjd}|S )Nr/   1?z	# suggestz3: (--[a-zA-Z0-9_\-./=?^ ]+ )*([a-zA-Z0-9_.:/?^ ]+)$r   rd   ru   findallr   r$   r   re   step_bitr   r   r%   r%   r&   r   i     zFineGrainedSuite.get_suggestc                 C  r   )Nr/   r   z	# inspectz1: (--[a-zA-Z0-9_\-=?^ ]+ )*([a-zA-Z0-9_.:/?^ ]+)$r   r   r   r%   r%   r&   r   o  r   zFineGrainedSuite.get_inspectN)r   r   r   r   )r   r   r   r(   )rc   rd   r   r   r.   r   r   r   )rY   r   r\   rz   r   r{   )rW   r   r\   rz   r   r{   )rR   r   r   r{   )r   rd   r   r   )ra   r   rY   r   rW   r   rX   r   r   r   rT   rd   r[   r   rZ   r   r   r   )r   rd   re   r   rW   r   r   rz   )
r[   r   rY   r   r   rd   r   rd   r   r{   )r[   r   rY   r   r   rd   r   r{   )r   rd   re   r   r   r   )__name__
__module____qualname__r   rx   r!   r'   rb   r?   rE   r   rS   rC   rO   rD   rI   rK   r   r   r%   r%   r%   r&   r   2   s$    


F




	
9
&
!
!r   r]   r{   r   c                 C  s   dd | D S )Nc                 S  s&   g | ]}t d t tj d|qS )z^tmpr   )ru   subescaper;   r   )r3   messager%   r%   r&   r5   w  s   & z&normalize_messages.<locals>.<listcomp>r%   )r]   r%   r%   r&   rG   v  s   rG   c                   @  s4   e Zd ZdddZdddZdddZdd	d
ZdS )TestMessageSortingr   r(   c                 C  sP   ddg}ddg}t ||tt|ksJ t tt||tt|ks&J d S )N!x.py:1: error: "int" not callable#foo/y.py:123: note: "X" not defined"foo/y.py:12: note: "Y" not defined!x.py:8: error: "str" not callable)r   listreversed)r$   msgsold_msgsr%   r%   r&   test_simple_sorting{  s   z&TestMessageSorting.test_simple_sortingc                 C  sP   g d}g d}ddg}t || ||| ksJ t || ||| ks&J d S )N)r   zand message continues (x: y)z    1()z    ^~~)zfoo/y.py: In function "f":r   zand again message continuesr   r   r   )r$   msg1msg2r   r%   r%   r&   test_long_form_sorting  s
   z)TestMessageSorting.test_long_form_sortingc                 C  sT   d}d}d}g d}t |||g||||gksJ t |||g||||gks(J d S )Nr   z foo/y:123: note: "X" not definedz&mypy: Error not associated with a file)zmypy: Something wrongzfoo/y:12: note: "Y" not definedr   r   )r$   r   r   msg3r   r%   r%   r&   test_mypy_error_prefix  s   
z)TestMessageSorting.test_mypy_error_prefixc                 C  s\   d}d}d}d}ddg}t |||g||||gksJ t ||||g|||||gks,J d S )Nr   r   zab.py:3: error: Problem: errorzaaa:3: error: Badr   r   r   )r$   r   r   new1new2r   r%   r%   r&   test_new_file_at_the_end  s    
z+TestMessageSorting.test_new_file_at_the_endN)r   r(   )r   r   r   r   r   r   r   r%   r%   r%   r&   r   z  s
    


r   )r]   r{   r   r{   )1__doc__
__future__r   r;   ru   rA   unittesttypingr   r7   mypyr   mypy.config_parserr   mypy.dmypy_serverr   mypy.dmypy_utilr   mypy.errorsr   mypy.find_sourcesr	   mypy.modulefinderr
   mypy.optionsr   mypy.server.mergecheckr   mypy.server.updater   mypy.test.configr   mypy.test.datar   r   r   r   mypy.test.helpersr   r   r   r   r   r   rM   r   rG   TestCaser   r%   r%   r%   r&   <module>   s6     
  
F