From 7064c38e53714edd76a9c2f80fed67b38a0b7c54 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 12 Oct 2025 19:39:32 +0100 Subject: [PATCH] [ty] Filter out `revealed-type` and `undefined-reveal` diagnostics from mdtest snapshots (#20820) --- .../resources/mdtest/call/overloads.md | 2 - .../mdtest/dataclasses/dataclasses.md | 1 - .../mdtest/exception/invalid_syntax.md | 2 - .../mdtest/generics/legacy/functions.md | 2 - .../mdtest/ide_support/all_members.md | 6 +- .../resources/mdtest/loops/async_for.md | 14 - .../resources/mdtest/loops/for.md | 30 -- .../resources/mdtest/mro.md | 4 - .../resources/mdtest/narrow/type_guards.md | 2 +- .../resources/mdtest/protocols.md | 10 +- ...asic_functionality_(6b9531a70334bfad).snap | 43 -- ...`__aiter__`_metho…_(4fbd80e21774cc23).snap | 34 +- ...`__anext__`_metho…_(a0b186714127abee).snap | 42 +- ...sibly_missing_`__…_(33924dbae5117216).snap | 48 +- ...sibly_missing_`__…_(e2600ca4708d9e54).snap | 48 +- ...chronously_iterab…_(80fa705b1c61d982).snap | 46 +- ...ng_signature_for_…_(b614724363eec343).snap | 48 +- ...ong_signature_for_…_(e1f3e9275d0a367).snap | 48 +- ...taclasses.KW_ONLY…_(dd1b8f2f71487f16).snap | 189 +++----- ..._`__getitem__`_me…_(3ffe352bb3a76715).snap | 46 +- ...`__iter__`_method…_(36425dbcbd793d2b).snap | 34 +- ...sibly-not-callabl…_(49a21e4b7fe6e97b).snap | 102 ++-- ...sibly_invalid_`__…_(6388761c90a0555c).snap | 102 ++-- ...sibly_invalid_`__…_(6805a6032e504b63).snap | 94 ++-- ...sibly_invalid_`__…_(c626bde8651b643a).snap | 110 ++--- ...sibly_missing_`__…_(77269542b8e81774).snap | 116 ++--- ...sibly_missing_`__…_(9f781babda99d74b).snap | 56 +-- ...sibly_missing_`__…_(d8a02a0fcbb390a3).snap | 54 +-- ...on_type_as_iterab…_(6177bb6d13a22241).snap | 58 +-- ...on_type_as_iterab…_(ba36fbef63a14969).snap | 48 +- ...h_non-callable_it…_(a1cdf01ad69ac37c).snap | 58 +-- ...iter__`_does_not_…_(92e3fdd69edad63d).snap | 36 +- ...iter__`_method_wi…_(1136c0e783d61ba4).snap | 44 +- ...iter__`_returns_a…_(707bd02a22c4acc8).snap | 88 ++-- ...nferring_a_bound_ty…_(d50204b9d91b7bd1).snap | 80 +-- ...nferring_a_constrai…_(48ab83f977c109b4).snap | 96 +--- ...nferring_a_bound_ty…_(5935d14c26afe407).snap | 39 -- ...nferring_a_constrai…_(d2c475fccc70a8e2).snap | 53 -- ...__bases__`_includes…_(d2532518c44112c8).snap | 70 +-- ...__bases__`_lists_wi…_(ea7ebc83ec359b54).snap | 456 ++++++++---------- ...timization___Limit_…_(cd61048adbc17331).snap | 45 -- ...ls_to_protocol_cl…_(288988036f34ddcf).snap | 72 +-- ...rrowing_of_protoco…_(98257e7c2300373).snap | 141 +----- ...tocol_members_in_…_(21be5d9bdab1c844).snap | 16 +- crates/ty_python_semantic/src/types.rs | 2 +- .../src/types/diagnostic.rs | 2 +- crates/ty_test/src/lib.rs | 12 +- 47 files changed, 849 insertions(+), 1900 deletions(-) delete mode 100644 crates/ty_python_semantic/resources/mdtest/snapshots/all_members.md_-_List_all_members_-_Basic_functionality_(6b9531a70334bfad).snap diff --git a/crates/ty_python_semantic/resources/mdtest/call/overloads.md b/crates/ty_python_semantic/resources/mdtest/call/overloads.md index 13430cf3cf..726d74a630 100644 --- a/crates/ty_python_semantic/resources/mdtest/call/overloads.md +++ b/crates/ty_python_semantic/resources/mdtest/call/overloads.md @@ -99,8 +99,6 @@ If the arity check only matches a single overload, it should be evaluated as a r call should be reported directly and not as a `no-matching-overload` error. ```py -from typing_extensions import reveal_type - from overloaded import f reveal_type(f()) # revealed: None diff --git a/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md b/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md index 398939bf9f..bb2092aa5c 100644 --- a/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md +++ b/crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.md @@ -1010,7 +1010,6 @@ python-version = "3.10" ```py from dataclasses import dataclass, field, KW_ONLY -from typing_extensions import reveal_type @dataclass class C: diff --git a/crates/ty_python_semantic/resources/mdtest/exception/invalid_syntax.md b/crates/ty_python_semantic/resources/mdtest/exception/invalid_syntax.md index 19bb7c4377..f9fea8b7cb 100644 --- a/crates/ty_python_semantic/resources/mdtest/exception/invalid_syntax.md +++ b/crates/ty_python_semantic/resources/mdtest/exception/invalid_syntax.md @@ -3,8 +3,6 @@ ## Invalid syntax ```py -from typing_extensions import reveal_type - try: print except as e: # error: [invalid-syntax] diff --git a/crates/ty_python_semantic/resources/mdtest/generics/legacy/functions.md b/crates/ty_python_semantic/resources/mdtest/generics/legacy/functions.md index 7da1d19286..9745fdca21 100644 --- a/crates/ty_python_semantic/resources/mdtest/generics/legacy/functions.md +++ b/crates/ty_python_semantic/resources/mdtest/generics/legacy/functions.md @@ -181,7 +181,6 @@ reveal_type(takes_homogeneous_tuple((42, 43))) # revealed: Literal[42, 43] ```py from typing import TypeVar -from typing_extensions import reveal_type T = TypeVar("T", bound=int) @@ -200,7 +199,6 @@ reveal_type(f("string")) # revealed: Unknown ```py from typing import TypeVar -from typing_extensions import reveal_type T = TypeVar("T", int, None) diff --git a/crates/ty_python_semantic/resources/mdtest/ide_support/all_members.md b/crates/ty_python_semantic/resources/mdtest/ide_support/all_members.md index a8be450f36..03ea95b4a2 100644 --- a/crates/ty_python_semantic/resources/mdtest/ide_support/all_members.md +++ b/crates/ty_python_semantic/resources/mdtest/ide_support/all_members.md @@ -5,8 +5,6 @@ all members available on a given type. This routine is used for autocomplete sug ## Basic functionality - - The `ty_extensions.all_members` and `ty_extensions.has_member` functions expose a Python-level API that can be used to query which attributes `ide_support::all_members` understands as being available on a given object. For example, all member functions of `str` are available on `"a"`. The Python API @@ -45,10 +43,10 @@ The full list of all members is relatively long, but `reveal_type` can be used i `all_members` to see them all: ```py -from typing_extensions import reveal_type from ty_extensions import all_members -reveal_type(all_members("a")) # error: [revealed-type] +# revealed: tuple[Literal["__add__"], Literal["__annotations__"], Literal["__class__"], Literal["__contains__"], Literal["__delattr__"], Literal["__dict__"], Literal["__dir__"], Literal["__doc__"], Literal["__eq__"], Literal["__format__"], Literal["__ge__"], Literal["__getattribute__"], Literal["__getitem__"], Literal["__getnewargs__"], Literal["__gt__"], Literal["__hash__"], Literal["__init__"], Literal["__init_subclass__"], Literal["__iter__"], Literal["__le__"], Literal["__len__"], Literal["__lt__"], Literal["__mod__"], Literal["__module__"], Literal["__mul__"], Literal["__ne__"], Literal["__new__"], Literal["__reduce__"], Literal["__reduce_ex__"], Literal["__repr__"], Literal["__reversed__"], Literal["__rmul__"], Literal["__setattr__"], Literal["__sizeof__"], Literal["__str__"], Literal["__subclasshook__"], Literal["capitalize"], Literal["casefold"], Literal["center"], Literal["count"], Literal["encode"], Literal["endswith"], Literal["expandtabs"], Literal["find"], Literal["format"], Literal["format_map"], Literal["index"], Literal["isalnum"], Literal["isalpha"], Literal["isascii"], Literal["isdecimal"], Literal["isdigit"], Literal["isidentifier"], Literal["islower"], Literal["isnumeric"], Literal["isprintable"], Literal["isspace"], Literal["istitle"], Literal["isupper"], Literal["join"], Literal["ljust"], Literal["lower"], Literal["lstrip"], Literal["maketrans"], Literal["partition"], Literal["removeprefix"], Literal["removesuffix"], Literal["replace"], Literal["rfind"], Literal["rindex"], Literal["rjust"], Literal["rpartition"], Literal["rsplit"], Literal["rstrip"], Literal["split"], Literal["splitlines"], Literal["startswith"], Literal["strip"], Literal["swapcase"], Literal["title"], Literal["translate"], Literal["upper"], Literal["zfill"]] +reveal_type(all_members("a")) ``` ## Kinds of types diff --git a/crates/ty_python_semantic/resources/mdtest/loops/async_for.md b/crates/ty_python_semantic/resources/mdtest/loops/async_for.md index 1271e2b41f..29fba1ce77 100644 --- a/crates/ty_python_semantic/resources/mdtest/loops/async_for.md +++ b/crates/ty_python_semantic/resources/mdtest/loops/async_for.md @@ -42,8 +42,6 @@ async def foo(): ### No `__aiter__` method ```py -from typing_extensions import reveal_type - class NotAsyncIterable: ... async def foo(): @@ -55,8 +53,6 @@ async def foo(): ### Synchronously iterable, but not asynchronously iterable ```py -from typing_extensions import reveal_type - async def foo(): class Iterator: def __next__(self) -> int: @@ -74,8 +70,6 @@ async def foo(): ### No `__anext__` method ```py -from typing_extensions import reveal_type - class NoAnext: ... class AsyncIterable: @@ -91,8 +85,6 @@ async def foo(): ### Possibly missing `__anext__` method ```py -from typing_extensions import reveal_type - async def foo(flag: bool): class PossiblyUnboundAnext: if flag: @@ -111,8 +103,6 @@ async def foo(flag: bool): ### Possibly missing `__aiter__` method ```py -from typing_extensions import reveal_type - async def foo(flag: bool): class AsyncIterable: async def __anext__(self) -> int: @@ -131,8 +121,6 @@ async def foo(flag: bool): ### Wrong signature for `__aiter__` ```py -from typing_extensions import reveal_type - class AsyncIterator: async def __anext__(self) -> int: return 42 @@ -150,8 +138,6 @@ async def foo(): ### Wrong signature for `__anext__` ```py -from typing_extensions import reveal_type - class AsyncIterator: async def __anext__(self, arg: int) -> int: # wrong return 42 diff --git a/crates/ty_python_semantic/resources/mdtest/loops/for.md b/crates/ty_python_semantic/resources/mdtest/loops/for.md index f6300f5975..4066c8e2e3 100644 --- a/crates/ty_python_semantic/resources/mdtest/loops/for.md +++ b/crates/ty_python_semantic/resources/mdtest/loops/for.md @@ -108,8 +108,6 @@ reveal_type(x) ```py -from typing_extensions import reveal_type - def _(flag: bool): class NotIterable: if flag: @@ -271,8 +269,6 @@ def g( ```py -from typing_extensions import reveal_type - class TestIter: def __next__(self) -> int: return 42 @@ -292,8 +288,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - class TestIter: def __next__(self) -> int: return 42 @@ -370,8 +364,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - class Iterator: def __next__(self) -> int: return 42 @@ -390,8 +382,6 @@ for x in Iterable(): ```py -from typing_extensions import reveal_type - class Bad: def __iter__(self) -> int: return 42 @@ -424,8 +414,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - class Iterator1: def __next__(self, extra_arg) -> int: return 42 @@ -455,8 +443,6 @@ for y in Iterable2(): ```py -from typing_extensions import reveal_type - def _(flag: bool): class Iterator: def __next__(self) -> int: @@ -509,8 +495,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - class Iterator: def __next__(self) -> int: return 42 @@ -534,8 +518,6 @@ def _(flag1: bool, flag2: bool): ```py -from typing_extensions import reveal_type - class Bad: __getitem__: None = None @@ -549,8 +531,6 @@ for x in Bad(): ```py -from typing_extensions import reveal_type - def _(flag: bool): class CustomCallable: if flag: @@ -585,8 +565,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - class Iterable: # invalid because it will implicitly be passed an `int` # by the interpreter @@ -626,8 +604,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - class Iterator: def __next__(self) -> int: return 42 @@ -663,8 +639,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - def _(flag: bool): class Iterator1: if flag: @@ -704,8 +678,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - def _(flag: bool): class Iterable1: if flag: @@ -737,8 +709,6 @@ def _(flag: bool): ```py -from typing_extensions import reveal_type - class Iterator: def __next__(self) -> bytes: return b"foo" diff --git a/crates/ty_python_semantic/resources/mdtest/mro.md b/crates/ty_python_semantic/resources/mdtest/mro.md index a4a9368aa0..e27bc761dd 100644 --- a/crates/ty_python_semantic/resources/mdtest/mro.md +++ b/crates/ty_python_semantic/resources/mdtest/mro.md @@ -241,8 +241,6 @@ find a union type in a class's bases, we infer the class's `__mro__` as being `[, Unknown, object]`, the same as for MROs that cause errors at runtime. ```py -from typing_extensions import reveal_type - def returns_bool() -> bool: return True @@ -391,8 +389,6 @@ class BadSub2(Bad2()): ... # error: [invalid-base] ```py -from typing_extensions import reveal_type - class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] diff --git a/crates/ty_python_semantic/resources/mdtest/narrow/type_guards.md b/crates/ty_python_semantic/resources/mdtest/narrow/type_guards.md index bd5fc0705d..0d94326c89 100644 --- a/crates/ty_python_semantic/resources/mdtest/narrow/type_guards.md +++ b/crates/ty_python_semantic/resources/mdtest/narrow/type_guards.md @@ -281,7 +281,7 @@ def _(x: Foo | Bar, flag: bool) -> None: The `TypeIs` type remains effective across generic boundaries: ```py -from typing_extensions import TypeVar, reveal_type +from typing_extensions import TypeVar T = TypeVar("T") diff --git a/crates/ty_python_semantic/resources/mdtest/protocols.md b/crates/ty_python_semantic/resources/mdtest/protocols.md index 4efb4ebdf0..5a939e4880 100644 --- a/crates/ty_python_semantic/resources/mdtest/protocols.md +++ b/crates/ty_python_semantic/resources/mdtest/protocols.md @@ -347,7 +347,7 @@ python-version = "3.12" ``` ```py -from typing_extensions import Protocol, reveal_type +from typing_extensions import Protocol # error: [call-non-callable] reveal_type(Protocol()) # revealed: Unknown @@ -381,9 +381,7 @@ And as a corollary, `type[MyProtocol]` can also be called: ```py def f(x: type[MyProtocol]): - # TODO: add a `reveal_type` call here once it's no longer a `Todo` type - # (which doesn't work well with snapshots) - x() + reveal_type(x()) # revealed: @Todo(type[T] for protocols) ``` ## Members of a protocol @@ -534,7 +532,7 @@ python-version = "3.9" ```py import sys -from typing_extensions import Protocol, get_protocol_members, reveal_type +from typing_extensions import Protocol, get_protocol_members class Foo(Protocol): if sys.version_info >= (3, 10): @@ -2393,7 +2391,7 @@ By default, a protocol class cannot be used as the second argument to `isinstanc type inside these branches (this matches the behavior of other type checkers): ```py -from typing_extensions import Protocol, reveal_type +from typing_extensions import Protocol class HasX(Protocol): x: int diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/all_members.md_-_List_all_members_-_Basic_functionality_(6b9531a70334bfad).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/all_members.md_-_List_all_members_-_Basic_functionality_(6b9531a70334bfad).snap deleted file mode 100644 index fb31b51fe8..0000000000 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/all_members.md_-_List_all_members_-_Basic_functionality_(6b9531a70334bfad).snap +++ /dev/null @@ -1,43 +0,0 @@ ---- -source: crates/ty_test/src/lib.rs -expression: snapshot ---- ---- -mdtest name: all_members.md - List all members - Basic functionality -mdtest path: crates/ty_python_semantic/resources/mdtest/ide_support/all_members.md ---- - -# Python source files - -## mdtest_snippet.py - -``` - 1 | from ty_extensions import static_assert, has_member - 2 | - 3 | static_assert(has_member("a", "replace")) - 4 | static_assert(has_member("a", "startswith")) - 5 | static_assert(has_member("a", "isupper")) - 6 | static_assert(has_member("a", "__add__")) - 7 | static_assert(has_member("a", "__gt__")) - 8 | static_assert(has_member("a", "__doc__")) - 9 | static_assert(has_member("a", "__repr__")) -10 | static_assert(not has_member("a", "non_existent")) -11 | from typing_extensions import reveal_type -12 | from ty_extensions import all_members -13 | -14 | reveal_type(all_members("a")) # error: [revealed-type] -``` - -# Diagnostics - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:14:13 - | -12 | from ty_extensions import all_members -13 | -14 | reveal_type(all_members("a")) # error: [revealed-type] - | ^^^^^^^^^^^^^^^^ `tuple[Literal["__add__"], Literal["__annotations__"], Literal["__class__"], Literal["__contains__"], Literal["__delattr__"], Literal["__dict__"], Literal["__dir__"], Literal["__doc__"], Literal["__eq__"], Literal["__format__"], Literal["__ge__"], Literal["__getattribute__"], Literal["__getitem__"], Literal["__getnewargs__"], Literal["__gt__"], Literal["__hash__"], Literal["__init__"], Literal["__init_subclass__"], Literal["__iter__"], Literal["__le__"], Literal["__len__"], Literal["__lt__"], Literal["__mod__"], Literal["__module__"], Literal["__mul__"], Literal["__ne__"], Literal["__new__"], Literal["__reduce__"], Literal["__reduce_ex__"], Literal["__repr__"], Literal["__reversed__"], Literal["__rmul__"], Literal["__setattr__"], Literal["__sizeof__"], Literal["__str__"], Literal["__subclasshook__"], Literal["capitalize"], Literal["casefold"], Literal["center"], Literal["count"], Literal["encode"], Literal["endswith"], Literal["expandtabs"], Literal["find"], Literal["format"], Literal["format_map"], Literal["index"], Literal["isalnum"], Literal["isalpha"], Literal["isascii"], Literal["isdecimal"], Literal["isdigit"], Literal["isidentifier"], Literal["islower"], Literal["isnumeric"], Literal["isprintable"], Literal["isspace"], Literal["istitle"], Literal["isupper"], Literal["join"], Literal["ljust"], Literal["lower"], Literal["lstrip"], Literal["maketrans"], Literal["partition"], Literal["removeprefix"], Literal["removesuffix"], Literal["replace"], Literal["rfind"], Literal["rindex"], Literal["rjust"], Literal["rpartition"], Literal["rsplit"], Literal["rstrip"], Literal["split"], Literal["splitlines"], Literal["startswith"], Literal["strip"], Literal["swapcase"], Literal["title"], Literal["translate"], Literal["upper"], Literal["zfill"]]` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__aiter__`_metho…_(4fbd80e21774cc23).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__aiter__`_metho…_(4fbd80e21774cc23).snap index 0953c5286e..e5613631f4 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__aiter__`_metho…_(4fbd80e21774cc23).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__aiter__`_metho…_(4fbd80e21774cc23).snap @@ -12,41 +12,27 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md ## mdtest_snippet.py ``` -1 | from typing_extensions import reveal_type +1 | class NotAsyncIterable: ... 2 | -3 | class NotAsyncIterable: ... -4 | -5 | async def foo(): -6 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable" -7 | async for x in NotAsyncIterable(): -8 | reveal_type(x) # revealed: Unknown +3 | async def foo(): +4 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable" +5 | async for x in NotAsyncIterable(): +6 | reveal_type(x) # revealed: Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `NotAsyncIterable` is not async-iterable - --> src/mdtest_snippet.py:7:20 + --> src/mdtest_snippet.py:5:20 | -5 | async def foo(): -6 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable" -7 | async for x in NotAsyncIterable(): +3 | async def foo(): +4 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable" +5 | async for x in NotAsyncIterable(): | ^^^^^^^^^^^^^^^^^^ -8 | reveal_type(x) # revealed: Unknown +6 | reveal_type(x) # revealed: Unknown | info: It has no `__aiter__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:8:21 - | -6 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable" -7 | async for x in NotAsyncIterable(): -8 | reveal_type(x) # revealed: Unknown - | ^ `Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__anext__`_metho…_(a0b186714127abee).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__anext__`_metho…_(a0b186714127abee).snap index 6994519044..3123e9df2e 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__anext__`_metho…_(a0b186714127abee).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_No_`__anext__`_metho…_(a0b186714127abee).snap @@ -12,45 +12,31 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type + 1 | class NoAnext: ... 2 | - 3 | class NoAnext: ... - 4 | - 5 | class AsyncIterable: - 6 | def __aiter__(self) -> NoAnext: - 7 | return NoAnext() - 8 | - 9 | async def foo(): -10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -11 | async for x in AsyncIterable(): -12 | reveal_type(x) # revealed: Unknown + 3 | class AsyncIterable: + 4 | def __aiter__(self) -> NoAnext: + 5 | return NoAnext() + 6 | + 7 | async def foo(): + 8 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" + 9 | async for x in AsyncIterable(): +10 | reveal_type(x) # revealed: Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `AsyncIterable` is not async-iterable - --> src/mdtest_snippet.py:11:20 + --> src/mdtest_snippet.py:9:20 | - 9 | async def foo(): -10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -11 | async for x in AsyncIterable(): + 7 | async def foo(): + 8 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" + 9 | async for x in AsyncIterable(): | ^^^^^^^^^^^^^^^ -12 | reveal_type(x) # revealed: Unknown +10 | reveal_type(x) # revealed: Unknown | info: Its `__aiter__` method returns an object of type `NoAnext`, which has no `__anext__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:12:21 - | -10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -11 | async for x in AsyncIterable(): -12 | reveal_type(x) # revealed: Unknown - | ^ `Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(33924dbae5117216).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(33924dbae5117216).snap index ddc15768bc..e3197f030d 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(33924dbae5117216).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(33924dbae5117216).snap @@ -12,47 +12,33 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | async def foo(flag: bool): - 4 | class AsyncIterable: - 5 | async def __anext__(self) -> int: - 6 | return 42 - 7 | - 8 | class PossiblyUnboundAiter: - 9 | if flag: -10 | def __aiter__(self) -> AsyncIterable: -11 | return AsyncIterable() -12 | -13 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable" -14 | async for x in PossiblyUnboundAiter(): -15 | reveal_type(x) # revealed: int + 1 | async def foo(flag: bool): + 2 | class AsyncIterable: + 3 | async def __anext__(self) -> int: + 4 | return 42 + 5 | + 6 | class PossiblyUnboundAiter: + 7 | if flag: + 8 | def __aiter__(self) -> AsyncIterable: + 9 | return AsyncIterable() +10 | +11 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable" +12 | async for x in PossiblyUnboundAiter(): +13 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `PossiblyUnboundAiter` may not be async-iterable - --> src/mdtest_snippet.py:14:20 + --> src/mdtest_snippet.py:12:20 | -13 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable" -14 | async for x in PossiblyUnboundAiter(): +11 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable" +12 | async for x in PossiblyUnboundAiter(): | ^^^^^^^^^^^^^^^^^^^^^^ -15 | reveal_type(x) # revealed: int +13 | reveal_type(x) # revealed: int | info: Its `__aiter__` attribute (with type `bound method PossiblyUnboundAiter.__aiter__() -> AsyncIterable`) may not be callable info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:15:21 - | -13 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable" -14 | async for x in PossiblyUnboundAiter(): -15 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(e2600ca4708d9e54).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(e2600ca4708d9e54).snap index f6e3888116..c563eca460 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(e2600ca4708d9e54).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Possibly_missing_`__…_(e2600ca4708d9e54).snap @@ -12,47 +12,33 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | async def foo(flag: bool): - 4 | class PossiblyUnboundAnext: - 5 | if flag: - 6 | async def __anext__(self) -> int: - 7 | return 42 - 8 | - 9 | class AsyncIterable: -10 | def __aiter__(self) -> PossiblyUnboundAnext: -11 | return PossiblyUnboundAnext() -12 | -13 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable" -14 | async for x in AsyncIterable(): -15 | reveal_type(x) # revealed: int + 1 | async def foo(flag: bool): + 2 | class PossiblyUnboundAnext: + 3 | if flag: + 4 | async def __anext__(self) -> int: + 5 | return 42 + 6 | + 7 | class AsyncIterable: + 8 | def __aiter__(self) -> PossiblyUnboundAnext: + 9 | return PossiblyUnboundAnext() +10 | +11 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable" +12 | async for x in AsyncIterable(): +13 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `AsyncIterable` may not be async-iterable - --> src/mdtest_snippet.py:14:20 + --> src/mdtest_snippet.py:12:20 | -13 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable" -14 | async for x in AsyncIterable(): +11 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable" +12 | async for x in AsyncIterable(): | ^^^^^^^^^^^^^^^ -15 | reveal_type(x) # revealed: int +13 | reveal_type(x) # revealed: int | info: Its `__aiter__` method returns an object of type `PossiblyUnboundAnext`, which may not have a `__anext__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:15:21 - | -13 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable" -14 | async for x in AsyncIterable(): -15 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Synchronously_iterab…_(80fa705b1c61d982).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Synchronously_iterab…_(80fa705b1c61d982).snap index 29e0d262df..74d072df7c 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Synchronously_iterab…_(80fa705b1c61d982).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Synchronously_iterab…_(80fa705b1c61d982).snap @@ -12,46 +12,32 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | async def foo(): - 4 | class Iterator: - 5 | def __next__(self) -> int: - 6 | return 42 - 7 | - 8 | class Iterable: - 9 | def __iter__(self) -> Iterator: -10 | return Iterator() -11 | -12 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable" -13 | async for x in Iterator(): -14 | reveal_type(x) # revealed: Unknown + 1 | async def foo(): + 2 | class Iterator: + 3 | def __next__(self) -> int: + 4 | return 42 + 5 | + 6 | class Iterable: + 7 | def __iter__(self) -> Iterator: + 8 | return Iterator() + 9 | +10 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable" +11 | async for x in Iterator(): +12 | reveal_type(x) # revealed: Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterator` is not async-iterable - --> src/mdtest_snippet.py:13:20 + --> src/mdtest_snippet.py:11:20 | -12 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable" -13 | async for x in Iterator(): +10 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable" +11 | async for x in Iterator(): | ^^^^^^^^^^ -14 | reveal_type(x) # revealed: Unknown +12 | reveal_type(x) # revealed: Unknown | info: It has no `__aiter__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:14:21 - | -12 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable" -13 | async for x in Iterator(): -14 | reveal_type(x) # revealed: Unknown - | ^ `Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(b614724363eec343).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(b614724363eec343).snap index 33e475d546..290aed4af8 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(b614724363eec343).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(b614724363eec343).snap @@ -12,48 +12,34 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class AsyncIterator: - 4 | async def __anext__(self, arg: int) -> int: # wrong - 5 | return 42 - 6 | - 7 | class AsyncIterable: - 8 | def __aiter__(self) -> AsyncIterator: - 9 | return AsyncIterator() -10 | -11 | async def foo(): -12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -13 | async for x in AsyncIterable(): -14 | reveal_type(x) # revealed: int + 1 | class AsyncIterator: + 2 | async def __anext__(self, arg: int) -> int: # wrong + 3 | return 42 + 4 | + 5 | class AsyncIterable: + 6 | def __aiter__(self) -> AsyncIterator: + 7 | return AsyncIterator() + 8 | + 9 | async def foo(): +10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" +11 | async for x in AsyncIterable(): +12 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `AsyncIterable` is not async-iterable - --> src/mdtest_snippet.py:13:20 + --> src/mdtest_snippet.py:11:20 | -11 | async def foo(): -12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -13 | async for x in AsyncIterable(): + 9 | async def foo(): +10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" +11 | async for x in AsyncIterable(): | ^^^^^^^^^^^^^^^ -14 | reveal_type(x) # revealed: int +12 | reveal_type(x) # revealed: int | info: Its `__aiter__` method returns an object of type `AsyncIterator`, which has an invalid `__anext__` method info: Expected signature for `__anext__` is `def __anext__(self): ...` info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:14:21 - | -12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -13 | async for x in AsyncIterable(): -14 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(e1f3e9275d0a367).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(e1f3e9275d0a367).snap index 3373f0d4ae..6dd3a1bfa0 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(e1f3e9275d0a367).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/async_for.md_-_Async_-_Error_cases_-_Wrong_signature_for_…_(e1f3e9275d0a367).snap @@ -12,48 +12,34 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class AsyncIterator: - 4 | async def __anext__(self) -> int: - 5 | return 42 - 6 | - 7 | class AsyncIterable: - 8 | def __aiter__(self, arg: int) -> AsyncIterator: # wrong - 9 | return AsyncIterator() -10 | -11 | async def foo(): -12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -13 | async for x in AsyncIterable(): -14 | reveal_type(x) # revealed: int + 1 | class AsyncIterator: + 2 | async def __anext__(self) -> int: + 3 | return 42 + 4 | + 5 | class AsyncIterable: + 6 | def __aiter__(self, arg: int) -> AsyncIterator: # wrong + 7 | return AsyncIterator() + 8 | + 9 | async def foo(): +10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" +11 | async for x in AsyncIterable(): +12 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `AsyncIterable` is not async-iterable - --> src/mdtest_snippet.py:13:20 + --> src/mdtest_snippet.py:11:20 | -11 | async def foo(): -12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -13 | async for x in AsyncIterable(): + 9 | async def foo(): +10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" +11 | async for x in AsyncIterable(): | ^^^^^^^^^^^^^^^ -14 | reveal_type(x) # revealed: int +12 | reveal_type(x) # revealed: int | info: Its `__aiter__` method has an invalid signature info: Expected signature `def __aiter__(self): ...` info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:14:21 - | -12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" -13 | async for x in AsyncIterable(): -14 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/dataclasses.md_-_Dataclasses_-_`dataclasses.KW_ONLY…_(dd1b8f2f71487f16).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/dataclasses.md_-_Dataclasses_-_`dataclasses.KW_ONLY…_(dd1b8f2f71487f16).snap index 2cd0c99649..02328d725a 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/dataclasses.md_-_Dataclasses_-_`dataclasses.KW_ONLY…_(dd1b8f2f71487f16).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/dataclasses.md_-_Dataclasses_-_`dataclasses.KW_ONLY…_(dd1b8f2f71487f16).snap @@ -13,86 +13,71 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses. ``` 1 | from dataclasses import dataclass, field, KW_ONLY - 2 | from typing_extensions import reveal_type - 3 | - 4 | @dataclass - 5 | class C: - 6 | x: int - 7 | _: KW_ONLY - 8 | y: str - 9 | -10 | reveal_type(C.__init__) # revealed: (self: C, x: int, *, y: str) -> None -11 | -12 | # error: [missing-argument] -13 | # error: [too-many-positional-arguments] -14 | C(3, "") -15 | -16 | C(3, y="") -17 | @dataclass -18 | class Fails: # error: [duplicate-kw-only] -19 | a: int -20 | b: KW_ONLY -21 | c: str -22 | d: KW_ONLY -23 | e: bytes -24 | -25 | reveal_type(Fails.__init__) # revealed: (self: Fails, a: int, *, c: str, e: bytes) -> None -26 | def flag() -> bool: -27 | return True -28 | -29 | @dataclass -30 | class D: # error: [duplicate-kw-only] -31 | x: int -32 | _1: KW_ONLY -33 | -34 | if flag(): -35 | y: str -36 | _2: KW_ONLY -37 | z: float -38 | from dataclasses import dataclass, KW_ONLY -39 | -40 | @dataclass -41 | class D: -42 | x: int -43 | _: KW_ONLY -44 | y: str -45 | -46 | @dataclass -47 | class E(D): -48 | z: bytes -49 | -50 | # This should work: x=1 (positional), z=b"foo" (positional), y="foo" (keyword-only) -51 | E(1, b"foo", y="foo") -52 | -53 | reveal_type(E.__init__) # revealed: (self: E, x: int, z: bytes, *, y: str) -> None + 2 | + 3 | @dataclass + 4 | class C: + 5 | x: int + 6 | _: KW_ONLY + 7 | y: str + 8 | + 9 | reveal_type(C.__init__) # revealed: (self: C, x: int, *, y: str) -> None +10 | +11 | # error: [missing-argument] +12 | # error: [too-many-positional-arguments] +13 | C(3, "") +14 | +15 | C(3, y="") +16 | @dataclass +17 | class Fails: # error: [duplicate-kw-only] +18 | a: int +19 | b: KW_ONLY +20 | c: str +21 | d: KW_ONLY +22 | e: bytes +23 | +24 | reveal_type(Fails.__init__) # revealed: (self: Fails, a: int, *, c: str, e: bytes) -> None +25 | def flag() -> bool: +26 | return True +27 | +28 | @dataclass +29 | class D: # error: [duplicate-kw-only] +30 | x: int +31 | _1: KW_ONLY +32 | +33 | if flag(): +34 | y: str +35 | _2: KW_ONLY +36 | z: float +37 | from dataclasses import dataclass, KW_ONLY +38 | +39 | @dataclass +40 | class D: +41 | x: int +42 | _: KW_ONLY +43 | y: str +44 | +45 | @dataclass +46 | class E(D): +47 | z: bytes +48 | +49 | # This should work: x=1 (positional), z=b"foo" (positional), y="foo" (keyword-only) +50 | E(1, b"foo", y="foo") +51 | +52 | reveal_type(E.__init__) # revealed: (self: E, x: int, z: bytes, *, y: str) -> None ``` # Diagnostics -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:10:13 - | - 8 | y: str - 9 | -10 | reveal_type(C.__init__) # revealed: (self: C, x: int, *, y: str) -> None - | ^^^^^^^^^^ `(self: C, x: int, *, y: str) -> None` -11 | -12 | # error: [missing-argument] - | - -``` - ``` error[missing-argument]: No argument provided for required parameter `y` - --> src/mdtest_snippet.py:14:1 + --> src/mdtest_snippet.py:13:1 | -12 | # error: [missing-argument] -13 | # error: [too-many-positional-arguments] -14 | C(3, "") +11 | # error: [missing-argument] +12 | # error: [too-many-positional-arguments] +13 | C(3, "") | ^^^^^^^^ -15 | -16 | C(3, y="") +14 | +15 | C(3, y="") | info: rule `missing-argument` is enabled by default @@ -100,14 +85,14 @@ info: rule `missing-argument` is enabled by default ``` error[too-many-positional-arguments]: Too many positional arguments: expected 1, got 2 - --> src/mdtest_snippet.py:14:6 + --> src/mdtest_snippet.py:13:6 | -12 | # error: [missing-argument] -13 | # error: [too-many-positional-arguments] -14 | C(3, "") +11 | # error: [missing-argument] +12 | # error: [too-many-positional-arguments] +13 | C(3, "") | ^^ -15 | -16 | C(3, y="") +14 | +15 | C(3, y="") | info: rule `too-many-positional-arguments` is enabled by default @@ -115,57 +100,31 @@ info: rule `too-many-positional-arguments` is enabled by default ``` error[duplicate-kw-only]: Dataclass has more than one field annotated with `KW_ONLY` - --> src/mdtest_snippet.py:18:7 + --> src/mdtest_snippet.py:17:7 | -16 | C(3, y="") -17 | @dataclass -18 | class Fails: # error: [duplicate-kw-only] +15 | C(3, y="") +16 | @dataclass +17 | class Fails: # error: [duplicate-kw-only] | ^^^^^ -19 | a: int -20 | b: KW_ONLY +18 | a: int +19 | b: KW_ONLY | info: `KW_ONLY` fields: `b`, `d` info: rule `duplicate-kw-only` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:25:13 - | -23 | e: bytes -24 | -25 | reveal_type(Fails.__init__) # revealed: (self: Fails, a: int, *, c: str, e: bytes) -> None - | ^^^^^^^^^^^^^^ `(self: Fails, a: int, *, c: str, e: bytes) -> None` -26 | def flag() -> bool: -27 | return True - | - -``` - ``` error[duplicate-kw-only]: Dataclass has more than one field annotated with `KW_ONLY` - --> src/mdtest_snippet.py:30:7 + --> src/mdtest_snippet.py:29:7 | -29 | @dataclass -30 | class D: # error: [duplicate-kw-only] +28 | @dataclass +29 | class D: # error: [duplicate-kw-only] | ^ -31 | x: int -32 | _1: KW_ONLY +30 | x: int +31 | _1: KW_ONLY | info: `KW_ONLY` fields: `_1`, `_2` info: rule `duplicate-kw-only` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:53:13 - | -51 | E(1, b"foo", y="foo") -52 | -53 | reveal_type(E.__init__) # revealed: (self: E, x: int, z: bytes, *, y: str) -> None - | ^^^^^^^^^^ `(self: E, x: int, z: bytes, *, y: str) -> None` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Bad_`__getitem__`_me…_(3ffe352bb3a76715).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Bad_`__getitem__`_me…_(3ffe352bb3a76715).snap index a9104c6526..35b07a080c 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Bad_`__getitem__`_me…_(3ffe352bb3a76715).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Bad_`__getitem__`_me…_(3ffe352bb3a76715).snap @@ -12,44 +12,30 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class Iterable: - 4 | # invalid because it will implicitly be passed an `int` - 5 | # by the interpreter - 6 | def __getitem__(self, key: str) -> int: - 7 | return 42 - 8 | - 9 | # error: [not-iterable] -10 | for x in Iterable(): -11 | reveal_type(x) # revealed: int +1 | class Iterable: +2 | # invalid because it will implicitly be passed an `int` +3 | # by the interpreter +4 | def __getitem__(self, key: str) -> int: +5 | return 42 +6 | +7 | # error: [not-iterable] +8 | for x in Iterable(): +9 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable` is not iterable - --> src/mdtest_snippet.py:10:10 - | - 9 | # error: [not-iterable] -10 | for x in Iterable(): - | ^^^^^^^^^^ -11 | reveal_type(x) # revealed: int - | + --> src/mdtest_snippet.py:8:10 + | +7 | # error: [not-iterable] +8 | for x in Iterable(): + | ^^^^^^^^^^ +9 | reveal_type(x) # revealed: int + | info: It has no `__iter__` method and its `__getitem__` method has an incorrect signature for the old-style iteration protocol info: `__getitem__` must be at least as permissive as `def __getitem__(self, key: int): ...` to satisfy the old-style iteration protocol info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:11:17 - | - 9 | # error: [not-iterable] -10 | for x in Iterable(): -11 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_No_`__iter__`_method…_(36425dbcbd793d2b).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_No_`__iter__`_method…_(36425dbcbd793d2b).snap index ad4ffa4b00..356132982d 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_No_`__iter__`_method…_(36425dbcbd793d2b).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_No_`__iter__`_method…_(36425dbcbd793d2b).snap @@ -12,40 +12,26 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` -1 | from typing_extensions import reveal_type -2 | -3 | class Bad: -4 | __getitem__: None = None -5 | -6 | # error: [not-iterable] -7 | for x in Bad(): -8 | reveal_type(x) # revealed: Unknown +1 | class Bad: +2 | __getitem__: None = None +3 | +4 | # error: [not-iterable] +5 | for x in Bad(): +6 | reveal_type(x) # revealed: Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `Bad` is not iterable - --> src/mdtest_snippet.py:7:10 + --> src/mdtest_snippet.py:5:10 | -6 | # error: [not-iterable] -7 | for x in Bad(): +4 | # error: [not-iterable] +5 | for x in Bad(): | ^^^^^ -8 | reveal_type(x) # revealed: Unknown +6 | reveal_type(x) # revealed: Unknown | info: It has no `__iter__` method and its `__getitem__` attribute has type `None`, which is not callable info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:8:17 - | -6 | # error: [not-iterable] -7 | for x in Bad(): -8 | reveal_type(x) # revealed: Unknown - | ^ `Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly-not-callabl…_(49a21e4b7fe6e97b).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly-not-callabl…_(49a21e4b7fe6e97b).snap index 1a20384b0d..58ceae4187 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly-not-callabl…_(49a21e4b7fe6e97b).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly-not-callabl…_(49a21e4b7fe6e97b).snap @@ -12,48 +12,46 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | def _(flag: bool): - 4 | class CustomCallable: - 5 | if flag: - 6 | def __call__(self, *args, **kwargs) -> int: - 7 | return 42 - 8 | else: - 9 | __call__: None = None -10 | -11 | class Iterable1: -12 | __getitem__: CustomCallable = CustomCallable() -13 | -14 | class Iterable2: -15 | if flag: -16 | def __getitem__(self, key: int) -> int: -17 | return 42 -18 | else: -19 | __getitem__: None = None -20 | -21 | # error: [not-iterable] -22 | for x in Iterable1(): -23 | # TODO... `int` might be ideal here? -24 | reveal_type(x) # revealed: int | Unknown -25 | -26 | # error: [not-iterable] -27 | for y in Iterable2(): -28 | # TODO... `int` might be ideal here? -29 | reveal_type(y) # revealed: int | Unknown + 1 | def _(flag: bool): + 2 | class CustomCallable: + 3 | if flag: + 4 | def __call__(self, *args, **kwargs) -> int: + 5 | return 42 + 6 | else: + 7 | __call__: None = None + 8 | + 9 | class Iterable1: +10 | __getitem__: CustomCallable = CustomCallable() +11 | +12 | class Iterable2: +13 | if flag: +14 | def __getitem__(self, key: int) -> int: +15 | return 42 +16 | else: +17 | __getitem__: None = None +18 | +19 | # error: [not-iterable] +20 | for x in Iterable1(): +21 | # TODO... `int` might be ideal here? +22 | reveal_type(x) # revealed: int | Unknown +23 | +24 | # error: [not-iterable] +25 | for y in Iterable2(): +26 | # TODO... `int` might be ideal here? +27 | reveal_type(y) # revealed: int | Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable1` may not be iterable - --> src/mdtest_snippet.py:22:14 + --> src/mdtest_snippet.py:20:14 | -21 | # error: [not-iterable] -22 | for x in Iterable1(): +19 | # error: [not-iterable] +20 | for x in Iterable1(): | ^^^^^^^^^^^ -23 | # TODO... `int` might be ideal here? -24 | reveal_type(x) # revealed: int | Unknown +21 | # TODO... `int` might be ideal here? +22 | reveal_type(x) # revealed: int | Unknown | info: It has no `__iter__` method and its `__getitem__` attribute is invalid info: `__getitem__` has type `CustomCallable`, which is not callable @@ -61,44 +59,18 @@ info: rule `not-iterable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:24:21 - | -22 | for x in Iterable1(): -23 | # TODO... `int` might be ideal here? -24 | reveal_type(x) # revealed: int | Unknown - | ^ `int | Unknown` -25 | -26 | # error: [not-iterable] - | - -``` - ``` error[not-iterable]: Object of type `Iterable2` may not be iterable - --> src/mdtest_snippet.py:27:14 + --> src/mdtest_snippet.py:25:14 | -26 | # error: [not-iterable] -27 | for y in Iterable2(): +24 | # error: [not-iterable] +25 | for y in Iterable2(): | ^^^^^^^^^^^ -28 | # TODO... `int` might be ideal here? -29 | reveal_type(y) # revealed: int | Unknown +26 | # TODO... `int` might be ideal here? +27 | reveal_type(y) # revealed: int | Unknown | info: It has no `__iter__` method and its `__getitem__` attribute is invalid info: `__getitem__` has type `(bound method Iterable2.__getitem__(key: int) -> int) | None`, which is not callable info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:29:21 - | -27 | for y in Iterable2(): -28 | # TODO... `int` might be ideal here? -29 | reveal_type(y) # revealed: int | Unknown - | ^ `int | Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6388761c90a0555c).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6388761c90a0555c).snap index ca18f1184a..d36ae95142 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6388761c90a0555c).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6388761c90a0555c).snap @@ -12,48 +12,46 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class Iterator: - 4 | def __next__(self) -> int: - 5 | return 42 - 6 | - 7 | def _(flag: bool): - 8 | class Iterable1: - 9 | if flag: -10 | def __iter__(self) -> Iterator: -11 | return Iterator() -12 | else: -13 | def __iter__(self, invalid_extra_arg) -> Iterator: -14 | return Iterator() -15 | -16 | # error: [not-iterable] -17 | for x in Iterable1(): -18 | reveal_type(x) # revealed: int -19 | -20 | class Iterable2: -21 | if flag: -22 | def __iter__(self) -> Iterator: -23 | return Iterator() -24 | else: -25 | __iter__: None = None -26 | -27 | # error: [not-iterable] -28 | for x in Iterable2(): -29 | # TODO: `int` would probably be better here: -30 | reveal_type(x) # revealed: int | Unknown + 1 | class Iterator: + 2 | def __next__(self) -> int: + 3 | return 42 + 4 | + 5 | def _(flag: bool): + 6 | class Iterable1: + 7 | if flag: + 8 | def __iter__(self) -> Iterator: + 9 | return Iterator() +10 | else: +11 | def __iter__(self, invalid_extra_arg) -> Iterator: +12 | return Iterator() +13 | +14 | # error: [not-iterable] +15 | for x in Iterable1(): +16 | reveal_type(x) # revealed: int +17 | +18 | class Iterable2: +19 | if flag: +20 | def __iter__(self) -> Iterator: +21 | return Iterator() +22 | else: +23 | __iter__: None = None +24 | +25 | # error: [not-iterable] +26 | for x in Iterable2(): +27 | # TODO: `int` would probably be better here: +28 | reveal_type(x) # revealed: int | Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable1` may not be iterable - --> src/mdtest_snippet.py:17:14 + --> src/mdtest_snippet.py:15:14 | -16 | # error: [not-iterable] -17 | for x in Iterable1(): +14 | # error: [not-iterable] +15 | for x in Iterable1(): | ^^^^^^^^^^^ -18 | reveal_type(x) # revealed: int +16 | reveal_type(x) # revealed: int | info: Its `__iter__` method may have an invalid signature info: Type of `__iter__` is `(bound method Iterable1.__iter__() -> Iterator) | (bound method Iterable1.__iter__(invalid_extra_arg) -> Iterator)` @@ -62,43 +60,17 @@ info: rule `not-iterable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:18:21 - | -16 | # error: [not-iterable] -17 | for x in Iterable1(): -18 | reveal_type(x) # revealed: int - | ^ `int` -19 | -20 | class Iterable2: - | - -``` - ``` error[not-iterable]: Object of type `Iterable2` may not be iterable - --> src/mdtest_snippet.py:28:14 + --> src/mdtest_snippet.py:26:14 | -27 | # error: [not-iterable] -28 | for x in Iterable2(): +25 | # error: [not-iterable] +26 | for x in Iterable2(): | ^^^^^^^^^^^ -29 | # TODO: `int` would probably be better here: -30 | reveal_type(x) # revealed: int | Unknown +27 | # TODO: `int` would probably be better here: +28 | reveal_type(x) # revealed: int | Unknown | info: Its `__iter__` attribute (with type `(bound method Iterable2.__iter__() -> Iterator) | None`) may not be callable info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:30:21 - | -28 | for x in Iterable2(): -29 | # TODO: `int` would probably be better here: -30 | reveal_type(x) # revealed: int | Unknown - | ^ `int | Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6805a6032e504b63).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6805a6032e504b63).snap index ba0f58ca09..dfa5173a1e 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6805a6032e504b63).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(6805a6032e504b63).snap @@ -12,45 +12,43 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | def _(flag: bool): - 4 | class Iterable1: - 5 | if flag: - 6 | def __getitem__(self, item: int) -> str: - 7 | return "foo" - 8 | else: - 9 | __getitem__: None = None -10 | -11 | class Iterable2: -12 | if flag: -13 | def __getitem__(self, item: int) -> str: -14 | return "foo" -15 | else: -16 | def __getitem__(self, item: str) -> int: -17 | return 42 -18 | -19 | # error: [not-iterable] -20 | for x in Iterable1(): -21 | # TODO: `str` might be better -22 | reveal_type(x) # revealed: str | Unknown -23 | -24 | # error: [not-iterable] -25 | for y in Iterable2(): -26 | reveal_type(y) # revealed: str | int + 1 | def _(flag: bool): + 2 | class Iterable1: + 3 | if flag: + 4 | def __getitem__(self, item: int) -> str: + 5 | return "foo" + 6 | else: + 7 | __getitem__: None = None + 8 | + 9 | class Iterable2: +10 | if flag: +11 | def __getitem__(self, item: int) -> str: +12 | return "foo" +13 | else: +14 | def __getitem__(self, item: str) -> int: +15 | return 42 +16 | +17 | # error: [not-iterable] +18 | for x in Iterable1(): +19 | # TODO: `str` might be better +20 | reveal_type(x) # revealed: str | Unknown +21 | +22 | # error: [not-iterable] +23 | for y in Iterable2(): +24 | reveal_type(y) # revealed: str | int ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable1` may not be iterable - --> src/mdtest_snippet.py:20:14 + --> src/mdtest_snippet.py:18:14 | -19 | # error: [not-iterable] -20 | for x in Iterable1(): +17 | # error: [not-iterable] +18 | for x in Iterable1(): | ^^^^^^^^^^^ -21 | # TODO: `str` might be better -22 | reveal_type(x) # revealed: str | Unknown +19 | # TODO: `str` might be better +20 | reveal_type(x) # revealed: str | Unknown | info: It has no `__iter__` method and its `__getitem__` attribute is invalid info: `__getitem__` has type `(bound method Iterable1.__getitem__(item: int) -> str) | None`, which is not callable @@ -58,43 +56,17 @@ info: rule `not-iterable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:22:21 - | -20 | for x in Iterable1(): -21 | # TODO: `str` might be better -22 | reveal_type(x) # revealed: str | Unknown - | ^ `str | Unknown` -23 | -24 | # error: [not-iterable] - | - -``` - ``` error[not-iterable]: Object of type `Iterable2` may not be iterable - --> src/mdtest_snippet.py:25:14 + --> src/mdtest_snippet.py:23:14 | -24 | # error: [not-iterable] -25 | for y in Iterable2(): +22 | # error: [not-iterable] +23 | for y in Iterable2(): | ^^^^^^^^^^^ -26 | reveal_type(y) # revealed: str | int +24 | reveal_type(y) # revealed: str | int | info: It has no `__iter__` method and its `__getitem__` method (with type `(bound method Iterable2.__getitem__(item: int) -> str) | (bound method Iterable2.__getitem__(item: str) -> int)`) may have an incorrect signature for the old-style iteration protocol info: `__getitem__` must be at least as permissive as `def __getitem__(self, key: int): ...` to satisfy the old-style iteration protocol info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:26:21 - | -24 | # error: [not-iterable] -25 | for y in Iterable2(): -26 | reveal_type(y) # revealed: str | int - | ^ `str | int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(c626bde8651b643a).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(c626bde8651b643a).snap index ddeda6f7f9..e4fb5e4576 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(c626bde8651b643a).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_invalid_`__…_(c626bde8651b643a).snap @@ -12,52 +12,50 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | def _(flag: bool): - 4 | class Iterator1: - 5 | if flag: - 6 | def __next__(self) -> int: - 7 | return 42 - 8 | else: - 9 | def __next__(self, invalid_extra_arg) -> str: -10 | return "foo" -11 | -12 | class Iterator2: -13 | if flag: -14 | def __next__(self) -> int: -15 | return 42 -16 | else: -17 | __next__: None = None -18 | -19 | class Iterable1: -20 | def __iter__(self) -> Iterator1: -21 | return Iterator1() -22 | -23 | class Iterable2: -24 | def __iter__(self) -> Iterator2: -25 | return Iterator2() -26 | -27 | # error: [not-iterable] -28 | for x in Iterable1(): -29 | reveal_type(x) # revealed: int | str -30 | -31 | # error: [not-iterable] -32 | for y in Iterable2(): -33 | # TODO: `int` would probably be better here: -34 | reveal_type(y) # revealed: int | Unknown + 1 | def _(flag: bool): + 2 | class Iterator1: + 3 | if flag: + 4 | def __next__(self) -> int: + 5 | return 42 + 6 | else: + 7 | def __next__(self, invalid_extra_arg) -> str: + 8 | return "foo" + 9 | +10 | class Iterator2: +11 | if flag: +12 | def __next__(self) -> int: +13 | return 42 +14 | else: +15 | __next__: None = None +16 | +17 | class Iterable1: +18 | def __iter__(self) -> Iterator1: +19 | return Iterator1() +20 | +21 | class Iterable2: +22 | def __iter__(self) -> Iterator2: +23 | return Iterator2() +24 | +25 | # error: [not-iterable] +26 | for x in Iterable1(): +27 | reveal_type(x) # revealed: int | str +28 | +29 | # error: [not-iterable] +30 | for y in Iterable2(): +31 | # TODO: `int` would probably be better here: +32 | reveal_type(y) # revealed: int | Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable1` may not be iterable - --> src/mdtest_snippet.py:28:14 + --> src/mdtest_snippet.py:26:14 | -27 | # error: [not-iterable] -28 | for x in Iterable1(): +25 | # error: [not-iterable] +26 | for x in Iterable1(): | ^^^^^^^^^^^ -29 | reveal_type(x) # revealed: int | str +27 | reveal_type(x) # revealed: int | str | info: Its `__iter__` method returns an object of type `Iterator1`, which may have an invalid `__next__` method info: Expected signature for `__next__` is `def __next__(self): ...` @@ -65,43 +63,17 @@ info: rule `not-iterable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:29:21 - | -27 | # error: [not-iterable] -28 | for x in Iterable1(): -29 | reveal_type(x) # revealed: int | str - | ^ `int | str` -30 | -31 | # error: [not-iterable] - | - -``` - ``` error[not-iterable]: Object of type `Iterable2` may not be iterable - --> src/mdtest_snippet.py:32:14 + --> src/mdtest_snippet.py:30:14 | -31 | # error: [not-iterable] -32 | for y in Iterable2(): +29 | # error: [not-iterable] +30 | for y in Iterable2(): | ^^^^^^^^^^^ -33 | # TODO: `int` would probably be better here: -34 | reveal_type(y) # revealed: int | Unknown +31 | # TODO: `int` would probably be better here: +32 | reveal_type(y) # revealed: int | Unknown | info: Its `__iter__` method returns an object of type `Iterator2`, which has a `__next__` attribute that may not be callable info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:34:21 - | -32 | for y in Iterable2(): -33 | # TODO: `int` would probably be better here: -34 | reveal_type(y) # revealed: int | Unknown - | ^ `int | Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(77269542b8e81774).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(77269542b8e81774).snap index dde017803c..16b74d788c 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(77269542b8e81774).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(77269542b8e81774).snap @@ -12,99 +12,71 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class Iterator: - 4 | def __next__(self) -> bytes: - 5 | return b"foo" - 6 | - 7 | def _(flag: bool, flag2: bool): - 8 | class Iterable1: - 9 | if flag: -10 | def __getitem__(self, item: int) -> str: -11 | return "foo" -12 | else: -13 | __getitem__: None = None -14 | -15 | if flag2: -16 | def __iter__(self) -> Iterator: -17 | return Iterator() -18 | -19 | class Iterable2: -20 | if flag: -21 | def __getitem__(self, item: int) -> str: -22 | return "foo" -23 | else: -24 | def __getitem__(self, item: str) -> int: -25 | return 42 -26 | if flag2: -27 | def __iter__(self) -> Iterator: -28 | return Iterator() -29 | -30 | # error: [not-iterable] -31 | for x in Iterable1(): -32 | # TODO: `bytes | str` might be better -33 | reveal_type(x) # revealed: bytes | str | Unknown -34 | -35 | # error: [not-iterable] -36 | for y in Iterable2(): -37 | reveal_type(y) # revealed: bytes | str | int + 1 | class Iterator: + 2 | def __next__(self) -> bytes: + 3 | return b"foo" + 4 | + 5 | def _(flag: bool, flag2: bool): + 6 | class Iterable1: + 7 | if flag: + 8 | def __getitem__(self, item: int) -> str: + 9 | return "foo" +10 | else: +11 | __getitem__: None = None +12 | +13 | if flag2: +14 | def __iter__(self) -> Iterator: +15 | return Iterator() +16 | +17 | class Iterable2: +18 | if flag: +19 | def __getitem__(self, item: int) -> str: +20 | return "foo" +21 | else: +22 | def __getitem__(self, item: str) -> int: +23 | return 42 +24 | if flag2: +25 | def __iter__(self) -> Iterator: +26 | return Iterator() +27 | +28 | # error: [not-iterable] +29 | for x in Iterable1(): +30 | # TODO: `bytes | str` might be better +31 | reveal_type(x) # revealed: bytes | str | Unknown +32 | +33 | # error: [not-iterable] +34 | for y in Iterable2(): +35 | reveal_type(y) # revealed: bytes | str | int ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable1` may not be iterable - --> src/mdtest_snippet.py:31:14 + --> src/mdtest_snippet.py:29:14 | -30 | # error: [not-iterable] -31 | for x in Iterable1(): +28 | # error: [not-iterable] +29 | for x in Iterable1(): | ^^^^^^^^^^^ -32 | # TODO: `bytes | str` might be better -33 | reveal_type(x) # revealed: bytes | str | Unknown +30 | # TODO: `bytes | str` might be better +31 | reveal_type(x) # revealed: bytes | str | Unknown | info: It may not have an `__iter__` method and its `__getitem__` attribute (with type `(bound method Iterable1.__getitem__(item: int) -> str) | None`) may not be callable info: rule `not-iterable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:33:21 - | -31 | for x in Iterable1(): -32 | # TODO: `bytes | str` might be better -33 | reveal_type(x) # revealed: bytes | str | Unknown - | ^ `bytes | str | Unknown` -34 | -35 | # error: [not-iterable] - | - -``` - ``` error[not-iterable]: Object of type `Iterable2` may not be iterable - --> src/mdtest_snippet.py:36:14 + --> src/mdtest_snippet.py:34:14 | -35 | # error: [not-iterable] -36 | for y in Iterable2(): +33 | # error: [not-iterable] +34 | for y in Iterable2(): | ^^^^^^^^^^^ -37 | reveal_type(y) # revealed: bytes | str | int +35 | reveal_type(y) # revealed: bytes | str | int | info: It may not have an `__iter__` method and its `__getitem__` method (with type `(bound method Iterable2.__getitem__(item: int) -> str) | (bound method Iterable2.__getitem__(item: str) -> int)`) may have an incorrect signature for the old-style iteration protocol info: `__getitem__` must be at least as permissive as `def __getitem__(self, key: int): ...` to satisfy the old-style iteration protocol info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:37:21 - | -35 | # error: [not-iterable] -36 | for y in Iterable2(): -37 | reveal_type(y) # revealed: bytes | str | int - | ^ `bytes | str | int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(9f781babda99d74b).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(9f781babda99d74b).snap index b2bfc28b10..2e0457bc4d 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(9f781babda99d74b).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(9f781babda99d74b).snap @@ -12,52 +12,38 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | def _(flag: bool): - 4 | class Iterator: - 5 | def __next__(self) -> int: - 6 | return 42 - 7 | - 8 | class Iterable: - 9 | if flag: -10 | def __iter__(self) -> Iterator: -11 | return Iterator() -12 | # invalid signature because it only accepts a `str`, -13 | # but the old-style iteration protocol will pass it an `int` -14 | def __getitem__(self, key: str) -> bytes: -15 | return bytes() -16 | -17 | # error: [not-iterable] -18 | for x in Iterable(): -19 | reveal_type(x) # revealed: int | bytes + 1 | def _(flag: bool): + 2 | class Iterator: + 3 | def __next__(self) -> int: + 4 | return 42 + 5 | + 6 | class Iterable: + 7 | if flag: + 8 | def __iter__(self) -> Iterator: + 9 | return Iterator() +10 | # invalid signature because it only accepts a `str`, +11 | # but the old-style iteration protocol will pass it an `int` +12 | def __getitem__(self, key: str) -> bytes: +13 | return bytes() +14 | +15 | # error: [not-iterable] +16 | for x in Iterable(): +17 | reveal_type(x) # revealed: int | bytes ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable` may not be iterable - --> src/mdtest_snippet.py:18:14 + --> src/mdtest_snippet.py:16:14 | -17 | # error: [not-iterable] -18 | for x in Iterable(): +15 | # error: [not-iterable] +16 | for x in Iterable(): | ^^^^^^^^^^ -19 | reveal_type(x) # revealed: int | bytes +17 | reveal_type(x) # revealed: int | bytes | info: It may not have an `__iter__` method and its `__getitem__` method has an incorrect signature for the old-style iteration protocol info: `__getitem__` must be at least as permissive as `def __getitem__(self, key: int): ...` to satisfy the old-style iteration protocol info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:19:21 - | -17 | # error: [not-iterable] -18 | for x in Iterable(): -19 | reveal_type(x) # revealed: int | bytes - | ^ `int | bytes` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(d8a02a0fcbb390a3).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(d8a02a0fcbb390a3).snap index 41e7b6a425..b41da99a08 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(d8a02a0fcbb390a3).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Possibly_missing_`__…_(d8a02a0fcbb390a3).snap @@ -12,50 +12,36 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class Iterator: - 4 | def __next__(self) -> int: - 5 | return 42 - 6 | - 7 | def _(flag1: bool, flag2: bool): - 8 | class Iterable: - 9 | if flag1: -10 | def __iter__(self) -> Iterator: -11 | return Iterator() -12 | if flag2: -13 | def __getitem__(self, key: int) -> bytes: -14 | return bytes() -15 | -16 | # error: [not-iterable] -17 | for x in Iterable(): -18 | reveal_type(x) # revealed: int | bytes + 1 | class Iterator: + 2 | def __next__(self) -> int: + 3 | return 42 + 4 | + 5 | def _(flag1: bool, flag2: bool): + 6 | class Iterable: + 7 | if flag1: + 8 | def __iter__(self) -> Iterator: + 9 | return Iterator() +10 | if flag2: +11 | def __getitem__(self, key: int) -> bytes: +12 | return bytes() +13 | +14 | # error: [not-iterable] +15 | for x in Iterable(): +16 | reveal_type(x) # revealed: int | bytes ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable` may not be iterable - --> src/mdtest_snippet.py:17:14 + --> src/mdtest_snippet.py:15:14 | -16 | # error: [not-iterable] -17 | for x in Iterable(): +14 | # error: [not-iterable] +15 | for x in Iterable(): | ^^^^^^^^^^ -18 | reveal_type(x) # revealed: int | bytes +16 | reveal_type(x) # revealed: int | bytes | info: It may not have an `__iter__` method or a `__getitem__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:18:21 - | -16 | # error: [not-iterable] -17 | for x in Iterable(): -18 | reveal_type(x) # revealed: int | bytes - | ^ `int | bytes` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(6177bb6d13a22241).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(6177bb6d13a22241).snap index e7ab06ed09..0a5173b109 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(6177bb6d13a22241).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(6177bb6d13a22241).snap @@ -12,52 +12,38 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class TestIter: - 4 | def __next__(self) -> int: - 5 | return 42 - 6 | - 7 | class Test: - 8 | def __iter__(self) -> TestIter: - 9 | return TestIter() -10 | -11 | class Test2: -12 | def __iter__(self) -> int: -13 | return 42 -14 | -15 | def _(flag: bool): -16 | # TODO: Improve error message to state which union variant isn't iterable (https://github.com/astral-sh/ruff/issues/13989) -17 | # error: [not-iterable] -18 | for x in Test() if flag else Test2(): -19 | reveal_type(x) # revealed: int + 1 | class TestIter: + 2 | def __next__(self) -> int: + 3 | return 42 + 4 | + 5 | class Test: + 6 | def __iter__(self) -> TestIter: + 7 | return TestIter() + 8 | + 9 | class Test2: +10 | def __iter__(self) -> int: +11 | return 42 +12 | +13 | def _(flag: bool): +14 | # TODO: Improve error message to state which union variant isn't iterable (https://github.com/astral-sh/ruff/issues/13989) +15 | # error: [not-iterable] +16 | for x in Test() if flag else Test2(): +17 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `Test | Test2` may not be iterable - --> src/mdtest_snippet.py:18:14 + --> src/mdtest_snippet.py:16:14 | -16 | # TODO: Improve error message to state which union variant isn't iterable (https://github.com/astral-sh/ruff/issues/13989) -17 | # error: [not-iterable] -18 | for x in Test() if flag else Test2(): +14 | # TODO: Improve error message to state which union variant isn't iterable (https://github.com/astral-sh/ruff/issues/13989) +15 | # error: [not-iterable] +16 | for x in Test() if flag else Test2(): | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -19 | reveal_type(x) # revealed: int +17 | reveal_type(x) # revealed: int | info: Its `__iter__` method returns an object of type `TestIter | int`, which may not have a `__next__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:19:21 - | -17 | # error: [not-iterable] -18 | for x in Test() if flag else Test2(): -19 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(ba36fbef63a14969).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(ba36fbef63a14969).snap index 8eb966da9d..7a9a395bd4 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(ba36fbef63a14969).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_Union_type_as_iterab…_(ba36fbef63a14969).snap @@ -12,47 +12,33 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class TestIter: - 4 | def __next__(self) -> int: - 5 | return 42 - 6 | - 7 | class Test: - 8 | def __iter__(self) -> TestIter: - 9 | return TestIter() -10 | -11 | def _(flag: bool): -12 | # error: [not-iterable] -13 | for x in Test() if flag else 42: -14 | reveal_type(x) # revealed: int + 1 | class TestIter: + 2 | def __next__(self) -> int: + 3 | return 42 + 4 | + 5 | class Test: + 6 | def __iter__(self) -> TestIter: + 7 | return TestIter() + 8 | + 9 | def _(flag: bool): +10 | # error: [not-iterable] +11 | for x in Test() if flag else 42: +12 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `Test | Literal[42]` may not be iterable - --> src/mdtest_snippet.py:13:14 + --> src/mdtest_snippet.py:11:14 | -11 | def _(flag: bool): -12 | # error: [not-iterable] -13 | for x in Test() if flag else 42: + 9 | def _(flag: bool): +10 | # error: [not-iterable] +11 | for x in Test() if flag else 42: | ^^^^^^^^^^^^^^^^^^^^^^ -14 | reveal_type(x) # revealed: int +12 | reveal_type(x) # revealed: int | info: It may not have an `__iter__` method and it doesn't have a `__getitem__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:14:21 - | -12 | # error: [not-iterable] -13 | for x in Test() if flag else 42: -14 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_With_non-callable_it…_(a1cdf01ad69ac37c).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_With_non-callable_it…_(a1cdf01ad69ac37c).snap index 3e5d3bf4eb..52f88e823a 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_With_non-callable_it…_(a1cdf01ad69ac37c).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_With_non-callable_it…_(a1cdf01ad69ac37c).snap @@ -12,34 +12,32 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | def _(flag: bool): - 4 | class NotIterable: - 5 | if flag: - 6 | __iter__: int = 1 - 7 | else: - 8 | __iter__: None = None - 9 | -10 | # error: [not-iterable] -11 | for x in NotIterable(): -12 | pass -13 | -14 | # revealed: Unknown -15 | # error: [possibly-unresolved-reference] -16 | reveal_type(x) + 1 | def _(flag: bool): + 2 | class NotIterable: + 3 | if flag: + 4 | __iter__: int = 1 + 5 | else: + 6 | __iter__: None = None + 7 | + 8 | # error: [not-iterable] + 9 | for x in NotIterable(): +10 | pass +11 | +12 | # revealed: Unknown +13 | # error: [possibly-unresolved-reference] +14 | reveal_type(x) ``` # Diagnostics ``` error[not-iterable]: Object of type `NotIterable` is not iterable - --> src/mdtest_snippet.py:11:14 + --> src/mdtest_snippet.py:9:14 | -10 | # error: [not-iterable] -11 | for x in NotIterable(): + 8 | # error: [not-iterable] + 9 | for x in NotIterable(): | ^^^^^^^^^^^^^ -12 | pass +10 | pass | info: Its `__iter__` attribute has type `int | None`, which is not callable info: rule `not-iterable` is enabled by default @@ -48,25 +46,13 @@ info: rule `not-iterable` is enabled by default ``` info[possibly-unresolved-reference]: Name `x` used when possibly not defined - --> src/mdtest_snippet.py:16:17 + --> src/mdtest_snippet.py:14:17 | -14 | # revealed: Unknown -15 | # error: [possibly-unresolved-reference] -16 | reveal_type(x) +12 | # revealed: Unknown +13 | # error: [possibly-unresolved-reference] +14 | reveal_type(x) | ^ | info: rule `possibly-unresolved-reference` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:16:17 - | -14 | # revealed: Unknown -15 | # error: [possibly-unresolved-reference] -16 | reveal_type(x) - | ^ `Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_does_not_…_(92e3fdd69edad63d).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_does_not_…_(92e3fdd69edad63d).snap index 25942db89e..05eea5a6ca 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_does_not_…_(92e3fdd69edad63d).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_does_not_…_(92e3fdd69edad63d).snap @@ -12,41 +12,27 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` -1 | from typing_extensions import reveal_type -2 | -3 | class Bad: -4 | def __iter__(self) -> int: -5 | return 42 -6 | -7 | # error: [not-iterable] -8 | for x in Bad(): -9 | reveal_type(x) # revealed: Unknown +1 | class Bad: +2 | def __iter__(self) -> int: +3 | return 42 +4 | +5 | # error: [not-iterable] +6 | for x in Bad(): +7 | reveal_type(x) # revealed: Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `Bad` is not iterable - --> src/mdtest_snippet.py:8:10 + --> src/mdtest_snippet.py:6:10 | -7 | # error: [not-iterable] -8 | for x in Bad(): +5 | # error: [not-iterable] +6 | for x in Bad(): | ^^^^^ -9 | reveal_type(x) # revealed: Unknown +7 | reveal_type(x) # revealed: Unknown | info: Its `__iter__` method returns an object of type `int`, which has no `__next__` method info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:9:17 - | -7 | # error: [not-iterable] -8 | for x in Bad(): -9 | reveal_type(x) # revealed: Unknown - | ^ `Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_method_wi…_(1136c0e783d61ba4).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_method_wi…_(1136c0e783d61ba4).snap index e37675bbc2..340c169cde 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_method_wi…_(1136c0e783d61ba4).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_method_wi…_(1136c0e783d61ba4).snap @@ -12,46 +12,32 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class Iterator: - 4 | def __next__(self) -> int: - 5 | return 42 - 6 | - 7 | class Iterable: - 8 | def __iter__(self, extra_arg) -> Iterator: - 9 | return Iterator() -10 | -11 | # error: [not-iterable] -12 | for x in Iterable(): -13 | reveal_type(x) # revealed: int + 1 | class Iterator: + 2 | def __next__(self) -> int: + 3 | return 42 + 4 | + 5 | class Iterable: + 6 | def __iter__(self, extra_arg) -> Iterator: + 7 | return Iterator() + 8 | + 9 | # error: [not-iterable] +10 | for x in Iterable(): +11 | reveal_type(x) # revealed: int ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable` is not iterable - --> src/mdtest_snippet.py:12:10 + --> src/mdtest_snippet.py:10:10 | -11 | # error: [not-iterable] -12 | for x in Iterable(): + 9 | # error: [not-iterable] +10 | for x in Iterable(): | ^^^^^^^^^^ -13 | reveal_type(x) # revealed: int +11 | reveal_type(x) # revealed: int | info: Its `__iter__` method has an invalid signature info: Expected signature `def __iter__(self): ...` info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:13:17 - | -11 | # error: [not-iterable] -12 | for x in Iterable(): -13 | reveal_type(x) # revealed: int - | ^ `int` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_returns_a…_(707bd02a22c4acc8).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_returns_a…_(707bd02a22c4acc8).snap index b5c24e5283..e29a88efa8 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_returns_a…_(707bd02a22c4acc8).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/for.md_-_For_loops_-_`__iter__`_returns_a…_(707bd02a22c4acc8).snap @@ -12,42 +12,40 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | class Iterator1: - 4 | def __next__(self, extra_arg) -> int: - 5 | return 42 - 6 | - 7 | class Iterator2: - 8 | __next__: None = None - 9 | -10 | class Iterable1: -11 | def __iter__(self) -> Iterator1: -12 | return Iterator1() -13 | -14 | class Iterable2: -15 | def __iter__(self) -> Iterator2: -16 | return Iterator2() -17 | -18 | # error: [not-iterable] -19 | for x in Iterable1(): -20 | reveal_type(x) # revealed: int -21 | -22 | # error: [not-iterable] -23 | for y in Iterable2(): -24 | reveal_type(y) # revealed: Unknown + 1 | class Iterator1: + 2 | def __next__(self, extra_arg) -> int: + 3 | return 42 + 4 | + 5 | class Iterator2: + 6 | __next__: None = None + 7 | + 8 | class Iterable1: + 9 | def __iter__(self) -> Iterator1: +10 | return Iterator1() +11 | +12 | class Iterable2: +13 | def __iter__(self) -> Iterator2: +14 | return Iterator2() +15 | +16 | # error: [not-iterable] +17 | for x in Iterable1(): +18 | reveal_type(x) # revealed: int +19 | +20 | # error: [not-iterable] +21 | for y in Iterable2(): +22 | reveal_type(y) # revealed: Unknown ``` # Diagnostics ``` error[not-iterable]: Object of type `Iterable1` is not iterable - --> src/mdtest_snippet.py:19:10 + --> src/mdtest_snippet.py:17:10 | -18 | # error: [not-iterable] -19 | for x in Iterable1(): +16 | # error: [not-iterable] +17 | for x in Iterable1(): | ^^^^^^^^^^^ -20 | reveal_type(x) # revealed: int +18 | reveal_type(x) # revealed: int | info: Its `__iter__` method returns an object of type `Iterator1`, which has an invalid `__next__` method info: Expected signature for `__next__` is `def __next__(self): ...` @@ -55,42 +53,16 @@ info: rule `not-iterable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:20:17 - | -18 | # error: [not-iterable] -19 | for x in Iterable1(): -20 | reveal_type(x) # revealed: int - | ^ `int` -21 | -22 | # error: [not-iterable] - | - -``` - ``` error[not-iterable]: Object of type `Iterable2` is not iterable - --> src/mdtest_snippet.py:23:10 + --> src/mdtest_snippet.py:21:10 | -22 | # error: [not-iterable] -23 | for y in Iterable2(): +20 | # error: [not-iterable] +21 | for y in Iterable2(): | ^^^^^^^^^^^ -24 | reveal_type(y) # revealed: Unknown +22 | reveal_type(y) # revealed: Unknown | info: Its `__iter__` method returns an object of type `Iterator2`, which has a `__next__` attribute that is not callable info: rule `not-iterable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:24:17 - | -22 | # error: [not-iterable] -23 | for y in Iterable2(): -24 | reveal_type(y) # revealed: Unknown - | ^ `Unknown` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_bound_ty…_(d50204b9d91b7bd1).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_bound_ty…_(d50204b9d91b7bd1).snap index f5e6aa220a..f84cd7ec25 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_bound_ty…_(d50204b9d91b7bd1).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_bound_ty…_(d50204b9d91b7bd1).snap @@ -13,78 +13,38 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/legacy/function ``` 1 | from typing import TypeVar - 2 | from typing_extensions import reveal_type - 3 | - 4 | T = TypeVar("T", bound=int) - 5 | - 6 | def f(x: T) -> T: - 7 | return x - 8 | - 9 | reveal_type(f(1)) # revealed: Literal[1] -10 | reveal_type(f(True)) # revealed: Literal[True] -11 | # error: [invalid-argument-type] -12 | reveal_type(f("string")) # revealed: Unknown + 2 | + 3 | T = TypeVar("T", bound=int) + 4 | + 5 | def f(x: T) -> T: + 6 | return x + 7 | + 8 | reveal_type(f(1)) # revealed: Literal[1] + 9 | reveal_type(f(True)) # revealed: Literal[True] +10 | # error: [invalid-argument-type] +11 | reveal_type(f("string")) # revealed: Unknown ``` # Diagnostics -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:9:13 - | - 7 | return x - 8 | - 9 | reveal_type(f(1)) # revealed: Literal[1] - | ^^^^ `Literal[1]` -10 | reveal_type(f(True)) # revealed: Literal[True] -11 | # error: [invalid-argument-type] - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:10:13 - | - 9 | reveal_type(f(1)) # revealed: Literal[1] -10 | reveal_type(f(True)) # revealed: Literal[True] - | ^^^^^^^ `Literal[True]` -11 | # error: [invalid-argument-type] -12 | reveal_type(f("string")) # revealed: Unknown - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:12:13 - | -10 | reveal_type(f(True)) # revealed: Literal[True] -11 | # error: [invalid-argument-type] -12 | reveal_type(f("string")) # revealed: Unknown - | ^^^^^^^^^^^ `Unknown` - | - -``` - ``` error[invalid-argument-type]: Argument to function `f` is incorrect - --> src/mdtest_snippet.py:12:15 + --> src/mdtest_snippet.py:11:15 | -10 | reveal_type(f(True)) # revealed: Literal[True] -11 | # error: [invalid-argument-type] -12 | reveal_type(f("string")) # revealed: Unknown + 9 | reveal_type(f(True)) # revealed: Literal[True] +10 | # error: [invalid-argument-type] +11 | reveal_type(f("string")) # revealed: Unknown | ^^^^^^^^ Argument type `Literal["string"]` does not satisfy upper bound `int` of type variable `T` | info: Type variable defined here - --> src/mdtest_snippet.py:4:1 + --> src/mdtest_snippet.py:3:1 | -2 | from typing_extensions import reveal_type -3 | -4 | T = TypeVar("T", bound=int) +1 | from typing import TypeVar +2 | +3 | T = TypeVar("T", bound=int) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -5 | -6 | def f(x: T) -> T: +4 | +5 | def f(x: T) -> T: | info: rule `invalid-argument-type` is enabled by default diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_constrai…_(48ab83f977c109b4).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_constrai…_(48ab83f977c109b4).snap index bcba88dbd9..b0594ecca1 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_constrai…_(48ab83f977c109b4).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___L…_-_Inferring_a_constrai…_(48ab83f977c109b4).snap @@ -13,93 +13,39 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/legacy/function ``` 1 | from typing import TypeVar - 2 | from typing_extensions import reveal_type - 3 | - 4 | T = TypeVar("T", int, None) - 5 | - 6 | def f(x: T) -> T: - 7 | return x - 8 | - 9 | reveal_type(f(1)) # revealed: int -10 | reveal_type(f(True)) # revealed: int -11 | reveal_type(f(None)) # revealed: None -12 | # error: [invalid-argument-type] -13 | reveal_type(f("string")) # revealed: Unknown + 2 | + 3 | T = TypeVar("T", int, None) + 4 | + 5 | def f(x: T) -> T: + 6 | return x + 7 | + 8 | reveal_type(f(1)) # revealed: int + 9 | reveal_type(f(True)) # revealed: int +10 | reveal_type(f(None)) # revealed: None +11 | # error: [invalid-argument-type] +12 | reveal_type(f("string")) # revealed: Unknown ``` # Diagnostics -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:9:13 - | - 7 | return x - 8 | - 9 | reveal_type(f(1)) # revealed: int - | ^^^^ `int` -10 | reveal_type(f(True)) # revealed: int -11 | reveal_type(f(None)) # revealed: None - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:10:13 - | - 9 | reveal_type(f(1)) # revealed: int -10 | reveal_type(f(True)) # revealed: int - | ^^^^^^^ `int` -11 | reveal_type(f(None)) # revealed: None -12 | # error: [invalid-argument-type] - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:11:13 - | - 9 | reveal_type(f(1)) # revealed: int -10 | reveal_type(f(True)) # revealed: int -11 | reveal_type(f(None)) # revealed: None - | ^^^^^^^ `None` -12 | # error: [invalid-argument-type] -13 | reveal_type(f("string")) # revealed: Unknown - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:13:13 - | -11 | reveal_type(f(None)) # revealed: None -12 | # error: [invalid-argument-type] -13 | reveal_type(f("string")) # revealed: Unknown - | ^^^^^^^^^^^ `Unknown` - | - -``` - ``` error[invalid-argument-type]: Argument to function `f` is incorrect - --> src/mdtest_snippet.py:13:15 + --> src/mdtest_snippet.py:12:15 | -11 | reveal_type(f(None)) # revealed: None -12 | # error: [invalid-argument-type] -13 | reveal_type(f("string")) # revealed: Unknown +10 | reveal_type(f(None)) # revealed: None +11 | # error: [invalid-argument-type] +12 | reveal_type(f("string")) # revealed: Unknown | ^^^^^^^^ Argument type `Literal["string"]` does not satisfy constraints (`int`, `None`) of type variable `T` | info: Type variable defined here - --> src/mdtest_snippet.py:4:1 + --> src/mdtest_snippet.py:3:1 | -2 | from typing_extensions import reveal_type -3 | -4 | T = TypeVar("T", int, None) +1 | from typing import TypeVar +2 | +3 | T = TypeVar("T", int, None) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -5 | -6 | def f(x: T) -> T: +4 | +5 | def f(x: T) -> T: | info: rule `invalid-argument-type` is enabled by default diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_bound_ty…_(5935d14c26afe407).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_bound_ty…_(5935d14c26afe407).snap index a4dd346d6c..4ee7b9d656 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_bound_ty…_(5935d14c26afe407).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_bound_ty…_(5935d14c26afe407).snap @@ -25,45 +25,6 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/pep695/function # Diagnostics -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:6:13 - | -4 | return x -5 | -6 | reveal_type(f(1)) # revealed: Literal[1] - | ^^^^ `Literal[1]` -7 | reveal_type(f(True)) # revealed: Literal[True] -8 | # error: [invalid-argument-type] - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:7:13 - | -6 | reveal_type(f(1)) # revealed: Literal[1] -7 | reveal_type(f(True)) # revealed: Literal[True] - | ^^^^^^^ `Literal[True]` -8 | # error: [invalid-argument-type] -9 | reveal_type(f("string")) # revealed: Unknown - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:9:13 - | -7 | reveal_type(f(True)) # revealed: Literal[True] -8 | # error: [invalid-argument-type] -9 | reveal_type(f("string")) # revealed: Unknown - | ^^^^^^^^^^^ `Unknown` - | - -``` - ``` error[invalid-argument-type]: Argument to function `f` is incorrect --> src/mdtest_snippet.py:9:15 diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_constrai…_(d2c475fccc70a8e2).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_constrai…_(d2c475fccc70a8e2).snap index 24ef2ebfb0..36c8170f75 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_constrai…_(d2c475fccc70a8e2).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/functions.md_-_Generic_functions___P…_-_Inferring_a_constrai…_(d2c475fccc70a8e2).snap @@ -26,59 +26,6 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/pep695/function # Diagnostics -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:6:13 - | -4 | return x -5 | -6 | reveal_type(f(1)) # revealed: int - | ^^^^ `int` -7 | reveal_type(f(True)) # revealed: int -8 | reveal_type(f(None)) # revealed: None - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:7:13 - | -6 | reveal_type(f(1)) # revealed: int -7 | reveal_type(f(True)) # revealed: int - | ^^^^^^^ `int` -8 | reveal_type(f(None)) # revealed: None -9 | # error: [invalid-argument-type] - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:8:13 - | - 6 | reveal_type(f(1)) # revealed: int - 7 | reveal_type(f(True)) # revealed: int - 8 | reveal_type(f(None)) # revealed: None - | ^^^^^^^ `None` - 9 | # error: [invalid-argument-type] -10 | reveal_type(f("string")) # revealed: Unknown - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:10:13 - | - 8 | reveal_type(f(None)) # revealed: None - 9 | # error: [invalid-argument-type] -10 | reveal_type(f("string")) # revealed: Unknown - | ^^^^^^^^^^^ `Unknown` - | - -``` - ``` error[invalid-argument-type]: Argument to function `f` is incorrect --> src/mdtest_snippet.py:10:15 diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_includes…_(d2532518c44112c8).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_includes…_(d2532518c44112c8).snap index 1b60443d4d..ecdcac656c 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_includes…_(d2532518c44112c8).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_includes…_(d2532518c44112c8).snap @@ -12,67 +12,39 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/mro.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type - 2 | - 3 | def returns_bool() -> bool: - 4 | return True - 5 | - 6 | class A: ... - 7 | class B: ... - 8 | - 9 | if returns_bool(): -10 | x = A -11 | else: -12 | x = B + 1 | def returns_bool() -> bool: + 2 | return True + 3 | + 4 | class A: ... + 5 | class B: ... + 6 | + 7 | if returns_bool(): + 8 | x = A + 9 | else: +10 | x = B +11 | +12 | reveal_type(x) # revealed: | 13 | -14 | reveal_type(x) # revealed: | -15 | -16 | # error: 11 [unsupported-base] "Unsupported class base with type ` | `" -17 | class Foo(x): ... -18 | -19 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] +14 | # error: 11 [unsupported-base] "Unsupported class base with type ` | `" +15 | class Foo(x): ... +16 | +17 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] ``` # Diagnostics -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:14:13 - | -12 | x = B -13 | -14 | reveal_type(x) # revealed: | - | ^ ` | ` -15 | -16 | # error: 11 [unsupported-base] "Unsupported class base with type ` | `" - | - -``` - ``` warning[unsupported-base]: Unsupported class base with type ` | ` - --> src/mdtest_snippet.py:17:11 + --> src/mdtest_snippet.py:15:11 | -16 | # error: 11 [unsupported-base] "Unsupported class base with type ` | `" -17 | class Foo(x): ... +14 | # error: 11 [unsupported-base] "Unsupported class base with type ` | `" +15 | class Foo(x): ... | ^ -18 | -19 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] +16 | +17 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] | info: ty cannot resolve a consistent MRO for class `Foo` due to this base info: Only class objects or `Any` are supported as class bases info: rule `unsupported-base` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:19:13 - | -17 | class Foo(x): ... -18 | -19 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] - | ^^^^^^^^^^^ `tuple[, Unknown, ]` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_lists_wi…_(ea7ebc83ec359b54).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_lists_wi…_(ea7ebc83ec359b54).snap index fceb6462c8..4f216ab4a8 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_lists_wi…_(ea7ebc83ec359b54).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/mro.md_-_Method_Resolution_Or…_-_`__bases__`_lists_wi…_(ea7ebc83ec359b54).snap @@ -12,167 +12,147 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/mro.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import reveal_type + 1 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" 2 | - 3 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" + 3 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] 4 | - 5 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] - 6 | - 7 | class Spam: ... - 8 | class Eggs: ... - 9 | class Bar: ... -10 | class Baz: ... + 5 | class Spam: ... + 6 | class Eggs: ... + 7 | class Bar: ... + 8 | class Baz: ... + 9 | +10 | # fmt: off 11 | -12 | # fmt: off -13 | -14 | # error: [duplicate-base] "Duplicate base class `Spam`" -15 | # error: [duplicate-base] "Duplicate base class `Eggs`" -16 | class Ham( -17 | Spam, -18 | Eggs, -19 | Bar, -20 | Baz, -21 | Spam, -22 | Eggs, -23 | ): ... +12 | # error: [duplicate-base] "Duplicate base class `Spam`" +13 | # error: [duplicate-base] "Duplicate base class `Eggs`" +14 | class Ham( +15 | Spam, +16 | Eggs, +17 | Bar, +18 | Baz, +19 | Spam, +20 | Eggs, +21 | ): ... +22 | +23 | # fmt: on 24 | -25 | # fmt: on +25 | reveal_type(Ham.__mro__) # revealed: tuple[, Unknown, ] 26 | -27 | reveal_type(Ham.__mro__) # revealed: tuple[, Unknown, ] -28 | -29 | class Mushrooms: ... -30 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] +27 | class Mushrooms: ... +28 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] +29 | +30 | reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] 31 | -32 | reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] +32 | # fmt: off 33 | -34 | # fmt: off -35 | -36 | # error: [duplicate-base] "Duplicate base class `Eggs`" -37 | class VeryEggyOmelette( -38 | Eggs, -39 | Ham, -40 | Spam, -41 | Eggs, -42 | Mushrooms, -43 | Bar, +34 | # error: [duplicate-base] "Duplicate base class `Eggs`" +35 | class VeryEggyOmelette( +36 | Eggs, +37 | Ham, +38 | Spam, +39 | Eggs, +40 | Mushrooms, +41 | Bar, +42 | Eggs, +43 | Baz, 44 | Eggs, -45 | Baz, -46 | Eggs, -47 | ): ... -48 | -49 | # fmt: off -50 | # fmt: off +45 | ): ... +46 | +47 | # fmt: off +48 | # fmt: off +49 | +50 | class A: ... 51 | -52 | class A: ... -53 | -54 | class B( # type: ignore[duplicate-base] -55 | A, -56 | A, -57 | ): ... -58 | -59 | class C( -60 | A, -61 | A -62 | ): # type: ignore[duplicate-base] -63 | x: int -64 | -65 | # fmt: on -66 | # fmt: off -67 | -68 | # error: [duplicate-base] -69 | class D( -70 | A, -71 | # error: [unused-ignore-comment] -72 | A, # type: ignore[duplicate-base] -73 | ): ... -74 | -75 | # error: [duplicate-base] -76 | class E( -77 | A, -78 | A -79 | ): -80 | # error: [unused-ignore-comment] -81 | x: int # type: ignore[duplicate-base] -82 | -83 | # fmt: on +52 | class B( # type: ignore[duplicate-base] +53 | A, +54 | A, +55 | ): ... +56 | +57 | class C( +58 | A, +59 | A +60 | ): # type: ignore[duplicate-base] +61 | x: int +62 | +63 | # fmt: on +64 | # fmt: off +65 | +66 | # error: [duplicate-base] +67 | class D( +68 | A, +69 | # error: [unused-ignore-comment] +70 | A, # type: ignore[duplicate-base] +71 | ): ... +72 | +73 | # error: [duplicate-base] +74 | class E( +75 | A, +76 | A +77 | ): +78 | # error: [unused-ignore-comment] +79 | x: int # type: ignore[duplicate-base] +80 | +81 | # fmt: on ``` # Diagnostics ``` error[duplicate-base]: Duplicate base class `str` - --> src/mdtest_snippet.py:3:7 + --> src/mdtest_snippet.py:1:7 | -1 | from typing_extensions import reveal_type -2 | -3 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" +1 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" | ^^^^^^^^^^^^^ -4 | -5 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] +2 | +3 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] | info: The definition of class `Foo` will raise `TypeError` at runtime - --> src/mdtest_snippet.py:3:11 + --> src/mdtest_snippet.py:1:11 | -1 | from typing_extensions import reveal_type -2 | -3 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" +1 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" | --- ^^^ Class `str` later repeated here | | | Class `str` first included in bases list here -4 | -5 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] +2 | +3 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] | info: rule `duplicate-base` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:5:13 - | -3 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" -4 | -5 | reveal_type(Foo.__mro__) # revealed: tuple[, Unknown, ] - | ^^^^^^^^^^^ `tuple[, Unknown, ]` -6 | -7 | class Spam: ... - | - -``` - ``` error[duplicate-base]: Duplicate base class `Spam` - --> src/mdtest_snippet.py:16:7 + --> src/mdtest_snippet.py:14:7 | -14 | # error: [duplicate-base] "Duplicate base class `Spam`" -15 | # error: [duplicate-base] "Duplicate base class `Eggs`" -16 | class Ham( +12 | # error: [duplicate-base] "Duplicate base class `Spam`" +13 | # error: [duplicate-base] "Duplicate base class `Eggs`" +14 | class Ham( | _______^ -17 | | Spam, -18 | | Eggs, -19 | | Bar, -20 | | Baz, -21 | | Spam, -22 | | Eggs, -23 | | ): ... +15 | | Spam, +16 | | Eggs, +17 | | Bar, +18 | | Baz, +19 | | Spam, +20 | | Eggs, +21 | | ): ... | |_^ -24 | -25 | # fmt: on +22 | +23 | # fmt: on | info: The definition of class `Ham` will raise `TypeError` at runtime - --> src/mdtest_snippet.py:17:5 + --> src/mdtest_snippet.py:15:5 | -15 | # error: [duplicate-base] "Duplicate base class `Eggs`" -16 | class Ham( -17 | Spam, +13 | # error: [duplicate-base] "Duplicate base class `Eggs`" +14 | class Ham( +15 | Spam, | ---- Class `Spam` first included in bases list here -18 | Eggs, -19 | Bar, -20 | Baz, -21 | Spam, +16 | Eggs, +17 | Bar, +18 | Baz, +19 | Spam, | ^^^^ Class `Spam` later repeated here -22 | Eggs, -23 | ): ... +20 | Eggs, +21 | ): ... | info: rule `duplicate-base` is enabled by default @@ -180,134 +160,106 @@ info: rule `duplicate-base` is enabled by default ``` error[duplicate-base]: Duplicate base class `Eggs` - --> src/mdtest_snippet.py:16:7 + --> src/mdtest_snippet.py:14:7 | -14 | # error: [duplicate-base] "Duplicate base class `Spam`" -15 | # error: [duplicate-base] "Duplicate base class `Eggs`" -16 | class Ham( +12 | # error: [duplicate-base] "Duplicate base class `Spam`" +13 | # error: [duplicate-base] "Duplicate base class `Eggs`" +14 | class Ham( | _______^ -17 | | Spam, -18 | | Eggs, -19 | | Bar, -20 | | Baz, -21 | | Spam, -22 | | Eggs, -23 | | ): ... +15 | | Spam, +16 | | Eggs, +17 | | Bar, +18 | | Baz, +19 | | Spam, +20 | | Eggs, +21 | | ): ... | |_^ -24 | -25 | # fmt: on +22 | +23 | # fmt: on | info: The definition of class `Ham` will raise `TypeError` at runtime - --> src/mdtest_snippet.py:18:5 + --> src/mdtest_snippet.py:16:5 | -16 | class Ham( -17 | Spam, -18 | Eggs, +14 | class Ham( +15 | Spam, +16 | Eggs, | ---- Class `Eggs` first included in bases list here -19 | Bar, -20 | Baz, -21 | Spam, -22 | Eggs, +17 | Bar, +18 | Baz, +19 | Spam, +20 | Eggs, | ^^^^ Class `Eggs` later repeated here -23 | ): ... +21 | ): ... | info: rule `duplicate-base` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:27:13 - | -25 | # fmt: on -26 | -27 | reveal_type(Ham.__mro__) # revealed: tuple[, Unknown, ] - | ^^^^^^^^^^^ `tuple[, Unknown, ]` -28 | -29 | class Mushrooms: ... - | - -``` - ``` error[duplicate-base]: Duplicate base class `Mushrooms` - --> src/mdtest_snippet.py:30:7 + --> src/mdtest_snippet.py:28:7 | -29 | class Mushrooms: ... -30 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] +27 | class Mushrooms: ... +28 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -31 | -32 | reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] +29 | +30 | reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] | info: The definition of class `Omelette` will raise `TypeError` at runtime - --> src/mdtest_snippet.py:30:28 + --> src/mdtest_snippet.py:28:28 | -29 | class Mushrooms: ... -30 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] +27 | class Mushrooms: ... +28 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] | --------- ^^^^^^^^^ Class `Mushrooms` later repeated here | | | Class `Mushrooms` first included in bases list here -31 | -32 | reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] +29 | +30 | reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] | info: rule `duplicate-base` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:32:13 - | -30 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] -31 | -32 | reveal_type(Omelette.__mro__) # revealed: tuple[, Unknown, ] - | ^^^^^^^^^^^^^^^^ `tuple[, Unknown, ]` -33 | -34 | # fmt: off - | - -``` - ``` error[duplicate-base]: Duplicate base class `Eggs` - --> src/mdtest_snippet.py:37:7 + --> src/mdtest_snippet.py:35:7 | -36 | # error: [duplicate-base] "Duplicate base class `Eggs`" -37 | class VeryEggyOmelette( +34 | # error: [duplicate-base] "Duplicate base class `Eggs`" +35 | class VeryEggyOmelette( | _______^ -38 | | Eggs, -39 | | Ham, -40 | | Spam, -41 | | Eggs, -42 | | Mushrooms, -43 | | Bar, +36 | | Eggs, +37 | | Ham, +38 | | Spam, +39 | | Eggs, +40 | | Mushrooms, +41 | | Bar, +42 | | Eggs, +43 | | Baz, 44 | | Eggs, -45 | | Baz, -46 | | Eggs, -47 | | ): ... +45 | | ): ... | |_^ -48 | -49 | # fmt: off +46 | +47 | # fmt: off | info: The definition of class `VeryEggyOmelette` will raise `TypeError` at runtime - --> src/mdtest_snippet.py:38:5 + --> src/mdtest_snippet.py:36:5 | -36 | # error: [duplicate-base] "Duplicate base class `Eggs`" -37 | class VeryEggyOmelette( -38 | Eggs, +34 | # error: [duplicate-base] "Duplicate base class `Eggs`" +35 | class VeryEggyOmelette( +36 | Eggs, | ---- Class `Eggs` first included in bases list here -39 | Ham, -40 | Spam, -41 | Eggs, +37 | Ham, +38 | Spam, +39 | Eggs, | ^^^^ Class `Eggs` later repeated here -42 | Mushrooms, -43 | Bar, +40 | Mushrooms, +41 | Bar, +42 | Eggs, + | ^^^^ Class `Eggs` later repeated here +43 | Baz, 44 | Eggs, | ^^^^ Class `Eggs` later repeated here -45 | Baz, -46 | Eggs, - | ^^^^ Class `Eggs` later repeated here -47 | ): ... +45 | ): ... | info: rule `duplicate-base` is enabled by default @@ -315,30 +267,30 @@ info: rule `duplicate-base` is enabled by default ``` error[duplicate-base]: Duplicate base class `A` - --> src/mdtest_snippet.py:69:7 + --> src/mdtest_snippet.py:67:7 | -68 | # error: [duplicate-base] -69 | class D( +66 | # error: [duplicate-base] +67 | class D( | _______^ -70 | | A, -71 | | # error: [unused-ignore-comment] -72 | | A, # type: ignore[duplicate-base] -73 | | ): ... +68 | | A, +69 | | # error: [unused-ignore-comment] +70 | | A, # type: ignore[duplicate-base] +71 | | ): ... | |_^ -74 | -75 | # error: [duplicate-base] +72 | +73 | # error: [duplicate-base] | info: The definition of class `D` will raise `TypeError` at runtime - --> src/mdtest_snippet.py:70:5 + --> src/mdtest_snippet.py:68:5 | -68 | # error: [duplicate-base] -69 | class D( -70 | A, +66 | # error: [duplicate-base] +67 | class D( +68 | A, | - Class `A` first included in bases list here -71 | # error: [unused-ignore-comment] -72 | A, # type: ignore[duplicate-base] +69 | # error: [unused-ignore-comment] +70 | A, # type: ignore[duplicate-base] | ^ Class `A` later repeated here -73 | ): ... +71 | ): ... | info: rule `duplicate-base` is enabled by default @@ -346,42 +298,42 @@ info: rule `duplicate-base` is enabled by default ``` info[unused-ignore-comment] - --> src/mdtest_snippet.py:72:9 + --> src/mdtest_snippet.py:70:9 | -70 | A, -71 | # error: [unused-ignore-comment] -72 | A, # type: ignore[duplicate-base] +68 | A, +69 | # error: [unused-ignore-comment] +70 | A, # type: ignore[duplicate-base] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused blanket `type: ignore` directive -73 | ): ... +71 | ): ... | ``` ``` error[duplicate-base]: Duplicate base class `A` - --> src/mdtest_snippet.py:76:7 + --> src/mdtest_snippet.py:74:7 | -75 | # error: [duplicate-base] -76 | class E( +73 | # error: [duplicate-base] +74 | class E( | _______^ -77 | | A, -78 | | A -79 | | ): +75 | | A, +76 | | A +77 | | ): | |_^ -80 | # error: [unused-ignore-comment] -81 | x: int # type: ignore[duplicate-base] +78 | # error: [unused-ignore-comment] +79 | x: int # type: ignore[duplicate-base] | info: The definition of class `E` will raise `TypeError` at runtime - --> src/mdtest_snippet.py:77:5 + --> src/mdtest_snippet.py:75:5 | -75 | # error: [duplicate-base] -76 | class E( -77 | A, +73 | # error: [duplicate-base] +74 | class E( +75 | A, | - Class `A` first included in bases list here -78 | A +76 | A | ^ Class `A` later repeated here -79 | ): -80 | # error: [unused-ignore-comment] +77 | ): +78 | # error: [unused-ignore-comment] | info: rule `duplicate-base` is enabled by default @@ -389,14 +341,14 @@ info: rule `duplicate-base` is enabled by default ``` info[unused-ignore-comment] - --> src/mdtest_snippet.py:81:13 + --> src/mdtest_snippet.py:79:13 | -79 | ): -80 | # error: [unused-ignore-comment] -81 | x: int # type: ignore[duplicate-base] +77 | ): +78 | # error: [unused-ignore-comment] +79 | x: int # type: ignore[duplicate-base] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused blanket `type: ignore` directive -82 | -83 | # fmt: on +80 | +81 | # fmt: on | ``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/overloads.md_-_Overloads_-_Argument_type_expans…_-_Optimization___Limit_…_(cd61048adbc17331).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/overloads.md_-_Overloads_-_Argument_type_expans…_-_Optimization___Limit_…_(cd61048adbc17331).snap index cf278f4328..ae7b142691 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/overloads.md_-_Overloads_-_Argument_type_expans…_-_Optimization___Limit_…_(cd61048adbc17331).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/overloads.md_-_Overloads_-_Argument_type_expans…_-_Optimization___Limit_…_(cd61048adbc17331).snap @@ -136,48 +136,3 @@ info: (x: B, /, **kwargs: int) -> B info: rule `no-matching-overload` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:8:9 - | - 6 | # error: [no-matching-overload] - 7 | # revealed: Unknown - 8 | / f( - 9 | | A(), -10 | | a1=a, -11 | | a2=a, -12 | | a3=a, -13 | | a4=a, -14 | | a5=a, -15 | | a6=a, -16 | | a7=a, -17 | | a8=a, -18 | | a9=a, -19 | | a10=a, -20 | | a11=a, -21 | | a12=a, -22 | | a13=a, -23 | | a14=a, -24 | | a15=a, -25 | | a16=a, -26 | | a17=a, -27 | | a18=a, -28 | | a19=a, -29 | | a20=a, -30 | | a21=a, -31 | | a22=a, -32 | | a23=a, -33 | | a24=a, -34 | | a25=a, -35 | | a26=a, -36 | | a27=a, -37 | | a28=a, -38 | | a29=a, -39 | | a30=a, -40 | | ) - | |_________^ `Unknown` -41 | ) - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Calls_to_protocol_cl…_(288988036f34ddcf).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Calls_to_protocol_cl…_(288988036f34ddcf).snap index 923dac0803..4e18a85fd6 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Calls_to_protocol_cl…_(288988036f34ddcf).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Calls_to_protocol_cl…_(288988036f34ddcf).snap @@ -12,7 +12,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import Protocol, reveal_type + 1 | from typing_extensions import Protocol 2 | 3 | # error: [call-non-callable] 4 | reveal_type(Protocol()) # revealed: Unknown @@ -36,9 +36,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md 22 | 23 | reveal_type(SubclassOfGenericProtocol[int]()) # revealed: SubclassOfGenericProtocol[int] 24 | def f(x: type[MyProtocol]): -25 | # TODO: add a `reveal_type` call here once it's no longer a `Todo` type -26 | # (which doesn't work well with snapshots) -27 | x() +25 | reveal_type(x()) # revealed: @Todo(type[T] for protocols) ``` # Diagnostics @@ -57,19 +55,6 @@ info: rule `call-non-callable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:4:13 - | -3 | # error: [call-non-callable] -4 | reveal_type(Protocol()) # revealed: Unknown - | ^^^^^^^^^^ `Unknown` -5 | -6 | class MyProtocol(Protocol): - | - -``` - ``` error[call-non-callable]: Cannot instantiate class `MyProtocol` --> src/mdtest_snippet.py:10:13 @@ -93,19 +78,6 @@ info: rule `call-non-callable` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:10:13 - | - 9 | # error: [call-non-callable] "Cannot instantiate class `MyProtocol`" -10 | reveal_type(MyProtocol()) # revealed: MyProtocol - | ^^^^^^^^^^^^ `MyProtocol` -11 | -12 | class GenericProtocol[T](Protocol): - | - -``` - ``` error[call-non-callable]: Cannot instantiate class `GenericProtocol` --> src/mdtest_snippet.py:16:13 @@ -127,43 +99,3 @@ info: Protocol classes cannot be instantiated info: rule `call-non-callable` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:16:13 - | -15 | # error: [call-non-callable] "Cannot instantiate class `GenericProtocol`" -16 | reveal_type(GenericProtocol[int]()) # revealed: GenericProtocol[int] - | ^^^^^^^^^^^^^^^^^^^^^^ `GenericProtocol[int]` -17 | class SubclassOfMyProtocol(MyProtocol): ... - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:19:13 - | -17 | class SubclassOfMyProtocol(MyProtocol): ... -18 | -19 | reveal_type(SubclassOfMyProtocol()) # revealed: SubclassOfMyProtocol - | ^^^^^^^^^^^^^^^^^^^^^^ `SubclassOfMyProtocol` -20 | -21 | class SubclassOfGenericProtocol[T](GenericProtocol[T]): ... - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:23:13 - | -21 | class SubclassOfGenericProtocol[T](GenericProtocol[T]): ... -22 | -23 | reveal_type(SubclassOfGenericProtocol[int]()) # revealed: SubclassOfGenericProtocol[int] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SubclassOfGenericProtocol[int]` -24 | def f(x: type[MyProtocol]): -25 | # TODO: add a `reveal_type` call here once it's no longer a `Todo` type - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Narrowing_of_protoco…_(98257e7c2300373).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Narrowing_of_protoco…_(98257e7c2300373).snap index 65263835c3..1247edf089 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Narrowing_of_protoco…_(98257e7c2300373).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Narrowing_of_protoco…_(98257e7c2300373).snap @@ -12,7 +12,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md ## mdtest_snippet.py ``` - 1 | from typing_extensions import Protocol, reveal_type + 1 | from typing_extensions import Protocol 2 | 3 | class HasX(Protocol): 4 | x: int @@ -69,7 +69,7 @@ error[invalid-argument-type]: Class `HasX` cannot be used as the second argument info: `HasX` is declared as a protocol class, but it is not declared as runtime-checkable --> src/mdtest_snippet.py:3:7 | -1 | from typing_extensions import Protocol, reveal_type +1 | from typing_extensions import Protocol 2 | 3 | class HasX(Protocol): | ^^^^^^^^^^^^^^ `HasX` declared here @@ -81,34 +81,6 @@ info: rule `invalid-argument-type` is enabled by default ``` -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:8:21 - | - 6 | def f(arg: object, arg2: type): - 7 | if isinstance(arg, HasX): # error: [invalid-argument-type] - 8 | reveal_type(arg) # revealed: HasX - | ^^^ `HasX` - 9 | else: -10 | reveal_type(arg) # revealed: ~HasX - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:10:21 - | - 8 | reveal_type(arg) # revealed: HasX - 9 | else: -10 | reveal_type(arg) # revealed: ~HasX - | ^^^ `~HasX` -11 | -12 | if issubclass(arg2, HasX): # error: [invalid-argument-type] - | - -``` - ``` error[invalid-argument-type]: Class `HasX` cannot be used as the second argument to `issubclass` --> src/mdtest_snippet.py:12:8 @@ -123,7 +95,7 @@ error[invalid-argument-type]: Class `HasX` cannot be used as the second argument info: `HasX` is declared as a protocol class, but it is not declared as runtime-checkable --> src/mdtest_snippet.py:3:7 | -1 | from typing_extensions import Protocol, reveal_type +1 | from typing_extensions import Protocol 2 | 3 | class HasX(Protocol): | ^^^^^^^^^^^^^^ `HasX` declared here @@ -134,110 +106,3 @@ info: See https://docs.python.org/3/library/typing.html#typing.runtime_checkable info: rule `invalid-argument-type` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:13:21 - | -12 | if issubclass(arg2, HasX): # error: [invalid-argument-type] -13 | reveal_type(arg2) # revealed: type[HasX] - | ^^^^ `type[HasX]` -14 | else: -15 | reveal_type(arg2) # revealed: type & ~type[HasX] - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:15:21 - | -13 | reveal_type(arg2) # revealed: type[HasX] -14 | else: -15 | reveal_type(arg2) # revealed: type & ~type[HasX] - | ^^^^ `type & ~type[HasX]` -16 | from typing import runtime_checkable - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:24:21 - | -22 | def f(arg: object): -23 | if isinstance(arg, RuntimeCheckableHasX): # no error! -24 | reveal_type(arg) # revealed: RuntimeCheckableHasX - | ^^^ `RuntimeCheckableHasX` -25 | else: -26 | reveal_type(arg) # revealed: ~RuntimeCheckableHasX - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:26:21 - | -24 | reveal_type(arg) # revealed: RuntimeCheckableHasX -25 | else: -26 | reveal_type(arg) # revealed: ~RuntimeCheckableHasX - | ^^^ `~RuntimeCheckableHasX` -27 | @runtime_checkable -28 | class OnlyMethodMembers(Protocol): - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:33:21 - | -31 | def f(arg1: type, arg2: type): -32 | if issubclass(arg1, RuntimeCheckableHasX): # TODO: should emit an error here (has non-method members) -33 | reveal_type(arg1) # revealed: type[RuntimeCheckableHasX] - | ^^^^ `type[RuntimeCheckableHasX]` -34 | else: -35 | reveal_type(arg1) # revealed: type & ~type[RuntimeCheckableHasX] - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:35:21 - | -33 | reveal_type(arg1) # revealed: type[RuntimeCheckableHasX] -34 | else: -35 | reveal_type(arg1) # revealed: type & ~type[RuntimeCheckableHasX] - | ^^^^ `type & ~type[RuntimeCheckableHasX]` -36 | -37 | if issubclass(arg2, OnlyMethodMembers): # no error! - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:38:21 - | -37 | if issubclass(arg2, OnlyMethodMembers): # no error! -38 | reveal_type(arg2) # revealed: type[OnlyMethodMembers] - | ^^^^ `type[OnlyMethodMembers]` -39 | else: -40 | reveal_type(arg2) # revealed: type & ~type[OnlyMethodMembers] - | - -``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:40:21 - | -38 | reveal_type(arg2) # revealed: type[OnlyMethodMembers] -39 | else: -40 | reveal_type(arg2) # revealed: type & ~type[OnlyMethodMembers] - | ^^^^ `type & ~type[OnlyMethodMembers]` - | - -``` diff --git a/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Protocol_members_in_…_(21be5d9bdab1c844).snap b/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Protocol_members_in_…_(21be5d9bdab1c844).snap index d7436cbec7..28599faa0c 100644 --- a/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Protocol_members_in_…_(21be5d9bdab1c844).snap +++ b/crates/ty_python_semantic/resources/mdtest/snapshots/protocols.md_-_Protocols_-_Protocol_members_in_…_(21be5d9bdab1c844).snap @@ -13,7 +13,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md ``` 1 | import sys - 2 | from typing_extensions import Protocol, get_protocol_members, reveal_type + 2 | from typing_extensions import Protocol, get_protocol_members 3 | 4 | class Foo(Protocol): 5 | if sys.version_info >= (3, 10): @@ -43,7 +43,7 @@ warning[ambiguous-protocol-member]: Cannot assign to undeclared variable in the info: Assigning to an undeclared variable in a protocol class leads to an ambiguous interface --> src/mdtest_snippet.py:4:7 | -2 | from typing_extensions import Protocol, get_protocol_members, reveal_type +2 | from typing_extensions import Protocol, get_protocol_members 3 | 4 | class Foo(Protocol): | ^^^^^^^^^^^^^ `Foo` declared as a protocol here @@ -54,15 +54,3 @@ info: No declarations found for `e` in the body of `Foo` or any of its superclas info: rule `ambiguous-protocol-member` is enabled by default ``` - -``` -info[revealed-type]: Revealed type - --> src/mdtest_snippet.py:14:13 - | -12 | def f(self) -> None: ... -13 | -14 | reveal_type(get_protocol_members(Foo)) # revealed: frozenset[Literal["d", "e", "f"]] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ `frozenset[Literal["d", "e", "f"]]` - | - -``` diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index c8c1965bcc..894ef87710 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -21,8 +21,8 @@ use type_ordering::union_or_intersection_elements_ordering; pub(crate) use self::builder::{IntersectionBuilder, UnionBuilder}; pub use self::cyclic::CycleDetector; pub(crate) use self::cyclic::{PairVisitor, TypeTransformer}; -pub use self::diagnostic::TypeCheckDiagnostics; pub(crate) use self::diagnostic::register_lints; +pub use self::diagnostic::{TypeCheckDiagnostics, UNDEFINED_REVEAL}; pub(crate) use self::infer::{ TypeContext, infer_deferred_types, infer_definition_types, infer_expression_type, infer_expression_types, infer_isolated_expression, infer_scope_types, diff --git a/crates/ty_python_semantic/src/types/diagnostic.rs b/crates/ty_python_semantic/src/types/diagnostic.rs index 1b38ecd1f3..f208ae3f5d 100644 --- a/crates/ty_python_semantic/src/types/diagnostic.rs +++ b/crates/ty_python_semantic/src/types/diagnostic.rs @@ -1568,7 +1568,7 @@ declare_lint! { /// ```python /// reveal_type(1) # NameError: name 'reveal_type' is not defined /// ``` - pub(crate) static UNDEFINED_REVEAL = { + pub static UNDEFINED_REVEAL = { summary: "detects usages of `reveal_type` without importing it", status: LintStatus::preview("1.0.0"), default_level: Level::Warn, diff --git a/crates/ty_test/src/lib.rs b/crates/ty_test/src/lib.rs index 8b03002b20..611fbbd6bf 100644 --- a/crates/ty_test/src/lib.rs +++ b/crates/ty_test/src/lib.rs @@ -6,7 +6,7 @@ use colored::Colorize; use config::SystemKind; use parser as test_parser; use ruff_db::Db as _; -use ruff_db::diagnostic::{Diagnostic, DisplayDiagnosticConfig}; +use ruff_db::diagnostic::{Diagnostic, DiagnosticId, DisplayDiagnosticConfig}; use ruff_db::files::{File, FileRootKind, system_path_to_file}; use ruff_db::panic::catch_unwind; use ruff_db::parsed::parsed_module; @@ -16,7 +16,7 @@ use ruff_source_file::{LineIndex, OneIndexed}; use std::backtrace::BacktraceStatus; use std::fmt::Write; use ty_python_semantic::pull_types::pull_types; -use ty_python_semantic::types::check_types; +use ty_python_semantic::types::{UNDEFINED_REVEAL, check_types}; use ty_python_semantic::{ Module, Program, ProgramSettings, PythonEnvironment, PythonPlatform, PythonVersionSource, PythonVersionWithSource, SearchPath, SearchPathSettings, SysPrefixPathOrigin, list_modules, @@ -377,8 +377,14 @@ fn run_test( by_line: line_failures, }), }; + + // Filter out `revealed-type` and `undefined-reveal` diagnostics from snapshots, + // since they make snapshots very noisy! if test.should_snapshot_diagnostics() { - snapshot_diagnostics.extend(diagnostics); + snapshot_diagnostics.extend(diagnostics.into_iter().filter(|diagnostic| { + diagnostic.id() != DiagnosticId::RevealedType + && !diagnostic.id().is_lint_named(&UNDEFINED_REVEAL.name()) + })); } failure