promcraft 0.1.0__py3-none-any.whl
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.
- promcraft/__init__.py +251 -0
- promcraft/aggregation.py +225 -0
- promcraft/base.py +90 -0
- promcraft/functions.py +521 -0
- promcraft/operator.py +367 -0
- promcraft/py.typed +0 -0
- promcraft/scalar.py +88 -0
- promcraft/string.py +37 -0
- promcraft/vector.py +168 -0
- promcraft-0.1.0.dist-info/METADATA +670 -0
- promcraft-0.1.0.dist-info/RECORD +13 -0
- promcraft-0.1.0.dist-info/WHEEL +4 -0
- promcraft-0.1.0.dist-info/licenses/LICENSE +21 -0
promcraft/__init__.py
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
from promcraft.aggregation import (
|
|
2
|
+
AggregationOperator,
|
|
3
|
+
Grouping,
|
|
4
|
+
avg,
|
|
5
|
+
bottomk,
|
|
6
|
+
count,
|
|
7
|
+
count_values,
|
|
8
|
+
group,
|
|
9
|
+
limit_ratio,
|
|
10
|
+
limitk,
|
|
11
|
+
max,
|
|
12
|
+
min,
|
|
13
|
+
quantile,
|
|
14
|
+
stddev,
|
|
15
|
+
stdvar,
|
|
16
|
+
sum,
|
|
17
|
+
topk,
|
|
18
|
+
)
|
|
19
|
+
from promcraft.base import Query
|
|
20
|
+
from promcraft.operator import (
|
|
21
|
+
BinaryOprator,
|
|
22
|
+
Group,
|
|
23
|
+
Match,
|
|
24
|
+
add,
|
|
25
|
+
and_,
|
|
26
|
+
atan2,
|
|
27
|
+
div,
|
|
28
|
+
eq,
|
|
29
|
+
gt,
|
|
30
|
+
gte,
|
|
31
|
+
lt,
|
|
32
|
+
lte,
|
|
33
|
+
mod,
|
|
34
|
+
mul,
|
|
35
|
+
neq,
|
|
36
|
+
or_,
|
|
37
|
+
pow,
|
|
38
|
+
sub,
|
|
39
|
+
unless,
|
|
40
|
+
)
|
|
41
|
+
from promcraft.scalar import Duration, Float, Hex, Scalar
|
|
42
|
+
from promcraft.string import String
|
|
43
|
+
from promcraft.vector import InstantVector, Label, RangeVector
|
|
44
|
+
|
|
45
|
+
# isort: split
|
|
46
|
+
# promcraft.functions must be imported AFTER promcraft.scalar and promcraft.vector so that
|
|
47
|
+
# our 'scalar' and 'vector' function names overwrite the submodule bindings that Python
|
|
48
|
+
# injects automatically when a submodule is imported.
|
|
49
|
+
from promcraft.functions import (
|
|
50
|
+
Function,
|
|
51
|
+
abs,
|
|
52
|
+
absent,
|
|
53
|
+
absent_over_time,
|
|
54
|
+
acos,
|
|
55
|
+
acosh,
|
|
56
|
+
asin,
|
|
57
|
+
asinh,
|
|
58
|
+
atan,
|
|
59
|
+
atanh,
|
|
60
|
+
avg_over_time,
|
|
61
|
+
ceil,
|
|
62
|
+
changes,
|
|
63
|
+
clamp,
|
|
64
|
+
clamp_max,
|
|
65
|
+
clamp_min,
|
|
66
|
+
cos,
|
|
67
|
+
cosh,
|
|
68
|
+
count_over_time,
|
|
69
|
+
day_of_month,
|
|
70
|
+
day_of_week,
|
|
71
|
+
day_of_year,
|
|
72
|
+
days_in_month,
|
|
73
|
+
deg,
|
|
74
|
+
delta,
|
|
75
|
+
deriv,
|
|
76
|
+
double_exponential_smoothing,
|
|
77
|
+
exp,
|
|
78
|
+
floor,
|
|
79
|
+
histogram_avg,
|
|
80
|
+
histogram_count,
|
|
81
|
+
histogram_fraction,
|
|
82
|
+
histogram_quantile,
|
|
83
|
+
histogram_stddev,
|
|
84
|
+
histogram_stdvar,
|
|
85
|
+
histogram_sum,
|
|
86
|
+
hour,
|
|
87
|
+
idelta,
|
|
88
|
+
increase,
|
|
89
|
+
info,
|
|
90
|
+
irate,
|
|
91
|
+
label_join,
|
|
92
|
+
label_replace,
|
|
93
|
+
last_over_time,
|
|
94
|
+
ln,
|
|
95
|
+
log2,
|
|
96
|
+
log10,
|
|
97
|
+
max_over_time,
|
|
98
|
+
min_over_time,
|
|
99
|
+
minute,
|
|
100
|
+
month,
|
|
101
|
+
pi,
|
|
102
|
+
predict_linear,
|
|
103
|
+
present_over_time,
|
|
104
|
+
quantile_over_time,
|
|
105
|
+
rad,
|
|
106
|
+
rate,
|
|
107
|
+
resets,
|
|
108
|
+
round,
|
|
109
|
+
scalar,
|
|
110
|
+
sgn,
|
|
111
|
+
sin,
|
|
112
|
+
sinh,
|
|
113
|
+
sort,
|
|
114
|
+
sort_by_label,
|
|
115
|
+
sort_by_label_desc,
|
|
116
|
+
sort_desc,
|
|
117
|
+
sqrt,
|
|
118
|
+
stddev_over_time,
|
|
119
|
+
stdvar_over_time,
|
|
120
|
+
sum_over_time,
|
|
121
|
+
tan,
|
|
122
|
+
tanh,
|
|
123
|
+
time,
|
|
124
|
+
timestamp,
|
|
125
|
+
vector,
|
|
126
|
+
year,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
__all__ = [
|
|
130
|
+
"AggregationOperator",
|
|
131
|
+
"BinaryOprator",
|
|
132
|
+
"Duration",
|
|
133
|
+
"Float",
|
|
134
|
+
"Function",
|
|
135
|
+
"Group",
|
|
136
|
+
"Grouping",
|
|
137
|
+
"Hex",
|
|
138
|
+
"InstantVector",
|
|
139
|
+
"Label",
|
|
140
|
+
"Match",
|
|
141
|
+
"Query",
|
|
142
|
+
"RangeVector",
|
|
143
|
+
"Scalar",
|
|
144
|
+
"String",
|
|
145
|
+
"abs",
|
|
146
|
+
"absent",
|
|
147
|
+
"absent_over_time",
|
|
148
|
+
"acos",
|
|
149
|
+
"acosh",
|
|
150
|
+
"add",
|
|
151
|
+
"and_",
|
|
152
|
+
"asin",
|
|
153
|
+
"asinh",
|
|
154
|
+
"atan",
|
|
155
|
+
"atan2",
|
|
156
|
+
"atanh",
|
|
157
|
+
"avg",
|
|
158
|
+
"avg_over_time",
|
|
159
|
+
"bottomk",
|
|
160
|
+
"ceil",
|
|
161
|
+
"changes",
|
|
162
|
+
"clamp",
|
|
163
|
+
"clamp_max",
|
|
164
|
+
"clamp_min",
|
|
165
|
+
"cos",
|
|
166
|
+
"cosh",
|
|
167
|
+
"count",
|
|
168
|
+
"count_over_time",
|
|
169
|
+
"count_values",
|
|
170
|
+
"day_of_month",
|
|
171
|
+
"day_of_week",
|
|
172
|
+
"day_of_year",
|
|
173
|
+
"days_in_month",
|
|
174
|
+
"deg",
|
|
175
|
+
"delta",
|
|
176
|
+
"deriv",
|
|
177
|
+
"div",
|
|
178
|
+
"double_exponential_smoothing",
|
|
179
|
+
"eq",
|
|
180
|
+
"exp",
|
|
181
|
+
"floor",
|
|
182
|
+
"group",
|
|
183
|
+
"gt",
|
|
184
|
+
"gte",
|
|
185
|
+
"histogram_avg",
|
|
186
|
+
"histogram_count",
|
|
187
|
+
"histogram_fraction",
|
|
188
|
+
"histogram_quantile",
|
|
189
|
+
"histogram_stddev",
|
|
190
|
+
"histogram_stdvar",
|
|
191
|
+
"histogram_sum",
|
|
192
|
+
"hour",
|
|
193
|
+
"idelta",
|
|
194
|
+
"increase",
|
|
195
|
+
"info",
|
|
196
|
+
"irate",
|
|
197
|
+
"label_join",
|
|
198
|
+
"label_replace",
|
|
199
|
+
"last_over_time",
|
|
200
|
+
"limit_ratio",
|
|
201
|
+
"limitk",
|
|
202
|
+
"ln",
|
|
203
|
+
"log2",
|
|
204
|
+
"log10",
|
|
205
|
+
"lt",
|
|
206
|
+
"lte",
|
|
207
|
+
"max",
|
|
208
|
+
"max_over_time",
|
|
209
|
+
"min",
|
|
210
|
+
"min_over_time",
|
|
211
|
+
"minute",
|
|
212
|
+
"mod",
|
|
213
|
+
"month",
|
|
214
|
+
"mul",
|
|
215
|
+
"neq",
|
|
216
|
+
"or_",
|
|
217
|
+
"pi",
|
|
218
|
+
"pow",
|
|
219
|
+
"predict_linear",
|
|
220
|
+
"present_over_time",
|
|
221
|
+
"quantile",
|
|
222
|
+
"quantile_over_time",
|
|
223
|
+
"rad",
|
|
224
|
+
"rate",
|
|
225
|
+
"resets",
|
|
226
|
+
"round",
|
|
227
|
+
"scalar",
|
|
228
|
+
"sgn",
|
|
229
|
+
"sin",
|
|
230
|
+
"sinh",
|
|
231
|
+
"sort",
|
|
232
|
+
"sort_by_label",
|
|
233
|
+
"sort_by_label_desc",
|
|
234
|
+
"sort_desc",
|
|
235
|
+
"sqrt",
|
|
236
|
+
"stddev",
|
|
237
|
+
"stddev_over_time",
|
|
238
|
+
"stdvar",
|
|
239
|
+
"stdvar_over_time",
|
|
240
|
+
"sub",
|
|
241
|
+
"sum",
|
|
242
|
+
"sum_over_time",
|
|
243
|
+
"tan",
|
|
244
|
+
"tanh",
|
|
245
|
+
"time",
|
|
246
|
+
"timestamp",
|
|
247
|
+
"topk",
|
|
248
|
+
"unless",
|
|
249
|
+
"vector",
|
|
250
|
+
"year",
|
|
251
|
+
]
|
promcraft/aggregation.py
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from promcraft.base import Query
|
|
5
|
+
from promcraft.scalar import Scalar
|
|
6
|
+
from promcraft.string import String
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Grouping:
|
|
10
|
+
"""Aggregation grouping clause that controls which label dimensions appear in results.
|
|
11
|
+
|
|
12
|
+
- ``by(labels)`` — keep only the listed labels in the output.
|
|
13
|
+
- ``without(labels)`` — drop the listed labels; preserve all others.
|
|
14
|
+
|
|
15
|
+
Example::
|
|
16
|
+
|
|
17
|
+
Grouping.by(["job", "env"]) # → 'by(job, env)'
|
|
18
|
+
Grouping.without(["instance"]) # → 'without(instance)'
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, type: Literal["by", "without"], labels: list[str]) -> None:
|
|
22
|
+
self.type = type
|
|
23
|
+
self.labels = labels
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def by(cls, labels: list[str]) -> "Grouping":
|
|
27
|
+
"""Return a ``by(labels)`` grouping clause."""
|
|
28
|
+
return cls("by", labels)
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def without(cls, labels: list[str]) -> "Grouping":
|
|
32
|
+
"""Return a ``without(labels)`` grouping clause."""
|
|
33
|
+
return cls("without", labels)
|
|
34
|
+
|
|
35
|
+
def __str__(self) -> str:
|
|
36
|
+
labels_str = ", ".join(self.labels)
|
|
37
|
+
return f"{self.type}({labels_str})"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class AggregationOperator(Query):
|
|
41
|
+
"""A PromQL aggregation expression that collapses multiple time series into fewer results.
|
|
42
|
+
|
|
43
|
+
Aggregation operators reduce a set of series by computing a single
|
|
44
|
+
output value per group. An optional :class:`Grouping` clause
|
|
45
|
+
(``by`` / ``without``) controls which label dimensions define the groups.
|
|
46
|
+
Some operators (``topk``, ``bottomk``, ``count_values``, ``quantile``,
|
|
47
|
+
``limitk``, ``limit_ratio``) require an additional scalar or string
|
|
48
|
+
``parameter``.
|
|
49
|
+
|
|
50
|
+
The fluent :meth:`by` and :meth:`without` methods return new immutable
|
|
51
|
+
instances with the grouping applied.
|
|
52
|
+
|
|
53
|
+
Example::
|
|
54
|
+
|
|
55
|
+
AggregationOperator(AggregationOperator.Operator.SUM, v).by(["job"])
|
|
56
|
+
# → 'sum(v) by(job)'
|
|
57
|
+
|
|
58
|
+
AggregationOperator(AggregationOperator.Operator.TOPK, v, parameter=Float(5))
|
|
59
|
+
# → 'topk(5.0, v)'
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
class Operator(enum.Enum):
|
|
63
|
+
"""Enum of all PromQL aggregation operators."""
|
|
64
|
+
|
|
65
|
+
SUM = "sum"
|
|
66
|
+
AVG = "avg"
|
|
67
|
+
MIN = "min"
|
|
68
|
+
MAX = "max"
|
|
69
|
+
COUNT = "count"
|
|
70
|
+
GROUP = "group"
|
|
71
|
+
STDDEV = "stddev"
|
|
72
|
+
STDVAR = "stdvar"
|
|
73
|
+
TOPK = "topk"
|
|
74
|
+
BOTTOMK = "bottomk"
|
|
75
|
+
COUNT_VALUES = "count_values"
|
|
76
|
+
QUANTILE = "quantile"
|
|
77
|
+
LIMITK = "limitk"
|
|
78
|
+
LIMIT_RATIO = "limit_ratio"
|
|
79
|
+
|
|
80
|
+
def __str__(self) -> str:
|
|
81
|
+
return self.value
|
|
82
|
+
|
|
83
|
+
def __init__(
|
|
84
|
+
self,
|
|
85
|
+
op: Operator,
|
|
86
|
+
vector: Query,
|
|
87
|
+
parameter: Scalar | String | None = None,
|
|
88
|
+
grouping: Grouping | None = None,
|
|
89
|
+
) -> None:
|
|
90
|
+
self.op = op
|
|
91
|
+
self.vector = vector
|
|
92
|
+
self.parameter = parameter
|
|
93
|
+
self.grouping = grouping
|
|
94
|
+
|
|
95
|
+
def __str__(self) -> str:
|
|
96
|
+
grouping_str = f" {self.grouping}" if self.grouping else ""
|
|
97
|
+
if self.parameter is not None:
|
|
98
|
+
args = f"{self.parameter}, {self.vector}"
|
|
99
|
+
else:
|
|
100
|
+
args = str(self.vector)
|
|
101
|
+
return f"{self.op}({args}){grouping_str}"
|
|
102
|
+
|
|
103
|
+
def by(self, labels: list[str]) -> "AggregationOperator":
|
|
104
|
+
"""Return a copy of this aggregation with a ``by(labels)`` grouping clause."""
|
|
105
|
+
return AggregationOperator(
|
|
106
|
+
op=self.op,
|
|
107
|
+
vector=self.vector,
|
|
108
|
+
parameter=self.parameter,
|
|
109
|
+
grouping=Grouping.by(labels),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def without(self, labels: list[str]) -> "AggregationOperator":
|
|
113
|
+
"""Return a copy of this aggregation with a ``without(labels)`` grouping clause."""
|
|
114
|
+
return AggregationOperator(
|
|
115
|
+
op=self.op,
|
|
116
|
+
vector=self.vector,
|
|
117
|
+
parameter=self.parameter,
|
|
118
|
+
grouping=Grouping.without(labels),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def sum(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
123
|
+
"""Sum of all sample values across the aggregated dimensions (``sum(v)``)."""
|
|
124
|
+
return AggregationOperator(AggregationOperator.Operator.SUM, vector, grouping=grouping)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def avg(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
128
|
+
"""Arithmetic mean of sample values across the aggregated dimensions (``avg(v)``)."""
|
|
129
|
+
return AggregationOperator(AggregationOperator.Operator.AVG, vector, grouping=grouping)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def min(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
133
|
+
"""Smallest sample value across the aggregated dimensions (``min(v)``)."""
|
|
134
|
+
return AggregationOperator(AggregationOperator.Operator.MIN, vector, grouping=grouping)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def max(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
138
|
+
"""Largest sample value across the aggregated dimensions (``max(v)``)."""
|
|
139
|
+
return AggregationOperator(AggregationOperator.Operator.MAX, vector, grouping=grouping)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def count(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
143
|
+
"""Number of time series in the aggregated dimensions (``count(v)``)."""
|
|
144
|
+
return AggregationOperator(AggregationOperator.Operator.COUNT, vector, grouping=grouping)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def group(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
148
|
+
"""Return 1 for each group that contains at least one element (``group(v)``)."""
|
|
149
|
+
return AggregationOperator(AggregationOperator.Operator.GROUP, vector, grouping=grouping)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def stddev(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
153
|
+
"""Population standard deviation of sample values across the aggregated dimensions.
|
|
154
|
+
|
|
155
|
+
PromQL: ``stddev(v)``
|
|
156
|
+
"""
|
|
157
|
+
return AggregationOperator(AggregationOperator.Operator.STDDEV, vector, grouping=grouping)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def stdvar(vector: Query, grouping: Grouping | None = None) -> AggregationOperator:
|
|
161
|
+
"""Population standard variance of sample values across the aggregated dimensions.
|
|
162
|
+
|
|
163
|
+
PromQL: ``stdvar(v)``
|
|
164
|
+
"""
|
|
165
|
+
return AggregationOperator(AggregationOperator.Operator.STDVAR, vector, grouping=grouping)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def topk(
|
|
169
|
+
parameter: Scalar, vector: Query, grouping: Grouping | None = None
|
|
170
|
+
) -> AggregationOperator:
|
|
171
|
+
"""Largest ``k`` sample values across the aggregated dimensions (``topk(k, v)``)."""
|
|
172
|
+
return AggregationOperator(
|
|
173
|
+
AggregationOperator.Operator.TOPK, vector, parameter=parameter, grouping=grouping
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def bottomk(
|
|
178
|
+
parameter: Scalar, vector: Query, grouping: Grouping | None = None
|
|
179
|
+
) -> AggregationOperator:
|
|
180
|
+
"""Smallest ``k`` sample values across the aggregated dimensions (``bottomk(k, v)``)."""
|
|
181
|
+
return AggregationOperator(
|
|
182
|
+
AggregationOperator.Operator.BOTTOMK, vector, parameter=parameter, grouping=grouping
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def count_values(
|
|
187
|
+
parameter: String, vector: Query, grouping: Grouping | None = None
|
|
188
|
+
) -> AggregationOperator:
|
|
189
|
+
"""Count the number of series per unique sample value, writing counts to ``parameter`` label.
|
|
190
|
+
|
|
191
|
+
PromQL: ``count_values(label, v)``
|
|
192
|
+
"""
|
|
193
|
+
return AggregationOperator(
|
|
194
|
+
AggregationOperator.Operator.COUNT_VALUES, vector, parameter=parameter, grouping=grouping
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def quantile(
|
|
199
|
+
parameter: Scalar, vector: Query, grouping: Grouping | None = None
|
|
200
|
+
) -> AggregationOperator:
|
|
201
|
+
"""φ-quantile (0 ≤ φ ≤ 1) of sample values across the aggregated dimensions.
|
|
202
|
+
|
|
203
|
+
PromQL: ``quantile(φ, v)``
|
|
204
|
+
"""
|
|
205
|
+
return AggregationOperator(
|
|
206
|
+
AggregationOperator.Operator.QUANTILE, vector, parameter=parameter, grouping=grouping
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def limitk(
|
|
211
|
+
parameter: Scalar, vector: Query, grouping: Grouping | None = None
|
|
212
|
+
) -> AggregationOperator:
|
|
213
|
+
"""Pseudo-randomly sample at most ``k`` series from the input (``limitk(k, v)``)."""
|
|
214
|
+
return AggregationOperator(
|
|
215
|
+
AggregationOperator.Operator.LIMITK, vector, parameter=parameter, grouping=grouping
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def limit_ratio(
|
|
220
|
+
parameter: Scalar, vector: Query, grouping: Grouping | None = None
|
|
221
|
+
) -> AggregationOperator:
|
|
222
|
+
"""Pseudo-randomly sample fraction ``r`` of series from the input (``limit_ratio(r, v)``)."""
|
|
223
|
+
return AggregationOperator(
|
|
224
|
+
AggregationOperator.Operator.LIMIT_RATIO, vector, parameter=parameter, grouping=grouping
|
|
225
|
+
)
|
promcraft/base.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from promcraft.operator import BinaryOprator
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Query(ABC):
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def __str__(self) -> str:
|
|
11
|
+
raise NotImplementedError(
|
|
12
|
+
"Subclasses must implement __str__ method",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
def __add__(self, other: "Query") -> "BinaryOprator":
|
|
16
|
+
from promcraft.operator import add
|
|
17
|
+
|
|
18
|
+
return add(self, other)
|
|
19
|
+
|
|
20
|
+
def __sub__(self, other: "Query") -> "BinaryOprator":
|
|
21
|
+
from promcraft.operator import sub
|
|
22
|
+
|
|
23
|
+
return sub(self, other)
|
|
24
|
+
|
|
25
|
+
def __mul__(self, other: "Query") -> "BinaryOprator":
|
|
26
|
+
from promcraft.operator import mul
|
|
27
|
+
|
|
28
|
+
return mul(self, other)
|
|
29
|
+
|
|
30
|
+
def __truediv__(self, other: "Query") -> "BinaryOprator":
|
|
31
|
+
from promcraft.operator import div
|
|
32
|
+
|
|
33
|
+
return div(self, other)
|
|
34
|
+
|
|
35
|
+
def __mod__(self, other: "Query") -> "BinaryOprator":
|
|
36
|
+
from promcraft.operator import mod
|
|
37
|
+
|
|
38
|
+
return mod(self, other)
|
|
39
|
+
|
|
40
|
+
def __pow__(self, other: "Query") -> "BinaryOprator":
|
|
41
|
+
from promcraft.operator import pow
|
|
42
|
+
|
|
43
|
+
return pow(self, other)
|
|
44
|
+
|
|
45
|
+
def __eq__(self, other: object) -> "BinaryOprator": # type: ignore[override]
|
|
46
|
+
from promcraft.operator import eq
|
|
47
|
+
|
|
48
|
+
if not isinstance(other, Query):
|
|
49
|
+
raise NotImplementedError("Cannot compare Query with non-Query object")
|
|
50
|
+
return eq(self, other)
|
|
51
|
+
|
|
52
|
+
def __hash__(self) -> int:
|
|
53
|
+
return id(self)
|
|
54
|
+
|
|
55
|
+
def __ne__(self, other: object) -> "BinaryOprator": # type: ignore[override]
|
|
56
|
+
from promcraft.operator import neq
|
|
57
|
+
|
|
58
|
+
if not isinstance(other, Query):
|
|
59
|
+
raise NotImplementedError("Cannot compare Query with non-Query object")
|
|
60
|
+
return neq(self, other)
|
|
61
|
+
|
|
62
|
+
def __lt__(self, other: "Query") -> "BinaryOprator":
|
|
63
|
+
from promcraft.operator import lt
|
|
64
|
+
|
|
65
|
+
return lt(self, other)
|
|
66
|
+
|
|
67
|
+
def __le__(self, other: "Query") -> "BinaryOprator":
|
|
68
|
+
from promcraft.operator import lte
|
|
69
|
+
|
|
70
|
+
return lte(self, other)
|
|
71
|
+
|
|
72
|
+
def __gt__(self, other: "Query") -> "BinaryOprator":
|
|
73
|
+
from promcraft.operator import gt
|
|
74
|
+
|
|
75
|
+
return gt(self, other)
|
|
76
|
+
|
|
77
|
+
def __ge__(self, other: "Query") -> "BinaryOprator":
|
|
78
|
+
from promcraft.operator import gte
|
|
79
|
+
|
|
80
|
+
return gte(self, other)
|
|
81
|
+
|
|
82
|
+
def __and__(self, other: "Query") -> "BinaryOprator":
|
|
83
|
+
from promcraft.operator import and_
|
|
84
|
+
|
|
85
|
+
return and_(self, other)
|
|
86
|
+
|
|
87
|
+
def __or__(self, other: "Query") -> "BinaryOprator":
|
|
88
|
+
from promcraft.operator import or_
|
|
89
|
+
|
|
90
|
+
return or_(self, other)
|