o
    i0A                     @   sp  U d dl mZ d dlmZ d dlmZ d dlmZ d dlZd dl	m
Z
 d dlZd dlmZ d dlm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 d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm Z  d dl!m"Z" d dl#m$Z$ ee%Z&e'Z(edg dZ)ee*ee+e"f   e,d< edddZ-edddZ.dee+e"f fddZ/G dd deZ0dS )    )defaultdict)
ContextVar)deepcopy)	getmoduleN)Path)CodeType)
ModuleType)instrument_all_lines)gen_json_report)print_coverage_report)collapse_ranges)
get_logger)ModuleWatchdog)platlib_path)platstdlib_path)purelib_path)stdlib_path)CoverageLines)resolved_code_originctx_covered)defaultctx_is_import_coverageFctx_coverage_enabledreturnc                  C   s.   t  rt  } r| d S td ttS )Nz>_get_ctx_covered_lines() called but ctx_covered stack is empty)r   getr   logdebugr   r   )context_stack r   R/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/internal/coverage/code.py_get_ctx_covered_lines#   s
   
r!   c                
       s  e Zd ZU dZejd  ed< d< fddZed=deje	e
  def fd	d
Zdeeeejeeeedf f  f fddZe		d>dejeeef  dejeeef  fddZed?de
defddZed?dede
defddZd?dedeeef fddZdd ZG dd  d Zed!d" Zed#d$ Zed%d& Zed'eje
 dejee
ef  fd(d)Zed*d+ Zed?de
defd,d-Zd.e d/e!de fd0d1Z"d/e!ddfd2d3Z#d/e!ddfd4d5Z$d.e de fd6d7Z%d>d8d9Z&ed< fd:d;Z'  Z(S )@ModuleCodeCollectorN	_instancer   c                    s   t    d| _g | _ttttg| _| j	t
t j d| _t | _tt| _tt| _tt| _i | _i | _tt| _zdd lm  m} | j|_W d S  tyX   Y d S w )NFr   )super__init___collect_import_coverage_include_pathsr   r   r   r   _exclude_pathsappendr   __file__resolveparent_coverage_enabledsetseenr   r   linescovered_import_time_covered_import_time_contexts_import_time_name_to_path_import_names_by_path_pytest.assertion.rewrite	assertionrewrite_execexecImportError)selfpar	__class__r   r    r%   /   s&   




zModuleCodeCollector.__init__Finclude_pathscollect_import_time_coveragec                    sj   t  rd S t   | jd u rd S |d u rtt g}|| j_|| j_	|r3t 
dd | jj d S d S )Nc                 S   s   dS NTr   )xr   r   r    <lambda>c   s    z-ModuleCodeCollector.install.<locals>.<lambda>)r"   is_installedr$   installr#   r   osgetcwdr'   r&   register_import_exception_hook_exit_context_on_exception_hook)clsr@   rA   r>   r   r    rF   P   s   

zModuleCodeCollector.installarg.c                 C   sj   |\}}}| j r| j| }|| t r t | }|| |d ur1| jr3| j| | d S d S d S N)r-   r1   addr   r   r!   r&   r5   )r<   rL   linepathimport_namer0   	ctx_linesr   r   r    hookf   s   




zModuleCodeCollector.hookr0   r1   c                 C   s   | j }|du r	dS d}t rt }|r%| D ]\}}|j| | q|rJ| D ] \}}|jr:|j| | t rI|durI|| | q+dS dS )z[Inject coverage data into the collector. This can be used to arbitrarily add covered files.N)	r#   r   r   r!   itemsr0   updater-   r1   )rK   r0   r1   instancectx_covered_linesrP   
path_linespath_coveredr   r   r    inject_coveragey   s$   z#ModuleCodeCollector.inject_coverageworkspace_pathignore_nocoverc                 C   s6   | j d u rd S | j }|j}| }t||||d d S )Nr\   )r#   r0   _get_covered_linesr   )rK   r[   r\   rV   executable_linescovered_linesr   r   r    report   s   
zModuleCodeCollector.reportfilenamec              	   C   sh   | j d u rd S | j }|j}| }t|d}|t||||d W d    d S 1 s-w   Y  d S )Nwr]   )r#   r0   r^   openwriter
   )rK   rb   r[   r\   rV   r_   r`   fr   r   r    write_json_report_to_file   s   
"z-ModuleCodeCollector.write_json_report_to_fileinclude_importedc                 C   s*   t t rt n| j}|r| | |S rM   )r   r   r   r!   r1   _add_import_time_lines)r<   rh   r`   r   r   r    r^      s   
z&ModuleCodeCollector._get_covered_linesc                 C   s8  t  }t | }|r| }||v rq	|| || jvrq	| j| }|| | | j|t  D ]b}|\}}|D ]Y}	|rF| d|	 n|	}
|
| jv rO|
n|	}|| jv rd| j| }||vrd|| |
	ddd }|rd
|}|| jv r| j| }||vr|| ||krn|dd }|soq;q3|sdS dS )zRModify given covered_lines in place and add lines that were covered at import time.Nr   )r.   keyspoprN   r2   rU   r5   r   r4   splitjoin)r<   r`   visited_pathsto_visit_pathsrP   imported_module_linesdependenciespackagemodulesmoduledep_fqdndep_namedependency_pathparent_packageparent_package_strr   r   r    ri      sD   









z*ModuleCodeCollector._add_import_time_linesc                   @   sB   e Zd ZddefddZdd Zdd Zd	eee	f fd
dZ
dS )z$ModuleCodeCollector.CollectInContextFis_import_coveragec                 C   s$   || _ t d u rtg  d S d S rM   )r{   r   r   r.   )r<   r{   r   r   r    r%      s   z-ModuleCodeCollector.CollectInContext.__init__c                 C   sF   t  tt td | jrt| j t	j
dkr!t	j  | S )NT)      )r   r   r)   r   r   r   r.   r{   r   sysversion_info
monitoringrestart_events)r<   r   r   r    	__enter__   s   


z.ModuleCodeCollector.CollectInContext.__enter__c                 O   s.   t  }|  t|dkrtd d S d S )Nr   F)r   r   rl   lenr   r.   )r<   argskwargscovered_lines_stackr   r   r    __exit__   s
   z-ModuleCodeCollector.CollectInContext.__exit__r   c                 C   s   t  }tj }r|| |S rM   )r!   r"   r#   ri   )r<   r`   global_instancer   r   r    get_covered_lines   s   

z6ModuleCodeCollector.CollectInContext.get_covered_linesNF)__name__
__module____qualname__boolr%   r   r   dictstrr   r   r   r   r   r    CollectInContext   s
    r   c                 C      | j d u rd S d| j _d S rB   r#   r-   rK   r   r   r    start_coverage      
z"ModuleCodeCollector.start_coveragec                 C   r   NFr   r   r   r   r    stop_coverage  r   z!ModuleCodeCollector.stop_coveragec                 C   s"   t  rdS | jd u rdS | jjS )NTF)r   r   r#   r-   r   r   r   r    coverage_enabled  s
   
z$ModuleCodeCollector.coverage_enabledpathsc                 C   sD   i }| j du r	i S |D ]}t|}|| j jv r| j j| ||< q|S )z5Returns import-time coverage data for the given pathsN)r#   r   r2   )rK   r   	coveragesrP   path_strr   r   r    get_import_coverage_for_paths  s   
z1ModuleCodeCollector.get_import_coverage_for_pathsc                 C   s   | j d uot S rM   )r#   r   r   r   r   r   r    coverage_enabled_in_context!  s   z/ModuleCodeCollector.coverage_enabled_in_contextc              	   C   s   | j du rg S g }| j j|d}| D ]D\}}t|}||r(t||n|}dd tt|	 D }	t
|	}
g }|
D ]}||d d|d ddg q?|||d q|S )	a  Generate the same data as expected by ddtrace.ci_visibility.coverage.build_payload:

        if input_path is provided, filter files to only include that path, and make it relative to said path

        "files": [
            {
                "filename": <String>,
                "segments": [
                    [Int, Int, Int, Int, Int],  # noqa:F401
                ]
            },
            ...
        ]
        N)rh   c                 S   s   g | ]
\}}|d kr|qS )   r   ).0ivr   r   r    
<listcomp>@  s    z9ModuleCodeCollector.report_seen_lines.<locals>.<listcomp>r   r   r   )rb   segments)r#   r^   rT   r   is_relative_tor   relative_to	enumeratesortedto_sorted_listr   r)   )rK   r[   rh   filesr1   abs_path_strr0   abs_pathr   sorted_linescollapsed_rangesfile_segmentsfile_segmentr   r   r    report_seen_lines%  s   
z%ModuleCodeCollector.report_seen_linescode_modulec                    s   |d u r|S t | t fdd| jD s|S t fdd| jD r&|S | ||d ur0|jnd}| jrM|j| j|j	< | j
dd}|  || j|j< |S )Nc                 3       | ]}  |V  qd S rM   r   )r   include_path	code_pathr   r    	<genexpr>P      z0ModuleCodeCollector.transform.<locals>.<genexpr>c                 3   r   rM   r   )r   exclude_pathr   r   r    r   T  r    T)r{   )r   anyr'   r(   instrument_code__package__r&   co_filenamer4   r   r   r   r3   )r<   r   r   retvalmodule_contextr   r   r    	transformJ  s   zModuleCodeCollector.transformc                 C   sj   t |dr1|j| jv r3| j|j }| }|  ||j r*| j|j ||j  | j|j= d S d S d S Nr*   )hasattrr*   r3   r   r   r2   rU   )r<   _r   	collectorr`   r   r   r    rJ   b  s   
z3ModuleCodeCollector._exit_context_on_exception_hookc                 C   st   | j sd S t|dr6|j| jv r8| j|j }| }|  ||j r/| j|j ||j  | j|j= d S d S d S r   )r&   r   r*   r3   r   r   r2   rU   )r<   r   r   r`   r   r   r    after_importl  s   
z ModuleCodeCollector.after_importc                 C   sd   ||j f| jv r
|S | j||j f t|| j|j |\}}| j||j f | j|j  | |S rM   )r   r/   rN   r	   rS   r0   rU   )r<   r   rs   new_coder0   r   r   r    r   y  s   z#ModuleCodeCollector.instrument_codec                 K   sD   t |}t|tr|jdkr| ||n|}t|||fi | d S )Nz<module>)r   
isinstancer   co_namer   _original_exec)r<   _object_globals_localsr   ru   
new_objectr   r   r    r9     s   
zModuleCodeCollector._execc                    s:   zdd l m  m} t|_W n	 ty   Y nw t  S )Nr   )r6   r7   r8   r   r:   r;   r$   	uninstall)rK   r=   r>   r   r    r     s   

zModuleCodeCollector.uninstall)r   Nr   )NNr   ))r   r   r   r#   tOptional__annotations__r%   classmethodlistr   r   rF   tupleintr   rS   r   r   rZ   ra   rg   r^   ri   r   r   r   r   Iterabler   r   r   r   r   r   rJ   r   r   r9   r   __classcell__r   r   r>   r    r"   ,   sP   
 !$.
,"


(
$

r"   )1collectionsr   contextvarsr   copyr   inspectr   rG   pathlibr   r~   typesr   r   typingr   )ddtrace.internal.coverage.instrumentationr	    ddtrace.internal.coverage.reportr
   r   ddtrace.internal.coverage.utilr   ddtrace.internal.loggerr   ddtrace.internal.moduler   ddtrace.internal.packagesr   r   r   r   /ddtrace.internal.test_visibility.coverage_linesr   !ddtrace.internal.utils.inspectionr   r   r   r:   r   r   r   r   r   r   r   r!   r"   r   r   r   r    <module>   s:    $	