o
    Vh                     @   sH   d dl mZmZ d dlmZ d
ddZeeffddZG dd	 d	Z	dS )    )defaultdictdeque)filterfalseNc                 c   sf    t  }|j}|du rt|j| D ]	}|| |V  qdS | D ]}||}||vr0|| |V  qdS )zHList unique elements, preserving order. Remember all elements ever seen.N)setaddr   __contains__)iterablekeyseenseen_addelementk r   q/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/importlib_metadata/_itertools.pyunique_everseen   s   r   c                 C   sT   | du rt dS |durt| |rt | fS zt | W S  ty)   t | f Y S w )ax  If *obj* is iterable, return an iterator over its items::

        >>> obj = (1, 2, 3)
        >>> list(always_iterable(obj))
        [1, 2, 3]

    If *obj* is not iterable, return a one-item iterable containing *obj*::

        >>> obj = 1
        >>> list(always_iterable(obj))
        [1]

    If *obj* is ``None``, return an empty iterable:

        >>> obj = None
        >>> list(always_iterable(None))
        []

    By default, binary and text strings are not considered iterable::

        >>> obj = 'foo'
        >>> list(always_iterable(obj))
        ['foo']

    If *base_type* is set, objects for which ``isinstance(obj, base_type)``
    returns ``True`` won't be considered iterable.

        >>> obj = {'a': 1}
        >>> list(always_iterable(obj))  # Iterate over the dict's keys
        ['a']
        >>> list(always_iterable(obj, base_type=dict))  # Treat dicts as a unit
        [{'a': 1}]

    Set *base_type* to ``None`` to avoid any special handling and treat objects
    Python considers iterable as iterable:

        >>> obj = 'foo'
        >>> list(always_iterable(obj, base_type=None))
        ['f', 'o', 'o']
    Nr   )iter
isinstance	TypeError)obj	base_typer   r   r   always_iterable   s   )

r   c                   @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )bucketa  Wrap *iterable* and return an object that buckets the iterable into
    child iterables based on a *key* function.

        >>> iterable = ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'b3']
        >>> s = bucket(iterable, key=lambda x: x[0])  # Bucket by 1st character
        >>> sorted(list(s))  # Get the keys
        ['a', 'b', 'c']
        >>> a_iterable = s['a']
        >>> next(a_iterable)
        'a1'
        >>> next(a_iterable)
        'a2'
        >>> list(s['b'])
        ['b1', 'b2', 'b3']

    The original iterable will be advanced and its items will be cached until
    they are used by the child iterables. This may require significant storage.

    By default, attempting to select a bucket to which no items belong  will
    exhaust the iterable and cache all values.
    If you specify a *validator* function, selected buckets will instead be
    checked against it.

        >>> from itertools import count
        >>> it = count(1, 2)  # Infinite sequence of odd numbers
        >>> key = lambda x: x % 10  # Bucket by last digit
        >>> validator = lambda x: x in {1, 3, 5, 7, 9}  # Odd digits only
        >>> s = bucket(it, key=key, validator=validator)
        >>> 2 in s
        False
        >>> list(s[2])
        []

    Nc                 C   s,   t || _|| _tt| _|pdd | _d S )Nc                 S   s   dS )NTr   )xr   r   r   <lambda>v   s    z!bucket.__init__.<locals>.<lambda>)r   _it_keyr   r   _cache
_validator)selfr   r	   	validatorr   r   r   __init__r   s   

zbucket.__init__c                 C   sH   |  |sdS zt| | }W n
 ty   Y dS w | j| | dS )NFT)r   nextStopIterationr   
appendleft)r   valueitemr   r   r   r   x   s   
zbucket.__contains__c                 c   s~    	 | j | r| j |  V  n.	 zt| j}W n
 ty"   Y dS w | |}||kr0|V  n| |r=| j | | qq)z
        Helper to yield items from the parent iterator that match *value*.
        Items that don't match are stored in the local cache as they
        are encountered.
        TN)r   popleftr!   r   r"   r   r   append)r   r$   r%   
item_valuer   r   r   _get_values   s$   


zbucket._get_valuesc                 c   sF    | j D ]}| |}| |r| j| | q| j E d H  d S N)r   r   r   r   r'   keys)r   r%   r(   r   r   r   __iter__   s   


zbucket.__iter__c                 C   s   |  |s	tdS | |S )Nr   )r   r   r)   )r   r$   r   r   r   __getitem__   s   

zbucket.__getitem__r*   )	__name__
__module____qualname____doc__r    r   r)   r,   r-   r   r   r   r   r   N   s    
#r   r*   )
collectionsr   r   	itertoolsr   r   strbytesr   r   r   r   r   r   <module>   s
    
6