
vÅÏ^  ã               @   s9   d  Z  d d l Z d d l m Z Gd d „  d ƒ Z d S)zT
A class for storing a tree graph. Primarily used for filter constructs in the
ORM.
é    N)Úmake_hashablec               @   sÇ   e  Z d  Z d Z d Z d d d d d „ Z e d d d 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 d „ Z d d „  Z d S)ÚNodez±
    A single internal node in the tree graph. A Node should be viewed as a
    connection (the root) with the children being either leaf nodes or other
    Node instances.
    ÚDEFAULTNFc             C   s>   | r | d d … n g  |  _  | p+ |  j |  _ | |  _ d S)z@Construct a new Node. If no connector is given, use the default.N)ÚchildrenÚdefaultÚ	connectorÚnegated)Úselfr   r   r   © r
   ú3/tmp/pip-build-8lau8j11/django/django/utils/tree.pyÚ__init__   s    zNode.__init__c             C   s   t  | | | ƒ } |  | _ | S)aª  
        Create a new instance of this class when new Nodes (or subclasses) are
        needed in the internal code in this class. Normally, it just shadows
        __init__(). However, subclasses with an __init__ signature that aren't
        an extension of Node.__init__ might need to implement this method to
        allow a Node to create a new instance of them (if they have any extra
        setting up to do).
        )r   Ú	__class__)Úclsr   r   r   Úobjr
   r
   r   Ú_new_instance   s    
	zNode._new_instancec             C   s?   |  j  r d n d } | |  j d j d d „  |  j Dƒ ƒ f S)Nz(NOT (%s: %s))z(%s: %s)z, c             s   s   |  ] } t  | ƒ Vq d  S)N)Ústr)Ú.0Úcr
   r
   r   ú	<genexpr>-   s    zNode.__str__.<locals>.<genexpr>)r   r   Újoinr   )r	   Útemplater
   r
   r   Ú__str__+   s    zNode.__str__c             C   s   d |  j  j |  f S)Nz<%s: %s>)r   Ú__name__)r	   r
   r
   r   Ú__repr__/   s    zNode.__repr__c             C   sC   t  d |  j d |  j ƒ } |  j | _ t j |  j | ƒ | _ | S)Nr   r   )r   r   r   r   ÚcopyÚdeepcopyr   )r	   Zmemodictr   r
   r
   r   Ú__deepcopy__2   s    zNode.__deepcopy__c             C   s   t  |  j ƒ S)z,Return the number of children this node has.)Úlenr   )r	   r
   r
   r   Ú__len__8   s    zNode.__len__c             C   s   t  |  j ƒ S)z-Return whether or not this node has children.)Úboolr   )r	   r
   r
   r   Ú__bool__<   s    zNode.__bool__c             C   s   | |  j  k S)z:Return True if 'other' is a direct child of this instance.)r   )r	   Úotherr
   r
   r   Ú__contains__@   s    zNode.__contains__c             C   sF   |  j  | j  k oE |  j |  j f | j | j f k oE |  j | j k S)N)r   r   r   r   )r	   r!   r
   r
   r   Ú__eq__D   s    $zNode.__eq__c             C   s+   t  |  j |  j |  j f t |  j ƒ ˜ ƒ S)N)Úhashr   r   r   r   r   )r	   r
   r
   r   Ú__hash__K   s    zNode.__hash__Tc             C   sâ   | |  j  k r | S| s- |  j  j | ƒ | S|  j | k r¤ t | t ƒ r | j r | j | k sv t | ƒ d k r |  j  j | j  ƒ |  S|  j  j | ƒ | Sn: |  j |  j  |  j |  j ƒ } | |  _ | | g |  _  | Sd S)a/  
        Combine this tree and the data represented by data using the
        connector conn_type. The combine is done by squashing the node other
        away if possible.

        This tree (self) will never be pushed to a child node of the
        combined tree, nor will the connector or negated properties change.

        Return a node which can be used in place of data regardless if the
        node other got squashed or not.

        If `squash` is False the data is prepared and added as a child to
        this tree without further logic.
        é   N)	r   Úappendr   Ú
isinstancer   r   r   Úextendr   )r	   ÚdataZ	conn_typeZsquashr   r
   r
   r   ÚaddN   s"    !	zNode.addc             C   s   |  j  |  _  d S)z'Negate the sense of the root connector.N)r   )r	   r
   r
   r   Únegatez   s    zNode.negate)r   Ú
__module__Ú__qualname__Ú__doc__r   r   Úclassmethodr   r   r   r   r   r    r"   r#   r%   r+   r,   r
   r
   r
   r   r      s   ,r   )r/   r   Zdjango.utils.hashabler   r   r
   r
   r
   r   Ú<module>   s   