-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy patharguments.py
More file actions
57 lines (46 loc) · 1.66 KB
/
arguments.py
File metadata and controls
57 lines (46 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""Class-based function extension base."""
import inspect
from typing import TYPE_CHECKING
from typing import Any
from typing import Callable
from typing import List
if TYPE_CHECKING:
from jsonpath.env import JSONPathEnvironment
from jsonpath.token import Token
from jsonpath.exceptions import JSONPathTypeError
def validate(
_: "JSONPathEnvironment",
func: Callable[..., Any],
args: List[Any],
token: "Token",
) -> List[Any]:
"""Generic validation of function extension arguments using introspection.
RFC 9535 requires us to reject paths that use filter functions with too
many or too few arguments.
"""
params = list(inspect.signature(func).parameters.values())
# Keyword only params are not supported
if [p for p in params if p.kind in (p.KEYWORD_ONLY, p.VAR_KEYWORD)]:
raise JSONPathTypeError(
f"function {token.value!r} requires keyword arguments",
token=token,
)
# Too few args?
positional_args = [
p for p in params if p.kind in (p.POSITIONAL_ONLY, p.POSITIONAL_OR_KEYWORD)
]
if len(args) < len(positional_args):
raise JSONPathTypeError(
f"{token.value!r}() requires {len(positional_args)} arguments",
token=token,
)
# Does the signature have var args?
has_var_args = bool([p for p in params if p.kind == p.VAR_POSITIONAL])
# Too many args?
if not has_var_args and len(args) > len(positional_args):
raise JSONPathTypeError(
f"{token.value!r}() requires at most "
f"{len(positional_args) + len(positional_args)} arguments",
token=token,
)
return args