Skip to content

Commit 2ac8f65

Browse files
committed
API docs for Query.select and fix some links
1 parent 297c442 commit 2ac8f65

File tree

6 files changed

+30
-15
lines changed

6 files changed

+30
-15
lines changed

docs/advanced.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ user_names = jsonpath.findall(
3939

4040
## Function Extensions
4141

42-
Add, remove or replace [filter functions](functions.md) by updating the [`function_extensions`](api.md#jsonpath.env.JSONPathEnvironment.function_extensions) attribute of a [`JSONPathEnvironment`](api.md#jsonpath.env.JSONPathEnvironment). It is a regular Python dictionary mapping filter function names to any [callable](https://docs.python.org/3/library/typing.html#typing.Callable), like a function or class with a `__call__` method.
42+
Add, remove or replace [filter functions](functions.md) by updating the [`function_extensions`](api.md#jsonpath.JSONPathEnvironment.function_extensions) attribute of a [`JSONPathEnvironment`](api.md#jsonpath.JSONPathEnvironment). It is a regular Python dictionary mapping filter function names to any [callable](https://docs.python.org/3/library/typing.html#typing.Callable), like a function or class with a `__call__` method.
4343

4444
### Type System for Function Expressions
4545

4646
[Section 2.4.1](https://datatracker.ietf.org/doc/html/rfc9535#name-type-system-for-function-ex) of RFC 9535 defines a type system for function expressions and requires that we check that filter expressions are well-typed. With that in mind, you are encouraged to implement custom filter functions by extending [`jsonpath.function_extensions.FilterFunction`](api.md#jsonpath.function_extensions.FilterFunction), which forces you to be explicit about the [types](api.md#jsonpath.function_extensions.ExpressionType) of arguments the function extension accepts and the type of its return value.
4747

4848
!!! info
4949

50-
[`FilterFunction`](api.md#jsonpath.function_extensions.FilterFunction) was new in Python JSONPath version 0.10.0. Prior to that we did not enforce function expression well-typedness. To use any arbitrary [callable](https://docs.python.org/3/library/typing.html#typing.Callable) as a function extension - or if you don't want built-in filter functions to raise a `JSONPathTypeError` for function expressions that are not well-typed - set [`well_typed`](api.md#jsonpath.env.JSONPathEnvironment.well_typed) to `False` when constructing a [`JSONPathEnvironment`](api.md#jsonpath.env.JSONPathEnvironment).
50+
[`FilterFunction`](api.md#jsonpath.function_extensions.FilterFunction) was new in Python JSONPath version 0.10.0. Prior to that we did not enforce function expression well-typedness. To use any arbitrary [callable](https://docs.python.org/3/library/typing.html#typing.Callable) as a function extension - or if you don't want built-in filter functions to raise a `JSONPathTypeError` for function expressions that are not well-typed - set [`well_typed`](api.md#jsonpath.JSONPathEnvironment.well_typed) to `False` when constructing a [`JSONPathEnvironment`](api.md#jsonpath.JSONPathEnvironment).
5151

5252
### Example
5353

@@ -137,7 +137,7 @@ env = MyEnv()
137137

138138
### Compile Time Validation
139139

140-
Calls to [type-aware](#type-system-for-function-expressions) function extension are validated at JSONPath compile-time automatically. If [`well_typed`](api.md#jsonpath.env.JSONPathEnvironment.well_typed) is set to `False` or a custom function extension does not inherit from [`FilterFunction`](api.md#jsonpath.function_extensions.FilterFunction), its arguments can be validated by implementing the function as a class with a `__call__` method, and a `validate` method. `validate` will be called after parsing the function, giving you the opportunity to inspect its arguments and raise a `JSONPathTypeError` should any arguments be unacceptable. If defined, `validate` must take a reference to the current environment, an argument list and the token pointing to the start of the function call.
140+
Calls to [type-aware](#type-system-for-function-expressions) function extension are validated at JSONPath compile-time automatically. If [`well_typed`](api.md#jsonpath.JSONPathEnvironment.well_typed) is set to `False` or a custom function extension does not inherit from [`FilterFunction`](api.md#jsonpath.function_extensions.FilterFunction), its arguments can be validated by implementing the function as a class with a `__call__` method, and a `validate` method. `validate` will be called after parsing the function, giving you the opportunity to inspect its arguments and raise a `JSONPathTypeError` should any arguments be unacceptable. If defined, `validate` must take a reference to the current environment, an argument list and the token pointing to the start of the function call.
141141

142142
```python
143143
def validate(

docs/api.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
::: jsonpath.Query
1515
handler: python
1616

17+
::: jsonpath.Projection
18+
handler: python
19+
1720
::: jsonpath.function_extensions.FilterFunction
1821
handler: python
1922

docs/async.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Largely motivated by its integration with [Python Liquid](https://jg-rp.github.io/liquid/jsonpath/introduction), Python JSONPath offers an asynchronous API that allows for items in a target data structure to be "fetched" lazily.
44

5-
[`findall_async()`](api.md#jsonpath.env.JSONPathEnvironment.findall_async) and [`finditer_async()`](api.md#jsonpath.env.JSONPathEnvironment.finditer) are [asyncio](https://docs.python.org/3/library/asyncio.html) equivalents to [`findall()`](api.md#jsonpath.env.JSONPathEnvironment.findall) and [`finditer()`](api.md#jsonpath.env.JSONPathEnvironment.finditer). By default, any class implementing the [mapping](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping) or [sequence](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence) interfaces, and a `__getitem_async__()` method, will have `__getitem_async__()` awaited instead of calling `__getitem__()` when resolving mapping keys or sequence indices.
5+
[`findall_async()`](api.md#jsonpath.JSONPathEnvironment.findall_async) and [`finditer_async()`](api.md#jsonpath.JSONPathEnvironment.finditer_async) are [asyncio](https://docs.python.org/3/library/asyncio.html) equivalents to [`findall()`](api.md#jsonpath.JSONPathEnvironment.findall) and [`finditer()`](api.md#jsonpath.JSONPathEnvironment.finditer). By default, any class implementing the [mapping](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping) or [sequence](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence) interfaces, and a `__getitem_async__()` method, will have `__getitem_async__()` awaited instead of calling `__getitem__()` when resolving mapping keys or sequence indices.
66

77
## Example
88

docs/quickstart.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This page gets you started using JSONPath, JSON Pointer and JSON Patch wih Pytho
44

55
## `findall(path, data)`
66

7-
Find all objects matching a JSONPath with [`jsonpath.findall()`](api.md#jsonpath.env.JSONPathEnvironment.findall). It takes, as arguments, a JSONPath string and some _data_ object. It always returns a list of objects selected from _data_, never a scalar value.
7+
Find all objects matching a JSONPath with [`jsonpath.findall()`](api.md#jsonpath.JSONPathEnvironment.findall). It takes, as arguments, a JSONPath string and some _data_ object. It always returns a list of objects selected from _data_, never a scalar value.
88

99
_data_ can be a file-like object or string containing JSON formatted data, or a Python [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping) or [`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence), like a dictionary or list. In this example we select user names from a dictionary containing a list of user dictionaries.
1010

@@ -52,7 +52,7 @@ with open("users.json") as fd:
5252

5353
## `finditer(path, data)`
5454

55-
Use [`jsonpath.finditer()`](api.md#jsonpath.env.JSONPathEnvironment.finditer) to iterate over instances of [`jsonpath.JSONPathMatch`](api.md#jsonpath.JSONPathMatch) for every object in _data_ that matches _path_. It accepts the same arguments as [`findall()`](#findall), a path string and data from which to select matches.
55+
Use [`jsonpath.finditer()`](api.md#jsonpath.JSONPathEnvironment.finditer) to iterate over instances of [`jsonpath.JSONPathMatch`](api.md#jsonpath.JSONPathMatch) for every object in _data_ that matches _path_. It accepts the same arguments as [`findall()`](#findallpath-data), a path string and data from which to select matches.
5656

5757
```python
5858
import jsonpath
@@ -96,7 +96,7 @@ The selected object is available from a [`JSONPathMatch`](api.md#jsonpath.JSONPa
9696

9797
## `compile(path)`
9898

99-
When you have a JSONPath that needs to be matched against different data repeatedly, you can _compile_ the path ahead of time using [`jsonpath.compile()`](api.md#jsonpath.env.JSONPathEnvironment.compile). It takes a path as a string and returns a [`JSONPath`](api.md#jsonpath.JSONPath) instance. `JSONPath` has `findall()` and `finditer()` methods that behave similarly to package-level `findall()` and `finditer()`, just without the `path` argument.
99+
When you have a JSONPath that needs to be matched against different data repeatedly, you can _compile_ the path ahead of time using [`jsonpath.compile()`](api.md#jsonpath.JSONPathEnvironment.compile). It takes a path as a string and returns a [`JSONPath`](api.md#jsonpath.JSONPath) instance. `JSONPath` has `findall()` and `finditer()` methods that behave similarly to package-level `findall()` and `finditer()`, just without the `path` argument.
100100

101101
```python
102102
import jsonpath
@@ -137,7 +137,7 @@ other_users = path.findall(other_data)
137137

138138
**_New in version 0.8.0_**
139139

140-
Get a [`jsonpath.JSONPathMatch`](api.md#jsonpath.JSONPathMatch) instance for the first match found in _data_. If there are no matches, `None` is returned. `match()` accepts the same arguments as [`findall()`](#findall).
140+
Get a [`jsonpath.JSONPathMatch`](api.md#jsonpath.JSONPathMatch) instance for the first match found in _data_. If there are no matches, `None` is returned. `match()` accepts the same arguments as [`findall()`](#findallpath-data).
141141

142142
```python
143143
import jsonpath
@@ -228,7 +228,7 @@ sue_score = pointer.resolve("/users/99/score", data, default=0)
228228
print(sue_score) # 0
229229
```
230230

231-
See also [`JSONPathMatch.pointer()`](api.md#jsonpath.match.JSONPathMatch.pointer), which builds a [`JSONPointer`](api.md#jsonpath.JSONPointer) from a `JSONPathMatch`.
231+
See also [`JSONPathMatch.pointer()`](api.md#jsonpath.JSONPathMatch.pointer), which builds a [`JSONPointer`](api.md#jsonpath.JSONPointer) from a `JSONPathMatch`.
232232

233233
## `patch.apply(patch, data)`
234234

@@ -294,7 +294,7 @@ print(data) # {'some': {'other': 'thing', 'foo': {'bar': [1], 'else': 'thing'}}
294294

295295
## What's Next?
296296

297-
Read about the [Query Iterators](query.md) API or [user-defined filter functions](advanced.md#function-extensions). Also see how to make extra data available to filters with [Extra Filter Context](advanced.md#extra-filter-context).
297+
Read about the [Query Iterators](query.md) API or [user-defined filter functions](advanced.md#function-extensions). Also see how to make extra data available to filters with [Extra Filter Context](advanced.md#filter-variables).
298298

299299
`findall()`, `finditer()` and `compile()` are shortcuts that use the default[`JSONPathEnvironment`](api.md#jsonpath.JSONPathEnvironment). `jsonpath.findall(path, data)` is equivalent to:
300300

jsonpath/fluent_api.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ class Projection(Enum):
3131
"""Projection style used by `Query.select()`."""
3232

3333
RELATIVE = auto()
34-
ROOT = auto()
35-
FLAT = auto()
34+
"""The default projection. Selections include parent arrays and objects relative
35+
to the JSONPathMatch."""
3636

37+
ROOT = auto()
38+
"""Selections include parent arrays and objects relative to the root JSON value."""
3739

38-
EMPTY = object()
40+
FLAT = auto()
41+
"""All selections are appended to a new array/list, without arrays and objects
42+
on the path to the selected value."""
3943

4044

4145
class Query:
@@ -157,8 +161,16 @@ def select(
157161
) -> Iterable[object]:
158162
"""Query projection using relative JSONPaths.
159163
160-
Returns an iterable of objects built from selecting _expressions_ relative to
161-
each match from the current query.
164+
Arguments:
165+
expressions: One or more JSONPath query expressions to select relative
166+
to each match in this query iterator.
167+
projection: The style of projection used when selecting values. Can be
168+
one of `Projection.RELATIVE`, `Projection.ROOT` or `Projection.FLAT`.
169+
Defaults to `Projection.RELATIVE`.
170+
171+
Returns:
172+
An iterable of objects built from selecting _expressions_ relative to
173+
each match from the current query.
162174
"""
163175
return filter(
164176
bool,

0 commit comments

Comments
 (0)