[red-knot] Format mdtest Python snippets more concisely (#13905)

This commit is contained in:
Alex Waygood 2024-10-24 12:09:31 +01:00 committed by GitHub
parent 77ae0ccf0f
commit 3eb454699a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 4 additions and 193 deletions

View file

@ -46,10 +46,10 @@ repos:
)$ )$
- repo: https://github.com/adamchainz/blacken-docs - repo: https://github.com/adamchainz/blacken-docs
rev: 1.19.0 rev: 1.19.1
hooks: hooks:
- id: blacken-docs - id: blacken-docs
args: ["--line-length", "130"] args: ["--pyi", "--line-length", "130"]
files: '^crates/.*/resources/mdtest/.*\.md' files: '^crates/.*/resources/mdtest/.*\.md'
additional_dependencies: additional_dependencies:
- black==24.10.0 - black==24.10.0

View file

@ -15,13 +15,11 @@ Name lookups within a class scope fall back to globals, but lookups of class att
```py ```py
x = 1 x = 1
class C: class C:
y = x y = x
if flag: if flag:
x = 2 x = 2
reveal_type(C.x) # revealed: Literal[2] reveal_type(C.x) # revealed: Literal[2]
reveal_type(C.y) # revealed: Literal[1] reveal_type(C.y) # revealed: Literal[1]
``` ```

View file

@ -4,15 +4,12 @@
```py ```py
if flag: if flag:
class C: class C:
x = 1 x = 1
else: else:
class C: class C:
x = 2 x = 2
reveal_type(C.x) # revealed: Literal[1, 2] reveal_type(C.x) # revealed: Literal[1, 2]
``` ```

View file

@ -53,10 +53,8 @@ class A:
def __or__(self, other) -> A: def __or__(self, other) -> A:
return self return self
class B: ... class B: ...
reveal_type(A() + B()) # revealed: A reveal_type(A() + B()) # revealed: A
reveal_type(A() - B()) # revealed: A 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: def __ror__(self, other) -> A:
return self return self
class B: ... class B: ...
reveal_type(B() + A()) # revealed: A reveal_type(B() + A()) # revealed: A
reveal_type(B() - A()) # revealed: A 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: def __rsub__(self, other) -> int:
return 1 return 1
class B: ... class B: ...
reveal_type(A() + B()) # revealed: int reveal_type(A() + B()) # revealed: int
reveal_type(B() - A()) # revealed: int reveal_type(B() - A()) # revealed: int
``` ```
@ -167,15 +161,12 @@ class A:
def __add__(self, other: B) -> int: def __add__(self, other: B) -> int:
return 42 return 42
class B: class B:
def __radd__(self, other: A) -> str: def __radd__(self, other: A) -> str:
return "foo" return "foo"
reveal_type(A() + B()) # revealed: int reveal_type(A() + B()) # revealed: int
# Edge case: C is a subtype of C, *but* if the two sides are of *equal* types, # Edge case: C is a subtype of C, *but* if the two sides are of *equal* types,
# the lhs *still* takes precedence # the lhs *still* takes precedence
class C: class C:
@ -185,7 +176,6 @@ class C:
def __radd__(self, other: C) -> str: def __radd__(self, other: C) -> str:
return "foo" return "foo"
reveal_type(C() + C()) # revealed: int reveal_type(C() + C()) # revealed: int
``` ```
@ -203,22 +193,17 @@ class A:
def __radd__(self, other) -> str: def __radd__(self, other) -> str:
return "foo" return "foo"
class MyString(str): ... class MyString(str): ...
class B(A): class B(A):
def __radd__(self, other) -> MyString: def __radd__(self, other) -> MyString:
return MyString() return MyString()
reveal_type(A() + B()) # revealed: 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__` # N.B. Still a subtype of `A`, even though `A` does not appear directly in the class's `__bases__`
class C(B): ... class C(B): ...
# TODO: we currently only understand direct subclasses as subtypes of the superclass. # 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; # 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 # 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: def __radd__(self, other) -> int:
return 42 return 42
class B(A): ... class B(A): ...
reveal_type(A() + B()) # revealed: str reveal_type(A() + B()) # revealed: str
``` ```
@ -266,12 +249,10 @@ class A:
def __sub__(self, other: A) -> A: def __sub__(self, other: A) -> A:
return A() return A()
class B: class B:
def __rsub__(self, other: A) -> B: def __rsub__(self, other: A) -> B:
return B() return B()
# TODO: this should be `B` (the return annotation of `B.__rsub__`), # TODO: this should be `B` (the return annotation of `B.__rsub__`),
# because `A.__sub__` is annotated as only accepting `A`, # because `A.__sub__` is annotated as only accepting `A`,
# but `B.__rsub__` will accept `A`. # but `B.__rsub__` will accept `A`.
@ -287,11 +268,9 @@ class A:
def __call__(self, other) -> int: def __call__(self, other) -> int:
return 42 return 42
class B: class B:
__add__ = A() __add__ = A()
reveal_type(B() + B()) # revealed: int 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__` # TODO should be complex, need to check arg type and fall back to `rhs.__radd__`
reveal_type(3 + 3j) # revealed: int reveal_type(3 + 3j) # revealed: int
def returns_int() -> int: def returns_int() -> int:
return 42 return 42
def returns_bool() -> bool: def returns_bool() -> bool:
return True return True
x = returns_bool() x = returns_bool()
y = returns_int() y = returns_int()
@ -343,7 +319,6 @@ class A:
def __radd__(self, other) -> A: def __radd__(self, other) -> A:
return self return self
reveal_type(A() + 1) # revealed: A reveal_type(A() + 1) # revealed: A
# TODO should be `A` since `int.__add__` doesn't support `A` instances # TODO should be `A` since `int.__add__` doesn't support `A` instances
reveal_type(1 + A()) # revealed: int reveal_type(1 + A()) # revealed: int
@ -388,15 +363,12 @@ from does_not_exist import Foo # error: [unresolved-import]
reveal_type(Foo) # revealed: Unknown reveal_type(Foo) # revealed: Unknown
class X: class X:
def __add__(self, other: object) -> int: def __add__(self, other: object) -> int:
return 42 return 42
class Y(Foo): ... class Y(Foo): ...
# TODO: Should be `int | Unknown`; see above discussion. # TODO: Should be `int | Unknown`; see above discussion.
reveal_type(X() + Y()) # revealed: int 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: def add_impl(self, other) -> int:
return 1 return 1
class A: class A:
def __init__(self): def __init__(self):
self.__add__ = add_impl self.__add__ = add_impl
# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `A` and `A`" # error: [unsupported-operator] "Operator `+` is unsupported between objects of type `A` and `A`"
# revealed: Unknown # revealed: Unknown
reveal_type(A() + A()) reveal_type(A() + A())
@ -427,7 +397,6 @@ reveal_type(A() + A())
```py ```py
class A: ... class A: ...
# error: [unsupported-operator] # error: [unsupported-operator]
# revealed: Unknown # revealed: Unknown
reveal_type(A() + A()) 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: class A:
def __add__(self, other) -> int: ... def __add__(self, other) -> int: ...
class B: class B:
def __radd__(self, other) -> int: ... def __radd__(self, other) -> int: ...
class C: ... class C: ...
# error: [unsupported-operator] # error: [unsupported-operator]
# revealed: Unknown # revealed: Unknown
reveal_type(C() + A()) reveal_type(C() + A())
@ -471,7 +437,6 @@ class Foo:
def __radd__(self, other: Foo) -> Foo: def __radd__(self, other: Foo) -> Foo:
return self return self
# error: [unsupported-operator] # error: [unsupported-operator]
# revealed: Unknown # revealed: Unknown
reveal_type(Foo() + Foo()) reveal_type(Foo() + Foo())

View file

@ -62,10 +62,8 @@ bool(1) / False
# revealed: float # revealed: float
reveal_type(1.0 / 0) reveal_type(1.0 / 0)
class MyInt(int): ... class MyInt(int): ...
# No error for a subclass of int # No error for a subclass of int
# revealed: float # revealed: float
reveal_type(MyInt(3) / 0) reveal_type(MyInt(3) / 0)

View file

@ -10,14 +10,11 @@ class Multiplier:
def __call__(self, number: float) -> float: def __call__(self, number: float) -> float:
return number * self.factor return number * self.factor
a = Multiplier(2.0)(3.0) a = Multiplier(2.0)(3.0)
reveal_type(a) # revealed: float reveal_type(a) # revealed: float
class Unit: ... class Unit: ...
b = Unit()(3.0) # error: "Object of type `Unit` is not callable" b = Unit()(3.0) # error: "Object of type `Unit` is not callable"
reveal_type(b) # revealed: Unknown reveal_type(b) # revealed: Unknown
``` ```

View file

@ -3,6 +3,5 @@
```py ```py
class Foo: ... class Foo: ...
reveal_type(Foo()) # revealed: Foo reveal_type(Foo()) # revealed: Foo
``` ```

View file

@ -6,7 +6,6 @@
def get_int() -> int: def get_int() -> int:
return 42 return 42
reveal_type(get_int()) # revealed: int reveal_type(get_int()) # revealed: int
``` ```
@ -16,7 +15,6 @@ reveal_type(get_int()) # revealed: int
async def get_int_async() -> int: async def get_int_async() -> int:
return 42 return 42
# TODO: we don't yet support `types.CoroutineType`, should be generic `Coroutine[Any, Any, int]` # TODO: we don't yet support `types.CoroutineType`, should be generic `Coroutine[Any, Any, int]`
reveal_type(get_int_async()) # revealed: @Todo reveal_type(get_int_async()) # revealed: @Todo
``` ```
@ -26,20 +24,16 @@ reveal_type(get_int_async()) # revealed: @Todo
```py ```py
from typing import Callable from typing import Callable
def foo() -> int: def foo() -> int:
return 42 return 42
def decorator(func) -> Callable[[], int]: def decorator(func) -> Callable[[], int]:
return foo return foo
@decorator @decorator
def bar() -> str: def bar() -> str:
return "bar" return "bar"
# TODO: should reveal `int`, as the decorator replaces `bar` with `foo` # TODO: should reveal `int`, as the decorator replaces `bar` with `foo`
reveal_type(bar()) # revealed: @Todo reveal_type(bar()) # revealed: @Todo
``` ```

View file

@ -13,7 +13,6 @@ else:
def f() -> str: def f() -> str:
return "foo" return "foo"
reveal_type(f()) # revealed: int | str reveal_type(f()) # revealed: int | str
``` ```
@ -27,7 +26,6 @@ if flag:
def f() -> int: def f() -> int:
return 1 return 1
reveal_type(f()) # revealed: Unknown | int reveal_type(f()) # revealed: Unknown | int
``` ```
@ -43,7 +41,6 @@ else:
def f() -> int: def f() -> int:
return 1 return 1
x = f() # error: "Object of type `Literal[1] | Literal[f]` is not callable (due to union element `Literal[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 reveal_type(x) # revealed: Unknown | int
``` ```
@ -62,7 +59,6 @@ else:
def f() -> int: def f() -> int:
return 1 return 1
# error: "Object of type `Literal[1] | Literal["foo"] | Literal[f]` is not callable (due to union elements Literal[1], Literal["foo"])" # error: "Object of type `Literal[1] | Literal["foo"] | Literal[f]` is not callable (due to union elements Literal[1], Literal["foo"])"
# revealed: Unknown | int # revealed: Unknown | int
reveal_type(f()) reveal_type(f())

View file

@ -21,7 +21,6 @@ reveal_type(1 <= "" and 0 < 1) # revealed: @Todo | Literal[True]
# TODO: implement lookup of `__eq__` on typeshed `int` stub. # TODO: implement lookup of `__eq__` on typeshed `int` stub.
def int_instance() -> int: ... def int_instance() -> int: ...
reveal_type(1 == int_instance()) # revealed: @Todo reveal_type(1 == int_instance()) # revealed: @Todo
reveal_type(9 < int_instance()) # revealed: bool reveal_type(9 < int_instance()) # revealed: bool
reveal_type(int_instance() < int_instance()) # revealed: bool reveal_type(int_instance() < int_instance()) # revealed: bool

View file

@ -21,15 +21,15 @@ Walking through examples:
```py ```py
from __future__ import annotations from __future__ import annotations
class A: class A:
def __lt__(self, other) -> A: ... def __lt__(self, other) -> A: ...
class B: class B:
def __lt__(self, other) -> B: ... def __lt__(self, other) -> B: ...
class C: class C:
def __lt__(self, other) -> C: ... def __lt__(self, other) -> C: ...
x = A() < B() < C() x = A() < B() < C()
reveal_type(x) # revealed: A | B reveal_type(x) # revealed: A | B

View file

@ -5,7 +5,6 @@
```py ```py
def str_instance() -> str: ... def str_instance() -> str: ...
reveal_type("abc" == "abc") # revealed: Literal[True] reveal_type("abc" == "abc") # revealed: Literal[True]
reveal_type("ab_cd" <= "ab_ce") # revealed: Literal[True] reveal_type("ab_cd" <= "ab_ce") # revealed: Literal[True]
reveal_type("abc" in "ab cd") # revealed: Literal[False] reveal_type("abc" in "ab cd") # revealed: Literal[False]

View file

@ -61,7 +61,6 @@ reveal_type(c >= d) # revealed: Literal[True]
def bool_instance() -> bool: ... def bool_instance() -> bool: ...
def int_instance() -> int: ... def int_instance() -> int: ...
a = (bool_instance(),) a = (bool_instance(),)
b = (int_instance(),) b = (int_instance(),)
@ -144,7 +143,6 @@ class A:
def __gt__(self, o) -> tuple: ... def __gt__(self, o) -> tuple: ...
def __ge__(self, o) -> list: ... def __ge__(self, o) -> list: ...
a = (A(), A()) a = (A(), A())
# TODO: All @Todo should be bool # TODO: All @Todo should be bool
@ -163,7 +161,6 @@ reveal_type(a >= a) # revealed: @Todo
```py ```py
def int_instance() -> int: ... def int_instance() -> int: ...
a = (1, 2) a = (1, 2)
b = ((3, 4), (1, 2)) b = ((3, 4), (1, 2))
c = ((1, 2, 3), (4, 5, 6)) c = ((1, 2, 3), (4, 5, 6))

View file

@ -40,7 +40,6 @@ to the `except` suite *after* that redefinition.
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -63,7 +62,6 @@ unify and `x` is not inferred as having a union type following the
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -88,7 +86,6 @@ possibility when it comes to control-flow analysis.
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -119,7 +116,6 @@ the three suites:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -153,7 +149,6 @@ the end of the `except` suite:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -182,7 +177,6 @@ in their entireties:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -216,7 +210,6 @@ therefore `Literal[2]`:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -244,7 +237,6 @@ suites, however; this is still a TODO item for us.)
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
x = 1 x = 1
try: try:
@ -277,15 +269,12 @@ following possibilities inside `finally` suites:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
def could_raise_returns_bytes() -> bytes: def could_raise_returns_bytes() -> bytes:
return b"foo" return b"foo"
def could_raise_returns_bool() -> bool: def could_raise_returns_bool() -> bool:
return True return True
x = 1 x = 1
try: try:
@ -318,15 +307,12 @@ conclusion of the `finally` suite.)
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
def could_raise_returns_bytes() -> bytes: def could_raise_returns_bytes() -> bytes:
return b"foo" return b"foo"
def could_raise_returns_bool() -> bool: def could_raise_returns_bool() -> bool:
return True return True
x = 1 x = 1
try: try:
@ -352,23 +338,18 @@ An example with multiple `except` branches and a `finally` branch:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
def could_raise_returns_bytes() -> bytes: def could_raise_returns_bytes() -> bytes:
return b"foo" return b"foo"
def could_raise_returns_bool() -> bool: def could_raise_returns_bool() -> bool:
return True return True
def could_raise_returns_memoryview() -> memoryview: def could_raise_returns_memoryview() -> memoryview:
return memoryview(b"") return memoryview(b"")
def could_raise_returns_float() -> float: def could_raise_returns_float() -> float:
return 3.14 return 3.14
x = 1 x = 1
try: try:
@ -404,23 +385,18 @@ partway through the `else` suite due to an exception raised *there*.
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
def could_raise_returns_bytes() -> bytes: def could_raise_returns_bytes() -> bytes:
return b"foo" return b"foo"
def could_raise_returns_bool() -> bool: def could_raise_returns_bool() -> bool:
return True return True
def could_raise_returns_memoryview() -> memoryview: def could_raise_returns_memoryview() -> memoryview:
return memoryview(b"") return memoryview(b"")
def could_raise_returns_float() -> float: def could_raise_returns_float() -> float:
return 3.14 return 3.14
x = 1 x = 1
try: try:
@ -452,31 +428,24 @@ The same again, this time with multiple `except` branches:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
def could_raise_returns_bytes() -> bytes: def could_raise_returns_bytes() -> bytes:
return b"foo" return b"foo"
def could_raise_returns_bool() -> bool: def could_raise_returns_bool() -> bool:
return True return True
def could_raise_returns_memoryview() -> memoryview: def could_raise_returns_memoryview() -> memoryview:
return memoryview(b"") return memoryview(b"")
def could_raise_returns_float() -> float: def could_raise_returns_float() -> float:
return 3.14 return 3.14
def could_raise_returns_range() -> range: def could_raise_returns_range() -> range:
return range(42) return range(42)
def could_raise_returns_slice() -> slice: def could_raise_returns_slice() -> slice:
return slice(None) return slice(None)
x = 1 x = 1
try: try:
@ -524,53 +493,39 @@ prior to the suite running to completion.
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
def could_raise_returns_bytes() -> bytes: def could_raise_returns_bytes() -> bytes:
return b"foo" return b"foo"
def could_raise_returns_bool() -> bool: def could_raise_returns_bool() -> bool:
return True return True
def could_raise_returns_memoryview() -> memoryview: def could_raise_returns_memoryview() -> memoryview:
return memoryview(b"") return memoryview(b"")
def could_raise_returns_float() -> float: def could_raise_returns_float() -> float:
return 3.14 return 3.14
def could_raise_returns_range() -> range: def could_raise_returns_range() -> range:
return range(42) return range(42)
def could_raise_returns_slice() -> slice: def could_raise_returns_slice() -> slice:
return slice(None) return slice(None)
def could_raise_returns_complex() -> complex: def could_raise_returns_complex() -> complex:
return 3j return 3j
def could_raise_returns_bytearray() -> bytearray: def could_raise_returns_bytearray() -> bytearray:
return bytearray() return bytearray()
class Foo: ... class Foo: ...
class Bar: ... class Bar: ...
def could_raise_returns_Foo() -> Foo: def could_raise_returns_Foo() -> Foo:
return Foo() return Foo()
def could_raise_returns_Bar() -> Bar: def could_raise_returns_Bar() -> Bar:
return Bar() return Bar()
x = 1 x = 1
try: try:
@ -632,23 +587,18 @@ variable by that name in the outer scope:
def could_raise_returns_str() -> str: def could_raise_returns_str() -> str:
return "foo" return "foo"
def could_raise_returns_bytes() -> bytes: def could_raise_returns_bytes() -> bytes:
return b"foo" return b"foo"
def could_raise_returns_range() -> range: def could_raise_returns_range() -> range:
return range(42) return range(42)
def could_raise_returns_bytearray() -> bytearray: def could_raise_returns_bytearray() -> bytearray:
return bytearray() return bytearray()
def could_raise_returns_float() -> float: def could_raise_returns_float() -> float:
return 3.14 return 3.14
x = 1 x = 1
try: try:
@ -670,7 +620,6 @@ try:
# TODO: should be `str | bytes | bytearray | float` # TODO: should be `str | bytes | bytearray | float`
reveal_type(x) # revealed: bytes | float reveal_type(x) # revealed: bytes | float
reveal_type(x) # revealed: bytes | float reveal_type(x) # revealed: bytes | float
x = foo x = foo
reveal_type(x) # revealed: Literal[foo] reveal_type(x) # revealed: Literal[foo]
except: except:

View file

@ -6,7 +6,6 @@
def foo() -> str: def foo() -> str:
pass pass
reveal_type(True or False) # revealed: Literal[True] reveal_type(True or False) # revealed: Literal[True]
reveal_type("x" or "y" or "z") # revealed: Literal["x"] reveal_type("x" or "y" or "z") # revealed: Literal["x"]
reveal_type("" or "y" or "z") # revealed: Literal["y"] 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: def foo() -> str:
pass pass
reveal_type(True and False) # revealed: Literal[False] reveal_type(True and False) # revealed: Literal[False]
reveal_type(False and True) # revealed: Literal[False] reveal_type(False and True) # revealed: Literal[False]
reveal_type(foo() and False) # revealed: str | 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: def returns_bool() -> bool:
return True return True
if returns_bool(): if returns_bool():
x = True x = True
else: else:
@ -54,7 +51,6 @@ reveal_type(x) # revealed: bool
def foo() -> str: def foo() -> str:
pass pass
reveal_type("x" and "y" or "z") # revealed: Literal["y"] reveal_type("x" and "y" or "z") # revealed: Literal["y"]
reveal_type("x" or "y" and "z") # revealed: Literal["x"] reveal_type("x" or "y" and "z") # revealed: Literal["x"]
reveal_type("" and "y" or "z") # revealed: Literal["z"] 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 ```py path=a.py
redefined_builtin_bool = bool redefined_builtin_bool = bool
def my_bool(x) -> bool: def my_bool(x) -> bool:
return True return True
``` ```
@ -90,10 +85,8 @@ reveal_type(bool((0,))) # revealed: Literal[True]
reveal_type(bool("NON EMPTY")) # revealed: Literal[True] reveal_type(bool("NON EMPTY")) # revealed: Literal[True]
reveal_type(bool(True)) # revealed: Literal[True] reveal_type(bool(True)) # revealed: Literal[True]
def foo(): ... def foo(): ...
reveal_type(bool(foo)) # revealed: Literal[True] reveal_type(bool(foo)) # revealed: Literal[True]
``` ```

View file

@ -12,7 +12,6 @@ class MyBox[T]:
def __init__(self, data: T): def __init__(self, data: T):
self.data = data self.data = data
# TODO not error (should be subscriptable) # TODO not error (should be subscriptable)
box: MyBox[int] = MyBox(5) # error: [non-subscriptable] box: MyBox[int] = MyBox(5) # error: [non-subscriptable]
# TODO error differently (str and int don't unify) # TODO error differently (str and int don't unify)
@ -32,11 +31,9 @@ class MyBox[T]:
def __init__(self, data: T): def __init__(self, data: T):
self.data = data self.data = data
# TODO not error on the subscripting # TODO not error on the subscripting
class MySecureBox[T](MyBox[T]): ... # error: [non-subscriptable] class MySecureBox[T](MyBox[T]): ... # error: [non-subscriptable]
secure_box: MySecureBox[int] = MySecureBox(5) secure_box: MySecureBox[int] = MySecureBox(5)
reveal_type(secure_box) # revealed: MySecureBox reveal_type(secure_box) # revealed: MySecureBox
# TODO reveal int # TODO reveal int
@ -52,10 +49,8 @@ This should hold true even with generics at play.
```py path=a.pyi ```py path=a.pyi
class Seq[T]: ... class Seq[T]: ...
# TODO not error on the subscripting # TODO not error on the subscripting
class S[T](Seq[S]): ... # error: [non-subscriptable] class S[T](Seq[S]): ... # error: [non-subscriptable]
reveal_type(S) # revealed: Literal[S] reveal_type(S) # revealed: Literal[S]
``` ```

View file

@ -7,12 +7,10 @@ class IntIterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
class IntIterable: class IntIterable:
def __iter__(self) -> IntIterator: def __iter__(self) -> IntIterator:
return IntIterator() return IntIterator()
for x in IntIterable(): for x in IntIterable():
pass pass
@ -26,12 +24,10 @@ class IntIterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
class IntIterable: class IntIterable:
def __iter__(self) -> IntIterator: def __iter__(self) -> IntIterator:
return IntIterator() return IntIterator()
x = "foo" x = "foo"
for x in IntIterable(): for x in IntIterable():
@ -47,12 +43,10 @@ class IntIterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
class IntIterable: class IntIterable:
def __iter__(self) -> IntIterator: def __iter__(self) -> IntIterator:
return IntIterator() return IntIterator()
for x in IntIterable(): for x in IntIterable():
pass pass
else: else:
@ -68,12 +62,10 @@ class IntIterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
class IntIterable: class IntIterable:
def __iter__(self) -> IntIterator: def __iter__(self) -> IntIterator:
return IntIterator() return IntIterator()
for x in IntIterable(): for x in IntIterable():
if x > 5: if x > 5:
break break
@ -90,7 +82,6 @@ class OldStyleIterable:
def __getitem__(self, key: int) -> int: def __getitem__(self, key: int) -> int:
return 42 return 42
for x in OldStyleIterable(): for x in OldStyleIterable():
pass pass
@ -115,7 +106,6 @@ class NotIterable:
else: else:
__iter__ = None __iter__ = None
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable" for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
pass pass
@ -136,10 +126,8 @@ for x in nonsense: # error: "Object of type `Literal[123]` is not iterable"
class NotIterable: class NotIterable:
def __getitem__(self, key: int) -> int: def __getitem__(self, key: int) -> int:
return 42 return 42
__iter__ = None __iter__ = None
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable" for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
pass pass
``` ```

View file

@ -5,16 +5,13 @@
```py ```py
class NotIterable: ... class NotIterable: ...
class Iterator: class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
class Iterable: class Iterable:
def __iter__(self) -> Iterator: ... def __iter__(self) -> Iterator: ...
def generator_function(): def generator_function():
yield from Iterable() yield from Iterable()
yield from NotIterable() # error: "Object of type `NotIterable` is not iterable" yield from NotIterable() # error: "Object of type `NotIterable` is not iterable"

View file

@ -16,7 +16,6 @@ reveal_type(x) # revealed: None | Literal[1]
```py ```py
class A: ... class A: ...
x = A() x = A()
y = x if flag else None y = x if flag else None

View file

@ -5,7 +5,6 @@
```py ```py
def int_instance() -> int: ... def int_instance() -> int: ...
x = int_instance() x = int_instance()
if x != 1: if x != 1:

View file

@ -31,11 +31,8 @@ if x != 1:
```py ```py
class A: ... class A: ...
class B: ... class B: ...
C = A if flag else B C = A if flag else B
if C != A: if C != A:
@ -49,7 +46,6 @@ Only single-valued types should narrow the type:
```py ```py
def int_instance() -> int: ... def int_instance() -> int: ...
x = int_instance() if flag else None x = int_instance() if flag else None
y = int_instance() y = int_instance()

View file

@ -66,14 +66,10 @@ if isinstance(x, (bool, (bytes, int))):
```py ```py
class A: ... class A: ...
class B: ... class B: ...
def get_object() -> object: ... def get_object() -> object: ...
x = get_object() x = get_object()
if isinstance(x, A): if isinstance(x, A):
@ -101,7 +97,6 @@ if isinstance(x, t):
def isinstance(x, t): def isinstance(x, t):
return True return True
x = 1 if flag else "a" x = 1 if flag else "a"
if isinstance(x, int): if isinstance(x, int):
reveal_type(x) # revealed: Literal[1] | Literal["a"] reveal_type(x) # revealed: Literal[1] | Literal["a"]

View file

@ -9,11 +9,9 @@ with the conditionally-defined type:
def returns_bool() -> bool: def returns_bool() -> bool:
return True return True
if returns_bool(): if returns_bool():
copyright = 1 copyright = 1
def f(): def f():
reveal_type(copyright) # revealed: Literal[copyright] | Literal[1] reveal_type(copyright) # revealed: Literal[copyright] | Literal[1]
``` ```
@ -26,11 +24,9 @@ Same is true if the name is annotated:
def returns_bool() -> bool: def returns_bool() -> bool:
return True return True
if returns_bool(): if returns_bool():
copyright: int = 1 copyright: int = 1
def f(): def f():
reveal_type(copyright) # revealed: Literal[copyright] | int reveal_type(copyright) # revealed: Literal[copyright] | int
``` ```

View file

@ -5,7 +5,6 @@
```py ```py
class C: ... class C: ...
C = 1 # error: "Implicit shadowing of class `C`; annotate to make it explicit if this is intentional" 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 ```py
class C: ... class C: ...
C: int = 1 C: int = 1
``` ```

View file

@ -14,7 +14,6 @@ def f(x: str):
```py path=a.py ```py path=a.py
def f(): ... def f(): ...
f = 1 # error: "Implicit shadowing of function `f`; annotate to make it explicit if this is intentional" 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 ```py path=a.py
def f(): ... def f(): ...
f: int = 1 f: int = 1
``` ```

View file

@ -7,6 +7,5 @@ In type stubs, classes can reference themselves in their base class definitions.
```py path=a.pyi ```py path=a.pyi
class C(C): ... class C(C): ...
reveal_type(C) # revealed: Literal[C] reveal_type(C) # revealed: Literal[C]
``` ```

View file

@ -28,7 +28,6 @@ reveal_type(y) # revealed: Unknown
```py ```py
def int_instance() -> int: ... def int_instance() -> int: ...
a = b"abcde"[int_instance()] a = b"abcde"[int_instance()]
# TODO: Support overloads... Should be `bytes` # TODO: Support overloads... Should be `bytes`
reveal_type(a) # revealed: @Todo reveal_type(a) # revealed: @Todo

View file

@ -5,7 +5,6 @@
```py ```py
class NotSubscriptable: ... class NotSubscriptable: ...
a = NotSubscriptable[0] # error: "Cannot subscript object of type `Literal[NotSubscriptable]` with no `__class_getitem__` method" 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: def __class_getitem__(cls, item: int) -> str:
return item return item
reveal_type(Identity[0]) # revealed: str reveal_type(Identity[0]) # revealed: str
``` ```
@ -25,19 +23,16 @@ reveal_type(Identity[0]) # revealed: str
```py ```py
flag = True flag = True
class UnionClassGetItem: class UnionClassGetItem:
if flag: if flag:
def __class_getitem__(cls, item: int) -> str: def __class_getitem__(cls, item: int) -> str:
return item return item
else: else:
def __class_getitem__(cls, item: int) -> int: def __class_getitem__(cls, item: int) -> int:
return item return item
reveal_type(UnionClassGetItem[0]) # revealed: str | int reveal_type(UnionClassGetItem[0]) # revealed: str | int
``` ```
@ -46,17 +41,14 @@ reveal_type(UnionClassGetItem[0]) # revealed: str | int
```py ```py
flag = True flag = True
class A: class A:
def __class_getitem__(cls, item: int) -> str: def __class_getitem__(cls, item: int) -> str:
return item return item
class B: class B:
def __class_getitem__(cls, item: int) -> int: def __class_getitem__(cls, item: int) -> int:
return item return item
x = A if flag else B x = A if flag else B
reveal_type(x) # revealed: Literal[A, B] reveal_type(x) # revealed: Literal[A, B]
@ -69,16 +61,13 @@ reveal_type(x[0]) # revealed: str | int
flag = True flag = True
if flag: if flag:
class Spam: class Spam:
def __class_getitem__(self, x: int) -> str: def __class_getitem__(self, x: int) -> str:
return "foo" return "foo"
else: else:
class Spam: ... 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]`" # 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 # revealed: str | Unknown
reveal_type(Spam[42]) reveal_type(Spam[42])
@ -90,7 +79,6 @@ reveal_type(Spam[42])
flag = True flag = True
if flag: if flag:
class Eggs: class Eggs:
def __class_getitem__(self, x: int) -> str: def __class_getitem__(self, x: int) -> str:
return "foo" return "foo"

View file

@ -5,7 +5,6 @@
```py ```py
class NotSubscriptable: ... class NotSubscriptable: ...
a = NotSubscriptable()[0] # error: "Cannot subscript object of type `NotSubscriptable` with no `__getitem__` method" 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: class NotSubscriptable:
__getitem__ = None __getitem__ = None
a = NotSubscriptable()[0] # error: "Method `__getitem__` of type `None` is not callable on object of type `NotSubscriptable`" 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: def __getitem__(self, index: int) -> int:
return index return index
reveal_type(Identity()[0]) # revealed: int reveal_type(Identity()[0]) # revealed: int
``` ```
@ -35,18 +32,15 @@ reveal_type(Identity()[0]) # revealed: int
```py ```py
flag = True flag = True
class Identity: class Identity:
if flag: if flag:
def __getitem__(self, index: int) -> int: def __getitem__(self, index: int) -> int:
return index return index
else: else:
def __getitem__(self, index: int) -> str: def __getitem__(self, index: int) -> str:
return str(index) return str(index)
reveal_type(Identity()[0]) # revealed: int | str reveal_type(Identity()[0]) # revealed: int | str
``` ```

View file

@ -25,7 +25,6 @@ reveal_type(b) # revealed: Unknown
```py ```py
def int_instance() -> int: ... def int_instance() -> int: ...
a = "abcde"[int_instance()] a = "abcde"[int_instance()]
# TODO: Support overloads... Should be `str` # TODO: Support overloads... Should be `str`
reveal_type(a) # revealed: @Todo reveal_type(a) # revealed: @Todo

View file

@ -14,17 +14,14 @@ class Number:
def __invert__(self) -> Literal[True]: def __invert__(self) -> Literal[True]:
return True return True
a = Number() a = Number()
reveal_type(+a) # revealed: int reveal_type(+a) # revealed: int
reveal_type(-a) # revealed: int reveal_type(-a) # revealed: int
reveal_type(~a) # revealed: @Todo reveal_type(~a) # revealed: @Todo
class NoDunder: ... class NoDunder: ...
b = 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`"
-b # error: [unsupported-operator] "Unary operator `-` is unsupported for type `NoDunder`" -b # error: [unsupported-operator] "Unary operator `-` is unsupported for type `NoDunder`"

View file

@ -12,11 +12,9 @@ reveal_type(not not None) # revealed: Literal[False]
```py ```py
from typing import reveal_type from typing import reveal_type
def f(): def f():
return 1 return 1
reveal_type(not f) # revealed: Literal[False] reveal_type(not f) # revealed: Literal[False]
# TODO Unknown should not be part of the type of typing.reveal_type # TODO Unknown should not be part of the type of typing.reveal_type
# reveal_type(not reveal_type) revealed: Literal[False] # reveal_type(not reveal_type) revealed: Literal[False]
@ -28,7 +26,6 @@ reveal_type(not f) # revealed: Literal[False]
import b import b
import warnings import warnings
reveal_type(not b) # revealed: Literal[False] reveal_type(not b) # revealed: Literal[False]
reveal_type(not warnings) # revealed: Literal[False] reveal_type(not warnings) # revealed: Literal[False]
``` ```

View file

@ -155,12 +155,10 @@ class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
class Iterable: class Iterable:
def __iter__(self) -> Iterator: def __iter__(self) -> Iterator:
return Iterator() return Iterator()
(a, b) = Iterable() (a, b) = Iterable()
reveal_type(a) # revealed: int reveal_type(a) # revealed: int
reveal_type(b) # revealed: int reveal_type(b) # revealed: int
@ -173,12 +171,10 @@ class Iterator:
def __next__(self) -> int: def __next__(self) -> int:
return 42 return 42
class Iterable: class Iterable:
def __iter__(self) -> Iterator: def __iter__(self) -> Iterator:
return Iterator() return Iterator()
(a, (b, c), d) = (1, Iterable(), 2) (a, (b, c), d) = (1, Iterable(), 2)
reveal_type(a) # revealed: Literal[1] reveal_type(a) # revealed: Literal[1]
reveal_type(b) # revealed: int reveal_type(b) # revealed: int