Skip to content

Commit 2d2787c

Browse files
committed
Implement boolean constraint
1 parent 7b83121 commit 2d2787c

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

astroid/constraint.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,47 @@ def satisfied_by(self, inferred: InferenceResult) -> bool:
8484
return self.negate ^ _matches(inferred, self.CONST_NONE)
8585

8686

87+
class BooleanConstraint(Constraint):
88+
"""Represents an "x" or "not x" constraint."""
89+
90+
@classmethod
91+
def match(
92+
cls, node: _NameNodes, expr: nodes.NodeNG, negate: bool = False
93+
) -> Self | None:
94+
"""Return a new constraint for node if expr matches one of these patterns:
95+
96+
- direct match (expr == node): use given negate value
97+
- negated match (expr == `not node`): flip negate value
98+
99+
Return None if no pattern matches.
100+
"""
101+
if _matches(expr, node):
102+
return cls(node=node, negate=negate)
103+
104+
if (
105+
isinstance(expr, nodes.UnaryOp)
106+
and expr.op == "not"
107+
and _matches(expr.operand, node)
108+
):
109+
return cls(node=node, negate=not negate)
110+
111+
return None
112+
113+
def satisfied_by(self, inferred: InferenceResult) -> bool:
114+
"""Return True for uninferable results, or depending on negate flag:
115+
116+
- negate=False: satisfied if boolean value is True
117+
- negate=True: satisfied if boolean value is False
118+
"""
119+
inferred_booleaness = inferred.bool_value()
120+
if isinstance(inferred, util.UninferableBase) or isinstance(
121+
inferred_booleaness, util.UninferableBase
122+
):
123+
return True
124+
125+
return self.negate ^ inferred_booleaness
126+
127+
87128
def get_constraints(
88129
expr: _NameNodes, frame: nodes.LocalsDictNodeNG
89130
) -> dict[nodes.If, set[Constraint]]:
@@ -114,7 +155,12 @@ def get_constraints(
114155
return constraints_mapping
115156

116157

117-
ALL_CONSTRAINT_CLASSES = frozenset((NoneConstraint,))
158+
ALL_CONSTRAINT_CLASSES = frozenset(
159+
(
160+
NoneConstraint,
161+
BooleanConstraint,
162+
)
163+
)
118164
"""All supported constraint types."""
119165

120166

0 commit comments

Comments
 (0)