Allow None vs TypeVar overlap for overloads#15846
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
JukkaL
left a comment
There was a problem hiding this comment.
I agree that this use case seems sufficiently common that we can relax some type safety to support it.
| def foo(x: None, y: None) -> str: ... | ||
| @overload | ||
| def foo(x: T, y: T) -> int: ... | ||
| def foo(x): ... |
There was a problem hiding this comment.
Test also calling this to make sure we infer the return type correctly?
There was a problem hiding this comment.
Oh well, this discovered an obvious flaw in my solution, for this
@overload
def foo(x: None) -> None: ...
@overload
def foo(x: T) -> list[T]: ...
x: int | None
foo(x)we will continue to infer list[int | None], not list[int] | None that people will likely expect. I will try to check if there is a simple way to force union-math for this case. If there are none, this PR may become much more complex.
There was a problem hiding this comment.
OK, I think I have come up with some heuristics to force union math for None vs TypeVar overlap situations. It is not very precise, but should be generally safe, since IIUC union math infer better types anyway, we usually try to avoid it simply because it is computationally intensive.
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This comment has been minimized.
This comment has been minimized.
|
Diff from mypy_primer, showing the effect of this PR on open source code: pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/nanops.py:1143: error: Unused "type: ignore" comment [unused-ignore]
+ pandas/core/nanops.py:1144: error: Argument 1 to "_maybe_arg_null_out" has incompatible type "Any | signedinteger[Any]"; expected "ndarray[Any, Any]" [arg-type]
+ pandas/core/nanops.py:1188: error: Unused "type: ignore" comment [unused-ignore]
+ pandas/core/nanops.py:1189: error: Argument 1 to "_maybe_arg_null_out" has incompatible type "Any | signedinteger[Any]"; expected "ndarray[Any, Any]" [arg-type]
streamlit (https://github.com/streamlit/streamlit)
+ lib/streamlit/delta_generator.py:415: error: Unused "type: ignore" comment [unused-ignore]
+ lib/streamlit/delta_generator.py:439: error: Unused "type: ignore" comment [unused-ignore]
discord.py (https://github.com/Rapptz/discord.py)
- discord/app_commands/commands.py:2388: error: Overloaded function signatures 1 and 2 overlap with incompatible return types [misc]
|
|
FWIW new errors in |
|
Although the PR now is more hacky than originally approved, I think it is still fine. So I am going to merge it unless there are objections. |
|
Thank you for this! I agree that a generic way to say "This TypeVar is NOT one of these things" (something like python/typing#801) is the most general way to go, but this definitely solves my problem and what seems to be a most common type of problem out there. |
Fixes #8881
This is technically unsafe, and I remember we explicitly discussed this a while ago, but related use cases turn out to be more common than I expected (judging by how popular the issue is). Also the fix is really simple.