[ty] Filter out `revealed-type` and `undefined-reveal` diagnostics from mdtest snapshots (#20820)

This commit is contained in:
Alex Waygood 2025-10-12 19:39:32 +01:00 committed by GitHub
parent dc64c08633
commit 7064c38e53
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 849 additions and 1900 deletions

View File

@ -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. call should be reported directly and not as a `no-matching-overload` error.
```py ```py
from typing_extensions import reveal_type
from overloaded import f from overloaded import f
reveal_type(f()) # revealed: None reveal_type(f()) # revealed: None

View File

@ -1010,7 +1010,6 @@ python-version = "3.10"
```py ```py
from dataclasses import dataclass, field, KW_ONLY from dataclasses import dataclass, field, KW_ONLY
from typing_extensions import reveal_type
@dataclass @dataclass
class C: class C:

View File

@ -3,8 +3,6 @@
## Invalid syntax ## Invalid syntax
```py ```py
from typing_extensions import reveal_type
try: try:
print print
except as e: # error: [invalid-syntax] except as e: # error: [invalid-syntax]

View File

@ -181,7 +181,6 @@ reveal_type(takes_homogeneous_tuple((42, 43))) # revealed: Literal[42, 43]
```py ```py
from typing import TypeVar from typing import TypeVar
from typing_extensions import reveal_type
T = TypeVar("T", bound=int) T = TypeVar("T", bound=int)
@ -200,7 +199,6 @@ reveal_type(f("string")) # revealed: Unknown
```py ```py
from typing import TypeVar from typing import TypeVar
from typing_extensions import reveal_type
T = TypeVar("T", int, None) T = TypeVar("T", int, None)

View File

@ -5,8 +5,6 @@ all members available on a given type. This routine is used for autocomplete sug
## Basic functionality ## Basic functionality
<!-- snapshot-diagnostics -->
The `ty_extensions.all_members` and `ty_extensions.has_member` functions expose a Python-level API 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 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 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: `all_members` to see them all:
```py ```py
from typing_extensions import reveal_type
from ty_extensions import all_members 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 ## Kinds of types

View File

@ -42,8 +42,6 @@ async def foo():
### No `__aiter__` method ### No `__aiter__` method
```py ```py
from typing_extensions import reveal_type
class NotAsyncIterable: ... class NotAsyncIterable: ...
async def foo(): async def foo():
@ -55,8 +53,6 @@ async def foo():
### Synchronously iterable, but not asynchronously iterable ### Synchronously iterable, but not asynchronously iterable
```py ```py
from typing_extensions import reveal_type
async def foo(): async def foo():
class Iterator: class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
@ -74,8 +70,6 @@ async def foo():
### No `__anext__` method ### No `__anext__` method
```py ```py
from typing_extensions import reveal_type
class NoAnext: ... class NoAnext: ...
class AsyncIterable: class AsyncIterable:
@ -91,8 +85,6 @@ async def foo():
### Possibly missing `__anext__` method ### Possibly missing `__anext__` method
```py ```py
from typing_extensions import reveal_type
async def foo(flag: bool): async def foo(flag: bool):
class PossiblyUnboundAnext: class PossiblyUnboundAnext:
if flag: if flag:
@ -111,8 +103,6 @@ async def foo(flag: bool):
### Possibly missing `__aiter__` method ### Possibly missing `__aiter__` method
```py ```py
from typing_extensions import reveal_type
async def foo(flag: bool): async def foo(flag: bool):
class AsyncIterable: class AsyncIterable:
async def __anext__(self) -> int: async def __anext__(self) -> int:
@ -131,8 +121,6 @@ async def foo(flag: bool):
### Wrong signature for `__aiter__` ### Wrong signature for `__aiter__`
```py ```py
from typing_extensions import reveal_type
class AsyncIterator: class AsyncIterator:
async def __anext__(self) -> int: async def __anext__(self) -> int:
return 42 return 42
@ -150,8 +138,6 @@ async def foo():
### Wrong signature for `__anext__` ### Wrong signature for `__anext__`
```py ```py
from typing_extensions import reveal_type
class AsyncIterator: class AsyncIterator:
async def __anext__(self, arg: int) -> int: # wrong async def __anext__(self, arg: int) -> int: # wrong
return 42 return 42

View File

@ -108,8 +108,6 @@ reveal_type(x)
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
def _(flag: bool): def _(flag: bool):
class NotIterable: class NotIterable:
if flag: if flag:
@ -271,8 +269,6 @@ def g(
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class TestIter: class TestIter:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
@ -292,8 +288,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class TestIter: class TestIter:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
@ -370,8 +364,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Iterator: class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
@ -390,8 +382,6 @@ for x in Iterable():
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Bad: class Bad:
def __iter__(self) -> int: def __iter__(self) -> int:
return 42 return 42
@ -424,8 +414,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Iterator1: class Iterator1:
def __next__(self, extra_arg) -> int: def __next__(self, extra_arg) -> int:
return 42 return 42
@ -455,8 +443,6 @@ for y in Iterable2():
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
def _(flag: bool): def _(flag: bool):
class Iterator: class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
@ -509,8 +495,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Iterator: class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
@ -534,8 +518,6 @@ def _(flag1: bool, flag2: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Bad: class Bad:
__getitem__: None = None __getitem__: None = None
@ -549,8 +531,6 @@ for x in Bad():
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
def _(flag: bool): def _(flag: bool):
class CustomCallable: class CustomCallable:
if flag: if flag:
@ -585,8 +565,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Iterable: class Iterable:
# invalid because it will implicitly be passed an `int` # invalid because it will implicitly be passed an `int`
# by the interpreter # by the interpreter
@ -626,8 +604,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Iterator: class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
@ -663,8 +639,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
def _(flag: bool): def _(flag: bool):
class Iterator1: class Iterator1:
if flag: if flag:
@ -704,8 +678,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
def _(flag: bool): def _(flag: bool):
class Iterable1: class Iterable1:
if flag: if flag:
@ -737,8 +709,6 @@ def _(flag: bool):
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Iterator: class Iterator:
def __next__(self) -> bytes: def __next__(self) -> bytes:
return b"foo" return b"foo"

View File

@ -241,8 +241,6 @@ find a union type in a class's bases, we infer the class's `__mro__` as being
`[<class>, Unknown, object]`, the same as for MROs that cause errors at runtime. `[<class>, Unknown, object]`, the same as for MROs that cause errors at runtime.
```py ```py
from typing_extensions import reveal_type
def returns_bool() -> bool: def returns_bool() -> bool:
return True return True
@ -391,8 +389,6 @@ class BadSub2(Bad2()): ... # error: [invalid-base]
<!-- snapshot-diagnostics --> <!-- snapshot-diagnostics -->
```py ```py
from typing_extensions import reveal_type
class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`"
reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>] reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>]

View File

@ -281,7 +281,7 @@ def _(x: Foo | Bar, flag: bool) -> None:
The `TypeIs` type remains effective across generic boundaries: The `TypeIs` type remains effective across generic boundaries:
```py ```py
from typing_extensions import TypeVar, reveal_type from typing_extensions import TypeVar
T = TypeVar("T") T = TypeVar("T")

View File

@ -347,7 +347,7 @@ python-version = "3.12"
``` ```
```py ```py
from typing_extensions import Protocol, reveal_type from typing_extensions import Protocol
# error: [call-non-callable] # error: [call-non-callable]
reveal_type(Protocol()) # revealed: Unknown reveal_type(Protocol()) # revealed: Unknown
@ -381,9 +381,7 @@ And as a corollary, `type[MyProtocol]` can also be called:
```py ```py
def f(x: type[MyProtocol]): def f(x: type[MyProtocol]):
# TODO: add a `reveal_type` call here once it's no longer a `Todo` type reveal_type(x()) # revealed: @Todo(type[T] for protocols)
# (which doesn't work well with snapshots)
x()
``` ```
## Members of a protocol ## Members of a protocol
@ -534,7 +532,7 @@ python-version = "3.9"
```py ```py
import sys import sys
from typing_extensions import Protocol, get_protocol_members, reveal_type from typing_extensions import Protocol, get_protocol_members
class Foo(Protocol): class Foo(Protocol):
if sys.version_info >= (3, 10): 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): type inside these branches (this matches the behavior of other type checkers):
```py ```py
from typing_extensions import Protocol, reveal_type from typing_extensions import Protocol
class HasX(Protocol): class HasX(Protocol):
x: int x: int

View File

@ -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"]]`
|
```

View File

@ -12,41 +12,27 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class NotAsyncIterable: ...
2 | 2 |
3 | class NotAsyncIterable: ... 3 | async def foo():
4 | 4 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable"
5 | async def foo(): 5 | async for x in NotAsyncIterable():
6 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable" 6 | reveal_type(x) # revealed: Unknown
7 | async for x in NotAsyncIterable():
8 | reveal_type(x) # revealed: Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `NotAsyncIterable` is not async-iterable 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(): 3 | async def foo():
6 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable" 4 | # error: [not-iterable] "Object of type `NotAsyncIterable` is not async-iterable"
7 | async for x in NotAsyncIterable(): 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: It has no `__aiter__` method
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,45 +12,31 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class NoAnext: ...
2 | 2 |
3 | class NoAnext: ... 3 | class AsyncIterable:
4 | 4 | def __aiter__(self) -> NoAnext:
5 | class AsyncIterable: 5 | return NoAnext()
6 | def __aiter__(self) -> NoAnext: 6 |
7 | return NoAnext() 7 | async def foo():
8 | 8 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable"
9 | async def foo(): 9 | async for x in AsyncIterable():
10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" 10 | reveal_type(x) # revealed: Unknown
11 | async for x in AsyncIterable():
12 | reveal_type(x) # revealed: Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `AsyncIterable` is not async-iterable 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(): 7 | async def foo():
10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" 8 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable"
11 | async for x in AsyncIterable(): 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: Its `__aiter__` method returns an object of type `NoAnext`, which has no `__anext__` method
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,47 +12,33 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | async def foo(flag: bool):
2 | 2 | class AsyncIterable:
3 | async def foo(flag: bool): 3 | async def __anext__(self) -> int:
4 | class AsyncIterable: 4 | return 42
5 | async def __anext__(self) -> int: 5 |
6 | return 42 6 | class PossiblyUnboundAiter:
7 | 7 | if flag:
8 | class PossiblyUnboundAiter: 8 | def __aiter__(self) -> AsyncIterable:
9 | if flag: 9 | return AsyncIterable()
10 | def __aiter__(self) -> AsyncIterable: 10 |
11 | return AsyncIterable() 11 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable"
12 | 12 | async for x in PossiblyUnboundAiter():
13 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable" 13 | reveal_type(x) # revealed: int
14 | async for x in PossiblyUnboundAiter():
15 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `PossiblyUnboundAiter` may not be async-iterable 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" 11 | # error: "Object of type `PossiblyUnboundAiter` may not be async-iterable"
14 | async for x in PossiblyUnboundAiter(): 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: Its `__aiter__` attribute (with type `bound method PossiblyUnboundAiter.__aiter__() -> AsyncIterable`) may not be callable
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,47 +12,33 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | async def foo(flag: bool):
2 | 2 | class PossiblyUnboundAnext:
3 | async def foo(flag: bool): 3 | if flag:
4 | class PossiblyUnboundAnext: 4 | async def __anext__(self) -> int:
5 | if flag: 5 | return 42
6 | async def __anext__(self) -> int: 6 |
7 | return 42 7 | class AsyncIterable:
8 | 8 | def __aiter__(self) -> PossiblyUnboundAnext:
9 | class AsyncIterable: 9 | return PossiblyUnboundAnext()
10 | def __aiter__(self) -> PossiblyUnboundAnext: 10 |
11 | return PossiblyUnboundAnext() 11 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable"
12 | 12 | async for x in AsyncIterable():
13 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable" 13 | reveal_type(x) # revealed: int
14 | async for x in AsyncIterable():
15 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `AsyncIterable` may not be async-iterable 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" 11 | # error: [not-iterable] "Object of type `AsyncIterable` may not be async-iterable"
14 | async for x in AsyncIterable(): 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: 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: 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`
|
```

View File

@ -12,46 +12,32 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | async def foo():
2 | 2 | class Iterator:
3 | async def foo(): 3 | def __next__(self) -> int:
4 | class Iterator: 4 | return 42
5 | def __next__(self) -> int: 5 |
6 | return 42 6 | class Iterable:
7 | 7 | def __iter__(self) -> Iterator:
8 | class Iterable: 8 | return Iterator()
9 | def __iter__(self) -> Iterator: 9 |
10 | return Iterator() 10 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable"
11 | 11 | async for x in Iterator():
12 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable" 12 | reveal_type(x) # revealed: Unknown
13 | async for x in Iterator():
14 | reveal_type(x) # revealed: Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterator` is not async-iterable 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" 10 | # error: [not-iterable] "Object of type `Iterator` is not async-iterable"
13 | async for x in Iterator(): 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: It has no `__aiter__` method
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,48 +12,34 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class AsyncIterator:
2 | 2 | async def __anext__(self, arg: int) -> int: # wrong
3 | class AsyncIterator: 3 | return 42
4 | async def __anext__(self, arg: int) -> int: # wrong 4 |
5 | return 42 5 | class AsyncIterable:
6 | 6 | def __aiter__(self) -> AsyncIterator:
7 | class AsyncIterable: 7 | return AsyncIterator()
8 | def __aiter__(self) -> AsyncIterator: 8 |
9 | return AsyncIterator() 9 | async def foo():
10 | 10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable"
11 | async def foo(): 11 | async for x in AsyncIterable():
12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" 12 | reveal_type(x) # revealed: int
13 | async for x in AsyncIterable():
14 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `AsyncIterable` is not async-iterable 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(): 9 | async def foo():
12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" 10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable"
13 | async for x in AsyncIterable(): 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: 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: Expected signature for `__anext__` is `def __anext__(self): ...`
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,48 +12,34 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/async_for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class AsyncIterator:
2 | 2 | async def __anext__(self) -> int:
3 | class AsyncIterator: 3 | return 42
4 | async def __anext__(self) -> int: 4 |
5 | return 42 5 | class AsyncIterable:
6 | 6 | def __aiter__(self, arg: int) -> AsyncIterator: # wrong
7 | class AsyncIterable: 7 | return AsyncIterator()
8 | def __aiter__(self, arg: int) -> AsyncIterator: # wrong 8 |
9 | return AsyncIterator() 9 | async def foo():
10 | 10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable"
11 | async def foo(): 11 | async for x in AsyncIterable():
12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" 12 | reveal_type(x) # revealed: int
13 | async for x in AsyncIterable():
14 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `AsyncIterable` is not async-iterable 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(): 9 | async def foo():
12 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable" 10 | # error: [not-iterable] "Object of type `AsyncIterable` is not async-iterable"
13 | async for x in AsyncIterable(): 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: Its `__aiter__` method has an invalid signature
info: Expected signature `def __aiter__(self): ...` info: Expected signature `def __aiter__(self): ...`
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -13,86 +13,71 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/dataclasses/dataclasses.
``` ```
1 | from dataclasses import dataclass, field, KW_ONLY 1 | from dataclasses import dataclass, field, KW_ONLY
2 | from typing_extensions import reveal_type 2 |
3 | 3 | @dataclass
4 | @dataclass 4 | class C:
5 | class C: 5 | x: int
6 | x: int 6 | _: KW_ONLY
7 | _: KW_ONLY 7 | y: str
8 | y: str 8 |
9 | 9 | reveal_type(C.__init__) # revealed: (self: C, x: int, *, y: str) -> None
10 | reveal_type(C.__init__) # revealed: (self: C, x: int, *, y: str) -> None 10 |
11 | 11 | # error: [missing-argument]
12 | # error: [missing-argument] 12 | # error: [too-many-positional-arguments]
13 | # error: [too-many-positional-arguments] 13 | C(3, "")
14 | C(3, "") 14 |
15 | 15 | C(3, y="")
16 | C(3, y="") 16 | @dataclass
17 | @dataclass 17 | class Fails: # error: [duplicate-kw-only]
18 | class Fails: # error: [duplicate-kw-only] 18 | a: int
19 | a: int 19 | b: KW_ONLY
20 | b: KW_ONLY 20 | c: str
21 | c: str 21 | d: KW_ONLY
22 | d: KW_ONLY 22 | e: bytes
23 | e: bytes 23 |
24 | 24 | reveal_type(Fails.__init__) # revealed: (self: Fails, a: int, *, c: str, e: bytes) -> None
25 | reveal_type(Fails.__init__) # revealed: (self: Fails, a: int, *, c: str, e: bytes) -> None 25 | def flag() -> bool:
26 | def flag() -> bool: 26 | return True
27 | return True 27 |
28 | 28 | @dataclass
29 | @dataclass 29 | class D: # error: [duplicate-kw-only]
30 | class D: # error: [duplicate-kw-only] 30 | x: int
31 | x: int 31 | _1: KW_ONLY
32 | _1: KW_ONLY 32 |
33 | 33 | if flag():
34 | if flag(): 34 | y: str
35 | y: str 35 | _2: KW_ONLY
36 | _2: KW_ONLY 36 | z: float
37 | z: float 37 | from dataclasses import dataclass, KW_ONLY
38 | from dataclasses import dataclass, KW_ONLY 38 |
39 | 39 | @dataclass
40 | @dataclass 40 | class D:
41 | class D: 41 | x: int
42 | x: int 42 | _: KW_ONLY
43 | _: KW_ONLY 43 | y: str
44 | y: str 44 |
45 | 45 | @dataclass
46 | @dataclass 46 | class E(D):
47 | class E(D): 47 | z: bytes
48 | z: bytes 48 |
49 | 49 | # This should work: x=1 (positional), z=b"foo" (positional), y="foo" (keyword-only)
50 | # This should work: x=1 (positional), z=b"foo" (positional), y="foo" (keyword-only) 50 | E(1, b"foo", y="foo")
51 | E(1, b"foo", y="foo") 51 |
52 | 52 | reveal_type(E.__init__) # revealed: (self: E, x: int, z: bytes, *, y: str) -> None
53 | reveal_type(E.__init__) # revealed: (self: E, x: int, z: bytes, *, y: str) -> None
``` ```
# Diagnostics # 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` 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] 11 | # error: [missing-argument]
13 | # error: [too-many-positional-arguments] 12 | # error: [too-many-positional-arguments]
14 | C(3, "") 13 | C(3, "")
| ^^^^^^^^ | ^^^^^^^^
15 | 14 |
16 | C(3, y="") 15 | C(3, y="")
| |
info: rule `missing-argument` is enabled by default 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 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] 11 | # error: [missing-argument]
13 | # error: [too-many-positional-arguments] 12 | # error: [too-many-positional-arguments]
14 | C(3, "") 13 | C(3, "")
| ^^ | ^^
15 | 14 |
16 | C(3, y="") 15 | C(3, y="")
| |
info: rule `too-many-positional-arguments` is enabled by default 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` 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="") 15 | C(3, y="")
17 | @dataclass 16 | @dataclass
18 | class Fails: # error: [duplicate-kw-only] 17 | class Fails: # error: [duplicate-kw-only]
| ^^^^^ | ^^^^^
19 | a: int 18 | a: int
20 | b: KW_ONLY 19 | b: KW_ONLY
| |
info: `KW_ONLY` fields: `b`, `d` info: `KW_ONLY` fields: `b`, `d`
info: rule `duplicate-kw-only` is enabled by default 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` 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 28 | @dataclass
30 | class D: # error: [duplicate-kw-only] 29 | class D: # error: [duplicate-kw-only]
| ^ | ^
31 | x: int 30 | x: int
32 | _1: KW_ONLY 31 | _1: KW_ONLY
| |
info: `KW_ONLY` fields: `_1`, `_2` info: `KW_ONLY` fields: `_1`, `_2`
info: rule `duplicate-kw-only` is enabled by default 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`
|
```

View File

@ -12,44 +12,30 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Iterable:
2 | 2 | # invalid because it will implicitly be passed an `int`
3 | class Iterable: 3 | # by the interpreter
4 | # invalid because it will implicitly be passed an `int` 4 | def __getitem__(self, key: str) -> int:
5 | # by the interpreter 5 | return 42
6 | def __getitem__(self, key: str) -> int: 6 |
7 | return 42 7 | # error: [not-iterable]
8 | 8 | for x in Iterable():
9 | # error: [not-iterable] 9 | reveal_type(x) # revealed: int
10 | for x in Iterable():
11 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable` is not iterable error[not-iterable]: Object of type `Iterable` is not iterable
--> src/mdtest_snippet.py:10:10 --> src/mdtest_snippet.py:8:10
| |
9 | # error: [not-iterable] 7 | # error: [not-iterable]
10 | for x in Iterable(): 8 | for x in Iterable():
| ^^^^^^^^^^ | ^^^^^^^^^^
11 | reveal_type(x) # revealed: int 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: 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: `__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: 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`
|
```

View File

@ -12,40 +12,26 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Bad:
2 | 2 | __getitem__: None = None
3 | class Bad: 3 |
4 | __getitem__: None = None 4 | # error: [not-iterable]
5 | 5 | for x in Bad():
6 | # error: [not-iterable] 6 | reveal_type(x) # revealed: Unknown
7 | for x in Bad():
8 | reveal_type(x) # revealed: Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Bad` is not iterable 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] 4 | # error: [not-iterable]
7 | for x in Bad(): 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: 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: 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`
|
```

View File

@ -12,48 +12,46 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | def _(flag: bool):
2 | 2 | class CustomCallable:
3 | def _(flag: bool): 3 | if flag:
4 | class CustomCallable: 4 | def __call__(self, *args, **kwargs) -> int:
5 | if flag: 5 | return 42
6 | def __call__(self, *args, **kwargs) -> int: 6 | else:
7 | return 42 7 | __call__: None = None
8 | else: 8 |
9 | __call__: None = None 9 | class Iterable1:
10 | 10 | __getitem__: CustomCallable = CustomCallable()
11 | class Iterable1: 11 |
12 | __getitem__: CustomCallable = CustomCallable() 12 | class Iterable2:
13 | 13 | if flag:
14 | class Iterable2: 14 | def __getitem__(self, key: int) -> int:
15 | if flag: 15 | return 42
16 | def __getitem__(self, key: int) -> int: 16 | else:
17 | return 42 17 | __getitem__: None = None
18 | else: 18 |
19 | __getitem__: None = None 19 | # error: [not-iterable]
20 | 20 | for x in Iterable1():
21 | # error: [not-iterable] 21 | # TODO... `int` might be ideal here?
22 | for x in Iterable1(): 22 | reveal_type(x) # revealed: int | Unknown
23 | # TODO... `int` might be ideal here? 23 |
24 | reveal_type(x) # revealed: int | Unknown 24 | # error: [not-iterable]
25 | 25 | for y in Iterable2():
26 | # error: [not-iterable] 26 | # TODO... `int` might be ideal here?
27 | for y in Iterable2(): 27 | reveal_type(y) # revealed: int | Unknown
28 | # TODO... `int` might be ideal here?
29 | reveal_type(y) # revealed: int | Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable1` may not be iterable 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] 19 | # error: [not-iterable]
22 | for x in Iterable1(): 20 | for x in Iterable1():
| ^^^^^^^^^^^ | ^^^^^^^^^^^
23 | # TODO... `int` might be ideal here? 21 | # TODO... `int` might be ideal here?
24 | reveal_type(x) # revealed: int | Unknown 22 | reveal_type(x) # revealed: int | Unknown
| |
info: It has no `__iter__` method and its `__getitem__` attribute is invalid info: It has no `__iter__` method and its `__getitem__` attribute is invalid
info: `__getitem__` has type `CustomCallable`, which is not callable 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 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] 24 | # error: [not-iterable]
27 | for y in Iterable2(): 25 | for y in Iterable2():
| ^^^^^^^^^^^ | ^^^^^^^^^^^
28 | # TODO... `int` might be ideal here? 26 | # TODO... `int` might be ideal here?
29 | reveal_type(y) # revealed: int | Unknown 27 | reveal_type(y) # revealed: int | Unknown
| |
info: It has no `__iter__` method and its `__getitem__` attribute is invalid 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: `__getitem__` has type `(bound method Iterable2.__getitem__(key: int) -> int) | None`, which is not callable
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,48 +12,46 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Iterator:
2 | 2 | def __next__(self) -> int:
3 | class Iterator: 3 | return 42
4 | def __next__(self) -> int: 4 |
5 | return 42 5 | def _(flag: bool):
6 | 6 | class Iterable1:
7 | def _(flag: bool): 7 | if flag:
8 | class Iterable1: 8 | def __iter__(self) -> Iterator:
9 | if flag: 9 | return Iterator()
10 | def __iter__(self) -> Iterator: 10 | else:
11 | return Iterator() 11 | def __iter__(self, invalid_extra_arg) -> Iterator:
12 | else: 12 | return Iterator()
13 | def __iter__(self, invalid_extra_arg) -> Iterator: 13 |
14 | return Iterator() 14 | # error: [not-iterable]
15 | 15 | for x in Iterable1():
16 | # error: [not-iterable] 16 | reveal_type(x) # revealed: int
17 | for x in Iterable1(): 17 |
18 | reveal_type(x) # revealed: int 18 | class Iterable2:
19 | 19 | if flag:
20 | class Iterable2: 20 | def __iter__(self) -> Iterator:
21 | if flag: 21 | return Iterator()
22 | def __iter__(self) -> Iterator: 22 | else:
23 | return Iterator() 23 | __iter__: None = None
24 | else: 24 |
25 | __iter__: None = None 25 | # error: [not-iterable]
26 | 26 | for x in Iterable2():
27 | # error: [not-iterable] 27 | # TODO: `int` would probably be better here:
28 | for x in Iterable2(): 28 | reveal_type(x) # revealed: int | Unknown
29 | # TODO: `int` would probably be better here:
30 | reveal_type(x) # revealed: int | Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable1` may not be iterable 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] 14 | # error: [not-iterable]
17 | for x in Iterable1(): 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: 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)` 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 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] 25 | # error: [not-iterable]
28 | for x in Iterable2(): 26 | for x in Iterable2():
| ^^^^^^^^^^^ | ^^^^^^^^^^^
29 | # TODO: `int` would probably be better here: 27 | # TODO: `int` would probably be better here:
30 | reveal_type(x) # revealed: int | Unknown 28 | reveal_type(x) # revealed: int | Unknown
| |
info: Its `__iter__` attribute (with type `(bound method Iterable2.__iter__() -> Iterator) | None`) may not be callable 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: 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`
|
```

View File

@ -12,45 +12,43 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | def _(flag: bool):
2 | 2 | class Iterable1:
3 | def _(flag: bool): 3 | if flag:
4 | class Iterable1: 4 | def __getitem__(self, item: int) -> str:
5 | if flag: 5 | return "foo"
6 | def __getitem__(self, item: int) -> str: 6 | else:
7 | return "foo" 7 | __getitem__: None = None
8 | else: 8 |
9 | __getitem__: None = None 9 | class Iterable2:
10 | 10 | if flag:
11 | class Iterable2: 11 | def __getitem__(self, item: int) -> str:
12 | if flag: 12 | return "foo"
13 | def __getitem__(self, item: int) -> str: 13 | else:
14 | return "foo" 14 | def __getitem__(self, item: str) -> int:
15 | else: 15 | return 42
16 | def __getitem__(self, item: str) -> int: 16 |
17 | return 42 17 | # error: [not-iterable]
18 | 18 | for x in Iterable1():
19 | # error: [not-iterable] 19 | # TODO: `str` might be better
20 | for x in Iterable1(): 20 | reveal_type(x) # revealed: str | Unknown
21 | # TODO: `str` might be better 21 |
22 | reveal_type(x) # revealed: str | Unknown 22 | # error: [not-iterable]
23 | 23 | for y in Iterable2():
24 | # error: [not-iterable] 24 | reveal_type(y) # revealed: str | int
25 | for y in Iterable2():
26 | reveal_type(y) # revealed: str | int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable1` may not be iterable 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] 17 | # error: [not-iterable]
20 | for x in Iterable1(): 18 | for x in Iterable1():
| ^^^^^^^^^^^ | ^^^^^^^^^^^
21 | # TODO: `str` might be better 19 | # TODO: `str` might be better
22 | reveal_type(x) # revealed: str | Unknown 20 | reveal_type(x) # revealed: str | Unknown
| |
info: It has no `__iter__` method and its `__getitem__` attribute is invalid 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 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 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] 22 | # error: [not-iterable]
25 | for y in Iterable2(): 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: 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: `__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: 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`
|
```

View File

@ -12,52 +12,50 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | def _(flag: bool):
2 | 2 | class Iterator1:
3 | def _(flag: bool): 3 | if flag:
4 | class Iterator1: 4 | def __next__(self) -> int:
5 | if flag: 5 | return 42
6 | def __next__(self) -> int: 6 | else:
7 | return 42 7 | def __next__(self, invalid_extra_arg) -> str:
8 | else: 8 | return "foo"
9 | def __next__(self, invalid_extra_arg) -> str: 9 |
10 | return "foo" 10 | class Iterator2:
11 | 11 | if flag:
12 | class Iterator2: 12 | def __next__(self) -> int:
13 | if flag: 13 | return 42
14 | def __next__(self) -> int: 14 | else:
15 | return 42 15 | __next__: None = None
16 | else: 16 |
17 | __next__: None = None 17 | class Iterable1:
18 | 18 | def __iter__(self) -> Iterator1:
19 | class Iterable1: 19 | return Iterator1()
20 | def __iter__(self) -> Iterator1: 20 |
21 | return Iterator1() 21 | class Iterable2:
22 | 22 | def __iter__(self) -> Iterator2:
23 | class Iterable2: 23 | return Iterator2()
24 | def __iter__(self) -> Iterator2: 24 |
25 | return Iterator2() 25 | # error: [not-iterable]
26 | 26 | for x in Iterable1():
27 | # error: [not-iterable] 27 | reveal_type(x) # revealed: int | str
28 | for x in Iterable1(): 28 |
29 | reveal_type(x) # revealed: int | str 29 | # error: [not-iterable]
30 | 30 | for y in Iterable2():
31 | # error: [not-iterable] 31 | # TODO: `int` would probably be better here:
32 | for y in Iterable2(): 32 | reveal_type(y) # revealed: int | Unknown
33 | # TODO: `int` would probably be better here:
34 | reveal_type(y) # revealed: int | Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable1` may not be iterable 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] 25 | # error: [not-iterable]
28 | for x in Iterable1(): 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: 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): ...` 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 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] 29 | # error: [not-iterable]
32 | for y in Iterable2(): 30 | for y in Iterable2():
| ^^^^^^^^^^^ | ^^^^^^^^^^^
33 | # TODO: `int` would probably be better here: 31 | # TODO: `int` would probably be better here:
34 | reveal_type(y) # revealed: int | Unknown 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: 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: 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`
|
```

View File

@ -12,99 +12,71 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Iterator:
2 | 2 | def __next__(self) -> bytes:
3 | class Iterator: 3 | return b"foo"
4 | def __next__(self) -> bytes: 4 |
5 | return b"foo" 5 | def _(flag: bool, flag2: bool):
6 | 6 | class Iterable1:
7 | def _(flag: bool, flag2: bool): 7 | if flag:
8 | class Iterable1: 8 | def __getitem__(self, item: int) -> str:
9 | if flag: 9 | return "foo"
10 | def __getitem__(self, item: int) -> str: 10 | else:
11 | return "foo" 11 | __getitem__: None = None
12 | else: 12 |
13 | __getitem__: None = None 13 | if flag2:
14 | 14 | def __iter__(self) -> Iterator:
15 | if flag2: 15 | return Iterator()
16 | def __iter__(self) -> Iterator: 16 |
17 | return Iterator() 17 | class Iterable2:
18 | 18 | if flag:
19 | class Iterable2: 19 | def __getitem__(self, item: int) -> str:
20 | if flag: 20 | return "foo"
21 | def __getitem__(self, item: int) -> str: 21 | else:
22 | return "foo" 22 | def __getitem__(self, item: str) -> int:
23 | else: 23 | return 42
24 | def __getitem__(self, item: str) -> int: 24 | if flag2:
25 | return 42 25 | def __iter__(self) -> Iterator:
26 | if flag2: 26 | return Iterator()
27 | def __iter__(self) -> Iterator: 27 |
28 | return Iterator() 28 | # error: [not-iterable]
29 | 29 | for x in Iterable1():
30 | # error: [not-iterable] 30 | # TODO: `bytes | str` might be better
31 | for x in Iterable1(): 31 | reveal_type(x) # revealed: bytes | str | Unknown
32 | # TODO: `bytes | str` might be better 32 |
33 | reveal_type(x) # revealed: bytes | str | Unknown 33 | # error: [not-iterable]
34 | 34 | for y in Iterable2():
35 | # error: [not-iterable] 35 | reveal_type(y) # revealed: bytes | str | int
36 | for y in Iterable2():
37 | reveal_type(y) # revealed: bytes | str | int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable1` may not be iterable 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] 28 | # error: [not-iterable]
31 | for x in Iterable1(): 29 | for x in Iterable1():
| ^^^^^^^^^^^ | ^^^^^^^^^^^
32 | # TODO: `bytes | str` might be better 30 | # TODO: `bytes | str` might be better
33 | reveal_type(x) # revealed: bytes | str | Unknown 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: 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: 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 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] 33 | # error: [not-iterable]
36 | for y in Iterable2(): 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: 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: `__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: 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`
|
```

View File

@ -12,52 +12,38 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | def _(flag: bool):
2 | 2 | class Iterator:
3 | def _(flag: bool): 3 | def __next__(self) -> int:
4 | class Iterator: 4 | return 42
5 | def __next__(self) -> int: 5 |
6 | return 42 6 | class Iterable:
7 | 7 | if flag:
8 | class Iterable: 8 | def __iter__(self) -> Iterator:
9 | if flag: 9 | return Iterator()
10 | def __iter__(self) -> Iterator: 10 | # invalid signature because it only accepts a `str`,
11 | return Iterator() 11 | # but the old-style iteration protocol will pass it an `int`
12 | # invalid signature because it only accepts a `str`, 12 | def __getitem__(self, key: str) -> bytes:
13 | # but the old-style iteration protocol will pass it an `int` 13 | return bytes()
14 | def __getitem__(self, key: str) -> bytes: 14 |
15 | return bytes() 15 | # error: [not-iterable]
16 | 16 | for x in Iterable():
17 | # error: [not-iterable] 17 | reveal_type(x) # revealed: int | bytes
18 | for x in Iterable():
19 | reveal_type(x) # revealed: int | bytes
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable` may not be iterable 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] 15 | # error: [not-iterable]
18 | for x in 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: 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: `__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: 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`
|
```

View File

@ -12,50 +12,36 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Iterator:
2 | 2 | def __next__(self) -> int:
3 | class Iterator: 3 | return 42
4 | def __next__(self) -> int: 4 |
5 | return 42 5 | def _(flag1: bool, flag2: bool):
6 | 6 | class Iterable:
7 | def _(flag1: bool, flag2: bool): 7 | if flag1:
8 | class Iterable: 8 | def __iter__(self) -> Iterator:
9 | if flag1: 9 | return Iterator()
10 | def __iter__(self) -> Iterator: 10 | if flag2:
11 | return Iterator() 11 | def __getitem__(self, key: int) -> bytes:
12 | if flag2: 12 | return bytes()
13 | def __getitem__(self, key: int) -> bytes: 13 |
14 | return bytes() 14 | # error: [not-iterable]
15 | 15 | for x in Iterable():
16 | # error: [not-iterable] 16 | reveal_type(x) # revealed: int | bytes
17 | for x in Iterable():
18 | reveal_type(x) # revealed: int | bytes
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable` may not be iterable 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] 14 | # error: [not-iterable]
17 | for x in 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: It may not have an `__iter__` method or a `__getitem__` method
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,52 +12,38 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class TestIter:
2 | 2 | def __next__(self) -> int:
3 | class TestIter: 3 | return 42
4 | def __next__(self) -> int: 4 |
5 | return 42 5 | class Test:
6 | 6 | def __iter__(self) -> TestIter:
7 | class Test: 7 | return TestIter()
8 | def __iter__(self) -> TestIter: 8 |
9 | return TestIter() 9 | class Test2:
10 | 10 | def __iter__(self) -> int:
11 | class Test2: 11 | return 42
12 | def __iter__(self) -> int: 12 |
13 | return 42 13 | def _(flag: bool):
14 | 14 | # TODO: Improve error message to state which union variant isn't iterable (https://github.com/astral-sh/ruff/issues/13989)
15 | def _(flag: bool): 15 | # error: [not-iterable]
16 | # TODO: Improve error message to state which union variant isn't iterable (https://github.com/astral-sh/ruff/issues/13989) 16 | for x in Test() if flag else Test2():
17 | # error: [not-iterable] 17 | reveal_type(x) # revealed: int
18 | for x in Test() if flag else Test2():
19 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Test | Test2` may not be iterable 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) 14 | # TODO: Improve error message to state which union variant isn't iterable (https://github.com/astral-sh/ruff/issues/13989)
17 | # error: [not-iterable] 15 | # error: [not-iterable]
18 | for x in Test() if flag else Test2(): 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: 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: 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`
|
```

View File

@ -12,47 +12,33 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class TestIter:
2 | 2 | def __next__(self) -> int:
3 | class TestIter: 3 | return 42
4 | def __next__(self) -> int: 4 |
5 | return 42 5 | class Test:
6 | 6 | def __iter__(self) -> TestIter:
7 | class Test: 7 | return TestIter()
8 | def __iter__(self) -> TestIter: 8 |
9 | return TestIter() 9 | def _(flag: bool):
10 | 10 | # error: [not-iterable]
11 | def _(flag: bool): 11 | for x in Test() if flag else 42:
12 | # error: [not-iterable] 12 | reveal_type(x) # revealed: int
13 | for x in Test() if flag else 42:
14 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Test | Literal[42]` may not be iterable 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): 9 | def _(flag: bool):
12 | # error: [not-iterable] 10 | # error: [not-iterable]
13 | for x in Test() if flag else 42: 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: It may not have an `__iter__` method and it doesn't have a `__getitem__` method
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,34 +12,32 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | def _(flag: bool):
2 | 2 | class NotIterable:
3 | def _(flag: bool): 3 | if flag:
4 | class NotIterable: 4 | __iter__: int = 1
5 | if flag: 5 | else:
6 | __iter__: int = 1 6 | __iter__: None = None
7 | else: 7 |
8 | __iter__: None = None 8 | # error: [not-iterable]
9 | 9 | for x in NotIterable():
10 | # error: [not-iterable] 10 | pass
11 | for x in NotIterable(): 11 |
12 | pass 12 | # revealed: Unknown
13 | 13 | # error: [possibly-unresolved-reference]
14 | # revealed: Unknown 14 | reveal_type(x)
15 | # error: [possibly-unresolved-reference]
16 | reveal_type(x)
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `NotIterable` is not iterable 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] 8 | # error: [not-iterable]
11 | for x in NotIterable(): 9 | for x in NotIterable():
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
12 | pass 10 | pass
| |
info: Its `__iter__` attribute has type `int | None`, which is not callable info: Its `__iter__` attribute has type `int | None`, which is not callable
info: rule `not-iterable` is enabled by default 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 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 12 | # revealed: Unknown
15 | # error: [possibly-unresolved-reference] 13 | # error: [possibly-unresolved-reference]
16 | reveal_type(x) 14 | reveal_type(x)
| ^ | ^
| |
info: rule `possibly-unresolved-reference` is enabled by default 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`
|
```

View File

@ -12,41 +12,27 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Bad:
2 | 2 | def __iter__(self) -> int:
3 | class Bad: 3 | return 42
4 | def __iter__(self) -> int: 4 |
5 | return 42 5 | # error: [not-iterable]
6 | 6 | for x in Bad():
7 | # error: [not-iterable] 7 | reveal_type(x) # revealed: Unknown
8 | for x in Bad():
9 | reveal_type(x) # revealed: Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Bad` is not iterable 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] 5 | # error: [not-iterable]
8 | for x in Bad(): 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: Its `__iter__` method returns an object of type `int`, which has no `__next__` method
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,46 +12,32 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Iterator:
2 | 2 | def __next__(self) -> int:
3 | class Iterator: 3 | return 42
4 | def __next__(self) -> int: 4 |
5 | return 42 5 | class Iterable:
6 | 6 | def __iter__(self, extra_arg) -> Iterator:
7 | class Iterable: 7 | return Iterator()
8 | def __iter__(self, extra_arg) -> Iterator: 8 |
9 | return Iterator() 9 | # error: [not-iterable]
10 | 10 | for x in Iterable():
11 | # error: [not-iterable] 11 | reveal_type(x) # revealed: int
12 | for x in Iterable():
13 | reveal_type(x) # revealed: int
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable` is not iterable 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] 9 | # error: [not-iterable]
12 | for x in 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: Its `__iter__` method has an invalid signature
info: Expected signature `def __iter__(self): ...` info: Expected signature `def __iter__(self): ...`
info: rule `not-iterable` is enabled by default 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`
|
```

View File

@ -12,42 +12,40 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/loops/for.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Iterator1:
2 | 2 | def __next__(self, extra_arg) -> int:
3 | class Iterator1: 3 | return 42
4 | def __next__(self, extra_arg) -> int: 4 |
5 | return 42 5 | class Iterator2:
6 | 6 | __next__: None = None
7 | class Iterator2: 7 |
8 | __next__: None = None 8 | class Iterable1:
9 | 9 | def __iter__(self) -> Iterator1:
10 | class Iterable1: 10 | return Iterator1()
11 | def __iter__(self) -> Iterator1: 11 |
12 | return Iterator1() 12 | class Iterable2:
13 | 13 | def __iter__(self) -> Iterator2:
14 | class Iterable2: 14 | return Iterator2()
15 | def __iter__(self) -> Iterator2: 15 |
16 | return Iterator2() 16 | # error: [not-iterable]
17 | 17 | for x in Iterable1():
18 | # error: [not-iterable] 18 | reveal_type(x) # revealed: int
19 | for x in Iterable1(): 19 |
20 | reveal_type(x) # revealed: int 20 | # error: [not-iterable]
21 | 21 | for y in Iterable2():
22 | # error: [not-iterable] 22 | reveal_type(y) # revealed: Unknown
23 | for y in Iterable2():
24 | reveal_type(y) # revealed: Unknown
``` ```
# Diagnostics # Diagnostics
``` ```
error[not-iterable]: Object of type `Iterable1` is not iterable 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] 16 | # error: [not-iterable]
19 | for x in Iterable1(): 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: Its `__iter__` method returns an object of type `Iterator1`, which has an invalid `__next__` method
info: Expected signature for `__next__` is `def __next__(self): ...` 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 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] 20 | # error: [not-iterable]
23 | for y in Iterable2(): 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: 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: 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`
|
```

View File

@ -13,78 +13,38 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/legacy/function
``` ```
1 | from typing import TypeVar 1 | from typing import TypeVar
2 | from typing_extensions import reveal_type 2 |
3 | 3 | T = TypeVar("T", bound=int)
4 | T = TypeVar("T", bound=int) 4 |
5 | 5 | def f(x: T) -> T:
6 | def f(x: T) -> T: 6 | return x
7 | return x 7 |
8 | 8 | reveal_type(f(1)) # revealed: Literal[1]
9 | reveal_type(f(1)) # revealed: Literal[1] 9 | reveal_type(f(True)) # revealed: Literal[True]
10 | reveal_type(f(True)) # revealed: Literal[True] 10 | # error: [invalid-argument-type]
11 | # error: [invalid-argument-type] 11 | reveal_type(f("string")) # revealed: Unknown
12 | reveal_type(f("string")) # revealed: Unknown
``` ```
# Diagnostics # 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 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] 9 | reveal_type(f(True)) # revealed: Literal[True]
11 | # error: [invalid-argument-type] 10 | # error: [invalid-argument-type]
12 | reveal_type(f("string")) # revealed: Unknown 11 | reveal_type(f("string")) # revealed: Unknown
| ^^^^^^^^ Argument type `Literal["string"]` does not satisfy upper bound `int` of type variable `T` | ^^^^^^^^ Argument type `Literal["string"]` does not satisfy upper bound `int` of type variable `T`
| |
info: Type variable defined here info: Type variable defined here
--> src/mdtest_snippet.py:4:1 --> src/mdtest_snippet.py:3:1
| |
2 | from typing_extensions import reveal_type 1 | from typing import TypeVar
3 | 2 |
4 | T = TypeVar("T", bound=int) 3 | T = TypeVar("T", bound=int)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
5 | 4 |
6 | def f(x: T) -> T: 5 | def f(x: T) -> T:
| |
info: rule `invalid-argument-type` is enabled by default info: rule `invalid-argument-type` is enabled by default

View File

@ -13,93 +13,39 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/legacy/function
``` ```
1 | from typing import TypeVar 1 | from typing import TypeVar
2 | from typing_extensions import reveal_type 2 |
3 | 3 | T = TypeVar("T", int, None)
4 | T = TypeVar("T", int, None) 4 |
5 | 5 | def f(x: T) -> T:
6 | def f(x: T) -> T: 6 | return x
7 | return x 7 |
8 | 8 | reveal_type(f(1)) # revealed: int
9 | reveal_type(f(1)) # revealed: int 9 | reveal_type(f(True)) # revealed: int
10 | reveal_type(f(True)) # revealed: int 10 | reveal_type(f(None)) # revealed: None
11 | reveal_type(f(None)) # revealed: None 11 | # error: [invalid-argument-type]
12 | # error: [invalid-argument-type] 12 | reveal_type(f("string")) # revealed: Unknown
13 | reveal_type(f("string")) # revealed: Unknown
``` ```
# Diagnostics # 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 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 10 | reveal_type(f(None)) # revealed: None
12 | # error: [invalid-argument-type] 11 | # error: [invalid-argument-type]
13 | reveal_type(f("string")) # revealed: Unknown 12 | reveal_type(f("string")) # revealed: Unknown
| ^^^^^^^^ Argument type `Literal["string"]` does not satisfy constraints (`int`, `None`) of type variable `T` | ^^^^^^^^ Argument type `Literal["string"]` does not satisfy constraints (`int`, `None`) of type variable `T`
| |
info: Type variable defined here info: Type variable defined here
--> src/mdtest_snippet.py:4:1 --> src/mdtest_snippet.py:3:1
| |
2 | from typing_extensions import reveal_type 1 | from typing import TypeVar
3 | 2 |
4 | T = TypeVar("T", int, None) 3 | T = TypeVar("T", int, None)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
5 | 4 |
6 | def f(x: T) -> T: 5 | def f(x: T) -> T:
| |
info: rule `invalid-argument-type` is enabled by default info: rule `invalid-argument-type` is enabled by default

View File

@ -25,45 +25,6 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/pep695/function
# Diagnostics # 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 error[invalid-argument-type]: Argument to function `f` is incorrect
--> src/mdtest_snippet.py:9:15 --> src/mdtest_snippet.py:9:15

View File

@ -26,59 +26,6 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/generics/pep695/function
# Diagnostics # 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 error[invalid-argument-type]: Argument to function `f` is incorrect
--> src/mdtest_snippet.py:10:15 --> src/mdtest_snippet.py:10:15

View File

@ -12,67 +12,39 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/mro.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | def returns_bool() -> bool:
2 | 2 | return True
3 | def returns_bool() -> bool: 3 |
4 | return True 4 | class A: ...
5 | 5 | class B: ...
6 | class A: ... 6 |
7 | class B: ... 7 | if returns_bool():
8 | 8 | x = A
9 | if returns_bool(): 9 | else:
10 | x = A 10 | x = B
11 | else: 11 |
12 | x = B 12 | reveal_type(x) # revealed: <class 'A'> | <class 'B'>
13 | 13 |
14 | reveal_type(x) # revealed: <class 'A'> | <class 'B'> 14 | # error: 11 [unsupported-base] "Unsupported class base with type `<class 'A'> | <class 'B'>`"
15 | 15 | class Foo(x): ...
16 | # error: 11 [unsupported-base] "Unsupported class base with type `<class 'A'> | <class 'B'>`" 16 |
17 | class Foo(x): ... 17 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>]
18 |
19 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>]
``` ```
# Diagnostics # Diagnostics
```
info[revealed-type]: Revealed type
--> src/mdtest_snippet.py:14:13
|
12 | x = B
13 |
14 | reveal_type(x) # revealed: <class 'A'> | <class 'B'>
| ^ `<class 'A'> | <class 'B'>`
15 |
16 | # error: 11 [unsupported-base] "Unsupported class base with type `<class 'A'> | <class 'B'>`"
|
```
``` ```
warning[unsupported-base]: Unsupported class base with type `<class 'A'> | <class 'B'>` warning[unsupported-base]: Unsupported class base with type `<class 'A'> | <class 'B'>`
--> src/mdtest_snippet.py:17:11 --> src/mdtest_snippet.py:15:11
| |
16 | # error: 11 [unsupported-base] "Unsupported class base with type `<class 'A'> | <class 'B'>`" 14 | # error: 11 [unsupported-base] "Unsupported class base with type `<class 'A'> | <class 'B'>`"
17 | class Foo(x): ... 15 | class Foo(x): ...
| ^ | ^
18 | 16 |
19 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>] 17 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>]
| |
info: ty cannot resolve a consistent MRO for class `Foo` due to this base 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: Only class objects or `Any` are supported as class bases
info: rule `unsupported-base` is enabled by default 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[<class 'Foo'>, Unknown, <class 'object'>]
| ^^^^^^^^^^^ `tuple[<class 'Foo'>, Unknown, <class 'object'>]`
|
```

View File

@ -12,167 +12,147 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/mro.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import reveal_type 1 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`"
2 | 2 |
3 | class Foo(str, str): ... # error: [duplicate-base] "Duplicate base class `str`" 3 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>]
4 | 4 |
5 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>] 5 | class Spam: ...
6 | 6 | class Eggs: ...
7 | class Spam: ... 7 | class Bar: ...
8 | class Eggs: ... 8 | class Baz: ...
9 | class Bar: ... 9 |
10 | class Baz: ... 10 | # fmt: off
11 | 11 |
12 | # fmt: off 12 | # error: [duplicate-base] "Duplicate base class `Spam`"
13 | 13 | # error: [duplicate-base] "Duplicate base class `Eggs`"
14 | # error: [duplicate-base] "Duplicate base class `Spam`" 14 | class Ham(
15 | # error: [duplicate-base] "Duplicate base class `Eggs`" 15 | Spam,
16 | class Ham( 16 | Eggs,
17 | Spam, 17 | Bar,
18 | Eggs, 18 | Baz,
19 | Bar, 19 | Spam,
20 | Baz, 20 | Eggs,
21 | Spam, 21 | ): ...
22 | Eggs, 22 |
23 | ): ... 23 | # fmt: on
24 | 24 |
25 | # fmt: on 25 | reveal_type(Ham.__mro__) # revealed: tuple[<class 'Ham'>, Unknown, <class 'object'>]
26 | 26 |
27 | reveal_type(Ham.__mro__) # revealed: tuple[<class 'Ham'>, Unknown, <class 'object'>] 27 | class Mushrooms: ...
28 | 28 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base]
29 | class Mushrooms: ... 29 |
30 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] 30 | reveal_type(Omelette.__mro__) # revealed: tuple[<class 'Omelette'>, Unknown, <class 'object'>]
31 | 31 |
32 | reveal_type(Omelette.__mro__) # revealed: tuple[<class 'Omelette'>, Unknown, <class 'object'>] 32 | # fmt: off
33 | 33 |
34 | # fmt: off 34 | # error: [duplicate-base] "Duplicate base class `Eggs`"
35 | 35 | class VeryEggyOmelette(
36 | # error: [duplicate-base] "Duplicate base class `Eggs`" 36 | Eggs,
37 | class VeryEggyOmelette( 37 | Ham,
38 | Eggs, 38 | Spam,
39 | Ham, 39 | Eggs,
40 | Spam, 40 | Mushrooms,
41 | Eggs, 41 | Bar,
42 | Mushrooms, 42 | Eggs,
43 | Bar, 43 | Baz,
44 | Eggs, 44 | Eggs,
45 | Baz, 45 | ): ...
46 | Eggs, 46 |
47 | ): ... 47 | # fmt: off
48 | 48 | # fmt: off
49 | # fmt: off 49 |
50 | # fmt: off 50 | class A: ...
51 | 51 |
52 | class A: ... 52 | class B( # type: ignore[duplicate-base]
53 | 53 | A,
54 | class B( # type: ignore[duplicate-base] 54 | A,
55 | A, 55 | ): ...
56 | A, 56 |
57 | ): ... 57 | class C(
58 | 58 | A,
59 | class C( 59 | A
60 | A, 60 | ): # type: ignore[duplicate-base]
61 | A 61 | x: int
62 | ): # type: ignore[duplicate-base] 62 |
63 | x: int 63 | # fmt: on
64 | 64 | # fmt: off
65 | # fmt: on 65 |
66 | # fmt: off 66 | # error: [duplicate-base]
67 | 67 | class D(
68 | # error: [duplicate-base] 68 | A,
69 | class D( 69 | # error: [unused-ignore-comment]
70 | A, 70 | A, # type: ignore[duplicate-base]
71 | # error: [unused-ignore-comment] 71 | ): ...
72 | A, # type: ignore[duplicate-base] 72 |
73 | ): ... 73 | # error: [duplicate-base]
74 | 74 | class E(
75 | # error: [duplicate-base] 75 | A,
76 | class E( 76 | A
77 | A, 77 | ):
78 | A 78 | # error: [unused-ignore-comment]
79 | ): 79 | x: int # type: ignore[duplicate-base]
80 | # error: [unused-ignore-comment] 80 |
81 | x: int # type: ignore[duplicate-base] 81 | # fmt: on
82 |
83 | # fmt: on
``` ```
# Diagnostics # Diagnostics
``` ```
error[duplicate-base]: Duplicate base class `str` 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 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`"
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
4 | 2 |
5 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>] 3 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>]
| |
info: The definition of class `Foo` will raise `TypeError` at runtime 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 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`"
| --- ^^^ Class `str` later repeated here | --- ^^^ Class `str` later repeated here
| | | |
| Class `str` first included in bases list here | Class `str` first included in bases list here
4 | 2 |
5 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>] 3 | reveal_type(Foo.__mro__) # revealed: tuple[<class 'Foo'>, Unknown, <class 'object'>]
| |
info: rule `duplicate-base` is enabled by default 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[<class 'Foo'>, Unknown, <class 'object'>]
| ^^^^^^^^^^^ `tuple[<class 'Foo'>, Unknown, <class 'object'>]`
6 |
7 | class Spam: ...
|
```
``` ```
error[duplicate-base]: Duplicate base 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`" 12 | # error: [duplicate-base] "Duplicate base class `Spam`"
15 | # error: [duplicate-base] "Duplicate base class `Eggs`" 13 | # error: [duplicate-base] "Duplicate base class `Eggs`"
16 | class Ham( 14 | class Ham(
| _______^ | _______^
17 | | Spam, 15 | | Spam,
18 | | Eggs, 16 | | Eggs,
19 | | Bar, 17 | | Bar,
20 | | Baz, 18 | | Baz,
21 | | Spam, 19 | | Spam,
22 | | Eggs, 20 | | Eggs,
23 | | ): ... 21 | | ): ...
| |_^ | |_^
24 | 22 |
25 | # fmt: on 23 | # fmt: on
| |
info: The definition of class `Ham` will raise `TypeError` at runtime 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`" 13 | # error: [duplicate-base] "Duplicate base class `Eggs`"
16 | class Ham( 14 | class Ham(
17 | Spam, 15 | Spam,
| ---- Class `Spam` first included in bases list here | ---- Class `Spam` first included in bases list here
18 | Eggs, 16 | Eggs,
19 | Bar, 17 | Bar,
20 | Baz, 18 | Baz,
21 | Spam, 19 | Spam,
| ^^^^ Class `Spam` later repeated here | ^^^^ Class `Spam` later repeated here
22 | Eggs, 20 | Eggs,
23 | ): ... 21 | ): ...
| |
info: rule `duplicate-base` is enabled by default 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` 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`" 12 | # error: [duplicate-base] "Duplicate base class `Spam`"
15 | # error: [duplicate-base] "Duplicate base class `Eggs`" 13 | # error: [duplicate-base] "Duplicate base class `Eggs`"
16 | class Ham( 14 | class Ham(
| _______^ | _______^
17 | | Spam, 15 | | Spam,
18 | | Eggs, 16 | | Eggs,
19 | | Bar, 17 | | Bar,
20 | | Baz, 18 | | Baz,
21 | | Spam, 19 | | Spam,
22 | | Eggs, 20 | | Eggs,
23 | | ): ... 21 | | ): ...
| |_^ | |_^
24 | 22 |
25 | # fmt: on 23 | # fmt: on
| |
info: The definition of class `Ham` will raise `TypeError` at runtime 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( 14 | class Ham(
17 | Spam, 15 | Spam,
18 | Eggs, 16 | Eggs,
| ---- Class `Eggs` first included in bases list here | ---- Class `Eggs` first included in bases list here
19 | Bar, 17 | Bar,
20 | Baz, 18 | Baz,
21 | Spam, 19 | Spam,
22 | Eggs, 20 | Eggs,
| ^^^^ Class `Eggs` later repeated here | ^^^^ Class `Eggs` later repeated here
23 | ): ... 21 | ): ...
| |
info: rule `duplicate-base` is enabled by default 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[<class 'Ham'>, Unknown, <class 'object'>]
| ^^^^^^^^^^^ `tuple[<class 'Ham'>, Unknown, <class 'object'>]`
28 |
29 | class Mushrooms: ...
|
```
``` ```
error[duplicate-base]: Duplicate base class `Mushrooms` error[duplicate-base]: Duplicate base class `Mushrooms`
--> src/mdtest_snippet.py:30:7 --> src/mdtest_snippet.py:28:7
| |
29 | class Mushrooms: ... 27 | class Mushrooms: ...
30 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] 28 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31 | 29 |
32 | reveal_type(Omelette.__mro__) # revealed: tuple[<class 'Omelette'>, Unknown, <class 'object'>] 30 | reveal_type(Omelette.__mro__) # revealed: tuple[<class 'Omelette'>, Unknown, <class 'object'>]
| |
info: The definition of class `Omelette` will raise `TypeError` at runtime 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: ... 27 | class Mushrooms: ...
30 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base] 28 | class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base]
| --------- ^^^^^^^^^ Class `Mushrooms` later repeated here | --------- ^^^^^^^^^ Class `Mushrooms` later repeated here
| | | |
| Class `Mushrooms` first included in bases list here | Class `Mushrooms` first included in bases list here
31 | 29 |
32 | reveal_type(Omelette.__mro__) # revealed: tuple[<class 'Omelette'>, Unknown, <class 'object'>] 30 | reveal_type(Omelette.__mro__) # revealed: tuple[<class 'Omelette'>, Unknown, <class 'object'>]
| |
info: rule `duplicate-base` is enabled by default 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[<class 'Omelette'>, Unknown, <class 'object'>]
| ^^^^^^^^^^^^^^^^ `tuple[<class 'Omelette'>, Unknown, <class 'object'>]`
33 |
34 | # fmt: off
|
```
``` ```
error[duplicate-base]: Duplicate base class `Eggs` 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`" 34 | # error: [duplicate-base] "Duplicate base class `Eggs`"
37 | class VeryEggyOmelette( 35 | class VeryEggyOmelette(
| _______^ | _______^
38 | | Eggs, 36 | | Eggs,
39 | | Ham, 37 | | Ham,
40 | | Spam, 38 | | Spam,
41 | | Eggs, 39 | | Eggs,
42 | | Mushrooms, 40 | | Mushrooms,
43 | | Bar, 41 | | Bar,
42 | | Eggs,
43 | | Baz,
44 | | Eggs, 44 | | Eggs,
45 | | Baz, 45 | | ): ...
46 | | Eggs,
47 | | ): ...
| |_^ | |_^
48 | 46 |
49 | # fmt: off 47 | # fmt: off
| |
info: The definition of class `VeryEggyOmelette` will raise `TypeError` at runtime 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`" 34 | # error: [duplicate-base] "Duplicate base class `Eggs`"
37 | class VeryEggyOmelette( 35 | class VeryEggyOmelette(
38 | Eggs, 36 | Eggs,
| ---- Class `Eggs` first included in bases list here | ---- Class `Eggs` first included in bases list here
39 | Ham, 37 | Ham,
40 | Spam, 38 | Spam,
41 | Eggs, 39 | Eggs,
| ^^^^ Class `Eggs` later repeated here | ^^^^ Class `Eggs` later repeated here
42 | Mushrooms, 40 | Mushrooms,
43 | Bar, 41 | Bar,
42 | Eggs,
| ^^^^ Class `Eggs` later repeated here
43 | Baz,
44 | Eggs, 44 | Eggs,
| ^^^^ Class `Eggs` later repeated here | ^^^^ Class `Eggs` later repeated here
45 | Baz, 45 | ): ...
46 | Eggs,
| ^^^^ Class `Eggs` later repeated here
47 | ): ...
| |
info: rule `duplicate-base` is enabled by default 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` error[duplicate-base]: Duplicate base class `A`
--> src/mdtest_snippet.py:69:7 --> src/mdtest_snippet.py:67:7
| |
68 | # error: [duplicate-base] 66 | # error: [duplicate-base]
69 | class D( 67 | class D(
| _______^ | _______^
70 | | A, 68 | | A,
71 | | # error: [unused-ignore-comment] 69 | | # error: [unused-ignore-comment]
72 | | A, # type: ignore[duplicate-base] 70 | | A, # type: ignore[duplicate-base]
73 | | ): ... 71 | | ): ...
| |_^ | |_^
74 | 72 |
75 | # error: [duplicate-base] 73 | # error: [duplicate-base]
| |
info: The definition of class `D` will raise `TypeError` at runtime 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] 66 | # error: [duplicate-base]
69 | class D( 67 | class D(
70 | A, 68 | A,
| - Class `A` first included in bases list here | - Class `A` first included in bases list here
71 | # error: [unused-ignore-comment] 69 | # error: [unused-ignore-comment]
72 | A, # type: ignore[duplicate-base] 70 | A, # type: ignore[duplicate-base]
| ^ Class `A` later repeated here | ^ Class `A` later repeated here
73 | ): ... 71 | ): ...
| |
info: rule `duplicate-base` is enabled by default info: rule `duplicate-base` is enabled by default
@ -346,42 +298,42 @@ info: rule `duplicate-base` is enabled by default
``` ```
info[unused-ignore-comment] info[unused-ignore-comment]
--> src/mdtest_snippet.py:72:9 --> src/mdtest_snippet.py:70:9
| |
70 | A, 68 | A,
71 | # error: [unused-ignore-comment] 69 | # error: [unused-ignore-comment]
72 | A, # type: ignore[duplicate-base] 70 | A, # type: ignore[duplicate-base]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused blanket `type: ignore` directive | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused blanket `type: ignore` directive
73 | ): ... 71 | ): ...
| |
``` ```
``` ```
error[duplicate-base]: Duplicate base class `A` error[duplicate-base]: Duplicate base class `A`
--> src/mdtest_snippet.py:76:7 --> src/mdtest_snippet.py:74:7
| |
75 | # error: [duplicate-base] 73 | # error: [duplicate-base]
76 | class E( 74 | class E(
| _______^ | _______^
77 | | A, 75 | | A,
78 | | A 76 | | A
79 | | ): 77 | | ):
| |_^ | |_^
80 | # error: [unused-ignore-comment] 78 | # error: [unused-ignore-comment]
81 | x: int # type: ignore[duplicate-base] 79 | x: int # type: ignore[duplicate-base]
| |
info: The definition of class `E` will raise `TypeError` at runtime 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] 73 | # error: [duplicate-base]
76 | class E( 74 | class E(
77 | A, 75 | A,
| - Class `A` first included in bases list here | - Class `A` first included in bases list here
78 | A 76 | A
| ^ Class `A` later repeated here | ^ Class `A` later repeated here
79 | ): 77 | ):
80 | # error: [unused-ignore-comment] 78 | # error: [unused-ignore-comment]
| |
info: rule `duplicate-base` is enabled by default info: rule `duplicate-base` is enabled by default
@ -389,14 +341,14 @@ info: rule `duplicate-base` is enabled by default
``` ```
info[unused-ignore-comment] info[unused-ignore-comment]
--> src/mdtest_snippet.py:81:13 --> src/mdtest_snippet.py:79:13
| |
79 | ): 77 | ):
80 | # error: [unused-ignore-comment] 78 | # error: [unused-ignore-comment]
81 | x: int # type: ignore[duplicate-base] 79 | x: int # type: ignore[duplicate-base]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused blanket `type: ignore` directive | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unused blanket `type: ignore` directive
82 | 80 |
83 | # fmt: on 81 | # fmt: on
| |
``` ```

View File

@ -136,48 +136,3 @@ info: (x: B, /, **kwargs: int) -> B
info: rule `no-matching-overload` is enabled by default 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 | )
|
```

View File

@ -12,7 +12,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import Protocol, reveal_type 1 | from typing_extensions import Protocol
2 | 2 |
3 | # error: [call-non-callable] 3 | # error: [call-non-callable]
4 | reveal_type(Protocol()) # revealed: Unknown 4 | reveal_type(Protocol()) # revealed: Unknown
@ -36,9 +36,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md
22 | 22 |
23 | reveal_type(SubclassOfGenericProtocol[int]()) # revealed: SubclassOfGenericProtocol[int] 23 | reveal_type(SubclassOfGenericProtocol[int]()) # revealed: SubclassOfGenericProtocol[int]
24 | def f(x: type[MyProtocol]): 24 | def f(x: type[MyProtocol]):
25 | # TODO: add a `reveal_type` call here once it's no longer a `Todo` type 25 | reveal_type(x()) # revealed: @Todo(type[T] for protocols)
26 | # (which doesn't work well with snapshots)
27 | x()
``` ```
# Diagnostics # 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` error[call-non-callable]: Cannot instantiate class `MyProtocol`
--> src/mdtest_snippet.py:10:13 --> 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` error[call-non-callable]: Cannot instantiate class `GenericProtocol`
--> src/mdtest_snippet.py:16:13 --> 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: 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
|
```

View File

@ -12,7 +12,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md
## mdtest_snippet.py ## mdtest_snippet.py
``` ```
1 | from typing_extensions import Protocol, reveal_type 1 | from typing_extensions import Protocol
2 | 2 |
3 | class HasX(Protocol): 3 | class HasX(Protocol):
4 | x: int 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 info: `HasX` is declared as a protocol class, but it is not declared as runtime-checkable
--> src/mdtest_snippet.py:3:7 --> src/mdtest_snippet.py:3:7
| |
1 | from typing_extensions import Protocol, reveal_type 1 | from typing_extensions import Protocol
2 | 2 |
3 | class HasX(Protocol): 3 | class HasX(Protocol):
| ^^^^^^^^^^^^^^ `HasX` declared here | ^^^^^^^^^^^^^^ `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` error[invalid-argument-type]: Class `HasX` cannot be used as the second argument to `issubclass`
--> src/mdtest_snippet.py:12:8 --> 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 info: `HasX` is declared as a protocol class, but it is not declared as runtime-checkable
--> src/mdtest_snippet.py:3:7 --> src/mdtest_snippet.py:3:7
| |
1 | from typing_extensions import Protocol, reveal_type 1 | from typing_extensions import Protocol
2 | 2 |
3 | class HasX(Protocol): 3 | class HasX(Protocol):
| ^^^^^^^^^^^^^^ `HasX` declared here | ^^^^^^^^^^^^^^ `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: 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]`
|
```

View File

@ -13,7 +13,7 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/protocols.md
``` ```
1 | import sys 1 | import sys
2 | from typing_extensions import Protocol, get_protocol_members, reveal_type 2 | from typing_extensions import Protocol, get_protocol_members
3 | 3 |
4 | class Foo(Protocol): 4 | class Foo(Protocol):
5 | if sys.version_info >= (3, 10): 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 info: Assigning to an undeclared variable in a protocol class leads to an ambiguous interface
--> src/mdtest_snippet.py:4:7 --> 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 | 3 |
4 | class Foo(Protocol): 4 | class Foo(Protocol):
| ^^^^^^^^^^^^^ `Foo` declared as a protocol here | ^^^^^^^^^^^^^ `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: 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"]]`
|
```

View File

@ -21,8 +21,8 @@ use type_ordering::union_or_intersection_elements_ordering;
pub(crate) use self::builder::{IntersectionBuilder, UnionBuilder}; pub(crate) use self::builder::{IntersectionBuilder, UnionBuilder};
pub use self::cyclic::CycleDetector; pub use self::cyclic::CycleDetector;
pub(crate) use self::cyclic::{PairVisitor, TypeTransformer}; pub(crate) use self::cyclic::{PairVisitor, TypeTransformer};
pub use self::diagnostic::TypeCheckDiagnostics;
pub(crate) use self::diagnostic::register_lints; pub(crate) use self::diagnostic::register_lints;
pub use self::diagnostic::{TypeCheckDiagnostics, UNDEFINED_REVEAL};
pub(crate) use self::infer::{ pub(crate) use self::infer::{
TypeContext, infer_deferred_types, infer_definition_types, infer_expression_type, TypeContext, infer_deferred_types, infer_definition_types, infer_expression_type,
infer_expression_types, infer_isolated_expression, infer_scope_types, infer_expression_types, infer_isolated_expression, infer_scope_types,

View File

@ -1568,7 +1568,7 @@ declare_lint! {
/// ```python /// ```python
/// reveal_type(1) # NameError: name 'reveal_type' is not defined /// 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", summary: "detects usages of `reveal_type` without importing it",
status: LintStatus::preview("1.0.0"), status: LintStatus::preview("1.0.0"),
default_level: Level::Warn, default_level: Level::Warn,

View File

@ -6,7 +6,7 @@ use colored::Colorize;
use config::SystemKind; use config::SystemKind;
use parser as test_parser; use parser as test_parser;
use ruff_db::Db as _; 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::files::{File, FileRootKind, system_path_to_file};
use ruff_db::panic::catch_unwind; use ruff_db::panic::catch_unwind;
use ruff_db::parsed::parsed_module; use ruff_db::parsed::parsed_module;
@ -16,7 +16,7 @@ use ruff_source_file::{LineIndex, OneIndexed};
use std::backtrace::BacktraceStatus; use std::backtrace::BacktraceStatus;
use std::fmt::Write; use std::fmt::Write;
use ty_python_semantic::pull_types::pull_types; 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::{ use ty_python_semantic::{
Module, Program, ProgramSettings, PythonEnvironment, PythonPlatform, PythonVersionSource, Module, Program, ProgramSettings, PythonEnvironment, PythonPlatform, PythonVersionSource,
PythonVersionWithSource, SearchPath, SearchPathSettings, SysPrefixPathOrigin, list_modules, PythonVersionWithSource, SearchPath, SearchPathSettings, SysPrefixPathOrigin, list_modules,
@ -377,8 +377,14 @@ fn run_test(
by_line: line_failures, 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() { 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 failure