
    Ae4                         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         Zd ZddZ G d de
      Z G d de      Z G d de      Zd Zy)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                 p    t         j                  j                  }t        D ]  }| |z   } ||      s|c S  y N)ospathexistsC_FILE_EXTENSIONS)	base_pathfile_existsext	file_names       /lib/python3.12/site-packages/Cython/Coverage.py_find_c_sourcer      s:    ''..K  O	y!     c                    t         j                  j                  |      }t         j                  j                  |      s|j	                  d      s|r{t         j                  j                  t         j                  j                  |       |      }t         j                  j                  |      rt         j                  j                  |      }t         j                  j                  |      s~t        j                  D ]k  }t         j                  j                  t         j                  j                  ||            }t         j                  j                  |      s`t        |      c S  t        |      S )N.pxi)
r   r   abspathr   endswithjoindirnamesysrealpathr   )	main_file	file_pathrelative_path_searchabs_pathrel_file_pathsys_path	test_paths          r   _find_dep_file_pathr,   $   s    wwy)H77>>(#););F)C)=RWW__Y%?K77>>-(ww}5H77>>(# 	5H((h	)JKIww~~i())44	5 h''r   c                   B    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
d Zd Zy)	PluginNc                     dt         fgS )NzCython versionr   selfs    r   sys_infozPlugin.sys_info=   s    !;/00r   c                    |j                  d      s|j                  d      rydx}}t        t        j                  j	                  |            }| j
                  r || j
                  v r| j
                  |   d   }|/| j                  |      \  }}|sy| j                  ||      \  }}|y| j                  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)r1   filenamec_filepy_file_codes         r   file_tracerzPlugin.file_tracer@   s     s#x':':9'E%bggooh&?@T->->!>&&x03F>"55h?OFG --fh?GAt|&"$D!(GVT=N=NPTPcPcddr   c                 (   t        t        j                  j                  |            }| j                  r"|| j                  v r| j                  |   \  }}}n/| j                  |      \  }}|sy | j                  ||      \  }}|y t        ||||      S r   )r   r   r   r   r6   r7   r8   CythonModuleReporter)r1   r;   r<   r)   r?   r>   s         r   file_reporterzPlugin.file_reporter^   s     &bggooh&?@T->->!>*.*;*;H*E'FM4//9IFA"&"9"9&("KM4|#FHmTJJr   c                 .   t         j                  j                  |      \  }}|j                         }|t        v rn|dk(  r;t        j                  d|t
        j                        }|r|d |j                          }n|dk(  r;t        j                  d|t
        j                        }|rk|d |j                          }nW|dk(  rQ| j                  t         j                  j                  |      |       || j                  v r| j                  |   d   d fS y|t        v r|n
t        |      }|t        j                  |      }t         j                  j!                  ||      j#                  t         j                  j$                        }t'        |      dkD  rWt         j                  j)                  t         j                  j                  |      d	j)                  |            }t        |      }d }	|r~t         j                  j                  |      d   d
z   }	t         j                  j+                  |	      sd }		 t-        |d      5 }
d|
j/                  d      vr
	 d d d        y	 d d d        ||	fS ||	fS # 1 sw Y   xY w# t0        t2        f$ r d }Y ||	fS w xY w)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"   r6   r   r   r
   uncachedrelpathsplitseplenr!   r   openreadIOErrorOSError)r1   r;   basenamer   platform_suffixr<   package_rootpackage_pathtest_basepathpy_source_filefs              r   r7   zPlugin._find_source_filesq   sI   ((2#iik((F] ii(ExQSQUQUVO#$<_%:%:%<=E\ ii(QS[]_]a]abO#$<_%:%:%<=F] %%bggooh&?J4,,,((215t;;  $55>(;S>099(CL77??8\BHHUL< 1$ "RWW__X-FQ]H^ _'6WW--f5a85@N77>>.1!%&$' *11C)* *C* ~%%v~%%* * W% ~%%s0   6I= I1I= !I= 1I:6I= =JJc                    t         j                  j                  |      syt         j                  j                  }t        j                  |      D ]d  } ||      d   j                         }|t        v s%| j                  t         j                  j                  ||      |       || j                  v sd y t        |      r0| j                  t         j                  j                  |      |       yy)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   isdirrI   listdirrJ   r   r8   r!   r6   r   rP   r"   )r1   dir_pathsource_filerI   r;   r   s         r   rP   zPlugin._find_c_source_files   s    
 ww}}X&77##

8, 	H8$Q'--/C''''Xx(H+V$"3"33	 (#%%bggooh&?M $r   c                 |   | j                   i | _         || j                   v r| j                   |   }n | j                  |      }|| j                   |<   | j                  i | _        |j                         D ]%  \  }}t	        ||d      }|||f| j                  |<   ' || j                  vry| 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'   rE   r	   )_parsed_c_files_parse_cfile_linesr6   itemsr,   )r1   r<   
sourcefile
code_linesr;   r?   r(   s          r   r8   zPlugin._read_source_lines   s     '#%D T)))--f5J008J+5D  ($ "D(..0 	CNHd*68@DFH+18T*BDh'	C
 T...  ,QR00r   c           	         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        |      5 }
t        |
      }
|
D ]  } ||      }|s=d|v r8|	6 ||      }|r,||	   j                  t        |j                  d                   J|j                         \  }}|}	t        |      }|
D ]I  } ||      }|r3|j                  d      j                         } ||      r |||   |<     ||      sI   	 ddd       |j                         D ]9  \  }}
t        |
      j                  |j                  |d	            }|D ]  }|
|=  ; |S # 1 sw Y   WxY w)
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	    )rL   compilematchr   dictsetrV   iteraddintgroupgroupsrstripri   
differenceget)r1   r<   match_source_path_linematch_current_code_linematch_comment_endmatch_trace_linenot_executablerk   executable_linescurrent_filenamelineslinero   
trace_liner;   linenocomment_line	code_line
dead_liness                      r   rh   zPlugin._parse_cfile_lines   s    "$,G!H!N!N"$**-E"F"L"LJJz288::&EFLL

 % 	 !&
&s+&\ 	UKE .t4)T16F6R%5d%;
%,-=>BB3zGWGWXYGZC[\#(<<> &#+ V$) 
L3LAE$)KKN$9$9$;	))4!7@
8,V4*<8
	4  *//1 	"OHeU../?/C/CHb/QRJ$ "&M"	" =	 	s   CG&
G&&G/)__name__
__module____qualname__r9   r6   rg   r2   r@   rC   r7   rP   r8   rh   rm   r   r   r.   r.   5   s8    NLO1e<K&0&dN$141r   r.   c                   .     e Zd ZdZ fdZd Zd Z xZS )r:   zA
    Find the Python/Cython source file for a Cython module.
    c                 p    t         t        |           || _        || _        || _        || _        || _        y r   )superr:   __init__module_filer=   r<   r6   r9   )r1   r   r=   r<   c_files_mapfile_path_map	__class__s         r   r   zCythonModuleTracer.__init__  s7     $02&'+r   c                      y)NTrm   r0   s    r   has_dynamic_source_filenamez.CythonModuleTracer.has_dynamic_source_filename  s    r   c                    |j                   j                  }	 | j                  |   S # t        $ r Y nw xY wt	        ||      }| j
                  r;|dd j                         dk(  r%| j
                  | j                  |<   | j
                  S | j                  J || j                  vr| j                  |df| j                  |<   || j                  |<   |S )zR
        Determine source file path.  Called by the function call tracer.
        Nr   )	f_codeco_filenamer9   KeyErrorr,   r=   rJ   r6   r<   )r1   r;   framere   r(   s        r   dynamic_source_filenamez*CythonModuleTracer.dynamic_source_filename  s     ll..	&&{33 		&x=<<K,224=/3||D,<<  ,,4,,,+/;;T*JDh'+3K(s   ' 	33)r   r   r   __doc__r   r   r   __classcell__r   s   @r   r:   r:     s    ,r   r:   c                   :     e Zd ZdZ fdZd Zd Zd Zd Z xZ	S )rB   zP
    Provide detailed trace information for one source file to coverage.py.
    c                 V    t         t        |   |       || _        || _        || _        y r   )r   rB   r   namer<   _code)r1   r<   re   r)   r?   r   s        r   r   zCythonModuleReporter.__init__-  s(    "D2;?!	
r   c                 ,    t        | j                        S )zJ
        Return set of line numbers that are possibly executable.
        )rq   r   r0   s    r   r   zCythonModuleReporter.lines3  s     4::r   c              #      K   d}t        | j                  j                               D ]%  \  }}||kD  rg  |dz  }||kD  rd|fg |dz  }' y w)Nr	   txt)sortedr   ri   )r1   current_lineline_nor   s       r   _iter_source_tokensz(CythonModuleReporter._iter_source_tokens9  sl     "()9)9);"< 	GYL(! L( 9%&&AL	s   ?AAc                    t         j                  j                  | j                        r/t	        | j                        5 }|j                         cddd       S dj                  d | j                         D              S # 1 sw Y   yxY w)zA
        Return the source code of the file as a string.
        N
c              3   4   K   | ]  }|r|d    d   nd  yw)r   r	    Nrm   ).0tokenss     r   	<genexpr>z.CythonModuleReporter.source.<locals>.<genexpr>J  s'      : "(1R/:s   )r   r   r   r;   r   rW   r!   r   )r1   r`   s     r   sourcezCythonModuleReporter.sourceB  sr     77>>$--(!$--0  Avvx    99 :"668: : :   s   A??Bc              #   (  K   t         j                  j                  | j                        r=t	        | j                        5 }|D ]  }d|j                  d      fg  	 ddd       y| j                         D ]	  }d|fg  y# 1 sw Y   yxY ww)z6
        Iterate over the source code tokens.
        r   r   N)r   r   r   r;   r   rw   r   )r1   r`   r   s      r   source_token_linesz'CythonModuleReporter.source_token_linesN  s      77>>$--(!$--0 7A 7D!4;;t#456677 7 002 &t}o%&	7 7s   ?BB &BBB)
r   r   r   r   r   r   r   r   r   r   r   s   @r   rB   rB   )  s!    
:
&r   rB   c                 6    | j                  t                      y r   )add_file_tracerr.   )regoptionss     r   coverage_initr   [  s    !r   )F)r   
__future__r   rL   os.pathr   r#   collectionsr   coverage.pluginr   r   r   coverage.filesr   Utilsr
   r   r   r   r   r   rq   rK   r   r,   r.   r:   rB   r   rm   r   r   <module>r      s    ' 	  
 # D D - J J  2 47HHI ("K^ K\# #L/&< /&d"r   