a
    ûbá4  ã                   @   sÚ   d Z ddlmZ ddlZddlZddlZddlmZ ddl	m
Z
mZmZ ddlmZ ddlmZmZmZ dd	lmZ g d
¢Zeg d¢e ƒZdd„ Zddd„ZG dd„ de
ƒZG dd„ deƒZG dd„ deƒZdd„ ZdS )zv
A Cython plugin for coverage.py

Requires the coverage package at least in version 4.0 (which added the plugin API).
é    )Úabsolute_importN)Údefaultdict)ÚCoveragePluginÚ
FileTracerÚFileReporter)Úcanonical_filenameé   )Úfind_root_package_dirÚis_package_dirÚopen_source_file©Ú__version__)z.cz.cppz.ccz.cxx)ú.pyz.pyxz.pxdc                 C   s.   t jj}tD ]}| | }||ƒr|  S qd S ©N)ÚosÚpathÚexistsÚC_FILE_EXTENSIONS)Ú	base_pathZfile_existsÚextÚ	file_name© r   ú_/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/Cython/Coverage.pyÚ_find_c_source   s    
r   Fc                 C   s¢   t j |¡}t j |¡sT| d¡s&|rTt j t j | ¡|¡}t j |¡rTt j |¡}t j |¡sštjD ]2}t j t j ||¡¡}t j |¡rft	|ƒ  S qft	|ƒS )Nú.pxi)
r   r   Úabspathr   ÚendswithÚjoinÚdirnameÚsysÚrealpathr   )Z	main_fileÚ	file_pathÚrelative_path_searchÚabs_pathÚrel_file_pathÚsys_pathZ	test_pathr   r   r   Ú_find_dep_file_path$   s    ÿ
r&   c                   @   sP   e Zd ZdZd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 )ÚPluginNc                 C   s
   dt fgS )NzCython versionr   ©Úselfr   r   r   Úsys_info=   s    zPlugin.sys_infoc                 C   s¬   |  d¡s|  d¡rdS d }}ttj |¡ƒ}| jrN|| jv rN| j| d }|du rˆ|  |¡\}}|sldS |  ||¡\}}|du rˆdS | jdu r˜i | _t	|||| j| jƒS )zR
        Try to find a C source file for a file path found by the tracer.
        ú<zmemory:Nr   )
Ú
startswithr   r   r   r   Ú_c_files_mapÚ_find_source_filesÚ_read_source_linesÚ_file_path_mapÚCythonModuleTracer)r)   ÚfilenameÚc_fileÚpy_fileÚ_Úcoder   r   r   Úfile_tracer@   s     
zPlugin.file_tracerc                 C   sr   t tj |¡ƒ}| jr2|| jv r2| j| \}}}n2|  |¡\}}|sHd S |  ||¡\}}|d u rdd S t||||ƒS r   )r   r   r   r   r-   r.   r/   ÚCythonModuleReporter)r)   r2   r3   r$   r6   r5   r   r   r   Úfile_reporter^   s    zPlugin.file_reporterc              	   C   sÖ  t j |¡\}}| ¡ }|tv r"nš|dkrPt d|tj¡}|r¼|d | ¡ … }nl|dkr~t d|tj¡}|r¼|d | ¡ … }n>|dkr¸|  	t j 
|¡|¡ || jv r¼| j| d d fS ndS |tv rÈ|nt|ƒ}|d u r.t |¡}t j ||¡ t jj¡}t|ƒdkr.t j t j 
|¡d	 |¡¡}t|ƒ}d }	|rÎt j |¡d d
 }	t j |	¡s^d }	zRt|dƒ2}
d|
 d¡vrŽW d   ƒ W dS W d   ƒ n1 s¤0    Y  W n ttfyÌ   d }Y n0 ||	fS )Nz.pydz[.]cp[0-9]+-win[_a-z0-9]*$z.soz&[.](?:cpython|pypy)-[0-9]+[-_a-z0-9]*$r   r   ©NNr   Ú.r   Úrbs   /* Generated by Cython é   )r   r   ÚsplitextÚlowerÚMODULE_FILE_EXTENSIONSÚreÚsearchÚIÚstartÚ_find_c_source_filesr   r-   r   r   r	   ZuncachedÚrelpathÚsplitÚsepÚlenr   r   ÚopenÚreadÚIOErrorÚOSError)r)   r2   Úbasenamer   Zplatform_suffixr3   Zpackage_rootÚpackage_pathZtest_basepathZpy_source_fileÚfr   r   r   r.   q   sH    


6
zPlugin._find_source_filesc                 C   s†   t j |¡sdS t jj}t  |¡D ]B}||ƒd  ¡ }|tv r"|  t j ||¡|¡ || j	v r" dS q"t
|ƒr‚|  t j |¡|¡ dS )z¦
        Desperately parse all C files in the directory or its package parents
        (not re-descending) to find the (included) source file in one of them.
        Nr   )r   r   Úisdirr>   Úlistdirr?   r   r/   r   r-   r
   rE   r   )r)   Zdir_pathÚsource_filer>   r2   r   r   r   r   rE   £   s    
zPlugin._find_c_source_filesc                 C   sš   | j du ri | _ || j v r&| j | }n|  |¡}|| j |< | jdu rJi | _| ¡ D ]&\}}t||dd}|||f| j|< qR|| jvrˆdS | j| dd… S )zý
        Parse a Cython generated C/C++ source file and find the executable lines.
        Each executable line starts with a comment header that states source file
        and line number, as well as the surrounding range of source code lines.
        NT)r"   r:   r   )Ú_parsed_c_filesÚ_parse_cfile_linesr-   Úitemsr&   )r)   r3   Z
sourcefileÚ
code_linesr2   r6   r#   r   r   r   r/   µ   s     




ÿ
zPlugin._read_source_linesc                 C   sv  t  d¡j}t  d¡j}t  d¡j}t  d¡j}t  d¡j}ttƒ}ttƒ}d}	t|ƒÌ}
t|
ƒ}
|
D ]®}||ƒ}|s¬d|v rf|	durf||ƒ}|rf||	  t	| 
d¡ƒ¡ qf| ¡ \}}|}	t	|ƒ}|
D ]J}||ƒ}|r| 
d¡ ¡ }||ƒrô qf||| |<  qfqÈ||ƒrÈ qfqÈqfW d  ƒ n1 s,0    Y  | ¡ D ]2\}}
t|
ƒ | |d	¡¡}|D ]}|
|= q`q>|S )
zb
        Parse a C file and extract all source file lines that generated executable code.
        z */[*] +"(.*)":([0-9]+)$z *[*] (.*) # <<<<<<+$z *[*]/$z *__Pyx_TraceLine\(([0-9]+),zX\s*c(?:type)?def\s+(?:(?:public|external)\s+)?(?:struct|union|enum|class)(\s+[^:]+|)\s*:Nz__Pyx_TraceLine(r   r   )rA   ÚcompileÚmatchr   ÚdictÚsetrJ   ÚiterÚaddÚintÚgroupÚgroupsÚrstriprV   Ú
differenceÚget)r)   r3   Zmatch_source_path_lineZmatch_current_code_lineZmatch_comment_endZmatch_trace_lineZnot_executablerW   Zexecutable_linesZcurrent_filenameÚlinesÚlinerY   Z
trace_liner2   ÚlinenoZcomment_lineÚ	code_lineZ
dead_linesr   r   r   rU   Ï   sL    ÿ
(zPlugin._parse_cfile_lines)Ú__name__Ú
__module__Ú__qualname__r0   r-   rT   r*   r7   r9   r.   rE   r/   rU   r   r   r   r   r'   5   s   2r'   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )r1   zA
    Find the Python/Cython source file for a Cython module.
    c                    s0   t t| ƒ ¡  || _|| _|| _|| _|| _d S r   )Úsuperr1   Ú__init__Úmodule_filer4   r3   r-   r0   )r)   rm   r4   r3   Zc_files_mapZfile_path_map©Ú	__class__r   r   rl     s    zCythonModuleTracer.__init__c                 C   s   dS )NTr   r(   r   r   r   Úhas_dynamic_source_filename  s    z.CythonModuleTracer.has_dynamic_source_filenamec                 C   s–   |j j}z| j| W S  ty&   Y n0 t||ƒ}| jr^|dd…  ¡ dkr^| j| j|< | jS | jduslJ ‚|| jvrˆ| j|df| j|< || j|< |S )zR
        Determine source file path.  Called by the function call tracer.
        éýÿÿÿNr   )	Úf_codeÚco_filenamer0   ÚKeyErrorr&   r4   r?   r-   r3   )r)   r2   ÚframerS   r#   r   r   r   Údynamic_source_filename  s    


z*CythonModuleTracer.dynamic_source_filename)rh   ri   rj   Ú__doc__rl   rp   rv   Ú__classcell__r   r   rn   r   r1     s   r1   c                       s@   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Z‡  Z	S )r8   zP
    Provide detailed trace information for one source file to coverage.py.
    c                    s&   t t| ƒ |¡ || _|| _|| _d S r   )rk   r8   rl   Únamer3   Ú_code)r)   r3   rS   r$   r6   rn   r   r   rl   -  s    zCythonModuleReporter.__init__c                 C   s
   t | jƒS )zJ
        Return set of line numbers that are possibly executable.
        )r[   rz   r(   r   r   r   rd   3  s    zCythonModuleReporter.linesc                 c   sL   d}t | j ¡ ƒD ]4\}}||kr2g V  |d7 }qd|fgV  |d7 }qd S )Nr   Útxt)Úsortedrz   rV   )r)   Úcurrent_lineZline_norg   r   r   r   Ú_iter_source_tokens9  s    
z(CythonModuleReporter._iter_source_tokensc                 C   s^   t j | j¡rBt| jƒ}| ¡ W  d  ƒ S 1 s60    Y  nd dd„ |  ¡ D ƒ¡S dS )zA
        Return the source code of the file as a string.
        NÚ
c                 s   s"   | ]}|r|d  d ndV  qdS )r   r   Ú Nr   )Ú.0Útokensr   r   r   Ú	<genexpr>J  s   ÿz.CythonModuleReporter.source.<locals>.<genexpr>)r   r   r   r2   r   rK   r   r~   )r)   rP   r   r   r   ÚsourceB  s    (
þzCythonModuleReporter.sourcec                 c   st   t j | j¡rVt| jƒ,}|D ]}d| d¡fgV  qW d  ƒ qp1 sJ0    Y  n|  ¡ D ]}d|fgV  q^dS )z6
        Iterate over the source code tokens.
        r{   r   N)r   r   r   r2   r   ra   r~   )r)   rP   re   r   r   r   Úsource_token_linesN  s    4z'CythonModuleReporter.source_token_lines)
rh   ri   rj   rw   rl   rd   r~   r„   r…   rx   r   r   rn   r   r8   )  s   	r8   c                 C   s   |   tƒ ¡ d S r   )Zadd_file_tracerr'   )ÚregÚoptionsr   r   r   Úcoverage_init[  s    rˆ   )F)rw   Ú
__future__r   rA   Úos.pathr   r   Úcollectionsr   Zcoverage.pluginr   r   r   Zcoverage.filesr   ZUtilsr	   r
   r   r€   r   r   r[   r@   r   r&   r'   r1   r8   rˆ   r   r   r   r   Ú<module>   s$   	
 O&2