@@ -67,17 +67,43 @@ def operator(self) -> str:
6767 return self ._operator
6868
6969 def allows (self , other : BaseConstraint ) -> bool :
70+ """Logic table to help
71+
72+ || != | == | in | not in
73+ --------||--------|--------|--------|--------
74+ != || != | != | not in | not in
75+ == || != | == | in | not in
76+ in || not in | in | in | not in
77+ not in || not in | not in | not in | false
78+
79+ """
7080 if not isinstance (other , Constraint ):
7181 raise ValueError ("Unimplemented comparison of constraints" )
7282
7383 is_equal_op = self ._operator == "=="
7484 is_non_equal_op = self ._operator == "!="
7585 is_other_equal_op = other .operator == "=="
7686 is_other_non_equal_op = other .operator == "!="
87+ is_in_op = self ._operator == "in"
88+ is_not_in_op = self ._operator == "not in"
89+ is_other_in_op = other .operator == "in"
90+ is_other_not_in_op = other .operator == "not in"
7791
7892 if is_equal_op and is_other_equal_op :
7993 return self ._value == other .value
8094
95+ if (
96+ is_in_op
97+ and is_other_in_op
98+ or is_in_op
99+ and is_equal_op
100+ or is_equal_op
101+ and is_other_in_op
102+ or is_in_op
103+ and is_other_equal_op
104+ ):
105+ return bool (self ._trans_op_str ["in" ](other .value , self ._value ))
106+
81107 if (
82108 is_equal_op
83109 and is_other_non_equal_op
@@ -88,8 +114,21 @@ def allows(self, other: BaseConstraint) -> bool:
88114 ):
89115 return self ._value != other .value
90116
91- if self ._operator in {"in" , "not in" } and other .operator == "==" :
92- return bool (self ._trans_op_str [self ._operator ](other .value , self ._value ))
117+ if (
118+ is_in_op
119+ and is_other_non_equal_op
120+ or is_in_op
121+ and is_other_not_in_op
122+ or is_not_in_op
123+ and is_other_non_equal_op
124+ or is_not_in_op
125+ and is_other_equal_op
126+ or is_not_in_op
127+ and is_other_in_op
128+ or is_non_equal_op
129+ and is_other_not_in_op
130+ ):
131+ return bool (self ._trans_op_str ["not in" ](other .value , self ._value ))
93132
94133 return False
95134
@@ -126,20 +165,20 @@ def intersect(self, other: BaseConstraint) -> BaseConstraint:
126165 return self
127166
128167 if (
129- (self .operator == "!=" and other .operator == "==" )
130- or (self .operator == "not in" and other .operator == "in" )
131- ) and self .allows (other ):
168+ self .operator in {"!=" , "not in" , "in" }
169+ and other .operator in {"==" , "in" , "not in" }
170+ and self .allows (other )
171+ ):
132172 return other
133173
134174 if (
135- (other .operator == "!=" and self .operator == "==" )
136- or (other .operator == "not in" and self .operator == "in" )
137- ) and other .allows (self ):
175+ other .operator in {"!=" , "not in" , "in" }
176+ and self .operator in {"==" , "in" , "not in" }
177+ and other .allows (self )
178+ ):
138179 return self
139180
140- if (other .operator == "!=" and self .operator == "!=" ) or (
141- other .operator == "not in" and self .operator == "not in"
142- ):
181+ if other .operator in {"!=" , "not in" } and self .operator in {"!=" , "not in" }:
143182 return MultiConstraint (self , other )
144183
145184 return EmptyConstraint ()
@@ -154,20 +193,18 @@ def union(self, other: BaseConstraint) -> BaseConstraint:
154193 return self
155194
156195 if (
157- ( self .operator == "!=" and other . operator == "==" )
158- or ( self .operator == "not in" and other . operator == " in")
196+ self .operator in { "!=" , "not in" , "in" }
197+ and other .operator in { "==" , " in", "not in"}
159198 ) and self .allows (other ):
160199 return self
161200
162201 if (
163- ( other .operator == "!=" and self . operator == "==" )
164- or ( other .operator == "not in" and self . operator == " in")
202+ other .operator in { "!=" , "not in" , "in" }
203+ and self .operator in { "==" , " in", "not in"}
165204 ) and other .allows (self ):
166205 return other
167206
168- if (other .operator == "==" and self .operator == "==" ) or (
169- other .operator == "in" and self .operator == "in"
170- ):
207+ if other .operator in {"==" , "in" } and self .operator in {"==" , "in" }:
171208 return UnionConstraint (self , other )
172209
173210 return AnyConstraint ()
@@ -194,5 +231,6 @@ def __hash__(self) -> int:
194231 return hash ((self ._operator , self ._value ))
195232
196233 def __str__ (self ) -> str :
234+ space = " " if self ._operator in {"in" , "not in" } else ""
197235 op = self ._operator if self ._operator != "==" else ""
198- return f"{ op } { self ._value } "
236+ return f"{ op } { space } { self ._value } "
0 commit comments