o M`p@sdZddlmZddlZddlZddlZddlZddlZzddlm Z Wn e y/e Z Ynwddl m Z mZdZdZz ddlmZmZWne yYddlmZmZeZYnwdZd Zd Zd Zejd krkeefZGd ddeZGdddeZGdddeZ Gdddee!Z"ddZ#ej$ej%e#dZ&de fddZ'e fddZ(Gddde)Z*Gdd d e*Z+Gd!d"d"e*Z,Gd#d$d$e*Z-Gd%d&d&e*Z.Gd'd(d(e*Z/Gd)d*d*e*Z0Gd+d,d,e)Z1Gd-d.d.e)Z2d/d0Z3dS)1z Apply JSON-Patches (RFC 6902) )unicode_literalsN)MappingProxyType) JsonPointerJsonPointerException)MutableMappingMutableSequenceu Stefan Kögl z1.32z0https://github.com/stefankoegl/python-json-patchzModified BSD License)rc@eZdZdZdS)JsonPatchExceptionzBase Json Patch exceptionN__name__ __module__ __qualname____doc__rr+/usr/lib/python3/dist-packages/jsonpatch.pyr Jr c@r )InvalidJsonPatchz, Raised if an invalid JSON Patch is created Nr rrrrrNrrc@r )JsonPatchConflicta Raised if patch could not be applied due to conflict situation such as: - attempt to add object key when it already exists; - attempt to operate with nonexistence object key; - attempt to insert value to array at position beyond its size; - etc. Nr rrrrrRrrc@r )JsonPatchTestFailedz A Test operation failed Nr rrrrr[rrcCs<tt}|D] \}}|||qtdd|DS)z'Convert duplicate keys values to lists.css0|]\}}|t|dkr|dn|fVqdS)rrN)len).0keyvaluesrrr fs  zmultidict..) collections defaultdictlistappenddictitems) ordered_pairsmdictrvaluerrr multidict_s  r%)object_pairs_hookFcCs2t|tr tj||d}nt||d}|||S)aApply 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 :param pointer_cls: JSON pointer class to use. :type pointer_cls: Type[JsonPointer] :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  pointer_cls) isinstance basestring JsonPatch from_stringapply)docpatchin_placer(rrr apply_patchrs !  r1cCstj|||dS)a!Generates patch by comparing 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 :param pointer_cls: JSON pointer class to use. :type pointer_cls: Type[JsonPointer] >>> 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')r+ from_diff)srcdstr(rrr make_patchsr5c@sbeZdZdZefddZddZddZdd Zd d Z e d d Z e ddZ e j ddZ dS)PatchOperationz'A single operation inside a JSON Patch.c Cs||_|ds tdt|d|jr |dj|_|d|_n|d|_z ||j|_Wnty>}ztdd}~ww||_dS)Npathz#Operation must have a 'path' memberzInvalid 'path') r( __contains__rr)r7locationpointer TypeError operation)selfr<r(exrrr__init__s     zPatchOperation.__init__cCstd)zGAbstract method that applies a patch operation to the specified object.z%should implement the patch operation.)NotImplementedError)r=objrrrr-zPatchOperation.applycCstt|jSN)hash frozensetr<r!r=rrr__hash__szPatchOperation.__hash__cCt|tsdS|j|jkSNF)r)r6r<r=otherrrr__eq__  zPatchOperation.__eq__cC ||k SrCrrJrrr__ne__ zPatchOperation.__ne__cCsd|jjddS)N/)joinr:partsrFrrrr7szPatchOperation.pathcCs2z t|jjdWSty|jjdYSw)NrR)intr:rT ValueErrorrFrrrrs  zPatchOperation.keycCs*t||jjd<|jj|_|j|jd<dS)NrRr7)strr:rTr7r9r<)r=r$rrrrs N)r rrrrr?r-rGrLrOpropertyr7rsetterrrrrr6s   r6c@(eZdZdZddZddZddZdS) RemoveOperationz/Removes an object property or an array element.c CsL|j|\}}z||=W|Sttfy%}z d|}t|d}~ww)Nz(can't remove a non-existent object '{0}')r:to_lastKeyError IndexErrorformatr)r=rAsubobjpartr>msgrrrr-s zRemoveOperation.applycCs2|j|kr|j|kr|jd7_|S|d8}|SNrr7rr=r7rrrr_on_undo_remove  zRemoveOperation._on_undo_removecCs2|j|kr|j|kr|jd8_|S|d8}|Srcrdrerrr _on_undo_addrgzRemoveOperation._on_undo_addNr rrrr-rfrhrrrrr[s  r[c@rZ) AddOperationz,Adds an object property or an array element.c Csz|jd}Wnty}ztdd}~ww|j|\}}t|trF|dkr0|||S|t|ks:|dkr>t d| |||St|t rY|durS|}|S|||<|S|durft d t|t d |j|)Nr$/The operation does not contain a 'value' member-rzcan't insert outside of listinvalid document type {0}2unable to fully resolve json pointer {0}, part {1})r<r]rr:r\r)rrrrinsertrr;r_typer9)r=rAr$r>r`rarrrr- s4     zAddOperation.applycCs2|j|kr|j|kr|jd7_|S|d7}|Srcrdrerrrrf)rgzAddOperation._on_undo_removecCs2|j|kr|j|kr|jd8_|S|d7}|Srcrdrerrrrh1rgzAddOperation._on_undo_addNrirrrrrjs  rjc@rZ) ReplaceOperationz?Replaces an object property or an array element by a new value.c Csz|jd}Wnty}ztdd}~ww|j|\}}|dur&|S|dkr.tdt|trB|t|ks=|dkrAtdn)t|t rU||vrTd |}t|n|durbt d t |td |j ||||<|S) Nr$rkrlz7'path' with '-' can't be applied to 'replace' operationrzcan't replace outside of listz)can't replace a non-existent object '{0}'rmrn)r<r]rr:r\r)rrrrr_r;rpr9)r=rAr$r>r`rarbrrrr-=s6   zReplaceOperation.applycC|SrCrrerrrrf]z ReplaceOperation._on_undo_removecCrrrCrrerrrrh`rszReplaceOperation._on_undo_addNrirrrrrq:s  rqc@sNeZdZdZddZeddZeddZejddZd d Z d d Z d S) MoveOperationz?Moves an object property or an array element to a new location.c Cszt|jd|jr|jd}n||jd}Wnty)}ztdd}~ww||\}}z||}WnttfyK}ztt|d}~ww|j |krS|St|t rb|j |rbtdt d|jdd|jd |}td|j|d|jd |}|S) Nfrom.The operation does not contain a 'from' memberz*Cannot move values into their own childrenremoveopr7r'addryr7r$)r)r<r(r]rr\r^rrWr:rcontainsr[r-rjr9r=rAfrom_ptrr>r`rar$rrrr-gsT      zMoveOperation.applycCs$||jd}d|jddS)NrurQrR)r(r<rSrTr=r~rrr from_pathszMoveOperation.from_pathcCs>||jd}zt|jdWSty|jdYSwNrurR)r(r<rUrTr;rrrrfrom_keys  zMoveOperation.from_keycCs.||jd}t||jd<|j|jd<dSr)r(r<rWrTr7)r=r$r~rrrrscCs^|j|kr|j|kr|jd7_n|d8}|j|kr-|j|kr)|jd7_|S|d7}|Srcrrr7rrerrrrf    zMoveOperation._on_undo_removecCs^|j|kr|j|kr|jd8_n|d8}|j|kr-|j|kr)|jd8_|S|d7}|SrcrrerrrrhrzMoveOperation._on_undo_addN) r rrrr-rXrrrYrfrhrrrrrtds%    rtc@eZdZdZddZdS) TestOperationz!Test value by specified location.c Csz|j|\}}|dur|}n|j||}Wnty*}ztt|d}~wwz|jd}WntyB}ztdd}~ww||krWd}t| |t ||t ||S)Nr$rkz0{0} ({1}) is not equal to tested value {2} ({3})) r:r\walkrrrWr<r]rr_rp)r=rAr`ravalr>r$rbrrrr-s0 zTestOperation.applyNr rrrr-rrrrr rc@r) CopyOperationzA Copies an object property or an array element to a new location c Csz ||jd}Wnty}ztdd}~ww||\}}z t||}Wnttfy?}ztt |d}~wwt d|j |d|jd |}|S)Nrurvrzr{r') r(r<r]rr\copydeepcopyr^rrWrjr9r-r}rrrr-s2 zCopyOperation.applyNrrrrrrrrc@seZdZeejZeeZe e e e e eedZ efddZddZddZeZdd Zd d Zd d ZddZedefddZeddefddZdddZeddZd ddZ ddZ!dS)!r+)rwrzreplacemovetestrcCs&||_||_|jD]}||q dSrC)r/r(_get_operation)r=r/r(ryrrrr?(s   zJsonPatch.__init__cCs|S)zstr(self) -> self.to_string()) to_stringrFrrr__str__3rBzJsonPatch.__str__cC t|jSrC)boolr/rFrrr__bool__7rPzJsonPatch.__bool__cCrrC)iterr/rFrrr__iter__<rPzJsonPatch.__iter__cCstt|jSrC)rDtuple_opsrFrrrrG?szJsonPatch.__hash__cCrHrI)r)r+rrJrrrrLBrMzJsonPatch.__eq__cCrNrCrrJrrrrOGrPzJsonPatch.__ne__NcCs|p|j}||}|||dS)aCreates JsonPatch instance from string source. :param patch_str: JSON patch as raw string. :type patch_str: str :param loads: A function of one argument that loads a serialized JSON string. :type loads: function :param pointer_cls: JSON pointer class to use. :type pointer_cls: Type[JsonPointer] :return: :class:`JsonPatch` instance. r') json_loader)cls patch_strloadsr(rr/rrrr,Js  zJsonPatch.from_stringTc CsB|p|j}t||||d}|dd||t|}|||dS)aCCreates JsonPatch instance based on comparison 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 :param dumps: A function of one argument that produces a serialized JSON string. :type dumps: function :param pointer_cls: JSON pointer class to use. :type pointer_cls: Type[JsonPointer] :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 r'N) json_dumper DiffBuilder_compare_valuesrexecute) rr3r4 optimizationdumpsr(rbuilderopsrrrr2^s   zJsonPatch.from_diffcCs|p|j}||jS)z!Returns patch set as JSON string.)rr/)r=rrrrrrs  zJsonPatch.to_stringcCstt|j|jSrC)rmaprr/rFrrrrszJsonPatch._opsFcCs(|st|}|jD]}||}q |S)a5Applies the patch to a given object. :param obj: Document object. :type obj: dict :param in_place: Tweaks the way how patch would be applied - directly to specified `obj` or to its copy. :type in_place: bool :return: Modified `obj`. )rrrr-)r=rAr0r<rrrr-s    zJsonPatch.applycCsZd|vrtd|d}t|tstd||jvr!td||j|}|||jdS)Nryz&Operation does not contain 'op' memberzOperation must be a stringzUnknown operation {0!r}r')rr)r* operationsr_r()r=r<ryrrrrrs   zJsonPatch._get_operationrC)F)"r rr staticmethodjsonrr _jsonloadsrrr[rjrqrtrrrrr?rr __nonzero__rrGrLrO classmethodr,r2rrXrr-rrrrrr+s>  -  $   r+c@seZdZejefddZddZddZddZ d d Z d d Z d dZ ddZ ddZddZddZddZddZddZdS)rcCsL||_||_iig|_ggg|_g|_}||_||_||dg|dd<dSrC)rr( index_storageindex_storage2_DiffBuilder__rootsrc_docdst_doc)r=rrrr(rootrrrr?s   zDiffBuilder.__init__cCsv|t|f}z |j|}||}|dur|g||<WdS|||WdSty:|j|||fYdSwrC)rprgetrr;r)r=r$indexst typed_keystoragestoredrrr store_indexs    zDiffBuilder.store_indexcCs|t|f}z|j||}|r|WSWdStyG|j|}tt|dddD]}||d|krC||dYSq.YdSw)NrrRr)rprrpopr;rranger)r=r$rrrrirrr take_indexs    zDiffBuilder.take_indexcCs,|j}|d}|||g|d<|d<|dS)Nrrr)r=ryrlastrrrroszDiffBuilder.insertcCs*|\}}}||d<||d<g|dd<dS)Nrrr)r=r link_prev link_next_rrrrws zDiffBuilder.removeccs:|j}|d}||ur|dV|d}||us dSdSNrr)r=startrcurrrrr iter_from zDiffBuilder.iter_fromccs:|j}|d}||ur|dV|d}||us dSdSrr)r=rrrrrrrzDiffBuilder.__iter__ccs|j}|d}||urW|d|urG|d|dd}}|j|jkrGt|tkrGt|tkrGtd|j|jdd|jdjV|dd}q|djV|d}||us dSdS)Nrrrr$r{r')rr9rpr[rjrqr<r()r=rrop_first op_secondrrrrs.      zDiffBuilder.executec Cs||t}|durQ|d}t|jtkr,t|tkr,||D] }||j|j|_q |||j t ||krOt d|j t ||d|j d}| |dSdStdt |||d|j d}| |}|||tdS)Nrrryrur7r'rzr{)r _ST_REMOVErprrUrrfr7rwr9 _path_joinrtr(rorjr_ST_ADD) r=r7ritemrryvnew_op new_indexrrr _item_addeds4   zDiffBuilder._item_addedc Cstdt||d|jd}||t}||}|dure|d}|j|jd}t |t kr@| |D] } | |j |j|_q4|||j|jkr^td|j|jd|jd}||d<dS||dS|||tdS)Nrwrxr'rrrr)r[rr(rrror:r\rrprrrhr7rrwr9rtrr) r=r7rrrrrry added_itemrrrr _item_removeds4      zDiffBuilder._item_removedcCs&|tdt|||d|jddS)Nrr{r')rorqrr()r=r7rrrrr_item_replaced?s zDiffBuilder._item_replacedc Cst|}t|}||}||}|D] }||t|||q|D] }||t|||q&||@D]}|||||||q8dSrC)setkeysrrWrr) r=r7r3r4src_keysdst_keys added_keys removed_keysrrrr_compare_dictsFs   zDiffBuilder._compare_dictsc Cst|t|}}t||}t||}t|D]d}||krd||||} } | | kr+qt| tr@t| tr@|t||| | qt| trUt| trU| t||| | q| ||| | ||| q||krr| ||||q| ||||qdSrC) rmaxminrr)rrrr_compare_listsrr) r=r7r3r4len_srclen_dstmax_lenmin_lenroldnewrrrrUs,     zDiffBuilder._compare_listscCst|trt|tr|t||||dSt|tr,t|tr,|t||||dS||||kr8dS||||dSrC)r)rrrrrrr)r=r7rr3r4rrrrqs   zDiffBuilder._compare_valuesN)r rrrrrr?rrrorwrrrrrrrrrrrrrrs   ! rcCs,|dur|S|dt|ddddS)NrQ~z~0z~1)rWrrdrrrrs r)4r __future__rrr functoolsrsystypesr ImportErrorr jsonpointerrrrrcollections.abcrrunicoderW __author__ __version__ __website__ __license__ version_infobytesr* Exceptionr rrAssertionErrorrr%partialrrr1r5objectr6r[rjrqrtrrr+rrrrrrs^      (64*VD X