davidtran999 commited on
Commit
e0413d9
·
verified ·
1 Parent(s): a58d8b2

Upload backend/venv/lib/python3.10/site-packages/jsonpointer.py with huggingface_hub

Browse files
backend/venv/lib/python3.10/site-packages/jsonpointer.py ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # python-json-pointer - An implementation of the JSON Pointer syntax
4
+ # https://github.com/stefankoegl/python-json-pointer
5
+ #
6
+ # Copyright (c) 2011 Stefan Kögl <stefan@skoegl.net>
7
+ # All rights reserved.
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions
11
+ # are met:
12
+ #
13
+ # 1. Redistributions of source code must retain the above copyright
14
+ # notice, this list of conditions and the following disclaimer.
15
+ # 2. Redistributions in binary form must reproduce the above copyright
16
+ # notice, this list of conditions and the following disclaimer in the
17
+ # documentation and/or other materials provided with the distribution.
18
+ # 3. The name of the author may not be used to endorse or promote products
19
+ # derived from this software without specific prior written permission.
20
+ #
21
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24
+ # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26
+ # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30
+ # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+
33
+ """ Identify specific nodes in a JSON document (RFC 6901) """
34
+
35
+ # Will be parsed by setup.py to determine package metadata
36
+ __author__ = 'Stefan Kögl <stefan@skoegl.net>'
37
+ __version__ = '3.0.0'
38
+ __website__ = 'https://github.com/stefankoegl/python-json-pointer'
39
+ __license__ = 'Modified BSD License'
40
+
41
+ import copy
42
+ import re
43
+ from collections.abc import Mapping, Sequence
44
+ from itertools import tee, chain
45
+
46
+ _nothing = object()
47
+
48
+
49
+ def set_pointer(doc, pointer, value, inplace=True):
50
+ """Resolves a pointer against doc and sets the value of the target within doc.
51
+
52
+ With inplace set to true, doc is modified as long as pointer is not the
53
+ root.
54
+
55
+ >>> obj = {'foo': {'anArray': [ {'prop': 44}], 'another prop': {'baz': 'A string' }}}
56
+
57
+ >>> set_pointer(obj, '/foo/anArray/0/prop', 55) == \
58
+ {'foo': {'another prop': {'baz': 'A string'}, 'anArray': [{'prop': 55}]}}
59
+ True
60
+
61
+ >>> set_pointer(obj, '/foo/yet another prop', 'added prop') == \
62
+ {'foo': {'another prop': {'baz': 'A string'}, 'yet another prop': 'added prop', 'anArray': [{'prop': 55}]}}
63
+ True
64
+
65
+ >>> obj = {'foo': {}}
66
+ >>> set_pointer(obj, '/foo/a%20b', 'x') == \
67
+ {'foo': {'a%20b': 'x' }}
68
+ True
69
+ """
70
+
71
+ pointer = JsonPointer(pointer)
72
+ return pointer.set(doc, value, inplace)
73
+
74
+
75
+ def resolve_pointer(doc, pointer, default=_nothing):
76
+ """ Resolves pointer against doc and returns the referenced object
77
+
78
+ >>> obj = {'foo': {'anArray': [ {'prop': 44}], 'another prop': {'baz': 'A string' }}, 'a%20b': 1, 'c d': 2}
79
+
80
+ >>> resolve_pointer(obj, '') == obj
81
+ True
82
+
83
+ >>> resolve_pointer(obj, '/foo') == obj['foo']
84
+ True
85
+
86
+ >>> resolve_pointer(obj, '/foo/another prop') == obj['foo']['another prop']
87
+ True
88
+
89
+ >>> resolve_pointer(obj, '/foo/another prop/baz') == obj['foo']['another prop']['baz']
90
+ True
91
+
92
+ >>> resolve_pointer(obj, '/foo/anArray/0') == obj['foo']['anArray'][0]
93
+ True
94
+
95
+ >>> resolve_pointer(obj, '/some/path', None) == None
96
+ True
97
+
98
+ >>> resolve_pointer(obj, '/a b', None) == None
99
+ True
100
+
101
+ >>> resolve_pointer(obj, '/a%20b') == 1
102
+ True
103
+
104
+ >>> resolve_pointer(obj, '/c d') == 2
105
+ True
106
+
107
+ >>> resolve_pointer(obj, '/c%20d', None) == None
108
+ True
109
+ """
110
+
111
+ pointer = JsonPointer(pointer)
112
+ return pointer.resolve(doc, default)
113
+
114
+
115
+ def pairwise(iterable):
116
+ """ Transforms a list to a list of tuples of adjacent items
117
+
118
+ s -> (s0,s1), (s1,s2), (s2, s3), ...
119
+
120
+ >>> list(pairwise([]))
121
+ []
122
+
123
+ >>> list(pairwise([1]))
124
+ []
125
+
126
+ >>> list(pairwise([1, 2, 3, 4]))
127
+ [(1, 2), (2, 3), (3, 4)]
128
+ """
129
+ a, b = tee(iterable)
130
+ for _ in b:
131
+ break
132
+ return zip(a, b)
133
+
134
+
135
+ class JsonPointerException(Exception):
136
+ pass
137
+
138
+
139
+ class EndOfList(object):
140
+ """Result of accessing element "-" of a list"""
141
+
142
+ def __init__(self, list_):
143
+ self.list_ = list_
144
+
145
+ def __repr__(self):
146
+ return '{cls}({lst})'.format(cls=self.__class__.__name__,
147
+ lst=repr(self.list_))
148
+
149
+
150
+ class JsonPointer(object):
151
+ """A JSON Pointer that can reference parts of a JSON document"""
152
+
153
+ # Array indices must not contain:
154
+ # leading zeros, signs, spaces, decimals, etc
155
+ _RE_ARRAY_INDEX = re.compile('0|[1-9][0-9]*$')
156
+ _RE_INVALID_ESCAPE = re.compile('(~[^01]|~$)')
157
+
158
+ def __init__(self, pointer):
159
+
160
+ # validate escapes
161
+ invalid_escape = self._RE_INVALID_ESCAPE.search(pointer)
162
+ if invalid_escape:
163
+ raise JsonPointerException('Found invalid escape {}'.format(
164
+ invalid_escape.group()))
165
+
166
+ parts = pointer.split('/')
167
+ if parts.pop(0) != '':
168
+ raise JsonPointerException('Location must start with /')
169
+
170
+ parts = [unescape(part) for part in parts]
171
+ self.parts = parts
172
+
173
+ def to_last(self, doc):
174
+ """Resolves ptr until the last step, returns (sub-doc, last-step)"""
175
+
176
+ if not self.parts:
177
+ return doc, None
178
+
179
+ for part in self.parts[:-1]:
180
+ doc = self.walk(doc, part)
181
+
182
+ return doc, JsonPointer.get_part(doc, self.parts[-1])
183
+
184
+ def resolve(self, doc, default=_nothing):
185
+ """Resolves the pointer against doc and returns the referenced object"""
186
+
187
+ for part in self.parts:
188
+
189
+ try:
190
+ doc = self.walk(doc, part)
191
+ except JsonPointerException:
192
+ if default is _nothing:
193
+ raise
194
+ else:
195
+ return default
196
+
197
+ return doc
198
+
199
+ get = resolve
200
+
201
+ def set(self, doc, value, inplace=True):
202
+ """Resolve the pointer against the doc and replace the target with value."""
203
+
204
+ if len(self.parts) == 0:
205
+ if inplace:
206
+ raise JsonPointerException('Cannot set root in place')
207
+ return value
208
+
209
+ if not inplace:
210
+ doc = copy.deepcopy(doc)
211
+
212
+ (parent, part) = self.to_last(doc)
213
+
214
+ if isinstance(parent, Sequence) and part == '-':
215
+ parent.append(value)
216
+ else:
217
+ parent[part] = value
218
+
219
+ return doc
220
+
221
+ @classmethod
222
+ def get_part(cls, doc, part):
223
+ """Returns the next step in the correct type"""
224
+
225
+ if isinstance(doc, Mapping):
226
+ return part
227
+
228
+ elif isinstance(doc, Sequence):
229
+
230
+ if part == '-':
231
+ return part
232
+
233
+ if not JsonPointer._RE_ARRAY_INDEX.match(str(part)):
234
+ raise JsonPointerException("'%s' is not a valid sequence index" % part)
235
+
236
+ return int(part)
237
+
238
+ elif hasattr(doc, '__getitem__'):
239
+ # Allow indexing via ducktyping
240
+ # if the target has defined __getitem__
241
+ return part
242
+
243
+ else:
244
+ raise JsonPointerException("Document '%s' does not support indexing, "
245
+ "must be mapping/sequence or support __getitem__" % type(doc))
246
+
247
+ def get_parts(self):
248
+ """Returns the list of the parts. For example, JsonPointer('/a/b').get_parts() == ['a', 'b']"""
249
+
250
+ return self.parts
251
+
252
+ def walk(self, doc, part):
253
+ """ Walks one step in doc and returns the referenced part """
254
+
255
+ part = JsonPointer.get_part(doc, part)
256
+
257
+ assert hasattr(doc, '__getitem__'), "invalid document type %s" % (type(doc),)
258
+
259
+ if isinstance(doc, Sequence):
260
+ if part == '-':
261
+ return EndOfList(doc)
262
+
263
+ try:
264
+ return doc[part]
265
+
266
+ except IndexError:
267
+ raise JsonPointerException("index '%s' is out of bounds" % (part,))
268
+
269
+ # Else the object is a mapping or supports __getitem__(so assume custom indexing)
270
+ try:
271
+ return doc[part]
272
+
273
+ except KeyError:
274
+ raise JsonPointerException("member '%s' not found in %s" % (part, doc))
275
+
276
+ def contains(self, ptr):
277
+ """ Returns True if self contains the given ptr """
278
+ return self.parts[:len(ptr.parts)] == ptr.parts
279
+
280
+ def __contains__(self, item):
281
+ """ Returns True if self contains the given ptr """
282
+ return self.contains(item)
283
+
284
+ def join(self, suffix):
285
+ """ Returns a new JsonPointer with the given suffix append to this ptr """
286
+ if isinstance(suffix, JsonPointer):
287
+ suffix_parts = suffix.parts
288
+ elif isinstance(suffix, str):
289
+ suffix_parts = JsonPointer(suffix).parts
290
+ else:
291
+ suffix_parts = suffix
292
+ try:
293
+ return JsonPointer.from_parts(chain(self.parts, suffix_parts))
294
+ except: # noqa E722
295
+ raise JsonPointerException("Invalid suffix")
296
+
297
+ def __truediv__(self, suffix): # Python 3
298
+ return self.join(suffix)
299
+
300
+ @property
301
+ def path(self):
302
+ """Returns the string representation of the pointer
303
+
304
+ >>> ptr = JsonPointer('/~0/0/~1').path == '/~0/0/~1'
305
+ """
306
+ parts = [escape(part) for part in self.parts]
307
+ return ''.join('/' + part for part in parts)
308
+
309
+ def __eq__(self, other):
310
+ """Compares a pointer to another object
311
+
312
+ Pointers can be compared by comparing their strings (or splitted
313
+ strings), because no two different parts can point to the same
314
+ structure in an object (eg no different number representations)
315
+ """
316
+
317
+ if not isinstance(other, JsonPointer):
318
+ return False
319
+
320
+ return self.parts == other.parts
321
+
322
+ def __hash__(self):
323
+ return hash(tuple(self.parts))
324
+
325
+ def __str__(self):
326
+ return self.path
327
+
328
+ def __repr__(self):
329
+ return type(self).__name__ + "(" + repr(self.path) + ")"
330
+
331
+ @classmethod
332
+ def from_parts(cls, parts):
333
+ """Constructs a JsonPointer from a list of (unescaped) paths
334
+
335
+ >>> JsonPointer.from_parts(['a', '~', '/', 0]).path == '/a/~0/~1/0'
336
+ True
337
+ """
338
+ parts = [escape(str(part)) for part in parts]
339
+ ptr = cls(''.join('/' + part for part in parts))
340
+ return ptr
341
+
342
+
343
+ def escape(s):
344
+ return s.replace('~', '~0').replace('/', '~1')
345
+
346
+
347
+ def unescape(s):
348
+ return s.replace('~1', '/').replace('~0', '~')