M`pldZddlmZddlZddlZddlZddlZddlZ ddlm Z ddl m Z mZdZdZ ddlmZmZdZd Zd Zd Zej4d k\reefZGd deZGddeZGddeZ Gddee!Z"dZ#ejHejJe#Z&de fdZ'e fdZ(Gdde)Z*Gdde*Z+Gdde*Z,Gd d!e*Z-Gd"d#e*Z.Gd$d%e*Z/Gd&d'e*Z0Gd(d)e)Z1Gd*d+e)Z2d,Z3y#e $re Z YwxYw#e $r ddlmZmZeZYwxYw)-z Apply JSON-Patches (RFC 6902) )unicode_literalsN)MappingProxyType) JsonPointerJsonPointerException)MutableMappingMutableSequenceu Stefan Kögl z1.32z0https://github.com/stefankoegl/python-json-patchzModified BSD License)rceZdZdZy)JsonPatchExceptionzBase Json Patch exceptionN__name__ __module__ __qualname____doc__+/usr/lib/python3/dist-packages/jsonpatch.pyr r J#rr ceZdZdZy)InvalidJsonPatchz, Raised if an invalid JSON Patch is created Nr rrrrrNs6rrceZdZdZy)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 rrrrrRsrrceZdZdZy)JsonPatchTestFailedz A Test operation failed Nr rrrrrrrctjt}|D]\}}||j|t d|j DS)z'Convert duplicate keys values to lists.c3PK|]\}}|t|dk(r|dn|f yw)rrN)len).0keyvaluess r zmultidict..fs4 C 3v;!+fQi8s$&) collections defaultdictlistappenddictitems) ordered_pairsmdictr values r multidictr,_s]  # #D )E#! U c % ! !;;= r)object_pairs_hookFct|trtj||}n t||}|j ||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_placer0s r apply_patchr9rsAB%$%%e%E%[9 ;;sH %%rc2tj|||S)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/)r3 from_diff)srcdstr0s r make_patchr>s*   sC[  AArcveZdZdZefdZdZdZdZdZ e dZ e dZ e jd Z y ) PatchOperationz'A single operation inside a JSON Patch.cd||_|jds tdt|d|jr&|dj|_|d|_||_y|d|_ |j|j |_||_y#t$r}tdd}~wwxYw)Npathz#Operation must have a 'path' memberzInvalid 'path') r0 __contains__rr1rBlocationpointer TypeError operation)selfrGr0exs r__init__zPatchOperation.__init__s&%%f-"#HI I i')9)9 :%f-22DM$V,DL# &f-DM 9#// > # 9&'788 9s. B B/ B**B/ctd)zGAbstract method that applies a patch operation to the specified object.z%should implement the patch operation.)NotImplementedError)rHobjs rr5zPatchOperation.applys!"IJJrcZtt|jjSN)hash frozensetrGr(rHs r__hash__zPatchOperation.__hash__sIdnn224566rcVt|tsy|j|jk(SNF)r1r@rGrHothers r__eq__zPatchOperation.__eq__s"%0~~00rc||k( SrOrrVs r__ne__zPatchOperation.__ne__5=!!rcRdj|jjddS)N/)joinrEpartsrRs rrBzPatchOperation.paths"xx **3B/00rc t|jjdS#t$r|jjdcYSwxYw)Nr^)intrEr` ValueErrorrRs rr zPatchOperation.keysE *t||))"-. . *<<%%b) ) *s!$"A A ct||jjd<|jj|_|j|j d<y)Nr^rB)strrEr`rBrDrG)rHr+s rr zPatchOperation.keys=!$U 2 )) !%vrN)rrrrrrJr5rSrXrZpropertyrBr setterrrrr@r@sb1.9#$K71 "11**  ZZ//rr@c"eZdZdZdZdZdZy)RemoveOperationz/Removes an object property or an array element.c|jj|\}} ||=|S#ttf$r!}dj |}t |d}~wwxYw)Nz(can't remove a non-existent object '{0}')rEto_lastKeyError IndexErrorformatr)rHrMsubobjpartrImsgs rr5zRemoveOperation.applys_||++C0  )t  *% )<CCDIC#C( ( )s%AAAcz|j|k(r+|j|k\r|xjdz c_|S|dz}|SNrrBr rHrBr s r_on_undo_removezRemoveOperation._on_undo_removes= 99 xx3A  q rcz|j|k(r+|j|kDr|xjdzc_|S|dz}|Srsrtrus r _on_undo_addzRemoveOperation._on_undo_add= 99 xx#~A  q rNrrrrr5rvrxrrrriris9rric"eZdZdZdZdZdZy) AddOperationz,Adds an object property or an array element.c |jd}|jj |\}}t |t rJ|dk(r|j||S|t|kDs|dkr td|j|||St |tr ||}|S|||<|S|#tdjt|tdj|j|#t$r}tdd}~wwxYw)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})rGrlrrErkr1r r&rrinsertrrFrntyperD)rHrMr+rIrorps rr5zAddOperation.apply s# CNN7+E ||++C0  fo .s{ e$& #F #tax'(FGG dE*  /|  %t  | ; B B4< PQQ'(\(c(cdhdqdqsw(xyy5 C"AC C CsC00 D 9 DD cz|j|k(r+|j|kDr|xjdz c_|S|dz }|Srsrtrus rrvzAddOperation._on_undo_remove)ryrcz|j|k(r+|j|kDr|xjdzc_|S|dz }|Srsrtrus rrxzAddOperation._on_undo_add1ryrNrzrrrr|r|s6@rr|c"eZdZdZdZdZdZy)ReplaceOperationz?Replaces an object property or an array element by a new value.c |jd}|jj |\}}||S|dk(r tdt |t r|t|k\s|dkrtdt |tr ||vrfdj|}t||#tdjt|td j|j||||<|S#t$r}tdd}~wwxYw) Nr+r~rz7'path' with '-' can't be applied to 'replace' operationrzcan't replace outside of listz)can't replace a non-existent object '{0}'rr)rGrlrrErkr1r rrrrnrFrrD)rHrMr+rIrorprqs rr5zReplaceOperation.apply=s CNN7+E ||++C0  <L 3;"#\] ] fo .s6{"dQh'(GHH  /6!AHHN',,| ; B B4< PQQ'(\(c(cdhdqdqsw(xyyt  7 C"AC C CsC22 D ; DD c|SrOrrus rrvz ReplaceOperation._on_undo_remove] rc|SrOrrus rrxzReplaceOperation._on_undo_add`rrNrzrrrrr:sI@rrcfeZdZdZdZedZedZejdZdZ dZ y) MoveOperationz?Moves an object property or an array element to a new location.c t|jd|jr|jd}n|j|jd}|j |\}} ||}|j|k(r|St|tr&|jj|r tdtd|jdd|jj|}td|j|d|jj|}|S#t$r}t dd}~wwxYw#tt f$r}tt|d}~wwxYw) Nfrom.The operation does not contain a 'from' memberz*Cannot move values into their own childrenremoveoprBr/addrrBr+)r1rGr0rlrrkrmrrerErcontainsrir5r|rDrHrMfrom_ptrrIrorpr+s rr5zMoveOperation.applygsg B$..0$2B2BC>>&1++DNN6,BC  '',  -4LE <<8 #J fn - %%h/#$PQ QNN6* '')*/s MM '' )*/s  ; B"@B B B*% -#CG, , -s0AD (D< D9) D44D9<E$ EE$cz|j|jd}dj|jddS)Nrr]r^)r0rGr_r`rHrs r from_pathzMoveOperation.from_paths5##DNN6$:;xxs+,,rc|j|jd} t|jdS#t$r|jdcYSwxYwNrr^)r0rGrbr`rFrs rfrom_keyzMoveOperation.from_keysR##DNN6$:; &x~~b)* * &>>"% % &s8AAc|j|jd}t||jd<|j|jd<yr)r0rGrer`rB)rHr+rs rrzMoveOperation.from_keys?##DNN6$:; Zr!)vrc|j|k(r*|j|k\r|xjdz c_n|dz}|j|k(r+|j|kDr|xjdz c_|S|dz }|SrsrrrBr rus rrvzMoveOperation._on_undo_removesl >>T !}}# " q 99 xx#~A  q rc|j|k(r*|j|kDr|xjdzc_n|dz}|j|k(r+|j|kDr|xjdzc_|S|dz }|Srsrrus rrxzMoveOperation._on_undo_addsl >>T !}}s" " q 99 xx#~A  q rN) rrrrr5rfrrrgrvrxrrrrrdsUI#J--&&__//  rrceZdZdZdZy) TestOperationz!Test value by specified location.c  |jj|\}}||}n|jj||} |j d}||k7r1d}t |j|t||t||S#t$r}t t |d}~wwxYw#t$r}tdd}~wwxYw)Nr+r~z0{0} ({1}) is not equal to tested value {2} ({3})) rErkwalkrrrerGrlrrnr)rHrMrorpvalrIr+rqs rr5zTestOperation.applys /<<//4LFD|ll''5 CNN7+E %<DC%cjjd3i16U 'EF F $ /%c"g. . /  C"AC C Cs/?B B. B+B&&B+. C7 CCNrrrrr5rrrrrs +rrceZdZdZdZy) CopyOperationzA Copies an object property or an array element to a new location c |j|jd}|j |\}} t j ||}td|j|d|jj|}|S#t$r}tdd}~wwxYw#ttf$r}tt|d}~wwxYw)Nrrrrr/) r0rGrlrrkcopydeepcopyrmrrer|rDr5rs rr5zCopyOperation.applys B''v(>?H  '',  -MM&,/EMM '' )*/s  ! B"@B B B*% -#CG, , -s.BB B BBC.CCNrrrrrrs Krrc eZdZeej ZeeZe e e e e eedZ efdZdZdZeZdZdZdZdZed efd Zed d efd Zdd ZedZddZ dZ!y )r3)rrreplacemovetestrcd||_||_|jD]}|j|yrO)r7r0_get_operation)rHr7r0rs rrJzJsonPatch.__init__(s4 & ** $B    # $rc"|jS)zstr(self) -> self.to_string()) to_stringrRs r__str__zJsonPatch.__str__3s~~rc,t|jSrO)boolr7rRs r__bool__zJsonPatch.__bool__7DJJrc,t|jSrO)iterr7rRs r__iter__zJsonPatch.__iter__<rrc>tt|jSrO)rPtuple_opsrRs rrSzJsonPatch.__hash__?sE$))$%%rcVt|tsy|j|jk(SrU)r1r3rrVs rrXzJsonPatch.__eq__Bs"%+yyEJJ&&rc||k( SrOrrVs rrZzJsonPatch.__ne__Gr[rNcF|xs |j}||}|||S)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_strloadsr0rr7s rr4zJsonPatch.from_stringJs) .s I&5k22rTc|xs |j}t||||}|jdd||t|j }|||S)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_valuesr%execute) rr<r= optimizationdumpsr0rbuilderopss rr;zJsonPatch.from_diff^sT>.s c3 MD#s37??$%3K00rcF|xs |j}||jS)z!Returns patch set as JSON string.)rr7)rHrrs rrzJsonPatch.to_strings!/t// 4::&&rcTtt|j|jSrO)rmaprr7rRs rrzJsonPatch._opssS,,djj9::rcx|stj|}|jD]}|j|}|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`. )rrrr5)rHrMr8rGs rr5zJsonPatch.applys=--$C 'I//#&C ' rcd|vr td|d}t|ts td||jvrtdj ||j|}|||j S)Nrz&Operation does not contain 'op' memberzOperation must be a stringzUnknown operation {0!r}r/)rr1r2 operationsrnr0)rHrGrrs rrzJsonPatch._get_operationsy y "#KL L t_"j)"#?@ @ T__ $"#<#C#CB#GH Hoob!9$*:*:;;rrO)F)"rrr staticmethodjsonrr _jsonloadsrrrir|rrrrrrrJrr __nonzero__rrSrXrZ classmethodr4r;rrfrr5rrrrr3r3stzz*Kz*K!!# #J,Z+6 $  K &' "*.K33&(,D#"1"1H' ;;*  ?s(A A )A98A9c>|t|f} |j|j|}|r|jSy#t$rS|j |}t t|dz ddD]%}||d|k(s|j|dccYSYywxYw)Nrr^r)rrrpoprFrranger)rHr+rrrris r take_indexzDiffBuilder.take_indexsDK(  -''+// :Fzz|# -))"-G3w<>2r2 -1:a=I-";;q>!,, - -s/A?BBBBcH|j}|d}|||gx|d<|d<|dS)Nrrr)rHrrlasts rrzDiffBuilder.inserts6{{Aw!4,,Q$q'Awrc.|\}}}||d<||d<g|ddy)Nrrr)rHr link_prev link_next_s rrzDiffBuilder.removes)"' 9a !  ! arc#ZK|j}|d}||ur|d|d}||uryywNrr)rHstartrcurrs r iter_fromzDiffBuilder.iter_froms<{{Qx$q'M7D$&++c#ZK|j}|d}||ur|d|d}||uryywrr)rHrrs rrzDiffBuilder.__iter__s<{{Aw$q'M7D$rc#K|j}|d}||ur|d|ur|d|dd}}|j|jk(rkt|tk(rYt|tk(rGt d|j|j dd|jj |dd}|dj |d}||uryyw)Nrrrr+rr/)rrDrrir|rrGr0)rHrrop_first op_seconds rrzDiffBuilder.executes{{Aw$Awd"&*1gtAwqz)$$ (:(::X/9Y<7*' ) 2 2!*!4!4W!=,$(#3#3 56?Y ?  71:Dq'## #7D$s CC  C c|j|t}||d}t|jtk(rSt|tk(rA|j |D]-}|j |j|j|_/|j||jt||k7rAtd|jt||d|j}|j|yytdt|||d|j}|j|}|j||t y)NrrrrrBr/rr)r _ST_REMOVErr rbrrvrBrrD _path_joinrr0rr|r_ST_ADD) rHrBr itemrrvnew_op new_indexs r _item_addedzDiffBuilder._item_addeds"j1  qBBFF|s"tCyC'7.@A..rww?BF@ KK {{js33& KK&tS1( $// 1  F# 4""4-# ++ -F  F+I   T9g 6rctdt||d|j}|j|t}|j |}||d}|j j|jd}t|tk(rA|j|D]-} | j|j|j|_/|j||j |j k7r5t#d|j |j d|j}||d<y|j|y|j%||t&y)Nrrr/rrrr)rirr0rrrrErkrrr%rrxrBr rrDrrr) rHrBr r r rr r added_itemr s r _item_removedzDiffBuilder._item_removeds, tS)" '')g.KK'  qB ++DLL9! 6CW}s8SXS#:^4sN3'' 4(=sCH_5"38'' 4(=sCH&&tS#6$$T347"""4#c(;  sCH5- 6rcjt|tr.t|tr|jt||||yt|tr.t|tr|j t||||y|j ||j |k(ry|j|||yrO)r1rrrr rrr)rHrBr r<r=s rrzDiffBuilder._compare_valuesqs c> *3/    4 5sC @ _ -30    4 5sC @ZZ_ 3 /    c3 /rN)rrrrrrrJrrrrrrrr rrrrrrrrrrsS/3zz{% ? -  (72:B* @680rrcl||S|dzt|jddjddzS)Nr]~z~0z~1)rerrts rrrs9 { #:C((d3;;CF FFr)4r __future__rr#r functoolsrsystypesr ImportErrorr' jsonpointerrrrrcollections.abcrr unicodere __author__ __version__ __website__ __license__ version_infobytesr2 Exceptionr rrAssertionErrorrr,partialrrr9r>objectr@rir|rrrrr3rrrrrr:sB&'  & :   ?0  @ $ vJ$$7)7*$,n$  Y  tzzY G &+ %&P&1B03/V3/ln<1>1h'~'TSNSlN6N2@<@