@@ -55,17 +55,34 @@ def _get_all_true(df: pd.DataFrame) -> pd.Series:
55
55
56
56
57
57
class CombineQMixin :
58
- """Mixin class for combining queries."""
58
+ """Mixin class for combining queries.
59
+
60
+ Four operators are defined for combining queries:
61
+
62
+ 1. ``&`` for logical AND operations.
63
+ The returned object is an :py:class:`AndQ` instance and - when executed -
64
+ returns a boolean mask where both queries are satisfied. When the right-hand
65
+ side is ``None``, the left-hand side query object is returned unchanged.
66
+ 2. ``|`` for logical OR operations.
67
+ The returned object is an :py:class:`OrQ` instance and - when executed -
68
+ returns a boolean mask where either query is satisfied. When the right-hand
69
+ side is ``None``, the left-hand side query object is returned unchanged.
70
+ 3. ``~`` for inverting a query.
71
+ The returned object is a :py:class:`NotQ` instance and - when executed -
72
+ returns a boolean mask where the query is not satisfied.
73
+ 4. ``==`` for checking if two queries are equal.
74
+ Two queries are equal if their column names, operators, and values are equal.
75
+ Note that this does not check if the queries are semantically equal, i.e., if
76
+ they would return the same result when executed.
77
+ """
59
78
60
79
def __and__ (self , other : QTypes | None ) -> AndQ :
61
80
"""Combine two queries with a logical AND."""
62
- other = other or NoneQ ()
63
- return AndQ (self , other )
81
+ return self if other is None else AndQ (self , other )
64
82
65
83
def __or__ (self , other : QTypes | None ) -> OrQ :
66
84
"""Combine two queries with a logical OR."""
67
- other = other or NoneQ ()
68
- return OrQ (self , other )
85
+ return self if other is None else OrQ (self , other )
69
86
70
87
def __invert__ (self ) -> NotQ :
71
88
"""Negate the query."""
@@ -166,6 +183,8 @@ class AndQ(CombineQMixin):
166
183
1 True
167
184
2 False
168
185
dtype: bool
186
+ >>> all((q1 & None).execute(df) == q1.execute(df))
187
+ True
169
188
"""
170
189
171
190
def __init__ (self , q1 : QTypes , q2 : QTypes ) -> None :
@@ -198,6 +217,8 @@ class OrQ(CombineQMixin):
198
217
1 False
199
218
2 True
200
219
Name: col1, dtype: bool
220
+ >>> all((q1 | None).execute(df) == q1.execute(df))
221
+ True
201
222
"""
202
223
203
224
def __init__ (self , q1 : QTypes , q2 : QTypes ) -> None :
@@ -257,6 +278,7 @@ def execute(self, df: pd.DataFrame) -> pd.Series:
257
278
258
279
259
280
QTypes = Q | AndQ | OrQ | NotQ | None
281
+ """Type for a query object or a combination of query objects."""
260
282
261
283
262
284
class C :
0 commit comments