root/releases/pkgcore/0.2.1/sandbox/xorrestriction.py @ marienz%2540gentoo.org-20060907005342-f0564d29760e2263

Revision marienz%2540gentoo.org-20060907005342-f0564d29760e2263, 4.8 KB (checked in by Marien Zwart <marienz@…>, 2 years ago)

Banish XorRestriction? to the sandbox.

Line 
1
2class XorRestriction(base):
3    """Boolean XOR grouping of restrictions."""
4    __slots__ = ()
5
6    def __init__(self, *a, **kw):
7        raise NotImplementedError("kindly don't use xor yet")
8
9    def match(self, vals):
10        if not self.restrictions:
11            return not self.negate
12
13        if self.negate:
14            # 1|1 == 0|0 == 1, 0|1 == 1|0 == 0
15            armed = self.restrictions[0].match(*vals)
16            for rest in islice(self.restrictions, 1, len(self.restrictions)):
17                if armed != rest.match(vals):
18                    return False
19            return True
20        # 0|1 == 1|0 == 1, 0|0 == 1|1 == 0
21        armed = False
22        for rest in self.restrictions:
23            if armed == rest.match(vals):
24                if armed:
25                    return False
26            else:
27                if not armed:
28                    armed = True
29        if armed:
30            return True
31        return False
32
33    def force_True(self, pkg, *vals):
34        pvals = [pkg]
35        pvals.extend(vals)
36        entry_point = pkg.changes_count()
37        truths = [r.match(*pvals) for r in self.restrictions]
38        count = truths.count(True)
39        # get the simple one out of the way first.
40        l = len(truths)
41        if self.negate:
42            f = lambda r: r.force_False(*pvals)
43            t = lambda r: r.force_True(*pvals)
44            if count > l/2:     order = ((t, count, True), (f, l - count, False))
45            else:                       order = ((f, l - count, False), (t, count, True))
46            for action, current, desired in order:
47                if current == l:
48                    return True
49                for x, r in enumerate(self.restrictions):
50                    if truths[x] != desired:
51                        if action(r):
52                            current += 1
53                        else:
54                            break
55                if current == l:
56                    return True
57                pkg.rollback(entry_point)
58            return False
59
60        stack = []
61        for x, val in enumerate(truths):
62            falses = filter(None, val)
63            if truths[x]:
64                falses.remove(x)
65                stack.append((falses, None))
66            else:
67                stack.append((falses, x))
68
69        if count == 1:
70            return True
71            del stack[truths.index(True)]
72
73        for falses, truths in stack:
74            failed = False
75            for x in falses:
76                if not self.restrictions[x].force_False(*pvals):
77                    failed = True
78                    break
79            if not failed:
80                if trues is not None:
81                    if self.restrictions[x].force_True(*pvals):
82                        return True
83                else:
84                    return True
85            pkg.rollback(entry_point)
86        return False
87
88    def force_False(self, pkg, *vals):
89        pvals = [pkg]
90        pvals.extend(vals)
91        entry_point = pkg.changes_count()
92        truths = [r.match(*pvals) for r in self.restrictions]
93        count = truths.count(True)
94        # get the simple one out of the way first.
95        l = len(truths)
96        if not self.negate:
97            f = lambda r: r.force_False(*pvals)
98            t = lambda r: r.force_True(*pvals)
99            if count > l/2:     order = ((t, count, True), (f, l - count, False))
100            else:                       order = ((f, l - count, False), (t, count, True))
101            for action, current, desired in order:
102                if current == l:
103                    return True
104
105                for x, r in enumerate(self.restrictions):
106                    if truths[x] != desired:
107                        if action(r):
108                            current += 1
109                        else:
110                            break
111                if current == l:
112                    return True
113                pkg.rollback(entry_point)
114            return False
115        # the fun one.
116        stack = []
117        for x, val in enumerate(truths):
118            falses = filter(None, val)
119            if truths[x]:
120                falses.remove(x)
121                stack.append((falses, None))
122            else:
123                stack.append((falses, x))
124
125        if count == 1:
126            return True
127
128        for falses, truths in stack:
129            failed = False
130            for x in falses:
131                if not self.restrictions[x].force_False(*pvals):
132                    failed = True
133                    break
134            if not failed:
135                if trues is not None:
136                    if self.restrictions[x].force_True(*pvals):
137                        return True
138                else:
139                    return True
140            pkg.rollback(entry_point)
141        return False
142
143    def __str__(self):
144        if self.negate:
145            return "not ( %s )" % " ^^ ".join(str(x) for x in self.restrictions)
146        return "( %s )" % " ^^ ".join(str(x) for x in self.restrictions)
Note: See TracBrowser for help on using the browser.