jsonpointer 3.2.1__py3-none-any.whl → 3.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jsonpointer-3.2.1.data → jsonpointer-3.4.data}/scripts/jsonpointer +14 -3
- {jsonpointer-3.2.1.dist-info → jsonpointer-3.4.dist-info}/METADATA +1 -1
- jsonpointer-3.4.dist-info/RECORD +8 -0
- jsonpointer.py +69 -10
- jsonpointer-3.2.1.dist-info/RECORD +0 -8
- {jsonpointer-3.2.1.dist-info → jsonpointer-3.4.dist-info}/WHEEL +0 -0
- {jsonpointer-3.2.1.dist-info → jsonpointer-3.4.dist-info}/licenses/AUTHORS +0 -0
- {jsonpointer-3.2.1.dist-info → jsonpointer-3.4.dist-info}/licenses/LICENSE.txt +0 -0
- {jsonpointer-3.2.1.dist-info → jsonpointer-3.4.dist-info}/top_level.txt +0 -0
|
@@ -27,6 +27,8 @@ parser.add_argument('FILE', type=str, nargs='+',
|
|
|
27
27
|
help='Files for which the pointer should be resolved')
|
|
28
28
|
parser.add_argument('--indent', type=int, default=None,
|
|
29
29
|
help='Indent output by n spaces')
|
|
30
|
+
parser.add_argument('--continue-on-error', action='store_true',
|
|
31
|
+
help='Continue with remaining files after JSON or text decoding errors')
|
|
30
32
|
parser.add_argument('-v', '--version', action='version',
|
|
31
33
|
version='%(prog)s ' + jsonpointer.__version__)
|
|
32
34
|
|
|
@@ -77,8 +79,8 @@ def parse_pointer(args):
|
|
|
77
79
|
def resolve_files():
|
|
78
80
|
""" Resolve a JSON pointer on JSON files
|
|
79
81
|
|
|
80
|
-
Returns False if the pointer could not be resolved on at least one
|
|
81
|
-
|
|
82
|
+
Returns False if the pointer could not be resolved on at least one file,
|
|
83
|
+
or if --continue-on-error skipped a JSON or text decoding error. """
|
|
82
84
|
args = parser.parse_args()
|
|
83
85
|
|
|
84
86
|
ptr, files = parse_pointer(args)
|
|
@@ -90,7 +92,16 @@ def resolve_files():
|
|
|
90
92
|
except argparse.ArgumentTypeError as e:
|
|
91
93
|
parser.error(str(e))
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
try:
|
|
96
|
+
doc = json.load(f)
|
|
97
|
+
except (json.JSONDecodeError, UnicodeDecodeError) as e:
|
|
98
|
+
if not args.continue_on_error:
|
|
99
|
+
raise
|
|
100
|
+
print('Could not parse JSON in %r: %s' % (name, e),
|
|
101
|
+
file=sys.stderr)
|
|
102
|
+
ok = False
|
|
103
|
+
continue
|
|
104
|
+
|
|
94
105
|
try:
|
|
95
106
|
result = jsonpointer.resolve_pointer(doc, ptr)
|
|
96
107
|
print(json.dumps(result, indent=args.indent))
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
jsonpointer.py,sha256=HRi-qytUqsZMCDOUDddMQC4qojDzk75X0PUZZfz20U4,13792
|
|
2
|
+
jsonpointer-3.4.data/scripts/jsonpointer,sha256=aMNUGc0Tro2UnAFF_k3NKKnOovSVBJ8ZOpigcaow97M,3545
|
|
3
|
+
jsonpointer-3.4.dist-info/licenses/AUTHORS,sha256=TVgxnQ9ZyHvvWwez_k2w8ZwtfVVFsDTGv3tXyJu-9X8,113
|
|
4
|
+
jsonpointer-3.4.dist-info/licenses/LICENSE.txt,sha256=2LJPFdRyiF94ii1umFhQ8mRie4YBKhe7JCyD8xDZB-U,1413
|
|
5
|
+
jsonpointer-3.4.dist-info/METADATA,sha256=bVrbJCJq3CdnPkG40Lb9IvATuFjOxqeigYRUByV97dU,2638
|
|
6
|
+
jsonpointer-3.4.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
7
|
+
jsonpointer-3.4.dist-info/top_level.txt,sha256=BsUcar_C0nZzPGV2ackrJ9CpVU8_0W_pHYKwpdnWddM,12
|
|
8
|
+
jsonpointer-3.4.dist-info/RECORD,,
|
jsonpointer.py
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
# Will be parsed by setup.py to determine package metadata
|
|
34
34
|
__author__ = 'Stefan Kögl <stefan@skoegl.net>'
|
|
35
|
-
__version__ = '3.
|
|
35
|
+
__version__ = '3.4'
|
|
36
36
|
__website__ = 'https://github.com/stefankoegl/python-json-pointer'
|
|
37
37
|
__license__ = 'Modified BSD License'
|
|
38
38
|
|
|
@@ -48,12 +48,17 @@ _nothing = object()
|
|
|
48
48
|
VERBOSE_EXCEPTIONS = True
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
def set_pointer(doc, pointer, value, inplace=True):
|
|
51
|
+
def set_pointer(doc, pointer, value, inplace=True, create=False):
|
|
52
52
|
"""Resolves a pointer against doc and sets the value of the target within doc.
|
|
53
53
|
|
|
54
54
|
With inplace set to true, doc is modified as long as pointer is not the
|
|
55
55
|
root.
|
|
56
56
|
|
|
57
|
+
With create set to true, missing intermediate members are created as
|
|
58
|
+
dicts instead of raising a JsonPointerException. A missing intermediate
|
|
59
|
+
array element can be created by referencing the end of the array, either
|
|
60
|
+
with "-" or with an index equal to the length of the array.
|
|
61
|
+
|
|
57
62
|
>>> obj = {'foo': {'anArray': [ {'prop': 44}], 'another prop': {'baz': 'A string' }}}
|
|
58
63
|
|
|
59
64
|
>>> set_pointer(obj, '/foo/anArray/0/prop', 55) == \
|
|
@@ -68,10 +73,14 @@ def set_pointer(doc, pointer, value, inplace=True):
|
|
|
68
73
|
>>> set_pointer(obj, '/foo/a%20b', 'x') == \
|
|
69
74
|
{'foo': {'a%20b': 'x' }}
|
|
70
75
|
True
|
|
76
|
+
|
|
77
|
+
>>> set_pointer({}, '/cat/name', 'whiskers', create=True) == \
|
|
78
|
+
{'cat': {'name': 'whiskers'}}
|
|
79
|
+
True
|
|
71
80
|
"""
|
|
72
81
|
|
|
73
82
|
pointer = JsonPointer(pointer)
|
|
74
|
-
return pointer.set(doc, value, inplace)
|
|
83
|
+
return pointer.set(doc, value, inplace, create)
|
|
75
84
|
|
|
76
85
|
|
|
77
86
|
def resolve_pointer(doc, pointer, default=_nothing):
|
|
@@ -200,8 +209,11 @@ class JsonPointer:
|
|
|
200
209
|
|
|
201
210
|
get = resolve
|
|
202
211
|
|
|
203
|
-
def set(self, doc, value, inplace=True):
|
|
204
|
-
"""Resolve the pointer against the doc and replace the target with value.
|
|
212
|
+
def set(self, doc, value, inplace=True, create=False):
|
|
213
|
+
"""Resolve the pointer against the doc and replace the target with value.
|
|
214
|
+
|
|
215
|
+
With create set to true, missing intermediate members are created as
|
|
216
|
+
dicts (see set_pointer)."""
|
|
205
217
|
|
|
206
218
|
if len(self.parts) == 0:
|
|
207
219
|
if inplace:
|
|
@@ -211,20 +223,67 @@ class JsonPointer:
|
|
|
211
223
|
if not inplace:
|
|
212
224
|
doc = copy.deepcopy(doc)
|
|
213
225
|
|
|
214
|
-
|
|
226
|
+
if create:
|
|
227
|
+
parent = doc
|
|
228
|
+
for i, part in enumerate(self.parts[:-1]):
|
|
229
|
+
part = self._get_create_part(parent, part)
|
|
230
|
+
if self._is_missing(parent, part):
|
|
231
|
+
# Everything below this point is new, so build the
|
|
232
|
+
# missing structure detached and attach it in one step.
|
|
233
|
+
# This leaves doc unchanged if anything goes wrong.
|
|
234
|
+
child = value
|
|
235
|
+
for missing in reversed(self.parts[i + 1:]):
|
|
236
|
+
child = {missing: child}
|
|
237
|
+
self._set_child(parent, part, child)
|
|
238
|
+
return doc
|
|
239
|
+
parent = self.walk(parent, part)
|
|
240
|
+
part = self._get_create_part(parent, self.parts[-1])
|
|
241
|
+
else:
|
|
242
|
+
(parent, part) = self.to_last(doc)
|
|
243
|
+
|
|
244
|
+
self._set_child(parent, part, value)
|
|
245
|
+
return doc
|
|
246
|
+
|
|
247
|
+
@classmethod
|
|
248
|
+
def _get_create_part(cls, doc, part):
|
|
249
|
+
"""Like get_part, but maps an index just past the end of a sequence
|
|
250
|
+
to "-" so that it is appended"""
|
|
251
|
+
|
|
252
|
+
part = cls.get_part(doc, part)
|
|
253
|
+
if isinstance(doc, Sequence) and part == len(doc):
|
|
254
|
+
return '-'
|
|
255
|
+
return part
|
|
256
|
+
|
|
257
|
+
@staticmethod
|
|
258
|
+
def _is_missing(doc, part):
|
|
259
|
+
"""Returns True if part does not exist in doc but could be added"""
|
|
260
|
+
|
|
261
|
+
if isinstance(doc, Mapping):
|
|
262
|
+
return part not in doc
|
|
263
|
+
|
|
264
|
+
if isinstance(doc, Sequence) and not isinstance(doc, str):
|
|
265
|
+
return part == '-'
|
|
266
|
+
|
|
267
|
+
return False
|
|
268
|
+
|
|
269
|
+
@staticmethod
|
|
270
|
+
def _set_child(parent, part, value):
|
|
271
|
+
"""Sets parent[part] to value, appending for the end of a sequence"""
|
|
215
272
|
|
|
216
273
|
if isinstance(parent, str):
|
|
217
274
|
raise JsonPointerException("Cannot set value in a string")
|
|
218
275
|
elif isinstance(parent, Sequence) and part == '-':
|
|
219
|
-
|
|
276
|
+
try:
|
|
277
|
+
parent.append(value)
|
|
278
|
+
except AttributeError as e:
|
|
279
|
+
# immutable sequences, such as tuples, can't be appended to
|
|
280
|
+
raise JsonPointerException("Invalid assignment target: %s" % (e,))
|
|
220
281
|
else:
|
|
221
282
|
try:
|
|
222
283
|
parent[part] = value
|
|
223
284
|
except (TypeError, IndexError) as e:
|
|
224
285
|
raise JsonPointerException("Invalid assignment target: %s" % (e,))
|
|
225
286
|
|
|
226
|
-
return doc
|
|
227
|
-
|
|
228
287
|
@classmethod
|
|
229
288
|
def get_part(cls, doc, part):
|
|
230
289
|
"""Returns the next step in the correct type"""
|
|
@@ -307,7 +366,7 @@ class JsonPointer:
|
|
|
307
366
|
suffix_parts = suffix
|
|
308
367
|
try:
|
|
309
368
|
return self.__class__.from_parts(chain(self.parts, suffix_parts))
|
|
310
|
-
except:
|
|
369
|
+
except Exception:
|
|
311
370
|
raise JsonPointerException("Invalid suffix")
|
|
312
371
|
|
|
313
372
|
def __truediv__(self, suffix):
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
jsonpointer.py,sha256=tB2Kq4dD2FzDJUefAkAq7i35pNI8highXt5zNvBuuGg,11409
|
|
2
|
-
jsonpointer-3.2.1.data/scripts/jsonpointer,sha256=y47Agdt7Hqi5zkQ8Jhwn9mZZKV-ILdgs7onNOiku9eQ,3033
|
|
3
|
-
jsonpointer-3.2.1.dist-info/licenses/AUTHORS,sha256=TVgxnQ9ZyHvvWwez_k2w8ZwtfVVFsDTGv3tXyJu-9X8,113
|
|
4
|
-
jsonpointer-3.2.1.dist-info/licenses/LICENSE.txt,sha256=2LJPFdRyiF94ii1umFhQ8mRie4YBKhe7JCyD8xDZB-U,1413
|
|
5
|
-
jsonpointer-3.2.1.dist-info/METADATA,sha256=KdXwl56UHRWNNc0_glGZWyHOeRBvbs04g0uMv0YOooU,2640
|
|
6
|
-
jsonpointer-3.2.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
7
|
-
jsonpointer-3.2.1.dist-info/top_level.txt,sha256=BsUcar_C0nZzPGV2ackrJ9CpVU8_0W_pHYKwpdnWddM,12
|
|
8
|
-
jsonpointer-3.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|