-
Notifications
You must be signed in to change notification settings - Fork 1
/
query_set.py
114 lines (82 loc) · 2.34 KB
/
query_set.py
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import fnmatch
class match:
def __init__(self, query, match):
self.query = query
self.match = match
class base_query:
def __invert__(self):
return logical_not(self)
def __or__(self, other):
return logical_or(self, other)
def __and__(self, other):
return logical_and(self, other)
def __xor__(self, other):
return logical_xor(self, other)
class contains_element(base_query):
def __init__(self, pattern, ignore_case=True):
self.ignore_case = ignore_case
if self.ignore_case:
self.pattern = pattern.lower()
else:
self.pattern = pattern
def query(self, collection):
result = set()
for to_test in collection:
if self.ignore_case:
if fnmatch.fnmatch(to_test.lower(), self.pattern):
result.add(to_test)
else:
if fnmatch.fnmatch(to_test, self.pattern):
result.add(to_test)
if result:
return match(self, result)
def __repr__(self):
return f'{self.pattern}'
class unary_operation(base_query):
def __init__(self, reference):
self.reference = reference
class binary_operation(base_query):
def __init__(self, left, right):
self.left = left
self.right = right
class logical_not(unary_operation):
def __invert__(self):
return self.reference
def query(self, collection):
if not self.reference.query(collection):
return match(self, set())
def __repr__(self):
return f'~({self.reference})'
class logical_or(binary_operation):
def query(self, collection):
result = set()
if left := self.left.query(collection):
result |= left.match
if right := self.right.query(collection):
result |= right.match
if left or right:
return match(self, result)
def __repr__(self):
return f'({self.left}) | ({self.right})'
class logical_xor(binary_operation):
def query(self, collection):
result = set()
if left := self.left.query(collection):
result |= left.match
if right := self.right.query(collection):
result |= right.match
if left and right:
return
elif left or right:
return match(self, result)
def __repr__(self):
return f'({self.left}) ^ ({self.right})'
class logical_and(binary_operation):
def query(self, collection):
if (left := self.left.query(collection)) is None:
return
if (right := self.right.query(collection)) is None:
return
return match(self, left.match | right.match)
def __repr__(self):
return f'({self.left}) & ({self.right})'