KEMBAR78
Use empty context as fallback for return statements by ilevkivskyi · Pull Request #19767 · python/mypy · GitHub
Skip to content

Conversation

ilevkivskyi
Copy link
Member

@ilevkivskyi ilevkivskyi commented Aug 31, 2025

Fixes #16924
Fixes #15886

Mypy uses external type context first, this can cause bad type inference in return statements (see example in test case added), usually we recommend a workaround to users like replacing:

    return foo(x)

with

    y = foo(x)
    return y

But this is a bit ugly, and more importantly we can essentially automatically try this workaround. This is what this PR adds. I checked performance impact, and don't see any (but for some reason noise level on my desktop is much higher now).

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copy link
Collaborator

@sterliakov sterliakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice trick! One q

mypy/checker.py Outdated
# If there are errors with the original type context, try re-inferring in empty context.
original_messages = msg.filtered_errors()
original_type_map = type_map
with self.msg.filter_errors(filter_errors=True, save_filtered_errors=True) as msg:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How should [deprecated] errors be handled here? They can be context-dependent in case of some scary overload

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably just filter_deprecated=True in both branches to avoid false positives?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we need to filter deprecated as well.

@github-actions
Copy link
Contributor

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

spark (https://github.com/apache/spark)
+ python/pyspark/core/rdd.py:2210: error: Unused "type: ignore" comment  [unused-ignore]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/flows.py:1980: error: Argument "on_completion" to "Flow" has incompatible type "Optional[list[FlowStateHook[[VarArg(Any), KwArg(Any)], Any]]]"; expected "Optional[list[FlowStateHook[P, R]]]"  [arg-type]
- src/prefect/flows.py:1981: error: Argument "on_failure" to "Flow" has incompatible type "Optional[list[FlowStateHook[[VarArg(Any), KwArg(Any)], Any]]]"; expected "Optional[list[FlowStateHook[P, R]]]"  [arg-type]
- src/prefect/flows.py:1982: error: Argument "on_cancellation" to "Flow" has incompatible type "Optional[list[FlowStateHook[[VarArg(Any), KwArg(Any)], Any]]]"; expected "Optional[list[FlowStateHook[P, R]]]"  [arg-type]
- src/prefect/flows.py:1983: error: Argument "on_crashed" to "Flow" has incompatible type "Optional[list[FlowStateHook[[VarArg(Any), KwArg(Any)], Any]]]"; expected "Optional[list[FlowStateHook[P, R]]]"  [arg-type]
- src/prefect/flows.py:1984: error: Argument "on_running" to "Flow" has incompatible type "Optional[list[FlowStateHook[[VarArg(Any), KwArg(Any)], Any]]]"; expected "Optional[list[FlowStateHook[P, R]]]"  [arg-type]

Tanjun (https://github.com/FasterSpeeding/Tanjun)
- tanjun/context/menu.py:200: error: Argument "default" to "resolve_to_member" of "MenuContext" has incompatible type "None"; expected "User"  [arg-type]

hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
- src/hydra_zen/wrapper/_implementations.py:1756: error: Unsupported operand types for + ("list[None]" and "list[str]")  [operator]

jax (https://github.com/google/jax)
+ jax/_src/sharding_impls.py:189: error: Unused "type: ignore" comment  [unused-ignore]

ibis (https://github.com/ibis-project/ibis)
- ibis/backends/sql/__init__.py:515: error: Item "Iterable[str]" of "str | Iterable[str]" has no attribute "format"  [union-attr]

@ilevkivskyi ilevkivskyi merged commit a856e55 into python:master Sep 1, 2025
20 checks passed
@ilevkivskyi ilevkivskyi deleted the return-fallback branch September 1, 2025 00:19
ilevkivskyi pushed a commit that referenced this pull request Sep 2, 2025
Fixes #19716. It is a follow-up to #19767 and was missed there due to
malformed test stubs (the same testcase fails when run by full mypy
against typeshed, I did not notice missing AwaitExpr because of the
passing test...). I synced typevar variance with typeshed definitions
and added AwaitExpr to the list of context-dependent exprs. Cc
@ilevkivskyi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants