-
Notifications
You must be signed in to change notification settings - Fork 248
fix Support constrained TypeVars #1422 #1963
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: main
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
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.
Pull request overview
This PR fixes issue #1422 by correctly handling constrained TypeVars in return type checking and missing-return analysis. The key change is recognizing that a constrained TypeVar T = TypeVar("T", int, str) can be satisfied by any of its constraints (not all), and that isinstance chains covering all constraints constitute exhaustive checking.
- Updated subset checking to accept any matching constraint for constrained TypeVars
- Added exhaustive isinstance chain detection to suppress false missing-return errors when all constraints are covered
- Added regression test for constrained TypeVar with isinstance chain
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| pyrefly/lib/solver/subset.rs | Changed constrained TypeVar subtype checking from all to any to correctly handle constraint matching |
| pyrefly/lib/binding/function.rs | Added isinstance chain analysis for constrained TypeVars to detect exhaustive type checking patterns |
| pyrefly/lib/test/returns.rs | Added regression test for constrained TypeVar with exhaustive isinstance chain |
| pyrefly/lib/test/generic_restrictions.rs | Removed now-incorrect return type error expectation due to fixed constraint checking |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2411c12 to
cf52028
Compare
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
|
Diff from mypy_primer, showing the effect of this PR on open source code: prefect (https://github.com/PrefectHQ/prefect)
- ERROR src/prefect/utilities/templating.py:199:36-68: `str` is not assignable to variable `template` with type `T` [bad-assignment]
- ERROR src/prefect/utilities/templating.py:201:32-72: `str` is not assignable to variable `template` with type `T` [bad-assignment]
- ERROR src/prefect/utilities/templating.py:323:16-328:10: Returned type `list[dict[str, Any] | Unknown]` is not assignable to declared return type `dict[str, Any] | T` [bad-return]
- ERROR src/prefect/utilities/templating.py:423:24-26: Returned type `Literal['']` is not assignable to declared return type `T` [bad-return]
- ERROR src/prefect/utilities/templating.py:432:36-68: `str` is not assignable to variable `template` with type `T` [bad-assignment]
- ERROR src/prefect/utilities/templating.py:434:36-85: `str` is not assignable to variable `template` with type `T` [bad-assignment]
- ERROR src/prefect/utilities/templating.py:437:16-440:10: Returned type `dict[Unknown, Unknown]` is not assignable to declared return type `T` [bad-return]
- ERROR src/prefect/utilities/templating.py:442:16-83: Returned type `list[Unknown]` is not assignable to declared return type `T` [bad-return]
- ::error file=src/prefect/utilities/templating.py,line=199,col=36,endLine=199,endColumn=68,title=Pyrefly bad-assignment::`str` is not assignable to variable `template` with type `T`
- ::error file=src/prefect/utilities/templating.py,line=201,col=32,endLine=201,endColumn=72,title=Pyrefly bad-assignment::`str` is not assignable to variable `template` with type `T`
- ::error file=src/prefect/utilities/templating.py,line=323,col=16,endLine=328,endColumn=10,title=Pyrefly bad-return::Returned type `list[dict[str, Any] | Unknown]` is not assignable to declared return type `dict[str, Any] | T`
- ::error file=src/prefect/utilities/templating.py,line=423,col=24,endLine=423,endColumn=26,title=Pyrefly bad-return::Returned type `Literal['']` is not assignable to declared return type `T`
- ::error file=src/prefect/utilities/templating.py,line=432,col=36,endLine=432,endColumn=68,title=Pyrefly bad-assignment::`str` is not assignable to variable `template` with type `T`
- ::error file=src/prefect/utilities/templating.py,line=434,col=36,endLine=434,endColumn=85,title=Pyrefly bad-assignment::`str` is not assignable to variable `template` with type `T`
- ::error file=src/prefect/utilities/templating.py,line=437,col=16,endLine=440,endColumn=10,title=Pyrefly bad-return::Returned type `dict[Unknown, Unknown]` is not assignable to declared return type `T`
- ::error file=src/prefect/utilities/templating.py,line=442,col=16,endLine=442,endColumn=83,title=Pyrefly bad-return::Returned type `list[Unknown]` is not assignable to declared return type `T`
zulip (https://github.com/zulip/zulip)
- ERROR zerver/lib/queue.py:109:17-25: Argument `(ChannelT, Basic.Deliver, BasicProperties, bytes) -> None` is not assignable to parameter `on_message_callback` with type `(Channel, Basic.Deliver, BasicProperties, bytes) -> object` in function `pika.channel.Channel.basic_consume` [bad-argument-type]
- ::error file=zerver/lib/queue.py,line=109,col=17,endLine=109,endColumn=25,title=Pyrefly bad-argument-type::Argument `(ChannelT, Basic.Deliver, BasicProperties, bytes) -> None` is not assignable to parameter `on_message_callback` with type `(Channel, Basic.Deliver, BasicProperties, bytes) -> object` in function `pika.channel.Channel.basic_consume`
pyodide (https://github.com/pyodide/pyodide)
- ERROR src/tests/test_static_typing.py:56:20-25: Returned type `float | int | str` is not assignable to declared return type `T` [bad-return]
- ::error file=src/tests/test_static_typing.py,line=56,col=20,endLine=56,endColumn=25,title=Pyrefly bad-return::Returned type `float | int | str` is not assignable to declared return type `T`
pytest (https://github.com/pytest-dev/pytest)
- ERROR src/_pytest/capture.py:948:13-31: `bytes | Unknown` is not assignable to attribute `_captured_out` with type `AnyStr` [bad-assignment]
- ERROR src/_pytest/capture.py:949:13-31: `bytes | Unknown` is not assignable to attribute `_captured_err` with type `AnyStr` [bad-assignment]
- ERROR src/_pytest/capture.py:968:30-42: Argument `bytes | AnyStr | Unknown` is not assignable to parameter `out` with type `AnyStr` in function `CaptureResult.__new__` [bad-argument-type]
- ERROR src/_pytest/capture.py:968:44-56: Argument `bytes | AnyStr | Unknown` is not assignable to parameter `err` with type `AnyStr` in function `CaptureResult.__new__` [bad-argument-type]
- ::error file=src/_pytest/capture.py,line=948,col=13,endLine=948,endColumn=31,title=Pyrefly bad-assignment::`bytes | Unknown` is not assignable to attribute `_captured_out` with type `AnyStr`
- ::error file=src/_pytest/capture.py,line=949,col=13,endLine=949,endColumn=31,title=Pyrefly bad-assignment::`bytes | Unknown` is not assignable to attribute `_captured_err` with type `AnyStr`
- ::error file=src/_pytest/capture.py,line=968,col=30,endLine=968,endColumn=42,title=Pyrefly bad-argument-type::Argument `bytes | AnyStr | Unknown` is not assignable to parameter `out` with type `AnyStr` in function `CaptureResult.__new__`
- ::error file=src/_pytest/capture.py,line=968,col=44,endLine=968,endColumn=56,title=Pyrefly bad-argument-type::Argument `bytes | AnyStr | Unknown` is not assignable to parameter `err` with type `AnyStr` in function `CaptureResult.__new__`
dulwich (https://github.com/dulwich/dulwich)
- ERROR dulwich/objects.py:243:16-22: Returned type `str` is not assignable to declared return type `PathT` [bad-return]
- ERROR dulwich/objects.py:254:16-24: Returned type `bytes` is not assignable to declared return type `PathT` [bad-return]
- ERROR dulwich/refs.py:1992:12-20: Returned type `dict[Ref, ObjectID | None]` is not assignable to declared return type `T` [bad-return]
- ::error file=dulwich/objects.py,line=243,col=16,endLine=243,endColumn=22,title=Pyrefly bad-return::Returned type `str` is not assignable to declared return type `PathT`
- ::error file=dulwich/objects.py,line=254,col=16,endLine=254,endColumn=24,title=Pyrefly bad-return::Returned type `bytes` is not assignable to declared return type `PathT`
- ::error file=dulwich/refs.py,line=1992,col=12,endLine=1992,endColumn=20,title=Pyrefly bad-return::Returned type `dict[Ref, ObjectID | None]` is not assignable to declared return type `T`
xarray (https://github.com/pydata/xarray)
- ERROR xarray/computation/rolling.py:1216:20-55: Returned type `DataArray` is not assignable to declared return type `T_Xarray` [bad-return]
- ERROR xarray/computation/rolling.py:1218:20-26: Returned type `Dataset` is not assignable to declared return type `T_Xarray` [bad-return]
- ERROR xarray/core/dtypes.py:108:12-33: Returned type `tuple[dtype[Any], Unknown]` is not assignable to declared return type `tuple[T_dtype, Any]` [bad-return]
+ ERROR xarray/core/dtypes.py:107:33-43: Argument `complex | datetime64[None] | float | timedelta64[str]` is not assignable to parameter `value` with type `SupportsFloat | SupportsIndex | bytes | str | None` in function `numpy.floating.__new__` [bad-argument-type]
- ERROR xarray/core/groupby.py:1204:16-22: Returned type `Dataset` is not assignable to declared return type `T_Xarray` [bad-return]
- ::error file=xarray/computation/rolling.py,line=1216,col=20,endLine=1216,endColumn=55,title=Pyrefly bad-return::Returned type `DataArray` is not assignable to declared return type `T_Xarray`
- ::error file=xarray/computation/rolling.py,line=1218,col=20,endLine=1218,endColumn=26,title=Pyrefly bad-return::Returned type `Dataset` is not assignable to declared return type `T_Xarray`
- ::error file=xarray/core/dtypes.py,line=108,col=12,endLine=108,endColumn=33,title=Pyrefly bad-return::Returned type `tuple[dtype[Any], Unknown]` is not assignable to declared return type `tuple[T_dtype, Any]`
+ ::error file=xarray/core/dtypes.py,line=107,col=33,endLine=107,endColumn=43,title=Pyrefly bad-argument-type::Argument `complex | datetime64[None] | float | timedelta64[str]` is not assignable to parameter `value` with type `SupportsFloat | SupportsIndex | bytes | str | None` in function `numpy.floating.__new__`
- ::error file=xarray/core/groupby.py,line=1204,col=16,endLine=1204,endColumn=22,title=Pyrefly bad-return::Returned type `Dataset` is not assignable to declared return type `T_Xarray`
hydpy (https://github.com/hydpy-dev/hydpy)
- ERROR hydpy/core/devicetools.py:2541:20-79: Returned type `tuple[(int & t) | (str & t) | None, (int & t) | (str & t) | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]` [bad-return]
+ ERROR hydpy/core/devicetools.py:2541:20-79: Returned type `tuple[int | str | None, int | str | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]` [bad-return]
- ERROR hydpy/core/devicetools.py:2724:20-79: Returned type `tuple[(int & t) | (str & t) | None, (int & t) | (str & t) | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]` [bad-return]
+ ERROR hydpy/core/devicetools.py:2724:20-79: Returned type `tuple[int | str | None, int | str | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]` [bad-return]
+ ERROR hydpy/core/importtools.py:796:32-65: No matching overload found for function `SubmodelAdder.update` called with arguments: (TM_contra, TI_contra, refresh=Literal[False]) [no-matching-overload]
+ ERROR hydpy/core/importtools.py:799:32-84: No matching overload found for function `SubmodelAdder.update` called with arguments: (TM_contra, TI_contra, position=int, refresh=Literal[False]) [no-matching-overload]
+ ERROR hydpy/core/importtools.py:949:29-31: No matching overload found for function `SubmodelAdder.get_wrapped` called with arguments: () [no-matching-overload]
+ ERROR hydpy/core/importtools.py:952:29-31: No matching overload found for function `SubmodelAdder.get_wrapped` called with arguments: () [no-matching-overload]
- ERROR hydpy/core/parametertools.py:1540:20-49: Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat` [bad-return]
- ERROR hydpy/core/parametertools.py:1542:20-49: Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat` [bad-return]
- ERROR hydpy/core/parametertools.py:1569:20-49: Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat` [bad-return]
- ERROR hydpy/core/parametertools.py:1571:20-49: Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat` [bad-return]
- ERROR hydpy/core/selectiontools.py:715:20-43: Returned type `Node` is not assignable to declared return type `TypeNodeElement` [bad-return]
- ERROR hydpy/core/selectiontools.py:717:20-46: Returned type `Element` is not assignable to declared return type `TypeNodeElement` [bad-return]
- ERROR hydpy/exe/xmltools.py:1868:45-53: Expected class object, got `type[ChangeItem & _TypeGetOrChangeItem]` [invalid-argument]
- ERROR hydpy/exe/xmltools.py:1868:45-53: Expected class object, got `type[GetItem & _TypeGetOrChangeItem]` [invalid-argument]
- ERROR hydpy/exe/xmltools.py:1869:34-38: Argument `ExchangeItem` is not assignable to parameter `object` with type `_TypeGetOrChangeItem` in function `list.append` [bad-argument-type]
- ERROR hydpy/exe/xmltools.py:1873:49-57: Expected class object, got `type[ChangeItem & _TypeGetOrChangeItem]` [invalid-argument]
- ERROR hydpy/exe/xmltools.py:1873:49-57: Expected class object, got `type[GetItem & _TypeGetOrChangeItem]` [invalid-argument]
- ERROR hydpy/exe/xmltools.py:1874:38-42: Argument `ExchangeItem` is not assignable to parameter `object` with type `_TypeGetOrChangeItem` in function `list.append` [bad-argument-type]
- ERROR hydpy/exe/xmltools.py:2373:20-2379:14: `SetItem` is not assignable to variable `item` with type `_TypeSetOrAddOrMultiplyItem` [bad-assignment]
- ::error file=hydpy/core/devicetools.py,line=2541,col=20,endLine=2541,endColumn=79,title=Pyrefly bad-return::Returned type `tuple[(int & t) | (str & t) | None, (int & t) | (str & t) | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]`
+ ::error file=hydpy/core/devicetools.py,line=2541,col=20,endLine=2541,endColumn=79,title=Pyrefly bad-return::Returned type `tuple[int | str | None, int | str | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]`
- ::error file=hydpy/core/devicetools.py,line=2724,col=20,endLine=2724,endColumn=79,title=Pyrefly bad-return::Returned type `tuple[(int & t) | (str & t) | None, (int & t) | (str & t) | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]`
+ ::error file=hydpy/core/devicetools.py,line=2724,col=20,endLine=2724,endColumn=79,title=Pyrefly bad-return::Returned type `tuple[int | str | None, int | str | None] | tuple[t | None, t | None] | t` is not assignable to declared return type `tuple[t | None, t | None]`
+ ::error file=hydpy/core/importtools.py,line=796,col=32,endLine=796,endColumn=65,title=Pyrefly no-matching-overload::No matching overload found for function `SubmodelAdder.update` called with arguments: (TM_contra, TI_contra, refresh=Literal[False])%0A Possible overloads:%0A (model: TM_contra, submodel: TI_contra, /, *, refresh: bool) -> None [closest match]%0A (model: TM_contra, submodel: TI_contra, /, *, position: int, refresh: bool) -> None
+ ::error file=hydpy/core/importtools.py,line=799,col=32,endLine=799,endColumn=84,title=Pyrefly no-matching-overload::No matching overload found for function `SubmodelAdder.update` called with arguments: (TM_contra, TI_contra, position=int, refresh=Literal[False])%0A Possible overloads:%0A (model: TM_contra, submodel: TI_contra, /, *, refresh: bool) -> None%0A (model: TM_contra, submodel: TI_contra, /, *, position: int, refresh: bool) -> None [closest match]
+ ::error file=hydpy/core/importtools.py,line=949,col=29,endLine=949,endColumn=31,title=Pyrefly no-matching-overload::No matching overload found for function `SubmodelAdder.get_wrapped` called with arguments: ()%0A Possible overloads:%0A () -> PrepSub0D[TM_contra, TI_contra] [closest match]%0A () -> PrepSub1D[TM_contra, TI_contra]
+ ::error file=hydpy/core/importtools.py,line=952,col=29,endLine=952,endColumn=31,title=Pyrefly no-matching-overload::No matching overload found for function `SubmodelAdder.get_wrapped` called with arguments: ()%0A Possible overloads:%0A () -> PrepSub0D[TM_contra, TI_contra] [closest match]%0A () -> PrepSub1D[TM_contra, TI_contra]
- ::error file=hydpy/core/parametertools.py,line=1540,col=20,endLine=1540,endColumn=49,title=Pyrefly bad-return::Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat`
- ::error file=hydpy/core/parametertools.py,line=1542,col=20,endLine=1542,endColumn=49,title=Pyrefly bad-return::Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat`
- ::error file=hydpy/core/parametertools.py,line=1569,col=20,endLine=1569,endColumn=49,title=Pyrefly bad-return::Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat`
- ::error file=hydpy/core/parametertools.py,line=1571,col=20,endLine=1571,endColumn=49,title=Pyrefly bad-return::Returned type `float | ndarray[tuple[Any, ...], dtype[float64]]` is not assignable to declared return type `ArrayFloat`
- ::error file=hydpy/core/selectiontools.py,line=715,col=20,endLine=715,endColumn=43,title=Pyrefly bad-return::Returned type `Node` is not assignable to declared return type `TypeNodeElement`
- ::error file=hydpy/core/selectiontools.py,line=717,col=20,endLine=717,endColumn=46,title=Pyrefly bad-return::Returned type `Element` is not assignable to declared return type `TypeNodeElement`
- ::error file=hydpy/exe/xmltools.py,line=1868,col=45,endLine=1868,endColumn=53,title=Pyrefly invalid-argument::Expected class object, got `type[ChangeItem & _TypeGetOrChangeItem]`
- ::error file=hydpy/exe/xmltools.py,line=1868,col=45,endLine=1868,endColumn=53,title=Pyrefly invalid-argument::Expected class object, got `type[GetItem & _TypeGetOrChangeItem]`
- ::error file=hydpy/exe/xmltools.py,line=1869,col=34,endLine=1869,endColumn=38,title=Pyrefly bad-argument-type::Argument `ExchangeItem` is not assignable to parameter `object` with type `_TypeGetOrChangeItem` in function `list.append`
- ::error file=hydpy/exe/xmltools.py,line=1873,col=49,endLine=1873,endColumn=57,title=Pyrefly invalid-argument::Expected class object, got `type[ChangeItem & _TypeGetOrChangeItem]`
- ::error file=hydpy/exe/xmltools.py,line=1873,col=49,endLine=1873,endColumn=57,title=Pyrefly invalid-argument::Expected class object, got `type[GetItem & _TypeGetOrChangeItem]`
- ::error file=hydpy/exe/xmltools.py,line=1874,col=38,endLine=1874,endColumn=42,title=Pyrefly bad-argument-type::Argument `ExchangeItem` is not assignable to parameter `object` with type `_TypeGetOrChangeItem` in function `list.append`
- ::error file=hydpy/exe/xmltools.py,line=2373,col=20,endLine=2379,endColumn=14,title=Pyrefly bad-assignment::`SetItem` is not assignable to variable `item` with type `_TypeSetOrAddOrMultiplyItem`
static-frame (https://github.com/static-frame/static-frame)
- ERROR static_frame/core/node_values.py:147:24-155:18: Returned type `Frame[Any, Any, *tuple[Any, ...]]` is not assignable to declared return type `TVContainer_co` [bad-return]
- ERROR static_frame/core/node_values.py:176:20-181:14: Returned type `Series[Any, Any]` is not assignable to declared return type `TVContainer_co` [bad-return]
- ERROR static_frame/core/node_values.py:275:20-284:14: Returned type `Frame[Any, Any, *tuple[Any, ...]] | Index[Any] | IndexHierarchy[*tuple[Any, ...]] | Series[Any, Any]` is not assignable to declared return type `TVContainer_co` [bad-return]
- ::error file=static_frame/core/node_values.py,line=147,col=24,endLine=155,endColumn=18,title=Pyrefly bad-return::Returned type `Frame[Any, Any, *tuple[Any, ...]]` is not assignable to declared return type `TVContainer_co`
- ::error file=static_frame/core/node_values.py,line=176,col=20,endLine=181,endColumn=14,title=Pyrefly bad-return::Returned type `Series[Any, Any]` is not assignable to declared return type `TVContainer_co`
- ::error file=static_frame/core/node_values.py,line=275,col=20,endLine=284,endColumn=14,title=Pyrefly bad-return::Returned type `Frame[Any, Any, *tuple[Any, ...]] | Index[Any] | IndexHierarchy[*tuple[Any, ...]] | Series[Any, Any]` is not assignable to declared return type `TVContainer_co`
koda-validate (https://github.com/keithasaurus/koda-validate)
- ERROR koda_validate/generic.py:321:16-27: Returned type `bytes | str` is not assignable to declared return type `StrOrBytes` [bad-return]
- ERROR koda_validate/generic.py:330:16-27: Returned type `bytes | str` is not assignable to declared return type `StrOrBytes` [bad-return]
- ERROR koda_validate/generic.py:336:16-27: Returned type `bytes | str` is not assignable to declared return type `StrOrBytes` [bad-return]
- ::error file=koda_validate/generic.py,line=321,col=16,endLine=321,endColumn=27,title=Pyrefly bad-return::Returned type `bytes | str` is not assignable to declared return type `StrOrBytes`
- ::error file=koda_validate/generic.py,line=330,col=16,endLine=330,endColumn=27,title=Pyrefly bad-return::Returned type `bytes | str` is not assignable to declared return type `StrOrBytes`
- ::error file=koda_validate/generic.py,line=336,col=16,endLine=336,endColumn=27,title=Pyrefly bad-return::Returned type `bytes | str` is not assignable to declared return type `StrOrBytes`
discord.py (https://github.com/Rapptz/discord.py)
- ERROR discord/backoff.py:63:56-61: Default `Literal[False]` is not assignable to parameter `integral` with type `T` [bad-function-definition]
- ::error file=discord/backoff.py,line=63,col=56,endLine=63,endColumn=61,title=Pyrefly bad-function-definition::Default `Literal[False]` is not assignable to parameter `integral` with type `T`
pandas (https://github.com/pandas-dev/pandas)
- ERROR pandas/core/dtypes/cast.py:408:16-36: Returned type `Index | ndarray[tuple[Any, ...], dtype[signedinteger[_64Bit]]] | NumpyIndexT` is not assignable to declared return type `NumpyIndexT` [bad-return]
- ERROR pandas/core/dtypes/cast.py:410:16-37: Returned type `Index | ndarray[tuple[Any, ...], dtype[unsignedinteger[_64Bit]]] | NumpyIndexT` is not assignable to declared return type `NumpyIndexT` [bad-return]
- ERROR pandas/core/dtypes/cast.py:412:16-38: Returned type `Index | ndarray[tuple[Any, ...], dtype[float64]] | NumpyIndexT` is not assignable to declared return type `NumpyIndexT` [bad-return]
- ERROR pandas/core/resample.py:3149:12-21: Returned type `DatetimeIndex | PeriodIndex | TimedeltaIndex` is not assignable to declared return type `FreqIndexT` [bad-return]
- ERROR pandas/io/stata.py:2253:16-53: Returned type `bytes` is not assignable to declared return type `AnyStr` [bad-return]
- ERROR pandas/io/stata.py:2254:12-48: Returned type `bytes | str` is not assignable to declared return type `AnyStr` [bad-return]
- ::error file=pandas/core/dtypes/cast.py,line=408,col=16,endLine=408,endColumn=36,title=Pyrefly bad-return::Returned type `Index | ndarray[tuple[Any, ...], dtype[signedinteger[_64Bit]]] | NumpyIndexT` is not assignable to declared return type `NumpyIndexT`
- ::error file=pandas/core/dtypes/cast.py,line=410,col=16,endLine=410,endColumn=37,title=Pyrefly bad-return::Returned type `Index | ndarray[tuple[Any, ...], dtype[unsignedinteger[_64Bit]]] | NumpyIndexT` is not assignable to declared return type `NumpyIndexT`
- ::error file=pandas/core/dtypes/cast.py,line=412,col=16,endLine=412,endColumn=38,title=Pyrefly bad-return::Returned type `Index | ndarray[tuple[Any, ...], dtype[float64]] | NumpyIndexT` is not assignable to declared return type `NumpyIndexT`
- ::error file=pandas/core/resample.py,line=3149,col=12,endLine=3149,endColumn=21,title=Pyrefly bad-return::Returned type `DatetimeIndex | PeriodIndex | TimedeltaIndex` is not assignable to declared return type `FreqIndexT`
- ::error file=pandas/io/stata.py,line=2253,col=16,endLine=2253,endColumn=53,title=Pyrefly bad-return::Returned type `bytes` is not assignable to declared return type `AnyStr`
- ::error file=pandas/io/stata.py,line=2254,col=12,endLine=2254,endColumn=48,title=Pyrefly bad-return::Returned type `bytes | str` is not assignable to declared return type `AnyStr`
scrapy (https://github.com/scrapy/scrapy)
- ERROR scrapy/utils/datatypes.py:76:16-27: Returned type `bytes | str` is not assignable to declared return type `AnyStr` [bad-return]
- ::error file=scrapy/utils/datatypes.py,line=76,col=16,endLine=76,endColumn=27,title=Pyrefly bad-return::Returned type `bytes | str` is not assignable to declared return type `AnyStr`
|
stroxler
left a comment
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.
Thanks for the PR. I think it works, but I actually think the implementation isn't the right direction, we fixed the reported bug but not the root cause, which is missing exhaustiveness checks.
In particular, this snippet has exactly the same bug:
def g(x: int | str) -> int | str:
if isinstance(x, int):
return x
elif isinstance(x, str):
return x
I have some related work in draft match exhaustiveness changes I have (which are blocked from landing right away because I have major features that depend on one another + on some internal constraints)
I think I may need to come back to this PR once that work is unblocked to better understand how it all fits together, but my instinct is that we need a much more general mechanism for handling whether a final statement with branching control flow "falls off the end" or not in function return logic.
| (t1, Type::Quantified(q)) => match q.restriction() { | ||
| // This only works for constraints and not bounds, because a TypeVar must resolve to exactly one of its constraints. | ||
| Restriction::Constraints(constraints) => all(constraints.iter(), |constraint| { | ||
| Restriction::Constraints(constraints) => any(constraints.iter(), |constraint| { |
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.
I think this change is probably not closely related, and it looks like it's probably right to me.
Would you want to submit a PR with just this one change?
Summary
Fixes #1422
Adjusted constrained TypeVar handling so return checks accept any constraint and missing-return is suppressed when an isinstance chain covers all constraints, then added a regression test and updated expectations.
Updated constrained TypeVar subtyping to accept any matching constraint.
Added a conservative exhaustive-isinstance check for constrained TypeVar parameters to avoid false missing-return errors.
Test Plan
Added a new return regression test and removed the now-obsolete return-type error expectation.