Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ These breaking changes apply to Python JSONPath in its default configuration. We
- Added the [Keys filter selector](https://jg-rp.github.io/python-jsonpath/syntax/#keys-filter-selector).
- Added the [Singular query selector](https://jg-rp.github.io/python-jsonpath/syntax/#singular-query-selector).
- We now use the [regex] package, if available, instead of `re` for match and search function extensions. See [optional dependencies](https://jg-rp.github.io/python-jsonpath/#optional-dependencies).
- Added the `strict` argument to all [convenience functions](https://jg-rp.github.io/python-jsonpath/convenience/), the CLI and the `JSONPathEnvironment` constructor. When `strict=True`, all extensions to RFC 9535 and any lax parsing rules will be disabled.
- Added the `strict` argument to all [convenience functions](https://jg-rp.github.io/python-jsonpath/convenience/), the CLI and the `JSONPathEnvironment` constructor. When `strict=True`, all extensions to RFC 9535, any non-standard function extensions and any lax parsing rules will be disabled.
- Added class variable `JSONPathEnvironment.max_recursion_depth` to control the maximum recursion depth of descendant segments.
- Added pretty exception messages.

Expand Down
4 changes: 4 additions & 0 deletions docs/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

A filter function is a named function that can be called as part of a [filter selector](syntax.md#filter-selector). Here we describe built in filters. You can [define your own function extensions](advanced.md#function-extensions) too.

!!! note

If you pass `strict=True` when calling [`findall()`](convenience.md#jsonpath.findall), [`finditer()`](convenience.md#jsonpath.finditer), etc., Only standard functions - those defined by RFC 9535 - will be enabled. The standard functions are `count`, `length`, `match`, `search` and `value`.

## `count()`

```text
Expand Down
12 changes: 7 additions & 5 deletions jsonpath/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,11 +450,13 @@ def setup_function_extensions(self) -> None:
self.function_extensions["match"] = function_extensions.Match()
self.function_extensions["search"] = function_extensions.Search()
self.function_extensions["value"] = function_extensions.Value()
self.function_extensions["isinstance"] = function_extensions.IsInstance()
self.function_extensions["is"] = self.function_extensions["isinstance"]
self.function_extensions["typeof"] = function_extensions.TypeOf()
self.function_extensions["type"] = self.function_extensions["typeof"]
self.function_extensions["startswith"] = function_extensions.StartsWith()

if not self.strict:
self.function_extensions["isinstance"] = function_extensions.IsInstance()
self.function_extensions["is"] = self.function_extensions["isinstance"]
self.function_extensions["typeof"] = function_extensions.TypeOf()
self.function_extensions["type"] = self.function_extensions["typeof"]
self.function_extensions["startswith"] = function_extensions.StartsWith()

def validate_function_extension_signature(
self, token: Token, args: List[Any]
Expand Down
32 changes: 32 additions & 0 deletions tests/test_strictness.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from jsonpath import JSONPathEnvironment
from jsonpath import JSONPathNameError


@pytest.fixture()
Expand Down Expand Up @@ -73,3 +74,34 @@ def test_singular_path_selector_without_root_identifier(
}

assert env.findall(query, data) == [{"q": [4, 5, 6]}]


def test_isinstance_is_disabled_in_strict_mode() -> None:
env = JSONPathEnvironment(strict=True)

query = "$.some[?is(@.thing, 'string')]"
with pytest.raises(JSONPathNameError):
env.compile(query)

query = "$.some[?isinstance(@.thing, 'string')]"
with pytest.raises(JSONPathNameError):
env.compile(query)


def test_typeof_is_disabled_in_strict_mode() -> None:
env = JSONPathEnvironment(strict=True)

query = "$.some[?type(@.thing) == 'string']"
with pytest.raises(JSONPathNameError):
env.compile(query)

query = "$.some[?typeof(@.thing) == 'string']"
with pytest.raises(JSONPathNameError):
env.compile(query)


def test_startswith_is_disabled_in_strict_mode() -> None:
env = JSONPathEnvironment(strict=True)
query = "$[?startswith(@, 'ab')]"
with pytest.raises(JSONPathNameError):
env.compile(query)
Loading