python-jsonpath 1.3.1__py3-none-any.whl → 1.3.2__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.
- jsonpath/__about__.py +1 -1
- jsonpath/__init__.py +0 -2
- jsonpath/env.py +1 -1
- jsonpath/exceptions.py +2 -5
- jsonpath/filter.py +36 -6
- jsonpath/pointer.py +71 -47
- {python_jsonpath-1.3.1.dist-info → python_jsonpath-1.3.2.dist-info}/METADATA +1 -1
- {python_jsonpath-1.3.1.dist-info → python_jsonpath-1.3.2.dist-info}/RECORD +11 -11
- {python_jsonpath-1.3.1.dist-info → python_jsonpath-1.3.2.dist-info}/WHEEL +0 -0
- {python_jsonpath-1.3.1.dist-info → python_jsonpath-1.3.2.dist-info}/entry_points.txt +0 -0
- {python_jsonpath-1.3.1.dist-info → python_jsonpath-1.3.2.dist-info}/licenses/LICENSE.txt +0 -0
jsonpath/__about__.py
CHANGED
jsonpath/__init__.py
CHANGED
|
@@ -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",
|
jsonpath/env.py
CHANGED
|
@@ -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.
|
jsonpath/exceptions.py
CHANGED
|
@@ -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:
|
jsonpath/filter.py
CHANGED
|
@@ -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
|
|
jsonpath/pointer.py
CHANGED
|
@@ -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]]
|
|
@@ -486,7 +510,7 @@ class RelativeJSONPointer:
|
|
|
486
510
|
return isinstance(__value, RelativeJSONPointer) and str(self) == str(__value)
|
|
487
511
|
|
|
488
512
|
def __hash__(self) -> int:
|
|
489
|
-
return hash((self.origin, self.index, self.pointer))
|
|
513
|
+
return hash((self.origin, self.index, self.pointer)) # pragma: no cover
|
|
490
514
|
|
|
491
515
|
def _parse(
|
|
492
516
|
self,
|
|
@@ -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
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
jsonpath/__about__.py,sha256=
|
|
2
|
-
jsonpath/__init__.py,sha256=
|
|
1
|
+
jsonpath/__about__.py,sha256=lKzAT7eRQ0XCM36oMem3ZY_sdLarE9W-QFI1Ret5qKc,132
|
|
2
|
+
jsonpath/__init__.py,sha256=WlqHtXZcMy2AnAqvBQeiUcS1_I7Upif2j7SSLYZGTNg,2335
|
|
3
3
|
jsonpath/__main__.py,sha256=6Y5wOE7U-MHymopXOsxofaY30tVZYPGTJO0L4vytoUw,61
|
|
4
4
|
jsonpath/_data.py,sha256=JEpu5Kg0_kgxYKUilBcHVdTmPxf3-Vc0NgaW6olsqyY,577
|
|
5
5
|
jsonpath/cli.py,sha256=scpWfJXl1jLQ80ZyXqMCu8JtRgZUXluC11x6OkC4oeA,10026
|
|
6
|
-
jsonpath/env.py,sha256=
|
|
7
|
-
jsonpath/exceptions.py,sha256=
|
|
8
|
-
jsonpath/filter.py,sha256=
|
|
6
|
+
jsonpath/env.py,sha256=Q3ymsGf0ktpiVGU5OLjYCayHFCEfN-jvZCjFzFJJ3HU,22814
|
|
7
|
+
jsonpath/exceptions.py,sha256=ku3XNuMn4CsYhe-iZpZ8DuFPR2AEcV0SEl55X3Huhaw,4218
|
|
8
|
+
jsonpath/filter.py,sha256=Ay71K1PzI3_Vur5Y7pAQguV0ceo4yqBZVsuj_jD7nck,22755
|
|
9
9
|
jsonpath/fluent_api.py,sha256=mfAA2t-xUGOmGVr_1h9lxo3y4FsAvaxOpvOH8jZ4DHU,9117
|
|
10
10
|
jsonpath/lex.py,sha256=8yrSLd3Q3A9Y4GeacOjboUp40XsR_BkRDQ3CC3UVcP8,10296
|
|
11
11
|
jsonpath/match.py,sha256=qJ8IUn8RsuC-iL6RKr2vTn0l1f7bcx1m9cnZiAEqYH0,3657
|
|
12
12
|
jsonpath/parse.py,sha256=s7BuFsSgX2GuDubrFr-SDcCk2ZInGzPV04FNFcUwxPM,25214
|
|
13
13
|
jsonpath/patch.py,sha256=T6CP0GDJg6drD9qWs6ueRFdQRhXj_xPGEtW5x01iJb8,25388
|
|
14
14
|
jsonpath/path.py,sha256=RUeP7k_WcvP5ZnYblcRDd_-wgo9VnMKyIevTcRImYE4,16421
|
|
15
|
-
jsonpath/pointer.py,sha256=
|
|
15
|
+
jsonpath/pointer.py,sha256=UjqqWQWL8D-chjSEQ2al_Ev5xcHaKxFFfQxPfuBSwO0,23100
|
|
16
16
|
jsonpath/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
jsonpath/selectors.py,sha256=oesy964W8Qd1qSSb0qtWJY63A2D0lZc0ppF-pGEYmgU,27313
|
|
18
18
|
jsonpath/serialize.py,sha256=viMcWY52wkUseTNfPKillVWswHePJ2L_B3PV3bDVvmU,360
|
|
@@ -29,8 +29,8 @@ jsonpath/function_extensions/match.py,sha256=KjsH33fCFGonp2RV__FuaeIOTwLLcvgaaCi
|
|
|
29
29
|
jsonpath/function_extensions/search.py,sha256=O11fnkHlbvf0QPrLISYfhlPXBvVPBr-U8V0dGbd614Y,710
|
|
30
30
|
jsonpath/function_extensions/typeof.py,sha256=yCAj9zOqSnam1mfHCGolNHWDmsBOvU3rAhbZDYycx50,1780
|
|
31
31
|
jsonpath/function_extensions/value.py,sha256=fQMbPUV87Jn1nOwAlBpTeLmLIG5ejH0XQBOM_SR-Us4,721
|
|
32
|
-
python_jsonpath-1.3.
|
|
33
|
-
python_jsonpath-1.3.
|
|
34
|
-
python_jsonpath-1.3.
|
|
35
|
-
python_jsonpath-1.3.
|
|
36
|
-
python_jsonpath-1.3.
|
|
32
|
+
python_jsonpath-1.3.2.dist-info/METADATA,sha256=_fv6UDYXR5zUSS_JPOqW8yM4pgdLxz-MhHS1b4BN_qg,6493
|
|
33
|
+
python_jsonpath-1.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
34
|
+
python_jsonpath-1.3.2.dist-info/entry_points.txt,sha256=xvbWnAebJyOMI_9ugK0xrpFRlwmEsAJD2kNHU0Dvscc,43
|
|
35
|
+
python_jsonpath-1.3.2.dist-info/licenses/LICENSE.txt,sha256=u7PksAQGI1QYWcERHeauMseZ4XAzDKUrKW8Z4wbeU1k,1101
|
|
36
|
+
python_jsonpath-1.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|