blob: 6b391adc4e2e97ed99db151264bf7566a594f1b5 (
plain)
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
|
__docformat__ = 'restructuredtext'
class Pattern:
"""
A pattern matches a string much like a regex. Our patterns have the
additional properties of being unionable and intersectable.
"""
def __init__(self, positive_match, *args):
"""
`args` is a series of strings the pattern should match. If
`positive_match` is False, then `args` is a series of strings that
should *not* be matched.
"""
self.items = set(args)
self.invert = not positive_match
def match(self, str):
"""
Determine if this Pattern matches `str`
"""
retval = str in self.items
if self.invert: retval = not retval
return retval
def nonempty(self):
"""
Returns True if this pattern will *ever* match *any* string.
"""
if self.invert: return True
if len(self.items) > 0: return True
return False
def full(self):
"""
Returns True if this pattern matches *all* strings.
"""
return self.invert and len(self.items) == 0
def singular(self):
"""
Returns True if this pattern will match *exactly one* string
"""
return not self.invert and len(self.items) == 1
def complement(self):
"""
Return a Pattern that matches anything this pattern *doesn't* match.
"""
return Pattern(self.invert, *self.items)
def union(self, other):
"""
Return a Pattern that matches anything this pattern *or* the pattern
`other` would match.
"""
invert = True
if self.invert and other.invert:
items = self.items & other.items
elif not (self.invert or other.invert):
items = self.items | other.items
invert = False
else:
if self.invert:
items = self.items - other.items
else:
items = other.items - self.items
return Pattern(not invert, *items)
def intersect(self, other):
"""
Return a Pattern that matches anything this pattern *and* the pattern
`other` would match.
"""
return self.complement().union(other.complement()).complement()
def __str__(self):
if len(self.items) == 0:
if self.invert:
return "*"
else:
return "(-)"
if self.invert:
return "!(%s)" % "|".join(self.items)
else:
return "(%s)" % "|".join(self.items)
def __repr__(self):
return str(self)
def __hash__(self):
return hash(str(self))
def __eq__(self, other):
if not other.__class__ == Pattern:
return False
return self.items == other.items and self.invert == other.invert
|