o
    i$                     @   s.  U 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Zd dl	m
Z
 ze \ZZW n ey8   dZY nw edZi Zeeejf ed< dedeeef fd	d
ZdefddZdd Zdejeeef  fddZddefddZ	ddeje defddZdededeeejf fddZdS )    N)Path)collapse_rangesP   z6^\s*(?P<command>.*)\s*#.*\s+pragma\s*:\s*no\s?cover.*$	ast_cacheworkspace_pathreturnc                 C   s>   i }| D ]}t |}t||r||n|}|||< q|S N)r   stris_relative_torelative_to)executable_linesr   relative_path_strspathpath_objpath_str r   T/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/internal/coverage/report.py_get_relative_path_strings   s   
r   r   c                 C   sP   | t vr$t| d}| }W d    n1 sw   Y  t|t | < t |  S )Nr)r   openreadastparse)r   ffile_srcr   r   r   _get_ast_for_path!   s   
r   c                 C   sr   t | dr| jD ]}t||}|d ur|  S qt | dsd S | j| jkr'd S | j|  kr4| jkr7| S  d S d S )Nbody
end_lineno)hasattrr   find_statement_for_linelinenor   )nodeline
child_node
found_noder   r   r   r   )   s   



r   c                 C   sf   t | | }t|}|r1|d  dr-t| }t||}|dur+|j|j	fS dS ||fS dS )zReturns the start and end lines of statements to ignore the line includes pragma nocover.

    If the line ends with a :, parse the AST and return the block the line belongs to.
    command:N)
	linecachegetlinestripNOCOVER_PRAGMA_REmatchendswithr   r   r    r   )r   src_linetextmatchesparsed	statementr   r   r   no_cover>   s   

r2   Fc                 C   s  d}d}d}t | dkrtd d S t| |}tdd | D d }|}tdtd tdd	| d
ddddddd tdt  t|  D ]\}	}
|
	 }||	 	 }|s|
D ]*}||vrl||vrlqat
|	|}|rt|d |d d D ]}|| || q~qat |}t |}|| }||7 }||7 }||7 }|dkrqOtt|| }ddd |D }|rd| dnd}t||	 | d|d|dt|| d dd|  qOtdt  t|| d }tdd	| |d|d|dd t  d S )Nr   z"No Datadog line coverage recorded.c                 s   s    | ]}t |V  qd S r   len).0r   r   r   r   	<genexpr>]   s    z(print_coverage_report.<locals>.<genexpr>   z DATADOG LINE COVERAGE REPORT =PATH<LINESz>8MISSED COVEREDz  MISSED LINES-   ,c                 S   s.   g | ]\}}||kr| d | nt |qS )r?   )r	   )r5   startendr   r   r   
<listcomp>   s   . z)print_coverage_report.<locals>.<listcomp>z  [] sd   %TOTAL)r4   printr   maxvaluescenterwsorteditemscopyr2   rangediscardr   joinint)r   covered_linesr   ignore_nocovertotal_executable_linestotal_covered_linestotal_missed_linesr   nr   
orig_lines
path_linespath_coveredr"   no_cover_linesno_cover_linen_lines	n_coveredn_missedmissed_rangesmissed
missed_strtotal_covered_percentr   r   r   print_coverage_reportR   sV   
*

6(
ri   c                 C   s   di i}i }|dur| t| | t|  D ]Z\}}| }||  }	|sU|D ]*}
|
|vr5|
|	vr5q*t||
}|rTt|d |d d D ]}|| |	| qGq*|dur]|| n|}tt|	tt||	 d|d |< qt	
|S )a  Writes a JSON-formatted coverage report similar in structure to coverage.py 's JSON report, but only
    containing a subset (namely file-level executed and missing lines).

    {
      "files": {
        "path/to/file.py": {
          "executed_lines": [1, 2, 3, 4, 11, 12, 13, ...],
          "missing_lines": [5, 6, 7, 15, 16, 17, ...]
        },
        ...
      }
    }

    Paths are relative to workspace_path if provided, and are absolute otherwise.
    filesNr   r@   )executed_linesmissing_lines)updater   rP   rQ   rR   r2   rS   rT   listjsondumps)r   rW   r   rX   outputr   r   r]   r^   r_   r"   r`   ra   r   r   r   r   gen_json_report   s,   



rr   coverage_py_filenamedd_coverage_filenamec           
         s  t | d}t| W d   n1 sw   Y  t |d}t|W d   n1 s/w   Y   fddd D i i  fdd d D i i d} d  d  @ D ]}tt d | d t d | d	  td | d  }tt d | d
 td | d
  }ttd | d t d | d  }ttd | d
 t d | d
  }	|rt||d |< |rt||d |< |rt||d |< |	rt|	|d |< q\|S )zWCompare two JSON-formatted coverage reports and return a dictionary of the differences.r   Nc                    s   g | ]
}| d  vr|qS )rj   r   r5   r   )coverage_py_datar   r   rD      s    z,compare_coverage_reports.<locals>.<listcomp>rj   c                    s4   g | ]}t  d  | d dkr|d  vr|qS )rj   rk   r   r3   ru   rv   dd_coverage_datar   r   rD      s
    $)coverage_py_missed_files!coverage_py_missed_executed_lines coverage_py_missed_missing_linesdd_coverage_missed_files!dd_coverage_missed_executed_lines dd_coverage_missed_missing_linesrk   excluded_linesrl   r}   r~   rz   r{   )r   ro   loadkeysrP   setr   )
rs   rt   coverage_py_fdd_coverage_fcompared_datar   r}   r~   rz   r{   r   rw   r   compare_coverage_reports   sh   r   )F)NF) r   ro   r'   ospathlibr   retypingtddtrace.internal.coverage.utilr   get_terminal_sizerO   _OSErrorcompiler*   r   dictr	   Any__annotations__r   r   r   OptionaltuplerV   r2   ri   rr   r   r   r   r   r   <module>   s6   
 
9
$0