python-jsonpath 1.1.0__tar.gz → 1.1.1__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.
Files changed (35) hide show
  1. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/PKG-INFO +1 -1
  2. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/__about__.py +1 -1
  3. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/__init__.py +0 -2
  4. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/filter.py +7 -6
  5. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/selectors.py +35 -11
  6. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/.gitignore +0 -0
  7. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/LICENSE.txt +0 -0
  8. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/README.md +0 -0
  9. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/__main__.py +0 -0
  10. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/_data.py +0 -0
  11. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/cli.py +0 -0
  12. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/env.py +0 -0
  13. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/exceptions.py +0 -0
  14. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/fluent_api.py +0 -0
  15. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/__init__.py +0 -0
  16. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/arguments.py +0 -0
  17. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/count.py +0 -0
  18. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/filter_function.py +0 -0
  19. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/is_instance.py +0 -0
  20. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/keys.py +0 -0
  21. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/length.py +0 -0
  22. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/match.py +0 -0
  23. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/search.py +0 -0
  24. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/typeof.py +0 -0
  25. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/function_extensions/value.py +0 -0
  26. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/lex.py +0 -0
  27. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/match.py +0 -0
  28. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/parse.py +0 -0
  29. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/patch.py +0 -0
  30. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/path.py +0 -0
  31. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/pointer.py +0 -0
  32. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/py.typed +0 -0
  33. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/stream.py +0 -0
  34. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/jsonpath/token.py +0 -0
  35. {python_jsonpath-1.1.0 → python_jsonpath-1.1.1}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-jsonpath
3
- Version: 1.1.0
3
+ Version: 1.1.1
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,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2023-present James Prior <jamesgr.prior@gmail.com>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "1.1.0"
4
+ __version__ = "1.1.1"
@@ -31,12 +31,10 @@ from .pointer import resolve
31
31
  __all__ = (
32
32
  "compile",
33
33
  "CompoundJSONPath",
34
- "find",
35
34
  "findall_async",
36
35
  "findall",
37
36
  "finditer_async",
38
37
  "finditer",
39
- "first",
40
38
  "JSONPatch",
41
39
  "JSONPath",
42
40
  "JSONPathEnvironment",
@@ -318,7 +318,7 @@ class PrefixExpression(FilterExpression):
318
318
  class InfixExpression(FilterExpression):
319
319
  """A pair of expressions and a comparison or logical operator."""
320
320
 
321
- __slots__ = ("left", "operator", "right")
321
+ __slots__ = ("left", "operator", "right", "logical")
322
322
 
323
323
  def __init__(
324
324
  self,
@@ -329,10 +329,11 @@ class InfixExpression(FilterExpression):
329
329
  self.left = left
330
330
  self.operator = operator
331
331
  self.right = right
332
+ self.logical = operator in ("&&", "||")
332
333
  super().__init__()
333
334
 
334
335
  def __str__(self) -> str:
335
- if self.operator in ("&&", "||"):
336
+ if self.logical:
336
337
  return f"({self.left} {self.operator} {self.right})"
337
338
  return f"{self.left} {self.operator} {self.right}"
338
339
 
@@ -346,22 +347,22 @@ class InfixExpression(FilterExpression):
346
347
 
347
348
  def evaluate(self, context: FilterContext) -> bool:
348
349
  left = self.left.evaluate(context)
349
- if isinstance(left, NodeList) and len(left) == 1:
350
+ if not self.logical and isinstance(left, NodeList) and len(left) == 1:
350
351
  left = left[0].obj
351
352
 
352
353
  right = self.right.evaluate(context)
353
- if isinstance(right, NodeList) and len(right) == 1:
354
+ if not self.logical and isinstance(right, NodeList) and len(right) == 1:
354
355
  right = right[0].obj
355
356
 
356
357
  return context.env.compare(left, self.operator, right)
357
358
 
358
359
  async def evaluate_async(self, context: FilterContext) -> bool:
359
360
  left = await self.left.evaluate_async(context)
360
- if isinstance(left, NodeList) and len(left) == 1:
361
+ if not self.logical and isinstance(left, NodeList) and len(left) == 1:
361
362
  left = left[0].obj
362
363
 
363
364
  right = await self.right.evaluate_async(context)
364
- if isinstance(right, NodeList) and len(right) == 1:
365
+ if not self.logical and isinstance(right, NodeList) and len(right) == 1:
365
366
  right = right[0].obj
366
367
 
367
368
  return context.env.compare(left, self.operator, right)
@@ -1,4 +1,4 @@
1
- """JSONPath selector objects, as returned from `Parser.parse`."""
1
+ """JSONPath segments and selectors, as returned from `Parser.parse`."""
2
2
  from __future__ import annotations
3
3
 
4
4
  from abc import ABC
@@ -28,7 +28,7 @@ if TYPE_CHECKING:
28
28
 
29
29
 
30
30
  class JSONPathSelector(ABC):
31
- """Base class for all JSONPath selectors."""
31
+ """Base class for all JSONPath segments and selectors."""
32
32
 
33
33
  __slots__ = ("env", "token")
34
34
 
@@ -38,7 +38,17 @@ class JSONPathSelector(ABC):
38
38
 
39
39
  @abstractmethod
40
40
  def resolve(self, matches: Iterable[JSONPathMatch]) -> Iterable[JSONPathMatch]:
41
- """Expand matches from previous JSONPath selectors in to new matches."""
41
+ """Apply the segment/selector to each node in _matches_.
42
+
43
+ Arguments:
44
+ matches: Nodes matched by preceding segments/selectors. This is like
45
+ a lazy _NodeList_, as described in RFC 9535, but each match carries
46
+ more than the node's value and location.
47
+
48
+ Returns:
49
+ The `JSONPathMatch` instances created by applying this selector to each
50
+ preceding node.
51
+ """
42
52
 
43
53
  @abstractmethod
44
54
  def resolve_async(
@@ -48,7 +58,7 @@ class JSONPathSelector(ABC):
48
58
 
49
59
 
50
60
  class PropertySelector(JSONPathSelector):
51
- """A JSONPath property."""
61
+ """A shorthand or bracketed property selector."""
52
62
 
53
63
  __slots__ = ("name", "shorthand")
54
64
 
@@ -115,7 +125,12 @@ class PropertySelector(JSONPathSelector):
115
125
 
116
126
 
117
127
  class IndexSelector(JSONPathSelector):
118
- """Dotted and bracketed sequence access by index."""
128
+ """Select an element from an array by index.
129
+
130
+ Considering we don't require mapping (JSON object) keys/properties to
131
+ be quoted, and that we support mappings with numeric keys, we also check
132
+ to see if the "index" is a mapping key, which is non-standard.
133
+ """
119
134
 
120
135
  __slots__ = ("index", "_as_key")
121
136
 
@@ -213,7 +228,10 @@ class IndexSelector(JSONPathSelector):
213
228
 
214
229
 
215
230
  class KeysSelector(JSONPathSelector):
216
- """Select an mapping's keys/properties."""
231
+ """Select mapping/object keys/properties.
232
+
233
+ NOTE: This is a non-standard selector.
234
+ """
217
235
 
218
236
  __slots__ = ("shorthand",)
219
237
 
@@ -354,7 +372,7 @@ class SliceSelector(JSONPathSelector):
354
372
 
355
373
 
356
374
  class WildSelector(JSONPathSelector):
357
- """Wildcard expansion selector."""
375
+ """Select all items from a sequence/array or values from a mapping/object."""
358
376
 
359
377
  __slots__ = ("shorthand",)
360
378
 
@@ -433,7 +451,10 @@ class WildSelector(JSONPathSelector):
433
451
 
434
452
 
435
453
  class RecursiveDescentSelector(JSONPathSelector):
436
- """A JSONPath selector that visits all objects recursively."""
454
+ """A JSONPath selector that visits all nodes recursively.
455
+
456
+ NOTE: Strictly this is a "segment", not a "selector".
457
+ """
437
458
 
438
459
  def __str__(self) -> str:
439
460
  return ".."
@@ -504,7 +525,10 @@ async def _alist(it: List[T]) -> AsyncIterable[T]:
504
525
 
505
526
 
506
527
  class ListSelector(JSONPathSelector):
507
- """A JSONPath selector representing a list of properties, slices or indices."""
528
+ """A bracketed list of selectors, the results of which are concatenated together.
529
+
530
+ NOTE: Strictly this is a "segment", not a "selector".
531
+ """
508
532
 
509
533
  __slots__ = ("items",)
510
534
 
@@ -555,7 +579,7 @@ class ListSelector(JSONPathSelector):
555
579
 
556
580
 
557
581
  class Filter(JSONPathSelector):
558
- """A filter selector."""
582
+ """Filter sequence/array items or mapping/object values with a filter expression."""
559
583
 
560
584
  __slots__ = ("expression", "cacheable_nodes")
561
585
 
@@ -713,7 +737,7 @@ class Filter(JSONPathSelector):
713
737
 
714
738
 
715
739
  class FilterContext:
716
- """A filter expression context."""
740
+ """Contextual information and data for evaluating a filter expression."""
717
741
 
718
742
  __slots__ = (
719
743
  "current_key",