File: typeof.py

package info (click to toggle)
python-jsonpath 2.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,028 kB
  • sloc: python: 9,473; makefile: 6
file content (54 lines) | stat: -rw-r--r-- 1,780 bytes parent folder | download
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
"""A non-standard "typeof" filter function."""

from typing import Mapping
from typing import Sequence

from jsonpath.filter import UNDEFINED
from jsonpath.filter import UNDEFINED_LITERAL
from jsonpath.function_extensions import ExpressionType
from jsonpath.function_extensions import FilterFunction
from jsonpath.match import NodeList


class TypeOf(FilterFunction):
    """A non-standard "typeof" filter function.

    Arguments:
        single_number_type: If True, will return "number" for ints and floats,
            otherwise we'll use "int" and "float" respectively. Defaults to `True`.
    """

    arg_types = [ExpressionType.NODES]
    return_type = ExpressionType.VALUE

    def __init__(self, *, single_number_type: bool = True) -> None:
        self.single_number_type = single_number_type

    def __call__(self, nodes: NodeList) -> str:  # noqa: PLR0911
        """Return the type of _obj_ as a string.

        The strings returned from this function use JSON terminology, much
        like the result of JavaScript's `typeof` operator.
        """
        if not nodes:
            return "undefined"

        obj = nodes.values_or_singular()

        if obj is UNDEFINED or obj is UNDEFINED_LITERAL:
            return "undefined"
        if obj is None:
            return "null"
        if isinstance(obj, str):
            return "string"
        if isinstance(obj, Sequence):
            return "array"
        if isinstance(obj, Mapping):
            return "object"
        if isinstance(obj, bool):
            return "boolean"
        if isinstance(obj, int):
            return "number" if self.single_number_type else "int"
        if isinstance(obj, float):
            return "number" if self.single_number_type else "float"
        return "object"