-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[red-knot] Port type inference tests to new test framework (#13719)
## Summary Porting infer tests to new markdown tests framework. Link to the corresponding issue: #13696 --------- Co-authored-by: Carl Meyer <[email protected]>
- Loading branch information
Showing
56 changed files
with
2,682 additions
and
4,012 deletions.
There are no files selected for viewing
25 changes: 25 additions & 0 deletions
25
crates/red_knot_python_semantic/resources/mdtest/assignment/annotations.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Assignment with annotations | ||
|
||
## Annotation only transparent to local inference | ||
|
||
```py | ||
x = 1 | ||
x: int | ||
y = x | ||
|
||
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`" | ||
|
||
``` | ||
|
||
## Violates previous annotation | ||
|
||
```py | ||
x: int | ||
x = 'foo' # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`" | ||
``` |
9 changes: 9 additions & 0 deletions
9
crates/red_knot_python_semantic/resources/mdtest/assignment/multi_target.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Multi-target assignment | ||
|
||
## Basic | ||
|
||
```py | ||
x = y = 1 | ||
reveal_type(x) # revealed: Literal[1] | ||
reveal_type(y) # revealed: Literal[1] | ||
``` |
32 changes: 32 additions & 0 deletions
32
crates/red_knot_python_semantic/resources/mdtest/assignment/unbound.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Unbound | ||
|
||
## Maybe unbound | ||
|
||
```py | ||
if flag: | ||
y = 3 | ||
x = y | ||
reveal_type(x) # revealed: Unbound | Literal[3] | ||
``` | ||
|
||
## Unbound | ||
|
||
```py | ||
x = foo; foo = 1 | ||
reveal_type(x) # revealed: Unbound | ||
``` | ||
|
||
## Unbound class variable | ||
|
||
Class variables can reference global variables unless overridden within the class scope. | ||
|
||
```py | ||
x = 1 | ||
class C: | ||
y = x | ||
if flag: | ||
x = 2 | ||
|
||
reveal_type(C.x) # revealed: Unbound | Literal[2] | ||
reveal_type(C.y) # revealed: Literal[1] | ||
``` |
17 changes: 17 additions & 0 deletions
17
crates/red_knot_python_semantic/resources/mdtest/assignment/walrus.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Walrus operator | ||
|
||
## Basic | ||
|
||
```py | ||
x = (y := 1) + 1 | ||
reveal_type(x) # revealed: Literal[2] | ||
reveal_type(y) # revealed: Literal[1] | ||
``` | ||
|
||
## Walrus self-addition | ||
|
||
```py | ||
x = 0 | ||
(x := x + 1) | ||
reveal_type(x) # revealed: Literal[1] | ||
``` |
15 changes: 15 additions & 0 deletions
15
crates/red_knot_python_semantic/resources/mdtest/attributes.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Class attributes | ||
|
||
## Union of attributes | ||
|
||
```py | ||
if flag: | ||
class C: | ||
x = 1 | ||
else: | ||
class C: | ||
x = 2 | ||
|
||
y = C.x | ||
reveal_type(y) # revealed: Literal[1, 2] | ||
``` |
36 changes: 36 additions & 0 deletions
36
crates/red_knot_python_semantic/resources/mdtest/binary/integers.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
## 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] | ||
``` | ||
|
||
## Division by Zero | ||
|
||
```py | ||
# TODO: `a` should be `int` and `e` should be `float` once we support inference. | ||
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 | ||
reveal_type(b) # revealed: int | ||
reveal_type(c) # revealed: int | ||
reveal_type(d) # revealed: @Todo | ||
reveal_type(e) # revealed: @Todo | ||
``` |
21 changes: 21 additions & 0 deletions
21
crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Callable instance | ||
|
||
## Dunder call | ||
|
||
```py | ||
class Multiplier: | ||
def __init__(self, factor: float): | ||
self.factor = factor | ||
|
||
def __call__(self, number: float) -> float: | ||
return number * self.factor | ||
|
||
a = Multiplier(2.0)(3.0) | ||
|
||
class Unit: ... | ||
|
||
b = Unit()(3.0) # error: "Object of type `Unit` is not callable" | ||
|
||
reveal_type(a) # revealed: float | ||
reveal_type(b) # revealed: Unknown | ||
``` |
8 changes: 8 additions & 0 deletions
8
crates/red_knot_python_semantic/resources/mdtest/call/constructor.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Constructor | ||
|
||
```py | ||
class Foo: ... | ||
|
||
x = Foo() | ||
reveal_type(x) # revealed: Foo | ||
``` |
51 changes: 51 additions & 0 deletions
51
crates/red_knot_python_semantic/resources/mdtest/call/function.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Call expression | ||
|
||
## Simple | ||
|
||
```py | ||
def get_int() -> int: | ||
return 42 | ||
|
||
x = get_int() | ||
reveal_type(x) # revealed: int | ||
``` | ||
|
||
## Async | ||
|
||
```py | ||
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 | ||
``` | ||
|
||
## Decorated | ||
|
||
```py | ||
from typing import Callable | ||
|
||
def foo() -> int: | ||
return 42 | ||
|
||
def decorator(func) -> Callable[[], int]: | ||
return foo | ||
|
||
@decorator | ||
def bar() -> str: | ||
return 'bar' | ||
|
||
x = bar() | ||
|
||
# TODO: should reveal `int`, as the decorator replaces `bar` with `foo` | ||
reveal_type(x) # revealed: @Todo | ||
``` | ||
|
||
## Invalid callable | ||
|
||
```py | ||
nonsense = 123 | ||
x = nonsense() # error: "Object of type `Literal[123]` is not callable" | ||
``` |
74 changes: 74 additions & 0 deletions
74
crates/red_knot_python_semantic/resources/mdtest/call/union.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Unions in calls | ||
|
||
## Union of return types | ||
|
||
```py | ||
if flag: | ||
def f() -> int: | ||
return 1 | ||
else: | ||
def f() -> str: | ||
return 'foo' | ||
|
||
x = f() | ||
reveal_type(x) # revealed: int | str | ||
``` | ||
|
||
## Calling with an unknown union | ||
|
||
```py | ||
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 | ||
``` | ||
|
||
## Non-callable elements in a union | ||
|
||
Calling a union with a non-callable element should emit a diagnostic. | ||
|
||
```py | ||
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 | ||
``` | ||
|
||
## Multiple non-callable elements in a union | ||
|
||
Calling a union with multiple non-callable elements should mention all of them in the diagnostic. | ||
|
||
```py | ||
if flag: | ||
f = 1 | ||
elif flag2: | ||
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 | ||
``` | ||
|
||
## All non-callable union elements | ||
|
||
Calling a union with no callable elements can emit a simpler diagnostic. | ||
|
||
```py | ||
if flag: | ||
f = 1 | ||
else: | ||
f = 'foo' | ||
|
||
x = f() # error: "Object of type `Literal[1] | Literal["foo"]` is not callable" | ||
reveal_type(x) # revealed: Unknown | ||
``` |
41 changes: 41 additions & 0 deletions
41
crates/red_knot_python_semantic/resources/mdtest/comparison/integers.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Comparing 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] | ||
``` | ||
|
||
## Integer instance | ||
|
||
```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 | ||
``` |
37 changes: 37 additions & 0 deletions
37
crates/red_knot_python_semantic/resources/mdtest/comparison/non_boolean_returns.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Non boolean returns | ||
|
||
Walking through examples: | ||
|
||
- `a = A() < B() < C()` | ||
|
||
1. `A() < B() and B() < C()` - split in N comparison | ||
1. `A()` and `B()` - evaluate outcome types | ||
1. `bool` and `bool` - evaluate truthiness | ||
1. `A | B` - union of "first true" types | ||
|
||
- `b = 0 < 1 < A() < 3` | ||
|
||
1. `0 < 1 and 1 < A() and A() < 3` - split in N comparison | ||
1. `True` and `bool` and `A` - evaluate outcome types | ||
1. `True` and `bool` and `bool` - evaluate truthiness | ||
1. `bool | A` - union of "true" types | ||
|
||
- `c = 10 < 0 < A() < B() < C()` short-circuit to False | ||
|
||
```py | ||
from __future__ import annotations | ||
class A: | ||
def __lt__(self, other) -> A: ... | ||
class B: | ||
def __lt__(self, other) -> B: ... | ||
class C: | ||
def __lt__(self, other) -> C: ... | ||
|
||
a = A() < B() < C() | ||
b = 0 < 1 < A() < 3 | ||
c = 10 < 0 < A() < B() < C() | ||
|
||
reveal_type(a) # revealed: A | B | ||
reveal_type(b) # revealed: bool | A | ||
reveal_type(c) # revealed: Literal[False] | ||
``` |
Oops, something went wrong.