-
Notifications
You must be signed in to change notification settings - Fork 0
Make infer_condition_value recognize the whole truth table #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -115,31 +115,44 @@ def infer_condition_value(expr: Expression, options: Options) -> int: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MYPY_TRUE if true under mypy and false at runtime, MYPY_FALSE if | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
false under mypy and true at runtime, else TRUTH_VALUE_UNKNOWN. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if isinstance(expr, UnaryExpr) and expr.op == "not": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
positive = infer_condition_value(expr.expr, options) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return inverted_truth_mapping[positive] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pyversion = options.python_version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
name = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
negated = False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
alias = expr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if isinstance(alias, UnaryExpr): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if alias.op == "not": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expr = alias.expr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
negated = True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result = TRUTH_VALUE_UNKNOWN | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if isinstance(expr, NameExpr): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
name = expr.name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif isinstance(expr, MemberExpr): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
name = expr.name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif isinstance(expr, OpExpr) and expr.op in ("and", "or"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if expr.op not in ("or", "and"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return TRUTH_VALUE_UNKNOWN | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+131
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check seems redundant, as the
Suggested change
Comment on lines
+131
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redundant Operator Check Creating Unreachable CodeRedundant check for operator type after already confirming expr.op is 'and' or 'or' at line 130. This creates unreachable code since the outer if-statement already ensures expr.op is either 'and' or 'or'.
Suggested change
Standards
Comment on lines
+131
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redundant Condition CheckRedundant check for operators not in ("or", "and") after already confirming expr.op is in ("and", "or"). This dead code branch is unreachable, causing unnecessary complexity. Standards
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
left = infer_condition_value(expr.left, options) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (left in (ALWAYS_TRUE, MYPY_TRUE) and expr.op == "and") or ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
left in (ALWAYS_FALSE, MYPY_FALSE) and expr.op == "or" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Either `True and <other>` or `False or <other>`: the result will | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# always be the right-hand-side. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return infer_condition_value(expr.right, options) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# The result will always be the left-hand-side (e.g. ALWAYS_* or | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# TRUTH_VALUE_UNKNOWN). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return left | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
right = infer_condition_value(expr.right, options) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
results = {left, right} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if expr.op == "or": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ALWAYS_TRUE in results: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ALWAYS_TRUE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif MYPY_TRUE in results: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return MYPY_TRUE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif left == right == MYPY_FALSE: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return MYPY_FALSE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif results <= {ALWAYS_FALSE, MYPY_FALSE}: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ALWAYS_FALSE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif expr.op == "and": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ALWAYS_FALSE in results: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ALWAYS_FALSE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif MYPY_FALSE in results: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return MYPY_FALSE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif left == right == ALWAYS_TRUE: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ALWAYS_TRUE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif results <= {ALWAYS_TRUE, MYPY_TRUE}: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return MYPY_TRUE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+137
to
+154
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Complex Conditional LogicComplex nested conditionals with multiple return paths make the truth table logic difficult to maintain. Consider using a lookup table or mapping approach for better readability and easier future modifications. Standards
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return TRUTH_VALUE_UNKNOWN | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+137
to
+155
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Incorrect truth‑table for Example: • mypy sees A minimal fix is to short‑circuit on @@
if expr.op == "or":
if ALWAYS_TRUE in results:
return ALWAYS_TRUE
elif MYPY_TRUE in results:
return MYPY_TRUE
+ # If at least one side is MYPY_FALSE the overall value is
+ # false for mypy but true at runtime.
+ elif MYPY_FALSE in results:
+ return MYPY_FALSE
- elif left == right == MYPY_FALSE:
- return MYPY_FALSE
- elif results <= {ALWAYS_FALSE, MYPY_FALSE}:
- return ALWAYS_FALSE
+ elif results == {ALWAYS_FALSE}:
+ return ALWAYS_FALSE This preserves the existing (Optional) : consider extracting a small helper (e.g. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result = consider_sys_version_info(expr, pyversion) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if result == TRUTH_VALUE_UNKNOWN: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -155,8 +168,6 @@ def infer_condition_value(expr: Expression, options: Options) -> int: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result = ALWAYS_TRUE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
elif name in options.always_false: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result = ALWAYS_FALSE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if negated: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result = inverted_truth_mapping[result] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return result | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
171
to
172
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Negation Logic RedundancyThe 'negated' flag is never set in the code but is used in this condition. This creates dead code that will never execute, potentially masking logical errors in negation handling. Standards
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unhandled Operator Case
The function handles only 'and' and 'or' operators explicitly, but the redundant check suggests other operators were intended. This could cause unexpected behavior if other operators are passed.
Standards