[red-knot] mdtest suite: formatting and cleanup (#13806)

Minor cleanup and consistent formatting of the Markdown-based tests.

- Removed lots of unnecessary `a`, `b`, `c`, … variables.
- Moved test assertions (`# revealed:` comments) closer to the tested
object.
- Always separate `# revealed` and `# error` comments from the code by
two spaces, according to the discussion
[here](https://github.com/astral-sh/ruff/pull/13746/files#r1799385758).
This trades readability for consistency in some cases.
- Fixed some headings
This commit is contained in:
David Peter 2024-10-18 11:07:53 +02:00 committed by GitHub
parent f80528fbf2
commit c2f7c39987
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 289 additions and 468 deletions

View file

@ -13,7 +13,7 @@ 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`"
```

View file

@ -19,6 +19,6 @@ class C:
if flag:
x = 2
reveal_type(C.x) # revealed: Literal[2]
reveal_type(C.y) # revealed: Literal[1]
reveal_type(C.x) # revealed: Literal[2]
reveal_type(C.y) # revealed: Literal[1]
```

View file

@ -10,6 +10,5 @@ else:
class C:
x = 2
y = C.x
reveal_type(y) # revealed: Literal[1, 2]
reveal_type(C.x) # revealed: Literal[1, 2]
```

View file

@ -1,21 +1,14 @@
## Binary operations on integers
# Binary operations on integers
## Basic Arithmetic
```py
a = 2 + 1
b = a - 4
c = a * b
d = c // 3
e = c / 3
f = 5 % 3
reveal_type(a) # revealed: Literal[3]
reveal_type(b) # revealed: Literal[-1]
reveal_type(c) # revealed: Literal[-3]
reveal_type(d) # revealed: Literal[-1]
reveal_type(e) # revealed: float
reveal_type(f) # revealed: Literal[2]
reveal_type(2 + 1) # revealed: Literal[3]
reveal_type(3 - 4) # revealed: Literal[-1]
reveal_type(3 * -1) # revealed: Literal[-3]
reveal_type(-3 // 3) # revealed: Literal[-1]
reveal_type(-3 / 3) # revealed: float
reveal_type(5 % 3) # revealed: Literal[2]
```
## Division by Zero
@ -33,16 +26,19 @@ subclass; we only emit the error if the LHS type is exactly `int` or `float`, no
```py
a = 1 / 0 # error: "Cannot divide object of type `Literal[1]` by zero"
b = 2 // 0 # error: "Cannot floor divide object of type `Literal[2]` by zero"
c = 3 % 0 # error: "Cannot reduce object of type `Literal[3]` modulo zero"
d = int() / 0 # error: "Cannot divide object of type `int` by zero"
e = 1.0 / 0 # error: "Cannot divide object of type `float` by zero"
reveal_type(a) # revealed: float
b = 2 // 0 # error: "Cannot floor divide object of type `Literal[2]` by zero"
reveal_type(b) # revealed: int
c = 3 % 0 # error: "Cannot reduce object of type `Literal[3]` modulo zero"
reveal_type(c) # revealed: int
d = int() / 0 # error: "Cannot divide object of type `int` by zero"
# TODO should be int
reveal_type(d) # revealed: @Todo
e = 1.0 / 0 # error: "Cannot divide object of type `float` by zero"
# TODO should be float
reveal_type(e) # revealed: @Todo

View file

@ -11,11 +11,10 @@ class Multiplier:
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(a) # revealed: float
reveal_type(b) # revealed: Unknown
b = Unit()(3.0) # error: "Object of type `Unit` is not callable"
reveal_type(b) # revealed: Unknown
```

View file

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

View file

@ -6,8 +6,7 @@
def get_int() -> int:
return 42
x = get_int()
reveal_type(x) # revealed: int
reveal_type(get_int()) # revealed: int
```
## Async
@ -16,10 +15,8 @@ reveal_type(x) # revealed: int
async def get_int_async() -> int:
return 42
x = get_int_async()
# TODO: we don't yet support `types.CoroutineType`, should be generic `Coroutine[Any, Any, int]`
reveal_type(x) # revealed: @Todo
reveal_type(get_int_async()) # revealed: @Todo
```
## Decorated
@ -37,10 +34,8 @@ def decorator(func) -> Callable[[], int]:
def bar() -> str:
return 'bar'
x = bar()
# TODO: should reveal `int`, as the decorator replaces `bar` with `foo`
reveal_type(x) # revealed: @Todo
reveal_type(bar()) # revealed: @Todo
```
## Invalid callable

View file

@ -10,21 +10,19 @@ else:
def f() -> str:
return 'foo'
x = f()
reveal_type(x) # revealed: int | str
reveal_type(f()) # revealed: int | str
```
## Calling with an unknown union
```py
from nonexistent import f # error: [unresolved-import] "Cannot resolve import `nonexistent`"
from nonexistent import f # error: [unresolved-import] "Cannot resolve import `nonexistent`"
if flag:
def f() -> int:
return 1
x = f()
reveal_type(x) # revealed: Unknown | int
reveal_type(f()) # revealed: Unknown | int
```
## Non-callable elements in a union

View file

@ -1,43 +1,43 @@
### Comparison: Byte literals
# Comparison: Byte literals
These tests assert that we infer precise `Literal` types for comparisons between objects
inferred as having `Literal` bytes types:
```py
reveal_type(b"abc" == b"abc") # revealed: Literal[True]
reveal_type(b"abc" == b"ab") # revealed: Literal[False]
reveal_type(b"abc" == b"ab") # revealed: Literal[False]
reveal_type(b"abc" != b"abc") # revealed: Literal[False]
reveal_type(b"abc" != b"ab") # revealed: Literal[True]
reveal_type(b"abc" != b"ab") # revealed: Literal[True]
reveal_type(b"abc" < b"abd") # revealed: Literal[True]
reveal_type(b"abc" < b"abb") # revealed: Literal[False]
reveal_type(b"abc" < b"abd") # revealed: Literal[True]
reveal_type(b"abc" < b"abb") # revealed: Literal[False]
reveal_type(b"abc" <= b"abc") # revealed: Literal[True]
reveal_type(b"abc" <= b"abb") # revealed: Literal[False]
reveal_type(b"abc" > b"abd") # revealed: Literal[False]
reveal_type(b"abc" > b"abb") # revealed: Literal[True]
reveal_type(b"abc" > b"abd") # revealed: Literal[False]
reveal_type(b"abc" > b"abb") # revealed: Literal[True]
reveal_type(b"abc" >= b"abc") # revealed: Literal[True]
reveal_type(b"abc" >= b"abd") # revealed: Literal[False]
reveal_type(b"" in b"") # revealed: Literal[True]
reveal_type(b"" in b"abc") # revealed: Literal[True]
reveal_type(b"abc" in b"") # revealed: Literal[False]
reveal_type(b"ab" in b"abc") # revealed: Literal[True]
reveal_type(b"abc" in b"abc") # revealed: Literal[True]
reveal_type(b"d" in b"abc") # revealed: Literal[False]
reveal_type(b"ac" in b"abc") # revealed: Literal[False]
reveal_type(b"" in b"") # revealed: Literal[True]
reveal_type(b"" in b"abc") # revealed: Literal[True]
reveal_type(b"abc" in b"") # revealed: Literal[False]
reveal_type(b"ab" in b"abc") # revealed: Literal[True]
reveal_type(b"abc" in b"abc") # revealed: Literal[True]
reveal_type(b"d" in b"abc") # revealed: Literal[False]
reveal_type(b"ac" in b"abc") # revealed: Literal[False]
reveal_type(b"\x81\x82" in b"\x80\x81\x82") # revealed: Literal[True]
reveal_type(b"\x82\x83" in b"\x80\x81\x82") # revealed: Literal[False]
reveal_type(b"ab" not in b"abc") # revealed: Literal[False]
reveal_type(b"ac" not in b"abc") # revealed: Literal[True]
reveal_type(b"ab" not in b"abc") # revealed: Literal[False]
reveal_type(b"ac" not in b"abc") # revealed: Literal[True]
reveal_type(b"abc" is b"abc") # revealed: bool
reveal_type(b"abc" is b"ab") # revealed: Literal[False]
reveal_type(b"abc" is b"abc") # revealed: bool
reveal_type(b"abc" is b"ab") # revealed: Literal[False]
reveal_type(b"abc" is not b"abc") # revealed: bool
reveal_type(b"abc" is not b"ab") # revealed: Literal[True]
reveal_type(b"abc" is not b"ab") # revealed: Literal[True]
```

View file

@ -1,29 +1,18 @@
# Comparing integers
# Comparison: Integers
## Integer literals
```py
a = 1 == 1 == True
b = 1 == 1 == 2 == 4
c = False < True <= 2 < 3 != 6
d = 1 < 1
e = 1 > 1
f = 1 is 1
g = 1 is not 1
h = 1 is 2
i = 1 is not 7
j = 1 <= "" and 0 < 1
reveal_type(a) # revealed: Literal[True]
reveal_type(b) # revealed: Literal[False]
reveal_type(c) # revealed: Literal[True]
reveal_type(d) # revealed: Literal[False]
reveal_type(e) # revealed: Literal[False]
reveal_type(f) # revealed: bool
reveal_type(g) # revealed: bool
reveal_type(h) # revealed: Literal[False]
reveal_type(i) # revealed: Literal[True]
reveal_type(j) # revealed: @Todo | Literal[True]
reveal_type(1 == 1 == True) # revealed: Literal[True]
reveal_type(1 == 1 == 2 == 4) # revealed: Literal[False]
reveal_type(False < True <= 2 < 3 != 6) # revealed: Literal[True]
reveal_type(1 < 1) # revealed: Literal[False]
reveal_type(1 > 1) # revealed: Literal[False]
reveal_type(1 is 1) # revealed: bool
reveal_type(1 is not 1) # revealed: bool
reveal_type(1 is 2) # revealed: Literal[False]
reveal_type(1 is not 7) # revealed: Literal[True]
reveal_type(1 <= "" and 0 < 1) # revealed: @Todo | Literal[True]
```
## Integer instance
@ -31,11 +20,8 @@ reveal_type(j) # revealed: @Todo | Literal[True]
```py
# TODO: implement lookup of `__eq__` on typeshed `int` stub.
def int_instance() -> int: ...
a = 1 == int_instance()
b = 9 < int_instance()
c = int_instance() < int_instance()
reveal_type(a) # revealed: @Todo
reveal_type(b) # revealed: bool
reveal_type(c) # revealed: bool
reveal_type(1 == int_instance()) # revealed: @Todo
reveal_type(9 < int_instance()) # revealed: bool
reveal_type(int_instance() < int_instance()) # revealed: bool
```

View file

@ -1,4 +1,4 @@
# Non boolean returns
# Comparison: Non boolean returns
Walking through examples:
@ -27,11 +27,12 @@ class B:
class C:
def __lt__(self, other) -> C: ...
a = A() < B() < C()
b = 0 < 1 < A() < 3
c = 10 < 0 < A() < B() < C()
x = A() < B() < C()
reveal_type(x) # revealed: A | B
reveal_type(a) # revealed: A | B
reveal_type(b) # revealed: bool | A
reveal_type(c) # revealed: Literal[False]
y = 0 < 1 < A() < 3
reveal_type(y) # revealed: bool | A
z = 10 < 0 < A() < B() < C()
reveal_type(z) # revealed: Literal[False]
```

View file

@ -1,29 +1,20 @@
# Comparing strings
# Comparison: Strings
## String literals
```py
def str_instance() -> str: ...
a = "abc" == "abc"
b = "ab_cd" <= "ab_ce"
c = "abc" in "ab cd"
d = "" not in "hello"
e = "--" is "--"
f = "A" is "B"
g = "--" is not "--"
h = "A" is not "B"
i = str_instance() < "..."
# ensure we're not comparing the interned salsa symbols, which compare by order of declaration.
j = "ab" < "ab_cd"
reveal_type(a) # revealed: Literal[True]
reveal_type(b) # revealed: Literal[True]
reveal_type(c) # revealed: Literal[False]
reveal_type(d) # revealed: Literal[False]
reveal_type(e) # revealed: bool
reveal_type(f) # revealed: Literal[False]
reveal_type(g) # revealed: bool
reveal_type(h) # revealed: Literal[True]
reveal_type(i) # revealed: bool
reveal_type(j) # revealed: Literal[True]
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]
reveal_type("" not in "hello") # revealed: Literal[False]
reveal_type("--" is "--") # revealed: bool
reveal_type("A" is "B") # revealed: Literal[False]
reveal_type("--" is not "--") # revealed: bool
reveal_type("A" is not "B") # revealed: Literal[True]
reveal_type(str_instance() < "...") # revealed: bool
# ensure we're not comparing the interned salsa symbols, which compare by order of declaration.
reveal_type("ab" < "ab_cd") # revealed: Literal[True]
```

View file

@ -1,4 +1,4 @@
# Comparison - Tuples
# Comparison: Tuples
## Heterogeneous
@ -18,16 +18,16 @@ b = (1, "test", (3, 14), False)
reveal_type(a == a) # revealed: Literal[True]
reveal_type(a != a) # revealed: Literal[False]
reveal_type(a < a) # revealed: Literal[False]
reveal_type(a < a) # revealed: Literal[False]
reveal_type(a <= a) # revealed: Literal[True]
reveal_type(a > a) # revealed: Literal[False]
reveal_type(a > a) # revealed: Literal[False]
reveal_type(a >= a) # revealed: Literal[True]
reveal_type(a == b) # revealed: Literal[False]
reveal_type(a != b) # revealed: Literal[True]
reveal_type(a < b) # revealed: Literal[True]
reveal_type(a < b) # revealed: Literal[True]
reveal_type(a <= b) # revealed: Literal[True]
reveal_type(a > b) # revealed: Literal[False]
reveal_type(a > b) # revealed: Literal[False]
reveal_type(a >= b) # revealed: Literal[False]
```
@ -39,9 +39,9 @@ b = (1, 2, 3, 4)
reveal_type(a == b) # revealed: Literal[False]
reveal_type(a != b) # revealed: Literal[True]
reveal_type(a < b) # revealed: Literal[True]
reveal_type(a < b) # revealed: Literal[True]
reveal_type(a <= b) # revealed: Literal[True]
reveal_type(a > b) # revealed: Literal[False]
reveal_type(a > b) # revealed: Literal[False]
reveal_type(a >= b) # revealed: Literal[False]
c = ("a", "b", "c", "d")
@ -49,9 +49,9 @@ d = ("a", "b", "c")
reveal_type(c == d) # revealed: Literal[False]
reveal_type(c != d) # revealed: Literal[True]
reveal_type(c < d) # revealed: Literal[False]
reveal_type(c < d) # revealed: Literal[False]
reveal_type(c <= d) # revealed: Literal[False]
reveal_type(c > d) # revealed: Literal[True]
reveal_type(c > d) # revealed: Literal[True]
reveal_type(c >= d) # revealed: Literal[True]
```
@ -67,16 +67,16 @@ b = (int_instance(),)
# TODO: All @Todo should be `bool`
reveal_type(a == a) # revealed: @Todo
reveal_type(a != a) # revealed: @Todo
reveal_type(a < a) # revealed: @Todo
reveal_type(a < a) # revealed: @Todo
reveal_type(a <= a) # revealed: @Todo
reveal_type(a > a) # revealed: @Todo
reveal_type(a > a) # revealed: @Todo
reveal_type(a >= a) # revealed: @Todo
reveal_type(a == b) # revealed: @Todo
reveal_type(a != b) # revealed: @Todo
reveal_type(a < b) # revealed: @Todo
reveal_type(a < b) # revealed: @Todo
reveal_type(a <= b) # revealed: @Todo
reveal_type(a > b) # revealed: @Todo
reveal_type(a > b) # revealed: @Todo
reveal_type(a >= b) # revealed: @Todo
```
@ -96,9 +96,9 @@ reveal_type(a == b) # revealed: @Todo
reveal_type(a != b) # revealed: @Todo
# TODO: should be Unknown and add more informative diagnostics
reveal_type(a < b) # revealed: @Todo
reveal_type(a < b) # revealed: @Todo
reveal_type(a <= b) # revealed: @Todo
reveal_type(a > b) # revealed: @Todo
reveal_type(a > b) # revealed: @Todo
reveal_type(a >= b) # revealed: @Todo
```
@ -111,9 +111,9 @@ b = (999999, "hello")
reveal_type(a == b) # revealed: Literal[False]
reveal_type(a != b) # revealed: Literal[True]
reveal_type(a < b) # revealed: Literal[True]
reveal_type(a < b) # revealed: Literal[True]
reveal_type(a <= b) # revealed: Literal[True]
reveal_type(a > b) # revealed: Literal[False]
reveal_type(a > b) # revealed: Literal[False]
reveal_type(a >= b) # revealed: Literal[False]
```
@ -126,9 +126,9 @@ c = (b, b, b)
reveal_type(c == c) # revealed: Literal[True]
reveal_type(c != c) # revealed: Literal[False]
reveal_type(c < c) # revealed: Literal[False]
reveal_type(c < c) # revealed: Literal[False]
reveal_type(c <= c) # revealed: Literal[True]
reveal_type(c > c) # revealed: Literal[False]
reveal_type(c > c) # revealed: Literal[False]
reveal_type(c >= c) # revealed: Literal[True]
```
@ -148,9 +148,9 @@ a = (A(), A())
# TODO: All @Todo should be bool
reveal_type(a == a) # revealed: @Todo
reveal_type(a != a) # revealed: @Todo
reveal_type(a < a) # revealed: @Todo
reveal_type(a < a) # revealed: @Todo
reveal_type(a <= a) # revealed: @Todo
reveal_type(a > a) # revealed: @Todo
reveal_type(a > a) # revealed: @Todo
reveal_type(a >= a) # revealed: @Todo
```

View file

@ -58,8 +58,8 @@ large = 2 if flag_l else 3
reveal_type(small <= large) # revealed: Literal[True]
reveal_type(small >= large) # revealed: bool
reveal_type(small < large) # revealed: bool
reveal_type(small > large) # revealed: Literal[False]
reveal_type(small < large) # revealed: bool
reveal_type(small > large) # revealed: Literal[False]
```
## Unsupported operations

View file

@ -1,15 +1,17 @@
# Unsupported operators
# Comparison: Unsupported operators
```py
a = 1 in 7 # error: "Operator `in` is not supported for types `Literal[1]` and `Literal[7]`"
b = 0 not in 10 # error: "Operator `not in` is not supported for types `Literal[0]` and `Literal[10]`"
c = object() < 5 # error: "Operator `<` is not supported for types `object` and `Literal[5]`"
a = 1 in 7 # error: "Operator `in` is not supported for types `Literal[1]` and `Literal[7]`"
reveal_type(a) # revealed: bool
b = 0 not in 10 # error: "Operator `not in` is not supported for types `Literal[0]` and `Literal[10]`"
reveal_type(b) # revealed: bool
c = object() < 5 # error: "Operator `<` is not supported for types `object` and `Literal[5]`"
reveal_type(c) # revealed: Unknown
# TODO should error, need to check if __lt__ signature is valid for right operand
d = 5 < object()
reveal_type(a) # revealed: bool
reveal_type(b) # revealed: bool
reveal_type(c) # revealed: Unknown
# TODO: should be `Unknown`
reveal_type(d) # revealed: bool
```

View file

@ -13,11 +13,9 @@ reveal_type(x) # revealed: Literal[1, 2]
y = 0
z = 0
x = (y := 1) if flag else (z := 2)
a = y
b = z
reveal_type(x) # revealed: Literal[1, 2]
reveal_type(a) # revealed: Literal[0, 1]
reveal_type(b) # revealed: Literal[0, 2]
reveal_type(y) # revealed: Literal[0, 1]
reveal_type(z) # revealed: Literal[0, 2]
```
## Nested if-expression

View file

@ -9,9 +9,7 @@ y = 2
if flag:
y = 3
x = y
reveal_type(x) # revealed: Literal[2, 3]
reveal_type(y) # revealed: Literal[2, 3]
```
## Simple if-elif-else
@ -92,7 +90,6 @@ if flag:
y = 3
elif flag2:
y = 4
x = y
reveal_type(x) # revealed: Literal[2, 3, 4]
reveal_type(y) # revealed: Literal[2, 3, 4]
```

View file

@ -15,7 +15,7 @@ except re.error as f:
## Unknown type in except handler does not cause spurious diagnostic
```py
from nonexistent_module import foo # error: [unresolved-import]
from nonexistent_module import foo # error: [unresolved-import]
try:
x

View file

@ -6,23 +6,14 @@
def foo() -> str:
pass
a = True or False
b = 'x' or 'y' or 'z'
c = '' or 'y' or 'z'
d = False or 'z'
e = False or True
f = False or False
g = foo() or False
h = foo() or True
reveal_type(a) # revealed: Literal[True]
reveal_type(b) # revealed: Literal["x"]
reveal_type(c) # revealed: Literal["y"]
reveal_type(d) # revealed: Literal["z"]
reveal_type(e) # revealed: Literal[True]
reveal_type(f) # revealed: Literal[False]
reveal_type(g) # revealed: str | Literal[False]
reveal_type(h) # revealed: str | Literal[True]
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(False or True) # revealed: Literal[True]
reveal_type(False or False) # revealed: Literal[False]
reveal_type(foo() or False) # revealed: str | Literal[False]
reveal_type(foo() or True) # revealed: str | Literal[True]
```
## AND
@ -31,21 +22,13 @@ reveal_type(h) # revealed: str | Literal[True]
def foo() -> str:
pass
a = True and False
b = False and True
c = foo() and False
d = foo() and True
e = 'x' and 'y' and 'z'
f = 'x' and 'y' and ''
g = '' and 'y'
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: Literal[False]
reveal_type(c) # revealed: str | Literal[False]
reveal_type(d) # revealed: str | Literal[True]
reveal_type(e) # revealed: Literal["z"]
reveal_type(f) # revealed: Literal[""]
reveal_type(g) # revealed: Literal[""]
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[""]
```
## Simple function calls to bool
@ -68,19 +51,12 @@ reveal_type(x) # revealed: bool
def foo() -> str:
pass
a = "x" and "y" or "z"
b = "x" or "y" and "z"
c = "" and "y" or "z"
d = "" or "y" and "z"
e = "x" and "y" or ""
f = "x" or "y" and ""
reveal_type(a) # revealed: Literal["y"]
reveal_type(b) # revealed: Literal["x"]
reveal_type(c) # revealed: Literal["z"]
reveal_type(d) # revealed: Literal["z"]
reveal_type(e) # revealed: Literal["y"]
reveal_type(f) # revealed: Literal["x"]
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"]
reveal_type("" or "y" and "z") # revealed: Literal["z"]
reveal_type("x" and "y" or "") # revealed: Literal["y"]
reveal_type("x" or "y" and "") # revealed: Literal["x"]
```
## `bool()` function
@ -95,57 +71,38 @@ def my_bool(x)-> bool: pass
```py
from a import redefined_builtin_bool, my_bool
a = redefined_builtin_bool(0)
b = my_bool(0)
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: bool
reveal_type(redefined_builtin_bool(0)) # revealed: Literal[False]
reveal_type(my_bool(0)) # revealed: bool
```
## Truthy values
```py
a = bool(1)
b = bool((0,))
c = bool("NON EMPTY")
d = bool(True)
reveal_type(bool(1)) # revealed: Literal[True]
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
e = bool(foo)
reveal_type(a) # revealed: Literal[True]
reveal_type(b) # revealed: Literal[True]
reveal_type(c) # revealed: Literal[True]
reveal_type(d) # revealed: Literal[True]
reveal_type(e) # revealed: Literal[True]
reveal_type(bool(foo)) # revealed: Literal[True]
```
## Falsy values
```py
a = bool(0)
b = bool(())
c = bool(None)
d = bool("")
e = bool(False)
f = bool()
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: Literal[False]
reveal_type(c) # revealed: Literal[False]
reveal_type(d) # revealed: Literal[False]
reveal_type(e) # revealed: Literal[False]
reveal_type(f) # revealed: Literal[False]
reveal_type(bool(0)) # revealed: Literal[False]
reveal_type(bool(())) # revealed: Literal[False]
reveal_type(bool(None)) # revealed: Literal[False]
reveal_type(bool("")) # revealed: Literal[False]
reveal_type(bool(False)) # revealed: Literal[False]
reveal_type(bool()) # revealed: Literal[False]
```
## Ambiguous values
```py
a = bool([])
b = bool({})
c = bool(set())
reveal_type(a) # revealed: bool
reveal_type(b) # revealed: bool
reveal_type(c) # revealed: bool
reveal_type(bool([])) # revealed: bool
reveal_type(bool({})) # revealed: bool
reveal_type(bool(set())) # revealed: bool
```

View file

@ -4,7 +4,7 @@
```py
from b import C as D; E = D
reveal_type(E) # revealed: Literal[C]
reveal_type(E) # revealed: Literal[C]
```
```py path=b.py
@ -15,7 +15,7 @@ class C: pass
```py
import b; D = b.C
reveal_type(D) # revealed: Literal[C]
reveal_type(D) # revealed: Literal[C]
```
```py path=b.py

View file

@ -2,5 +2,5 @@
```py
import builtins; x = builtins.copyright
reveal_type(x) # revealed: Literal[copyright]
reveal_type(x) # revealed: Literal[copyright]
```

View file

@ -3,14 +3,14 @@
## Unresolved import statement
```py
import bar # error: "Cannot resolve import `bar`"
import bar # error: "Cannot resolve import `bar`"
reveal_type(bar) # revealed: Unknown
```
## Unresolved import from statement
```py
from bar import baz # error: "Cannot resolve import `bar`"
from bar import baz # error: "Cannot resolve import `bar`"
reveal_type(baz) # revealed: Unknown
```
@ -20,14 +20,14 @@ reveal_type(baz) # revealed: Unknown
```
```py
from a import thing # error: "Module `a` has no member `thing`"
from a import thing # error: "Module `a` has no member `thing`"
reveal_type(thing) # revealed: Unknown
```
## Resolved import of symbol from unresolved import
```py path=a.py
import foo as foo # error: "Cannot resolve import `foo`"
import foo as foo # error: "Cannot resolve import `foo`"
reveal_type(foo) # revealed: Unknown
```

View file

@ -6,7 +6,7 @@
```
```py path=package/bar.py
from .foo import X # error: [unresolved-import]
from .foo import X # error: [unresolved-import]
reveal_type(X) # revealed: Unknown
```
@ -52,7 +52,7 @@ reveal_type(X) # revealed: Literal[42]
## Non-existent + bare to package
```py path=package/bar.py
from . import X # error: [unresolved-import]
from . import X # error: [unresolved-import]
reveal_type(X) # revealed: Unknown
```
@ -70,8 +70,8 @@ X = 42
## Non-existent + dunder init
```py path=package/__init__.py
from .foo import X # error: [unresolved-import]
reveal_type(X) # revealed: Unknown
from .foo import X # error: [unresolved-import]
reveal_type(X) # revealed: Unknown
```
## Long relative import
@ -98,8 +98,8 @@ x
```
```py path=package/bar.py
from .foo import x # error: [unresolved-import]
reveal_type(x) # revealed: Unknown
from .foo import x # error: [unresolved-import]
reveal_type(x) # revealed: Unknown
```
## Bare to module
@ -117,7 +117,7 @@ from . import foo # error: [unresolved-import]
y = foo.X
# TODO: should be `Literal[42]`
reveal_type(y) # revealed: Unknown
reveal_type(y) # revealed: Unknown
```
## Non-existent + bare to module
@ -129,5 +129,5 @@ reveal_type(y) # revealed: Unknown
# TODO: support submodule imports
from . import foo # error: [unresolved-import]
reveal_type(foo) # revealed: Unknown
reveal_type(foo) # revealed: Unknown
```

View file

@ -1,8 +1,6 @@
# Boolean literals
```py
x = True
y = False
reveal_type(x) # revealed: Literal[True]
reveal_type(y) # revealed: Literal[False]
reveal_type(True) # revealed: Literal[True]
reveal_type(False) # revealed: Literal[False]
```

View file

@ -3,6 +3,5 @@
## Empty dictionary
```py
x = {}
reveal_type(x) # revealed: dict
reveal_type({}) # revealed: dict
```

View file

@ -3,6 +3,5 @@
## Empty list
```py
x = []
reveal_type(x) # revealed: list
reveal_type([]) # revealed: list
```

View file

@ -3,6 +3,5 @@
## Basic set
```py
x = {1, 2}
reveal_type(x) # revealed: set
reveal_type({1, 2}) # revealed: set
```

View file

@ -3,18 +3,15 @@
## Empty tuple
```py
x = ()
reveal_type(x) # revealed: tuple[()]
reveal_type(()) # revealed: tuple[()]
```
## Heterogeneous tuple
```py
x = (1, 'a')
y = (1, (2, 3))
z = (x, 2)
reveal_type((1, 'a')) # revealed: tuple[Literal[1], Literal["a"]]
reveal_type(x) # revealed: tuple[Literal[1], Literal["a"]]
reveal_type(y) # revealed: tuple[Literal[1], tuple[Literal[2], Literal[3]]]
reveal_type(z) # revealed: tuple[tuple[Literal[1], Literal["a"]], Literal[2]]
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]]
```

View file

@ -7,38 +7,27 @@ x = 0
y = str()
z = False
a = f'hello'
b = f'h {x}'
c = 'one ' f'single ' f'literal'
d = 'first ' f'second({b})' f' third'
e = f'-{y}-'
f = f'-{y}-' f'--' '--'
g = f'{z} == {False} is {True}'
reveal_type(a) # revealed: Literal["hello"]
reveal_type(b) # revealed: Literal["h 0"]
reveal_type(c) # revealed: Literal["one single literal"]
reveal_type(d) # revealed: Literal["first second(h 0) third"]
reveal_type(e) # revealed: str
reveal_type(f) # revealed: str
reveal_type(g) # 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'
a = f'{string!r}'
# TODO: should be `Literal["'hello'"]`
reveal_type(a) # revealed: str
reveal_type(f'{string!r}') # revealed: str
```
## Format Specifiers
```py
a = f'{1:02}'
# TODO: should be `Literal["01"]`
reveal_type(a) # revealed: str
reveal_type(f'{1:02}') # revealed: str
```

View file

@ -3,24 +3,16 @@
## Simple
```py
w = "Hello"
x = 'world'
y = "Guten " + 'tag'
z = 'bon ' + "jour"
reveal_type(w) # revealed: Literal["Hello"]
reveal_type(x) # revealed: Literal["world"]
reveal_type(y) # revealed: Literal["Guten tag"]
reveal_type(z) # revealed: Literal["bon jour"]
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"]
```
## Nested Quotes
```py
x = 'I say "hello" to you'
y = "You say \"hey\" back"
z = 'No "closure here'
reveal_type(x) # revealed: Literal["I say \"hello\" to you"]
reveal_type(y) # revealed: Literal["You say \"hey\" back"]
reveal_type(z) # revealed: Literal["No \"closure here"]
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"]
reveal_type('No "closure here') # revealed: Literal["No \"closure here"]
```

View file

@ -106,7 +106,7 @@ class NotIterable:
else:
__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
reveal_type(x) # revealed: Unbound | Unknown
@ -116,7 +116,7 @@ reveal_type(x) # revealed: Unbound | Unknown
```py
nonsense = 123
for x in nonsense: # error: "Object of type `Literal[123]` is not iterable"
for x in nonsense: # error: "Object of type `Literal[123]` is not iterable"
pass
```
@ -129,6 +129,6 @@ class NotIterable:
__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
```

View file

@ -14,5 +14,5 @@ class Iterable:
def generator_function():
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

@ -17,11 +17,10 @@ x = 1
while flag:
x = 2
else:
y = x
reveal_type(x) # revealed: Literal[1, 2]
x = 3
reveal_type(x) # revealed: Literal[3]
reveal_type(y) # revealed: Literal[1, 2]
```
## While with Else (may break)

View file

@ -1,9 +0,0 @@
# `is not None` narrowing
```py
x = None if flag else 1
if x is not None:
reveal_type(x) # revealed: Literal[1]
reveal_type(x) # revealed: None | Literal[1]
```

View file

@ -4,7 +4,7 @@
```py
class C: pass
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"
```
## Explicit

View file

@ -13,7 +13,7 @@ def f(x: str):
```py path=a.py
def f(): pass
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"
```
## Explicit shadowing

View file

@ -3,13 +3,8 @@
## Simple
```py
w = b'red' b'knot'
x = b'hello'
y = b'world' + b'!'
z = b'\xff\x00'
reveal_type(w) # revealed: Literal[b"redknot"]
reveal_type(x) # revealed: Literal[b"hello"]
reveal_type(y) # revealed: Literal[b"world!"]
reveal_type(z) # 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

@ -14,8 +14,7 @@ class Identity:
def __class_getitem__(cls, item: int) -> str:
return item
a = Identity[0]
reveal_type(a) # revealed: str
reveal_type(Identity[0]) # revealed: str
```
## Class getitem union
@ -31,8 +30,7 @@ class Identity:
def __class_getitem__(cls, item: int) -> int:
return item
a = Identity[0]
reveal_type(a) # revealed: str | int
reveal_type(Identity[0]) # revealed: str | int
```
## Class getitem with class union
@ -53,9 +51,8 @@ if flag:
else:
a = Identity2
b = a[0]
reveal_type(a) # revealed: Literal[Identity1, Identity2]
reveal_type(b) # revealed: str | int
reveal_type(a) # revealed: Literal[Identity1, Identity2]
reveal_type(a[0]) # revealed: str | int
```
## Class getitem with unbound method union
@ -70,8 +67,8 @@ if flag:
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
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
```
## TODO: Class getitem non-class union
@ -86,7 +83,7 @@ if flag:
else:
Identity = 1
a = Identity[42] # error: "Cannot subscript object of type `Literal[Identity] | Literal[1]` with no `__getitem__` method"
a = Identity[42] # error: "Cannot subscript object of type `Literal[Identity] | Literal[1]` with no `__getitem__` method"
# TODO: should _probably_ emit `str | Unknown`
reveal_type(a) # revealed: Unknown
reveal_type(a) # revealed: Unknown
```

View file

@ -23,8 +23,7 @@ class Identity:
def __getitem__(self, index: int) -> int:
return index
a = Identity()[0]
reveal_type(a) # revealed: int
reveal_type(Identity()[0]) # revealed: int
```
## Getitem union
@ -40,6 +39,5 @@ class Identity:
def __getitem__(self, index: int) -> str:
return str(index)
a = Identity()[0]
reveal_type(a) # revealed: int | str
reveal_type(Identity()[0]) # revealed: int | str
```

View file

@ -10,10 +10,13 @@ A list can be indexed into with:
```py
x = [1, 2, 3]
reveal_type(x) # revealed: list
# TODO reveal int
reveal_type(x[0]) # revealed: @Todo
# TODO reveal list
reveal_type(x[0:1]) # revealed: @Todo
# TODO error
reveal_type(x["a"]) # revealed: @Todo
```
@ -26,8 +29,10 @@ This should also get type checked.
```py
x = [1, 2, 3]
x[0 if (y := 2) else 1] = 5
# TODO error? (indeterminite index type)
x["a" if (y := 2) else 1] = 6
# TODO error (can't index via string)
x["a" if (y := 2) else "b"] = 6
```

View file

@ -5,19 +5,16 @@
```py
s = 'abcde'
a = s[0]
b = s[1]
c = s[-1]
d = s[-2]
e = s[8] # error: [index-out-of-bounds] "Index 8 is out of bounds for string `Literal["abcde"]` with length 5"
f = s[-8] # error: [index-out-of-bounds] "Index -8 is out of bounds for string `Literal["abcde"]` with length 5"
reveal_type(s[0]) # revealed: Literal["a"]
reveal_type(s[1]) # revealed: Literal["b"]
reveal_type(s[-1]) # revealed: Literal["e"]
reveal_type(s[-2]) # revealed: Literal["d"]
reveal_type(a) # revealed: Literal["a"]
reveal_type(b) # revealed: Literal["b"]
reveal_type(c) # revealed: Literal["e"]
reveal_type(d) # revealed: Literal["d"]
reveal_type(e) # revealed: Unknown
reveal_type(f) # revealed: Unknown
a = s[8] # error: [index-out-of-bounds] "Index 8 is out of bounds for string `Literal["abcde"]` with length 5"
reveal_type(a) # revealed: Unknown
b = s[-8] # error: [index-out-of-bounds] "Index -8 is out of bounds for string `Literal["abcde"]` with length 5"
reveal_type(b) # revealed: Unknown
```
## Function return

View file

@ -5,17 +5,14 @@
```py
t = (1, 'a', 'b')
a = t[0]
b = t[1]
c = t[-1]
d = t[-2]
e = t[4] # error: [index-out-of-bounds]
f = t[-4] # error: [index-out-of-bounds]
reveal_type(t[0]) # revealed: Literal[1]
reveal_type(t[1]) # revealed: Literal["a"]
reveal_type(t[-1]) # revealed: Literal["b"]
reveal_type(t[-2]) # revealed: Literal["a"]
reveal_type(a) # revealed: Literal[1]
reveal_type(b) # revealed: Literal["a"]
reveal_type(c) # revealed: Literal["b"]
reveal_type(d) # revealed: Literal["a"]
reveal_type(e) # revealed: Unknown
reveal_type(f) # revealed: Unknown
a = t[4] # error: [index-out-of-bounds]
reveal_type(a) # revealed: Unknown
b = t[-4] # error: [index-out-of-bounds]
reveal_type(b) # revealed: Unknown
```

View file

@ -3,35 +3,23 @@
## Unary Addition
```py
a = +0
b = +1
c = +True
reveal_type(a) # revealed: Literal[0]
reveal_type(b) # revealed: Literal[1]
reveal_type(c) # revealed: Literal[1]
reveal_type(+0) # revealed: Literal[0]
reveal_type(+1) # revealed: Literal[1]
reveal_type(+True) # revealed: Literal[1]
```
## Unary Subtraction
```py
a = -0
b = -1
c = -True
reveal_type(a) # revealed: Literal[0]
reveal_type(b) # revealed: Literal[-1]
reveal_type(c) # revealed: Literal[-1]
reveal_type(-0) # revealed: Literal[0]
reveal_type(-1) # revealed: Literal[-1]
reveal_type(-True) # revealed: Literal[-1]
```
## Unary Bitwise Inversion
```py
a = ~0
b = ~1
c = ~True
reveal_type(a) # revealed: Literal[-1]
reveal_type(b) # revealed: Literal[-2]
reveal_type(c) # revealed: Literal[-2]
reveal_type(~0) # revealed: Literal[-1]
reveal_type(~1) # revealed: Literal[-2]
reveal_type(~True) # revealed: Literal[-2]
```

View file

@ -3,10 +3,8 @@
## None
```py
a = not None
b = not not None
reveal_type(a) # revealed: Literal[True]
reveal_type(b) # revealed: Literal[False]
reveal_type(not None) # revealed: Literal[True]
reveal_type(not not None) # revealed: Literal[False]
```
## Function
@ -17,12 +15,9 @@ from typing import reveal_type
def f():
return 1
a = not f
b = not reveal_type
reveal_type(a) # revealed: Literal[False]
reveal_type(not f) # revealed: Literal[False]
# TODO Unknown should not be part of the type of typing.reveal_type
# reveal_type(b) revealed: Literal[False]
# reveal_type(not reveal_type) revealed: Literal[False]
```
## Module
@ -30,11 +25,9 @@ reveal_type(a) # revealed: Literal[False]
```py
import b; import warnings
x = not b
z = not warnings
reveal_type(x) # revealed: Literal[False]
reveal_type(z) # revealed: Literal[False]
reveal_type(not b) # revealed: Literal[False]
reveal_type(not warnings) # revealed: Literal[False]
```
```py path=b.py
@ -57,93 +50,63 @@ else:
s = 0
t = ""
a = not p
b = not q
c = not r
d = not s
e = not t
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: bool
reveal_type(c) # revealed: bool
reveal_type(d) # revealed: bool
reveal_type(e) # revealed: Literal[True]
reveal_type(not p) # revealed: Literal[False]
reveal_type(not q) # revealed: bool
reveal_type(not r) # revealed: bool
reveal_type(not s) # revealed: bool
reveal_type(not t) # revealed: Literal[True]
```
## Integer literal
```py
a = not 1
b = not 1234567890987654321
e = not 0
x = not -1
y = not -1234567890987654321
z = not --987
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: Literal[False]
reveal_type(e) # revealed: Literal[True]
reveal_type(x) # revealed: Literal[False]
reveal_type(y) # revealed: Literal[False]
reveal_type(z) # revealed: Literal[False]
reveal_type(not 1) # revealed: Literal[False]
reveal_type(not 1234567890987654321) # revealed: Literal[False]
reveal_type(not 0) # revealed: Literal[True]
reveal_type(not -1) # revealed: Literal[False]
reveal_type(not -1234567890987654321) # revealed: Literal[False]
reveal_type(not --987) # revealed: Literal[False]
```
## Boolean literal
```py
w = True
x = False
y = not w
z = not x
reveal_type(w) # revealed: Literal[True]
x = False
reveal_type(x) # revealed: Literal[False]
reveal_type(y) # revealed: Literal[False]
reveal_type(z) # revealed: Literal[True]
reveal_type(not w) # revealed: Literal[False]
reveal_type(not x) # revealed: Literal[True]
```
## String literal
```py
a = not "hello"
b = not ""
c = not "0"
d = not "hello" + "world"
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: Literal[True]
reveal_type(c) # revealed: Literal[False]
reveal_type(d) # revealed: Literal[False]
reveal_type(not "hello") # revealed: Literal[False]
reveal_type(not "") # revealed: Literal[True]
reveal_type(not "0") # revealed: Literal[False]
reveal_type(not "hello" + "world") # revealed: Literal[False]
```
## Bytes literal
```py
a = not b"hello"
b = not b""
c = not b"0"
d = not b"hello" + b"world"
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: Literal[True]
reveal_type(c) # revealed: Literal[False]
reveal_type(d) # revealed: Literal[False]
reveal_type(not b"hello") # revealed: Literal[False]
reveal_type(not b"") # revealed: Literal[True]
reveal_type(not b"0") # revealed: Literal[False]
reveal_type(not b"hello" + b"world") # revealed: Literal[False]
```
## Tuple
```py
a = not (1,)
b = not (1, 2)
c = not (1, 2, 3)
d = not ()
e = not ("hello",)
f = not (1, "hello")
reveal_type(a) # revealed: Literal[False]
reveal_type(b) # revealed: Literal[False]
reveal_type(c) # revealed: Literal[False]
reveal_type(d) # revealed: Literal[True]
reveal_type(e) # revealed: Literal[False]
reveal_type(f) # revealed: Literal[False]
reveal_type(not (1,)) # revealed: Literal[False]
reveal_type(not (1, 2)) # revealed: Literal[False]
reveal_type(not (1, 2, 3)) # revealed: Literal[False]
reveal_type(not ()) # revealed: Literal[True]
reveal_type(not ("hello",)) # revealed: Literal[False]
reveal_type(not (1, "hello")) # revealed: Literal[False]
```