3
=]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 d
dddgZedddg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.cxxz.pyz.pyxz.pxdc             C   s.   t jj}x tD ]}| | }||r|S qW d S )N)ospathexistsC_FILE_EXTENSIONS)	base_pathZfile_existsext	file_name r   _/home/psgendb/BIRCHDEV/lib-linux-x86_64/python/lib64/python3.6/site-packages/Cython/Coverage.py_find_c_source   s    
r   Fc             C   s   t jj|}t jj| rV|jds(|rVt jjt jj| |}t jj|rVt jj|}t jj|sx8tjD ].}t jjt jj||}t jj|rjt	|S qjW t	|S )Nz.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 version)r   )selfr   r   r   sys_info=   s    zPlugin.sys_infoc             C   s   |j ds|j drdS d }}ttjj|}| jrN|| jkrN| j| d }|dkr| j|\}}|sldS | j||\}}|dkrdS | jdkri | _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|}| jr2|| jkr2| j| \}}}n2| j|\}}|sHd S | j||\}}|d krdd S t||||S )N)r   r   r   r   r(   r)   r*   CythonModuleReporter)r$   r-   r.   r    r1   r0   r   r   r   file_reporter^   s    zPlugin.file_reporterc             C   s  t jj|\}}|j }|tkr"n|dkrPtjd|tj}|r|d |j  }nl|dkr~tjd|tj}|r|d |j  }n>|dkr| j	t jj
|| || jkr| j| d d fS ndS |tkr|nt|}|d kr.tj|}t jj||jt jj}t|dkr.t jjt jj
|dj|}t|}d }	|rt jj|d d	 }	t jj|	s^d }	y.t|d
}
d|
jdkrdS W d Q R X W n ttfk
r   d }Y nX ||	fS )Nz.pydz[.]cp[0-9]+-win[_a-z0-9]*$z.soz&[.](?:cpython|pypy)-[0-9]+[-_a-z0-9]*$z.pxir   r   .z.pyrbs   /* Generated by Cython    )NN)NN)r   r   splitextlowerMODULE_FILE_EXTENSIONSresearchIstart_find_c_source_filesr   r(   r   r   r	   uncachedrelpathsplitseplenr   r   openreadIOErrorOSError)r$   r-   basenamer   Zplatform_suffixr.   Zpackage_rootpackage_pathZtest_basepathZpy_source_filefr   r   r   r)   q   sH    



zPlugin._find_source_filesc             C   s   t jj|sdS t jj}xNt j|D ]@}||d j }|tkr$| jt jj||| || j	kr$dS q$W t
|r| jt j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   isdirr8   listdirr9   r   r*   r   r(   r
   r?   r   )r$   dir_pathsource_filer8   r-   r   r   r   r   r?      s    
zPlugin._find_c_source_filesc             C   s   | j dkri | _ || j kr&| j | }n| j|}|| j |< | jdkrJi | _x2|j D ]&\}}t||dd}|||f| j|< qTW || jkrd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   )N)NN)_parsed_c_files_parse_cfile_linesr(   itemsr"   )r$   r.   
sourcefile
code_linesr-   r1   r   r   r   r   r*      s    





zPlugin._read_source_linesc             C   sj  t jdj}t jdj}t jdj}t jdj}t jdj}tt}tt}d}	t|}
t|
}
x|
D ]}||}|sd|krh|	dk	rh||}|rh||	 jt	|j
d qh|j \}}|}	t	|}xL|
D ]D}||}|r|j
dj }||rP ||| |< P q||rP qW qhW W dQ R X xB|j D ]6\}}
t|
j|j|f }x|D ]}|
|= qPW q,W |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;   compilematchr   dictsetrE   iteraddintgroupgroupsrstriprS   
differenceget)r$   r.   Zmatch_source_path_lineZmatch_current_code_lineZmatch_comment_endZmatch_trace_lineZnot_executablerU   Zexecutable_linesZcurrent_filenamelineslinerW   Z
trace_liner-   linenoZcomment_line	code_lineZ
dead_linesr   r   r   rR      sJ    



zPlugin._parse_cfile_lines)__name__
__module____qualname__r+   r(   rQ   r%   r2   r4   r)   r?   r*   rR   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 )r,   zA
    Find the Python/Cython source file for a Cython module.
    c                s0   t t| j  || _|| _|| _|| _|| _d S )N)superr,   __init__module_filer/   r.   r(   r+   )r$   rk   r/   r.   Zc_files_mapZfile_path_map)	__class__r   r   rj     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}y
| j| S  tk
r&   Y nX t||}| jr^|dd j dkr^| j| j|< | jS | jdk	slt|| jkr| j	|df| j|< || j|< |S )zR
        Determine source file path.  Called by the function call tracer.
           Nz.py)
f_codeco_filenamer+   KeyErrorr"   r/   r9   r(   AssertionErrorr.   )r$   r-   framerO   r   r   r   r   dynamic_source_filename  s    



z*CythonModuleTracer.dynamic_source_filename)rf   rg   rh   __doc__rj   rm   ru   __classcell__r   r   )rl   r   r,     s   r,   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 )r3   zP
    Provide detailed trace information for one source file to coverage.py.
    c                s&   t t| j| || _|| _|| _d S )N)ri   r3   rj   namer.   _code)r$   r.   rO   r    r1   )rl   r   r   rj   -  s    zCythonModuleReporter.__init__c             C   s
   t | jS )zJ
        Return set of line numbers that are possibly executable.
        )rY   ry   )r$   r   r   r   rb   3  s    zCythonModuleReporter.linesc             c   sT   d}xJt | jj D ]8\}}x||kr6g V  |d7 }qW d|fgV  |d7 }qW d S )Nr   txt)sortedry   rS   )r$   current_lineZline_nore   r   r   r   _iter_source_tokens9  s    
z(CythonModuleReporter._iter_source_tokensc          	   C   sF   t jj| jr*t| j
}|j S Q R X ndjdd | j 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>K  s   z.CythonModuleReporter.source.<locals>.<genexpr>)r   r   r   r-   r   rF   r   r}   )r$   rK   r   r   r   sourceB  s    zCythonModuleReporter.sourcec             c   sh   t jj| jrFt| j&}x|D ]}d|jdfgV  q W W dQ R X nx| j D ]}d|fgV  qPW dS )z6
        Iterate over the source code tokens.
        rz   r~   N)r   r   r   r-   r   r_   r}   )r$   rK   rc   r   r   r   source_token_linesN  s    
"z'CythonModuleReporter.source_token_lines)
rf   rg   rh   rv   rj   rb   r}   r   r   rw   r   r   )rl   r   r3   )  s   	r3   c             C   s   | j t  d S )N)Zadd_file_tracerr#   )regoptionsr   r   r   coverage_init[  s    r   )F)rv   
__future__r   r;   os.pathr   r   collectionsr   Zcoverage.pluginr   r   r   Zcoverage.filesr   Utilsr	   r
   r   r   r   r   rY   r:   r   r"   r#   r,   r3   r   r   r   r   r   <module>   s$   	
 O&2