diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/annotated.md b/crates/ty_python_semantic/resources/mdtest/annotations/annotated.md index 3fb2cc3138..ed566b859e 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/annotated.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/annotated.md @@ -76,7 +76,7 @@ from typing_extensions import Annotated class C(Annotated[int, "foo"]): ... # TODO: Should be `tuple[Literal[C], Literal[int], Literal[object]]` -reveal_type(C.__mro__) # revealed: tuple[Literal[C], @Todo(Inference of subscript on special form), Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, @Todo(Inference of subscript on special form), ] ``` ### Not parameterized @@ -88,5 +88,5 @@ from typing_extensions import Annotated # error: [invalid-base] class C(Annotated): ... -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Unknown, Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, Unknown, ] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/any.md b/crates/ty_python_semantic/resources/mdtest/annotations/any.md index 14468e3d93..d4b1e6f502 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/any.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/any.md @@ -59,7 +59,7 @@ from typing import Any class SubclassOfAny(Any): ... -reveal_type(SubclassOfAny.__mro__) # revealed: tuple[Literal[SubclassOfAny], Any, Literal[object]] +reveal_type(SubclassOfAny.__mro__) # revealed: tuple[, Any, ] x: SubclassOfAny = 1 # error: [invalid-assignment] y: int = SubclassOfAny() diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md b/crates/ty_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md index 5765db4b4d..895d3263d9 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/stdlib_typing_aliases.md @@ -85,25 +85,25 @@ import typing class ListSubclass(typing.List): ... # TODO: generic protocols -# revealed: tuple[Literal[ListSubclass], Literal[list], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, Literal[object]] +# revealed: tuple[, , , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, ] reveal_type(ListSubclass.__mro__) class DictSubclass(typing.Dict): ... # TODO: generic protocols -# revealed: tuple[Literal[DictSubclass], Literal[dict[Unknown, Unknown]], Literal[MutableMapping[Unknown, Unknown]], Literal[Mapping[Unknown, Unknown]], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], Literal[object]] +# revealed: tuple[, , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], ] reveal_type(DictSubclass.__mro__) class SetSubclass(typing.Set): ... # TODO: generic protocols -# revealed: tuple[Literal[SetSubclass], Literal[set], Literal[MutableSet], Literal[AbstractSet], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, Literal[object]] +# revealed: tuple[, , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, ] reveal_type(SetSubclass.__mro__) class FrozenSetSubclass(typing.FrozenSet): ... # TODO: should have `Generic`, should not have `Unknown` -# revealed: tuple[Literal[FrozenSetSubclass], Literal[frozenset], Unknown, Literal[object]] +# revealed: tuple[, , Unknown, ] reveal_type(FrozenSetSubclass.__mro__) #################### @@ -113,30 +113,30 @@ reveal_type(FrozenSetSubclass.__mro__) class ChainMapSubclass(typing.ChainMap): ... # TODO: generic protocols -# revealed: tuple[Literal[ChainMapSubclass], Literal[ChainMap[Unknown, Unknown]], Literal[MutableMapping[Unknown, Unknown]], Literal[Mapping[Unknown, Unknown]], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], Literal[object]] +# revealed: tuple[, , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], ] reveal_type(ChainMapSubclass.__mro__) class CounterSubclass(typing.Counter): ... # TODO: Should be (CounterSubclass, Counter, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object) -# revealed: tuple[Literal[CounterSubclass], Literal[Counter[Unknown]], Literal[dict[Unknown, int]], Literal[MutableMapping[Unknown, int]], Literal[Mapping[Unknown, int]], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], typing.Generic[_T], Literal[object]] +# revealed: tuple[, , , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], typing.Generic[_T], ] reveal_type(CounterSubclass.__mro__) class DefaultDictSubclass(typing.DefaultDict): ... # TODO: Should be (DefaultDictSubclass, defaultdict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object) -# revealed: tuple[Literal[DefaultDictSubclass], Literal[defaultdict[Unknown, Unknown]], Literal[dict[Unknown, Unknown]], Literal[MutableMapping[Unknown, Unknown]], Literal[Mapping[Unknown, Unknown]], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], Literal[object]] +# revealed: tuple[, , , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], ] reveal_type(DefaultDictSubclass.__mro__) class DequeSubclass(typing.Deque): ... # TODO: generic protocols -# revealed: tuple[Literal[DequeSubclass], Literal[deque], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, Literal[object]] +# revealed: tuple[, , , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, ] reveal_type(DequeSubclass.__mro__) class OrderedDictSubclass(typing.OrderedDict): ... # TODO: Should be (OrderedDictSubclass, OrderedDict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object) -# revealed: tuple[Literal[OrderedDictSubclass], Literal[OrderedDict[Unknown, Unknown]], Literal[dict[Unknown, Unknown]], Literal[MutableMapping[Unknown, Unknown]], Literal[Mapping[Unknown, Unknown]], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], Literal[object]] +# revealed: tuple[, , , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, typing.Generic[_KT, _VT_co], ] reveal_type(OrderedDictSubclass.__mro__) ``` diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_forms.md b/crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_forms.md index 14c595992c..0c186c070b 100644 --- a/crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_forms.md +++ b/crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_forms.md @@ -73,7 +73,7 @@ class E(Concatenate): ... # error: [invalid-base] class F(Callable): ... class G(Generic): ... # error: [invalid-base] "Cannot inherit from plain `Generic`" -reveal_type(F.__mro__) # revealed: tuple[Literal[F], @Todo(Support for Callable as a base class), Literal[object]] +reveal_type(F.__mro__) # revealed: tuple[, @Todo(Support for Callable as a base class), ] ``` ## Subscriptability diff --git a/crates/ty_python_semantic/resources/mdtest/attributes.md b/crates/ty_python_semantic/resources/mdtest/attributes.md index 682cc3a981..f07234026d 100644 --- a/crates/ty_python_semantic/resources/mdtest/attributes.md +++ b/crates/ty_python_semantic/resources/mdtest/attributes.md @@ -54,11 +54,11 @@ c_instance.declared_and_bound = False c_instance.declared_and_bound = "incompatible" # mypy shows no error here, but pyright raises "reportAttributeAccessIssue" -# error: [unresolved-attribute] "Attribute `inferred_from_value` can only be accessed on instances, not on the class object `Literal[C]` itself." +# error: [unresolved-attribute] "Attribute `inferred_from_value` can only be accessed on instances, not on the class object `` itself." reveal_type(C.inferred_from_value) # revealed: Unknown # mypy shows no error here, but pyright raises "reportAttributeAccessIssue" -# error: [invalid-attribute-access] "Cannot assign to instance attribute `inferred_from_value` from the class object `Literal[C]`" +# error: [invalid-attribute-access] "Cannot assign to instance attribute `inferred_from_value` from the class object ``" C.inferred_from_value = "overwritten on class" # This assignment is fine: @@ -90,11 +90,11 @@ reveal_type(c_instance.declared_and_bound) # revealed: str | None # Note that both mypy and pyright show no error in this case! So we may reconsider this in # the future, if it turns out to produce too many false positives. We currently emit: -# error: [unresolved-attribute] "Attribute `declared_and_bound` can only be accessed on instances, not on the class object `Literal[C]` itself." +# error: [unresolved-attribute] "Attribute `declared_and_bound` can only be accessed on instances, not on the class object `` itself." reveal_type(C.declared_and_bound) # revealed: Unknown # Same as above. Mypy and pyright do not show an error here. -# error: [invalid-attribute-access] "Cannot assign to instance attribute `declared_and_bound` from the class object `Literal[C]`" +# error: [invalid-attribute-access] "Cannot assign to instance attribute `declared_and_bound` from the class object ``" C.declared_and_bound = "overwritten on class" # error: [invalid-assignment] "Object of type `Literal[1]` is not assignable to attribute `declared_and_bound` of type `str | None`" @@ -115,10 +115,10 @@ c_instance = C() reveal_type(c_instance.only_declared) # revealed: str # Mypy and pyright do not show an error here. We treat this as a pure instance variable. -# error: [unresolved-attribute] "Attribute `only_declared` can only be accessed on instances, not on the class object `Literal[C]` itself." +# error: [unresolved-attribute] "Attribute `only_declared` can only be accessed on instances, not on the class object `` itself." reveal_type(C.only_declared) # revealed: Unknown -# error: [invalid-attribute-access] "Cannot assign to instance attribute `only_declared` from the class object `Literal[C]`" +# error: [invalid-attribute-access] "Cannot assign to instance attribute `only_declared` from the class object ``" C.only_declared = "overwritten on class" ``` @@ -191,10 +191,10 @@ reveal_type(c_instance.declared_only) # revealed: bytes reveal_type(c_instance.declared_and_bound) # revealed: bool -# error: [unresolved-attribute] "Attribute `inferred_from_value` can only be accessed on instances, not on the class object `Literal[C]` itself." +# error: [unresolved-attribute] "Attribute `inferred_from_value` can only be accessed on instances, not on the class object `` itself." reveal_type(C.inferred_from_value) # revealed: Unknown -# error: [invalid-attribute-access] "Cannot assign to instance attribute `inferred_from_value` from the class object `Literal[C]`" +# error: [invalid-attribute-access] "Cannot assign to instance attribute `inferred_from_value` from the class object ``" C.inferred_from_value = "overwritten on class" ``` @@ -718,7 +718,7 @@ reveal_type(C.pure_class_variable) # revealed: Unknown # TODO: should be no error when descriptor protocol is supported # and the assignment is properly attributed to the class method. -# error: [invalid-attribute-access] "Cannot assign to instance attribute `pure_class_variable` from the class object `Literal[C]`" +# error: [invalid-attribute-access] "Cannot assign to instance attribute `pure_class_variable` from the class object ``" C.pure_class_variable = "overwritten on class" # TODO: should be `Unknown | Literal["value set in class method"]` or @@ -925,7 +925,7 @@ def _(flag: bool): reveal_type(C1.y) # revealed: int | str C1.y = 100 - # error: [invalid-assignment] "Object of type `Literal["problematic"]` is not assignable to attribute `y` on type `Literal[C1, C1]`" + # error: [invalid-assignment] "Object of type `Literal["problematic"]` is not assignable to attribute `y` on type ` | `" C1.y = "problematic" class C2: @@ -1002,10 +1002,10 @@ def _(flag1: bool, flag2: bool): C = C1 if flag1 else C2 if flag2 else C3 - # error: [possibly-unbound-attribute] "Attribute `x` on type `Literal[C1, C2, C3]` is possibly unbound" + # error: [possibly-unbound-attribute] "Attribute `x` on type ` | | ` is possibly unbound" reveal_type(C.x) # revealed: Unknown | Literal[1, 3] - # error: [invalid-assignment] "Object of type `Literal[100]` is not assignable to attribute `x` on type `Literal[C1, C2, C3]`" + # error: [invalid-assignment] "Object of type `Literal[100]` is not assignable to attribute `x` on type ` | | `" C.x = 100 # error: [possibly-unbound-attribute] "Attribute `x` on type `C1 | C2 | C3` is possibly unbound" @@ -1034,7 +1034,7 @@ def _(flag: bool, flag1: bool, flag2: bool): C = C1 if flag1 else C2 if flag2 else C3 - # error: [possibly-unbound-attribute] "Attribute `x` on type `Literal[C1, C2, C3]` is possibly unbound" + # error: [possibly-unbound-attribute] "Attribute `x` on type ` | | ` is possibly unbound" reveal_type(C.x) # revealed: Unknown | Literal[1, 2, 3] # error: [possibly-unbound-attribute] @@ -1165,12 +1165,12 @@ def _(flag: bool): class C2: ... C = C1 if flag else C2 - # error: [unresolved-attribute] "Type `Literal[C1, C2]` has no attribute `x`" + # error: [unresolved-attribute] "Type ` | ` has no attribute `x`" reveal_type(C.x) # revealed: Unknown # TODO: This should ideally be a `unresolved-attribute` error. We need better union # handling in `validate_attribute_assignment` for this. - # error: [invalid-assignment] "Object of type `Literal[1]` is not assignable to attribute `x` on type `Literal[C1, C2]`" + # error: [invalid-assignment] "Object of type `Literal[1]` is not assignable to attribute `x` on type ` | `" C.x = 1 ``` @@ -1206,7 +1206,7 @@ class C(D, F): ... class B(E, D): ... class A(B, C): ... -# revealed: tuple[Literal[A], Literal[B], Literal[E], Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]] +# revealed: tuple[, , , , , , , ] reveal_type(A.__mro__) # `E` is earlier in the MRO than `F`, so we should use the type of `E.X` @@ -1399,7 +1399,7 @@ class A: class B(Any): ... class C(B, A): ... -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[B], Any, Literal[A], Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, , Any, , ] reveal_type(C.x) # revealed: Literal[1] & Any ``` @@ -1556,31 +1556,31 @@ The type of `x.__class__` is the same as `x`'s meta-type. `x.__class__` is alway ```py import typing_extensions -reveal_type(typing_extensions.__class__) # revealed: Literal[ModuleType] -reveal_type(type(typing_extensions)) # revealed: Literal[ModuleType] +reveal_type(typing_extensions.__class__) # revealed: +reveal_type(type(typing_extensions)) # revealed: a = 42 -reveal_type(a.__class__) # revealed: Literal[int] -reveal_type(type(a)) # revealed: Literal[int] +reveal_type(a.__class__) # revealed: +reveal_type(type(a)) # revealed: b = "42" -reveal_type(b.__class__) # revealed: Literal[str] +reveal_type(b.__class__) # revealed: c = b"42" -reveal_type(c.__class__) # revealed: Literal[bytes] +reveal_type(c.__class__) # revealed: d = True -reveal_type(d.__class__) # revealed: Literal[bool] +reveal_type(d.__class__) # revealed: e = (42, 42) -reveal_type(e.__class__) # revealed: Literal[tuple] +reveal_type(e.__class__) # revealed: def f(a: int, b: typing_extensions.LiteralString, c: int | str, d: type[str]): reveal_type(a.__class__) # revealed: type[int] reveal_type(type(a)) # revealed: type[int] - reveal_type(b.__class__) # revealed: Literal[str] - reveal_type(type(b)) # revealed: Literal[str] + reveal_type(b.__class__) # revealed: + reveal_type(type(b)) # revealed: reveal_type(c.__class__) # revealed: type[int] | type[str] reveal_type(type(c)) # revealed: type[int] | type[str] @@ -1591,11 +1591,11 @@ def f(a: int, b: typing_extensions.LiteralString, c: int | str, d: type[str]): # All we know is that the metaclass must be a (non-strict) subclass of `type`. reveal_type(d.__class__) # revealed: type[type] -reveal_type(f.__class__) # revealed: Literal[FunctionType] +reveal_type(f.__class__) # revealed: class Foo: ... -reveal_type(Foo.__class__) # revealed: Literal[type] +reveal_type(Foo.__class__) # revealed: ``` ## Module attributes diff --git a/crates/ty_python_semantic/resources/mdtest/binary/classes.md b/crates/ty_python_semantic/resources/mdtest/binary/classes.md index 464b2d3e7d..89dceef0e2 100644 --- a/crates/ty_python_semantic/resources/mdtest/binary/classes.md +++ b/crates/ty_python_semantic/resources/mdtest/binary/classes.md @@ -22,6 +22,6 @@ reveal_type(A | B) # revealed: UnionType class A: ... class B: ... -# error: "Operator `|` is unsupported between objects of type `Literal[A]` and `Literal[B]`" +# error: "Operator `|` is unsupported between objects of type `` and ``" reveal_type(A | B) # revealed: Unknown ``` diff --git a/crates/ty_python_semantic/resources/mdtest/binary/custom.md b/crates/ty_python_semantic/resources/mdtest/binary/custom.md index 8b0b6741e5..d2587b7a75 100644 --- a/crates/ty_python_semantic/resources/mdtest/binary/custom.md +++ b/crates/ty_python_semantic/resources/mdtest/binary/custom.md @@ -307,11 +307,11 @@ class Yes: class Sub(Yes): ... class No: ... -# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `Literal[Yes]` and `Literal[Yes]`" +# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `` and ``" reveal_type(Yes + Yes) # revealed: Unknown -# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `Literal[Sub]` and `Literal[Sub]`" +# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `` and ``" reveal_type(Sub + Sub) # revealed: Unknown -# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `Literal[No]` and `Literal[No]`" +# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `` and ``" reveal_type(No + No) # revealed: Unknown ``` diff --git a/crates/ty_python_semantic/resources/mdtest/binary/instances.md b/crates/ty_python_semantic/resources/mdtest/binary/instances.md index 650e7a636c..465527a4c4 100644 --- a/crates/ty_python_semantic/resources/mdtest/binary/instances.md +++ b/crates/ty_python_semantic/resources/mdtest/binary/instances.md @@ -388,13 +388,13 @@ class A(metaclass=Meta): ... class B(metaclass=Meta): ... reveal_type(A + B) # revealed: int -# error: [unsupported-operator] "Operator `-` is unsupported between objects of type `Literal[A]` and `Literal[B]`" +# error: [unsupported-operator] "Operator `-` is unsupported between objects of type `` and ``" reveal_type(A - B) # revealed: Unknown reveal_type(A < B) # revealed: bool reveal_type(A > B) # revealed: bool -# error: [unsupported-operator] "Operator `<=` is not supported for types `Literal[A]` and `Literal[B]`" +# error: [unsupported-operator] "Operator `<=` is not supported for types `` and ``" reveal_type(A <= B) # revealed: Unknown reveal_type(A[0]) # revealed: str diff --git a/crates/ty_python_semantic/resources/mdtest/boundness_declaredness/public.md b/crates/ty_python_semantic/resources/mdtest/boundness_declaredness/public.md index 956fa1cc7f..ab4f3ff0de 100644 --- a/crates/ty_python_semantic/resources/mdtest/boundness_declaredness/public.md +++ b/crates/ty_python_semantic/resources/mdtest/boundness_declaredness/public.md @@ -312,8 +312,8 @@ class C: ```py from mod import MyInt, C -reveal_type(MyInt) # revealed: Literal[int] -reveal_type(C.MyStr) # revealed: Literal[str] +reveal_type(MyInt) # revealed: +reveal_type(C.MyStr) # revealed: ``` ### Undeclared and possibly unbound @@ -336,8 +336,8 @@ if flag(): # error: [possibly-unbound-import] from mod import MyInt, C -reveal_type(MyInt) # revealed: Literal[int] -reveal_type(C.MyStr) # revealed: Literal[str] +reveal_type(MyInt) # revealed: +reveal_type(C.MyStr) # revealed: ``` ### Undeclared and unbound diff --git a/crates/ty_python_semantic/resources/mdtest/call/builtins.md b/crates/ty_python_semantic/resources/mdtest/call/builtins.md index a58162a15a..c93afe9baa 100644 --- a/crates/ty_python_semantic/resources/mdtest/call/builtins.md +++ b/crates/ty_python_semantic/resources/mdtest/call/builtins.md @@ -20,7 +20,7 @@ tested more extensively in `crates/ty_python_semantic/resources/mdtest/attribute tests for the `__class__` attribute.) ```py -reveal_type(type(1)) # revealed: Literal[int] +reveal_type(type(1)) # revealed: ``` But a three-argument call to type creates a dynamic instance of the `type` class: diff --git a/crates/ty_python_semantic/resources/mdtest/call/methods.md b/crates/ty_python_semantic/resources/mdtest/call/methods.md index c2646aaccd..c1b366749b 100644 --- a/crates/ty_python_semantic/resources/mdtest/call/methods.md +++ b/crates/ty_python_semantic/resources/mdtest/call/methods.md @@ -270,7 +270,7 @@ class Meta(type): class C(metaclass=Meta): pass -reveal_type(C.f) # revealed: bound method Literal[C].f(arg: int) -> str +reveal_type(C.f) # revealed: bound method .f(arg: int) -> str reveal_type(C.f(1)) # revealed: str ``` @@ -322,7 +322,7 @@ class C: def f(cls: type[C], x: int) -> str: return "a" -reveal_type(C.f) # revealed: bound method Literal[C].f(x: int) -> str +reveal_type(C.f) # revealed: bound method .f(x: int) -> str reveal_type(C().f) # revealed: bound method type[C].f(x: int) -> str ``` @@ -350,7 +350,7 @@ class D: # This function is wrongly annotated, it should be `type[D]` instead of `D` pass -# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `D`, found `Literal[D]`" +# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `D`, found ``" D.f() ``` @@ -360,7 +360,7 @@ When a class method is accessed on a derived class, it is bound to that derived class Derived(C): pass -reveal_type(Derived.f) # revealed: bound method Literal[Derived].f(x: int) -> str +reveal_type(Derived.f) # revealed: bound method .f(x: int) -> str reveal_type(Derived().f) # revealed: bound method type[Derived].f(x: int) -> str reveal_type(Derived.f(1)) # revealed: str @@ -386,15 +386,15 @@ reveal_type(getattr_static(C, "f").__get__) # revealed: Unknown -reveal_type(getattr_static(C, "f").__get__(C(), C)) # revealed: bound method Literal[C].f() -> Unknown +reveal_type(getattr_static(C, "f").__get__(None, C)) # revealed: bound method .f() -> Unknown +reveal_type(getattr_static(C, "f").__get__(C(), C)) # revealed: bound method .f() -> Unknown reveal_type(getattr_static(C, "f").__get__(C())) # revealed: bound method type[C].f() -> Unknown ``` The `owner` argument takes precedence over the `instance` argument: ```py -reveal_type(getattr_static(C, "f").__get__("dummy", C)) # revealed: bound method Literal[C].f() -> Unknown +reveal_type(getattr_static(C, "f").__get__("dummy", C)) # revealed: bound method .f() -> Unknown ``` ### Classmethods mixed with other decorators diff --git a/crates/ty_python_semantic/resources/mdtest/class/super.md b/crates/ty_python_semantic/resources/mdtest/class/super.md index 5ec8d09af1..ecffca0fb6 100644 --- a/crates/ty_python_semantic/resources/mdtest/class/super.md +++ b/crates/ty_python_semantic/resources/mdtest/class/super.md @@ -1,6 +1,6 @@ # Super -Python defines the terms *bound super object* and *unbound super object*. +Python defines the terms _bound super object_ and _unbound super object_. An **unbound super object** is created when `super` is called with only one argument. (e.g. `super(A)`). This object may later be bound using the `super.__get__` method. However, this form is @@ -30,24 +30,24 @@ class C(B): def c(self): ... cc: int = 3 -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[B], Literal[A], Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, , , ] super(C, C()).a super(C, C()).b -# error: [unresolved-attribute] "Type `` has no attribute `c`" +# error: [unresolved-attribute] "Type `, C>` has no attribute `c`" super(C, C()).c super(B, C()).a -# error: [unresolved-attribute] "Type `` has no attribute `b`" +# error: [unresolved-attribute] "Type `, C>` has no attribute `b`" super(B, C()).b -# error: [unresolved-attribute] "Type `` has no attribute `c`" +# error: [unresolved-attribute] "Type `, C>` has no attribute `c`" super(B, C()).c -# error: [unresolved-attribute] "Type `` has no attribute `a`" +# error: [unresolved-attribute] "Type `, C>` has no attribute `a`" super(A, C()).a -# error: [unresolved-attribute] "Type `` has no attribute `b`" +# error: [unresolved-attribute] "Type `, C>` has no attribute `b`" super(A, C()).b -# error: [unresolved-attribute] "Type `` has no attribute `c`" +# error: [unresolved-attribute] "Type `, C>` has no attribute `c`" super(A, C()).c reveal_type(super(C, C()).a) # revealed: bound method C.a() -> Unknown @@ -72,14 +72,14 @@ class A: class B(A): def __init__(self, a: int): - # TODO: Once `Self` is supported, this should be `` - reveal_type(super()) # revealed: + # TODO: Once `Self` is supported, this should be `, B>` + reveal_type(super()) # revealed: , Unknown> super().__init__(a) @classmethod def f(cls): - # TODO: Once `Self` is supported, this should be `` - reveal_type(super()) # revealed: + # TODO: Once `Self` is supported, this should be `, >` + reveal_type(super()) # revealed: , Unknown> super().f() super(B, B(42)).__init__(42) @@ -88,7 +88,7 @@ super(B, B).f() ### Unbound Super Object -Calling `super(cls)` without a second argument returns an *unbound super object*. This is treated as +Calling `super(cls)` without a second argument returns an _unbound super object_. This is treated as a plain `super` instance and does not support name lookup via the MRO. ```py @@ -115,7 +115,7 @@ class A: class B(A): ... reveal_type(super(B, B()).a) # revealed: int -# error: [invalid-assignment] "Cannot assign to attribute `a` on type ``" +# error: [invalid-assignment] "Cannot assign to attribute `a` on type `, B>`" super(B, B()).a = 3 # error: [invalid-assignment] "Cannot assign to attribute `a` on type `super`" super(B).a = 5 @@ -134,7 +134,7 @@ def f(x): reveal_type(x) # revealed: Unknown reveal_type(super(x, x)) # revealed: - reveal_type(super(A, x)) # revealed: + reveal_type(super(A, x)) # revealed: , Unknown> reveal_type(super(x, A())) # revealed: reveal_type(super(x, x).a) # revealed: Unknown @@ -149,29 +149,29 @@ from __future__ import annotations class A: def test(self): - reveal_type(super()) # revealed: + reveal_type(super()) # revealed: , Unknown> class B: def test(self): - reveal_type(super()) # revealed: + reveal_type(super()) # revealed: , Unknown> class C(A.B): def test(self): - reveal_type(super()) # revealed: + reveal_type(super()) # revealed: , Unknown> def inner(t: C): - reveal_type(super()) # revealed: - lambda x: reveal_type(super()) # revealed: + reveal_type(super()) # revealed: , C> + lambda x: reveal_type(super()) # revealed: , Unknown> ``` ## Built-ins and Literals ```py -reveal_type(super(bool, True)) # revealed: -reveal_type(super(bool, bool())) # revealed: -reveal_type(super(int, bool())) # revealed: -reveal_type(super(int, 3)) # revealed: -reveal_type(super(str, "")) # revealed: +reveal_type(super(bool, True)) # revealed: , bool> +reveal_type(super(bool, bool())) # revealed: , bool> +reveal_type(super(int, bool())) # revealed: , bool> +reveal_type(super(int, 3)) # revealed: , int> +reveal_type(super(str, "")) # revealed: , str> ``` ## Descriptor Behavior with Super @@ -195,7 +195,7 @@ reveal_type(super(B, B()).a2) # revealed: bound method type[B].a2() -> Unknown # A.__dict__["a1"].__get__(None, B) reveal_type(super(B, B).a1) # revealed: def a1(self) -> Unknown # A.__dict__["a2"].__get__(None, B) -reveal_type(super(B, B).a2) # revealed: bound method Literal[B].a2() -> Unknown +reveal_type(super(B, B).a2) # revealed: bound method .a2() -> Unknown ``` ## Union of Supers @@ -213,22 +213,22 @@ class C(A, B): ... class D(B, A): ... def f(x: C | D): - reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[A], Literal[B], Literal[object]] - reveal_type(D.__mro__) # revealed: tuple[Literal[D], Literal[B], Literal[A], Literal[object]] + reveal_type(C.__mro__) # revealed: tuple[, , , ] + reveal_type(D.__mro__) # revealed: tuple[, , , ] s = super(A, x) - reveal_type(s) # revealed: | + reveal_type(s) # revealed: , C> | , D> - # error: [possibly-unbound-attribute] "Attribute `b` on type ` | ` is possibly unbound" + # error: [possibly-unbound-attribute] "Attribute `b` on type `, C> | , D>` is possibly unbound" s.b def f(flag: bool): x = str() if flag else str("hello") reveal_type(x) # revealed: Literal["", "hello"] - reveal_type(super(str, x)) # revealed: + reveal_type(super(str, x)) # revealed: , str> def f(x: int | str): - # error: [invalid-super-argument] "`str` is not an instance or subclass of `Literal[int]` in `super(Literal[int], str)` call" + # error: [invalid-super-argument] "`str` is not an instance or subclass of `` in `super(, str)` call" super(int, x) ``` @@ -254,12 +254,12 @@ def f(flag: bool): class D(C): ... s = super(D, D()) - reveal_type(s) # revealed: | + reveal_type(s) # revealed: , B> | , D> reveal_type(s.x) # revealed: Unknown | Literal[1, 2] reveal_type(s.y) # revealed: int | str - # error: [possibly-unbound-attribute] "Attribute `a` on type ` | ` is possibly unbound" + # error: [possibly-unbound-attribute] "Attribute `a` on type `, B> | , D>` is possibly unbound" reveal_type(s.a) # revealed: str ``` @@ -339,30 +339,30 @@ def f(x: int): # error: [invalid-super-argument] "`typing.TypeAliasType` is not a valid class" super(IntAlias, 0) -# error: [invalid-super-argument] "`Literal[""]` is not an instance or subclass of `Literal[int]` in `super(Literal[int], Literal[""])` call" +# error: [invalid-super-argument] "`Literal[""]` is not an instance or subclass of `` in `super(, Literal[""])` call" # revealed: Unknown reveal_type(super(int, str())) -# error: [invalid-super-argument] "`Literal[str]` is not an instance or subclass of `Literal[int]` in `super(Literal[int], Literal[str])` call" +# error: [invalid-super-argument] "`` is not an instance or subclass of `` in `super(, )` call" # revealed: Unknown reveal_type(super(int, str)) class A: ... class B(A): ... -# error: [invalid-super-argument] "`A` is not an instance or subclass of `Literal[B]` in `super(Literal[B], A)` call" +# error: [invalid-super-argument] "`A` is not an instance or subclass of `` in `super(, A)` call" # revealed: Unknown reveal_type(super(B, A())) -# error: [invalid-super-argument] "`object` is not an instance or subclass of `Literal[B]` in `super(Literal[B], object)` call" +# error: [invalid-super-argument] "`object` is not an instance or subclass of `` in `super(, object)` call" # revealed: Unknown reveal_type(super(B, object())) -# error: [invalid-super-argument] "`Literal[A]` is not an instance or subclass of `Literal[B]` in `super(Literal[B], Literal[A])` call" +# error: [invalid-super-argument] "`` is not an instance or subclass of `` in `super(, )` call" # revealed: Unknown reveal_type(super(B, A)) -# error: [invalid-super-argument] "`Literal[object]` is not an instance or subclass of `Literal[B]` in `super(Literal[B], Literal[object])` call" +# error: [invalid-super-argument] "`` is not an instance or subclass of `` in `super(, )` call" # revealed: Unknown reveal_type(super(B, object)) @@ -386,7 +386,7 @@ class B(A): # TODO: Once `Self` is supported, this should raise `unresolved-attribute` error super().a -# error: [unresolved-attribute] "Type `` has no attribute `a`" +# error: [unresolved-attribute] "Type `, B>` has no attribute `a`" super(B, B(42)).a ``` @@ -405,6 +405,6 @@ class B(A): ... reveal_type(A()[0]) # revealed: int reveal_type(super(B, B()).__getitem__) # revealed: bound method B.__getitem__(key: int) -> int -# error: [non-subscriptable] "Cannot subscript object of type `` with no `__getitem__` method" +# error: [non-subscriptable] "Cannot subscript object of type `, B>` with no `__getitem__` method" super(B, B())[0] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/dataclasses.md b/crates/ty_python_semantic/resources/mdtest/dataclasses.md index 7d8c1edbdb..54ac25998b 100644 --- a/crates/ty_python_semantic/resources/mdtest/dataclasses.md +++ b/crates/ty_python_semantic/resources/mdtest/dataclasses.md @@ -181,7 +181,7 @@ class D: class_literal: TypeOf[SomeClass] class_subtype_of: type[SomeClass] -# revealed: (function_literal: def some_function() -> None, class_literal: Literal[SomeClass], class_subtype_of: type[SomeClass]) -> None +# revealed: (function_literal: def some_function() -> None, class_literal: , class_subtype_of: type[SomeClass]) -> None reveal_type(D.__init__) ``` @@ -489,7 +489,7 @@ class DataWithDescription[T]: data: T description: str -reveal_type(DataWithDescription[int]) # revealed: Literal[DataWithDescription[int]] +reveal_type(DataWithDescription[int]) # revealed: d_int = DataWithDescription[int](1, "description") # OK reveal_type(d_int.data) # revealed: int @@ -675,7 +675,7 @@ from dataclasses import dataclass class C: x: int -# error: [unresolved-attribute] "Attribute `x` can only be accessed on instances, not on the class object `Literal[C]` itself." +# error: [unresolved-attribute] "Attribute `x` can only be accessed on instances, not on the class object `` itself." C.x ``` @@ -715,8 +715,8 @@ class Person: name: str age: int | None = None -reveal_type(type(Person)) # revealed: Literal[type] -reveal_type(Person.__mro__) # revealed: tuple[Literal[Person], Literal[object]] +reveal_type(type(Person)) # revealed: +reveal_type(Person.__mro__) # revealed: tuple[, ] ``` The generated methods have the following signatures: diff --git a/crates/ty_python_semantic/resources/mdtest/descriptor_protocol.md b/crates/ty_python_semantic/resources/mdtest/descriptor_protocol.md index 8f8d17ae76..cc9661b54f 100644 --- a/crates/ty_python_semantic/resources/mdtest/descriptor_protocol.md +++ b/crates/ty_python_semantic/resources/mdtest/descriptor_protocol.md @@ -269,7 +269,7 @@ on the metaclass: ```py C1.meta_data_descriptor = 1 -# error: [invalid-assignment] "Invalid assignment to data descriptor attribute `meta_data_descriptor` on type `Literal[C1]` with custom `__set__` method" +# error: [invalid-assignment] "Invalid assignment to data descriptor attribute `meta_data_descriptor` on type `` with custom `__set__` method" C1.meta_data_descriptor = "invalid" ``` @@ -371,7 +371,7 @@ def _(flag: bool): # TODO: We currently emit two diagnostics here, corresponding to the two states of `flag`. The diagnostics are not # wrong, but they could be subsumed under a higher-level diagnostic. - # error: [invalid-assignment] "Invalid assignment to data descriptor attribute `meta_data_descriptor1` on type `Literal[C5]` with custom `__set__` method" + # error: [invalid-assignment] "Invalid assignment to data descriptor attribute `meta_data_descriptor1` on type `` with custom `__set__` method" # error: [invalid-assignment] "Object of type `None` is not assignable to attribute `meta_data_descriptor1` of type `Literal["value on class"]`" C5.meta_data_descriptor1 = None @@ -724,13 +724,13 @@ def _(flag: bool): non_data: NonDataDescriptor = NonDataDescriptor() data: DataDescriptor = DataDescriptor() - # error: [possibly-unbound-attribute] "Attribute `non_data` on type `Literal[PossiblyUnbound]` is possibly unbound" + # error: [possibly-unbound-attribute] "Attribute `non_data` on type `` is possibly unbound" reveal_type(PossiblyUnbound.non_data) # revealed: int # error: [possibly-unbound-attribute] "Attribute `non_data` on type `PossiblyUnbound` is possibly unbound" reveal_type(PossiblyUnbound().non_data) # revealed: int - # error: [possibly-unbound-attribute] "Attribute `data` on type `Literal[PossiblyUnbound]` is possibly unbound" + # error: [possibly-unbound-attribute] "Attribute `data` on type `` is possibly unbound" reveal_type(PossiblyUnbound.data) # revealed: int # error: [possibly-unbound-attribute] "Attribute `data` on type `PossiblyUnbound` is possibly unbound" diff --git a/crates/ty_python_semantic/resources/mdtest/exception/control_flow.md b/crates/ty_python_semantic/resources/mdtest/exception/control_flow.md index 2db3cf362d..fe1e253c31 100644 --- a/crates/ty_python_semantic/resources/mdtest/exception/control_flow.md +++ b/crates/ty_python_semantic/resources/mdtest/exception/control_flow.md @@ -600,12 +600,12 @@ except: reveal_type(x) # revealed: E x = Bar - reveal_type(x) # revealed: Literal[Bar] + reveal_type(x) # revealed: finally: - # TODO: should be `Literal[1] | Literal[foo] | Literal[Bar]` - reveal_type(x) # revealed: (def foo(param=A) -> Unknown) | Literal[Bar] + # TODO: should be `Literal[1] | | ` + reveal_type(x) # revealed: (def foo(param=A) -> Unknown) | -reveal_type(x) # revealed: (def foo(param=A) -> Unknown) | Literal[Bar] +reveal_type(x) # revealed: (def foo(param=A) -> Unknown) | ``` [1]: https://astral-sh.notion.site/Exception-handler-control-flow-11348797e1ca80bb8ce1e9aedbbe439d diff --git a/crates/ty_python_semantic/resources/mdtest/expression/attribute.md b/crates/ty_python_semantic/resources/mdtest/expression/attribute.md index 1ccf74edd4..43df56264c 100644 --- a/crates/ty_python_semantic/resources/mdtest/expression/attribute.md +++ b/crates/ty_python_semantic/resources/mdtest/expression/attribute.md @@ -26,9 +26,9 @@ def _(flag: bool): reveal_type(A.union_declared) # revealed: int | str - # error: [possibly-unbound-attribute] "Attribute `possibly_unbound` on type `Literal[A]` is possibly unbound" + # error: [possibly-unbound-attribute] "Attribute `possibly_unbound` on type `` is possibly unbound" reveal_type(A.possibly_unbound) # revealed: str - # error: [unresolved-attribute] "Type `Literal[A]` has no attribute `non_existent`" + # error: [unresolved-attribute] "Type `` has no attribute `non_existent`" reveal_type(A.non_existent) # revealed: Unknown ``` diff --git a/crates/ty_python_semantic/resources/mdtest/generics/legacy/classes.md b/crates/ty_python_semantic/resources/mdtest/generics/legacy/classes.md index 0d2fd6ae02..204c19e29b 100644 --- a/crates/ty_python_semantic/resources/mdtest/generics/legacy/classes.md +++ b/crates/ty_python_semantic/resources/mdtest/generics/legacy/classes.md @@ -29,7 +29,7 @@ class RepeatedTypevar(Generic[T, T]): ... You can only specialize `typing.Generic` with typevars (TODO: or param specs or typevar tuples). ```py -# error: [invalid-argument-type] "`Literal[int]` is not a valid argument to `typing.Generic`" +# error: [invalid-argument-type] "`` is not a valid argument to `typing.Generic`" class GenericOfType(Generic[int]): ... ``` @@ -436,7 +436,7 @@ T = TypeVar("T") class Base(Generic[T]): ... class Sub(Base[Sub]): ... -reveal_type(Sub) # revealed: Literal[Sub] +reveal_type(Sub) # revealed: ``` #### With string forward references @@ -451,7 +451,7 @@ T = TypeVar("T") class Base(Generic[T]): ... class Sub(Base["Sub"]): ... -reveal_type(Sub) # revealed: Literal[Sub] +reveal_type(Sub) # revealed: ``` #### Without string forward references diff --git a/crates/ty_python_semantic/resources/mdtest/generics/legacy/variables.md b/crates/ty_python_semantic/resources/mdtest/generics/legacy/variables.md index 17021dd398..dafc369109 100644 --- a/crates/ty_python_semantic/resources/mdtest/generics/legacy/variables.md +++ b/crates/ty_python_semantic/resources/mdtest/generics/legacy/variables.md @@ -19,7 +19,7 @@ in newer Python releases. from typing import TypeVar T = TypeVar("T") -reveal_type(type(T)) # revealed: Literal[TypeVar] +reveal_type(type(T)) # revealed: reveal_type(T) # revealed: typing.TypeVar reveal_type(T.__name__) # revealed: Literal["T"] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md b/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md index 89ebf00124..6162470aba 100644 --- a/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md +++ b/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md @@ -362,7 +362,7 @@ Here, `Sub` is not a generic class, since it fills its superclass's type paramet class Base[T]: ... class Sub(Base[Sub]): ... -reveal_type(Sub) # revealed: Literal[Sub] +reveal_type(Sub) # revealed: ``` #### With string forward references @@ -373,7 +373,7 @@ A similar case can work in a non-stub file, if forward references are stringifie class Base[T]: ... class Sub(Base["Sub"]): ... -reveal_type(Sub) # revealed: Literal[Sub] +reveal_type(Sub) # revealed: ``` #### Without string forward references diff --git a/crates/ty_python_semantic/resources/mdtest/generics/pep695/variables.md b/crates/ty_python_semantic/resources/mdtest/generics/pep695/variables.md index 2c84f02c95..2b921a3c3b 100644 --- a/crates/ty_python_semantic/resources/mdtest/generics/pep695/variables.md +++ b/crates/ty_python_semantic/resources/mdtest/generics/pep695/variables.md @@ -16,7 +16,7 @@ instances of `typing.TypeVar`, just like legacy type variables. ```py def f[T](): - reveal_type(type(T)) # revealed: Literal[TypeVar] + reveal_type(type(T)) # revealed: reveal_type(T) # revealed: typing.TypeVar reveal_type(T.__name__) # revealed: Literal["T"] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/import/basic.md b/crates/ty_python_semantic/resources/mdtest/import/basic.md index 53fcd705ea..60edbc392b 100644 --- a/crates/ty_python_semantic/resources/mdtest/import/basic.md +++ b/crates/ty_python_semantic/resources/mdtest/import/basic.md @@ -6,7 +6,7 @@ from b import C as D E = D -reveal_type(E) # revealed: Literal[C] +reveal_type(E) # revealed: ``` `b.py`: @@ -21,7 +21,7 @@ class C: ... import b D = b.C -reveal_type(D) # revealed: Literal[C] +reveal_type(D) # revealed: ``` `b.py`: @@ -35,7 +35,7 @@ class C: ... ```py import a.b -reveal_type(a.b.C) # revealed: Literal[C] +reveal_type(a.b.C) # revealed: ``` `a/__init__.py`: @@ -54,7 +54,7 @@ class C: ... ```py import a.b.c -reveal_type(a.b.c.C) # revealed: Literal[C] +reveal_type(a.b.c.C) # revealed: ``` `a/__init__.py`: @@ -78,7 +78,7 @@ class C: ... ```py import a.b as b -reveal_type(b.C) # revealed: Literal[C] +reveal_type(b.C) # revealed: ``` `a/__init__.py`: @@ -97,7 +97,7 @@ class C: ... ```py import a.b.c as c -reveal_type(c.C) # revealed: Literal[C] +reveal_type(c.C) # revealed: ``` `a/__init__.py`: diff --git a/crates/ty_python_semantic/resources/mdtest/import/builtins.md b/crates/ty_python_semantic/resources/mdtest/import/builtins.md index 7d1a3f5e0b..f8ef2a2f9a 100644 --- a/crates/ty_python_semantic/resources/mdtest/import/builtins.md +++ b/crates/ty_python_semantic/resources/mdtest/import/builtins.md @@ -16,7 +16,7 @@ Or used implicitly: ```py reveal_type(chr) # revealed: def chr(i: SupportsIndex, /) -> str -reveal_type(str) # revealed: Literal[str] +reveal_type(str) # revealed: ``` ## Builtin symbol from custom typeshed diff --git a/crates/ty_python_semantic/resources/mdtest/import/conventions.md b/crates/ty_python_semantic/resources/mdtest/import/conventions.md index 8781c38de1..73d9e1f525 100644 --- a/crates/ty_python_semantic/resources/mdtest/import/conventions.md +++ b/crates/ty_python_semantic/resources/mdtest/import/conventions.md @@ -95,6 +95,7 @@ from typing import Any, Literal `foo.pyi`: ```pyi + ``` ## Nested non-exports @@ -187,7 +188,7 @@ reveal_type(Foo) # revealed: Unknown ```pyi from b import AnyFoo as Foo -reveal_type(Foo) # revealed: Literal[AnyFoo] +reveal_type(Foo) # revealed: ``` `b.pyi`: @@ -251,11 +252,13 @@ class Foo: ... `a/b/__init__.pyi`: ```pyi + ``` `a/b/c.pyi`: ```pyi + ``` ## Conditional re-export in stub file @@ -281,7 +284,7 @@ def coinflip() -> bool: ... if coinflip(): Foo: str = ... -reveal_type(Foo) # revealed: Literal[Foo] | str +reveal_type(Foo) # revealed: | str ``` `b.pyi`: @@ -299,7 +302,7 @@ the other does not. # error: "Member `Foo` of module `a` is possibly unbound" from a import Foo -reveal_type(Foo) # revealed: Literal[Foo] +reveal_type(Foo) # revealed: ``` `a.pyi`: @@ -312,7 +315,7 @@ if coinflip(): else: from b import Foo as Foo -reveal_type(Foo) # revealed: Literal[Foo] +reveal_type(Foo) # revealed: ``` `b.pyi`: @@ -327,7 +330,7 @@ class Foo: ... # error: "Member `Foo` of module `a` is possibly unbound" from a import Foo -reveal_type(Foo) # revealed: Literal[Foo] +reveal_type(Foo) # revealed: ``` `a.pyi`: diff --git a/crates/ty_python_semantic/resources/mdtest/import/errors.md b/crates/ty_python_semantic/resources/mdtest/import/errors.md index 97716b5f18..14e785613b 100644 --- a/crates/ty_python_semantic/resources/mdtest/import/errors.md +++ b/crates/ty_python_semantic/resources/mdtest/import/errors.md @@ -69,12 +69,12 @@ x = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]" ```py class A: ... -reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[object]] +reveal_type(A.__mro__) # revealed: tuple[, ] import b class C(b.B): ... -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[B], Literal[A], Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, , , ] ``` `b.py`: @@ -84,5 +84,5 @@ from a import A class B(A): ... -reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[A], Literal[object]] +reveal_type(B.__mro__) # revealed: tuple[, , ] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/import/relative.md b/crates/ty_python_semantic/resources/mdtest/import/relative.md index 85e03404cc..9c3e303a9d 100644 --- a/crates/ty_python_semantic/resources/mdtest/import/relative.md +++ b/crates/ty_python_semantic/resources/mdtest/import/relative.md @@ -255,7 +255,7 @@ python-version = "3.13" ```py from foo import A -reveal_type(A) # revealed: Literal[A] +reveal_type(A) # revealed: ``` `/src/.venv//foo/__init__.py`: diff --git a/crates/ty_python_semantic/resources/mdtest/import/star.md b/crates/ty_python_semantic/resources/mdtest/import/star.md index 87726190d8..0603058358 100644 --- a/crates/ty_python_semantic/resources/mdtest/import/star.md +++ b/crates/ty_python_semantic/resources/mdtest/import/star.md @@ -1353,7 +1353,7 @@ are present due to `*` imports. ```py import collections.abc -reveal_type(collections.abc.Sequence) # revealed: Literal[Sequence] +reveal_type(collections.abc.Sequence) # revealed: reveal_type(collections.abc.Callable) # revealed: typing.Callable # TODO: false positive as it's only re-exported from `_collections.abc` due to presence in `__all__` diff --git a/crates/ty_python_semantic/resources/mdtest/import/tracking.md b/crates/ty_python_semantic/resources/mdtest/import/tracking.md index effbcd4a98..f31193b762 100644 --- a/crates/ty_python_semantic/resources/mdtest/import/tracking.md +++ b/crates/ty_python_semantic/resources/mdtest/import/tracking.md @@ -27,7 +27,7 @@ has been imported. import a # Would be an error with flow-sensitive tracking -reveal_type(a.b.C) # revealed: Literal[C] +reveal_type(a.b.C) # revealed: import a.b ``` @@ -53,10 +53,10 @@ submodule `b`, even though `a.b` is never imported in the main module. from q import a, b reveal_type(b) # revealed: -reveal_type(b.C) # revealed: Literal[C] +reveal_type(b.C) # revealed: reveal_type(a.b) # revealed: -reveal_type(a.b.C) # revealed: Literal[C] +reveal_type(a.b.C) # revealed: ``` `a/__init__.py`: diff --git a/crates/ty_python_semantic/resources/mdtest/metaclass.md b/crates/ty_python_semantic/resources/mdtest/metaclass.md index 84499c766a..3c4762fe8f 100644 --- a/crates/ty_python_semantic/resources/mdtest/metaclass.md +++ b/crates/ty_python_semantic/resources/mdtest/metaclass.md @@ -3,19 +3,19 @@ ```py class M(type): ... -reveal_type(M.__class__) # revealed: Literal[type] +reveal_type(M.__class__) # revealed: ``` ## `object` ```py -reveal_type(object.__class__) # revealed: Literal[type] +reveal_type(object.__class__) # revealed: ``` ## `type` ```py -reveal_type(type.__class__) # revealed: Literal[type] +reveal_type(type.__class__) # revealed: ``` ## Basic @@ -24,7 +24,7 @@ reveal_type(type.__class__) # revealed: Literal[type] class M(type): ... class B(metaclass=M): ... -reveal_type(B.__class__) # revealed: Literal[M] +reveal_type(B.__class__) # revealed: ``` ## Invalid metaclass @@ -37,7 +37,7 @@ class M: ... class A(metaclass=M): ... # TODO: emit a diagnostic for the invalid metaclass -reveal_type(A.__class__) # revealed: Literal[M] +reveal_type(A.__class__) # revealed: ``` ## Linear inheritance @@ -50,7 +50,7 @@ class M(type): ... class A(metaclass=M): ... class B(A): ... -reveal_type(B.__class__) # revealed: Literal[M] +reveal_type(B.__class__) # revealed: ``` ## Linear inheritance with PEP 695 generic class @@ -68,8 +68,8 @@ class A[T](metaclass=M): ... class B(A): ... class C(A[int]): ... -reveal_type(B.__class__) # revealed: Literal[M] -reveal_type(C.__class__) # revealed: Literal[M] +reveal_type(B.__class__) # revealed: +reveal_type(C.__class__) # revealed: ``` ## Conflict (1) @@ -117,7 +117,7 @@ class A(metaclass=M): ... class B(metaclass=M): ... class C(A, B): ... -reveal_type(C.__class__) # revealed: Literal[M] +reveal_type(C.__class__) # revealed: ``` ## Metaclass metaclass @@ -131,7 +131,7 @@ class M3(M2): ... class A(metaclass=M3): ... class B(A): ... -reveal_type(A.__class__) # revealed: Literal[M3] +reveal_type(A.__class__) # revealed: ``` ## Diamond inheritance @@ -159,14 +159,14 @@ from nonexistent_module import UnknownClass # error: [unresolved-import] class C(UnknownClass): ... # TODO: should be `type[type] & Unknown` -reveal_type(C.__class__) # revealed: Literal[type] +reveal_type(C.__class__) # revealed: class M(type): ... class A(metaclass=M): ... class B(A, UnknownClass): ... # TODO: should be `type[M] & Unknown` -reveal_type(B.__class__) # revealed: Literal[M] +reveal_type(B.__class__) # revealed: ``` ## Duplicate @@ -176,7 +176,7 @@ class M(type): ... class A(metaclass=M): ... class B(A, A): ... # error: [duplicate-base] "Duplicate base class `A`" -reveal_type(B.__class__) # revealed: Literal[M] +reveal_type(B.__class__) # revealed: ``` ## Non-class @@ -191,14 +191,14 @@ def f(*args, **kwargs) -> int: class A(metaclass=f): ... # TODO: Should be `int` -reveal_type(A) # revealed: Literal[A] +reveal_type(A) # revealed: reveal_type(A.__class__) # revealed: type[int] def _(n: int): # error: [invalid-metaclass] class B(metaclass=n): ... # TODO: Should be `Unknown` - reveal_type(B) # revealed: Literal[B] + reveal_type(B) # revealed: reveal_type(B.__class__) # revealed: type[Unknown] def _(flag: bool): @@ -207,7 +207,7 @@ def _(flag: bool): # error: [invalid-metaclass] class C(metaclass=m): ... # TODO: Should be `int | Unknown` - reveal_type(C) # revealed: Literal[C] + reveal_type(C) # revealed: reveal_type(C.__class__) # revealed: type[Unknown] class SignatureMismatch: ... @@ -216,9 +216,9 @@ class SignatureMismatch: ... class D(metaclass=SignatureMismatch): ... # TODO: Should be `Unknown` -reveal_type(D) # revealed: Literal[D] +reveal_type(D) # revealed: # TODO: Should be `type[Unknown]` -reveal_type(D.__class__) # revealed: Literal[SignatureMismatch] +reveal_type(D.__class__) # revealed: ``` ## Cyclic @@ -244,7 +244,7 @@ python-version = "3.12" class M(type): ... class A[T: str](metaclass=M): ... -reveal_type(A.__class__) # revealed: Literal[M] +reveal_type(A.__class__) # revealed: ``` ## Metaclasses of metaclasses @@ -255,9 +255,9 @@ class Bar(type, metaclass=Foo): ... class Baz(type, metaclass=Bar): ... class Spam(metaclass=Baz): ... -reveal_type(Spam.__class__) # revealed: Literal[Baz] -reveal_type(Spam.__class__.__class__) # revealed: Literal[Bar] -reveal_type(Spam.__class__.__class__.__class__) # revealed: Literal[Foo] +reveal_type(Spam.__class__) # revealed: +reveal_type(Spam.__class__.__class__) # revealed: +reveal_type(Spam.__class__.__class__.__class__) # revealed: def test(x: Spam): reveal_type(x.__class__) # revealed: type[Spam] diff --git a/crates/ty_python_semantic/resources/mdtest/mro.md b/crates/ty_python_semantic/resources/mdtest/mro.md index 5239849766..b9376d25d9 100644 --- a/crates/ty_python_semantic/resources/mdtest/mro.md +++ b/crates/ty_python_semantic/resources/mdtest/mro.md @@ -16,13 +16,13 @@ For documentation on method resolution orders, see: ```py class C: ... -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, ] ``` ## The special case: `object` itself ```py -reveal_type(object.__mro__) # revealed: tuple[Literal[object]] +reveal_type(object.__mro__) # revealed: tuple[] ``` ## Explicit inheritance from `object` @@ -30,7 +30,7 @@ reveal_type(object.__mro__) # revealed: tuple[Literal[object]] ```py class C(object): ... -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, ] ``` ## Explicit inheritance from non-`object` single base @@ -39,7 +39,7 @@ reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[object]] class A: ... class B(A): ... -reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[A], Literal[object]] +reveal_type(B.__mro__) # revealed: tuple[, , ] ``` ## Linearization of multiple bases @@ -49,7 +49,7 @@ class A: ... class B: ... class C(A, B): ... -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[A], Literal[B], Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, , , ] ``` ## Complex diamond inheritance (1) @@ -63,8 +63,8 @@ class Y(O): ... class A(X, Y): ... class B(Y, X): ... -reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[X], Literal[Y], Literal[O], Literal[object]] -reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[Y], Literal[X], Literal[O], Literal[object]] +reveal_type(A.__mro__) # revealed: tuple[, , , , ] +reveal_type(B.__mro__) # revealed: tuple[, , , , ] ``` ## Complex diamond inheritance (2) @@ -80,11 +80,11 @@ class C(D, F): ... class B(D, E): ... class A(B, C): ... -# revealed: tuple[Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]] +# revealed: tuple[, , , , ] reveal_type(C.__mro__) -# revealed: tuple[Literal[B], Literal[D], Literal[E], Literal[O], Literal[object]] +# revealed: tuple[, , , , ] reveal_type(B.__mro__) -# revealed: tuple[Literal[A], Literal[B], Literal[C], Literal[D], Literal[E], Literal[F], Literal[O], Literal[object]] +# revealed: tuple[, , , , , , , ] reveal_type(A.__mro__) ``` @@ -101,11 +101,11 @@ class C(D, F): ... class B(E, D): ... class A(B, C): ... -# revealed: tuple[Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]] +# revealed: tuple[, , , , ] reveal_type(C.__mro__) -# revealed: tuple[Literal[B], Literal[E], Literal[D], Literal[O], Literal[object]] +# revealed: tuple[, , , , ] reveal_type(B.__mro__) -# revealed: tuple[Literal[A], Literal[B], Literal[E], Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]] +# revealed: tuple[, , , , , , , ] reveal_type(A.__mro__) ``` @@ -125,13 +125,13 @@ class K2(D, B, E): ... class K3(D, A): ... class Z(K1, K2, K3): ... -# revealed: tuple[Literal[K1], Literal[A], Literal[B], Literal[C], Literal[O], Literal[object]] +# revealed: tuple[, , , , , ] reveal_type(K1.__mro__) -# revealed: tuple[Literal[K2], Literal[D], Literal[B], Literal[E], Literal[O], Literal[object]] +# revealed: tuple[, , , , , ] reveal_type(K2.__mro__) -# revealed: tuple[Literal[K3], Literal[D], Literal[A], Literal[O], Literal[object]] +# revealed: tuple[, , , , ] reveal_type(K3.__mro__) -# revealed: tuple[Literal[Z], Literal[K1], Literal[K2], Literal[K3], Literal[D], Literal[A], Literal[B], Literal[C], Literal[E], Literal[O], Literal[object]] +# revealed: tuple[, , , , , , , , , , ] reveal_type(Z.__mro__) ``` @@ -147,10 +147,11 @@ class D(A, B, C): ... class E(B, C): ... class F(E, A): ... -reveal_type(A.__mro__) # revealed: tuple[Literal[A], Unknown, Literal[object]] -reveal_type(D.__mro__) # revealed: tuple[Literal[D], Literal[A], Unknown, Literal[B], Literal[C], Literal[object]] -reveal_type(E.__mro__) # revealed: tuple[Literal[E], Literal[B], Literal[C], Literal[object]] -reveal_type(F.__mro__) # revealed: tuple[Literal[F], Literal[E], Literal[B], Literal[C], Literal[A], Unknown, Literal[object]] +reveal_type(A.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(D.__mro__) # revealed: tuple[, , Unknown, , , ] +reveal_type(E.__mro__) # revealed: tuple[, , , ] +# revealed: tuple[, , , , , Unknown, ] +reveal_type(F.__mro__) ``` ## `__bases__` lists that cause errors at runtime @@ -162,11 +163,11 @@ creation to fail, we infer the class's `__mro__` as being `[, Unknown, ob # error: [inconsistent-mro] "Cannot create a consistent method resolution order (MRO) for class `Foo` with bases list `[, ]`" class Foo(object, int): ... -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] class Bar(Foo): ... -reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Literal[Foo], Unknown, Literal[object]] +reveal_type(Bar.__mro__) # revealed: tuple[, , Unknown, ] # This is the `TypeError` at the bottom of "ex_2" # in the examples at @@ -176,17 +177,17 @@ class Y(O): ... class A(X, Y): ... class B(Y, X): ... -reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[X], Literal[Y], Literal[O], Literal[object]] -reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[Y], Literal[X], Literal[O], Literal[object]] +reveal_type(A.__mro__) # revealed: tuple[, , , , ] +reveal_type(B.__mro__) # revealed: tuple[, , , , ] # error: [inconsistent-mro] "Cannot create a consistent method resolution order (MRO) for class `Z` with bases list `[, ]`" class Z(A, B): ... -reveal_type(Z.__mro__) # revealed: tuple[Literal[Z], Unknown, Literal[object]] +reveal_type(Z.__mro__) # revealed: tuple[, Unknown, ] class AA(Z): ... -reveal_type(AA.__mro__) # revealed: tuple[Literal[AA], Literal[Z], Unknown, Literal[object]] +reveal_type(AA.__mro__) # revealed: tuple[, , Unknown, ] ``` ## `__bases__` includes a `Union` @@ -207,12 +208,12 @@ if returns_bool(): else: x = B -reveal_type(x) # revealed: Literal[A, B] +reveal_type(x) # revealed: | -# error: 11 [invalid-base] "Invalid class base with type `Literal[A, B]` (all bases must be a class, `Any`, `Unknown` or `Todo`)" +# error: 11 [invalid-base] "Invalid class base with type ` | ` (all bases must be a class, `Any`, `Unknown` or `Todo`)" class Foo(x): ... -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] ``` ## `__bases__` includes multiple `Union`s @@ -236,14 +237,14 @@ if returns_bool(): else: y = D -reveal_type(x) # revealed: Literal[A, B] -reveal_type(y) # revealed: Literal[C, D] +reveal_type(x) # revealed: | +reveal_type(y) # revealed: | -# error: 11 [invalid-base] "Invalid class base with type `Literal[A, B]` (all bases must be a class, `Any`, `Unknown` or `Todo`)" -# error: 14 [invalid-base] "Invalid class base with type `Literal[C, D]` (all bases must be a class, `Any`, `Unknown` or `Todo`)" +# error: 11 [invalid-base] "Invalid class base with type ` | ` (all bases must be a class, `Any`, `Unknown` or `Todo`)" +# error: 14 [invalid-base] "Invalid class base with type ` | ` (all bases must be a class, `Any`, `Unknown` or `Todo`)" class Foo(x, y): ... -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] ``` ## `__bases__` lists that cause errors... now with `Union`s @@ -261,14 +262,14 @@ if returns_bool(): else: foo = object -# error: 21 [invalid-base] "Invalid class base with type `Literal[Y, object]` (all bases must be a class, `Any`, `Unknown` or `Todo`)" +# error: 21 [invalid-base] "Invalid class base with type ` | ` (all bases must be a class, `Any`, `Unknown` or `Todo`)" class PossibleError(foo, X): ... -reveal_type(PossibleError.__mro__) # revealed: tuple[Literal[PossibleError], Unknown, Literal[object]] +reveal_type(PossibleError.__mro__) # revealed: tuple[, Unknown, ] class A(X, Y): ... -reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[X], Literal[Y], Literal[O], Literal[object]] +reveal_type(A.__mro__) # revealed: tuple[, , , , ] if returns_bool(): class B(X, Y): ... @@ -276,13 +277,13 @@ if returns_bool(): else: class B(Y, X): ... -# revealed: tuple[Literal[B], Literal[X], Literal[Y], Literal[O], Literal[object]] | tuple[Literal[B], Literal[Y], Literal[X], Literal[O], Literal[object]] +# revealed: tuple[, , , , ] | tuple[, , , , ] reveal_type(B.__mro__) -# error: 12 [invalid-base] "Invalid class base with type `Literal[B, B]` (all bases must be a class, `Any`, `Unknown` or `Todo`)" +# error: 12 [invalid-base] "Invalid class base with type ` | ` (all bases must be a class, `Any`, `Unknown` or `Todo`)" class Z(A, B): ... -reveal_type(Z.__mro__) # revealed: tuple[Literal[Z], Unknown, Literal[object]] +reveal_type(Z.__mro__) # revealed: tuple[, Unknown, ] ``` ## `__bases__` lists with duplicate bases @@ -290,7 +291,7 @@ reveal_type(Z.__mro__) # revealed: tuple[Literal[Z], Unknown, Literal[object]] ```py class Foo(str, str): ... # error: 16 [duplicate-base] "Duplicate base class `str`" -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] class Spam: ... class Eggs: ... @@ -301,12 +302,12 @@ class Ham( Eggs, # error: [duplicate-base] "Duplicate base class `Eggs`" ): ... -reveal_type(Ham.__mro__) # revealed: tuple[Literal[Ham], Unknown, Literal[object]] +reveal_type(Ham.__mro__) # revealed: tuple[, Unknown, ] class Mushrooms: ... class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] -reveal_type(Omelette.__mro__) # revealed: tuple[Literal[Omelette], Unknown, Literal[object]] +reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] ``` ## `__bases__` lists with duplicate `Unknown` bases @@ -330,7 +331,7 @@ reveal_type(unknown_object_2) # revealed: Unknown # error: [inconsistent-mro] "Cannot create a consistent method resolution order (MRO) for class `Foo` with bases list `[Unknown, Unknown]`" class Foo(unknown_object_1, unknown_object_2): ... -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] ``` ## Unrelated objects inferred as `Any`/`Unknown` do not have special `__mro__` attributes @@ -349,15 +350,15 @@ These are invalid, but we need to be able to handle them gracefully without pani ```pyi class Foo(Foo): ... # error: [cyclic-class-definition] -reveal_type(Foo) # revealed: Literal[Foo] -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo) # revealed: +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] class Bar: ... class Baz: ... class Boz(Bar, Baz, Boz): ... # error: [cyclic-class-definition] -reveal_type(Boz) # revealed: Literal[Boz] -reveal_type(Boz.__mro__) # revealed: tuple[Literal[Boz], Unknown, Literal[object]] +reveal_type(Boz) # revealed: +reveal_type(Boz.__mro__) # revealed: tuple[, Unknown, ] ``` ## Classes with indirect cycles in their MROs @@ -369,9 +370,9 @@ class Foo(Bar): ... # error: [cyclic-class-definition] class Bar(Baz): ... # error: [cyclic-class-definition] class Baz(Foo): ... # error: [cyclic-class-definition] -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] -reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Unknown, Literal[object]] -reveal_type(Baz.__mro__) # revealed: tuple[Literal[Baz], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(Bar.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(Baz.__mro__) # revealed: tuple[, Unknown, ] ``` ## Classes with cycles in their MROs, and multiple inheritance @@ -382,9 +383,9 @@ class Foo(Bar): ... # error: [cyclic-class-definition] class Bar(Baz): ... # error: [cyclic-class-definition] class Baz(Foo, Spam): ... # error: [cyclic-class-definition] -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] -reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Unknown, Literal[object]] -reveal_type(Baz.__mro__) # revealed: tuple[Literal[Baz], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(Bar.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(Baz.__mro__) # revealed: tuple[, Unknown, ] ``` ## Classes with cycles in their MRO, and a sub-graph @@ -400,8 +401,8 @@ class Bar(Foo): ... class Baz(Bar, BarCycle): ... class Spam(Baz): ... -reveal_type(FooCycle.__mro__) # revealed: tuple[Literal[FooCycle], Unknown, Literal[object]] -reveal_type(BarCycle.__mro__) # revealed: tuple[Literal[BarCycle], Unknown, Literal[object]] -reveal_type(Baz.__mro__) # revealed: tuple[Literal[Baz], Unknown, Literal[object]] -reveal_type(Spam.__mro__) # revealed: tuple[Literal[Spam], Unknown, Literal[object]] +reveal_type(FooCycle.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(BarCycle.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(Baz.__mro__) # revealed: tuple[, Unknown, ] +reveal_type(Spam.__mro__) # revealed: tuple[, Unknown, ] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/narrow/conditionals/eq.md b/crates/ty_python_semantic/resources/mdtest/narrow/conditionals/eq.md index bf3184b048..4ba04803c6 100644 --- a/crates/ty_python_semantic/resources/mdtest/narrow/conditionals/eq.md +++ b/crates/ty_python_semantic/resources/mdtest/narrow/conditionals/eq.md @@ -43,9 +43,9 @@ def _(flag: bool): C = A if flag else B if C != A: - reveal_type(C) # revealed: Literal[B] + reveal_type(C) # revealed: else: - reveal_type(C) # revealed: Literal[A] + reveal_type(C) # revealed: ``` ## `x != y` where `y` has multiple single-valued options diff --git a/crates/ty_python_semantic/resources/mdtest/narrow/issubclass.md b/crates/ty_python_semantic/resources/mdtest/narrow/issubclass.md index 3ad543361d..6f8d8e82a9 100644 --- a/crates/ty_python_semantic/resources/mdtest/narrow/issubclass.md +++ b/crates/ty_python_semantic/resources/mdtest/narrow/issubclass.md @@ -14,15 +14,15 @@ def _(flag: bool): reveal_type(t) # revealed: Never if issubclass(t, object): - reveal_type(t) # revealed: Literal[int, str] + reveal_type(t) # revealed: | if issubclass(t, int): - reveal_type(t) # revealed: Literal[int] + reveal_type(t) # revealed: else: - reveal_type(t) # revealed: Literal[str] + reveal_type(t) # revealed: if issubclass(t, str): - reveal_type(t) # revealed: Literal[str] + reveal_type(t) # revealed: if issubclass(t, int): reveal_type(t) # revealed: Never ``` @@ -34,16 +34,16 @@ def _(flag1: bool, flag2: bool): t = int if flag1 else str if flag2 else bytes if issubclass(t, int): - reveal_type(t) # revealed: Literal[int] + reveal_type(t) # revealed: else: - reveal_type(t) # revealed: Literal[str, bytes] + reveal_type(t) # revealed: | if issubclass(t, int): - reveal_type(t) # revealed: Literal[int] + reveal_type(t) # revealed: elif issubclass(t, str): - reveal_type(t) # revealed: Literal[str] + reveal_type(t) # revealed: else: - reveal_type(t) # revealed: Literal[bytes] + reveal_type(t) # revealed: ``` ### Multiple derived classes @@ -58,24 +58,24 @@ def _(flag1: bool, flag2: bool, flag3: bool): t1 = Derived1 if flag1 else Derived2 if issubclass(t1, Base): - reveal_type(t1) # revealed: Literal[Derived1, Derived2] + reveal_type(t1) # revealed: | if issubclass(t1, Derived1): - reveal_type(t1) # revealed: Literal[Derived1] + reveal_type(t1) # revealed: else: - reveal_type(t1) # revealed: Literal[Derived2] + reveal_type(t1) # revealed: t2 = Derived1 if flag2 else Base if issubclass(t2, Base): - reveal_type(t2) # revealed: Literal[Derived1, Base] + reveal_type(t2) # revealed: | t3 = Derived1 if flag3 else Unrelated if issubclass(t3, Base): - reveal_type(t3) # revealed: Literal[Derived1] + reveal_type(t3) # revealed: else: - reveal_type(t3) # revealed: Literal[Unrelated] + reveal_type(t3) # revealed: ``` ### Narrowing for non-literals @@ -109,10 +109,10 @@ def _(flag: bool): t = int if flag else NoneType if issubclass(t, NoneType): - reveal_type(t) # revealed: Literal[NoneType] + reveal_type(t) # revealed: if issubclass(t, type(None)): - reveal_type(t) # revealed: Literal[NoneType] + reveal_type(t) # revealed: ``` ## `classinfo` contains multiple types @@ -126,9 +126,9 @@ def _(flag1: bool, flag2: bool): t = int if flag1 else str if flag2 else bytes if issubclass(t, (int, (Unrelated, (bytes,)))): - reveal_type(t) # revealed: Literal[int, bytes] + reveal_type(t) # revealed: | else: - reveal_type(t) # revealed: Literal[str] + reveal_type(t) # revealed: ``` ## Special cases @@ -175,7 +175,7 @@ def flag() -> bool: t = int if flag() else str if issubclass(t, int): - reveal_type(t) # revealed: Literal[int, str] + reveal_type(t) # revealed: | ``` ### Do support narrowing if `issubclass` is aliased @@ -188,7 +188,7 @@ def flag() -> bool: t = int if flag() else str if issubclass_alias(t, int): - reveal_type(t) # revealed: Literal[int] + reveal_type(t) # revealed: ``` ### Do support narrowing if `issubclass` is imported @@ -201,7 +201,7 @@ def flag() -> bool: t = int if flag() else str if imported_issubclass(t, int): - reveal_type(t) # revealed: Literal[int] + reveal_type(t) # revealed: ``` ### Do not narrow if second argument is not a proper `classinfo` argument @@ -217,17 +217,17 @@ t = int if flag() else str # TODO: this should cause us to emit a diagnostic during # type checking if issubclass(t, "str"): - reveal_type(t) # revealed: Literal[int, str] + reveal_type(t) # revealed: | # TODO: this should cause us to emit a diagnostic during # type checking if issubclass(t, (bytes, "str")): - reveal_type(t) # revealed: Literal[int, str] + reveal_type(t) # revealed: | # TODO: this should cause us to emit a diagnostic during # type checking if issubclass(t, Any): - reveal_type(t) # revealed: Literal[int, str] + reveal_type(t) # revealed: | ``` ### Do not narrow if there are keyword arguments @@ -240,7 +240,7 @@ t = int if flag() else str # error: [unknown-argument] if issubclass(t, int, foo="bar"): - reveal_type(t) # revealed: Literal[int, str] + reveal_type(t) # revealed: | ``` ### `type[]` types are narrowed as well as class-literal types diff --git a/crates/ty_python_semantic/resources/mdtest/narrow/truthiness.md b/crates/ty_python_semantic/resources/mdtest/narrow/truthiness.md index d6a8684b38..b797ee4a16 100644 --- a/crates/ty_python_semantic/resources/mdtest/narrow/truthiness.md +++ b/crates/ty_python_semantic/resources/mdtest/narrow/truthiness.md @@ -108,12 +108,12 @@ def flag() -> bool: return True x = int if flag() else str -reveal_type(x) # revealed: Literal[int, str] +reveal_type(x) # revealed: | if x: - reveal_type(x) # revealed: (Literal[int] & ~AlwaysFalsy) | (Literal[str] & ~AlwaysFalsy) + reveal_type(x) # revealed: ( & ~AlwaysFalsy) | ( & ~AlwaysFalsy) else: - reveal_type(x) # revealed: (Literal[int] & ~AlwaysTruthy) | (Literal[str] & ~AlwaysTruthy) + reveal_type(x) # revealed: ( & ~AlwaysTruthy) | ( & ~AlwaysTruthy) ``` ## Determined Truthiness @@ -276,12 +276,12 @@ def _( reveal_type(d) # revealed: type[DeferredClass] & ~AlwaysFalsy tf = TruthyClass if flag else FalsyClass - reveal_type(tf) # revealed: Literal[TruthyClass, FalsyClass] + reveal_type(tf) # revealed: | if tf: - reveal_type(tf) # revealed: Literal[TruthyClass] + reveal_type(tf) # revealed: else: - reveal_type(tf) # revealed: Literal[FalsyClass] + reveal_type(tf) # revealed: ``` ## Narrowing in chained boolean expressions diff --git a/crates/ty_python_semantic/resources/mdtest/narrow/type.md b/crates/ty_python_semantic/resources/mdtest/narrow/type.md index 07cabd76d5..c5d8bfbe1f 100644 --- a/crates/ty_python_semantic/resources/mdtest/narrow/type.md +++ b/crates/ty_python_semantic/resources/mdtest/narrow/type.md @@ -150,7 +150,7 @@ def _(x: Base): ```py def _(x: object): if (y := type(x)) is bool: - reveal_type(y) # revealed: Literal[bool] + reveal_type(y) # revealed: if (type(y := x)) is bool: reveal_type(y) # revealed: bool ``` diff --git a/crates/ty_python_semantic/resources/mdtest/protocols.md b/crates/ty_python_semantic/resources/mdtest/protocols.md index a2f11fa579..b1d3860334 100644 --- a/crates/ty_python_semantic/resources/mdtest/protocols.md +++ b/crates/ty_python_semantic/resources/mdtest/protocols.md @@ -28,7 +28,7 @@ from typing import Protocol class MyProtocol(Protocol): ... -reveal_type(MyProtocol.__mro__) # revealed: tuple[Literal[MyProtocol], typing.Protocol, typing.Generic, Literal[object]] +reveal_type(MyProtocol.__mro__) # revealed: tuple[, typing.Protocol, typing.Generic, ] ``` Just like for any other class base, it is an error for `Protocol` to appear multiple times in a @@ -37,7 +37,7 @@ class's bases: ```py class Foo(Protocol, Protocol): ... # error: [inconsistent-mro] -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]] +reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] ``` Protocols can also be generic, either by including `Generic[]` in the bases list, subscripting @@ -71,7 +71,7 @@ class DuplicateBases(Protocol, Protocol[T]): x: T # TODO: should not have `Protocol` multiple times -# revealed: tuple[Literal[DuplicateBases], typing.Protocol, @Todo(`Protocol[]` subscript), typing.Generic, Literal[object]] +# revealed: tuple[, typing.Protocol, @Todo(`Protocol[]` subscript), typing.Generic, ] reveal_type(DuplicateBases.__mro__) ``` @@ -107,7 +107,7 @@ it is not sufficient for it to have `Protocol` in its MRO. ```py class SubclassOfMyProtocol(MyProtocol): ... -# revealed: tuple[Literal[SubclassOfMyProtocol], Literal[MyProtocol], typing.Protocol, typing.Generic, Literal[object]] +# revealed: tuple[, , typing.Protocol, typing.Generic, ] reveal_type(SubclassOfMyProtocol.__mro__) reveal_type(is_protocol(SubclassOfMyProtocol)) # revealed: Literal[False] @@ -126,7 +126,7 @@ class OtherProtocol(Protocol): class ComplexInheritance(SubProtocol, OtherProtocol, Protocol): ... -# revealed: tuple[Literal[ComplexInheritance], Literal[SubProtocol], Literal[MyProtocol], Literal[OtherProtocol], typing.Protocol, typing.Generic, Literal[object]] +# revealed: tuple[, , , , typing.Protocol, typing.Generic, ] reveal_type(ComplexInheritance.__mro__) reveal_type(is_protocol(ComplexInheritance)) # revealed: Literal[True] @@ -139,13 +139,13 @@ or `TypeError` is raised at runtime when the class is created. # error: [invalid-protocol] "Protocol class `Invalid` cannot inherit from non-protocol class `NotAProtocol`" class Invalid(NotAProtocol, Protocol): ... -# revealed: tuple[Literal[Invalid], Literal[NotAProtocol], typing.Protocol, typing.Generic, Literal[object]] +# revealed: tuple[, , typing.Protocol, typing.Generic, ] reveal_type(Invalid.__mro__) # error: [invalid-protocol] "Protocol class `AlsoInvalid` cannot inherit from non-protocol class `NotAProtocol`" class AlsoInvalid(MyProtocol, OtherProtocol, NotAProtocol, Protocol): ... -# revealed: tuple[Literal[AlsoInvalid], Literal[MyProtocol], Literal[OtherProtocol], Literal[NotAProtocol], typing.Protocol, typing.Generic, Literal[object]] +# revealed: tuple[, , , , typing.Protocol, typing.Generic, ] reveal_type(AlsoInvalid.__mro__) ``` @@ -163,7 +163,7 @@ T = TypeVar("T") # type checkers. class Fine(Protocol, object): ... -reveal_type(Fine.__mro__) # revealed: tuple[Literal[Fine], typing.Protocol, typing.Generic, Literal[object]] +reveal_type(Fine.__mro__) # revealed: tuple[, typing.Protocol, typing.Generic, ] class StillFine(Protocol, Generic[T], object): ... class EvenThis[T](Protocol, object): ... @@ -177,7 +177,7 @@ And multiple inheritance from a mix of protocol and non-protocol classes is fine ```py class FineAndDandy(MyProtocol, OtherProtocol, NotAProtocol): ... -# revealed: tuple[Literal[FineAndDandy], Literal[MyProtocol], Literal[OtherProtocol], typing.Protocol, typing.Generic, Literal[NotAProtocol], Literal[object]] +# revealed: tuple[, , , typing.Protocol, typing.Generic, , ] reveal_type(FineAndDandy.__mro__) ``` diff --git a/crates/ty_python_semantic/resources/mdtest/scopes/moduletype_attrs.md b/crates/ty_python_semantic/resources/mdtest/scopes/moduletype_attrs.md index f4fde3a2bb..4448d70428 100644 --- a/crates/ty_python_semantic/resources/mdtest/scopes/moduletype_attrs.md +++ b/crates/ty_python_semantic/resources/mdtest/scopes/moduletype_attrs.md @@ -56,7 +56,7 @@ reveal_type(typing.__init__) # revealed: bound method ModuleType.__init__(name: # These come from `builtins.object`, not `types.ModuleType`: reveal_type(typing.__eq__) # revealed: bound method ModuleType.__eq__(value: object, /) -> bool -reveal_type(typing.__class__) # revealed: Literal[ModuleType] +reveal_type(typing.__class__) # revealed: reveal_type(typing.__dict__) # revealed: dict[str, Any] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/scopes/unbound.md b/crates/ty_python_semantic/resources/mdtest/scopes/unbound.md index 6e4d57195a..4a15c071e8 100644 --- a/crates/ty_python_semantic/resources/mdtest/scopes/unbound.md +++ b/crates/ty_python_semantic/resources/mdtest/scopes/unbound.md @@ -16,7 +16,7 @@ class C: if flag: x = 2 -# error: [possibly-unbound-attribute] "Attribute `x` on type `Literal[C]` is possibly unbound" +# error: [possibly-unbound-attribute] "Attribute `x` on type `` is possibly unbound" reveal_type(C.x) # revealed: Unknown | Literal[2] reveal_type(C.y) # revealed: Unknown | Literal[1] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Possibly-unbound_attributes.snap b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Possibly-unbound_attributes.snap index a81beec91a..b89dec2de7 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Possibly-unbound_attributes.snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Possibly-unbound_attributes.snap @@ -26,7 +26,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/attribute_as # Diagnostics ``` -warning: lint:possibly-unbound-attribute: Attribute `attr` on type `Literal[C]` is possibly unbound +warning: lint:possibly-unbound-attribute: Attribute `attr` on type `` is possibly unbound --> src/mdtest_snippet.py:6:5 | 4 | attr: int = 0 diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Pure_instance_attributes.snap b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Pure_instance_attributes.snap index 695489b17a..f298a50634 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Pure_instance_attributes.snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Pure_instance_attributes.snap @@ -41,7 +41,7 @@ info: `lint:invalid-assignment` is enabled by default ``` ``` -error: lint:invalid-attribute-access: Cannot assign to instance attribute `attr` from the class object `Literal[C]` +error: lint:invalid-attribute-access: Cannot assign to instance attribute `attr` from the class object `` --> src/mdtest_snippet.py:9:1 | 7 | instance.attr = "wrong" # error: [invalid-assignment] diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Setting_attributes_on_union_types.snap b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Setting_attributes_on_union_types.snap index 1d4d0aa4f3..12ce7acff5 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Setting_attributes_on_union_types.snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Setting_attributes_on_union_types.snap @@ -37,7 +37,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/attribute_as # Diagnostics ``` -error: lint:invalid-assignment: Object of type `Literal[1]` is not assignable to attribute `attr` on type `Literal[C1, C1]` +error: lint:invalid-assignment: Object of type `Literal[1]` is not assignable to attribute `attr` on type ` | ` --> src/mdtest_snippet.py:11:5 | 10 | # TODO: The error message here could be improved to explain why the assignment fails. diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Unknown_attributes.snap b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Unknown_attributes.snap index 99f7fff99f..2d718809bc 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Unknown_attributes.snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/attribute_assignment.md_-_Attribute_assignment_-_Unknown_attributes.snap @@ -23,7 +23,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/attribute_as # Diagnostics ``` -error: lint:unresolved-attribute: Unresolved attribute `non_existent` on type `Literal[C]`. +error: lint:unresolved-attribute: Unresolved attribute `non_existent` on type ``. --> src/mdtest_snippet.py:3:1 | 1 | class C: ... diff --git a/crates/ty_python_semantic/resources/mdtest/stubs/class.md b/crates/ty_python_semantic/resources/mdtest/stubs/class.md index 715571e021..64fe0bf48d 100644 --- a/crates/ty_python_semantic/resources/mdtest/stubs/class.md +++ b/crates/ty_python_semantic/resources/mdtest/stubs/class.md @@ -15,8 +15,8 @@ class Foo[T]: ... class Bar(Foo[Bar]): ... -reveal_type(Bar) # revealed: Literal[Bar] -reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Literal[Foo[Bar]], Literal[object]] +reveal_type(Bar) # revealed: +reveal_type(Bar.__mro__) # revealed: tuple[, , ] ``` ## Access to attributes declared in stubs diff --git a/crates/ty_python_semantic/resources/mdtest/subscript/class.md b/crates/ty_python_semantic/resources/mdtest/subscript/class.md index cbe37b302b..ca6f364cdd 100644 --- a/crates/ty_python_semantic/resources/mdtest/subscript/class.md +++ b/crates/ty_python_semantic/resources/mdtest/subscript/class.md @@ -5,7 +5,8 @@ ```py class NotSubscriptable: ... -a = NotSubscriptable[0] # error: "Cannot subscript object of type `Literal[NotSubscriptable]` with no `__class_getitem__` method" +# error: "Cannot subscript object of type `` with no `__class_getitem__` method" +a = NotSubscriptable[0] ``` ## Class getitem @@ -47,7 +48,7 @@ def _(flag: bool): x = A if flag else B - reveal_type(x) # revealed: Literal[A, B] + reveal_type(x) # revealed: | reveal_type(x[0]) # revealed: str | int ``` @@ -62,7 +63,7 @@ def _(flag: bool): else: class Spam: ... - # error: [call-possibly-unbound-method] "Method `__class_getitem__` of type `Literal[Spam, Spam]` is possibly unbound" + # error: [call-possibly-unbound-method] "Method `__class_getitem__` of type ` | ` is possibly unbound" # revealed: str reveal_type(Spam[42]) ``` @@ -79,7 +80,7 @@ def _(flag: bool): else: Eggs = 1 - a = Eggs[42] # error: "Cannot subscript object of type `Literal[Eggs] | Literal[1]` with no `__getitem__` method" + a = Eggs[42] # error: "Cannot subscript object of type ` | Literal[1]` with no `__getitem__` method" # TODO: should _probably_ emit `str | Unknown` reveal_type(a) # revealed: Unknown diff --git a/crates/ty_python_semantic/resources/mdtest/subscript/tuple.md b/crates/ty_python_semantic/resources/mdtest/subscript/tuple.md index f07efe0e2f..2e733a8921 100644 --- a/crates/ty_python_semantic/resources/mdtest/subscript/tuple.md +++ b/crates/ty_python_semantic/resources/mdtest/subscript/tuple.md @@ -85,7 +85,7 @@ class A(tuple[int, str]): ... # Runtime value: `(A, tuple, object)` # TODO: Generics -reveal_type(A.__mro__) # revealed: tuple[Literal[A], @Todo(GenericAlias instance), Literal[object]] +reveal_type(A.__mro__) # revealed: tuple[, @Todo(GenericAlias instance), ] ``` ## `typing.Tuple` @@ -116,6 +116,6 @@ from typing import Tuple class C(Tuple): ... # TODO: generic protocols -# revealed: tuple[Literal[C], Literal[tuple], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), typing.Generic, Literal[object]] +# revealed: tuple[, , , , , , , @Todo(`Protocol[]` subscript), typing.Generic, ] reveal_type(C.__mro__) ``` diff --git a/crates/ty_python_semantic/resources/mdtest/type_api.md b/crates/ty_python_semantic/resources/mdtest/type_api.md index 5e1621ccb2..639bd4f83a 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_api.md +++ b/crates/ty_python_semantic/resources/mdtest/type_api.md @@ -105,7 +105,7 @@ def explicit_unknown(x: Unknown, y: tuple[str, Unknown], z: Unknown = 1) -> None ```py class C(Unknown): ... -# revealed: tuple[Literal[C], Unknown, Literal[object]] +# revealed: tuple[, Unknown, ] reveal_type(C.__mro__) # error: "Special form `ty_extensions.Unknown` expected no type parameter" diff --git a/crates/ty_python_semantic/resources/mdtest/type_of/basic.md b/crates/ty_python_semantic/resources/mdtest/type_of/basic.md index fc7f9f450b..e733df9b94 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_of/basic.md +++ b/crates/ty_python_semantic/resources/mdtest/type_of/basic.md @@ -147,8 +147,8 @@ _: type[A, B] ```py class Foo(type[int]): ... -# TODO: should be `tuple[Literal[Foo], Literal[type], Literal[object]] -reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], @Todo(GenericAlias instance), Literal[object]] +# TODO: should be `tuple[, , ] +reveal_type(Foo.__mro__) # revealed: tuple[, @Todo(GenericAlias instance), ] ``` ## `@final` classes @@ -169,6 +169,6 @@ from typing import final class Foo: ... def _(x: type[Foo], y: type[EllipsisType]): - reveal_type(x) # revealed: Literal[Foo] - reveal_type(y) # revealed: Literal[EllipsisType] + reveal_type(x) # revealed: + reveal_type(y) # revealed: ``` diff --git a/crates/ty_python_semantic/resources/mdtest/type_of/typing_dot_Type.md b/crates/ty_python_semantic/resources/mdtest/type_of/typing_dot_Type.md index ff31bb1516..bda56c9384 100644 --- a/crates/ty_python_semantic/resources/mdtest/type_of/typing_dot_Type.md +++ b/crates/ty_python_semantic/resources/mdtest/type_of/typing_dot_Type.md @@ -28,5 +28,5 @@ class C(Type): ... # Runtime value: `(C, type, typing.Generic, object)` # TODO: Add `Generic` to the MRO -reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[type], Literal[object]] +reveal_type(C.__mro__) # revealed: tuple[, , ] ``` diff --git a/crates/ty_python_semantic/resources/mdtest/unary/custom.md b/crates/ty_python_semantic/resources/mdtest/unary/custom.md index 1ad79dd3bc..1544e42890 100644 --- a/crates/ty_python_semantic/resources/mdtest/unary/custom.md +++ b/crates/ty_python_semantic/resources/mdtest/unary/custom.md @@ -52,25 +52,25 @@ class Yes: class Sub(Yes): ... class No: ... -# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[Yes]`" +# error: [unsupported-operator] "Unary operator `+` is unsupported for type ``" reveal_type(+Yes) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[Yes]`" +# error: [unsupported-operator] "Unary operator `-` is unsupported for type ``" reveal_type(-Yes) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[Yes]`" +# error: [unsupported-operator] "Unary operator `~` is unsupported for type ``" reveal_type(~Yes) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[Sub]`" +# error: [unsupported-operator] "Unary operator `+` is unsupported for type ``" reveal_type(+Sub) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[Sub]`" +# error: [unsupported-operator] "Unary operator `-` is unsupported for type ``" reveal_type(-Sub) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[Sub]`" +# error: [unsupported-operator] "Unary operator `~` is unsupported for type ``" reveal_type(~Sub) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[No]`" +# error: [unsupported-operator] "Unary operator `+` is unsupported for type ``" reveal_type(+No) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[No]`" +# error: [unsupported-operator] "Unary operator `-` is unsupported for type ``" reveal_type(-No) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[No]`" +# error: [unsupported-operator] "Unary operator `~` is unsupported for type ``" reveal_type(~No) # revealed: Unknown ``` @@ -160,10 +160,10 @@ reveal_type(+Sub) # revealed: bool reveal_type(-Sub) # revealed: str reveal_type(~Sub) # revealed: int -# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[No]`" +# error: [unsupported-operator] "Unary operator `+` is unsupported for type ``" reveal_type(+No) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[No]`" +# error: [unsupported-operator] "Unary operator `-` is unsupported for type ``" reveal_type(-No) # revealed: Unknown -# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[No]`" +# error: [unsupported-operator] "Unary operator `~` is unsupported for type ``" reveal_type(~No) # revealed: Unknown ``` diff --git a/crates/ty_python_semantic/src/types/display.rs b/crates/ty_python_semantic/src/types/display.rs index b4f9a103cb..e2ce40d3c8 100644 --- a/crates/ty_python_semantic/src/types/display.rs +++ b/crates/ty_python_semantic/src/types/display.rs @@ -42,9 +42,7 @@ impl Display for DisplayType<'_> { Type::IntLiteral(_) | Type::BooleanLiteral(_) | Type::StringLiteral(_) - | Type::BytesLiteral(_) - | Type::ClassLiteral(_) - | Type::GenericAlias(_) => { + | Type::BytesLiteral(_) => { write!(f, "Literal[{representation}]") } _ => representation.fmt(f), @@ -102,9 +100,10 @@ impl Display for DisplayRepresentation<'_> { Type::ModuleLiteral(module) => { write!(f, "", module.module(self.db).name()) } - // TODO functions and classes should display using a fully qualified name - Type::ClassLiteral(class) => f.write_str(class.name(self.db)), - Type::GenericAlias(generic) => generic.display(self.db).fmt(f), + Type::ClassLiteral(class) => { + write!(f, "", class.name(self.db)) + } + Type::GenericAlias(generic) => write!(f, "", generic.display(self.db)), Type::SubclassOf(subclass_of_ty) => match subclass_of_ty.subclass_of() { // Only show the bare class name here; ClassBase::display would render this as // type[] instead of type[Foo]. @@ -605,7 +604,6 @@ impl Display for DisplayLiteralGroup<'_> { /// For example, `Literal[1] | Literal[2] | Literal["s"]` is displayed as `"Literal[1, 2, "s"]"`. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] enum CondensedDisplayTypeKind { - Class, LiteralExpression, } @@ -614,7 +612,6 @@ impl TryFrom> for CondensedDisplayTypeKind { fn try_from(value: Type<'_>) -> Result { match value { - Type::ClassLiteral(_) => Ok(Self::Class), Type::IntLiteral(_) | Type::StringLiteral(_) | Type::BytesLiteral(_)