Add TypeForm (PEP 747) to the spec and conformance suite#2183
Add TypeForm (PEP 747) to the spec and conformance suite#2183JelleZijlstra wants to merge 7 commits intopython:mainfrom
Conversation
davidhalter
left a comment
There was a problem hiding this comment.
Thanks for the quick addition, I think some cases where clarifications would be great (and that are also not really mentioned in the PEP):
def f(x: TypeForm[int | str]): ...
# Are these all fine or not? These are not normal statements and it's quite unusual to
# infer arguments in this way whereas things like `x: TypeAlias = int` are more typical.
# I personally don't care if this is inferred or not, just that it is part of the conformance tests.
f(int)
f(int | str)
f("int")
# There are obviously more complicated cases for type inference like this one:
def g(x: list[TypeForm[int]]): ...
g([int])
g(["int"])
g([TypeForm("int")]) # Obviously fine
This would obviously affect all type inference for all type checkers in quite a big way. Again, I'm just not sure what the PEP wants here, but you can probably clarify. Here I would probably also prefer that at least some of the above cases are added to the conformance tests, because otherwise we would have different behavior for inference in a feature that doesn't really need that. Type inference is already a big mess across type checkers.
| v1_type_form: TypeForm[str | None] = str | None # OK | ||
|
|
||
| v2_actual: types.GenericAlias = list[int] # OK | ||
| v2_type_form: TypeForm = list[int] # OK |
There was a problem hiding this comment.
I would like this case to be clarified with an additional
assert_type(v2_type_form, TypeForm[Any])
since the PEP mentions that this case is not inferred, but Any (which seems reasonable). But I would like this to be consistent across type checkers.
There was a problem hiding this comment.
Not sure about that; some type checkers may infer a more precise type here and I don't think we need to disallow that. The PEP also doesn't say anything explicit about this case, where do you see that?
There was a problem hiding this comment.
@JelleZijlstra There is this sentence:
The type expression TypeForm, with no type argument provided, is equivalent to TypeForm[Any].
There was a problem hiding this comment.
That doesn't mean that v2_type_form should be inferred as TypeForm[Any], though.
For comparison, ty passes this test:
x: object = 1
assert_type(x, Literal[1])
There was a problem hiding this comment.
Although we plan to change this in ty, so that annotated assignments act like an upcast. Which will mean that
x: object = 1
assert_type(x, object)but still
x: object
x = 1
assert_type(x, Literal[1])But I think if the goal here is just to clarify that TypeForm in a type expression means TypeForm[Any], it would be better to sidestep these issues altogether and write the test in this form:
def _(x: TypeForm):
assert_type(x, TypeForm[Any])|
Another thing that I just remember is the case of Here I would also like some guidance. Are type checkers expected to store more information than |
|
@davidhalter asked:
The typing spec says very little about type inference behaviors in general. Inference behaviors differ across type checkers. Your example therefore isn't covered by the spec (or the PEP). If you change your example to the following, then it is covered by the PEP, and these are valid (no type error should be emitted). x: TypeForm[int | str]
x = int | str
x = "int | str" |
I think it's important for these to be accepted, so TypeForm can be used to type functions like |
But the reason for this is that Pyright/Mypy inference predates the spec and therefore a lot of inference related things could not be part of the spec. However here we are talking about new behavior and while we don't have to specify everything, I would still prefer to add as much as possible to the spec. |
This PR is focused on implementing PEP 747, so I'd rather not add new rules that go beyond the accepted PEP. More precise inference rules are better kept for a separate change. |
No description provided.