jsonlogic-py 0.2__tar.gz → 0.2.2__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.
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/PKG-INFO +2 -2
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/pyproject.toml +4 -1
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/requirements-dev.txt +1 -1
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic/__init__.py +23 -12
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic/jsontypes.py +6 -6
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic/operations.py +4 -2
- jsonlogic_py-0.2.2/src/jsonlogic/py.typed +0 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic_py.egg-info/PKG-INFO +2 -2
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic_py.egg-info/SOURCES.txt +1 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic_py.egg-info/requires.txt +1 -1
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/test/test_classes.py +4 -6
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/test/test_jsonlogic.py +1 -1
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/test/test_types.py +7 -7
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/README.md +0 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/requirements.txt +0 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/setup.cfg +0 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic/classes.py +0 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic/errors.py +0 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic_py.egg-info/dependency_links.txt +0 -0
- {jsonlogic_py-0.2 → jsonlogic_py-0.2.2}/src/jsonlogic_py.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jsonlogic-py
|
|
3
|
-
Version: 0.2
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A Python package that emits JSON Logic
|
|
5
5
|
Author: Peter Pirkelbauer, Seth Bromberger
|
|
6
6
|
Project-URL: Homepage, https://github.com/MetallData/jsonlogic
|
|
@@ -16,7 +16,7 @@ Provides-Extra: dev
|
|
|
16
16
|
Requires-Dist: pytest; extra == "dev"
|
|
17
17
|
Requires-Dist: coverage; extra == "dev"
|
|
18
18
|
Requires-Dist: json-logic-qubit; extra == "dev"
|
|
19
|
-
Requires-Dist:
|
|
19
|
+
Requires-Dist: ruff; extra == "dev"
|
|
20
20
|
Requires-Dist: mypy; extra == "dev"
|
|
21
21
|
|
|
22
22
|
## jsonlogic.py - JSON Logic expression generator
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "jsonlogic-py"
|
|
7
|
-
version = "0.2"
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Peter Pirkelbauer"}, { name="Seth Bromberger"}
|
|
10
10
|
]
|
|
@@ -24,7 +24,10 @@ classifiers = [
|
|
|
24
24
|
dependencies = {file = ["requirements.txt"]}
|
|
25
25
|
optional-dependencies = {dev = {file = ["requirements-dev.txt"] }}
|
|
26
26
|
|
|
27
|
+
[tool.setuptools.package-data]
|
|
28
|
+
jsonlogic = ["py.typed"]
|
|
27
29
|
|
|
28
30
|
[project.urls]
|
|
29
31
|
Homepage = "https://github.com/MetallData/jsonlogic"
|
|
30
32
|
Issues = "https://github.com/MetallData/jsonlogic/issues"
|
|
33
|
+
|
|
@@ -17,16 +17,16 @@ class Operand(Entity):
|
|
|
17
17
|
setattr(cls, dunder, lambda self, *x, o=op: Expression(o, self, *x))
|
|
18
18
|
return super().__new__(cls)
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def _prepare(self) -> Any:
|
|
21
21
|
"""prepares the structure for json by converting it into something that can be dumped"""
|
|
22
22
|
raise NotImplementedError()
|
|
23
23
|
|
|
24
|
-
def
|
|
24
|
+
def _to_json(self) -> str:
|
|
25
25
|
"""represents the object as JSON"""
|
|
26
|
-
return json.dumps(self.
|
|
26
|
+
return json.dumps(self._prepare())
|
|
27
27
|
|
|
28
28
|
def __str__(self):
|
|
29
|
-
return self.
|
|
29
|
+
return self._to_json()
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class Literal(Operand):
|
|
@@ -46,8 +46,8 @@ class Literal(Operand):
|
|
|
46
46
|
def __str__(self):
|
|
47
47
|
return str(self.type)
|
|
48
48
|
|
|
49
|
-
def
|
|
50
|
-
return self.type.
|
|
49
|
+
def _prepare(self) -> PyJsonType:
|
|
50
|
+
return self.type._prepare()
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
class Variable(Operand):
|
|
@@ -55,12 +55,12 @@ class Variable(Operand):
|
|
|
55
55
|
|
|
56
56
|
def __init__(self, var: str, docstr: str | None = None):
|
|
57
57
|
super().__init__()
|
|
58
|
-
self.
|
|
58
|
+
self._var = var
|
|
59
59
|
if docstr is not None:
|
|
60
60
|
self.__doc__ = docstr
|
|
61
61
|
|
|
62
|
-
def
|
|
63
|
-
return {"var": self.
|
|
62
|
+
def _prepare(self):
|
|
63
|
+
return {"var": self._var}
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
class Expression(Operand):
|
|
@@ -83,10 +83,18 @@ class Expression(Operand):
|
|
|
83
83
|
# add the remaining variables, casting them to Literals if they're not Variables, Expressions, or Literals.
|
|
84
84
|
self.on = tuple(Literal(o) if not isinstance(o, Operand) else o for o in on)
|
|
85
85
|
|
|
86
|
-
def
|
|
86
|
+
def _prepare(self):
|
|
87
|
+
if self.op.op == "contains":
|
|
88
|
+
o2 = self.on[0]
|
|
89
|
+
o2prep = o2._prepare() if isinstance(o2, Operand) else o2
|
|
90
|
+
o1prep = self.o1._prepare() if isinstance(self.o1, Operand) else self.o1
|
|
91
|
+
return {
|
|
92
|
+
"in": [o2prep, o1prep]
|
|
93
|
+
}
|
|
94
|
+
|
|
87
95
|
return {
|
|
88
|
-
str(self.op): [self.o1.
|
|
89
|
-
+ list(x.
|
|
96
|
+
str(self.op): [self.o1._prepare()]
|
|
97
|
+
+ list(x._prepare() if isinstance(x, Operand) else x for x in self.on)
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
|
|
@@ -126,3 +134,6 @@ class Expression(Operand):
|
|
|
126
134
|
|
|
127
135
|
# class _Any(Type, Any):
|
|
128
136
|
# """Type representing any JSONLogic type"""
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
__all__ = ["Operation", "Operand", "Literal", "Variable", "Expression"]
|
|
@@ -22,7 +22,7 @@ class JsonType(ABC):
|
|
|
22
22
|
def __str__(self):
|
|
23
23
|
return f"[{self.typename}]{self.val}"
|
|
24
24
|
|
|
25
|
-
def
|
|
25
|
+
def _prepare(self) -> PyJsonType:
|
|
26
26
|
"""Prepares the type for JSON serialization"""
|
|
27
27
|
raise NotImplementedError("class has not defined prepare()")
|
|
28
28
|
|
|
@@ -32,7 +32,7 @@ class JsonNumber(JsonType):
|
|
|
32
32
|
|
|
33
33
|
typename = "Number"
|
|
34
34
|
|
|
35
|
-
def
|
|
35
|
+
def _prepare(self):
|
|
36
36
|
return int(self.val) if isinstance(self.val, int) else float(self.val)
|
|
37
37
|
|
|
38
38
|
|
|
@@ -41,7 +41,7 @@ class JsonBool(JsonType):
|
|
|
41
41
|
|
|
42
42
|
typename = "Boolean"
|
|
43
43
|
|
|
44
|
-
def
|
|
44
|
+
def _prepare(self) -> bool:
|
|
45
45
|
return bool(self.val)
|
|
46
46
|
|
|
47
47
|
|
|
@@ -50,7 +50,7 @@ class JsonStr(JsonType):
|
|
|
50
50
|
|
|
51
51
|
typename = "String"
|
|
52
52
|
|
|
53
|
-
def
|
|
53
|
+
def _prepare(self) -> str:
|
|
54
54
|
return str(self.val)
|
|
55
55
|
|
|
56
56
|
|
|
@@ -59,7 +59,7 @@ class JsonArray(JsonType):
|
|
|
59
59
|
|
|
60
60
|
typename = "Array"
|
|
61
61
|
|
|
62
|
-
def
|
|
62
|
+
def _prepare(self) -> list:
|
|
63
63
|
return list(self.val)
|
|
64
64
|
|
|
65
65
|
|
|
@@ -68,7 +68,7 @@ class JsonObj(JsonType):
|
|
|
68
68
|
|
|
69
69
|
typename = "Object"
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def _prepare(self) -> dict:
|
|
72
72
|
return dict(self.val)
|
|
73
73
|
|
|
74
74
|
|
|
@@ -56,13 +56,14 @@ _jl_or = Operation("or", 2) # single |
|
|
|
56
56
|
# # return Expression("in", o, self)
|
|
57
57
|
|
|
58
58
|
# # to be modeled after Pandas' str.contains
|
|
59
|
-
_jl_contains = Operation("
|
|
59
|
+
_jl_contains = Operation("contains", 2)
|
|
60
|
+
_jl_isin = Operation("in", 2)
|
|
60
61
|
_jl_regex = Operation("regex", 2)
|
|
61
62
|
|
|
62
63
|
# string and array concatenation
|
|
63
64
|
_jl_cat = Operation("cat", None)
|
|
64
65
|
|
|
65
|
-
jl_operations: dict[str, Operation
|
|
66
|
+
jl_operations: dict[str, Operation] = {
|
|
66
67
|
"__lt__": _jl_lt,
|
|
67
68
|
"__le__": _jl_le,
|
|
68
69
|
"__eq__": _jl_eq,
|
|
@@ -85,6 +86,7 @@ jl_operations: dict[str, Operation | Callable[..., Operation]] = {
|
|
|
85
86
|
"__or__": _jl_or,
|
|
86
87
|
"__invert__": _jl_not,
|
|
87
88
|
"contains": _jl_contains,
|
|
89
|
+
"isin": _jl_isin,
|
|
88
90
|
"regex": _jl_regex,
|
|
89
91
|
"cat": _jl_cat,
|
|
90
92
|
}
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jsonlogic-py
|
|
3
|
-
Version: 0.2
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A Python package that emits JSON Logic
|
|
5
5
|
Author: Peter Pirkelbauer, Seth Bromberger
|
|
6
6
|
Project-URL: Homepage, https://github.com/MetallData/jsonlogic
|
|
@@ -16,7 +16,7 @@ Provides-Extra: dev
|
|
|
16
16
|
Requires-Dist: pytest; extra == "dev"
|
|
17
17
|
Requires-Dist: coverage; extra == "dev"
|
|
18
18
|
Requires-Dist: json-logic-qubit; extra == "dev"
|
|
19
|
-
Requires-Dist:
|
|
19
|
+
Requires-Dist: ruff; extra == "dev"
|
|
20
20
|
Requires-Dist: mypy; extra == "dev"
|
|
21
21
|
|
|
22
22
|
## jsonlogic.py - JSON Logic expression generator
|
|
@@ -4,8 +4,6 @@ import sys
|
|
|
4
4
|
sys.path.append("src")
|
|
5
5
|
|
|
6
6
|
from jsonlogic import Expression, Variable, Literal, Operand, Operation
|
|
7
|
-
from jsonlogic.classes import Entity
|
|
8
|
-
from dataclasses import dataclass
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
@pytest.fixture
|
|
@@ -40,13 +38,13 @@ def l2():
|
|
|
40
38
|
|
|
41
39
|
def test_expression(op1, op2, v1, v2, l1, l2):
|
|
42
40
|
e = Expression(op1, v1)
|
|
43
|
-
assert e.
|
|
41
|
+
assert e._to_json() == str(e) == '{"op1": [{"var": "var1"}]}'
|
|
44
42
|
|
|
45
43
|
e = Expression(op2, v1, v2)
|
|
46
|
-
assert e.
|
|
44
|
+
assert e._to_json() == str(e) == '{"op2": [{"var": "var1"}, {"var": "var2"}]}'
|
|
47
45
|
|
|
48
46
|
e = Expression(op2, v1, l1)
|
|
49
|
-
assert e.
|
|
47
|
+
assert e._to_json() == str(e) == '{"op2": [{"var": "var1"}, 5]}'
|
|
50
48
|
|
|
51
49
|
|
|
52
50
|
def test_operations():
|
|
@@ -63,4 +61,4 @@ def test_literals(l1, l2):
|
|
|
63
61
|
def test_operand():
|
|
64
62
|
o = Operand()
|
|
65
63
|
with pytest.raises(NotImplementedError):
|
|
66
|
-
o.
|
|
64
|
+
o._prepare()
|
|
@@ -12,7 +12,7 @@ def test_bool():
|
|
|
12
12
|
assert b.val is True
|
|
13
13
|
assert isinstance(b.val, bool)
|
|
14
14
|
assert str(b) == "[Boolean]True"
|
|
15
|
-
assert b.
|
|
15
|
+
assert b._prepare() is True
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def test_int():
|
|
@@ -21,7 +21,7 @@ def test_int():
|
|
|
21
21
|
assert b.val == 10
|
|
22
22
|
assert isinstance(b.val, int)
|
|
23
23
|
assert str(b) == "[Number]10"
|
|
24
|
-
assert b.
|
|
24
|
+
assert b._prepare() == 10
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def test_float():
|
|
@@ -30,7 +30,7 @@ def test_float():
|
|
|
30
30
|
assert b.val == 10.1
|
|
31
31
|
assert isinstance(b.val, float)
|
|
32
32
|
assert str(b) == "[Number]10.1"
|
|
33
|
-
assert b.
|
|
33
|
+
assert b._prepare() == 10.1
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def test_dict():
|
|
@@ -40,7 +40,7 @@ def test_dict():
|
|
|
40
40
|
assert b.val == d
|
|
41
41
|
assert isinstance(b.val, dict)
|
|
42
42
|
assert str(b).startswith("[Object]")
|
|
43
|
-
assert b.
|
|
43
|
+
assert b._prepare() == d
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
def test_str():
|
|
@@ -49,7 +49,7 @@ def test_str():
|
|
|
49
49
|
assert b.val == "hello"
|
|
50
50
|
assert isinstance(b.val, str)
|
|
51
51
|
assert str(b).startswith("[String]")
|
|
52
|
-
assert b.
|
|
52
|
+
assert b._prepare() == "hello"
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
def test_list():
|
|
@@ -59,7 +59,7 @@ def test_list():
|
|
|
59
59
|
assert b.val == d
|
|
60
60
|
assert isinstance(b.val, list)
|
|
61
61
|
assert str(b).startswith("[Array]")
|
|
62
|
-
assert b.
|
|
62
|
+
assert b._prepare() == d
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
def test_deduce():
|
|
@@ -82,4 +82,4 @@ def test_jsontype():
|
|
|
82
82
|
assert tt.typename == "UNDEFINED"
|
|
83
83
|
assert str(tt) == "[UNDEFINED]10"
|
|
84
84
|
with pytest.raises(NotImplementedError):
|
|
85
|
-
tt.
|
|
85
|
+
tt._prepare()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|