From c2f7c399879356b6fac72ab15e7bc781f7108931 Mon Sep 17 00:00:00 2001 From: David Peter Date: Fri, 18 Oct 2024 11:07:53 +0200 Subject: [PATCH] [red-knot] mdtest suite: formatting and cleanup (#13806) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../mdtest/assignment/annotations.md | 2 +- .../resources/mdtest/assignment/unbound.md | 4 +- .../resources/mdtest/attributes.md | 3 +- .../resources/mdtest/binary/integers.md | 34 +++-- .../mdtest/call/callable_instance.md | 7 +- .../resources/mdtest/call/constructor.md | 3 +- .../resources/mdtest/call/function.md | 11 +- .../resources/mdtest/call/union.md | 8 +- .../mdtest/comparison/byte_literals.md | 38 +++--- .../resources/mdtest/comparison/integers.md | 42 +++---- .../mdtest/comparison/non_boolean_returns.md | 15 +-- .../resources/mdtest/comparison/strings.md | 35 ++---- .../resources/mdtest/comparison/tuples.md | 42 +++---- .../resources/mdtest/comparison/unions.md | 4 +- .../mdtest/comparison/unsupported.md | 18 +-- .../mdtest/conditional/if_expression.md | 6 +- .../mdtest/conditional/if_statement.md | 7 +- .../resources/mdtest/exception/basic.md | 2 +- .../resources/mdtest/expression/boolean.md | 117 ++++++------------ .../resources/mdtest/import/basic.md | 4 +- .../resources/mdtest/import/builtins.md | 2 +- .../resources/mdtest/import/errors.md | 8 +- .../resources/mdtest/import/relative.md | 16 +-- .../resources/mdtest/literal/boolean.md | 6 +- .../mdtest/literal/collections/dictionary.md | 3 +- .../mdtest/literal/collections/list.md | 3 +- .../mdtest/literal/collections/set.md | 3 +- .../mdtest/literal/collections/tuple.md | 13 +- .../resources/mdtest/literal/f_string.md | 29 ++--- .../resources/mdtest/literal/string.md | 22 ++-- .../resources/mdtest/loops/for_loop.md | 6 +- .../resources/mdtest/loops/iterators.md | 2 +- .../resources/mdtest/loops/while_loop.md | 3 +- .../resources/mdtest/narrow/not_none.md | 9 -- .../resources/mdtest/shadowing/class.md | 2 +- .../resources/mdtest/shadowing/function.md | 2 +- .../resources/mdtest/subscript/bytes.md | 13 +- .../resources/mdtest/subscript/class.md | 19 ++- .../resources/mdtest/subscript/instance.md | 6 +- .../resources/mdtest/subscript/lists.md | 5 + .../resources/mdtest/subscript/string.md | 21 ++-- .../resources/mdtest/subscript/tuple.md | 21 ++-- .../resources/mdtest/unary/integers.md | 30 ++--- .../resources/mdtest/unary/not.md | 111 ++++++----------- 44 files changed, 289 insertions(+), 468 deletions(-) delete mode 100644 crates/red_knot_python_semantic/resources/mdtest/narrow/not_none.md diff --git a/crates/red_knot_python_semantic/resources/mdtest/assignment/annotations.md b/crates/red_knot_python_semantic/resources/mdtest/assignment/annotations.md index c56674aebb..bbac55c29a 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/assignment/annotations.md +++ b/crates/red_knot_python_semantic/resources/mdtest/assignment/annotations.md @@ -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`" ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/assignment/unbound.md b/crates/red_knot_python_semantic/resources/mdtest/assignment/unbound.md index 8005c6aee4..7c8bdda4a2 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/assignment/unbound.md +++ b/crates/red_knot_python_semantic/resources/mdtest/assignment/unbound.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/attributes.md b/crates/red_knot_python_semantic/resources/mdtest/attributes.md index b077f515c0..367cae61bb 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/attributes.md +++ b/crates/red_knot_python_semantic/resources/mdtest/attributes.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/binary/integers.md b/crates/red_knot_python_semantic/resources/mdtest/binary/integers.md index 0d5c4e7048..54655e5575 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/binary/integers.md +++ b/crates/red_knot_python_semantic/resources/mdtest/binary/integers.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md b/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md index 1b1c46bcc1..1719601372 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/callable_instance.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md b/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md index 100568a8dd..b9927fe086 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md @@ -3,6 +3,5 @@ ```py class Foo: ... -x = Foo() -reveal_type(x) # revealed: Foo +reveal_type(Foo()) # revealed: Foo ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/function.md b/crates/red_knot_python_semantic/resources/mdtest/call/function.md index 055345eb28..eaa6d143fd 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/function.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/function.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/call/union.md b/crates/red_knot_python_semantic/resources/mdtest/call/union.md index 25beeedcd4..f91aad0375 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/call/union.md +++ b/crates/red_knot_python_semantic/resources/mdtest/call/union.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/byte_literals.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/byte_literals.md index 30487f00d6..27aee9f1c8 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/byte_literals.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/byte_literals.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/integers.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/integers.md index a72f02129b..748b94eda3 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/integers.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/integers.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/non_boolean_returns.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/non_boolean_returns.md index 8917afba7f..e42203edd5 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/non_boolean_returns.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/non_boolean_returns.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/strings.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/strings.md index 04b5c41f01..04cfc6771e 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/strings.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/strings.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/tuples.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/tuples.md index 7497e23000..808f76f317 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/tuples.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/tuples.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/unions.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/unions.md index e7589b7fea..9686196bc0 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/unions.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/unions.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/comparison/unsupported.md b/crates/red_knot_python_semantic/resources/mdtest/comparison/unsupported.md index 156d03342e..237bf5a6b2 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/comparison/unsupported.md +++ b/crates/red_knot_python_semantic/resources/mdtest/comparison/unsupported.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/conditional/if_expression.md b/crates/red_knot_python_semantic/resources/mdtest/conditional/if_expression.md index cdd2e400da..c9028c7859 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/conditional/if_expression.md +++ b/crates/red_knot_python_semantic/resources/mdtest/conditional/if_expression.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/conditional/if_statement.md b/crates/red_knot_python_semantic/resources/mdtest/conditional/if_statement.md index fbfa4e7acd..73e73f4506 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/conditional/if_statement.md +++ b/crates/red_knot_python_semantic/resources/mdtest/conditional/if_statement.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/exception/basic.md b/crates/red_knot_python_semantic/resources/mdtest/exception/basic.md index f0af58b3b7..5e4c7b3468 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/exception/basic.md +++ b/crates/red_knot_python_semantic/resources/mdtest/exception/basic.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/expression/boolean.md b/crates/red_knot_python_semantic/resources/mdtest/expression/boolean.md index f27d6cfc11..3398cff77d 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/expression/boolean.md +++ b/crates/red_knot_python_semantic/resources/mdtest/expression/boolean.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/import/basic.md b/crates/red_knot_python_semantic/resources/mdtest/import/basic.md index b3702cbcac..6876ce3142 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/import/basic.md +++ b/crates/red_knot_python_semantic/resources/mdtest/import/basic.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/import/builtins.md b/crates/red_knot_python_semantic/resources/mdtest/import/builtins.md index 4c0c66fdd0..9f5044c484 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/import/builtins.md +++ b/crates/red_knot_python_semantic/resources/mdtest/import/builtins.md @@ -2,5 +2,5 @@ ```py import builtins; x = builtins.copyright -reveal_type(x) # revealed: Literal[copyright] +reveal_type(x) # revealed: Literal[copyright] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/import/errors.md b/crates/red_knot_python_semantic/resources/mdtest/import/errors.md index fac4acc60b..c611f40c7e 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/import/errors.md +++ b/crates/red_knot_python_semantic/resources/mdtest/import/errors.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/import/relative.md b/crates/red_knot_python_semantic/resources/mdtest/import/relative.md index fd1c4453db..ebbccc8bb7 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/import/relative.md +++ b/crates/red_knot_python_semantic/resources/mdtest/import/relative.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/literal/boolean.md b/crates/red_knot_python_semantic/resources/mdtest/literal/boolean.md index 00cc4073a7..ac13a56c4d 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/literal/boolean.md +++ b/crates/red_knot_python_semantic/resources/mdtest/literal/boolean.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/dictionary.md b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/dictionary.md index dc4aa3197f..9a57135f2a 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/dictionary.md +++ b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/dictionary.md @@ -3,6 +3,5 @@ ## Empty dictionary ```py -x = {} -reveal_type(x) # revealed: dict +reveal_type({}) # revealed: dict ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/list.md b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/list.md index 67b3e1f907..70c98aa3a6 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/list.md +++ b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/list.md @@ -3,6 +3,5 @@ ## Empty list ```py -x = [] -reveal_type(x) # revealed: list +reveal_type([]) # revealed: list ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/set.md b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/set.md index dcd1da384b..452fc719db 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/set.md +++ b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/set.md @@ -3,6 +3,5 @@ ## Basic set ```py -x = {1, 2} -reveal_type(x) # revealed: set +reveal_type({1, 2}) # revealed: set ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/tuple.md b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/tuple.md index 159da51d8e..deaf60cb27 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/literal/collections/tuple.md +++ b/crates/red_knot_python_semantic/resources/mdtest/literal/collections/tuple.md @@ -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]] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/literal/f_string.md b/crates/red_knot_python_semantic/resources/mdtest/literal/f_string.md index 524b76d9fc..30c72531ce 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/literal/f_string.md +++ b/crates/red_knot_python_semantic/resources/mdtest/literal/f_string.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/literal/string.md b/crates/red_knot_python_semantic/resources/mdtest/literal/string.md index 80a320eece..da5f469735 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/literal/string.md +++ b/crates/red_knot_python_semantic/resources/mdtest/literal/string.md @@ -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"] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/loops/for_loop.md b/crates/red_knot_python_semantic/resources/mdtest/loops/for_loop.md index dc12ca30af..95cf6e34cb 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/loops/for_loop.md +++ b/crates/red_knot_python_semantic/resources/mdtest/loops/for_loop.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/loops/iterators.md b/crates/red_knot_python_semantic/resources/mdtest/loops/iterators.md index 95ad5c448d..b9b8ae40b9 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/loops/iterators.md +++ b/crates/red_knot_python_semantic/resources/mdtest/loops/iterators.md @@ -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" ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/loops/while_loop.md b/crates/red_knot_python_semantic/resources/mdtest/loops/while_loop.md index e75786f693..daba14ac98 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/loops/while_loop.md +++ b/crates/red_knot_python_semantic/resources/mdtest/loops/while_loop.md @@ -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) diff --git a/crates/red_knot_python_semantic/resources/mdtest/narrow/not_none.md b/crates/red_knot_python_semantic/resources/mdtest/narrow/not_none.md deleted file mode 100644 index 5faed9a52b..0000000000 --- a/crates/red_knot_python_semantic/resources/mdtest/narrow/not_none.md +++ /dev/null @@ -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] -``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/shadowing/class.md b/crates/red_knot_python_semantic/resources/mdtest/shadowing/class.md index feae514a21..8267bfd635 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/shadowing/class.md +++ b/crates/red_knot_python_semantic/resources/mdtest/shadowing/class.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/shadowing/function.md b/crates/red_knot_python_semantic/resources/mdtest/shadowing/function.md index 90e2e3ec52..c6113a62dd 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/shadowing/function.md +++ b/crates/red_knot_python_semantic/resources/mdtest/shadowing/function.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/subscript/bytes.md b/crates/red_knot_python_semantic/resources/mdtest/subscript/bytes.md index af8fb7a424..58eda3ac46 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/subscript/bytes.md +++ b/crates/red_knot_python_semantic/resources/mdtest/subscript/bytes.md @@ -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"] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/subscript/class.md b/crates/red_knot_python_semantic/resources/mdtest/subscript/class.md index e9c28dff23..d00fe34cd7 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/subscript/class.md +++ b/crates/red_knot_python_semantic/resources/mdtest/subscript/class.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/subscript/instance.md b/crates/red_knot_python_semantic/resources/mdtest/subscript/instance.md index a363f0fb3c..e0edc55ba9 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/subscript/instance.md +++ b/crates/red_knot_python_semantic/resources/mdtest/subscript/instance.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/subscript/lists.md b/crates/red_knot_python_semantic/resources/mdtest/subscript/lists.md index dd665d7cc4..b82b23f192 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/subscript/lists.md +++ b/crates/red_knot_python_semantic/resources/mdtest/subscript/lists.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/subscript/string.md b/crates/red_knot_python_semantic/resources/mdtest/subscript/string.md index f4bee2b32e..6d73ac3355 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/subscript/string.md +++ b/crates/red_knot_python_semantic/resources/mdtest/subscript/string.md @@ -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 diff --git a/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md b/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md index f837d989d2..23b3537f0b 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md +++ b/crates/red_knot_python_semantic/resources/mdtest/subscript/tuple.md @@ -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 ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/unary/integers.md b/crates/red_knot_python_semantic/resources/mdtest/unary/integers.md index 04878aa68b..c91755981f 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/unary/integers.md +++ b/crates/red_knot_python_semantic/resources/mdtest/unary/integers.md @@ -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] ``` diff --git a/crates/red_knot_python_semantic/resources/mdtest/unary/not.md b/crates/red_knot_python_semantic/resources/mdtest/unary/not.md index db959a686a..f657ce0e40 100644 --- a/crates/red_knot_python_semantic/resources/mdtest/unary/not.md +++ b/crates/red_knot_python_semantic/resources/mdtest/unary/not.md @@ -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] ```