fix __bool__ check should look at Never return #1021#2966
fix __bool__ check should look at Never return #1021#2966asukaminato0721 wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Tightens Pyrefly’s truthiness checking so __bool__ implementations that never return (i.e., return type Never) are rejected in boolean contexts, aligning behavior with the expectation in issue #1021.
Changes:
- Update
check_dunder_bool_is_callableto additionally error when a callable__bool__has return typeNever. - Add a regression test covering
def __bool__(...) -> Neverused in anifcondition.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
pyrefly/lib/alt/attr.rs |
Adds a Never-return check for callable __bool__ attributes during truthiness validation. |
pyrefly/lib/test/simple.rs |
Adds a regression testcase asserting an error when __bool__ returns Never. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if dunder_bool_ty | ||
| .callable_return_type(self.heap) | ||
| .is_some_and(|ret| ret.is_never()) | ||
| { |
There was a problem hiding this comment.
callable_return_type only works for top-level callable types (Function/BoundMethod/Callable/Overload). Since callability is checked via as_call_target, dunder_bool_ty can still be callable via __call__ (e.g., an instance/class/protocol with __call__) but then callable_return_type returns None and this Never-return guard won’t fire. If the intent is to reject any callable __bool__ whose call result is Never, consider extracting the return type from the CallTarget (or doing a no-arg call_infer with swallowed errors) rather than relying on Type::callable_return_type.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
stroxler
left a comment
There was a problem hiding this comment.
I think this makes sense, I'll try to get a second review and merge. Thanks!
|
@stroxler has imported this pull request. If you are a Meta employee, you can view this in D100049632. |
|
It's interesting why
Looking at the definition of |
I managed to produce a false positive error here, maybe we shall tighten the check? |
fangyi-zhou
left a comment
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Thanks for addressing the issue with the false positive! I'd defer to members of the team to see if we need to do anything with the union issue. |
|
Diff from mypy_primer, showing the effect of this PR on open source code: pandas (https://github.com/pandas-dev/pandas)
+ ERROR pandas/core/arrays/base.py:598:12-42: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/base.py:1540:12-28: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/interval.py:1053:12-28: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/masked.py:1155:13-80: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/masked.py:1173:12-44: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/sparse/array.py:868:12-28: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/sparse/array.py:2041:8-24: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/generic.py:10058:12-19: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/groupby/generic.py:2851:20-38: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/indexes/multi.py:3596:12-40: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/nanops.py:358:20-40: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/reshape/merge.py:1606:28-55: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
|
Primer Diff Classification❌ 1 regression(s) | 1 project(s) total | +12 errors 1 regression(s) across pandas. error kinds:
Detailed analysis❌ Regression (1)pandas (+12)
Suggested fixesSummary: The 1. In
Was this helpful? React with 👍 or 👎 Classification by primer-classifier (1 LLM) |
Summary
Fixes #1021
tightening the
__bool__guard.The check still allows a raw Never value in boolean position, but it now rejects a callable
__bool__whose return type isNeverTest Plan
add test