fix __bool__ check should look at Never return #1021#2966
fix __bool__ check should look at Never return #1021#2966asukaminato0721 wants to merge 2 commits intofacebook:mainfrom
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.
|
Diff from mypy_primer, showing the effect of this PR on open source code: pandera (https://github.com/pandera-dev/pandera)
+ ERROR pandera/engines/pandas_engine.py:2045:16-49: The `__bool__` method of `Series[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandera/engines/pandas_engine.py:2071:16-49: The `__bool__` method of `Series[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandera/engines/pyarrow_engine.py:438:12-45: The `__bool__` method of `Series[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandera/engines/pyarrow_engine.py:463:12-45: The `__bool__` method of `Series[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
freqtrade (https://github.com/freqtrade/freqtrade)
+ ERROR freqtrade/strategy/interface.py:1372:12-65: The `__bool__` method of `Series[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR freqtrade/strategy/interface.py:1376:13-1379:50: The `__bool__` method of `Series[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
pandas (https://github.com/pandas-dev/pandas)
+ ERROR pandas/core/arrays/base.py:592: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:1534: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:1054: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:1104: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:1122: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:860:12-28: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/string_.py:491:16-30: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/string_.py:508:16-34: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/string_.py:573:16-30: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/arrays/string_.py:588:16-73: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/dtypes/cast.py:1406:8-53: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/dtypes/cast.py:1413:12-27: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/frame.py:12439:16-26: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/generic.py:10013: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/groupby/groupby.py:6010:14-76: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/groupby/ops.py:675:21-49: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/indexes/multi.py:3508:12-40: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/internals/construction.py:438:19-60: The `__bool__` method of `Index` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/internals/construction.py:438:19-60: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/internals/construction.py:972:16-59: The `__bool__` method of `Index` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/core/missing.py:614:12-39: 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/window/ewm.py:366:16-38: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/io/formats/style.py:1808:20-25: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/io/formats/style.py:1808:20-39: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/io/formats/style.py:1833:20-25: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/io/formats/style.py:1833:20-39: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/io/json/_normalize.py:515:16-33: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/io/stata.py:505:16-34: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/io/stata.py:1918:20-62: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/apply/test_frame_apply.py:760:10-45: The `__bool__` method of `NDFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/frame/methods/test_reindex.py:348:16-35: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/frame/test_constructors.py:2265:16-29: The `__bool__` method of `DataFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/frame/test_constructors.py:2265:16-29: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/generic/test_frame.py:53:17-21: The `__bool__` method of `DataFrame` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/generic/test_series.py:49:17-25: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/generic/test_series.py:57:17-25: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/generic/test_series.py:65:17-25: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/groupby/methods/test_rank.py:496:8-18: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/groupby/test_reductions.py:1168:12-38: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/resample/test_datetime_index.py:1355:8-28: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/resample/test_datetime_index.py:1380:8-28: The `__bool__` method of `Series` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR pandas/tests/test_col.py:351:13-26: The `__bool__` method of `Expression` returns `Never`, so it cannot be used as a boolean [invalid-argument]
optuna (https://github.com/optuna/optuna)
+ ERROR optuna/storages/_rdb/alembic/versions/v3.0.0.c.py:158:17-161:73: The `__bool__` method of `ColumnElement[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR optuna/storages/_rdb/alembic/versions/v3.0.0.c.py:167:17-168:77: The `__bool__` method of `ColumnElement[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR optuna/storages/_rdb/alembic/versions/v3.0.0.d.py:162:16-69: The `__bool__` method of `ColumnElement[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR optuna/storages/_rdb/alembic/versions/v3.0.0.d.py:166:16-70: The `__bool__` method of `ColumnElement[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
+ ERROR optuna/storages/_rdb/storage.py:665:20-85: The `__bool__` method of `ColumnElement[bool]` returns `Never`, so it cannot be used as a boolean [invalid-argument]
|
Primer Diff Classification❌ 4 regression(s) | 4 project(s) total | +53 errors 4 regression(s) across pandera, freqtrade, pandas, optuna. error kinds:
Detailed analysis❌ Regression (4)pandera (+4)
freqtrade (+2)
pandas (+42)
optuna (+5)
Suggested fixesSummary: The new 1. In the closure
Was this helpful? React with 👍 or 👎 Classification by primer-classifier (4 LLM) |
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.
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