o
    èÓáaJ  ã                   @   sŽ   d dl mZmZmZmZ d dlmZ d dlmZ dd„ Z	G dd„ de
ƒZe e¡ e e¡ e e¡ e e¡ dd	„ Zd
d„ Zeeƒ ƒZdS )é    )Ú	ContainerÚIterableÚSizedÚHashable)Úreduce)Úpmapc                 C   s   |   ||  |d¡d ¡S )Nr   é   )ÚsetÚget)ÚcountersÚelement© r   ú2/usr/lib/python3/dist-packages/pyrsistent/_pbag.pyÚ_add_to_counters   s   r   c                   @   s    e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ ZeZeZeZdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#S )$ÚPBagaÞ  
    A persistent bag/multiset type.

    Requires elements to be hashable, and allows duplicates, but has no
    ordering. Bags are hashable.

    Do not instantiate directly, instead use the factory functions :py:func:`b`
    or :py:func:`pbag` to create an instance.

    Some examples:

    >>> s = pbag([1, 2, 3, 1])
    >>> s2 = s.add(4)
    >>> s3 = s2.remove(1)
    >>> s
    pbag([1, 1, 2, 3])
    >>> s2
    pbag([1, 1, 2, 3, 4])
    >>> s3
    pbag([1, 2, 3, 4])
    )Ú_countsÚ__weakref__c                 C   s
   || _ d S )N©r   )ÚselfÚcountsr   r   r   Ú__init__#   s   
zPBag.__init__c                 C   s   t t| j|ƒƒS )zÃ
        Add an element to the bag.

        >>> s = pbag([1])
        >>> s2 = s.add(1)
        >>> s3 = s.add(2)
        >>> s2
        pbag([1, 1])
        >>> s3
        pbag([1, 2])
        )r   r   r   ©r   r   r   r   r   Úadd&   s   zPBag.addc                 C   s   |rt tt|| jƒƒS | S )z‹
        Update bag with all elements in iterable.

        >>> s = pbag([1])
        >>> s.update([1, 2])
        pbag([1, 1, 2])
        )r   r   r   r   )r   Úiterabler   r   r   Úupdate4   s   zPBag.updatec                 C   sT   || j vr	t|ƒ‚| j | dkr| j  |¡}t|ƒS | j  || j | d ¡}t|ƒS )zÔ
        Remove an element from the bag.

        >>> s = pbag([1, 1, 2])
        >>> s2 = s.remove(1)
        >>> s3 = s.remove(2)
        >>> s2
        pbag([1, 2])
        >>> s3
        pbag([1, 1])
        r   )r   ÚKeyErrorÚremover	   r   )r   r   Únewcr   r   r   r   A   s   
ÿzPBag.removec                 C   s   | j  |d¡S )z¦
        Return the number of times an element appears.


        >>> pbag([]).count('non-existent')
        0
        >>> pbag([1, 1, 2]).count(1)
        2
        r   )r   r
   r   r   r   r   ÚcountU   s   
z
PBag.countc                 C   s   t | j ¡ ƒS )ze
        Return the length including duplicates.

        >>> len(pbag([1, 1, 2]))
        3
        )Úsumr   Ú
itervalues©r   r   r   r   Ú__len__a   s   zPBag.__len__c                 c   s.   � | j  ¡ D ]\}}t|ƒD ]}|V  qqdS )z®
        Return an iterator of all elements, including duplicates.

        >>> list(pbag([1, 1, 2]))
        [1, 1, 2]
        >>> list(pbag([1, 2]))
        [1, 2]
        N)r   Ú	iteritemsÚrange)r   Úeltr   Úir   r   r   Ú__iter__j   s   €	ÿÿzPBag.__iter__c                 C   s
   || j v S )z�
        Check if an element is in the bag.

        >>> 1 in pbag([1, 1, 2])
        True
        >>> 0 in pbag([1, 2])
        False
        r   )r   r%   r   r   r   Ú__contains__w   s   
	zPBag.__contains__c                 C   s   d  t| ƒ¡S )Nz	pbag({0}))ÚformatÚlistr!   r   r   r   Ú__repr__‚   s   zPBag.__repr__c                 C   s    t |ƒtur
tdƒ‚| j|jkS )zó
        Check if two bags are equivalent, honoring the number of duplicates,
        and ignoring insertion order.

        >>> pbag([1, 1, 2]) == pbag([1, 2])
        False
        >>> pbag([2, 1, 0]) == pbag([0, 1, 2])
        True
        z Can only compare PBag with PBags)Útyper   Ú	TypeErrorr   ©r   Úotherr   r   r   Ú__eq__…   s   
zPBag.__eq__c                 C   s   t dƒ‚)NzPBags are not orderable)r-   r.   r   r   r   Ú__lt__“   s   zPBag.__lt__c                 C   sJ   t |tƒstS | j ¡ }|j ¡ D ]\}}|  |¡| ||< qt| ¡ ƒS )z‚
        Combine elements from two PBags.

        >>> pbag([1, 2, 2]) + pbag([2, 3, 3])
        pbag([1, 2, 2, 2, 3, 3])
        )Ú
isinstancer   ÚNotImplementedr   Úevolverr#   r   Ú
persistent)r   r/   ÚresultÚelemÚother_countr   r   r   Ú__add__œ   s   

zPBag.__add__c                 C   sj   t |tƒstS | j ¡ }|j ¡ D ]\}}|  |¡| }|dkr%|||< q|| v r.| |¡ qt| ¡ ƒS )zœ
        Remove elements from one PBag that are present in another.

        >>> pbag([1, 2, 2, 2, 3]) - pbag([2, 3, 3, 4])
        pbag([1, 2, 2])
        r   )	r2   r   r3   r   r4   r#   r   r   r5   )r   r/   r6   r7   r8   Únewcountr   r   r   Ú__sub__ª   s   



€zPBag.__sub__c                 C   sT   t |tƒstS | j ¡ }|j ¡ D ]\}}|  |¡}t||ƒ}|||< qt| ¡ ƒS )z¢
        Union: Keep elements that are present in either of two PBags.

        >>> pbag([1, 2, 2, 2]) | pbag([2, 3, 3])
        pbag([1, 2, 2, 2, 3, 3])
        )	r2   r   r3   r   r4   r#   r   Úmaxr5   )r   r/   r6   r7   r8   r   r:   r   r   r   Ú__or__¼   s   




zPBag.__or__c                 C   sX   t |tƒstS tƒ  ¡ }| j ¡ D ]\}}t|| |¡ƒ}|dkr%|||< qt| 	¡ ƒS )z–
        Intersection: Only keep elements that are present in both PBags.

        >>> pbag([1, 2, 2, 2]) & pbag([2, 3, 3])
        pbag([2])
        r   )
r2   r   r3   r   r4   r   r#   Úminr   r5   )r   r/   r6   r7   r   r:   r   r   r   Ú__and__Ì   s   

€zPBag.__and__c                 C   s
   t | jƒS )zÆ
        Hash based on value of elements.

        >>> m = pmap({pbag([1, 2]): "it's here!"})
        >>> m[pbag([2, 1])]
        "it's here!"
        >>> pbag([1, 1, 2]) in m
        False
        )Úhashr   r!   r   r   r   Ú__hash__Ü   s   

zPBag.__hash__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r   r   r   r   r   r"   r'   r(   r+   r0   r1   Ú__le__Ú__gt__Ú__ge__r9   r;   r=   r?   rA   r   r   r   r   r   
   s,    	r   c                  G   s   t | ƒS )zª
    Construct a persistent bag.

    Takes an arbitrary number of arguments to insert into the new persistent
    bag.

    >>> b(1, 2, 3, 2)
    pbag([1, 2, 2, 3])
    )Úpbag©Úelementsr   r   r   Úbï   s   
rM   c                 C   s   | st S ttt| tƒ ƒƒS )z•
    Convert an iterable to a persistent bag.

    Takes an iterable with elements to insert.

    >>> pbag([1, 2, 3, 2])
    pbag([1, 2, 2, 3])
    )Ú_EMPTY_PBAGr   r   r   r   rK   r   r   r   rJ   ü   s   	rJ   N)Úcollections.abcr   r   r   r   Ú	functoolsr   Úpyrsistent._pmapr   r   Úobjectr   ÚregisterrM   rJ   rN   r   r   r   r   Ú<module>   s     
`


