[red-knot] Autoformat mdtest Python snippets using blacken-docs (#13809)

This commit is contained in:
Alex Waygood 2024-10-19 15:57:06 +01:00 committed by GitHub
parent 2ff36530c3
commit 36cb1199cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 331 additions and 132 deletions

View file

@ -45,6 +45,15 @@ repos:
| docs/\w+\.md
)$
- repo: https://github.com/adamchainz/blacken-docs
rev: 1.19.0
hooks:
- id: blacken-docs
args: ["--line-length", "130"]
files: '^crates/.*/resources/mdtest/.*\.md'
additional_dependencies:
- black==24.10.0
- repo: https://github.com/crate-ci/typos
rev: v1.25.0
hooks:

View file

@ -13,13 +13,12 @@ reveal_type(y) # revealed: Literal[1]
## Violates own annotation
```py
x: int = 'foo' # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
x: int = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
```
## Violates previous annotation
```py
x: int
x = 'foo' # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
x = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
```

View file

@ -14,11 +14,14 @@ 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]
```

View file

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

View file

@ -42,7 +42,9 @@ e = 1.0 / 0 # error: "Cannot divide object of type `float` by zero"
# TODO should be float
reveal_type(e) # revealed: @Todo
class MyInt(int): pass
class MyInt(int): ...
# No error for a subclass of int
# TODO should be float

View file

@ -10,11 +10,14 @@ 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
```

View file

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

View file

@ -6,6 +6,7 @@
def get_int() -> int:
return 42
reveal_type(get_int()) # revealed: int
```
@ -15,6 +16,7 @@ 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
```
@ -24,15 +26,19 @@ 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'
return "bar"
# TODO: should reveal `int`, as the decorator replaces `bar` with `foo`
reveal_type(bar()) # revealed: @Todo

View file

@ -4,11 +4,15 @@
```py
if flag:
def f() -> int:
return 1
else:
def f() -> str:
return 'foo'
return "foo"
reveal_type(f()) # revealed: int | str
```
@ -19,9 +23,11 @@ reveal_type(f()) # revealed: int | str
from nonexistent import f # error: [unresolved-import] "Cannot resolve import `nonexistent`"
if flag:
def f() -> int:
return 1
reveal_type(f()) # revealed: Unknown | int
```
@ -33,9 +39,11 @@ Calling a union with a non-callable element should emit a diagnostic.
if flag:
f = 1
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
```
@ -48,13 +56,16 @@ Calling a union with multiple non-callable elements should mention all of them i
if flag:
f = 1
elif flag2:
f = 'foo'
f = "foo"
else:
def f() -> int:
return 1
x = f() # error: "Object of type `Literal[1] | Literal["foo"] | Literal[f]` is not callable (due to union elements Literal[1], Literal["foo"])"
reveal_type(x) # revealed: Unknown | int
# 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())
```
## All non-callable union elements
@ -65,7 +76,7 @@ Calling a union with no callable elements can emit a simpler diagnostic.
if flag:
f = 1
else:
f = 'foo'
f = "foo"
x = f() # error: "Object of type `Literal[1] | Literal["foo"]` is not callable"
reveal_type(x) # revealed: Unknown

View file

@ -21,6 +21,7 @@ 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

View file

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

View file

@ -5,6 +5,7 @@
```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]

View file

@ -61,6 +61,7 @@ reveal_type(c >= d) # revealed: Literal[True]
def bool_instance() -> bool: ...
def int_instance() -> int: ...
a = (bool_instance(),)
b = (int_instance(),)
@ -135,7 +136,7 @@ reveal_type(c >= c) # revealed: Literal[True]
#### Non Boolean Rich Comparisons
```py
class A():
class A:
def __eq__(self, o) -> str: ...
def __ne__(self, o) -> int: ...
def __lt__(self, o) -> float: ...
@ -143,6 +144,7 @@ class A():
def __gt__(self, o) -> tuple: ...
def __ge__(self, o) -> list: ...
a = (A(), A())
# TODO: All @Todo should be bool
@ -161,6 +163,7 @@ 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))

View file

@ -35,5 +35,5 @@ else:
# error: [conflicting-declarations]
# error: [invalid-assignment]
x = b'foo'
x = b"foo"
```

View file

@ -4,6 +4,7 @@
```py
import re
try:
x
except NameError as e:

View file

@ -38,7 +38,8 @@ to the `except` suite *after* that redefinition.
```py path=union_type_inferred.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -60,7 +61,8 @@ unify and `x` is not inferred as having a union type following the
```py path=branches_unify_to_non_union_type.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -84,7 +86,8 @@ possibility when it comes to control-flow analysis.
```py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -114,7 +117,8 @@ the three suites:
```py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -147,7 +151,8 @@ the end of the `except` suite:
```py path=single_except.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -175,7 +180,8 @@ in their entireties:
```py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -208,7 +214,8 @@ therefore `Literal[2]`:
```py path=redef_in_finally.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -235,7 +242,8 @@ suites, however; this is still a TODO item for us.)
```py path=no_redef_in_finally.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
x = 1
@ -267,14 +275,17 @@ following possibilities inside `finally` suites:
```py path=redef_in_finally.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
def could_raise_returns_bytes() -> bytes:
return b'foo'
return b"foo"
def could_raise_returns_bool() -> bool:
return True
x = 1
try:
@ -305,14 +316,17 @@ conclusion of the `finally` suite.)
```py path=no_redef_in_finally.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
def could_raise_returns_bytes() -> bytes:
return b'foo'
return b"foo"
def could_raise_returns_bool() -> bool:
return True
x = 1
try:
@ -336,20 +350,25 @@ An example with multiple `except` branches and a `finally` branch:
```py path=multiple_except_branches.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
def could_raise_returns_bytes() -> bytes:
return b'foo'
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:
@ -383,20 +402,25 @@ partway through the `else` suite due to an exception raised *there*.
```py path=single_except_branch.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
def could_raise_returns_bytes() -> bytes:
return b'foo'
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:
@ -426,26 +450,33 @@ The same again, this time with multiple `except` branches:
```py path=multiple_except_branches.py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
def could_raise_returns_bytes() -> bytes:
return b'foo'
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:
@ -491,41 +522,55 @@ prior to the suite running to completion.
```py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
def could_raise_returns_bytes() -> bytes:
return b'foo'
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:
@ -585,23 +630,29 @@ variable by that name in the outer scope:
```py
def could_raise_returns_str() -> str:
return 'foo'
return "foo"
def could_raise_returns_bytes() -> bytes:
return b'foo'
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:
def foo(param=could_raise_returns_str()):
x = could_raise_returns_str()

View file

@ -6,10 +6,11 @@
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"]
reveal_type(False or 'z') # revealed: Literal["z"]
reveal_type("x" or "y" or "z") # revealed: Literal["x"]
reveal_type("" or "y" or "z") # revealed: Literal["y"]
reveal_type(False or "z") # revealed: Literal["z"]
reveal_type(False or True) # revealed: Literal[True]
reveal_type(False or False) # revealed: Literal[False]
reveal_type(foo() or False) # revealed: str | Literal[False]
@ -22,13 +23,14 @@ 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]
reveal_type(foo() and True) # revealed: str | Literal[True]
reveal_type('x' and 'y' and 'z') # revealed: Literal["z"]
reveal_type('x' and 'y' and '') # revealed: Literal[""]
reveal_type('' and 'y') # revealed: Literal[""]
reveal_type("x" and "y" and "z") # revealed: Literal["z"]
reveal_type("x" and "y" and "") # revealed: Literal[""]
reveal_type("" and "y") # revealed: Literal[""]
```
## Simple function calls to bool
@ -37,6 +39,7 @@ reveal_type('' and 'y') # revealed: Literal[""]
def returns_bool() -> bool:
return True
if returns_bool():
x = True
else:
@ -51,6 +54,7 @@ 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"]
@ -66,7 +70,9 @@ reveal_type("x" or "y" and "") # revealed: Literal["x"]
```py path=a.py
redefined_builtin_bool = bool
def my_bool(x)-> bool: pass
def my_bool(x) -> bool:
return True
```
```py
@ -84,7 +90,10 @@ reveal_type(bool((0,))) # revealed: Literal[True]
reveal_type(bool("NON EMPTY")) # revealed: Literal[True]
reveal_type(bool(True)) # revealed: Literal[True]
def foo(): pass
def foo(): ...
reveal_type(bool(foo)) # revealed: Literal[True]
```

View file

@ -8,9 +8,11 @@ Basic PEP 695 generics
class MyBox[T]:
data: T
box_model_number = 695
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)
@ -30,9 +32,10 @@ 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]
pass
class MySecureBox[T](MyBox[T]): ... # error: [non-subscriptable]
secure_box: MySecureBox[int] = MySecureBox(5)
reveal_type(secure_box) # revealed: MySecureBox
@ -47,11 +50,12 @@ In type stubs, classes can reference themselves in their base class definitions.
This should hold true even with generics at play.
```py path=a.pyi
class Seq[T]:
pass
class Seq[T]: ...
# TODO not error on the subscripting
class S[T](Seq[S]): # error: [non-subscriptable]
pass
class S[T](Seq[S]): ... # error: [non-subscriptable]
reveal_type(S) # revealed: Literal[S]
```

View file

@ -3,21 +3,25 @@
## Class import following
```py
from b import C as D; E = D
from b import C as D
E = D
reveal_type(E) # revealed: Literal[C]
```
```py path=b.py
class C: pass
class C: ...
```
## Module member resolution
```py
import b; D = b.C
import b
D = b.C
reveal_type(D) # revealed: Literal[C]
```
```py path=b.py
class C: pass
class C: ...
```

View file

@ -1,6 +1,8 @@
# Importing builtin module
```py
import builtins; x = builtins.copyright
import builtins
x = builtins.copyright
reveal_type(x) # revealed: Literal[copyright]
```

View file

@ -12,6 +12,7 @@ reveal_type(y) # revealed: Unbound | Literal[3]
```py
from maybe_unbound import x, y
reveal_type(x) # revealed: Literal[3]
reveal_type(y) # revealed: Literal[3]
```
@ -30,6 +31,7 @@ Importing an annotated name prefers the declared type over the inferred type:
```py
from maybe_unbound_annotated import x, y
reveal_type(x) # revealed: Literal[3]
reveal_type(y) # revealed: int
```
@ -44,11 +46,13 @@ def f(): ...
if flag:
from c import f
else:
def f(): ...
```
```py
from b import f
# TODO: We should disambiguate in such cases, showing `Literal[b.f, c.f]`.
reveal_type(f) # revealed: Literal[f, f]
```
@ -71,5 +75,6 @@ else:
```py
from b import x
reveal_type(x) # revealed: int
```

View file

@ -4,6 +4,7 @@
```py
import bar # error: "Cannot resolve import `bar`"
reveal_type(bar) # revealed: Unknown
```
@ -11,6 +12,7 @@ reveal_type(bar) # revealed: Unknown
```py
from bar import baz # error: "Cannot resolve import `bar`"
reveal_type(baz) # revealed: Unknown
```
@ -21,6 +23,7 @@ reveal_type(baz) # revealed: Unknown
```py
from a import thing # error: "Module `a` has no member `thing`"
reveal_type(thing) # revealed: Unknown
```
@ -28,6 +31,7 @@ reveal_type(thing) # revealed: Unknown
```py path=a.py
import foo as foo # error: "Cannot resolve import `foo`"
reveal_type(foo) # revealed: Unknown
```
@ -36,6 +40,7 @@ import" violation:
```py
from a import foo
reveal_type(foo) # revealed: Unknown
```
@ -48,5 +53,5 @@ x: int
```py
from b import x
x = 'foo' # error: [invalid-assignment] "Object of type `Literal["foo"]"
x = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]"
```

View file

@ -7,6 +7,7 @@
```py path=package/bar.py
from .foo import X # error: [unresolved-import]
reveal_type(X) # revealed: Unknown
```
@ -21,6 +22,7 @@ X = 42
```py path=package/bar.py
from .foo import X
reveal_type(X) # revealed: Literal[42]
```
@ -35,6 +37,7 @@ X = 42
```py path=package/bar.py
from .foo.bar.baz import X
reveal_type(X) # revealed: Literal[42]
```
@ -46,6 +49,7 @@ X = 42
```py path=package/bar.py
from . import X
reveal_type(X) # revealed: Literal[42]
```
@ -53,6 +57,7 @@ reveal_type(X) # revealed: Literal[42]
```py path=package/bar.py
from . import X # error: [unresolved-import]
reveal_type(X) # revealed: Unknown
```
@ -60,6 +65,7 @@ reveal_type(X) # revealed: Unknown
```py path=package/__init__.py
from .foo import X
reveal_type(X) # revealed: Literal[42]
```
@ -71,6 +77,7 @@ X = 42
```py path=package/__init__.py
from .foo import X # error: [unresolved-import]
reveal_type(X) # revealed: Unknown
```
@ -85,6 +92,7 @@ X = 42
```py path=package/subpackage/subsubpackage/bar.py
from ...foo import X
reveal_type(X) # revealed: Literal[42]
```
@ -99,6 +107,7 @@ x
```py path=package/bar.py
from .foo import x # error: [unresolved-import]
reveal_type(x) # revealed: Unknown
```
@ -114,6 +123,7 @@ X = 42
```py path=package/bar.py
# TODO: support submodule imports
from . import foo # error: [unresolved-import]
y = foo.X
# TODO: should be `Literal[42]`

View file

@ -4,6 +4,7 @@
```py
from b import x
y = x
reveal_type(y) # revealed: int
```
@ -16,6 +17,7 @@ x: int
```py
from b import x
y = x
reveal_type(y) # revealed: int
```

View file

@ -9,9 +9,9 @@ reveal_type(()) # revealed: tuple[()]
## Heterogeneous tuple
```py
reveal_type((1, 'a')) # revealed: tuple[Literal[1], Literal["a"]]
reveal_type((1, "a")) # revealed: tuple[Literal[1], Literal["a"]]
reveal_type((1, (2, 3))) # revealed: tuple[Literal[1], tuple[Literal[2], Literal[3]]]
reveal_type(((1, 'a'), 2)) # revealed: tuple[tuple[Literal[1], Literal["a"]], Literal[2]]
reveal_type(((1, "a"), 2)) # revealed: tuple[tuple[Literal[1], Literal["a"]], Literal[2]]
```

View file

@ -7,27 +7,27 @@ x = 0
y = str()
z = False
reveal_type(f'hello') # revealed: Literal["hello"]
reveal_type(f'h {x}') # revealed: Literal["h 0"]
reveal_type('one ' f'single ' f'literal') # revealed: Literal["one single literal"]
reveal_type('first ' f'second({x})' f' third') # revealed: Literal["first second(0) third"]
reveal_type(f'-{y}-') # revealed: str
reveal_type(f'-{y}-' f'--' '--') # revealed: str
reveal_type(f'{z} == {False} is {True}') # revealed: Literal["False == False is True"]
reveal_type(f"hello") # revealed: Literal["hello"]
reveal_type(f"h {x}") # revealed: Literal["h 0"]
reveal_type("one " f"single " f"literal") # revealed: Literal["one single literal"]
reveal_type("first " f"second({x})" f" third") # revealed: Literal["first second(0) third"]
reveal_type(f"-{y}-") # revealed: str
reveal_type(f"-{y}-" f"--" "--") # revealed: str
reveal_type(f"{z} == {False} is {True}") # revealed: Literal["False == False is True"]
```
## Conversion Flags
```py
string = 'hello'
string = "hello"
# TODO: should be `Literal["'hello'"]`
reveal_type(f'{string!r}') # revealed: str
reveal_type(f"{string!r}") # revealed: str
```
## Format Specifiers
```py
# TODO: should be `Literal["01"]`
reveal_type(f'{1:02}') # revealed: str
reveal_type(f"{1:02}") # revealed: str
```

View file

@ -4,15 +4,18 @@
```py
reveal_type("Hello") # revealed: Literal["Hello"]
reveal_type('world') # revealed: Literal["world"]
reveal_type("Guten " + 'Tag') # revealed: Literal["Guten Tag"]
reveal_type('bon ' + "jour") # revealed: Literal["bon jour"]
reveal_type("world") # revealed: Literal["world"]
reveal_type("Guten " + "Tag") # revealed: Literal["Guten Tag"]
reveal_type("bon " + "jour") # revealed: Literal["bon jour"]
```
## Nested Quotes
```py
reveal_type('I say "hello" to you') # revealed: Literal["I say \"hello\" to you"]
reveal_type("You say \"hey\" back") # revealed: Literal["You say \"hey\" back"]
# revealed: Literal["You say \"hey\" back"]
reveal_type("You say \"hey\" back") # fmt: skip
reveal_type('No "closure here') # revealed: Literal["No \"closure here"]
```

View file

@ -7,10 +7,12 @@ class IntIterator:
def __next__(self) -> int:
return 42
class IntIterable:
def __iter__(self) -> IntIterator:
return IntIterator()
for x in IntIterable():
pass
@ -24,11 +26,13 @@ class IntIterator:
def __next__(self) -> int:
return 42
class IntIterable:
def __iter__(self) -> IntIterator:
return IntIterator()
x = 'foo'
x = "foo"
for x in IntIterable():
pass
@ -43,14 +47,16 @@ class IntIterator:
def __next__(self) -> int:
return 42
class IntIterable:
def __iter__(self) -> IntIterator:
return IntIterator()
for x in IntIterable():
pass
else:
x = 'foo'
x = "foo"
reveal_type(x) # revealed: Literal["foo"]
```
@ -62,15 +68,17 @@ class IntIterator:
def __next__(self) -> int:
return 42
class IntIterable:
def __iter__(self) -> IntIterator:
return IntIterator()
for x in IntIterable():
if x > 5:
break
else:
x = 'foo'
x = "foo"
reveal_type(x) # revealed: int | Literal["foo"]
```
@ -82,6 +90,7 @@ class OldStyleIterable:
def __getitem__(self, key: int) -> int:
return 42
for x in OldStyleIterable():
pass
@ -91,7 +100,7 @@ reveal_type(x) # revealed: Unbound | int
## With heterogeneous tuple
```py
for x in (1, 'a', b'foo'):
for x in (1, "a", b"foo"):
pass
reveal_type(x) # revealed: Unbound | Literal[1] | Literal["a"] | Literal[b"foo"]
@ -106,6 +115,7 @@ class NotIterable:
else:
__iter__ = None
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
pass
@ -129,6 +139,7 @@ class NotIterable:
__iter__ = None
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
pass
```

View file

@ -3,15 +3,18 @@
## Yield must be iterable
```py
class NotIterable: pass
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"

View file

@ -14,8 +14,8 @@ reveal_type(x) # revealed: None | Literal[1]
## `is` for other types
```py
class A:
...
class A: ...
x = A()
y = x if flag else None

View file

@ -9,9 +9,11 @@ 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]
```
@ -24,9 +26,11 @@ 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
```

View file

@ -3,7 +3,9 @@
## Implicit error
```py
class C: pass
class C: ...
C = 1 # error: "Implicit shadowing of class `C`; annotate to make it explicit if this is intentional"
```
@ -12,6 +14,8 @@ C = 1 # error: "Implicit shadowing of class `C`; annotate to make it explicit i
No diagnostic is raised in the case of explicit shadowing:
```py
class C: pass
class C: ...
C: int = 1
```

View file

@ -12,13 +12,17 @@ def f(x: str):
## Implicit error
```py path=a.py
def f(): pass
def f(): ...
f = 1 # error: "Implicit shadowing of function `f`; annotate to make it explicit if this is intentional"
```
## Explicit shadowing
```py path=a.py
def f(): pass
def f(): ...
f: int = 1
```

View file

@ -7,5 +7,5 @@ if flag:
x: str
else:
x: int
x: bytes = b'foo'
x: bytes = b"foo"
```

View file

@ -6,5 +6,7 @@ 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]
```

View file

@ -3,8 +3,8 @@
## Simple
```py
reveal_type(b'red' b'knot') # revealed: Literal[b"redknot"]
reveal_type(b'hello') # revealed: Literal[b"hello"]
reveal_type(b'world' + b'!') # revealed: Literal[b"world!"]
reveal_type(b'\xff\x00') # revealed: Literal[b"\xff\x00"]
reveal_type(b"red" b"knot") # revealed: Literal[b"redknot"]
reveal_type(b"hello") # revealed: Literal[b"hello"]
reveal_type(b"world" + b"!") # revealed: Literal[b"world!"]
reveal_type(b"\xff\x00") # revealed: Literal[b"\xff\x00"]
```

View file

@ -3,7 +3,9 @@
## Class getitem unbound
```py
class NotSubscriptable: pass
class NotSubscriptable: ...
a = NotSubscriptable[0] # error: "Cannot subscript object of type `Literal[NotSubscriptable]` with no `__class_getitem__` method"
```
@ -14,6 +16,7 @@ class Identity:
def __class_getitem__(cls, item: int) -> str:
return item
reveal_type(Identity[0]) # revealed: str
```
@ -22,15 +25,20 @@ reveal_type(Identity[0]) # revealed: str
```py
flag = True
class Identity:
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(Identity[0]) # revealed: str | int
reveal_type(UnionClassGetItem[0]) # revealed: str | int
```
## Class getitem with class union
@ -38,21 +46,21 @@ reveal_type(Identity[0]) # revealed: str | int
```py
flag = True
class Identity1:
class A:
def __class_getitem__(cls, item: int) -> str:
return item
class Identity2:
class B:
def __class_getitem__(cls, item: int) -> int:
return item
if flag:
a = Identity1
else:
a = Identity2
reveal_type(a) # revealed: Literal[Identity1, Identity2]
reveal_type(a[0]) # revealed: str | int
x = A if flag else B
reveal_type(x) # revealed: Literal[A, B]
reveal_type(x[0]) # revealed: str | int
```
## Class getitem with unbound method union
@ -61,14 +69,19 @@ reveal_type(a[0]) # revealed: str | int
flag = True
if flag:
class Identity:
def __class_getitem__(self, x: int) -> str:
pass
else:
class Identity: pass
a = Identity[42] # error: [call-non-callable] "Method `__class_getitem__` of type `Literal[__class_getitem__] | Unbound` is not callable on object of type `Literal[Identity, Identity]`"
reveal_type(a) # revealed: str | Unknown
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])
```
## TODO: Class getitem non-class union
@ -77,13 +90,16 @@ reveal_type(a) # revealed: str | Unknown
flag = True
if flag:
class Identity:
def __class_getitem__(self, x: int) -> str:
pass
else:
Identity = 1
a = Identity[42] # error: "Cannot subscript object of type `Literal[Identity] | Literal[1]` with no `__getitem__` method"
class Eggs:
def __class_getitem__(self, x: int) -> str:
return "foo"
else:
Eggs = 1
a = Eggs[42] # error: "Cannot subscript object of type `Literal[Eggs] | Literal[1]` with no `__getitem__` method"
# TODO: should _probably_ emit `str | Unknown`
reveal_type(a) # revealed: Unknown
```

View file

@ -3,7 +3,9 @@
## Getitem unbound
```py
class NotSubscriptable: pass
class NotSubscriptable: ...
a = NotSubscriptable()[0] # error: "Cannot subscript object of type `NotSubscriptable` with no `__getitem__` method"
```
@ -13,6 +15,7 @@ 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`"
```
@ -23,6 +26,7 @@ class Identity:
def __getitem__(self, index: int) -> int:
return index
reveal_type(Identity()[0]) # revealed: int
```
@ -31,13 +35,18 @@ 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
```

View file

@ -3,7 +3,7 @@
## Simple
```py
s = 'abcde'
s = "abcde"
reveal_type(s[0]) # revealed: Literal["a"]
reveal_type(s[1]) # revealed: Literal["b"]
@ -23,7 +23,8 @@ reveal_type(b) # revealed: Unknown
def add(x: int, y: int) -> int:
return x + y
a = 'abcde'[add(0, 1)]
a = "abcde"[add(0, 1)]
# TODO: Support overloads... Should be `str`
reveal_type(a) # revealed: @Todo
```

View file

@ -3,7 +3,7 @@
## Basic
```py
t = (1, 'a', 'b')
t = (1, "a", "b")
reveal_type(t[0]) # revealed: Literal[1]
reveal_type(t[1]) # revealed: Literal["a"]

View file

@ -12,9 +12,11 @@ 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]
@ -23,7 +25,8 @@ reveal_type(not f) # revealed: Literal[False]
## Module
```py
import b; import warnings
import b
import warnings
reveal_type(not b) # revealed: Literal[False]

View file

@ -191,7 +191,7 @@ reveal_type(d) # revealed: Literal[2]
### Simple unpacking
```py
a, b = 'ab'
a, b = "ab"
reveal_type(a) # revealed: LiteralString
reveal_type(b) # revealed: LiteralString
```
@ -200,7 +200,7 @@ reveal_type(b) # revealed: LiteralString
```py
# TODO: Add diagnostic (there aren't enough values to unpack)
a, b, c = 'ab'
a, b, c = "ab"
reveal_type(a) # revealed: LiteralString
reveal_type(b) # revealed: LiteralString
reveal_type(c) # revealed: Unknown
@ -210,7 +210,7 @@ reveal_type(c) # revealed: Unknown
```py
# TODO: Add diagnostic (too many values to unpack)
a, b = 'abc'
a, b = "abc"
reveal_type(a) # revealed: LiteralString
reveal_type(b) # revealed: LiteralString
```