o
    i=                     @   s  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 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e"e#e$e%e&ef Z'ee(e)e"e% e"e$ f Z*e"e#e$e%fZ+G dd deZ,G dd de,Z-G dd de	e-Z.de(dede(fd d!Z/G d"d# d#Z0d$ede1e(e0f fd%d&Z2G d'd( d(eZ3d)S )*    )defaultdict)deque)CodeType)FunctionType)
ModuleType)Any)Iterator)Optional)Protocol)Union)cast)FunctionWrapper)PYTHON_VERSION_INFO)
get_loggerorigin)_isinstance)collect_code_objects)functions_for_code)linenos)resolved_code_origin)undecorated)get_function_codec                   @   s2   e Zd ZU dZdZ ee ed< dZee ed< dS )
FullyNamedzA fully named object.N__name____fullname__)r   
__module____qualname____doc__r	   str__annotations__r    r!   r!   Y/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/debugging/_function/discovery.pyr   $   s   
 r   c                   @   s0   e Zd ZU dZeed< dededefddZdS )	FullyNamedFunctionzA fully named function object.r   argskwargsreturnc                 O   s   d S Nr!   )selfr$   r%   r!   r!   r"   __call__0   s   zFullyNamedFunction.__call__N)r   r   r   r   r   r    r   r)   r!   r!   r!   r"   r#   +   s   
 r#   c                
   @   sz   e Zd ZdZ	ddedeeed ef ee	e
f f  ddfddZdeeeef  fdd	Zdeeef fd
dZeZdS )ContainerIteratorzWrapper around different types of function containers.

    A container comes with an origin, i.e. a parent container and a position
    within it in the form of a key.
    N	containerr   r&   c                    s$  t  ttfrt j  | _ j| _nPt  t	r+tt
dd  D | _d| _n;t  trIt fdddD | _ jd usCJ  jj| _nt  ttfr_tt  jfg| _d | _ntdt  | _|d ur|d jd ur|d j}| jrd|| jf| _d S || _d S | j| _d S )	Nc                 s   s    | ]}|j V  qd S r'   )cell_contents).0_r!   r!   r"   	<genexpr>G   s    z-ContainerIterator.__init__.<locals>.<genexpr><locals>c                 3   s"    | ]\}}|t  |fV  qd S r'   )getattr)r-   mar+   r!   r"   r/   K   s    
>   getterfgetsetterfsetdeleterfdelzUnsupported container type: %sr   .)
isinstancetyper   iter__dict__copyitems_iterr   tuple	enumeratepropertyr7   classmethodstaticmethod__func__	TypeError
_containerr   join)r(   r+   r   origin_fullnamer!   r4   r"   __init__;   s*   




&zContainerIterator.__init__c                 C   s   | j S r'   )rE   r(   r!   r!   r"   __iter__`   s   zContainerIterator.__iter__c                 C   s
   t | jS r'   )nextrE   rQ   r!   r!   r"   __next__c   s   
zContainerIterator.__next__r'   )r   r   r   r   FunctionContainerTyper	   r   rF   ContainerKeyr#   r   rP   r   r   rR   rT   rS   r!   r!   r!   r"   r*   4   s    	
%r*   namefr&   c                 C   s8   |j }|dr| |r|S | |krd| |fS |S )N__z	.<alias>.)r   
startswithendswithrN   )rW   rX   	func_namer!   r!   r"   _local_namei   s   r]   c                   @   sB   e Zd ZdZdZddee dee ddfddZde	fd	d
Z
dS )_FunctionCodePairzFunction-Code Pair

    This class allows us to resolve a code object to a function object by
    querying the GC on-demand.
    )functioncodeNr`   r_   r&   c                 C   sF   |d ur|d ur|j |urtd|| _|d ur|j | _d S || _d S )Nz&Function and code objects do not match)__code__
ValueErrorr_   r`   )r(   r`   r_   r!   r!   r"   rP      s   z_FunctionCodePair.__init__c                 C   s   | j d urtt| j S | jd u rd}t|| j}t|}t|}|dkr.d| }t||dkr;d| }t||d  | _ }z|j| _W n	 tyQ   Y nw tt|}|j	 d|j
 |_|S )Nz'Cannot resolve pair with no code objectr   z(Cannot resolve code object to function:    z)Multiple functions found for code object r>   )r_   r   r#   r`   rb   r   lenra   AttributeErrorr   r   r   )r(   msgr`   	functionsn_frX   r!   r!   r"   resolve   s.   




z_FunctionCodePair.resolve)NN)r   r   r   r   	__slots__r	   r   r   rP   r#   rj   r!   r!   r!   r"   r^   v   s
     r^   modulec              	   C   s  t | }|du r
i S tt| g}i }t }t }|r| }t|j|v r'q|t|j |D ]\}}t|t	t
frBt|ddnd}	|	durtt	|}
t|trWt||n|j}||vrv|| tt|}|jrsd|j|fn||_t|tr||kr||fn|fD ]-}|jrd|j|fn|}||vst|	|krttt	||krt|
||n|d||< qz|
jr|t|
j|dfd W q1 ty   Y q1w t|trt|trt|jt	sq1|t|||fd q1|s|S )zCollect functions from a given module.

    All the collected functions are augmented with a ``__fullname__`` attribute
    to disambiguate the same functions assigned to different names.
    Nra   r>   r_   r0   r   )r   r   r*   setpopleftidrM   addr   r   r   r1   r   r?   r   r]   r   r#   r   rN   r   r^   r   __closure__appendre   CONTAINER_TYPESrH   r7   )rl   path
containersrg   seen_containersseen_functionsckor`   rX   
local_namerW   fullnamer!   r!   r"   _collect_functions   sT   


$

(r~   c                       s   e Zd ZdZdeddf fddZdedee fdd	Z	d
e
dedefddZdedefddZededd fddZedededefddZ  ZS )FunctionDiscoverya  Discover all function objects in a module.

    The discovered functions can be retrieved by line number or by their
    qualified name. In principle one wants to create a function discovery
    object per module and then cache the information. For this reason,
    instances of this class should be obtained with the ``from_module`` class
    method. This builds the discovery object and caches the information on the
    module object itself.
    rl   r&   Nc           
   	      s^  t  t t|}|d u rd S || _tdk rtt| _i | _t	|dr^i | _
|jD ]1}t|d}tdkrD|j d|j }|| j
|< n	| j|j | t|D ]	}| | | qQq*d S t|| _
t }| j
 D ]A\}}z| }	W n	 ty~   Y qkw |	|vrtttt|	 }|krttt|D ]}| | ttt|	d q||	 qkd S )N      __dd_code__)r`   r>   rm   )superrP   listr   _moduler   r   _name_index_cachedhasattr_fullname_indexr   r^   r   co_qualnameco_namers   r   r~   rn   rD   rj   rb   r   r   r   r   rq   )
r(   rl   module_pathr`   fcpr}   linenorx   r.   r_   	__class__r!   r"   rP      sD   




zFunctionDiscovery.__init__linec              	   C   sr   || j v r
| j | S || v r7g }| | D ]}z	||  W q ty(   Y qw |s0| |= |S || j |< |S g S )zGet the functions at the given line.

        Note that, in general, there can be multiple copies of the same
        functions. This can happen as a result, e.g., of using decorators.
        )r   rs   rj   rb   )r(   r   rg   r   r!   r!   r"   at_line%  s    


zFunctionDiscovery.at_linepairr}   c           	      C   s   z|  W S  typ } z_| j }}d }||j ddddD ]}zt||}W q" ty4   |w ||u r;||j}|d usDJ t	t
t|t
t|t|}t|tr\|j|u s^|||_t
t|W  Y d }~S d }~ww )Nr>    rc   )rj   rb   r   replacer   splitr1   re   r`   r   r   r   r   r   r?   ra   r_   r#   )	r(   r   r}   erl   targetpartr`   rX   r!   r!   r"   _resolve_pairA  s,   

 zFunctionDiscovery._resolve_pairqualnamec                 C   s   | j j d| }z
| | j| |W S  ty   Y nS tyn   tdk rl| j D ]@\}}||ks;|	d| rkt
|D ]+}z | ||}|| j|< |d |j|kr`|W      Y S W q? tyj   Y q?w q+Y nw td| )z'Get the function by its qualified name.r>   r   r   zFunction '%s' not found)r   r   r   r   rb   KeyErrorr   r   rD   r[   r   popr   )r(   r   r}   rW   fcpsr   rX   r!   r!   r"   by_namea  s.   


zFunctionDiscovery.by_namec                 C   s<   z|j W S  ty   | | }|_ t|dr|`| Y S w )zReturn a function discovery object from the given module.

        If this is called on a module for the first time, it caches the
        information on the module object itself. Subsequent calls will
        return the cached information.
        r   )__function_discovery__re   r   r   )clsrl   fdr!   r!   r"   from_module  s   	
zFunctionDiscovery.from_moduler`   c                 C   s   t ||_|S r'   )r   r   )r   r`   rl   r!   r!   r"   transformer  s   
zFunctionDiscovery.transformer)r   r   r   r   r   rP   intr   r#   r   r^   r   r   r   rI   r   r   r   __classcell__r!   r!   r   r"   r      s    
2 ! r   N)4collectionsr   r   typesr   r   r   typingr   r   r	   r
   r   r   wraptr   ddtrace.internal.compatr   ddtrace.internal.loggerr   ddtrace.internal.moduler   ddtrace.internal.safetyr   !ddtrace.internal.utils.inspectionr   r   r   r   r   ddtrace.internal.wrappingr   r   logr@   rH   rI   rJ   rF   rU   r   r   rV   rt   r   r#   r*   r]   r^   dictr~   r   r!   r!   r!   r"   <module>   sB    	57;