3
ˆd‚A  ã               @   s†   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	 d dl
mZ G dd„ deƒZejG d	d
„ d
eƒƒZG dd„ deƒZdS )é    N)Úchain)Úref)ÚIObservable)Ú_validate_everything)Ú
TraitErrorc               @   s(   e Zd ZdZdddœdd„Zdd„ ZdS )ÚTraitSetEventa‚   An object reporting in-place changes to a traits sets.

    Parameters
    ----------
    removed : set, optional
        Old values that were removed from the set.
    added : set, optional
        New values added to the set.

    Attributes
    ----------
    removed : set
        Old values that were removed from the set.
    added : set
        New values added to the set.
    N)ÚremovedÚaddedc            C   s,   |d krt ƒ }|| _|d kr"t ƒ }|| _d S )N)Úsetr   r	   )Úselfr   r	   © r   ú9/tmp/pip-build-7vycvbft/traits/traits/trait_set_object.pyÚ__init__'   s    zTraitSetEvent.__init__c             C   s   | j j› d| j›d| j›dS )Nz	(removed=z, added=ú))Ú	__class__Ú__name__r   r	   )r   r   r   r   Ú__repr__1   s    zTraitSetEvent.__repr__)r   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r      s   
r   c                   sü   e Zd ZdZ‡ fdd„Zf fdddœ‡ fdd„Zdd	„ Z‡ fd
d„Z‡ fdd„Z‡ fdd„Z	‡ fdd„Z
‡ fdd„Z‡ fdd„Z‡ fdd„Z‡ fdd„Z‡ fdd„Z‡ fdd„Z‡ fdd„Z‡ fd d!„Z‡ fd"d#„Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Z‡  ZS ),ÚTraitSetax   A subclass of set that validates and notifies listeners of changes.

    Parameters
    ----------
    value : iterable, optional
        Iterable providing the items for the set.
    item_validator : callable, optional
        Called to validate and/or transform items added to the set. The
        callable should accept a single item and return the transformed
        item, raising TraitError for invalid items. If not given, no
        item validation is performed.
    notifiers : list of callable, optional
        A list of callables with the signature::

            notifier(trait_set, removed, added)

        Where 'added' is a set containing new values that have been added.
        And 'removed' is a set containing old values that have been removed.

        If this argument is not given, the list of notifiers is initially
        empty.

    Attributes
    ----------
    item_validator : callable
        Called to validate and/or transform items added to the set. The
        callable should accept a single item and return the transformed
        item, raising TraitError for invalid items.
    notifiers : list of callable
        A list of callables with the signature::

            notifier(trait_set, removed, added)

        where 'added' is a set containing new values that have been added
        and 'removed' is a set containing old values that have been removed.
    c                s   t ƒ j| ƒ}t|_g |_|S )N)ÚsuperÚ__new__r   Úitem_validatorÚ	notifiers)ÚclsÚargsÚkwargsr   )r   r   r   r   `   s    zTraitSet.__new__N)r   r   c               s:   |d k	r|ˆ _ tƒ j‡ fdd„|D ƒƒ |d k	r6|ˆ _d S )Nc             3   s   | ]}ˆ j |ƒV  qd S )N)r   )Ú.0Úitem)r   r   r   ú	<genexpr>i   s    z$TraitSet.__init__.<locals>.<genexpr>)r   r   r   r   )r   Úvaluer   r   )r   )r   r   r   f   s
    zTraitSet.__init__c             C   s    x| j D ]}|| ||ƒ qW dS )a9   Call all notifiers.

        This simply calls all notifiers provided by the class, if any.
        The notifiers are expected to have the signature::

            notifier(trait_set, removed, added)

        Any return values are ignored. Any exceptions raised are not
        handled. Notifiers are therefore expected not to raise any
        exceptions under normal use.

        Parameters
        ----------
        removed : set
            The items that have been removed.
        added : set
            The new items that have been added to the set.
        N)r   )r   r   r	   Únotifierr   r   r   Únotifym   s    zTraitSet.notifyc                s<   | j ƒ }tƒ j|ƒ}|j| ƒ}t|ƒdkr8| j|tƒ ƒ |S )zÓ  Return self &= value.

        Parameters
        ----------
        value : set or frozenset
            A value.

        Returns
        -------
        self : TraitSet
            The updated set.
        r   )Úcopyr   Ú__iand__Ú
differenceÚlenr#   r
   )r   r!   Úold_setÚretvalr   )r   r   r   r%   …   s    
zTraitSet.__iand__c                s\   ˆ j ƒ }t|ttfƒr(‡ fdd„|D ƒ}tƒ j|ƒ}ˆ j|ƒ}t|ƒdkrXˆ jtƒ |ƒ |S )zÒ Return self |= value.

        Parameters
        ----------
        value : set or frozenset
            A value.

        Returns
        -------
        self : TraitSet
            The updated set.
        c                s   h | ]}ˆ j |ƒ’qS r   )r   )r   r   )r   r   r   ú	<setcomp>°   s   z#TraitSet.__ior__.<locals>.<setcomp>r   )	r$   Ú
isinstancer
   Ú	frozensetr   Ú__ior__r&   r'   r#   )r   r!   r(   r)   r	   )r   )r   r   r-   œ   s    

zTraitSet.__ior__c                s<   | j ƒ }tƒ j|ƒ}|j| ƒ}t|ƒdkr8| j|tƒ ƒ |S )zÐ Return self-=value.

        Parameters
        ----------
        value : set or frozenset
            A value.

        Returns
        -------
        self : TraitSet
            The updated set.
        r   )r$   r   Ú__isub__r&   r'   r#   r
   )r   r!   r(   r)   r   )r   r   r   r.   ¼   s    
zTraitSet.__isub__c                s~   t ƒ }t ƒ }t|t tfƒrZt |ƒ}ˆ j|ƒ}|j|ƒ}‡ fdd„|D ƒ}|jˆ ƒ}||B }tƒ j|ƒ}|sn|rzˆ j||ƒ |S )zÒ Return self ^= value.

        Parameters
        ----------
        value : set or frozenset
            A value.

        Returns
        -------
        self : TraitSet
            The updated set.
        c                s   h | ]}ˆ j |ƒ’qS r   )r   )r   r   )r   r   r   r*   ì   s    z$TraitSet.__ixor__.<locals>.<setcomp>)r
   r+   r,   Úintersectionr&   r   Ú__ixor__r#   )r   r!   r   r	   ÚvaluesZ	raw_addedZvalidated_addedr)   )r   )r   r   r0   Ó   s    



zTraitSet.__ixor__c                s6   | j |ƒ}|| k}tƒ j|ƒ |s2| jtƒ |hƒ dS )zÅ Add an element to a set.

        This has no effect if the element is already present.

        Parameters
        ----------
        value : any
            The value to add to the set.
        N)r   r   Úaddr#   r
   )r   r!   Úvalue_in_self)r   r   r   r2   ø   s
    
zTraitSet.addc                s(   t | ƒ}tƒ jƒ  |r$| j|t ƒ ƒ dS )z$ Remove all elements from this set. N)r
   r   Úclearr#   )r   r   )r   r   r   r4   	  s    
zTraitSet.clearc                s,   || k}t ƒ j|ƒ |r(| j|htƒ ƒ dS )zÊ Remove an element from the set if it is a member.

        If the element is not a member, do nothing.

        Parameters
        ----------
        value : any
            An item in the set
        N)r   Údiscardr#   r
   )r   r!   r3   )r   r   r   r5     s    zTraitSet.discardc                s<   | j ƒ }tƒ j|Ž  |j| ƒ}t|ƒdkr8| j|tƒ ƒ dS )z  Remove all elements of another set from this set.

        Parameters
        ----------
        args : iterables
            The other iterables.
        r   N)r$   r   Údifference_updater&   r'   r#   r
   )r   r   r(   r   )r   r   r   r6   "  s
    	
zTraitSet.difference_updatec                s<   | j ƒ }tƒ j|Ž  |j| ƒ}t|ƒdkr8| j|tƒ ƒ dS )z«  Update the set with the intersection of itself and another set.

        Parameters
        ----------
        args : iterables
            The other iterables.
        r   N)r$   r   Úintersection_updater&   r'   r#   r
   )r   r   r(   r   )r   r   r   r7   2  s
    	
zTraitSet.intersection_updatec                s   t ƒ jƒ }| j|htƒ ƒ |S )a   Remove and return an arbitrary set element.

        Raises KeyError if the set is empty.

        Returns
        -------
        item : any
            An element from the set.

        Raises
        ------
        KeyError
            If the set is empty.
        )r   Úpopr#   r
   )r   r   )r   r   r   r8   B  s    
zTraitSet.popc                s    t ƒ j|ƒ | j|htƒ ƒ dS )a2   Remove an element that is a member of the set.

        If the element is not a member, raise a KeyError.

        Parameters
        ----------
        value : any
            An element in the set

        Raises
        ------
        KeyError
            If the value is not found in the set.
        N)r   Úremover#   r
   )r   r!   )r   r   r   r9   V  s    zTraitSet.removec                s`   t |ƒ}ˆ j|ƒ}|j|ƒ}‡ fdd„|D ƒ}|jˆ ƒ}tƒ j||B ƒ |sP|r\ˆ j||ƒ dS )z Update the set with the symmetric difference of itself and another.

        Parameters
        ----------
        value : iterable
        c                s   h | ]}ˆ j |ƒ’qS r   )r   )r   r   )r   r   r   r*   t  s    z7TraitSet.symmetric_difference_update.<locals>.<setcomp>N)r
   r/   r&   r   Úsymmetric_difference_updater#   )r   r!   r1   r   Z
raw_resultZvalidated_resultr	   )r   )r   r   r:   i  s    


z$TraitSet.symmetric_difference_updatec                sL   ‡ fdd„t j|ƒD ƒ}|jˆ ƒ}tƒ j|ƒ t|ƒdkrHˆ jtƒ |ƒ dS )zž Update the set with the union of itself and others.

        Parameters
        ----------
        args : iterables
            The other iterables.
        c                s   h | ]}ˆ j |ƒ’qS r   )r   )r   r   )r   r   r   r*   „  s   z"TraitSet.update.<locals>.<setcomp>r   N)r   Úfrom_iterabler&   r   Úupdater'   r#   r
   )r   r   Zvalidated_valuesr	   )r   )r   r   r<   {  s    	

zTraitSet.updatec                s*   t ‡ fdd„| D ƒtj| jˆ ƒg d}|S )zb Perform a deepcopy operation.

        Notifiers are transient and should not be copied.
        c                s   g | ]}t j|ˆ ƒ‘qS r   )r$   Údeepcopy)r   Úx)Úmemor   r   ú
<listcomp>•  s    z)TraitSet.__deepcopy__.<locals>.<listcomp>)r   r   )r   r$   r=   Z	validator)r   r?   Úresultr   )r?   r   Ú__deepcopy__Ž  s
    zTraitSet.__deepcopy__c             C   s   | j jƒ }|d= |S )zw Get the state of the object for serialization.

        Notifiers are transient and should not be serialized.
        r   )Ú__dict__r$   )r   rA   r   r   r   Ú__getstate__œ  s    
zTraitSet.__getstate__c             C   s   g |d< | j j|ƒ dS )zƒ Restore the state of the object after serialization.

        Notifiers are transient and are restored to the empty list.
        r   N)rC   r<   )r   Ústater   r   r   Ú__setstate__¦  s    zTraitSet.__setstate__c             C   s   | j S )a   Return a list of callables where each callable is a notifier.
        The list is expected to be mutated for contributing or removing
        notifiers from the object.

        Parameters
        ----------
        force_create: boolean
            Not used here.
        )r   )r   Zforce_creater   r   r   Ú
_notifiers°  s    
zTraitSet._notifiers)r   r   r   r   r   r   r#   r%   r-   r.   r0   r2   r4   r5   r6   r7   r8   r9   r:   r<   rB   rD   rF   rG   Ú__classcell__r   r   )r   r   r   9   s*   % %

r   c                   sV   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Z‡ fd
d„Zdd„ Z	ddd„Z
‡  ZS )ÚTraitSetObjectaŠ   A specialization of TraitSet with a default validator and notifier
    for compatibility with Traits versions before 6.0.

    Parameters
    ----------
    trait : CTrait
        The trait that the set has been assigned to.
    object : HasTraits
        The object this set belongs to. Can also be None in cases where the
        set has been disconnected from its HasTraits parent.
    name : str
        The name of the trait on the object.
    value : iterable
        The initial value of the set.

    Attributes
    ----------
    trait : CTrait
        The trait that the set has been assigned to.
    object : callable
        A callable that when called with no arguments returns the HasTraits
        object that this set belongs to, or None if there is no such object.
    name : str
        The name of the trait on the object.
    value : iterable
        The initial value of the set.
    c                sX   || _ |d krdd„ nt|ƒ| _|| _d | _|jr<|d | _tƒ j|| j| j	gd d S )Nc               S   s   d S )Nr   r   r   r   r   Ú<lambda>Ý  s    z)TraitSetObject.__init__.<locals>.<lambda>Z_items)r   r   )
Útraitr   ÚobjectÚnameÚ
name_itemsZ	has_itemsr   r   Ú
_validatorr"   )r   rK   rL   rM   r!   )r   r   r   r   Ú  s    
zTraitSetObject.__init__c             C   sŠ   t | ddƒ}t | ddƒ}|dks(|dkr,|S |ƒ }|jj}|dkrF|S y||| j|ƒS  tk
r„ } z|jdƒ |‚W Y dd}~X nX dS )al   Validates the value by calling the inner trait's validate method.

        Parameters
        ----------
        value : any
            The value to be validated.

        Returns
        -------
        value : any
            The validated value.

        Raises
        ------
        TraitError
            On validation failure for the inner trait.
        rL   NrK   zEach element of the)ÚgetattrZ
item_traitÚvalidaterM   r   Z
set_prefix)r   r!   Z
object_refrK   rL   rQ   Zexcpr   r   r   rO   æ  s    
zTraitSetObject._validatorc             C   s`   | j dkrdS | jƒ }|dkr"dS t|| jƒ| k	r6dS t||d}| jjƒ }|j| j ||ƒ dS )aE   Converts and consolidates the parameters to a TraitSetEvent and
        then fires the event.

        Parameters
        ----------
        trait_set : set
            The complete set
        removed : set
            Set of values that were removed.
        added : set
            Set of values that were added.
        N)r   r	   )rN   rL   rP   rM   r   rK   Úitems_eventZtrait_items_event)r   Z	trait_setr   r	   rL   ÚeventrR   r   r   r   r"     s    

zTraitSetObject.notifierc                s$   t | jd| j‡ fdd„| D ƒƒ}|S )zb Perform a deepcopy operation.

        Notifiers are transient and should not be copied.
        Nc                s   h | ]}t j|ˆ ƒ’qS r   )r$   r=   )r   r>   )r?   r   r   r*   7  s    z.TraitSetObject.__deepcopy__.<locals>.<setcomp>)rI   rK   rM   )r   r?   rA   r   )r?   r   rB   -  s    zTraitSetObject.__deepcopy__c                s   t ƒ jƒ }|d= |d= |S )zw Get the state of the object for serialization.

        Notifiers are transient and should not be serialized.
        rL   rK   )r   rD   )r   rA   )r   r   r   rD   <  s    
zTraitSetObject.__getstate__c             C   s<   |j ddƒ | jg|d< dd„ |d< d|d< | jj|ƒ dS )	zƒ Restore the state of the object after serialization.

        Notifiers are transient and are restored to the empty list.
        rM   Ú r   c               S   s   d S )Nr   r   r   r   r   rJ   O  s    z-TraitSetObject.__setstate__.<locals>.<lambda>rL   NrK   )Ú
setdefaultr"   rC   r<   )r   rE   r   r   r   rF   G  s
    zTraitSetObject.__setstate__Nc             C   s   t jt| ƒtt| ƒf| jƒ fS )zB Overridden to make sure we call our custom __getstate__.
        )ÚcopyregÚ_reconstructorÚtyper
   ÚlistrD   )r   Úprotocolr   r   r   Ú__reduce_ex__S  s    zTraitSetObject.__reduce_ex__)N)r   r   r   r   r   rO   r"   rB   rD   rF   r[   rH   r   r   )r   r   rI   ½  s   ' rI   )r$   rV   Ú	itertoolsr   Úweakrefr   Ztraits.observation.i_observabler   Ztraits.trait_baser   Ztraits.trait_errorsr   rL   r   Úregisterr
   r   rI   r   r   r   r   Ú<module>   s   $   