mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 10:22:24 +00:00
[red-knot] Format mdtest Python snippets more concisely (#13905)
This commit is contained in:
parent
77ae0ccf0f
commit
3eb454699a
33 changed files with 4 additions and 193 deletions
|
@ -15,13 +15,11 @@ Name lookups within a class scope fall back to globals, but lookups of class att
|
|||
```py
|
||||
x = 1
|
||||
|
||||
|
||||
class C:
|
||||
y = x
|
||||
if flag:
|
||||
x = 2
|
||||
|
||||
|
||||
reveal_type(C.x) # revealed: Literal[2]
|
||||
reveal_type(C.y) # revealed: Literal[1]
|
||||
```
|
||||
|
|
|
@ -4,15 +4,12 @@
|
|||
|
||||
```py
|
||||
if flag:
|
||||
|
||||
class C:
|
||||
x = 1
|
||||
|
||||
else:
|
||||
|
||||
class C:
|
||||
x = 2
|
||||
|
||||
|
||||
reveal_type(C.x) # revealed: Literal[1, 2]
|
||||
```
|
||||
|
|
|
@ -53,10 +53,8 @@ class A:
|
|||
def __or__(self, other) -> A:
|
||||
return self
|
||||
|
||||
|
||||
class B: ...
|
||||
|
||||
|
||||
reveal_type(A() + B()) # revealed: A
|
||||
reveal_type(A() - B()) # revealed: A
|
||||
reveal_type(A() * B()) # revealed: A
|
||||
|
@ -117,10 +115,8 @@ class A:
|
|||
def __ror__(self, other) -> A:
|
||||
return self
|
||||
|
||||
|
||||
class B: ...
|
||||
|
||||
|
||||
reveal_type(B() + A()) # revealed: A
|
||||
reveal_type(B() - A()) # revealed: A
|
||||
reveal_type(B() * A()) # revealed: A
|
||||
|
@ -148,10 +144,8 @@ class A:
|
|||
def __rsub__(self, other) -> int:
|
||||
return 1
|
||||
|
||||
|
||||
class B: ...
|
||||
|
||||
|
||||
reveal_type(A() + B()) # revealed: int
|
||||
reveal_type(B() - A()) # revealed: int
|
||||
```
|
||||
|
@ -167,15 +161,12 @@ class A:
|
|||
def __add__(self, other: B) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class B:
|
||||
def __radd__(self, other: A) -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
reveal_type(A() + B()) # revealed: int
|
||||
|
||||
|
||||
# Edge case: C is a subtype of C, *but* if the two sides are of *equal* types,
|
||||
# the lhs *still* takes precedence
|
||||
class C:
|
||||
|
@ -185,7 +176,6 @@ class C:
|
|||
def __radd__(self, other: C) -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
reveal_type(C() + C()) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -203,22 +193,17 @@ class A:
|
|||
def __radd__(self, other) -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
class MyString(str): ...
|
||||
|
||||
|
||||
class B(A):
|
||||
def __radd__(self, other) -> MyString:
|
||||
return MyString()
|
||||
|
||||
|
||||
reveal_type(A() + B()) # revealed: MyString
|
||||
|
||||
|
||||
# N.B. Still a subtype of `A`, even though `A` does not appear directly in the class's `__bases__`
|
||||
class C(B): ...
|
||||
|
||||
|
||||
# TODO: we currently only understand direct subclasses as subtypes of the superclass.
|
||||
# We need to iterate through the full MRO rather than just the class's bases;
|
||||
# if we do, we'll understand `C` as a subtype of `A`, and correctly understand this as being
|
||||
|
@ -240,10 +225,8 @@ class A:
|
|||
def __radd__(self, other) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class B(A): ...
|
||||
|
||||
|
||||
reveal_type(A() + B()) # revealed: str
|
||||
```
|
||||
|
||||
|
@ -266,12 +249,10 @@ class A:
|
|||
def __sub__(self, other: A) -> A:
|
||||
return A()
|
||||
|
||||
|
||||
class B:
|
||||
def __rsub__(self, other: A) -> B:
|
||||
return B()
|
||||
|
||||
|
||||
# TODO: this should be `B` (the return annotation of `B.__rsub__`),
|
||||
# because `A.__sub__` is annotated as only accepting `A`,
|
||||
# but `B.__rsub__` will accept `A`.
|
||||
|
@ -287,11 +268,9 @@ class A:
|
|||
def __call__(self, other) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class B:
|
||||
__add__ = A()
|
||||
|
||||
|
||||
reveal_type(B() + B()) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -311,15 +290,12 @@ reveal_type(42 + 4.2) # revealed: int
|
|||
# TODO should be complex, need to check arg type and fall back to `rhs.__radd__`
|
||||
reveal_type(3 + 3j) # revealed: int
|
||||
|
||||
|
||||
def returns_int() -> int:
|
||||
return 42
|
||||
|
||||
|
||||
def returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
x = returns_bool()
|
||||
y = returns_int()
|
||||
|
||||
|
@ -343,7 +319,6 @@ class A:
|
|||
def __radd__(self, other) -> A:
|
||||
return self
|
||||
|
||||
|
||||
reveal_type(A() + 1) # revealed: A
|
||||
# TODO should be `A` since `int.__add__` doesn't support `A` instances
|
||||
reveal_type(1 + A()) # revealed: int
|
||||
|
@ -388,15 +363,12 @@ from does_not_exist import Foo # error: [unresolved-import]
|
|||
|
||||
reveal_type(Foo) # revealed: Unknown
|
||||
|
||||
|
||||
class X:
|
||||
def __add__(self, other: object) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class Y(Foo): ...
|
||||
|
||||
|
||||
# TODO: Should be `int | Unknown`; see above discussion.
|
||||
reveal_type(X() + Y()) # revealed: int
|
||||
```
|
||||
|
@ -411,12 +383,10 @@ The magic method must exist on the class, not just on the instance:
|
|||
def add_impl(self, other) -> int:
|
||||
return 1
|
||||
|
||||
|
||||
class A:
|
||||
def __init__(self):
|
||||
self.__add__ = add_impl
|
||||
|
||||
|
||||
# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `A` and `A`"
|
||||
# revealed: Unknown
|
||||
reveal_type(A() + A())
|
||||
|
@ -427,7 +397,6 @@ reveal_type(A() + A())
|
|||
```py
|
||||
class A: ...
|
||||
|
||||
|
||||
# error: [unsupported-operator]
|
||||
# revealed: Unknown
|
||||
reveal_type(A() + A())
|
||||
|
@ -441,14 +410,11 @@ A left-hand dunder method doesn't apply for the right-hand operand, or vice vers
|
|||
class A:
|
||||
def __add__(self, other) -> int: ...
|
||||
|
||||
|
||||
class B:
|
||||
def __radd__(self, other) -> int: ...
|
||||
|
||||
|
||||
class C: ...
|
||||
|
||||
|
||||
# error: [unsupported-operator]
|
||||
# revealed: Unknown
|
||||
reveal_type(C() + A())
|
||||
|
@ -471,7 +437,6 @@ class Foo:
|
|||
def __radd__(self, other: Foo) -> Foo:
|
||||
return self
|
||||
|
||||
|
||||
# error: [unsupported-operator]
|
||||
# revealed: Unknown
|
||||
reveal_type(Foo() + Foo())
|
||||
|
|
|
@ -62,10 +62,8 @@ bool(1) / False
|
|||
# revealed: float
|
||||
reveal_type(1.0 / 0)
|
||||
|
||||
|
||||
class MyInt(int): ...
|
||||
|
||||
|
||||
# No error for a subclass of int
|
||||
# revealed: float
|
||||
reveal_type(MyInt(3) / 0)
|
||||
|
|
|
@ -10,14 +10,11 @@ class Multiplier:
|
|||
def __call__(self, number: float) -> float:
|
||||
return number * self.factor
|
||||
|
||||
|
||||
a = Multiplier(2.0)(3.0)
|
||||
reveal_type(a) # revealed: float
|
||||
|
||||
|
||||
class Unit: ...
|
||||
|
||||
|
||||
b = Unit()(3.0) # error: "Object of type `Unit` is not callable"
|
||||
reveal_type(b) # revealed: Unknown
|
||||
```
|
||||
|
|
|
@ -3,6 +3,5 @@
|
|||
```py
|
||||
class Foo: ...
|
||||
|
||||
|
||||
reveal_type(Foo()) # revealed: Foo
|
||||
```
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
def get_int() -> int:
|
||||
return 42
|
||||
|
||||
|
||||
reveal_type(get_int()) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -16,7 +15,6 @@ reveal_type(get_int()) # revealed: int
|
|||
async def get_int_async() -> int:
|
||||
return 42
|
||||
|
||||
|
||||
# TODO: we don't yet support `types.CoroutineType`, should be generic `Coroutine[Any, Any, int]`
|
||||
reveal_type(get_int_async()) # revealed: @Todo
|
||||
```
|
||||
|
@ -26,20 +24,16 @@ reveal_type(get_int_async()) # revealed: @Todo
|
|||
```py
|
||||
from typing import Callable
|
||||
|
||||
|
||||
def foo() -> int:
|
||||
return 42
|
||||
|
||||
|
||||
def decorator(func) -> Callable[[], int]:
|
||||
return foo
|
||||
|
||||
|
||||
@decorator
|
||||
def bar() -> str:
|
||||
return "bar"
|
||||
|
||||
|
||||
# TODO: should reveal `int`, as the decorator replaces `bar` with `foo`
|
||||
reveal_type(bar()) # revealed: @Todo
|
||||
```
|
||||
|
|
|
@ -13,7 +13,6 @@ else:
|
|||
def f() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
reveal_type(f()) # revealed: int | str
|
||||
```
|
||||
|
||||
|
@ -27,7 +26,6 @@ if flag:
|
|||
def f() -> int:
|
||||
return 1
|
||||
|
||||
|
||||
reveal_type(f()) # revealed: Unknown | int
|
||||
```
|
||||
|
||||
|
@ -43,7 +41,6 @@ else:
|
|||
def f() -> int:
|
||||
return 1
|
||||
|
||||
|
||||
x = f() # error: "Object of type `Literal[1] | Literal[f]` is not callable (due to union element `Literal[1]`)"
|
||||
reveal_type(x) # revealed: Unknown | int
|
||||
```
|
||||
|
@ -62,7 +59,6 @@ else:
|
|||
def f() -> int:
|
||||
return 1
|
||||
|
||||
|
||||
# error: "Object of type `Literal[1] | Literal["foo"] | Literal[f]` is not callable (due to union elements Literal[1], Literal["foo"])"
|
||||
# revealed: Unknown | int
|
||||
reveal_type(f())
|
||||
|
|
|
@ -21,7 +21,6 @@ reveal_type(1 <= "" and 0 < 1) # revealed: @Todo | Literal[True]
|
|||
# TODO: implement lookup of `__eq__` on typeshed `int` stub.
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
reveal_type(1 == int_instance()) # revealed: @Todo
|
||||
reveal_type(9 < int_instance()) # revealed: bool
|
||||
reveal_type(int_instance() < int_instance()) # revealed: bool
|
||||
|
|
|
@ -21,15 +21,15 @@ Walking through examples:
|
|||
```py
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class A:
|
||||
def __lt__(self, other) -> A: ...
|
||||
|
||||
class B:
|
||||
def __lt__(self, other) -> B: ...
|
||||
|
||||
class C:
|
||||
def __lt__(self, other) -> C: ...
|
||||
|
||||
|
||||
x = A() < B() < C()
|
||||
reveal_type(x) # revealed: A | B
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
```py
|
||||
def str_instance() -> str: ...
|
||||
|
||||
|
||||
reveal_type("abc" == "abc") # revealed: Literal[True]
|
||||
reveal_type("ab_cd" <= "ab_ce") # revealed: Literal[True]
|
||||
reveal_type("abc" in "ab cd") # revealed: Literal[False]
|
||||
|
|
|
@ -61,7 +61,6 @@ reveal_type(c >= d) # revealed: Literal[True]
|
|||
def bool_instance() -> bool: ...
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
a = (bool_instance(),)
|
||||
b = (int_instance(),)
|
||||
|
||||
|
@ -144,7 +143,6 @@ class A:
|
|||
def __gt__(self, o) -> tuple: ...
|
||||
def __ge__(self, o) -> list: ...
|
||||
|
||||
|
||||
a = (A(), A())
|
||||
|
||||
# TODO: All @Todo should be bool
|
||||
|
@ -163,7 +161,6 @@ reveal_type(a >= a) # revealed: @Todo
|
|||
```py
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
a = (1, 2)
|
||||
b = ((3, 4), (1, 2))
|
||||
c = ((1, 2, 3), (4, 5, 6))
|
||||
|
|
|
@ -40,7 +40,6 @@ to the `except` suite *after* that redefinition.
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -63,7 +62,6 @@ unify and `x` is not inferred as having a union type following the
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -88,7 +86,6 @@ possibility when it comes to control-flow analysis.
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -119,7 +116,6 @@ the three suites:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -153,7 +149,6 @@ the end of the `except` suite:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -182,7 +177,6 @@ in their entireties:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -216,7 +210,6 @@ therefore `Literal[2]`:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -244,7 +237,6 @@ suites, however; this is still a TODO item for us.)
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -277,15 +269,12 @@ following possibilities inside `finally` suites:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -318,15 +307,12 @@ conclusion of the `finally` suite.)
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -352,23 +338,18 @@ An example with multiple `except` branches and a `finally` branch:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -404,23 +385,18 @@ partway through the `else` suite due to an exception raised *there*.
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -452,31 +428,24 @@ The same again, this time with multiple `except` branches:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
def could_raise_returns_range() -> range:
|
||||
return range(42)
|
||||
|
||||
|
||||
def could_raise_returns_slice() -> slice:
|
||||
return slice(None)
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -524,53 +493,39 @@ prior to the suite running to completion.
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
def could_raise_returns_range() -> range:
|
||||
return range(42)
|
||||
|
||||
|
||||
def could_raise_returns_slice() -> slice:
|
||||
return slice(None)
|
||||
|
||||
|
||||
def could_raise_returns_complex() -> complex:
|
||||
return 3j
|
||||
|
||||
|
||||
def could_raise_returns_bytearray() -> bytearray:
|
||||
return bytearray()
|
||||
|
||||
|
||||
class Foo: ...
|
||||
|
||||
|
||||
class Bar: ...
|
||||
|
||||
|
||||
def could_raise_returns_Foo() -> Foo:
|
||||
return Foo()
|
||||
|
||||
|
||||
def could_raise_returns_Bar() -> Bar:
|
||||
return Bar()
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -632,23 +587,18 @@ variable by that name in the outer scope:
|
|||
def could_raise_returns_str() -> str:
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_range() -> range:
|
||||
return range(42)
|
||||
|
||||
|
||||
def could_raise_returns_bytearray() -> bytearray:
|
||||
return bytearray()
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -670,7 +620,6 @@ try:
|
|||
# TODO: should be `str | bytes | bytearray | float`
|
||||
reveal_type(x) # revealed: bytes | float
|
||||
reveal_type(x) # revealed: bytes | float
|
||||
|
||||
x = foo
|
||||
reveal_type(x) # revealed: Literal[foo]
|
||||
except:
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
def foo() -> str:
|
||||
pass
|
||||
|
||||
|
||||
reveal_type(True or False) # revealed: Literal[True]
|
||||
reveal_type("x" or "y" or "z") # revealed: Literal["x"]
|
||||
reveal_type("" or "y" or "z") # revealed: Literal["y"]
|
||||
|
@ -23,7 +22,6 @@ reveal_type(foo() or True) # revealed: str | Literal[True]
|
|||
def foo() -> str:
|
||||
pass
|
||||
|
||||
|
||||
reveal_type(True and False) # revealed: Literal[False]
|
||||
reveal_type(False and True) # revealed: Literal[False]
|
||||
reveal_type(foo() and False) # revealed: str | Literal[False]
|
||||
|
@ -39,7 +37,6 @@ reveal_type("" and "y") # revealed: Literal[""]
|
|||
def returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
if returns_bool():
|
||||
x = True
|
||||
else:
|
||||
|
@ -54,7 +51,6 @@ reveal_type(x) # revealed: bool
|
|||
def foo() -> str:
|
||||
pass
|
||||
|
||||
|
||||
reveal_type("x" and "y" or "z") # revealed: Literal["y"]
|
||||
reveal_type("x" or "y" and "z") # revealed: Literal["x"]
|
||||
reveal_type("" and "y" or "z") # revealed: Literal["z"]
|
||||
|
@ -70,7 +66,6 @@ reveal_type("x" or "y" and "") # revealed: Literal["x"]
|
|||
```py path=a.py
|
||||
redefined_builtin_bool = bool
|
||||
|
||||
|
||||
def my_bool(x) -> bool:
|
||||
return True
|
||||
```
|
||||
|
@ -90,10 +85,8 @@ reveal_type(bool((0,))) # revealed: Literal[True]
|
|||
reveal_type(bool("NON EMPTY")) # revealed: Literal[True]
|
||||
reveal_type(bool(True)) # revealed: Literal[True]
|
||||
|
||||
|
||||
def foo(): ...
|
||||
|
||||
|
||||
reveal_type(bool(foo)) # revealed: Literal[True]
|
||||
```
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ class MyBox[T]:
|
|||
def __init__(self, data: T):
|
||||
self.data = data
|
||||
|
||||
|
||||
# TODO not error (should be subscriptable)
|
||||
box: MyBox[int] = MyBox(5) # error: [non-subscriptable]
|
||||
# TODO error differently (str and int don't unify)
|
||||
|
@ -32,11 +31,9 @@ class MyBox[T]:
|
|||
def __init__(self, data: T):
|
||||
self.data = data
|
||||
|
||||
|
||||
# TODO not error on the subscripting
|
||||
class MySecureBox[T](MyBox[T]): ... # error: [non-subscriptable]
|
||||
|
||||
|
||||
secure_box: MySecureBox[int] = MySecureBox(5)
|
||||
reveal_type(secure_box) # revealed: MySecureBox
|
||||
# TODO reveal int
|
||||
|
@ -52,10 +49,8 @@ This should hold true even with generics at play.
|
|||
```py path=a.pyi
|
||||
class Seq[T]: ...
|
||||
|
||||
|
||||
# TODO not error on the subscripting
|
||||
class S[T](Seq[S]): ... # error: [non-subscriptable]
|
||||
|
||||
|
||||
reveal_type(S) # revealed: Literal[S]
|
||||
```
|
||||
|
|
|
@ -7,12 +7,10 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
|
||||
for x in IntIterable():
|
||||
pass
|
||||
|
||||
|
@ -26,12 +24,10 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
|
||||
x = "foo"
|
||||
|
||||
for x in IntIterable():
|
||||
|
@ -47,12 +43,10 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
|
||||
for x in IntIterable():
|
||||
pass
|
||||
else:
|
||||
|
@ -68,12 +62,10 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
|
||||
for x in IntIterable():
|
||||
if x > 5:
|
||||
break
|
||||
|
@ -90,7 +82,6 @@ class OldStyleIterable:
|
|||
def __getitem__(self, key: int) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
for x in OldStyleIterable():
|
||||
pass
|
||||
|
||||
|
@ -115,7 +106,6 @@ class NotIterable:
|
|||
else:
|
||||
__iter__ = None
|
||||
|
||||
|
||||
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
|
||||
pass
|
||||
|
||||
|
@ -136,10 +126,8 @@ for x in nonsense: # error: "Object of type `Literal[123]` is not iterable"
|
|||
class NotIterable:
|
||||
def __getitem__(self, key: int) -> int:
|
||||
return 42
|
||||
|
||||
__iter__ = None
|
||||
|
||||
|
||||
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
|
||||
pass
|
||||
```
|
||||
|
|
|
@ -5,16 +5,13 @@
|
|||
```py
|
||||
class NotIterable: ...
|
||||
|
||||
|
||||
class Iterator:
|
||||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class Iterable:
|
||||
def __iter__(self) -> Iterator: ...
|
||||
|
||||
|
||||
def generator_function():
|
||||
yield from Iterable()
|
||||
yield from NotIterable() # error: "Object of type `NotIterable` is not iterable"
|
||||
|
|
|
@ -16,7 +16,6 @@ reveal_type(x) # revealed: None | Literal[1]
|
|||
```py
|
||||
class A: ...
|
||||
|
||||
|
||||
x = A()
|
||||
y = x if flag else None
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
```py
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
x = int_instance()
|
||||
|
||||
if x != 1:
|
||||
|
|
|
@ -31,11 +31,8 @@ if x != 1:
|
|||
|
||||
```py
|
||||
class A: ...
|
||||
|
||||
|
||||
class B: ...
|
||||
|
||||
|
||||
C = A if flag else B
|
||||
|
||||
if C != A:
|
||||
|
@ -49,7 +46,6 @@ Only single-valued types should narrow the type:
|
|||
```py
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
x = int_instance() if flag else None
|
||||
y = int_instance()
|
||||
|
||||
|
|
|
@ -66,14 +66,10 @@ if isinstance(x, (bool, (bytes, int))):
|
|||
|
||||
```py
|
||||
class A: ...
|
||||
|
||||
|
||||
class B: ...
|
||||
|
||||
|
||||
def get_object() -> object: ...
|
||||
|
||||
|
||||
x = get_object()
|
||||
|
||||
if isinstance(x, A):
|
||||
|
@ -101,7 +97,6 @@ if isinstance(x, t):
|
|||
def isinstance(x, t):
|
||||
return True
|
||||
|
||||
|
||||
x = 1 if flag else "a"
|
||||
if isinstance(x, int):
|
||||
reveal_type(x) # revealed: Literal[1] | Literal["a"]
|
||||
|
|
|
@ -9,11 +9,9 @@ with the conditionally-defined type:
|
|||
def returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
if returns_bool():
|
||||
copyright = 1
|
||||
|
||||
|
||||
def f():
|
||||
reveal_type(copyright) # revealed: Literal[copyright] | Literal[1]
|
||||
```
|
||||
|
@ -26,11 +24,9 @@ Same is true if the name is annotated:
|
|||
def returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
if returns_bool():
|
||||
copyright: int = 1
|
||||
|
||||
|
||||
def f():
|
||||
reveal_type(copyright) # revealed: Literal[copyright] | int
|
||||
```
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
```py
|
||||
class C: ...
|
||||
|
||||
|
||||
C = 1 # error: "Implicit shadowing of class `C`; annotate to make it explicit if this is intentional"
|
||||
```
|
||||
|
||||
|
@ -16,6 +15,5 @@ No diagnostic is raised in the case of explicit shadowing:
|
|||
```py
|
||||
class C: ...
|
||||
|
||||
|
||||
C: int = 1
|
||||
```
|
||||
|
|
|
@ -14,7 +14,6 @@ def f(x: str):
|
|||
```py path=a.py
|
||||
def f(): ...
|
||||
|
||||
|
||||
f = 1 # error: "Implicit shadowing of function `f`; annotate to make it explicit if this is intentional"
|
||||
```
|
||||
|
||||
|
@ -23,6 +22,5 @@ f = 1 # error: "Implicit shadowing of function `f`; annotate to make it explici
|
|||
```py path=a.py
|
||||
def f(): ...
|
||||
|
||||
|
||||
f: int = 1
|
||||
```
|
||||
|
|
|
@ -7,6 +7,5 @@ In type stubs, classes can reference themselves in their base class definitions.
|
|||
```py path=a.pyi
|
||||
class C(C): ...
|
||||
|
||||
|
||||
reveal_type(C) # revealed: Literal[C]
|
||||
```
|
||||
|
|
|
@ -28,7 +28,6 @@ reveal_type(y) # revealed: Unknown
|
|||
```py
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
a = b"abcde"[int_instance()]
|
||||
# TODO: Support overloads... Should be `bytes`
|
||||
reveal_type(a) # revealed: @Todo
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
```py
|
||||
class NotSubscriptable: ...
|
||||
|
||||
|
||||
a = NotSubscriptable[0] # error: "Cannot subscript object of type `Literal[NotSubscriptable]` with no `__class_getitem__` method"
|
||||
```
|
||||
|
||||
|
@ -16,7 +15,6 @@ class Identity:
|
|||
def __class_getitem__(cls, item: int) -> str:
|
||||
return item
|
||||
|
||||
|
||||
reveal_type(Identity[0]) # revealed: str
|
||||
```
|
||||
|
||||
|
@ -25,19 +23,16 @@ reveal_type(Identity[0]) # revealed: str
|
|||
```py
|
||||
flag = True
|
||||
|
||||
|
||||
class UnionClassGetItem:
|
||||
if flag:
|
||||
|
||||
def __class_getitem__(cls, item: int) -> str:
|
||||
return item
|
||||
|
||||
else:
|
||||
|
||||
def __class_getitem__(cls, item: int) -> int:
|
||||
return item
|
||||
|
||||
|
||||
reveal_type(UnionClassGetItem[0]) # revealed: str | int
|
||||
```
|
||||
|
||||
|
@ -46,17 +41,14 @@ reveal_type(UnionClassGetItem[0]) # revealed: str | int
|
|||
```py
|
||||
flag = True
|
||||
|
||||
|
||||
class A:
|
||||
def __class_getitem__(cls, item: int) -> str:
|
||||
return item
|
||||
|
||||
|
||||
class B:
|
||||
def __class_getitem__(cls, item: int) -> int:
|
||||
return item
|
||||
|
||||
|
||||
x = A if flag else B
|
||||
|
||||
reveal_type(x) # revealed: Literal[A, B]
|
||||
|
@ -69,16 +61,13 @@ reveal_type(x[0]) # revealed: str | int
|
|||
flag = True
|
||||
|
||||
if flag:
|
||||
|
||||
class Spam:
|
||||
def __class_getitem__(self, x: int) -> str:
|
||||
return "foo"
|
||||
|
||||
else:
|
||||
|
||||
class Spam: ...
|
||||
|
||||
|
||||
# error: [call-non-callable] "Method `__class_getitem__` of type `Literal[__class_getitem__] | Unbound` is not callable on object of type `Literal[Spam, Spam]`"
|
||||
# revealed: str | Unknown
|
||||
reveal_type(Spam[42])
|
||||
|
@ -90,7 +79,6 @@ reveal_type(Spam[42])
|
|||
flag = True
|
||||
|
||||
if flag:
|
||||
|
||||
class Eggs:
|
||||
def __class_getitem__(self, x: int) -> str:
|
||||
return "foo"
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
```py
|
||||
class NotSubscriptable: ...
|
||||
|
||||
|
||||
a = NotSubscriptable()[0] # error: "Cannot subscript object of type `NotSubscriptable` with no `__getitem__` method"
|
||||
```
|
||||
|
||||
|
@ -15,7 +14,6 @@ a = NotSubscriptable()[0] # error: "Cannot subscript object of type `NotSubscri
|
|||
class NotSubscriptable:
|
||||
__getitem__ = None
|
||||
|
||||
|
||||
a = NotSubscriptable()[0] # error: "Method `__getitem__` of type `None` is not callable on object of type `NotSubscriptable`"
|
||||
```
|
||||
|
||||
|
@ -26,7 +24,6 @@ class Identity:
|
|||
def __getitem__(self, index: int) -> int:
|
||||
return index
|
||||
|
||||
|
||||
reveal_type(Identity()[0]) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -35,18 +32,15 @@ reveal_type(Identity()[0]) # revealed: int
|
|||
```py
|
||||
flag = True
|
||||
|
||||
|
||||
class Identity:
|
||||
if flag:
|
||||
|
||||
def __getitem__(self, index: int) -> int:
|
||||
return index
|
||||
|
||||
else:
|
||||
|
||||
def __getitem__(self, index: int) -> str:
|
||||
return str(index)
|
||||
|
||||
|
||||
reveal_type(Identity()[0]) # revealed: int | str
|
||||
```
|
||||
|
|
|
@ -25,7 +25,6 @@ reveal_type(b) # revealed: Unknown
|
|||
```py
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
a = "abcde"[int_instance()]
|
||||
# TODO: Support overloads... Should be `str`
|
||||
reveal_type(a) # revealed: @Todo
|
||||
|
|
|
@ -14,17 +14,14 @@ class Number:
|
|||
def __invert__(self) -> Literal[True]:
|
||||
return True
|
||||
|
||||
|
||||
a = Number()
|
||||
|
||||
reveal_type(+a) # revealed: int
|
||||
reveal_type(-a) # revealed: int
|
||||
reveal_type(~a) # revealed: @Todo
|
||||
|
||||
|
||||
class NoDunder: ...
|
||||
|
||||
|
||||
b = NoDunder()
|
||||
+b # error: [unsupported-operator] "Unary operator `+` is unsupported for type `NoDunder`"
|
||||
-b # error: [unsupported-operator] "Unary operator `-` is unsupported for type `NoDunder`"
|
||||
|
|
|
@ -12,11 +12,9 @@ reveal_type(not not None) # revealed: Literal[False]
|
|||
```py
|
||||
from typing import reveal_type
|
||||
|
||||
|
||||
def f():
|
||||
return 1
|
||||
|
||||
|
||||
reveal_type(not f) # revealed: Literal[False]
|
||||
# TODO Unknown should not be part of the type of typing.reveal_type
|
||||
# reveal_type(not reveal_type) revealed: Literal[False]
|
||||
|
@ -28,7 +26,6 @@ reveal_type(not f) # revealed: Literal[False]
|
|||
import b
|
||||
import warnings
|
||||
|
||||
|
||||
reveal_type(not b) # revealed: Literal[False]
|
||||
reveal_type(not warnings) # revealed: Literal[False]
|
||||
```
|
||||
|
|
|
@ -155,12 +155,10 @@ class Iterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class Iterable:
|
||||
def __iter__(self) -> Iterator:
|
||||
return Iterator()
|
||||
|
||||
|
||||
(a, b) = Iterable()
|
||||
reveal_type(a) # revealed: int
|
||||
reveal_type(b) # revealed: int
|
||||
|
@ -173,12 +171,10 @@ class Iterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class Iterable:
|
||||
def __iter__(self) -> Iterator:
|
||||
return Iterator()
|
||||
|
||||
|
||||
(a, (b, c), d) = (1, Iterable(), 2)
|
||||
reveal_type(a) # revealed: Literal[1]
|
||||
reveal_type(b) # revealed: int
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue