Skip to content

Commit 697b0ae

Browse files
stroxlermeta-codesync[bot]
authored andcommitted
Don't complain if non-callable __bool__ is the last entry in a boolop
Summary: This matches the runtime: Python won't evaluate `_.__bool__()` unless it actually needs truthiness information; it's actually legal to use a non-boolable as the last value. Reviewed By: yangdanny97 Differential Revision: D85481912 fbshipit-source-id: 71b03b47c14035098e6f3f36cbfb3f6c998e157e
1 parent 1563b7a commit 697b0ae

File tree

2 files changed

+4
-6
lines changed

2 files changed

+4
-6
lines changed

pyrefly/lib/alt/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
10141014
let hint = hint.or_else(|| Some(HintRef::new(&t_acc, None)));
10151015
let mut t = self.expr_infer_with_hint(value, hint, errors);
10161016
self.expand_vars_mut(&mut t);
1017-
if should_shortcircuit(&t, value.range()) {
1017+
if i < last_index && should_shortcircuit(&t, value.range()) {
10181018
t_acc = self.union(t_acc, t);
10191019
break;
10201020
}

pyrefly/lib/test/operators.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,10 @@ assert_type(int() if Falsey() else str(), str)
483483
484484
# Test the use of a non-boolean-convertable type in boolean operators.
485485
#
486-
# TODO(stroxler): This behavior is conservative: the rightmost entry of a
487-
# boolean expression is actually not evaluated as a bool by the runtime (unless
488-
# the entire value is used as a boolean inside some other AST element), so the
489-
# type error on the second line is arguably a false-positive.
486+
# The runtime only uses truthiness in short-circuiting here, so it is actually
487+
# legal to use a non-boolable value as the rightmost entry of a bool op.
490488
assert_type(NotBoolable() or int(), int | NotBoolable) # E: Expected `__bool__` to be a callable, got `int`
491-
assert_type(int() or NotBoolable(), int | NotBoolable) # E: Expected `__bool__` to be a callable, got `int`
489+
assert_type(int() or NotBoolable(), int | NotBoolable)
492490
"#,
493491
);
494492

0 commit comments

Comments
 (0)