microsoft / pyright

Static Type Checker for Python
Other
13.16k stars 1.41k forks source link

TypeForm and type(x) #9055

Closed adampauls closed 4 hours ago

adampauls commented 5 hours ago

I'm aware the spec is not yet finalized and that the implementation is experimental. I'm also not clear on what the (current) spec says here.

Describe the bug

from typing import Any

from typing_extensions import TypeForm

s: str = "5"
t: type[str] = type(s)
tf: TypeForm[str] = type(s) #  error: Type "type[str]" is not assignable to declared type "TypeForm[str]"
    "type[type]" is not assignable to "type[TypeForm[str]]" (reportAssignmentType)

tf2: TypeForm[Any] = type(s) #  error: Type "type[str]" is not assignable to declared type "TypeForm[Any]"
    "type[type]" is not assignable to "type[TypeForm[Any]]" (reportAssignmentType)

tf3: TypeForm[Any] = str # ok

The spec says:

When a type expression is evaluated at runtime, the resulting value is a type form object.

TypeForm[T] describes the set of all type form objects that represent the type T or types that are assignable to T.

str is unambiguously a type expression, whose resulting value is unambiguously a "type form object" as per the spec. type(s) evaluates to str, so I believe type(s) evaluates to a "type form object", but it's possible the spec is not being clear here. If it is true that type(s) evaluates to a type form object, then surely it must be assignable to TypeForm.

It's possible the intent of the spec is that TypeForm represents things that are statically known to be the result of evaluating a type expression, and type(s) is itself unambiguously not a type expression. If so, then I think the spec needs to be reworded.

Version 1.1.381 from the command line.

erictraut commented 4 hours ago

This is working correctly. You're attempting to assign a value to a TypeForm type that does not come from a valid type expression. You'd see a similar error if you attempted to use the expression type(s) in a type annotation.