-
Notifications
You must be signed in to change notification settings - Fork 124
report error for unsolved type variables in function calls #1749
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think the primer has raised some false positives, or at least scenarios that need investigating |
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the example from that issue still doesn't report an error: a = []
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the error message is pretty confusing in this case:
maybe for list/set/dict/etc. literals it should give an example of how to fix it, eg:
maybe that can be a diagnostic addendum
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think I like suggesting
KotlinIsland marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| # this sample tests the detection of unsolved type variables in function calls | ||
|
|
||
| from typing import Any, Callable | ||
|
|
||
| def func1[T]() -> T: ... | ||
|
|
||
|
|
||
| def func2[T](x: T) -> T: | ||
| return x | ||
|
|
||
|
|
||
| def func3[T, U](x: T) -> U: ... | ||
|
|
||
|
|
||
| def func4[T = int]() -> T: ... | ||
|
|
||
|
|
||
| def func5[T, U = str](x: T) -> U: ... | ||
|
|
||
|
|
||
| # Error: T cannot be inferred | ||
| a = func1() | ||
|
|
||
| # OK: T is inferred from argument | ||
| b = func2(1) | ||
|
|
||
| # Error: U cannot be inferred (T is fine) | ||
| c = func3(1) # pyright: ignore[reportUnsolvedTypeVar] | ||
|
|
||
| # OK: T has a default value | ||
| d = func4() | ||
|
|
||
| # OK: T is inferred, U has a default value | ||
| e = func5(1) | ||
|
|
||
|
|
||
| # test with explicit type arguments | ||
| f: int = func1() | ||
|
|
||
| class MyClass[T]: ... | ||
|
|
||
| # ok: T is explicit | ||
| i = MyClass[int]() | ||
|
|
||
| # error: can't infer class type from constructor | ||
| i = MyClass() # pyright: ignore[reportUnsolvedTypeVar] | ||
|
|
||
| class Default[T=Any]: ... | ||
|
|
||
| # ok: T is explicit | ||
| i = Default[int]() | ||
|
|
||
| # ok: uses default | ||
| i = Default() | ||
|
|
||
| def deco[T]() -> Callable[[Callable[[], T]], Callable[[], T]]: ... | ||
|
|
||
| # ok: T is None | ||
| @deco() | ||
| def func6(): | ||
| pass | ||
|
|
||
| deco()(lambda: None) | ||
|
|
||
| # OK: T is inferred from argument | ||
| j: int = func2(func1()) | ||
|
|
||
| # error | ||
| k = [] | ||
|
|
||
| # no error | ||
| l: list[int] = [] |
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'm not sure I like this name.
"Solving" a type variable is a perspective of the type-checker implementer, that the type-checker user shouldn't need to think about.
The user doesn't need to think about "solving" things, or "solutions".
This kind of seems like something for the family of
reportUnknown...rules.reportUnknownTypeVar?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.
while the term is possibly confusing since type checkers seem to have different words for it (pyright uses the word "specialize" but idk if that term is unique to pyright), i don't consider the actual resolving of a type var to be an implementation detail. the user should be able to clearly tell when using a function or class with a generic whether that generic was able to be inferred or not, regardless of what word is used to describe that process.
i agree
reportUnknownTypeVarsounds like a better name, and is more consistent with other similar rules