U
    [h1                     @  s   d dl mZ d dlZd dl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mZ ddlmZ d	d
lmZ ejjG dd deZdS )    )annotationsN)Path   )TestBase   )config)eq_   )utilc                   @  s   e Zd ZdZejdddd Zejdddd Zd	d
 Ze dd Z	ejdd Z
edd Zdd ZddddZdS )MypyTest)Zno_sqlalchemy2_stubsfunction)Zscopec                 c  s   |   E d H  d S N	_cachedirself r   F./venv/lib/python3.8/site-packages/sqlalchemy/testing/fixtures/mypy.pyper_func_cachedir   s    zMypyTest.per_func_cachedirclassc                 c  s   |   E d H  d S r   r   r   r   r   r   cachedir!   s    zMypyTest.cachedirc              
   c  s   d}t  l}tt|d d}|d| d W 5 Q R X tt|d d}|d| d W 5 Q R X |V  W 5 Q R X d S )	N sqla_mypy_config.cfgwz
                    [mypy]

                    plugins = sqlalchemy.ext.mypy.plugin

                    show_error_codes = True

                    z
                    disable_error_code = no-untyped-call

                    [mypy-sqlalchemy.*]
                    ignore_errors = True

                    plain_mypy_config.cfgz^
                    [mypy]

                    show_error_codes = True

                    z
                    disable_error_code = var-annotated,no-untyped-call
                    [mypy-sqlalchemy.*]
                    ignore_errors = True

                    )tempfileZTemporaryDirectoryopenr   write)r   Z	mypy_pathr   Zconfig_filer   r   r   r   %   s.    

 
 zMypyTest._cachedirc                   s    ddl m  d fdd	}|S )Nr   )apiFc           	   	     s   |d kr}ddd|dt j||r&dndg}t j| }t j||}| |kr\t| | || t jdd   	|\}}}|||fS )Nz--strictz--raise-exceptionsz--cache-dirz--config-filer   r   ZMYPY_FORCE_COLOR)
ospathjoinbasenameshutilcopyfileappendenvironpoprun)	r    
use_pluginZuse_cachedirargsfilenameZtest_programstdoutstderrexitcoder   r   r   r   r(   N   s,    
z!MypyTest.mypy_runner.<locals>.run)FN)mypyr   )r   r   r(   r   r/   r   mypy_runnerJ   s    %zMypyTest.mypy_runnerc                   s   d fdd	}|S )NFc                   s2    | } | |d\}}}| |||| d S )N)r)   )_collect_messages_check_output)r    r)   expected_messagesr,   r-   r.   r1   r   r   r   r(   w   s    
    z)MypyTest.mypy_typecheck_file.<locals>.run)Fr   )r   r1   r(   r   r5   r   mypy_typecheck_fileu   s    zMypyTest.mypy_typecheck_filec                 C  s   t j| r| }n$t d j}t jt j|| }tt	|
d}tjjD ],}|rPt j|rP|t	||  
d qP|S )Nr   z**/*.py)r   r    isabsinspectstackr+   r!   dirnamelistr   globr   optionsZmypy_extra_test_pathsisdirextend)r:   r    Zcaller_pathfilesZ	extra_dirr   r   r   file_combinations   s    zMypyTest.file_combinationsc              
     s*  ddl m} g }td}td}t|}g }t|dD ]\ }||}	|	r|	dd\}
}}t	j
t|
t|fk r>td|	d  q>||}	|	rt|	d}t|	d}t|	d	}t|	d
}tdd|	d}|rtddd |}tddd |}|r|sntddd |}tddd |}tdd|}tddd |}d }}d| d}|rtjr|d t|rdndd d |dd   }|rtjrtd!d"d |}|||| f q>|r>| fd#d$|D  g |d d < q>W 5 Q R X |S )%Nr   )mypy_14z0\s*# EXPECTED(_MYPY)?(_RE)?(_ROW)?(_TYPE)?: (.+)z%^#\s*PYTHON_VERSION\s?>=\s?(\d+\.\d+)r   .zRequires python >= %sr   r	      z# noqa[:]? ?.*r      zRow\[([^\]]+)\]c                 S  s   d|  d d|  d dS )Nztuple[r   z!, fallback=sqlalchemy.engine.row.r   ]groupmr   r   r   <lambda>       z,MypyTest._collect_messages.<locals>.<lambda>zOptional\[(.*)\]c                 S  s   d|  d dS )NzUnion[r   z, None]rG   rI   r   r   r   rK      rL   z([\[\]])c                 S  s   d|  d S )N\r   rG   rI   r   r   r   rK      rL   z([\w_]+)c                 S  s   d|  d dS )Nz	(?:.*\.)?r   \*?rG   rI   r   r   r   rK      rL   ZListzbuiltins.listz\b(int|str|float|bool)\bc                 S  s   d|  d dS )Nz	builtins.r   rN   rG   rI   r   r   r   rK      rL   TzRevealed type is ""z\b(List|Tuple|Dict|Set)\bz\b(List|Tuple|Dict|Set|Type)\bc                 S  s   |  d S )Nr   )rH   lowerrI   r   r   r   rK      rL   zOptional\[(.*?)\]c                 S  s   |  d dS )Nr   z | NonerG   rI   r   r   r   rK      rL   c                 3  s    | ]\}}} |||fV  qd S r   r   ).0is_mypyis_reexpected_msgnumr   r   	<genexpr>   s
   z-MypyTest._collect_messages.<locals>.<genexpr>)Zsqlalchemy.ext.mypy.utilrB   recompiler   	enumeratematchrH   	partitionsysversion_infointr   Z	skip_testboolsubr
   Zpy39Zpy310r%   stripr?   )r   r    rB   r4   Zexpected_reZ	py_ver_reZfile_Zcurrent_assert_messageslinerJ   major_minorrR   rS   Zis_rowZis_typerT   r   rU   r   r2      s    


	  


zMypyTest._collect_messagesstr)r,   c                 C  s,  g }t j|}|rg }|d}	|	r|	d}
td|
rN|d|
f q$td|
r|	r|	d}td|sZ|	d| qqZq$td|
tj	rq$td|
r$|d	|
f q$|D ]\}}}}|
d
d}|sdnd}t|D ]t\}\}}|r(td| d| d| d| | 	|rX qfq| d| d| d| | |
d
dkr qfq|| q||= q|rd|}td|dd |rddd |D }td|dd dstd|r(tt| d tddd |D  ds(tdn&|dkrt||dd t|d|d d S )N
r   z.+\.py:\d+: error: .*errorz/.+\.py:\d+: note: +(?:Possible overload|def ).*z.+\.py:\d+: note: +def .*z*.+\.py:\d+: note: .*(?:perhaps|suggestion)z.+\.py:\d+: note: .*Znote'rO   z[SQLAlchemy Mypy plugin] r   z.*z\:z\: :z: z"Couldn't locate expected messages:)sepc                 s  s   | ]\}}|V  qd S r   r   rQ   re   msgr   r   r   rW   ?  s     z)MypyTest._check_output.<locals>.<genexpr>zRemaining messages:Fz'expected messages not found, see stdoutz& messages from mypy were not consumed:c                 s  s   | ]\}}|V  qd S r   r   rm   r   r   r   rW   E  s     z&errors and/or notes remain, see stdout)rn   )r   r    r"   splitr'   rX   r[   r%   insertIreplacerZ   r!   printAssertionErrorlenr   )r   r    r4   r,   r-   r.   Znot_locatedr+   outputZ	raw_lineseZolrV   rR   rS   rn   prefixidxtyperrmsgmissingZextrar   r   r   r3     st    

 
  



zMypyTest._check_outputN)__name__
__module____qualname__Z__requires__r   Zfixturer   r   r   r1   r6   staticmethodrA   r2   r3   r   r   r   r   r      s   



%
*


yr   )Z
__future__r   r8   r   pathlibr   rX   r#   r]   r   baser   r   r   Z
assertionsr   r
   Zadd_to_markerr0   r   r   r   r   r   <module>	   s   