o
    iF.                     @   s  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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 jdd ZG dd de	Zeeee eeef gef ZdedefddZe Zedkre d nedkre d ne d e Z!edkre! d nedkre! d ne! d e Z"edkre" d nedkre" d  ne" d! eedkZ#d"edeeddf fd#d$Z$e  Z% d% d"edeeddf fd&d'Z&d(ed)edej'fd*d+Z(d,ed(edefd-d.Z)d,ede*fd/d0Z+d,ed(ede*fd1d2Z,d3ed(edefd4d5Z-d,edefd6d7Z.d,ed"eddfd8d9Z/dS ):    N)CodeType)FunctionType)Any)Callable)	Generator)Optional)Protocol)cast)Instr)Assembly)link_function_to_code)
wrap_async)wrap_generator   c                   @   sP   e Zd ZU dZdZee ed< dZee	e
e
f  ed< de
de
de
fdd	ZdS )
WrappedFunctionzA wrapped function.N__dd_wrapped____dd_wrappers__argskwargsreturnc                 O   s   d S N )selfr   r   r   r   V/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/internal/wrapping/__init__.py__call__   s   zWrappedFunction.__call__)__name__
__module____qualname____doc__r   r   r   __annotations__r   dictr   r   r   r   r   r   r      s
   
 r   linenor   c                 C   s&   t dkrtdtjj| dS td| dS )N      	BINARY_OPr!   INPLACE_ADD)PYr
   bcBinaryOpADDr&   r   r   r   _add$   s   r,   )r#      z
            resume              0
            load_const          {wrapper}
            push_null
            load_const          {wrapped}
        r"   z
            resume              0
            push_null
            load_const          {wrapper}
            load_const          {wrapped}
        z]
            load_const          {wrapper}
            load_const          {wrapped}
        )r#      z
            copy                1
            load_method         $update
            load_fast           {varkwargsname}
            call                1
            pop_top
        z
            copy                1
            load_method         $update
            load_fast           {varkwargsname}
            precall             1
            call                1
            pop_top
        z
            dup_top
            load_attr           $update
            load_fast           {varkwargsname}
            call_function       1
            pop_top
        zH
            call                {arg}
            return_value
        zn
            precall             {arg}
            call                {arg}
            return_value
        zH
            call_function       {arg}
            return_value
        codec                 #   s     j } jt t jtjj@ } j}|r|| j	  nd}|rN fdd|d| D E dH  t
d|dV  |rLt
d|dV  tV  dS dS |rZt
d|dV  dS t
dddV  dS )zAGenerate the opcodes for building the positional arguments tuple.Nc                 3   sD    | ]}t d kr| jv rtdt|dntd|dV  qdS )r"   
LOAD_DEREFr&   	LOAD_FASTN)r(   co_cellvarsr
   r)   CellVar).0argnamer/   r!   r   r   	<genexpr>   s    
z#generate_posargs.<locals>.<genexpr>BUILD_TUPLEr&   r1   r   )co_varnamesco_firstlinenoFIRSTLINENO_OFFSETboolco_flagsr)   CompilerFlagsVARARGSco_argcountco_kwonlyargcountr
   r,   )r/   varnamesvarargsnargsvarargsnamer   r6   r   generate_posargs   s$   

rF   zI
        load_const          {arg}
        load_fast           {arg}
    c           
      c   s    | j }| j}| jt }t|tjj@ }t|tjj@ }| j	}| j
}|r,||| |  nd}|ra||||  D ]}	tjd|	i|dE dH  q8td||dV  |r_tjd|i|dE dH  dS dS |rmtd||dV  dS tdd|dV  dS )zCGenerate the opcodes for building the keyword arguments dictionary.Nargr&   	BUILD_MAPvarkwargsnamer1   r   )r=   r9   r:   r;   r<   r)   r>   r?   VARKEYWORDSr@   rA   PAIRbindr
   
UPDATE_MAP)
r/   flagsrB   r!   rC   	varkwargsrD   
kwonlyargsrI   rG   r   r   r   generate_kwargs   s&   
rQ   wrapperwrappedc                    s   |j }|jt  tj| |d d}|t| |t| |tjddi d t	dkrR|j
rA fdd|j
D |dd< |jrR|dtd	t|j d tjj|j@ rhtjj|j@ sht||  |S t||  |S )
a  Wrap a function with a wrapper function.

    The wrapper function expects the wrapped function as the first argument,
    followed by the tuple of arguments and the dictionary of keyword arguments.
    The nature of the wrapped function is also honored, meaning that a generator
    function will return a generator function, and a coroutine function will
    return a coroutine function, and so on. The signature is also preserved to
    avoid breaking, e.g., usages of the ``inspect`` module.
    )rR   rS   r&   rG   r#   r"   c                    s    g | ]}t d t| dqS )	MAKE_CELLr&   )r
   r)   r3   )r4   _r&   r   r   
<listcomp>   s     z!wrap_bytecode.<locals>.<listcomp>r   COPY_FREE_VARS)__code__r:   r;   HEADrL   extendrF   rQ   CALL_RETURNr(   r2   co_freevarsinsertr
   lenr)   r>   	GENERATORr=   	COROUTINEr   r   )rR   rS   r/   instrsr   r&   r   wrap_bytecode   s    
rb   fc           
      C   s  t | j }| jd| j| j}ztt| }tt |jtt|_W n	 ty(   Y nw | j	|_	|j
}|j }|j } t|tjj@  t|tjj@  }t||}	||	_|jd| |	_|j|	_|j|	_||	_||	_|j|	_|j|	_t dkrx|j!|	_"|	# | _tt| }||_t$||  |S )a>  Wrap a function with a wrapper.

    The wrapper expects the function as first argument, followed by the tuple
    of positional arguments and the dict of keyword arguments.

    Note that this changes the behavior of the original function with the
    wrapper function, instead of creating a new function object.
    	<wrapped>Nr"   )%r   rX   __globals____defaults____closure__r	   r   r   AttributeError__kwdefaults__r=   r@   rA   r<   r)   r>   r?   rJ   rb   argcountr9   argnamesco_filenamefilenamer\   freevarsrN   kwonlyargcountco_namenameco_posonlyargcountposonlyargcountr(   r2   cellvarsto_coder   )
rc   rR   r/   rS   wfrN   rj   kwonlycountrD   wrapped_coder   r   r   wrap   sN   	




ry   c                 C   sD   zt t| }t t|j}|jdksJ dW dS  ty!   Y dS w )z0Check if a function is wrapped with any wrapper.rd   Wrapper has wrapped functionTF)r	   r   r   r   r   rh   )rc   rv   innerr   r   r   
is_wrapped5  s   
r|   c                 C   s\   z#t t| }t t|j}|jdksJ d|| jjv rW dS t||W S  ty-   Y dS w )z7Check if a function is wrapped with a specific wrapper.rd   rz   TF)	r	   r   r   r   r   rX   	co_constsis_wrapped_withrh   )rc   rR   rv   r{   r   r   r   r~   B  s   
r~   rv   c                 C   s   zt t| j}W n ty   t t|  Y S w |jdks J d|t t| jjvr1tt t||S t t| }|j|_z
t t|j| _W |S  tyP   | `Y |S w )zUnwrap a wrapped function.

    This is the reverse of :func:`wrap`. In case of multiple wrapping layers,
    this will unwrap the one that uses ``wrapper``. If the function was not
    wrapped with ``wrapper``, it will return the first argument.
    rd   rz   )	r	   r   r   rh   r   rX   r}   unwrapr   )rv   rR   r{   rc   r   r   r   r   U  s"   

r   c                 C   s    t | rtt| jp| jS | jS r   r|   r	   r   r   rX   )rc   r   r   r   get_function_code|  s    r   c                 C   s&   |t | rtt| jp| _d S | _d S r   r   )rc   r/   r   r   r   set_function_code  s   &r   )0systypesr   r   typingr   r   r   r   r   r	   bytecoder)   r
   ddtrace.internal.assemblyr   !ddtrace.internal.utils.inspectionr    ddtrace.internal.wrapping.asyncsr   $ddtrace.internal.wrapping.generatorsr   version_infor(   r   tupler    strWrapperintr,   rY   parserM   r[   r;   rF   rK   rQ   Bytecoderb   ry   r<   r|   r~   r   r   r   r   r   r   r   <module>   s    
	

	
0='