mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Uninhabited should have all attributes

Open ilevkivskyi opened this issue 7 months ago • 4 comments

Although this can hide some mypy bugs, TBH this always bothered me as something conceptually wrong. The work on checkmember stuff inspired me to actually try it.

ilevkivskyi avatar Jun 14 '25 19:06 ilevkivskyi

Diff from mypy_primer, showing the effect of this PR on open source code:

Tanjun (https://github.com/FasterSpeeding/Tanjun)
- tanjun/clients.py:2294: error: "Never" has no attribute "__iter__" (not iterable)  [attr-defined]
+ tanjun/clients.py:2294: error: "Never" not callable  [misc]

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:1041: error: "Never" has no attribute "__next__"  [attr-defined]
+ ibis/expr/types/relations.py:1041: error: "Never" not callable  [misc]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/server/models/deployments.py:63: error: "Never" has no attribute "name"  [attr-defined]
- src/prefect/server/models/deployments.py:767: error: "Never" has no attribute "model_dump"  [attr-defined]
+ src/prefect/server/models/deployments.py:767: error: "Never" not callable  [misc]

manticore (https://github.com/trailofbits/manticore)
+ manticore/wasm/types.py:56: error: Unused "type: ignore" comment  [unused-ignore]

xarray (https://github.com/pydata/xarray)
+ xarray/core/variable.py:922: error: Unused "type: ignore" comment  [unused-ignore]
+ xarray/core/variable.py:924: error: Unused "type: ignore" comment  [unused-ignore]
+ xarray/core/variable.py:2808: error: Unused "type: ignore" comment  [unused-ignore]
+ xarray/core/variable.py:2810: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Jun 14 '25 20:06 github-actions[bot]

For me "Never" has no attribute "foo" is an early indicator of failed/impossible inference. Allowing arbitrary lookups on Never may prevent that from happening, potentially breaking some funny typing patterns like Never-returning overloads. This will be even more painful for users who don't run mypy with --warn-unreachable enabled.

While I understand your motivation, I think it's completely impractical here. Furthermore, if I'm not mistaken, the "Never" not callable error is no better than "Never" has no attribute "foo" - it's as safe to call Never as it is to access attribute foo on it. Allowing one but not another is an inconsistency and source of confusion. Allowing both can hide too many issues.

sterliakov avatar Jun 15 '25 22:06 sterliakov

I think this change is good (and there's like 2 other similar places), especially if combined something that marks any block with a variable bound to Never as unreachable.

Edit: Nevermind I see you address that w/r/t warn-unreachable not being set. I don't think this is actually an actionable error message though? Like, "ok so my variable is Never" doesn't convey much especially to those not familiar with mypy internals.

A5rocks avatar Jun 16 '25 00:06 A5rocks

marks any block with a variable bound to Never as unreachable.

Well, then we won't see "Never has no attribute ..." at all, so it doesn't really matter whether such attribute access is allowed?

I see some merit in saying "we do indicate some important issues via [unreachable] errors, please keep them enabled", but it's easier said than done - notably some parts of mypy itself still don't pass --warn-unreachable AFAIC.

sterliakov avatar Jun 16 '25 14:06 sterliakov

the "Never" not callable error is no better

Yes, I think we should actually enable that one as well. I am actually going to try that now.

ilevkivskyi avatar Jun 24 '25 23:06 ilevkivskyi

Diff from mypy_primer, showing the effect of this PR on open source code:

Tanjun (https://github.com/FasterSpeeding/Tanjun)
- tanjun/clients.py:2294: error: "Never" has no attribute "__iter__" (not iterable)  [attr-defined]

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/types/relations.py:1041: error: "Never" has no attribute "__next__"  [attr-defined]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/server/models/deployments.py:63: error: "Never" has no attribute "name"  [attr-defined]
- src/prefect/server/models/deployments.py:767: error: "Never" has no attribute "model_dump"  [attr-defined]

manticore (https://github.com/trailofbits/manticore)
+ manticore/wasm/types.py:56: error: Unused "type: ignore" comment  [unused-ignore]

xarray (https://github.com/pydata/xarray)
+ xarray/core/variable.py:922: error: Unused "type: ignore" comment  [unused-ignore]
+ xarray/core/variable.py:924: error: Unused "type: ignore" comment  [unused-ignore]
+ xarray/core/variable.py:2807: error: Unused "type: ignore" comment  [unused-ignore]
+ xarray/core/variable.py:2809: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Jun 25 '25 00:06 github-actions[bot]