
    *dl&                         d dl 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	m
Z
mZmZmZmZ  e j        de           Z G d de          Z G d	 d
          ZdS )    N)defaultdict)MutableMapping)Enum)AnyHashableIterableOptionalTupleUnionzconda.c                      e Zd ZdZ	 	 d#dedeed ee         ef                  dee         fdZ	dddd	dee         fd
Z
ed             Zd Zd Zd ZdefdZdedefdZdefdZdddededee         defdZdddededee         deeef         fdZd$dee         fdZddddeeef         dee         defdZddddededee         defdZdedeeeedf                  df         fdZd Zed%d!            Zd" Z dS )&
TrackedMapu  
    Implements a dictionary-like interface with self-logging capabilities.

    Each item in the dictionary can be annotated with a ``reason`` of type ``str``.
    Since a keyword argument is needed, this is only doable via the ``.set()`` method
    (or any of the derivative methods that call it, like ``.update()``). With normal
    ``dict`` assignment (à la ``d[key] = value``), ``reason`` will be None.

    Reasons are kept in a dictionary of lists, so a history of reasons is kept for each
    key present in the dictionary. Reasons for a given ``key`` can be checked with
    ``.reasons_for(key)``.

    Regardless the value of ``reason``, assignments, updates and deletions will be logged
    for easy debugging. It is in principle possible to track where each key came from
    by reading the logs, since the stack level is matched to the originating operation.

    ``.set()`` and ``.update()`` also support an ``overwrite`` boolean option, set to
    True by default. If False, an existing key will _not_ be overwritten with the
    new value.

    Parameters
    ----------
    name
        A short identifier for this tracked map. Useful for logging.
    data
        Initial data for this object. It can be a dictionary, an iterable of key-value
        pairs, or another ``TrackedMap`` instance. If given a ``TrackedMap`` instance,
        its data and reasons will be copied over, instead of wrapped, to avoid recursion.
    reason
        Optionally, a reason on why this object was initialized with such data. Ignored
        if no data is provided.

    Examples
    --------
    >>> TrackedMap("example", data={"key": "value"}, reason="Initialization)
    >>> tm = TrackedMap("example")
    >>> tm.set("key", "value", reason="First value")
    >>> tm.update({"another_key": "another_value"}, reason="Second value")
    >>> tm["third_key"] = "third value"
    >>> tm[key]
        "value"
    >>> tm.reasons_for(key)
        ["First value"]
    >>> tm["third_key"]
        "third value"
    >>> tm.reasons_for("third_key")
        [None]
    Nnamedatareasonc                    || _         | j        j        | _        t	          |t
                    rZ|j                                        | _        rfd| j        D             | _        d S |j                                        | _        d S i | _        t          t                    | _        |                     |pi            d S )Nc                     i | ]}|S  r   ).0kr   s     <lib/python3.11/site-packages/conda_libmamba_solver/models.py
<dictcomp>z'TrackedMap.__init__.<locals>.<dictcomp>K   s     ? ? ?qF ? ? ?    r   )_name	__class____name___clsname
isinstancer   _datacopy_reasonsr   listupdate)selfr   r   r   s      `r   __init__zTrackedMap.__init__?   s     
/dJ'' 		3**DJ 5 ? ? ? ?DJ ? ? ? $ 2 2 4 4DJ'--DMKK
6K22222r   T   )r   	overwrite_levelc                   t          |t                    sJ |d| d            	 | j        |         }| j                            |d g          d         }| j         d| j         d|d|d| d|                     |           }|}	n<# t          $ r/ | j         d| j         d|d	|                     |           }d
}	Y nw xY w|	r6|r)|d| dz  }| j        |         	                    |           || j        |<   n4| j         d| j         d|d|d| d|                     |           d| d}| 
                    ||           d S )Nz is not str ():[] (=z	, reason=z) updated to z	] set to T	 (reason=z) wanted new value z-) but stayed the same due to overwrite=False.
stacklevel)r   strr   r!   getr   r   _short_reprKeyErrorappend
_log_debug)
r$   keyvaluer   r'   r(   old
old_reasonmsgwrites
             r   _setzTrackedMap._setS   s&   #s##EE%E%EF%E%E%EEEE
	*S/C**377;J= X X4: X X X XX X%/X X>B>N>Nu>U>UX X  EE 	 	 	][[TZ[[#[[$BRBRSXBYBY[[CEEE	  
	 2,6,,,,c"))&111#DJsOO = Q Q4: Q Q Q QQ Q%/Q QDHDTDTUZD[D[Q Q!Q Q Q  	/////s   A!B	 	6CCc                     | j         S N)r   r$   s    r   r   zTrackedMap.nameo   s
    zr   c           	      .   | j         sdS dg}| j                                         D ]F\  }}| j                            |          }|rd| nd}|                    d|d|d|            G|                    d           d	                    |          S )
Nz{}{z  # reasons= z  z: ,}
)r   itemsr!   r3   r6   join)r$   linesr   vreasonss        r   __repr__zTrackedMap.__repr__s   s    z 	4J$$&& 	6 	6DAqm''**G29A.W...rGLL4a44Q447445555Syyr   c                 *    t          | j                  S r@   )iterr   rA   s    r   __iter__zTrackedMap.__iter__~   s    DJr   c                 *    t          | j                  S r@   )lenr   rA   s    r   __len__zTrackedMap.__len__   s    4:r   r8   c                     | j         |         S r@   )r   r$   r8   s     r   __getitem__zTrackedMap.__getitem__   s    z#r   r9   c                 2    |                      ||           d S r@   r>   )r$   r8   r9   s      r   __setitem__zTrackedMap.__setitem__   s    		#ur   c                     | j         |= | j                            |d            |                     | j         d| j         d|dd           d S )Nr,   r-   z] was deleted   r0   )r   r!   popr7   r   r   rU   s     r   __delitem__zTrackedMap.__delitem__   s]    JsO#t$$$4=LL4:LLLLLYZ[[[[[r   r   defaultreturnc          	           | j         j        |g|R  } | j        j        |g|R   | j         d| j         d|d|                     |           d}|r	|d| dz  }|                     |d           |S )	z
        Remove a key-value pair and return the value. A reason can be provided
        for logging purposes, but it won't be stored in the object.
        r,   r-   r.   ) was deletedr/   r*   r[   r0   )r   r\   r!   r   r   r4   r7   r$   r8   r   r^   r9   r<   s         r   r\   zTrackedMap.pop   s    
 
s-W---#(((((____c__9I9I%9P9P___ 	)(v((((C***r   c          	         | j                             |          \  }} | j        j        |g|R   | j         d| j         d|d|                     |           d}|r	|d| dz  }|                     |d           ||fS )	z
        Remove and return a key-value pair. A reason can be provided for logging purposes,
        but it won't be stored in the object.
        r,   r-   r.   ra   r/   r*   r[   r0   )r   popitemr!   r\   r   r   r4   r7   rb   s         r   rd   zTrackedMap.popitem   s     Z'',,
U#(((((____c__9I9I%9P9P___ 	)(v((((C***Ezr   c                     | j                                          | j                                         | j         d}|r	|d| dz  }|                     |d           dS )z
        Remove all entries in the map. A reason can be provided for logging purposes,
        but it won't be stored in the object.
        z was clearedr/   r*   r[   r0   N)r   clearr!   r   r7   )r$   r   r<   s      r   rf   zTrackedMap.clear   sv    
 	
))) 	)(v((((C*****r   r   r'   r'   c                    t          |d          r8|                                D ]!}|                     |||         ||           "dS |D ]\  }}|                     ||||           dS )a  
        Update the dictionary with a reason. Note that keyword arguments
        are not supported in this specific implementation, so you can only
        update a dictionary with another dictionary or iterable as a
        positional argument. This is done so `reason` and `overwrite` can
        be used to control options instead of silently ignoring a potential
        entry in a ``**kwargs`` argument.
        keysrg   N)hasattrri   r>   )r$   r   r   r'   r   rK   s         r   r#   zTrackedMap.update   s     4   	DYY[[ J J		!T!WVy	IIIIJ J  D D1		!Qv	CCCCD Dr   c                8    |                      ||||           dS )a  
        Set ``key`` to ``value``, optionally providing a ``reason`` why.

        Parameters
        ----------
        key
            Key to the passed value
        value
            Value
        reason
            A short description on why this key, value pair was added
        overwrite
            If False, do _not_ update the ``value`` for ``key`` if ``key``
            was already present in the dictionary.
        rg   NrX   )r$   r8   r9   r   r'   s        r   setzTrackedMap.set   s$    $ 			#uVy	AAAAAr   c                 6    | j                             |          S )z?
        Return the stored reasons for a given ``key``
        )r!   r3   rU   s     r   reasons_forzTrackedMap.reasons_for   s     }  %%%r   c                 :    |                      | j        |           S )N)r   r   )r   r   rA   s    r   r    zTrackedMap.copy   s    ~~4:D~999r   d   c                 j    t          |           }t          |          |k    r|d |dz
            d}|S )N   z...>)reprrR   )r9   maxlen
value_reprs      r   r4   zTrackedMap._short_repr   s?    %[[
z??V##&yqy1777Jr   c                 t    t           j        dk     r|                    dd            t          j        |i | d S )N)r&      r1   )sysversion_infor\   logdebug)r$   argskwargss      r   r7   zTrackedMap._log_debug   s?    f$$JJ|T***	4"6"""""r   )NNr@   )rp   )!r   
__module____qualname____doc__r2   r	   r   r   dictr%   r>   propertyr   rM   rP   rS   r   rV   r   rY   r]   r\   r
   rd   rf   boolr#   rl   rn   r    staticmethodr4   r7   r   r   r   r   r      s0       / /h IM $	3 33 u\8H+=tCDE3 	3 3 3 3( ;?$WX 0 0 0(3- 0 0 0 08   X	  	  	        x    x     \x \ \ \ \
 IM   x 3  QT     EI  '*4<SM	x}	   
+ 
+HSM 
+ 
+ 
+ 
+ GK^bD D D$.)D6>smDW[D D D D& EI\`B B BB$'B4<SMBUYB B B B(&x &E(5d;K2Ld2R,S & & & &: : :    \# # # # #r   r   c                   D    e Zd ZdZdefdZdedefdZde	de
fdZd	 Zd
S )EnumAsBoolsa  
    Allows an Enum to be bool-evaluated with attribute access.

    >>> update_modifier = UpdateModifier("update_deps")
    >>> update_modifier_as_bools = EnumAsBools(update_modifier)
    >>> update_modifier == UpdateModifier.UPDATE_DEPS  # from this
        True
    >>> update_modidier_as_bools.UPDATE_DEPS  # to this
        True
    >>> update_modifier_as_bools.UPDATE_ALL
        False
    enumc                 x    || _         d | j         j        j                                        D             | _        d S )Nc                     h | ]	}|j         
S r   )r   )r   rK   s     r   	<setcomp>z'EnumAsBools.__init__.<locals>.<setcomp>  s    QQQ!qvQQQr   )_enumr   __members__values_names)r$   r   s     r   r%   zEnumAsBools.__init__  s6    
QQtz';'G'N'N'P'PQQQr   r   r_   c                     |dv rt          | j        |          S || j        v r| j        j        |k    S t	          d| d| j        j        j                   )N)r   r9   'z' is not a valid name for )getattrr   r   r   AttributeErrorr   r   )r$   r   s     r   __getattr__zEnumAsBools.__getattr__  sc    $$$4:t,,,4;:?d**```AUA^``aaar   objc                 6    | j                             |          S r@   )r   __eq__)r$   r   s     r   r   zEnumAsBools.__eq__  s    z  %%%r   c                 *      fd j         D             S )Nc                 2    i | ]}|j         j        |k    S r   )r   r   )r   r   r$   s     r   r   z%EnumAsBools._dict.<locals>.<dictcomp>  s$    FFF$djo-FFFr   )r   rA   s   `r   _dictzEnumAsBools._dict  s    FFFF$+FFFFr   N)r   r~   r   r   r   r%   r2   r   r   objectr   r   r   r   r   r   r   r      s         RT R R R Rb b b b b b&& &T & & & &G G G G Gr   r   )loggingrx   collectionsr   collections.abcr   r   r   typingr   r   r   r	   r
   r   	getLoggerr   rz   r   r   r   r   r   <module>r      s	    



 # # # # # # * * * * * *       B B B B B B B B B B B B B B B Bg+++,,d# d# d# d# d# d# d# d#NG G G G G G G G G Gr   