o
    i                     @   sl   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
 e
eZdZd	e ZG d
d deZdS )    )Any)OptionalN)
is_wrapted)config   )
get_logger_datadog_pin_self_c                       s`  e Zd ZdZg dZ			d$dee deeeef  deeeef  ddfdd	Z	e
defd
dZdededdf fddZdefddZededed  fddZededed  fddZe		d%dedee deeeef  ddfddZdefddZd&dededdfddZdeddfd d!Z		d%dee deeeef  dd fd"d#Z  ZS )'Pina  Pin (a.k.a Patch INfo) is a small class which is used to
    set tracing metadata on a particular traced connection.
    This is useful if you wanted to, say, trace two different
    database clusters.

        >>> conn = sqlite.connect('/tmp/user.db')
        >>> # Override a pin for a specific connection
        >>> pin = Pin.override(conn, service='user-db')
        >>> conn = sqlite.connect('/tmp/image.db')
    tags_target_config_initializedNservicer   r   returnc                 C   s.   |pi | _ d | _|pi | _|| jd< d| _d S )Nservice_nameTr   )selfr   r   r    r   F/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/_trace/pin.py__init__"   s
   



zPin.__init__c                 C   s
   | j d S )zoBackward compatibility: accessing to `pin.service` returns the underlying
        configuration value.
        r   )r   r   r   r   r   r   1   s   
zPin.servicenamevaluec                    s2   t | ddr|dkrtdtt| || d S )Nr   Fr   z5can't mutate a pin, use override() or clone() instead)getattrAttributeErrorsuperr
   __setattr__)r   r   r   	__class__r   r   r   8   s   zPin.__setattr__c                 C   s   d| j | jf S )NzPin(service=%s, tags=%s)r   r   r   r   r   r   __repr__=   s   zPin.__repr__objsc                  G   s$   | D ]}t |}|r|  S qdS )a  
        Return the first :class:`ddtrace.trace.Pin` found on any of the provided objects or `None` if none were found


            >>> pin = Pin._find(wrapper, instance, conn)

        :param objs: The objects to search for a :class:`ddtrace.trace.Pin` on
        :type objs: List of objects
        :rtype: :class:`ddtrace.trace.Pin`, None
        :returns: The first found :class:`ddtrace.trace.Pin` or `None` is none was found
        N)r
   get_from)r"   objpinr   r   r   _find@   s   
z	Pin._findr$   c                 C   sZ   t | dr	|  S t| rtnt}t| |d}|dur+|jt| kr+| }|	|  |S )aq  Return the pin associated with the given object. If a pin is attached to
        `obj` but the instance is not the owner of the pin, a new pin is cloned and
        attached. This ensures that a pin inherited from a class is a copy for the new
        instance, avoiding that a specific instance overrides other pins values.

            >>> pin = Pin.get_from(conn)

        :param obj: The object to look for a :class:`ddtrace.trace.Pin` on
        :type obj: object
        :rtype: :class:`ddtrace.trace.Pin`, None
        :returns: :class:`ddtrace.trace.Pin` associated with the object, or None if none was found
        __getddpin__N)
hasattrr'   r   _DD_PIN_PROXY_NAME_DD_PIN_NAMEr   r   idcloneonto)r$   pin_namer%   r   r   r   r#   S   s   

zPin.get_fromc                 C   sD   |sdS |  |}|du rt||d}n|j||d}|| dS )a[  Override an object with the given attributes.

        That's the recommended way to customize an already instrumented client, without
        losing existing attributes.

            >>> conn = sqlite.connect('/tmp/user.db')
            >>> # Override a pin for a specific connection
            >>> Pin.override(conn, service='user-db')
        Nr    )r#   r
   r,   r-   )clsr$   r   r   r%   r   r   r   overridel   s   
zPin.overridec                 C   s   t jjptjS )N)ddtracetracerenabled
asm_config_apm_opt_outr   r   r   r   r3      s   zPin.enabledTsendc                 C   sv   z)t |dr|| W S t|rtnt}t|| _| jr#tj	
| j t||| W S  ty:   tjddd Y dS w )zPatch this pin onto the given object. If send is true, it will also
        queue the metadata to be sent to the server.
        __setddpin__zcan't pin onto object. skippingTexc_infoN)r(   r7   r   r)   r*   r+   r   r   r1   r   _add_extra_servicesetattrr   logdebug)r   r$   r6   r.   r   r   r   r-      s   

zPin.ontoc                 C   s\   zt |rtnt}t|}|d urt|| W d S W d S  ty-   tjddd Y d S w )Nz&can't remove pin from object. skippingTr8   )	r   r)   r*   r
   r#   delattrr   r<   r=   )r   r$   r.   r%   r   r   r   remove_from   s   
zPin.remove_fromc                 C   s6   |s
| j r
| j  }| j }t|p| j||d}|S )z=Return a clone of the pin with the given attributes replaced.)r   r   r   )r   copyr   r
   r   )r   r   r   r   r%   r   r   r   r,      s   


z	Pin.clone)NNN)NN)T)__name__
__module____qualname____doc__	__slots__r   strdictr   r   propertyr   r   r!   staticmethodr&   r#   classmethodr0   boolr3   r-   r?   r,   __classcell__r   r   r   r   r
      s^    
r
   )typingr   r   r1   ddtrace.internal.compatr   ddtrace.internal.settings.asmr   r4   internal.loggerr   rA   r<   r*   r)   objectr
   r   r   r   r   <module>   s    