U
    ?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   sb   t  }|j}|dkr6t|j| D ]}|| |V  q n(| D ]"}||}||kr:|| |V  q:dS )zHList unique elements, preserving order. Remember all elements ever seen.N)setaddr   __contains__)iterablekeyseenZseen_addelementk r   O/var/www/html/venv/lib/python3.8/site-packages/importlib_metadata/_itertools.pyunique_everseen   s    
r   c                 C   sZ   | dkrt dS |dk	r,t| |r,t | fS z
t | W S  tk
rT   t | f Y S X dS )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)objZ	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       z!bucket.__init__.<locals>.<lambda>)r   _it_keyr   r   _cache
_validator)selfr   r	   	validatorr   r   r   __init__r   s    

zbucket.__init__c                 C   sJ   |  |sdS zt| | }W n tk
r4   Y dS X | 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  q zt| j}W n tk
r@   Y dS X | |}||kr^|V  q q| |r| j | | qq dS )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.
        N)r   popleftr    r   r!   r   r   append)r   r#   r$   
item_valuer   r   r   _get_values   s    	


zbucket._get_valuesc                 c   sD   | 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__)N)	__name__
__module____qualname____doc__r   r   r(   r*   r+   r   r   r   r   r   N   s   #
r   )N)
collectionsr   r   	itertoolsr   r   strbytesr   r   r   r   r   r   <module>   s   
6