U
    d                     @   s   U d Z ddlZddlZddlmZ ddlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZ eedZeee  ed< edZedZed	ZG d
d deeef ZdS )zTools for creating and manipulating SON, the Serialized Ocument Notation.

Regular dictionaries can be used instead of SON objects, but not when the order
of keys is important. A SON object can be used just like a normal Python
dictionary.
    N)Mapping)AnyDictIterableIteratorListr   OptionalPatternTupleTypeTypeVarUnion RE_TYPE_Key_Value_Tc                       s  e Zd ZU dZee ed< d;eee	e
ef eee
ef  f  eddddZed eedd fd	d
ZedddZe
eddddZe
ddddZddddZee
 dddZe
edddZee
 dddZee dddZee dddZdd fd d!Ze
eed"d#d$Ze
eeef eeef d%d&d'Z ee
ef dd(d)Z!d<ee edd*d+d,Z"d=e
eeeef  eeedf d"d-d.Z#eed/d0d1Z$eed/d2d3Z%e&dd4d5Z'e(e
ef dd6d7Z)e(e&df dd8d9d:Z*  Z+S )>SONzSON data.

    A subclass of dict that maintains ordering of keys and provides a
    few extra niceties for dealing with SON. SON provides an API
    similar to collections.OrderedDict.
    
_SON__keysN)datakwargsreturnc                 K   s(   g | _ t|  | | | | d S N)r   dict__init__update)selfr   r    r   ,/tmp/pip-unpacked-wheel-oblwsawz/bson/son.pyr   ;   s    

zSON.__init__zSON[_Key, _Value])clsargsr   r   c                    s   t  j| f||}g |_|S r   )super__new__r   )r   r    r   instance	__class__r   r   r"   E   s    zSON.__new__)r   c                 C   s:   g }| j D ] }|d|d| | d q
dd| S )N(z, )z	SON([%s]))r   appendjoin)r   resultkeyr   r   r   __repr__J   s    
zSON.__repr__)r+   valuer   c                 C   s(   || j kr| j | t| || d S r   )r   r(   r   __setitem__)r   r+   r-   r   r   r   r.   P   s    
zSON.__setitem__)r+   r   c                 C   s   | j | t| | d S r   )r   remover   __delitem__r   r+   r   r   r   r0   U   s    zSON.__delitem__c                 C   s   t  }||  |S r   )r   r   r   otherr   r   r   copyY   s    
zSON.copyc                 c   s   | j E d H  d S r   r   r   r   r   r   __iter__a   s    zSON.__iter__c                 C   s
   || j kS r   r5   r1   r   r   r   has_keyd   s    zSON.has_keyc                 C   s   |   S r   )r7   r6   r   r   r   iterkeysg   s    zSON.iterkeysc                 c   s   |   D ]\}}|V  qd S r   items)r   _vr   r   r   
itervaluesk   s    zSON.itervaluesc                 C   s   dd |   D S )Nc                 S   s   g | ]\}}|qS r   r   ).0r<   r=   r   r   r   
<listcomp>p   s     zSON.values.<locals>.<listcomp>r:   r6   r   r   r   valueso   s    z
SON.valuesc                    s   g | _ t   d S r   )r   r!   clearr6   r$   r   r   rB   r   s    z	SON.clear)r+   defaultr   c                 C   s,   z
| | W S  t k
r&   || |< Y nX |S r   KeyErrorr   r+   rC   r   r   r   
setdefaultv   s
    
zSON.setdefault)r+   r    r   c                 G   sb   t |dkr$tdtdt |  z| | }W n& tk
rV   |rP|d  Y S  Y nX | |= |S )N   z&pop expected at most 2 arguments, got r   )len	TypeErrorreprrE   )r   r+   r    r-   r   r   r   pop}   s    zSON.popc                 C   sD   zt t|  \}}W n tk
r4   tdY nX | |= ||fS )Nzcontainer is empty)nextiterr;   StopIterationrE   )r   kr=   r   r   r   popitem   s    zSON.popitem)r3   r   r   c                 K   s~   |d kr
nbt |dr0| D ]\}}|| |< qn<t |drV| D ]}|| | |< qBn|D ]\}}|| |< qZ|rz| | d S )Nr;   keys)hasattrr;   rR   r   )r   r3   r   rP   r=   r   r   r   r      s    


z
SON.updatec                 C   s(   z
| | W S  t k
r"   | Y S X d S r   rD   rF   r   r   r   get   s    
zSON.get)r3   r   c                 C   s>   t |tr2t| t|ko0t|  t| kS |  |kS )z|Comparison to another SON is order-sensitive while comparison to a
        regular dictionary is order-insensitive.
        )
isinstancer   rI   listr;   to_dictr2   r   r   r   __eq__   s    
(z
SON.__eq__c                 C   s
   | |k S r   r   r2   r   r   r   __ne__   s    z
SON.__ne__c                 C   s
   t | jS r   )rI   r   r6   r   r   r   __len__   s    zSON.__len__c                    s    t t d fdd  t| S )zConvert a SON document to a normal Python dictionary instance.

        This is trickier than just *dict(...)* because it needs to be
        recursive.
        )r-   r   c                    sD   t | tr fdd| D S t | tr< fdd|  D S | S d S )Nc                    s   g | ]} |qS r   r   )r?   r=   transform_valuer   r   r@      s     z8SON.to_dict.<locals>.transform_value.<locals>.<listcomp>c                    s   i | ]\}}| |qS r   r   )r?   rP   r=   r[   r   r   
<dictcomp>   s      z8SON.to_dict.<locals>.transform_value.<locals>.<dictcomp>)rU   rV   _Mappingr;   )r-   r[   r   r   r\      s
    

z$SON.to_dict.<locals>.transform_value)r   r   r6   r   r[   r   rW      s    zSON.to_dict)memor   c                 C   sZ   t  }t| }||kr|| S |||< |  D ]&\}}t|tsLt||}|||< q.|S r   )r   idr;   rU   r   r4   deepcopy)r   r_   outZval_idrP   r=   r   r   r   __deepcopy__   s    

zSON.__deepcopy__)N)N)N),__name__
__module____qualname____doc__r   r   __annotations__r   r   r   r   r   r   r
   r   r   r"   strr,   r.   r0   r4   r   r7   boolr8   r9   r>   rA   rB   rG   r   rL   rQ   r   rT   rX   rY   intrZ   r   rW   rc   __classcell__r   r   r$   r   r   1   s:   
 "
"*r   )rg   r4   recollections.abcr   r^   typingr   r   r   r   r   r   r	   r
   r   r   r   typecompiler   rh   r   r   r   r   r   r   r   r   <module>   s   8