3 Gã\D&ã@s dZddlmZdZdZdZdZyddlmZe Z Wne k rLe ZYnXyddl mZmZWn$e k r†ddlmZmZYnXdd lmZdd lZdd lZeƒZdd d „Zefdd„Zdd„ZGdd„deƒZGdd„deƒZGdd„deƒZdd„Zdd„Zd S)z7 Identify specific nodes in a JSON document (RFC 6901) é)Úunicode_literalsu Stefan Kögl z2.0z2https://github.com/stefankoegl/python-json-pointerzModified BSD License)Úizip)ÚMappingÚSequence)ÚteeNTcCst|ƒ}|j|||ƒS)a¼Resolves pointer against doc and sets the value of the target within doc. With inplace set to true, doc is modified as long as pointer is not the root. >>> obj = {'foo': {'anArray': [ {'prop': 44}], 'another prop': {'baz': 'A string' }}} >>> set_pointer(obj, '/foo/anArray/0/prop', 55) == {'foo': {'another prop': {'baz': 'A string'}, 'anArray': [{'prop': 55}]}} True >>> set_pointer(obj, '/foo/yet another prop', 'added prop') == {'foo': {'another prop': {'baz': 'A string'}, 'yet another prop': 'added prop', 'anArray': [{'prop': 55}]}} True >>> obj = {'foo': {}} >>> set_pointer(obj, '/foo/a%20b', 'x') == {'foo': {'a%20b': 'x' }} True )Ú JsonPointerÚset)ÚdocÚpointerÚvalueÚinplace©r úh/private/var/folders/pf/wv4htv3x0qs2c2mp0dnn0kchsvlck3/T/pip-install-emcbgzcf/jsonpointer/jsonpointer.pyÚ set_pointer?srcCst|ƒ}|j||ƒS)aa Resolves pointer against doc and returns the referenced object >>> obj = {'foo': {'anArray': [ {'prop': 44}], 'another prop': {'baz': 'A string' }}, 'a%20b': 1, 'c d': 2} >>> resolve_pointer(obj, '') == obj True >>> resolve_pointer(obj, '/foo') == obj['foo'] True >>> resolve_pointer(obj, '/foo/another prop') == obj['foo']['another prop'] True >>> resolve_pointer(obj, '/foo/another prop/baz') == obj['foo']['another prop']['baz'] True >>> resolve_pointer(obj, '/foo/anArray/0') == obj['foo']['anArray'][0] True >>> resolve_pointer(obj, '/some/path', None) == None True >>> resolve_pointer(obj, '/a b', None) == None True >>> resolve_pointer(obj, '/a%20b') == 1 True >>> resolve_pointer(obj, '/c d') == 2 True >>> resolve_pointer(obj, '/c%20d', None) == None True )rÚresolve)r r Údefaultr r rÚresolve_pointerYs$rcCs&t|ƒ\}}x|D]}PqWt||ƒS)zñ Transforms a list to a list of tuples of adjacent items s -> (s0,s1), (s1,s2), (s2, s3), ... >>> list(pairwise([])) [] >>> list(pairwise([1])) [] >>> list(pairwise([1, 2, 3, 4])) [(1, 2), (2, 3), (3, 4)] )rr)ÚiterableÚaÚbÚ_r r rÚpairwise�s  rc@s eZdZdS)ÚJsonPointerExceptionN)Ú__name__Ú __module__Ú __qualname__r r r rr•src@s eZdZdZdd„Zdd„ZdS)Ú EndOfListz)Result of accessing element "-" of a listcCs ||_dS)N)Úlist_)Úselfrr r rÚ__init__œszEndOfList.__init__cCsdj|jjt|jƒd�S)Nz {cls}({lst}))ÚclsÚlst)ÚformatÚ __class__rÚreprr)rr r rÚ__repr__Ÿs zEndOfList.__repr__N)rrrÚ__doc__rr%r r r rr™src@s–eZdZdZejdƒZejdƒZdd„Zdd„Z e fdd „Z e Z dd d „Z d d„Zdd„Zdd„Zdd„Zedd„ƒZdd„Zdd„Zedd„ƒZdS)rz;A JSON Pointer that can reference parts of an JSON documentz0|[1-9][0-9]*$z (~[^01]|~$)cCsZ|jj|ƒ}|r"tdj|jƒƒƒ‚|jdƒ}|jdƒdkrBtdƒ‚dd„|Dƒ}||_dS)NzFound invalid escape {}ú/rÚzlocation must starts with /cSsg|] }t|ƒ‘qSr )Úunescape)Ú.0Úpartr r rú ¸sz(JsonPointer.__init__..)Ú_RE_INVALID_ESCAPEÚsearchrr"ÚgroupÚsplitÚpopÚparts)rr Zinvalid_escaper2r r rr¬s   zJsonPointer.__init__cCsH|js|dfSx"|jdd…D]}|j||ƒ}qW||j||jdƒfS)z>Resolves ptr until the last step, returns (sub-doc, last-step)Nééÿÿÿÿr4)r2ÚwalkÚget_part)rr r+r r rÚto_last»s zJsonPointer.to_lastc CsJxD|jD]:}y|j||ƒ}Wqtk r@|tkr8‚n|SYqXqW|S)zBResolves the pointer against doc and returns the referenced object)r2r5rÚ_nothing)rr rr+r r rrÆs zJsonPointer.resolveTcCsFt|jƒdkr|rtdƒ‚|S|s,tj|ƒ}|j|ƒ\}}|||<|S)zFResolve the pointer against the doc and replace the target with value.rzcannot set root in place)Úlenr2rÚcopyÚdeepcopyr7)rr r r Úparentr+r r rr×s zJsonPointer.setcCsjt|tƒr|St|tƒrH|dkr$|S|jjt|ƒƒs@td|ƒ‚t|ƒSt|dƒrV|Stdt |ƒƒ‚dS)z)Returns the next step in the correct typeú-z"'%s' is not a valid sequence indexÚ __getitem__zXDocument '%s' does not support indexing, must be mapping/sequence or support __getitem__N) Ú isinstancerrÚ_RE_ARRAY_INDEXÚmatchÚstrrÚintÚhasattrÚtype)rr r+r r rr6çs    zJsonPointer.get_partcCs |j||ƒ}t|dƒs(tdt|ƒfƒ‚t|tƒrn|dkrBt|ƒSy||Stk rltd|fƒ‚YnXy||St k rštd||fƒ‚YnXdS)z7 Walks one step in doc and returns the referenced part r>zinvalid document type %sr=zindex '%s' is out of boundszmember '%s' not found in %sN) r6rDÚAssertionErrorrEr?rrÚ IndexErrorrÚKeyError)rr r+r r rr5s  zJsonPointer.walkcCs|jdt|jƒ…|jkS)z- Returns True if self contains the given ptr N)r2r9)rÚptrr r rÚcontainsszJsonPointer.containscCs |j|ƒS)z- Returns True if self contains the given ptr )rJ)rÚitemr r rÚ __contains__szJsonPointer.__contains__cCs$dd„|jDƒ}djdd„|DƒƒS)zwReturns the string representation of the pointer >>> ptr = JsonPointer('/~0/0/~1').path == '/~0/0/~1' cSsg|] }t|ƒ‘qSr )Úescape)r*r+r r rr,(sz$JsonPointer.path..r(css|]}d|VqdS)r'Nr )r*r+r r rú )sz#JsonPointer.path..)r2Újoin)rr2r r rÚpath"szJsonPointer.pathcCst|tƒsdS|j|jkS)aCompares a pointer to another object Pointers can be compared by comparing their strings (or splitted strings), because no two different parts can point to the same structure in an object (eg no different number representations) F)r?rr2)rÚotherr r rÚ__eq__+s zJsonPointer.__eq__cCstt|jƒƒS)N)ÚhashÚtupler2)rr r rÚ__hash__8szJsonPointer.__hash__cCs*dd„|Dƒ}|djdd„|Dƒƒƒ}|S)zœConstructs a JsonPointer from a list of (unescaped) paths >>> JsonPointer.from_parts(['a', '~', '/', 0]).path == '/a/~0/~1/0' True cSsg|]}tt|ƒƒ‘qSr )rMrB)r*r+r r rr,Bsz*JsonPointer.from_parts..r(css|]}d|VqdS)r'Nr )r*r+r r rrNCsz)JsonPointer.from_parts..)rO)r r2rIr r rÚ from_parts;szJsonPointer.from_partsN)T)rrrr&ÚreÚcompiler@r-rr7r8rÚgetrr6r5rJrLÚpropertyrPrRrUÚ classmethodrVr r r rr¤s       rcCs|jddƒjddƒS)Nú~z~0r'z~1)Úreplace)Úsr r rrMGsrMcCs|jddƒjddƒS)Nz~1r'z~0r\)r])r^r r rr)Jsr))T)r&Ú __future__rÚ __author__Ú __version__Z __website__Ú __license__Ú itertoolsrÚunicoderBÚ ImportErrorÚzipÚcollections.abcrrÚ collectionsrrWr:Úobjectr8rrrÚ ExceptionrrrrMr)r r r rÚ!s6      ( $