o
    .j'                     @  s   d dl mZ d dlmZ d dlmZmZmZ d dlm	Z	 er&d dl
mZmZ zd dlmZ W n ey=   d dlmZ Y nw edZedZ		ddddZ		ddddZG dd deZg dZd	S )    )annotations)OrderedDict)TYPE_CHECKINGAnyTypeVar)
to_unicode)IterableMapping)SelfKTVTNkeysIterable[KT]canonical_orderIterable[KT] | Nonereturnlist[KT]c                   sV   dd t |pg D   fdd| D } fdd| D }t| fdddt| S )	a  Sort leading keys according to a canonical order.

    Keys specified in ``canonical_order`` appear first in that order.
    Remaining keys appear alphabetically at the end.

    Parameters:
        keys: The keys to sort.
        canonical_order: The preferred order for leading keys.
            Keys not in this sequence are sorted alphabetically after
            the canonical ones. If ``None``, all keys are sorted
            alphabetically.

    Returns:
        A new list of keys sorted by canonical order first, then alphabetically.

    Example:
        ..  code-block:: pycon

            >>> from icalendar.caselessdict import canonsort_keys
            >>> canonsort_keys(["C", "A", "B"], ["B", "C"])
            ['B', 'C', 'A']
    c                 S  s   i | ]\}}||qS  r   ).0ikr   r   K/home/thesage/.local/lib/python3.10/site-packages/icalendar/caselessdict.py
<dictcomp>-   s    z"canonsort_keys.<locals>.<dictcomp>c                   s   g | ]}| v r|qS r   r   r   r   canonical_mapr   r   
<listcomp>.       z"canonsort_keys.<locals>.<listcomp>c                   s   g | ]}| vr|qS r   r   r   r   r   r   r   /   r   c                   s    |  S Nr   )r   r   r   r   <lambda>0   s    z canonsort_keys.<locals>.<lambda>)key)	enumeratesorted)r   r   headtailr   r   r   canonsort_keys   s   r%   dict1Mapping[KT, VT]list[tuple[KT, VT]]c                   s    fddt   |D S )a4  Sort items from a mapping according to a canonical key order.

    Parameters:
        dict1: The mapping whose items to sort.
        canonical_order: The preferred order for leading keys.
            If ``None``, all keys are sorted alphabetically.

    Returns:
        A list of ``(key, value)`` tuples sorted by canonical order.

    Example:
        ..  code-block:: pycon

            >>> from icalendar.caselessdict import canonsort_items
            >>> canonsort_items({"C": 3, "A": 1, "B": 2}, ["B", "C"])
            [('B', 2), ('C', 3), ('A', 1)]
    c                   s   g | ]}| | fqS r   r   r   r&   r   r   r   G   r   z#canonsort_items.<locals>.<listcomp>)r%   r   )r&   r   r   r)   r   canonsort_items3   s   r*   c                      s   e Zd ZdZd5 fddZd	Zd6 fddZd7 fddZd8 fddZd9 fddZ	d:d; fddZ
d:d< fddZd:d; fddZd= fddZd9 fdd Zd5d!d"Zd> fd$d%Zd?d'd(Zd@d+d,Zd@d-d.Zd	ZdAd0d1ZdBd3d4Z  ZS )CCaselessDicta>  A case-insensitive dictionary that uses strings as keys.

    All keys are stored in uppercase internally, but values retain
    their original case. Keys can be provided as ``str`` or ``bytes``.
    They are converted to Unicode via :func:`~icalendar.parser_tools.to_unicode`,
    then uppercased before storage.
    argsr   kwargsr   Nonec                   sP   t  j|i | |  D ]\}}t| }||kr%t  | || |< qdS )a9  Parameters:
            *args: Positional arguments passed to :class:`~collections.OrderedDict`.
            **kwargs: Keyword arguments passed to :class:`~collections.OrderedDict`.

        Example:

            Create a new ``CaselessDict`` and normalize existing keys to uppercase.

            ..  code-block:: pycon

                >>> from icalendar.caselessdict import CaselessDict
                >>> d = CaselessDict(summary="Meeting")
                >>> d["SUMMARY"]
                'Meeting'
                >>> "summary" in d
                True
        N)super__init__itemsr   upper__delitem__)selfr,   r-   r    value	key_upper	__class__r   r   r0   S   s   zCaselessDict.__init__Nr    c                      t |}t | S )aF  Get the item from the ``CaselessDict`` instance by
        ``key``, case-insensitively.

        Parameters:
            key: The key to look up, case-insensitively.

        Returns:
            The (key, value) pair associated with the uppercased key.

        Raises:
            KeyError: If the key is not found.
        )r   r/   __getitem__r2   r4   r    r7   r   r   r:   n   s   zCaselessDict.__getitem__r5   c                   s   t |}t | | dS )zSet a (key, value) pair, storing the key in uppercase.

        Parameters:
            key: The key of the pair, case-insensitive.
            value: The value to associate with the key.
        N)r   r/   __setitem__r2   r4   r    r5   r7   r   r   r<   ~   s   zCaselessDict.__setitem__c                   s   t |}t |  dS )zDelete a (key, value) pair by its case-insensitive key.

        Parameters:
            key: The key to delete, case-insensitively.

        Raises:
            KeyError: If the key is not found.
        N)r   r/   r3   r2   r;   r7   r   r   r3      s   	zCaselessDict.__delitem__boolc                   r9   )zCheck whether a key exists in the mapping, case-insensitively.

        Parameters:
            key: The key to check case-insensitively.

        Returns:
            ``True`` if the uppercased key exists, else ``False``.
        r   r/   __contains__r2   r;   r7   r   r   r@      s   	zCaselessDict.__contains__defaultc                      t |}t | |S )a;  Return the ``key``, optionally with a ``default`` value.

        Parameters:
            key: The key to look up, case-insensitively.
            default: The value to return if the key is not found.

        Returns:
            The value for the key, if present, else the value specified by ``default``.
        )r   r/   getr2   r4   r    rA   r7   r   r   rC         
zCaselessDict.getc                   rB   )aU  Create the (key, value) pair, optionally with a ``value``.

        Once set, to change default value use :meth:`update`.

        Parameters:
            key: The key to look up or create, case-insensitively.
            value: The default value to set, if given, else ``None``.

        Returns:
            The value for the key.
        )r   r/   
setdefaultr2   r=   r7   r   r   rF      s   zCaselessDict.setdefaultc                   rB   )a+  Remove and return the value for ``key``, or ``default`` if not found.

        Parameters:
            key: The key to remove, case-insensitively.
            default: The value to return if the key is not found.

        Returns:
            The removed value, or the value of ``default``.
        )r   r/   popr2   rD   r7   r   r   rG      rE   zCaselessDict.poptuple[Any, Any]c                   s
   t   S )zRemove and return the last inserted (key, value) pair.

        Returns:
            A (key, value) tuple.

        Raises:
            KeyError: If the dictionary is empty.
        )r/   popitemr4   r7   r   r   rI         
	zCaselessDict.popitemc                   r9   )a  Check whether a key exists, case-insensitively.

        This is a legacy method. Use ``key in dict`` instead.

        Parameters:
            key: The key to check, case-insensitively.

        Returns:
            ``True`` if the key exists, else ``False``.
        r?   r;   r7   r   r   has_key   s   zCaselessDict.has_keyc                 O  sH   t ||g }|D ]}t|drt| }|D ]\}}|| |< qq	dS )aT  Update the dictionary with (key, value) pairs, normalizing keys to uppercase.

        Multiple keys that differ only in case will overwrite each other.
        Only the last value is retained.

        Parameters:
            *args: Mappings or iterables of (key, value) pairs.
            **kwargs: Additional (key, value) pairs.
        r1   N)listhasattriterr1   )r4   r,   r-   mappingsmappingr    r5   r   r   r   update   s   

zCaselessDict.updater
   c                   s   t | t  S )zReturn a shallow copy of the dictionary.

        Returns:
            A new instance of the same type with the same contents.
        )typer/   copyrJ   r7   r   r   rT      s   zCaselessDict.copystrc                 C  s   t | j dt|  dS )zReturn a string representation of the dictionary.

        Returns:
            A string in the form ``CaselessDict({...})``.
        ())rS   __name__dictrJ   r   r   r   __repr__   s   zCaselessDict.__repr__otherobjectc                 C  s.   t |tstS | |u pt|  t| kS )a  Check equality with another dictionary.

        Two ``CaselessDict`` instances are equal if they contain the same
        (key, value) pairs after uppercasing keys. Comparison with a regular
        ``dict`` also works.

        Parameters:
            other: The object to compare.

        Returns:
            ``True`` if equal, ``NotImplemented`` if ``other`` is not a ``dict``.
        )
isinstancerY   NotImplementedr1   r4   r[   r   r   r   __eq__  s   
 zCaselessDict.__eq__c                 C  s
   | |k S )zCheck inequality with another dictionary.

        Parameters:
            other: The object to compare.

        Returns:
            ``True`` if not equal, else ``False``.
        r   r_   r   r   r   __ne__  rK   zCaselessDict.__ne__	list[str]c                 C  s   t |  | jS )zSort keys according to the canonical order for this class.

        Keys listed in :attr:`canonical_order` appear first in that order.
        Remaining keys appear alphabetically at the end.

        Returns:
            A sorted list of keys.
        )r%   r   r   rJ   r   r   r   sorted_keys$  s   	zCaselessDict.sorted_keyslist[tuple[Any, Any]]c                 C  s   t | | jS )a  Sort items according to the canonical order for this class.

        Items whose keys are listed in :attr:`canonical_order` appear first
        in that order. Remaining items appear alphabetically by key.

        Returns:
            A sorted list of (key, value) tuples.
        )r*   r   rJ   r   r   r   sorted_items/  s   	zCaselessDict.sorted_items)r,   r   r-   r   r   r.   )r    r   r   r   )r    r   r5   r   r   r.   )r    r   r   r.   )r    r   r   r>   r   )r    r   rA   r   r   r   )r    r   r5   r   r   r   )r   rH   )r   r
   )r   rU   )r[   r\   r   r>   )r   rb   )r   rd   )rX   
__module____qualname____doc__r0   __hash__r:   r<   r3   r@   rC   rF   rG   rI   rL   rR   rT   rZ   r`   ra   r   rc   re   __classcell__r   r   r7   r   r+   J   s*    





r+   )r+   r*   r%   r   )r   r   r   r   r   r   )r&   r'   r   r   r   r(   )
__future__r   collectionsr   typingr   r   r   icalendar.parser_toolsr   collections.abcr   r	   r
   ImportErrortyping_extensionsr   r   r%   r*   r+   __all__r   r   r   r   <module>   s(      r