
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
dGZ_                 @   s  d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZmZ dZdZyddlmZmZ W n( ek
r   ddlmZmZ eZY nX dZdZd	Zd
Ze	jd0kreefZG dd deZG dd deZG dd deZG dd dee Z!dd Z"ej#ej$e"dZ%d1ddZ&dd Z'G dd de(Z)G dd de(Z*G d d! d!e*Z+G d"d# d#e*Z,G d$d% d%e*Z-G d&d' d'e*Z.G d(d) d)e*Z/G d*d+ d+e*Z0G d,d- d-e(Z1d.d/ Z2dS )2z Apply JSON-Patches (RFC 6902)     )unicode_literalsN)JsonPointerJsonPointerException   )MutableMappingMutableSequenceu    Stefan Kögl <stefan@skoegl.net>z1.21z0https://github.com/stefankoegl/python-json-patchzModified BSD License   c               @   s   e Zd ZdZdS )JsonPatchExceptionzBase Json Patch exceptionN)__name__
__module____qualname____doc__ r   r   /usr/lib/python3.6/jsonpatch.pyr	   G   s   r	   c               @   s   e Zd ZdZdS )InvalidJsonPatchz, Raised if an invalid JSON Patch is created N)r
   r   r   r   r   r   r   r   r   K   s   r   c               @   s   e Zd ZdZdS )JsonPatchConflicta  Raised if patch could not be applied due to conflict situation such as:
    - attempt to add object key then it already exists;
    - attempt to operate with nonexistence object key;
    - attempt to insert value to array at position beyond of it size;
    - etc.
    N)r
   r   r   r   r   r   r   r   r   O   s   r   c               @   s   e Zd ZdZdS )JsonPatchTestFailedz A Test operation failed N)r
   r   r   r   r   r   r   r   r   X   s   r   c             C   s@   t jt}x| D ]\}}|| j| qW tdd |j D S )z'Convert duplicate keys values to lists.c             s   s.   | ]&\}}|t |d kr |d n|fV  qdS )r   r   N)len).0keyvaluesr   r   r   	<genexpr>e   s   zmultidict.<locals>.<genexpr>)collectionsdefaultdictlistappenddictitems)Zordered_pairsZmdictr   valuer   r   r   	multidict\   s    
r   )Zobject_pairs_hookFc             C   s*   t |trtj|}nt|}|j| |S )aO  Apply list of patches to specified json document.

    :param doc: Document object.
    :type doc: dict

    :param patch: JSON patch as list of dicts or raw JSON-encoded string.
    :type patch: list or str

    :param in_place: While :const:`True` patch will modify target document.
                     By default patch will be applied to document copy.
    :type in_place: bool

    :return: Patched document object.
    :rtype: dict

    >>> doc = {'foo': 'bar'}
    >>> patch = [{'op': 'add', 'path': '/baz', 'value': 'qux'}]
    >>> other = apply_patch(doc, patch)
    >>> doc is not other
    True
    >>> other == {'foo': 'bar', 'baz': 'qux'}
    True
    >>> patch = [{'op': 'add', 'path': '/baz', 'value': 'qux'}]
    >>> apply_patch(doc, patch, in_place=True) == {'foo': 'bar', 'baz': 'qux'}
    True
    >>> doc == other
    True
    )
isinstance
basestring	JsonPatchfrom_stringapply)docpatchin_placer   r   r   apply_patcho   s    
r(   c             C   s   t j| |S )a  Generates patch by comparing of two document objects. Actually is
    a proxy to :meth:`JsonPatch.from_diff` method.

    :param src: Data source document object.
    :type src: dict

    :param dst: Data source document object.
    :type dst: dict

    >>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]}
    >>> dst = {'baz': 'qux', 'numbers': [1, 4, 7]}
    >>> patch = make_patch(src, dst)
    >>> new = patch.apply(src)
    >>> new == dst
    True
    )r"   	from_diff)srcdstr   r   r   
make_patch   s    r,   c               @   s   e Zd ZdZdd Zdd Zdd ZeZdd	 Zd
d Z	dd Z
dd Zedd ZedddZdd Zedd Zd ddZdd ZdS )!r"   ag  A JSON Patch is a list of Patch Operations.

    >>> patch = JsonPatch([
    ...     {'op': 'add', 'path': '/foo', 'value': 'bar'},
    ...     {'op': 'add', 'path': '/baz', 'value': [1, 2, 3]},
    ...     {'op': 'remove', 'path': '/baz/1'},
    ...     {'op': 'test', 'path': '/baz', 'value': [1, 3]},
    ...     {'op': 'replace', 'path': '/baz/0', 'value': 42},
    ...     {'op': 'remove', 'path': '/baz/1'},
    ... ])
    >>> doc = {}
    >>> result = patch.apply(doc)
    >>> expected = {'foo': 'bar', 'baz': [42]}
    >>> result == expected
    True

    JsonPatch object is iterable, so you could easily access to each patch
    statement in loop:

    >>> lpatch = list(patch)
    >>> expected = {'op': 'add', 'path': '/foo', 'value': 'bar'}
    >>> lpatch[0] == expected
    True
    >>> lpatch == patch.patch
    True

    Also JsonPatch could be converted directly to :class:`bool` if it contains
    any operation statements:

    >>> bool(patch)
    True
    >>> bool(JsonPatch([]))
    False

    This behavior is very handy with :func:`make_patch` to write more readable
    code:

    >>> old = {'foo': 'bar', 'numbers': [1, 3, 4, 8]}
    >>> new = {'baz': 'qux', 'numbers': [1, 4, 7]}
    >>> patch = make_patch(old, new)
    >>> if patch:
    ...     # document have changed, do something useful
    ...     patch.apply(old)    #doctest: +ELLIPSIS
    {...}
    c             C   s   || _ ttttttd| _d S )N)removeaddreplacemoveZtestcopy)r&   RemoveOperationAddOperationReplaceOperationMoveOperationTestOperationCopyOperation
operations)selfr&   r   r   r   __init__   s    zJsonPatch.__init__c             C   s   | j  S )zstr(self) -> self.to_string())	to_string)r9   r   r   r   __str__   s    zJsonPatch.__str__c             C   s
   t | jS )N)boolr&   )r9   r   r   r   __bool__   s    zJsonPatch.__bool__c             C   s
   t | jS )N)iterr&   )r9   r   r   r   __iter__   s    zJsonPatch.__iter__c             C   s   t t| jS )N)hashtuple_ops)r9   r   r   r   __hash__   s    zJsonPatch.__hash__c             C   s   t |tsdS | j|jkS )NF)r    r"   rC   )r9   otherr   r   r   __eq__   s    
zJsonPatch.__eq__c             C   s
   | |k S )Nr   )r9   rE   r   r   r   __ne__   s    zJsonPatch.__ne__c             C   s   t |}| |S )zCreates JsonPatch instance from string source.

        :param patch_str: JSON patch as raw string.
        :type patch_str: str

        :return: :class:`JsonPatch` instance.
        )
_jsonloads)clsZ	patch_strr&   r   r   r   r#      s    	zJsonPatch.from_stringTc             C   s*   t  }|jdd|| t|j }| |S )aO  Creates JsonPatch instance based on comparing of two document
        objects. Json patch would be created for `src` argument against `dst`
        one.

        :param src: Data source document object.
        :type src: dict

        :param dst: Data source document object.
        :type dst: dict

        :return: :class:`JsonPatch` instance.

        >>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]}
        >>> dst = {'baz': 'qux', 'numbers': [1, 4, 7]}
        >>> patch = JsonPatch.from_diff(src, dst)
        >>> new = patch.apply(src)
        >>> new == dst
        True
         N)DiffBuilder_compare_valuesr   execute)rI   r*   r+   optimizationZbuilderZopsr   r   r   r)     s    zJsonPatch.from_diffc             C   s   t j| jS )z!Returns patch set as JSON string.)jsondumpsr&   )r9   r   r   r   r;   !  s    zJsonPatch.to_stringc             C   s   t t| j| jS )N)rB   map_get_operationr&   )r9   r   r   r   rC   %  s    zJsonPatch._opsFc             C   s,   |st j|}x| jD ]}|j|}qW |S )a/  Applies the patch to given object.

        :param obj: Document object.
        :type obj: dict

        :param in_place: Tweaks way how patch would be applied - directly to
                         specified `obj` or to his copy.
        :type in_place: bool

        :return: Modified `obj`.
        )r1   deepcopyrC   r$   )r9   objr'   	operationr   r   r   r$   )  s
    
zJsonPatch.applyc             C   sT   d|krt d|d }t|ts*t d|| jkrBt dj|| j| }||S )Nopz&Operation does not contain 'op' memberzOperation must be a stringzUnknown operation {0!r})r   r    r!   r8   format)r9   rU   rV   rI   r   r   r   rR   >  s    


zJsonPatch._get_operationN)T)F)r
   r   r   r   r:   r<   r>   Z__nonzero__r@   rD   rF   rG   classmethodr#   r)   r;   propertyrC   r$   rR   r   r   r   r   r"      s    -
r"   c               @   s^   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Ze	dd Z
e	dd Zejdd ZdS )PatchOperationz'A single operation inside a JSON Patch.c             C   s    |d | _ t| j | _|| _d S )Npath)locationr   pointerrU   )r9   rU   r   r   r   r:   Q  s    
zPatchOperation.__init__c             C   s   t ddS )zAAbstract method that applies patch operation to specified object.z!should implement patch operation.N)NotImplementedError)r9   rT   r   r   r   r$   V  s    zPatchOperation.applyc             C   s   t t| jj S )N)rA   	frozensetrU   r   )r9   r   r   r   rD   Z  s    zPatchOperation.__hash__c             C   s   t |tsdS | j|jkS )NF)r    rZ   rU   )r9   rE   r   r   r   rF   ]  s    
zPatchOperation.__eq__c             C   s
   | |k S )Nr   )r9   rE   r   r   r   rG   b  s    zPatchOperation.__ne__c             C   s   dj | jjd d S )N/r   )joinr]   parts)r9   r   r   r   r[   e  s    zPatchOperation.pathc             C   s2   yt | jjd S  tk
r,   | jjd S X d S )Nr   ra   ra   )intr]   rc   
ValueError)r9   r   r   r   r   i  s    zPatchOperation.keyc             C   s*   t || jjd< | jj| _| j| jd< d S )Nr   r[   ra   )strr]   rc   r[   r\   rU   )r9   r   r   r   r   r   p  s    
N)r
   r   r   r   r:   r$   rD   rF   rG   rY   r[   r   setterr   r   r   r   rZ   N  s   rZ   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r2   z/Removes an object property or an array element.c             C   sX   | j j|\}}y
||= W n8 ttfk
rR } zdj|}t|W Y d d }~X nX |S )Nz&can't remove non-existent object '{0}')r]   to_lastKeyError
IndexErrorrW   r   )r9   rT   subobjpartexmsgr   r   r   r$   z  s    

zRemoveOperation.applyc             C   s0   | j |kr,| j|kr$|  jd7  _n|d8 }|S )Nr   )r[   r   )r9   r[   r   r   r   r   _on_undo_remove  s
    

zRemoveOperation._on_undo_removec             C   s0   | j |kr,| j|kr$|  jd8  _n|d8 }|S )Nr   )r[   r   )r9   r[   r   r   r   r   _on_undo_add  s
    

zRemoveOperation._on_undo_addN)r
   r   r   r   r$   ro   rp   r   r   r   r   r2   w  s   
r2   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r3   z,Adds an object property or an array element.c             C   s   y| j d }W n* tk
r8 } ztdW Y d d }~X nX | jj|\}}t|tr|dkrh|j| q|t|ks||dk rt	dq|j
|| n4t|tr|d kr|}q|||< ntdjt||S )Nr   z/The operation does not contain a 'value' member-r   zcan't insert outside of listzinvalid document type {0})rU   ri   r   r]   rh   r    r   r   r   r   insertr   	TypeErrorrW   type)r9   rT   r   rm   rk   rl   r   r   r   r$     s$    



zAddOperation.applyc             C   s0   | j |kr,| j|kr$|  jd7  _n|d7 }|S )Nr   )r[   r   )r9   r[   r   r   r   r   ro     s
    

zAddOperation._on_undo_removec             C   s0   | j |kr,| j|kr$|  jd8  _n|d7 }|S )Nr   )r[   r   )r9   r[   r   r   r   r   rp     s
    

zAddOperation._on_undo_addN)r
   r   r   r   r$   ro   rp   r   r   r   r   r3     s   r3   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r4   z=Replaces an object property or an array element by new value.c             C   s   y| j d }W n* tk
r8 } ztdW Y d d }~X nX | jj|\}}|d krV|S t|tr~|t|kst|dk rtdn8t|t	r||krdj
|}t|ntdj
t||||< |S )Nr   z/The operation does not contain a 'value' memberr   zcan't replace outside of listz'can't replace non-existent object '{0}'zinvalid document type {0})rU   ri   r   r]   rh   r    r   r   r   r   rW   rs   rt   )r9   rT   r   rm   rk   rl   rn   r   r   r   r$     s$    




zReplaceOperation.applyc             C   s   |S )Nr   )r9   r[   r   r   r   r   ro     s    z ReplaceOperation._on_undo_removec             C   s   |S )Nr   )r9   r[   r   r   r   r   rp     s    zReplaceOperation._on_undo_addN)r
   r   r   r   r$   ro   rp   r   r   r   r   r4     s   r4   c               @   sN   e Zd ZdZdd Zedd Zedd Zejdd Zd	d
 Z	dd Z
dS )r5   z=Moves an object property or an array element to new location.c          !   C   s   yt | jd }W n* tk
r< } ztdW Y d d }~X nX |j|\}}y|| }W n2 ttfk
r } ztt|W Y d d }~X nX | j|kr|S t	|t
r| jj|rtdtd| jd dj|}td| j|dj|}|S )Nfromz.The operation does not contain a 'from' memberz(Cannot move values into its own childrenr-   )rV   r[   r.   )rV   r[   r   )r   rU   ri   r   rh   rj   r   rf   r]   r    r   containsr2   r$   r3   r\   )r9   rT   from_ptrrm   rk   rl   r   r   r   r   r$     s2    


zMoveOperation.applyc             C   s"   t | jd }dj|jd d S )Nru   r`   r   ra   )r   rU   rb   rc   )r9   rw   r   r   r   	from_path  s    zMoveOperation.from_pathc             C   s<   t | jd }yt|jd S  tk
r6   |jd S X d S )Nru   r   ra   ra   )r   rU   rd   rc   rs   )r9   rw   r   r   r   from_key  s
    zMoveOperation.from_keyc             C   s,   t | jd }t||jd< |j| jd< d S )Nru   r   ra   )r   rU   rf   rc   r[   )r9   r   rw   r   r   r   ry     s    c             C   s\   | j |kr,| j|kr$|  jd7  _n|d8 }| j|krX| j|krP|  jd7  _n|d7 }|S )Nr   )rx   ry   r[   r   )r9   r[   r   r   r   r   ro   #  s    



zMoveOperation._on_undo_removec             C   s\   | j |kr,| j|kr$|  jd8  _n|d8 }| j|krX| j|krP|  jd8  _n|d7 }|S )Nr   )rx   ry   r[   r   )r9   r[   r   r   r   r   rp   0  s    



zMoveOperation._on_undo_addN)r
   r   r   r   r$   rY   rx   ry   rg   ro   rp   r   r   r   r   r5     s   "r5   c               @   s   e Zd ZdZdd ZdS )r6   z!Test value by specified location.c          #   C   s   y0| j j|\}}|d kr |}n| j j||}W n. tk
r^ } ztt|W Y d d }~X nX y| jd }W n* tk
r } ztdW Y d d }~X nX ||krd}t|j	|t
||t
||S )Nr   z/The operation does not contain a 'value' memberz0{0} ({1}) is not equal to tested value {2} ({3}))r]   rh   walkr   r   rf   rU   ri   r   rW   rt   )r9   rT   rk   rl   valrm   r   rn   r   r   r   r$   A  s"    zTestOperation.applyN)r
   r   r   r   r$   r   r   r   r   r6   >  s   r6   c               @   s   e Zd ZdZdd ZdS )r7   zA Copies an object property or an array element to a new location c          !   C   s   yt | jd }W n* tk
r< } ztdW Y d d }~X nX |j|\}}ytj|| }W n2 ttfk
r } ztt	|W Y d d }~X nX t
d| j|dj|}|S )Nru   z.The operation does not contain a 'from' memberr.   )rV   r[   r   )r   rU   ri   r   rh   r1   rS   rj   r   rf   r3   r\   r$   )r9   rT   rw   rm   rk   rl   r   r   r   r   r$   \  s     
zCopyOperation.applyN)r
   r   r   r   r$   r   r   r   r   r7   Y  s   r7   c               @   s|   e 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dd Zdd Zdd ZdS )rK   c             C   s4   i i g| _ g g g| _g  | _}||d g|d d < d S )N)index_storageindex_storage2_DiffBuilder__root)r9   rootr   r   r   r:   t  s    


zDiffBuilder.__init__c             C   sh   y:| j | }|j|}|d kr*|g||< n|| j| W n( tk
rb   | j| j||f Y nX d S )N)r|   getr   rs   r}   )r9   r   indexststoragestoredr   r   r   store_indexz  s    

zDiffBuilder.store_indexc             C   s   y | j | j|}|r|j S W nZ tk
rz   | j| }x:tt|d ddD ]"}|| d |krP|j|d S qPW Y nX d S )Nr   r   ra   ra   )r|   r   poprs   r}   ranger   )r9   r   r   r   r   ir   r   r   
take_index  s    
zDiffBuilder.take_indexc             C   s,   | j }|d }|||g |d< |d< |d S )Nr   r   )r~   )r9   rV   r   Zlastr   r   r   rr     s    zDiffBuilder.insertc             C   s*   |\}}}||d< ||d< g |d d < d S )Nr   r   r   )r9   r   Z	link_prevZ	link_next_r   r   r   r-     s    
zDiffBuilder.removec             c   s2   | j }|d }x||k	r,|d V  |d }qW d S )Nr      )r~   )r9   startr   currr   r   r   	iter_from  s
    

zDiffBuilder.iter_fromc             c   s2   | j }|d }x||k	r,|d V  |d }qW d S )Nr   r   )r~   )r9   r   r   r   r   r   r@     s
    

zDiffBuilder.__iter__c             c   s   | j }|d }x||k	r|d |k	r|d |d d  }}|j|jkrt|tkrt|tkrtd|j|jd djV  |d d }q|d jV  |d }qW d S )Nr   r   r/   r   )rV   r[   r   )r~   r\   rt   r2   r3   r4   rU   )r9   r   r   Zop_firstZ	op_secondr   r   r   rM     s     
zDiffBuilder.executec       	      C   s   | j |t}|d k	r|d }t|jtkrPx$| j|D ]}|j|j|j|_q6W | j| |j	t
||krtd|j	t
||d}| j| n.tdt
|||d}| j|}| j||t d S )Nr   r0   )rV   ru   r[   r.   )rV   r[   r   )r   
_ST_REMOVErt   r   rd   r   ro   r[   r-   r\   
_path_joinr5   rr   r3   r   _ST_ADD)	r9   r[   r   itemr   rV   vnew_op	new_indexr   r   r   _item_added  s&    


zDiffBuilder._item_addedc       	      C   s   t dt||d}| j|t}| j|}|d k	r|d }t|jtkrnx$| j|D ]}|j	|j
|j|_qTW | j| |j|jkrtd|j|jd}||d< q| j| n| j||t d S )Nr-   )rV   r[   r   r0   )rV   ru   r[   )r2   r   r   r   rr   rt   r   rd   r   rp   r[   r-   r\   r5   r   r   )	r9   r[   r   r   r   r   r   rV   r   r   r   r   _item_removed  s&    


zDiffBuilder._item_removedc             C   s    | j tdt|||d d S )Nr/   )rV   r[   r   )rr   r4   r   )r9   r[   r   r   r   r   r   _item_replaced  s    zDiffBuilder._item_replacedc       	      C   s   t |j }t |j }|| }|| }x"|D ]}| j|t|||  q.W x"|D ]}| j|t|||  qRW x(||@ D ]}| j|||| ||  qzW d S )N)setkeysr   rf   r   rL   )	r9   r[   r*   r+   Zsrc_keysZdst_keysZ
added_keysZremoved_keysr   r   r   r   _compare_dicts  s    

zDiffBuilder._compare_dictsc             C   s  t |t | }}t||}t||}xt|D ]}||k r|| ||  }	}
|	|
krZq0qt|	trt|
tr| jt|||	|
 qt|	trt|
tr| j	t|||	|
 q| j
|||	 | j|||
 q0||kr| j
||||  q0| j||||  q0W d S )N)r   maxminr   r    r   r   r   r   _compare_listsr   r   )r9   r[   r*   r+   Zlen_srcZlen_dstZmax_lenZmin_lenr   oldnewr   r   r   r     s&    





zDiffBuilder._compare_listsc             C   sr   ||krd S t |tr6t |tr6| jt|||| n8t |tr`t |tr`| jt|||| n| j||| d S )N)r    r   r   r   r   r   r   )r9   r[   r   r*   r+   r   r   r   rL   '  s    



zDiffBuilder._compare_valuesN)r
   r   r   r:   r   r   rr   r-   r   r@   rM   r   r   r   r   r   rL   r   r   r   r   rK   r  s   rK   c             C   s,   |d kr| S | d t |jddjdd S )Nr`   ~z~0z~1)rf   r/   )r[   r   r   r   r   r   7  s    r   )r   r   )F)3r   Z
__future__r   r   r1   	functoolsinspect	itertoolsrO   sysZjsonpointerr   r   r   r   collections.abcr   r   ImportErrorZunicoderf   
__author____version__Z__website__Z__license__version_infobytesr!   	Exceptionr	   r   r   AssertionErrorr   r   partialloadsrH   r(   r,   objectr"   rZ   r2   r3   r4   r5   r6   r7   rK   r   r   r   r   r   <module>!   sT   

	
% &)2$S F