python-jsonpath 1.3.0__tar.gz → 1.3.2__tar.gz
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.
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/.gitignore +6 -1
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/PKG-INFO +3 -1
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/README.md +2 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/__about__.py +1 -1
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/__init__.py +0 -2
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/env.py +1 -1
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/exceptions.py +2 -5
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/filter.py +37 -7
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/arguments.py +2 -1
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/patch.py +8 -8
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/pointer.py +73 -46
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/LICENSE.txt +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/__main__.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/_data.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/cli.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/fluent_api.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/__init__.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/count.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/filter_function.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/is_instance.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/keys.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/length.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/match.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/search.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/typeof.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/value.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/lex.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/match.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/parse.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/path.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/py.typed +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/selectors.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/serialize.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/stream.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/token.py +0 -0
- {python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-jsonpath
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: JSONPath, JSON Pointer and JSON Patch for Python.
|
|
5
5
|
Project-URL: Documentation, https://jg-rp.github.io/python-jsonpath/
|
|
6
6
|
Project-URL: Issues, https://github.com/jg-rp/python-jsonpath/issues
|
|
@@ -97,6 +97,8 @@ conda install -c conda-forge python-jsonpath
|
|
|
97
97
|
|
|
98
98
|
- [JSON P3](https://github.com/jg-rp/json-p3) - RFC 9535 implemented in TypeScript. JSON P3 does not include all the non-standard features of Python JSONPath, but does define some optional [extra syntax](https://jg-rp.github.io/json-p3/guides/jsonpath-extra).
|
|
99
99
|
|
|
100
|
+
- [Ruby JSON P3](https://github.com/jg-rp/ruby-json-p3) - RFC 9535, RFC 6901 and RFC 6902 implemented in Ruby.
|
|
101
|
+
|
|
100
102
|
## Examples
|
|
101
103
|
|
|
102
104
|
### JSONPath
|
|
@@ -72,6 +72,8 @@ conda install -c conda-forge python-jsonpath
|
|
|
72
72
|
|
|
73
73
|
- [JSON P3](https://github.com/jg-rp/json-p3) - RFC 9535 implemented in TypeScript. JSON P3 does not include all the non-standard features of Python JSONPath, but does define some optional [extra syntax](https://jg-rp.github.io/json-p3/guides/jsonpath-extra).
|
|
74
74
|
|
|
75
|
+
- [Ruby JSON P3](https://github.com/jg-rp/ruby-json-p3) - RFC 9535, RFC 6901 and RFC 6902 implemented in Ruby.
|
|
76
|
+
|
|
75
77
|
## Examples
|
|
76
78
|
|
|
77
79
|
### JSONPath
|
|
@@ -10,7 +10,6 @@ from .exceptions import JSONPathIndexError
|
|
|
10
10
|
from .exceptions import JSONPathNameError
|
|
11
11
|
from .exceptions import JSONPathSyntaxError
|
|
12
12
|
from .exceptions import JSONPathTypeError
|
|
13
|
-
from .exceptions import JSONPointerEncodeError
|
|
14
13
|
from .exceptions import JSONPointerError
|
|
15
14
|
from .exceptions import JSONPointerIndexError
|
|
16
15
|
from .exceptions import JSONPointerKeyError
|
|
@@ -52,7 +51,6 @@ __all__ = (
|
|
|
52
51
|
"JSONPathSyntaxError",
|
|
53
52
|
"JSONPathTypeError",
|
|
54
53
|
"JSONPointer",
|
|
55
|
-
"JSONPointerEncodeError",
|
|
56
54
|
"JSONPointerError",
|
|
57
55
|
"JSONPointerIndexError",
|
|
58
56
|
"JSONPointerKeyError",
|
|
@@ -99,7 +99,7 @@ class JSONPathEnvironment:
|
|
|
99
99
|
intersection_token (str): The pattern used as the intersection operator.
|
|
100
100
|
Defaults to `"&"`.
|
|
101
101
|
key_token (str): The pattern used to identify the current key or index when
|
|
102
|
-
filtering a
|
|
102
|
+
filtering a mapping or sequence. Defaults to `"#"`.
|
|
103
103
|
keys_selector_token (str): The pattern used as the "keys" selector. Defaults to
|
|
104
104
|
`"~"`.
|
|
105
105
|
lexer_class: The lexer to use when tokenizing path strings.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""JSONPath exceptions."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from typing import TYPE_CHECKING
|
|
@@ -80,10 +81,6 @@ class JSONPointerError(Exception):
|
|
|
80
81
|
"""Base class for all JSON Pointer errors."""
|
|
81
82
|
|
|
82
83
|
|
|
83
|
-
class JSONPointerEncodeError(JSONPointerError):
|
|
84
|
-
"""An exception raised when a JSONPathMatch can't be encoded to a JSON Pointer."""
|
|
85
|
-
|
|
86
|
-
|
|
87
84
|
class JSONPointerResolutionError(JSONPointerError):
|
|
88
85
|
"""Base exception for those that can be raised during pointer resolution."""
|
|
89
86
|
|
|
@@ -145,7 +142,7 @@ class JSONPatchTestFailure(JSONPatchError): # noqa: N818
|
|
|
145
142
|
def _truncate_message(value: str, num: int, end: str = "...") -> str:
|
|
146
143
|
if len(value) < num:
|
|
147
144
|
return value
|
|
148
|
-
return f"{value[:num-len(end)]}{end}"
|
|
145
|
+
return f"{value[: num - len(end)]}{end}"
|
|
149
146
|
|
|
150
147
|
|
|
151
148
|
def _truncate_words(val: str, num: int, end: str = "...") -> str:
|
|
@@ -30,7 +30,7 @@ if TYPE_CHECKING:
|
|
|
30
30
|
from .path import JSONPath
|
|
31
31
|
from .selectors import FilterContext
|
|
32
32
|
|
|
33
|
-
# ruff: noqa: D102
|
|
33
|
+
# ruff: noqa: D102, PLW1641
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class FilterExpression(ABC):
|
|
@@ -544,7 +544,12 @@ class SelfPath(Path):
|
|
|
544
544
|
return context.current
|
|
545
545
|
return NodeList()
|
|
546
546
|
|
|
547
|
-
return NodeList(
|
|
547
|
+
return NodeList(
|
|
548
|
+
self.path.finditer(
|
|
549
|
+
context.current,
|
|
550
|
+
filter_context=context.extra_context,
|
|
551
|
+
)
|
|
552
|
+
)
|
|
548
553
|
|
|
549
554
|
async def evaluate_async(self, context: FilterContext) -> object:
|
|
550
555
|
if isinstance(context.current, str): # TODO: refactor
|
|
@@ -557,7 +562,13 @@ class SelfPath(Path):
|
|
|
557
562
|
return NodeList()
|
|
558
563
|
|
|
559
564
|
return NodeList(
|
|
560
|
-
[
|
|
565
|
+
[
|
|
566
|
+
match
|
|
567
|
+
async for match in await self.path.finditer_async(
|
|
568
|
+
context.current,
|
|
569
|
+
filter_context=context.extra_context,
|
|
570
|
+
)
|
|
571
|
+
]
|
|
561
572
|
)
|
|
562
573
|
|
|
563
574
|
|
|
@@ -576,11 +587,22 @@ class RootPath(Path):
|
|
|
576
587
|
return str(self.path)
|
|
577
588
|
|
|
578
589
|
def evaluate(self, context: FilterContext) -> object:
|
|
579
|
-
return NodeList(
|
|
590
|
+
return NodeList(
|
|
591
|
+
self.path.finditer(
|
|
592
|
+
context.root,
|
|
593
|
+
filter_context=context.extra_context,
|
|
594
|
+
)
|
|
595
|
+
)
|
|
580
596
|
|
|
581
597
|
async def evaluate_async(self, context: FilterContext) -> object:
|
|
582
598
|
return NodeList(
|
|
583
|
-
[
|
|
599
|
+
[
|
|
600
|
+
match
|
|
601
|
+
async for match in await self.path.finditer_async(
|
|
602
|
+
context.root,
|
|
603
|
+
filter_context=context.extra_context,
|
|
604
|
+
)
|
|
605
|
+
]
|
|
584
606
|
)
|
|
585
607
|
|
|
586
608
|
|
|
@@ -600,13 +622,21 @@ class FilterContextPath(Path):
|
|
|
600
622
|
return "_" + path_repr[1:]
|
|
601
623
|
|
|
602
624
|
def evaluate(self, context: FilterContext) -> object:
|
|
603
|
-
return NodeList(
|
|
625
|
+
return NodeList(
|
|
626
|
+
self.path.finditer(
|
|
627
|
+
context.extra_context,
|
|
628
|
+
filter_context=context.extra_context,
|
|
629
|
+
)
|
|
630
|
+
)
|
|
604
631
|
|
|
605
632
|
async def evaluate_async(self, context: FilterContext) -> object:
|
|
606
633
|
return NodeList(
|
|
607
634
|
[
|
|
608
635
|
match
|
|
609
|
-
async for match in await self.path.finditer_async(
|
|
636
|
+
async for match in await self.path.finditer_async(
|
|
637
|
+
context.extra_context,
|
|
638
|
+
filter_context=context.extra_context,
|
|
639
|
+
)
|
|
610
640
|
]
|
|
611
641
|
)
|
|
612
642
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Class-based function extension base."""
|
|
2
|
+
|
|
2
3
|
import inspect
|
|
3
4
|
from typing import TYPE_CHECKING
|
|
4
5
|
from typing import Any
|
|
@@ -26,7 +27,7 @@ def validate(
|
|
|
26
27
|
params = list(inspect.signature(func).parameters.values())
|
|
27
28
|
|
|
28
29
|
# Keyword only params are not supported
|
|
29
|
-
if
|
|
30
|
+
if [p for p in params if p.kind in (p.KEYWORD_ONLY, p.VAR_KEYWORD)]:
|
|
30
31
|
raise JSONPathTypeError(
|
|
31
32
|
f"function {token.value!r} requires keyword arguments",
|
|
32
33
|
token=token,
|
|
@@ -74,7 +74,7 @@ class OpAdd(Op):
|
|
|
74
74
|
else:
|
|
75
75
|
parent.insert(int(target), self.value)
|
|
76
76
|
elif isinstance(parent, MutableMapping):
|
|
77
|
-
parent[target] = self.value
|
|
77
|
+
parent[str(target)] = self.value
|
|
78
78
|
else:
|
|
79
79
|
raise JSONPatchError(
|
|
80
80
|
f"unexpected operation on {parent.__class__.__name__!r}"
|
|
@@ -124,7 +124,7 @@ class OpAddAp(OpAdd):
|
|
|
124
124
|
"""A non-standard add operation that appends to arrays/lists .
|
|
125
125
|
|
|
126
126
|
This is like _OpAdd_, but assumes an index of "-" if the path can not
|
|
127
|
-
be resolved.
|
|
127
|
+
be resolved rather than raising a JSONPatchError.
|
|
128
128
|
|
|
129
129
|
**New in version 1.2.0**
|
|
130
130
|
"""
|
|
@@ -183,7 +183,7 @@ class OpRemove(Op):
|
|
|
183
183
|
elif isinstance(parent, MutableMapping):
|
|
184
184
|
if obj is UNDEFINED:
|
|
185
185
|
raise JSONPatchError("can't remove nonexistent property")
|
|
186
|
-
del parent[self.path.parts[-1]]
|
|
186
|
+
del parent[str(self.path.parts[-1])]
|
|
187
187
|
else:
|
|
188
188
|
raise JSONPatchError(
|
|
189
189
|
f"unexpected operation on {parent.__class__.__name__!r}"
|
|
@@ -221,7 +221,7 @@ class OpReplace(Op):
|
|
|
221
221
|
elif isinstance(parent, MutableMapping):
|
|
222
222
|
if obj is UNDEFINED:
|
|
223
223
|
raise JSONPatchError("can't replace nonexistent property")
|
|
224
|
-
parent[self.path.parts[-1]] = self.value
|
|
224
|
+
parent[str(self.path.parts[-1])] = self.value
|
|
225
225
|
else:
|
|
226
226
|
raise JSONPatchError(
|
|
227
227
|
f"unexpected operation on {parent.__class__.__name__!r}"
|
|
@@ -259,7 +259,7 @@ class OpMove(Op):
|
|
|
259
259
|
if isinstance(source_parent, MutableSequence):
|
|
260
260
|
del source_parent[int(self.source.parts[-1])]
|
|
261
261
|
if isinstance(source_parent, MutableMapping):
|
|
262
|
-
del source_parent[self.source.parts[-1]]
|
|
262
|
+
del source_parent[str(self.source.parts[-1])]
|
|
263
263
|
|
|
264
264
|
dest_parent, _ = self.dest.resolve_parent(data)
|
|
265
265
|
|
|
@@ -270,7 +270,7 @@ class OpMove(Op):
|
|
|
270
270
|
if isinstance(dest_parent, MutableSequence):
|
|
271
271
|
dest_parent.insert(int(self.dest.parts[-1]), source_obj)
|
|
272
272
|
elif isinstance(dest_parent, MutableMapping):
|
|
273
|
-
dest_parent[self.dest.parts[-1]] = source_obj
|
|
273
|
+
dest_parent[str(self.dest.parts[-1])] = source_obj
|
|
274
274
|
else:
|
|
275
275
|
raise JSONPatchError(
|
|
276
276
|
f"unexpected operation on {dest_parent.__class__.__name__!r}"
|
|
@@ -312,7 +312,7 @@ class OpCopy(Op):
|
|
|
312
312
|
if isinstance(dest_parent, MutableSequence):
|
|
313
313
|
dest_parent.insert(int(self.dest.parts[-1]), copy.deepcopy(source_obj))
|
|
314
314
|
elif isinstance(dest_parent, MutableMapping):
|
|
315
|
-
dest_parent[self.dest.parts[-1]] = copy.deepcopy(source_obj)
|
|
315
|
+
dest_parent[str(self.dest.parts[-1])] = copy.deepcopy(source_obj)
|
|
316
316
|
else:
|
|
317
317
|
raise JSONPatchError(
|
|
318
318
|
f"unexpected operation on {dest_parent.__class__.__name__!r}"
|
|
@@ -419,7 +419,7 @@ class JSONPatch:
|
|
|
419
419
|
value=self._op_value(operation, "value", "addne", i),
|
|
420
420
|
)
|
|
421
421
|
elif op == "addap":
|
|
422
|
-
self.
|
|
422
|
+
self.addap(
|
|
423
423
|
path=self._op_pointer(operation, "path", "addap", i),
|
|
424
424
|
value=self._op_value(operation, "value", "addap", i),
|
|
425
425
|
)
|
|
@@ -32,7 +32,7 @@ if TYPE_CHECKING:
|
|
|
32
32
|
|
|
33
33
|
class _Undefined:
|
|
34
34
|
def __str__(self) -> str:
|
|
35
|
-
return "<jsonpath.pointer.UNDEFINED>"
|
|
35
|
+
return "<jsonpath.pointer.UNDEFINED>" # pragma: no cover
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
UNDEFINED = _Undefined()
|
|
@@ -115,59 +115,83 @@ class JSONPointer:
|
|
|
115
115
|
try:
|
|
116
116
|
index = int(s)
|
|
117
117
|
if index < self.min_int_index or index > self.max_int_index:
|
|
118
|
-
raise
|
|
118
|
+
raise JSONPointerError("index out of range")
|
|
119
119
|
return index
|
|
120
120
|
except ValueError:
|
|
121
121
|
return s
|
|
122
122
|
|
|
123
|
-
def _getitem(self, obj: Any, key: Any) -> Any:
|
|
123
|
+
def _getitem(self, obj: Any, key: Any) -> Any:
|
|
124
124
|
try:
|
|
125
|
+
# Handle the most common cases. A mapping with a string key, or a sequence
|
|
126
|
+
# with an integer index.
|
|
127
|
+
#
|
|
128
|
+
# Note that `obj` does not have to be a Mapping or Sequence here. Any object
|
|
129
|
+
# implementing `__getitem__` will do.
|
|
125
130
|
return getitem(obj, key)
|
|
126
131
|
except KeyError as err:
|
|
127
|
-
|
|
128
|
-
if isinstance(key, int):
|
|
129
|
-
try:
|
|
130
|
-
return getitem(obj, str(key))
|
|
131
|
-
except KeyError:
|
|
132
|
-
raise JSONPointerKeyError(key) from err
|
|
133
|
-
# Handle non-standard keys/property selector/pointer.
|
|
134
|
-
if (
|
|
135
|
-
isinstance(key, str)
|
|
136
|
-
and isinstance(obj, Mapping)
|
|
137
|
-
and key.startswith((self.keys_selector, "#"))
|
|
138
|
-
and key[1:] in obj
|
|
139
|
-
):
|
|
140
|
-
return key[1:]
|
|
141
|
-
# Handle non-standard index/property pointer (`#`)
|
|
142
|
-
raise JSONPointerKeyError(key) from err
|
|
132
|
+
return self._handle_key_error(obj, key, err)
|
|
143
133
|
except TypeError as err:
|
|
144
|
-
|
|
145
|
-
if key == "-":
|
|
146
|
-
# "-" is a valid index when appending to a JSON array
|
|
147
|
-
# with JSON Patch, but not when resolving a JSON Pointer.
|
|
148
|
-
raise JSONPointerIndexError("index out of range") from None
|
|
149
|
-
# Handle non-standard index pointer.
|
|
150
|
-
if isinstance(key, str) and key.startswith("#"):
|
|
151
|
-
_index = int(key[1:])
|
|
152
|
-
if _index >= len(obj):
|
|
153
|
-
raise JSONPointerIndexError(
|
|
154
|
-
f"index out of range: {_index}"
|
|
155
|
-
) from err
|
|
156
|
-
return _index
|
|
157
|
-
# Try int index. Reject non-zero ints that start with a zero.
|
|
158
|
-
if isinstance(key, str):
|
|
159
|
-
index = self._index(key)
|
|
160
|
-
if isinstance(index, int):
|
|
161
|
-
try:
|
|
162
|
-
return getitem(obj, int(key))
|
|
163
|
-
except IndexError as index_err:
|
|
164
|
-
raise JSONPointerIndexError(
|
|
165
|
-
f"index out of range: {key}"
|
|
166
|
-
) from index_err
|
|
167
|
-
raise JSONPointerTypeError(f"{key}: {err}") from err
|
|
134
|
+
return self._handle_type_error(obj, key, err)
|
|
168
135
|
except IndexError as err:
|
|
169
136
|
raise JSONPointerIndexError(f"index out of range: {key}") from err
|
|
170
137
|
|
|
138
|
+
def _handle_key_error(self, obj: Any, key: Any, err: Exception) -> object:
|
|
139
|
+
if isinstance(key, int):
|
|
140
|
+
# Try a string repr of the index-like item as a mapping key.
|
|
141
|
+
return self._getitem(obj, str(key))
|
|
142
|
+
|
|
143
|
+
# Handle non-standard key/property selector/pointer.
|
|
144
|
+
#
|
|
145
|
+
# For the benefit of `RelativeJSONPointer.to()` and `JSONPathMatch.pointer()`,
|
|
146
|
+
# treat keys starting with a `#` or `~` as a "key pointer". If `key[1:]` is a
|
|
147
|
+
# key in `obj`, return the key.
|
|
148
|
+
#
|
|
149
|
+
# Note that if a key with a leading `#`/`~` exists in `obj`, it will have been
|
|
150
|
+
# handled by `_getitem`.
|
|
151
|
+
if (
|
|
152
|
+
isinstance(key, str)
|
|
153
|
+
and isinstance(obj, Mapping)
|
|
154
|
+
and key.startswith((self.keys_selector, "#"))
|
|
155
|
+
and key[1:] in obj
|
|
156
|
+
):
|
|
157
|
+
return key[1:]
|
|
158
|
+
|
|
159
|
+
raise JSONPointerKeyError(key) from err
|
|
160
|
+
|
|
161
|
+
def _handle_type_error(self, obj: Any, key: Any, err: Exception) -> object:
|
|
162
|
+
if (
|
|
163
|
+
isinstance(obj, str)
|
|
164
|
+
or not isinstance(obj, Sequence)
|
|
165
|
+
or not isinstance(key, str)
|
|
166
|
+
):
|
|
167
|
+
raise JSONPointerTypeError(f"{key}: {err}") from err
|
|
168
|
+
|
|
169
|
+
# `obj` is array-like
|
|
170
|
+
# `key` is a string
|
|
171
|
+
|
|
172
|
+
if key == "-":
|
|
173
|
+
# "-" is a valid index when appending to a JSON array with JSON Patch, but
|
|
174
|
+
# not when resolving a JSON Pointer.
|
|
175
|
+
raise JSONPointerIndexError("index out of range") from None
|
|
176
|
+
|
|
177
|
+
# Handle non-standard index pointer.
|
|
178
|
+
#
|
|
179
|
+
# For the benefit of `RelativeJSONPointer.to()`, treat keys starting with a `#`
|
|
180
|
+
# and followed by a valid index as an "index pointer". If `int(key[1:])` is
|
|
181
|
+
# less than `len(obj)`, return the index.
|
|
182
|
+
if re.match(r"#[1-9]\d*", key):
|
|
183
|
+
_index = int(key[1:])
|
|
184
|
+
if _index >= len(obj):
|
|
185
|
+
raise JSONPointerIndexError(f"index out of range: {_index}") from err
|
|
186
|
+
return _index
|
|
187
|
+
|
|
188
|
+
# Try int index. Reject non-zero ints that start with a zero.
|
|
189
|
+
index = self._index(key)
|
|
190
|
+
if isinstance(index, int):
|
|
191
|
+
return self._getitem(obj, index)
|
|
192
|
+
|
|
193
|
+
raise JSONPointerTypeError(f"{key}: {err}") from err
|
|
194
|
+
|
|
171
195
|
def resolve(
|
|
172
196
|
self,
|
|
173
197
|
data: Union[str, IOBase, Sequence[object], Mapping[str, object]],
|
|
@@ -263,7 +287,7 @@ class JSONPointer:
|
|
|
263
287
|
pointer = cls._encode(match.parts)
|
|
264
288
|
else:
|
|
265
289
|
# This should not happen, unless the JSONPathMatch has been tampered with.
|
|
266
|
-
pointer = ""
|
|
290
|
+
pointer = "" # pragma: no cover
|
|
267
291
|
|
|
268
292
|
return cls(
|
|
269
293
|
pointer,
|
|
@@ -328,10 +352,10 @@ class JSONPointer:
|
|
|
328
352
|
return isinstance(other, JSONPointer) and self.parts == other.parts
|
|
329
353
|
|
|
330
354
|
def __hash__(self) -> int:
|
|
331
|
-
return hash(self.parts)
|
|
355
|
+
return hash(self.parts) # pragma: no cover
|
|
332
356
|
|
|
333
357
|
def __repr__(self) -> str:
|
|
334
|
-
return f"JSONPointer({self._s!r})"
|
|
358
|
+
return f"JSONPointer({self._s!r})" # pragma: no cover
|
|
335
359
|
|
|
336
360
|
def exists(
|
|
337
361
|
self, data: Union[str, IOBase, Sequence[object], Mapping[str, object]]
|
|
@@ -485,6 +509,9 @@ class RelativeJSONPointer:
|
|
|
485
509
|
def __eq__(self, __value: object) -> bool:
|
|
486
510
|
return isinstance(__value, RelativeJSONPointer) and str(self) == str(__value)
|
|
487
511
|
|
|
512
|
+
def __hash__(self) -> int:
|
|
513
|
+
return hash((self.origin, self.index, self.pointer)) # pragma: no cover
|
|
514
|
+
|
|
488
515
|
def _parse(
|
|
489
516
|
self,
|
|
490
517
|
rel: str,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_jsonpath-1.3.0 → python_jsonpath-1.3.2}/jsonpath/function_extensions/filter_function.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|