mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
[red-knot] Autoformat mdtest
Python snippets using blacken-docs
(#13809)
This commit is contained in:
parent
2ff36530c3
commit
36cb1199cc
45 changed files with 331 additions and 132 deletions
|
@ -45,6 +45,15 @@ repos:
|
|||
| docs/\w+\.md
|
||||
)$
|
||||
|
||||
- repo: https://github.com/adamchainz/blacken-docs
|
||||
rev: 1.19.0
|
||||
hooks:
|
||||
- id: blacken-docs
|
||||
args: ["--line-length", "130"]
|
||||
files: '^crates/.*/resources/mdtest/.*\.md'
|
||||
additional_dependencies:
|
||||
- black==24.10.0
|
||||
|
||||
- repo: https://github.com/crate-ci/typos
|
||||
rev: v1.25.0
|
||||
hooks:
|
||||
|
|
|
@ -13,13 +13,12 @@ reveal_type(y) # revealed: Literal[1]
|
|||
## Violates own annotation
|
||||
|
||||
```py
|
||||
x: int = 'foo' # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
|
||||
|
||||
x: int = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
|
||||
```
|
||||
|
||||
## Violates previous annotation
|
||||
|
||||
```py
|
||||
x: int
|
||||
x = 'foo' # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
|
||||
x = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]` is not assignable to `int`"
|
||||
```
|
||||
|
|
|
@ -14,11 +14,14 @@ Name lookups within a class scope fall back to globals, but lookups of class att
|
|||
|
||||
```py
|
||||
x = 1
|
||||
|
||||
|
||||
class C:
|
||||
y = x
|
||||
if flag:
|
||||
x = 2
|
||||
|
||||
|
||||
reveal_type(C.x) # revealed: Literal[2]
|
||||
reveal_type(C.y) # revealed: Literal[1]
|
||||
```
|
||||
|
|
|
@ -4,11 +4,15 @@
|
|||
|
||||
```py
|
||||
if flag:
|
||||
|
||||
class C:
|
||||
x = 1
|
||||
|
||||
else:
|
||||
|
||||
class C:
|
||||
x = 2
|
||||
|
||||
|
||||
reveal_type(C.x) # revealed: Literal[1, 2]
|
||||
```
|
||||
|
|
|
@ -42,7 +42,9 @@ e = 1.0 / 0 # error: "Cannot divide object of type `float` by zero"
|
|||
# TODO should be float
|
||||
reveal_type(e) # revealed: @Todo
|
||||
|
||||
class MyInt(int): pass
|
||||
|
||||
class MyInt(int): ...
|
||||
|
||||
|
||||
# No error for a subclass of int
|
||||
# TODO should be float
|
||||
|
|
|
@ -10,11 +10,14 @@ class Multiplier:
|
|||
def __call__(self, number: float) -> float:
|
||||
return number * self.factor
|
||||
|
||||
|
||||
a = Multiplier(2.0)(3.0)
|
||||
reveal_type(a) # revealed: float
|
||||
|
||||
|
||||
class Unit: ...
|
||||
|
||||
|
||||
b = Unit()(3.0) # error: "Object of type `Unit` is not callable"
|
||||
reveal_type(b) # revealed: Unknown
|
||||
```
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
```py
|
||||
class Foo: ...
|
||||
|
||||
|
||||
reveal_type(Foo()) # revealed: Foo
|
||||
```
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
def get_int() -> int:
|
||||
return 42
|
||||
|
||||
|
||||
reveal_type(get_int()) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -15,6 +16,7 @@ reveal_type(get_int()) # revealed: int
|
|||
async def get_int_async() -> int:
|
||||
return 42
|
||||
|
||||
|
||||
# TODO: we don't yet support `types.CoroutineType`, should be generic `Coroutine[Any, Any, int]`
|
||||
reveal_type(get_int_async()) # revealed: @Todo
|
||||
```
|
||||
|
@ -24,15 +26,19 @@ reveal_type(get_int_async()) # revealed: @Todo
|
|||
```py
|
||||
from typing import Callable
|
||||
|
||||
|
||||
def foo() -> int:
|
||||
return 42
|
||||
|
||||
|
||||
def decorator(func) -> Callable[[], int]:
|
||||
return foo
|
||||
|
||||
|
||||
@decorator
|
||||
def bar() -> str:
|
||||
return 'bar'
|
||||
return "bar"
|
||||
|
||||
|
||||
# TODO: should reveal `int`, as the decorator replaces `bar` with `foo`
|
||||
reveal_type(bar()) # revealed: @Todo
|
||||
|
|
|
@ -4,11 +4,15 @@
|
|||
|
||||
```py
|
||||
if flag:
|
||||
|
||||
def f() -> int:
|
||||
return 1
|
||||
|
||||
else:
|
||||
|
||||
def f() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
reveal_type(f()) # revealed: int | str
|
||||
```
|
||||
|
@ -19,9 +23,11 @@ reveal_type(f()) # revealed: int | str
|
|||
from nonexistent import f # error: [unresolved-import] "Cannot resolve import `nonexistent`"
|
||||
|
||||
if flag:
|
||||
|
||||
def f() -> int:
|
||||
return 1
|
||||
|
||||
|
||||
reveal_type(f()) # revealed: Unknown | int
|
||||
```
|
||||
|
||||
|
@ -33,9 +39,11 @@ Calling a union with a non-callable element should emit a diagnostic.
|
|||
if flag:
|
||||
f = 1
|
||||
else:
|
||||
|
||||
def f() -> int:
|
||||
return 1
|
||||
|
||||
|
||||
x = f() # error: "Object of type `Literal[1] | Literal[f]` is not callable (due to union element `Literal[1]`)"
|
||||
reveal_type(x) # revealed: Unknown | int
|
||||
```
|
||||
|
@ -48,13 +56,16 @@ Calling a union with multiple non-callable elements should mention all of them i
|
|||
if flag:
|
||||
f = 1
|
||||
elif flag2:
|
||||
f = 'foo'
|
||||
f = "foo"
|
||||
else:
|
||||
|
||||
def f() -> int:
|
||||
return 1
|
||||
|
||||
x = f() # error: "Object of type `Literal[1] | Literal["foo"] | Literal[f]` is not callable (due to union elements Literal[1], Literal["foo"])"
|
||||
reveal_type(x) # revealed: Unknown | int
|
||||
|
||||
# error: "Object of type `Literal[1] | Literal["foo"] | Literal[f]` is not callable (due to union elements Literal[1], Literal["foo"])"
|
||||
# revealed: Unknown | int
|
||||
reveal_type(f())
|
||||
```
|
||||
|
||||
## All non-callable union elements
|
||||
|
@ -65,7 +76,7 @@ Calling a union with no callable elements can emit a simpler diagnostic.
|
|||
if flag:
|
||||
f = 1
|
||||
else:
|
||||
f = 'foo'
|
||||
f = "foo"
|
||||
|
||||
x = f() # error: "Object of type `Literal[1] | Literal["foo"]` is not callable"
|
||||
reveal_type(x) # revealed: Unknown
|
||||
|
|
|
@ -21,6 +21,7 @@ reveal_type(1 <= "" and 0 < 1) # revealed: @Todo | Literal[True]
|
|||
# TODO: implement lookup of `__eq__` on typeshed `int` stub.
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
reveal_type(1 == int_instance()) # revealed: @Todo
|
||||
reveal_type(9 < int_instance()) # revealed: bool
|
||||
reveal_type(int_instance() < int_instance()) # revealed: bool
|
||||
|
|
|
@ -20,6 +20,8 @@ Walking through examples:
|
|||
|
||||
```py
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class A:
|
||||
def __lt__(self, other) -> A: ...
|
||||
class B:
|
||||
|
@ -27,6 +29,7 @@ class B:
|
|||
class C:
|
||||
def __lt__(self, other) -> C: ...
|
||||
|
||||
|
||||
x = A() < B() < C()
|
||||
reveal_type(x) # revealed: A | B
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
```py
|
||||
def str_instance() -> str: ...
|
||||
|
||||
|
||||
reveal_type("abc" == "abc") # revealed: Literal[True]
|
||||
reveal_type("ab_cd" <= "ab_ce") # revealed: Literal[True]
|
||||
reveal_type("abc" in "ab cd") # revealed: Literal[False]
|
||||
|
|
|
@ -61,6 +61,7 @@ reveal_type(c >= d) # revealed: Literal[True]
|
|||
def bool_instance() -> bool: ...
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
a = (bool_instance(),)
|
||||
b = (int_instance(),)
|
||||
|
||||
|
@ -135,7 +136,7 @@ reveal_type(c >= c) # revealed: Literal[True]
|
|||
#### Non Boolean Rich Comparisons
|
||||
|
||||
```py
|
||||
class A():
|
||||
class A:
|
||||
def __eq__(self, o) -> str: ...
|
||||
def __ne__(self, o) -> int: ...
|
||||
def __lt__(self, o) -> float: ...
|
||||
|
@ -143,6 +144,7 @@ class A():
|
|||
def __gt__(self, o) -> tuple: ...
|
||||
def __ge__(self, o) -> list: ...
|
||||
|
||||
|
||||
a = (A(), A())
|
||||
|
||||
# TODO: All @Todo should be bool
|
||||
|
@ -161,6 +163,7 @@ reveal_type(a >= a) # revealed: @Todo
|
|||
```py
|
||||
def int_instance() -> int: ...
|
||||
|
||||
|
||||
a = (1, 2)
|
||||
b = ((3, 4), (1, 2))
|
||||
c = ((1, 2, 3), (4, 5, 6))
|
||||
|
|
|
@ -35,5 +35,5 @@ else:
|
|||
|
||||
# error: [conflicting-declarations]
|
||||
# error: [invalid-assignment]
|
||||
x = b'foo'
|
||||
x = b"foo"
|
||||
```
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
```py
|
||||
import re
|
||||
|
||||
try:
|
||||
x
|
||||
except NameError as e:
|
||||
|
|
|
@ -38,7 +38,8 @@ to the `except` suite *after* that redefinition.
|
|||
|
||||
```py path=union_type_inferred.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -60,7 +61,8 @@ unify and `x` is not inferred as having a union type following the
|
|||
|
||||
```py path=branches_unify_to_non_union_type.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -84,7 +86,8 @@ possibility when it comes to control-flow analysis.
|
|||
|
||||
```py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -114,7 +117,8 @@ the three suites:
|
|||
|
||||
```py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -147,7 +151,8 @@ the end of the `except` suite:
|
|||
|
||||
```py path=single_except.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -175,7 +180,8 @@ in their entireties:
|
|||
|
||||
```py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -208,7 +214,8 @@ therefore `Literal[2]`:
|
|||
|
||||
```py path=redef_in_finally.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -235,7 +242,8 @@ suites, however; this is still a TODO item for us.)
|
|||
|
||||
```py path=no_redef_in_finally.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
|
@ -267,14 +275,17 @@ following possibilities inside `finally` suites:
|
|||
|
||||
```py path=redef_in_finally.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b'foo'
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -305,14 +316,17 @@ conclusion of the `finally` suite.)
|
|||
|
||||
```py path=no_redef_in_finally.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b'foo'
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -336,20 +350,25 @@ An example with multiple `except` branches and a `finally` branch:
|
|||
|
||||
```py path=multiple_except_branches.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b'foo'
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -383,20 +402,25 @@ partway through the `else` suite due to an exception raised *there*.
|
|||
|
||||
```py path=single_except_branch.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b'foo'
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -426,26 +450,33 @@ The same again, this time with multiple `except` branches:
|
|||
|
||||
```py path=multiple_except_branches.py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b'foo'
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
def could_raise_returns_range() -> range:
|
||||
return range(42)
|
||||
|
||||
|
||||
def could_raise_returns_slice() -> slice:
|
||||
return slice(None)
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -491,41 +522,55 @@ prior to the suite running to completion.
|
|||
|
||||
```py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b'foo'
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def could_raise_returns_memoryview() -> memoryview:
|
||||
return memoryview(b"")
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
def could_raise_returns_range() -> range:
|
||||
return range(42)
|
||||
|
||||
|
||||
def could_raise_returns_slice() -> slice:
|
||||
return slice(None)
|
||||
|
||||
|
||||
def could_raise_returns_complex() -> complex:
|
||||
return 3j
|
||||
|
||||
|
||||
def could_raise_returns_bytearray() -> bytearray:
|
||||
return bytearray()
|
||||
|
||||
|
||||
class Foo: ...
|
||||
|
||||
|
||||
class Bar: ...
|
||||
|
||||
|
||||
def could_raise_returns_Foo() -> Foo:
|
||||
return Foo()
|
||||
|
||||
|
||||
def could_raise_returns_Bar() -> Bar:
|
||||
return Bar()
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
@ -585,23 +630,29 @@ variable by that name in the outer scope:
|
|||
|
||||
```py
|
||||
def could_raise_returns_str() -> str:
|
||||
return 'foo'
|
||||
return "foo"
|
||||
|
||||
|
||||
def could_raise_returns_bytes() -> bytes:
|
||||
return b'foo'
|
||||
return b"foo"
|
||||
|
||||
|
||||
def could_raise_returns_range() -> range:
|
||||
return range(42)
|
||||
|
||||
|
||||
def could_raise_returns_bytearray() -> bytearray:
|
||||
return bytearray()
|
||||
|
||||
|
||||
def could_raise_returns_float() -> float:
|
||||
return 3.14
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
try:
|
||||
|
||||
def foo(param=could_raise_returns_str()):
|
||||
x = could_raise_returns_str()
|
||||
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
def foo() -> str:
|
||||
pass
|
||||
|
||||
|
||||
reveal_type(True or False) # revealed: Literal[True]
|
||||
reveal_type('x' or 'y' or 'z') # revealed: Literal["x"]
|
||||
reveal_type('' or 'y' or 'z') # revealed: Literal["y"]
|
||||
reveal_type(False or 'z') # revealed: Literal["z"]
|
||||
reveal_type("x" or "y" or "z") # revealed: Literal["x"]
|
||||
reveal_type("" or "y" or "z") # revealed: Literal["y"]
|
||||
reveal_type(False or "z") # revealed: Literal["z"]
|
||||
reveal_type(False or True) # revealed: Literal[True]
|
||||
reveal_type(False or False) # revealed: Literal[False]
|
||||
reveal_type(foo() or False) # revealed: str | Literal[False]
|
||||
|
@ -22,13 +23,14 @@ reveal_type(foo() or True) # revealed: str | Literal[True]
|
|||
def foo() -> str:
|
||||
pass
|
||||
|
||||
|
||||
reveal_type(True and False) # revealed: Literal[False]
|
||||
reveal_type(False and True) # revealed: Literal[False]
|
||||
reveal_type(foo() and False) # revealed: str | Literal[False]
|
||||
reveal_type(foo() and True) # revealed: str | Literal[True]
|
||||
reveal_type('x' and 'y' and 'z') # revealed: Literal["z"]
|
||||
reveal_type('x' and 'y' and '') # revealed: Literal[""]
|
||||
reveal_type('' and 'y') # revealed: Literal[""]
|
||||
reveal_type("x" and "y" and "z") # revealed: Literal["z"]
|
||||
reveal_type("x" and "y" and "") # revealed: Literal[""]
|
||||
reveal_type("" and "y") # revealed: Literal[""]
|
||||
```
|
||||
|
||||
## Simple function calls to bool
|
||||
|
@ -37,6 +39,7 @@ reveal_type('' and 'y') # revealed: Literal[""]
|
|||
def returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
if returns_bool():
|
||||
x = True
|
||||
else:
|
||||
|
@ -51,6 +54,7 @@ reveal_type(x) # revealed: bool
|
|||
def foo() -> str:
|
||||
pass
|
||||
|
||||
|
||||
reveal_type("x" and "y" or "z") # revealed: Literal["y"]
|
||||
reveal_type("x" or "y" and "z") # revealed: Literal["x"]
|
||||
reveal_type("" and "y" or "z") # revealed: Literal["z"]
|
||||
|
@ -66,7 +70,9 @@ reveal_type("x" or "y" and "") # revealed: Literal["x"]
|
|||
```py path=a.py
|
||||
redefined_builtin_bool = bool
|
||||
|
||||
def my_bool(x)-> bool: pass
|
||||
|
||||
def my_bool(x) -> bool:
|
||||
return True
|
||||
```
|
||||
|
||||
```py
|
||||
|
@ -84,7 +90,10 @@ reveal_type(bool((0,))) # revealed: Literal[True]
|
|||
reveal_type(bool("NON EMPTY")) # revealed: Literal[True]
|
||||
reveal_type(bool(True)) # revealed: Literal[True]
|
||||
|
||||
def foo(): pass
|
||||
|
||||
def foo(): ...
|
||||
|
||||
|
||||
reveal_type(bool(foo)) # revealed: Literal[True]
|
||||
```
|
||||
|
||||
|
|
|
@ -8,9 +8,11 @@ Basic PEP 695 generics
|
|||
class MyBox[T]:
|
||||
data: T
|
||||
box_model_number = 695
|
||||
|
||||
def __init__(self, data: T):
|
||||
self.data = data
|
||||
|
||||
|
||||
# TODO not error (should be subscriptable)
|
||||
box: MyBox[int] = MyBox(5) # error: [non-subscriptable]
|
||||
# TODO error differently (str and int don't unify)
|
||||
|
@ -30,9 +32,10 @@ class MyBox[T]:
|
|||
def __init__(self, data: T):
|
||||
self.data = data
|
||||
|
||||
|
||||
# TODO not error on the subscripting
|
||||
class MySecureBox[T](MyBox[T]): # error: [non-subscriptable]
|
||||
pass
|
||||
class MySecureBox[T](MyBox[T]): ... # error: [non-subscriptable]
|
||||
|
||||
|
||||
secure_box: MySecureBox[int] = MySecureBox(5)
|
||||
reveal_type(secure_box) # revealed: MySecureBox
|
||||
|
@ -47,11 +50,12 @@ In type stubs, classes can reference themselves in their base class definitions.
|
|||
This should hold true even with generics at play.
|
||||
|
||||
```py path=a.pyi
|
||||
class Seq[T]:
|
||||
pass
|
||||
class Seq[T]: ...
|
||||
|
||||
|
||||
# TODO not error on the subscripting
|
||||
class S[T](Seq[S]): # error: [non-subscriptable]
|
||||
pass
|
||||
class S[T](Seq[S]): ... # error: [non-subscriptable]
|
||||
|
||||
|
||||
reveal_type(S) # revealed: Literal[S]
|
||||
```
|
||||
|
|
|
@ -3,21 +3,25 @@
|
|||
## Class import following
|
||||
|
||||
```py
|
||||
from b import C as D; E = D
|
||||
from b import C as D
|
||||
|
||||
E = D
|
||||
reveal_type(E) # revealed: Literal[C]
|
||||
```
|
||||
|
||||
```py path=b.py
|
||||
class C: pass
|
||||
class C: ...
|
||||
```
|
||||
|
||||
## Module member resolution
|
||||
|
||||
```py
|
||||
import b; D = b.C
|
||||
import b
|
||||
|
||||
D = b.C
|
||||
reveal_type(D) # revealed: Literal[C]
|
||||
```
|
||||
|
||||
```py path=b.py
|
||||
class C: pass
|
||||
class C: ...
|
||||
```
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Importing builtin module
|
||||
|
||||
```py
|
||||
import builtins; x = builtins.copyright
|
||||
import builtins
|
||||
|
||||
x = builtins.copyright
|
||||
reveal_type(x) # revealed: Literal[copyright]
|
||||
```
|
||||
|
|
|
@ -12,6 +12,7 @@ reveal_type(y) # revealed: Unbound | Literal[3]
|
|||
|
||||
```py
|
||||
from maybe_unbound import x, y
|
||||
|
||||
reveal_type(x) # revealed: Literal[3]
|
||||
reveal_type(y) # revealed: Literal[3]
|
||||
```
|
||||
|
@ -30,6 +31,7 @@ Importing an annotated name prefers the declared type over the inferred type:
|
|||
|
||||
```py
|
||||
from maybe_unbound_annotated import x, y
|
||||
|
||||
reveal_type(x) # revealed: Literal[3]
|
||||
reveal_type(y) # revealed: int
|
||||
```
|
||||
|
@ -44,11 +46,13 @@ def f(): ...
|
|||
if flag:
|
||||
from c import f
|
||||
else:
|
||||
|
||||
def f(): ...
|
||||
```
|
||||
|
||||
```py
|
||||
from b import f
|
||||
|
||||
# TODO: We should disambiguate in such cases, showing `Literal[b.f, c.f]`.
|
||||
reveal_type(f) # revealed: Literal[f, f]
|
||||
```
|
||||
|
@ -71,5 +75,6 @@ else:
|
|||
|
||||
```py
|
||||
from b import x
|
||||
|
||||
reveal_type(x) # revealed: int
|
||||
```
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
```py
|
||||
import bar # error: "Cannot resolve import `bar`"
|
||||
|
||||
reveal_type(bar) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -11,6 +12,7 @@ reveal_type(bar) # revealed: Unknown
|
|||
|
||||
```py
|
||||
from bar import baz # error: "Cannot resolve import `bar`"
|
||||
|
||||
reveal_type(baz) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -21,6 +23,7 @@ reveal_type(baz) # revealed: Unknown
|
|||
|
||||
```py
|
||||
from a import thing # error: "Module `a` has no member `thing`"
|
||||
|
||||
reveal_type(thing) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -28,6 +31,7 @@ reveal_type(thing) # revealed: Unknown
|
|||
|
||||
```py path=a.py
|
||||
import foo as foo # error: "Cannot resolve import `foo`"
|
||||
|
||||
reveal_type(foo) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -36,6 +40,7 @@ import" violation:
|
|||
|
||||
```py
|
||||
from a import foo
|
||||
|
||||
reveal_type(foo) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -48,5 +53,5 @@ x: int
|
|||
```py
|
||||
from b import x
|
||||
|
||||
x = 'foo' # error: [invalid-assignment] "Object of type `Literal["foo"]"
|
||||
x = "foo" # error: [invalid-assignment] "Object of type `Literal["foo"]"
|
||||
```
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
```py path=package/bar.py
|
||||
from .foo import X # error: [unresolved-import]
|
||||
|
||||
reveal_type(X) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -21,6 +22,7 @@ X = 42
|
|||
|
||||
```py path=package/bar.py
|
||||
from .foo import X
|
||||
|
||||
reveal_type(X) # revealed: Literal[42]
|
||||
```
|
||||
|
||||
|
@ -35,6 +37,7 @@ X = 42
|
|||
|
||||
```py path=package/bar.py
|
||||
from .foo.bar.baz import X
|
||||
|
||||
reveal_type(X) # revealed: Literal[42]
|
||||
```
|
||||
|
||||
|
@ -46,6 +49,7 @@ X = 42
|
|||
|
||||
```py path=package/bar.py
|
||||
from . import X
|
||||
|
||||
reveal_type(X) # revealed: Literal[42]
|
||||
```
|
||||
|
||||
|
@ -53,6 +57,7 @@ reveal_type(X) # revealed: Literal[42]
|
|||
|
||||
```py path=package/bar.py
|
||||
from . import X # error: [unresolved-import]
|
||||
|
||||
reveal_type(X) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -60,6 +65,7 @@ reveal_type(X) # revealed: Unknown
|
|||
|
||||
```py path=package/__init__.py
|
||||
from .foo import X
|
||||
|
||||
reveal_type(X) # revealed: Literal[42]
|
||||
```
|
||||
|
||||
|
@ -71,6 +77,7 @@ X = 42
|
|||
|
||||
```py path=package/__init__.py
|
||||
from .foo import X # error: [unresolved-import]
|
||||
|
||||
reveal_type(X) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -85,6 +92,7 @@ X = 42
|
|||
|
||||
```py path=package/subpackage/subsubpackage/bar.py
|
||||
from ...foo import X
|
||||
|
||||
reveal_type(X) # revealed: Literal[42]
|
||||
```
|
||||
|
||||
|
@ -99,6 +107,7 @@ x
|
|||
|
||||
```py path=package/bar.py
|
||||
from .foo import x # error: [unresolved-import]
|
||||
|
||||
reveal_type(x) # revealed: Unknown
|
||||
```
|
||||
|
||||
|
@ -114,6 +123,7 @@ X = 42
|
|||
```py path=package/bar.py
|
||||
# TODO: support submodule imports
|
||||
from . import foo # error: [unresolved-import]
|
||||
|
||||
y = foo.X
|
||||
|
||||
# TODO: should be `Literal[42]`
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
```py
|
||||
from b import x
|
||||
|
||||
y = x
|
||||
reveal_type(y) # revealed: int
|
||||
```
|
||||
|
@ -16,6 +17,7 @@ x: int
|
|||
|
||||
```py
|
||||
from b import x
|
||||
|
||||
y = x
|
||||
reveal_type(y) # revealed: int
|
||||
```
|
||||
|
|
|
@ -9,9 +9,9 @@ reveal_type(()) # revealed: tuple[()]
|
|||
## Heterogeneous tuple
|
||||
|
||||
```py
|
||||
reveal_type((1, 'a')) # revealed: tuple[Literal[1], Literal["a"]]
|
||||
reveal_type((1, "a")) # revealed: tuple[Literal[1], Literal["a"]]
|
||||
|
||||
reveal_type((1, (2, 3))) # revealed: tuple[Literal[1], tuple[Literal[2], Literal[3]]]
|
||||
|
||||
reveal_type(((1, 'a'), 2)) # revealed: tuple[tuple[Literal[1], Literal["a"]], Literal[2]]
|
||||
reveal_type(((1, "a"), 2)) # revealed: tuple[tuple[Literal[1], Literal["a"]], Literal[2]]
|
||||
```
|
||||
|
|
|
@ -7,27 +7,27 @@ x = 0
|
|||
y = str()
|
||||
z = False
|
||||
|
||||
reveal_type(f'hello') # revealed: Literal["hello"]
|
||||
reveal_type(f'h {x}') # revealed: Literal["h 0"]
|
||||
reveal_type('one ' f'single ' f'literal') # revealed: Literal["one single literal"]
|
||||
reveal_type('first ' f'second({x})' f' third') # revealed: Literal["first second(0) third"]
|
||||
reveal_type(f'-{y}-') # revealed: str
|
||||
reveal_type(f'-{y}-' f'--' '--') # revealed: str
|
||||
reveal_type(f'{z} == {False} is {True}') # revealed: Literal["False == False is True"]
|
||||
reveal_type(f"hello") # revealed: Literal["hello"]
|
||||
reveal_type(f"h {x}") # revealed: Literal["h 0"]
|
||||
reveal_type("one " f"single " f"literal") # revealed: Literal["one single literal"]
|
||||
reveal_type("first " f"second({x})" f" third") # revealed: Literal["first second(0) third"]
|
||||
reveal_type(f"-{y}-") # revealed: str
|
||||
reveal_type(f"-{y}-" f"--" "--") # revealed: str
|
||||
reveal_type(f"{z} == {False} is {True}") # revealed: Literal["False == False is True"]
|
||||
```
|
||||
|
||||
## Conversion Flags
|
||||
|
||||
```py
|
||||
string = 'hello'
|
||||
string = "hello"
|
||||
|
||||
# TODO: should be `Literal["'hello'"]`
|
||||
reveal_type(f'{string!r}') # revealed: str
|
||||
reveal_type(f"{string!r}") # revealed: str
|
||||
```
|
||||
|
||||
## Format Specifiers
|
||||
|
||||
```py
|
||||
# TODO: should be `Literal["01"]`
|
||||
reveal_type(f'{1:02}') # revealed: str
|
||||
reveal_type(f"{1:02}") # revealed: str
|
||||
```
|
||||
|
|
|
@ -4,15 +4,18 @@
|
|||
|
||||
```py
|
||||
reveal_type("Hello") # revealed: Literal["Hello"]
|
||||
reveal_type('world') # revealed: Literal["world"]
|
||||
reveal_type("Guten " + 'Tag') # revealed: Literal["Guten Tag"]
|
||||
reveal_type('bon ' + "jour") # revealed: Literal["bon jour"]
|
||||
reveal_type("world") # revealed: Literal["world"]
|
||||
reveal_type("Guten " + "Tag") # revealed: Literal["Guten Tag"]
|
||||
reveal_type("bon " + "jour") # revealed: Literal["bon jour"]
|
||||
```
|
||||
|
||||
## Nested Quotes
|
||||
|
||||
```py
|
||||
reveal_type('I say "hello" to you') # revealed: Literal["I say \"hello\" to you"]
|
||||
reveal_type("You say \"hey\" back") # revealed: Literal["You say \"hey\" back"]
|
||||
|
||||
# revealed: Literal["You say \"hey\" back"]
|
||||
reveal_type("You say \"hey\" back") # fmt: skip
|
||||
|
||||
reveal_type('No "closure here') # revealed: Literal["No \"closure here"]
|
||||
```
|
||||
|
|
|
@ -7,10 +7,12 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
|
||||
for x in IntIterable():
|
||||
pass
|
||||
|
||||
|
@ -24,11 +26,13 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
x = 'foo'
|
||||
|
||||
x = "foo"
|
||||
|
||||
for x in IntIterable():
|
||||
pass
|
||||
|
@ -43,14 +47,16 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
|
||||
for x in IntIterable():
|
||||
pass
|
||||
else:
|
||||
x = 'foo'
|
||||
x = "foo"
|
||||
|
||||
reveal_type(x) # revealed: Literal["foo"]
|
||||
```
|
||||
|
@ -62,15 +68,17 @@ class IntIterator:
|
|||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class IntIterable:
|
||||
def __iter__(self) -> IntIterator:
|
||||
return IntIterator()
|
||||
|
||||
|
||||
for x in IntIterable():
|
||||
if x > 5:
|
||||
break
|
||||
else:
|
||||
x = 'foo'
|
||||
x = "foo"
|
||||
|
||||
reveal_type(x) # revealed: int | Literal["foo"]
|
||||
```
|
||||
|
@ -82,6 +90,7 @@ class OldStyleIterable:
|
|||
def __getitem__(self, key: int) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
for x in OldStyleIterable():
|
||||
pass
|
||||
|
||||
|
@ -91,7 +100,7 @@ reveal_type(x) # revealed: Unbound | int
|
|||
## With heterogeneous tuple
|
||||
|
||||
```py
|
||||
for x in (1, 'a', b'foo'):
|
||||
for x in (1, "a", b"foo"):
|
||||
pass
|
||||
|
||||
reveal_type(x) # revealed: Unbound | Literal[1] | Literal["a"] | Literal[b"foo"]
|
||||
|
@ -106,6 +115,7 @@ class NotIterable:
|
|||
else:
|
||||
__iter__ = None
|
||||
|
||||
|
||||
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
|
||||
pass
|
||||
|
||||
|
@ -129,6 +139,7 @@ class NotIterable:
|
|||
|
||||
__iter__ = None
|
||||
|
||||
|
||||
for x in NotIterable(): # error: "Object of type `NotIterable` is not iterable"
|
||||
pass
|
||||
```
|
||||
|
|
|
@ -3,15 +3,18 @@
|
|||
## Yield must be iterable
|
||||
|
||||
```py
|
||||
class NotIterable: pass
|
||||
class NotIterable: ...
|
||||
|
||||
|
||||
class Iterator:
|
||||
def __next__(self) -> int:
|
||||
return 42
|
||||
|
||||
|
||||
class Iterable:
|
||||
def __iter__(self) -> Iterator: ...
|
||||
|
||||
|
||||
def generator_function():
|
||||
yield from Iterable()
|
||||
yield from NotIterable() # error: "Object of type `NotIterable` is not iterable"
|
||||
|
|
|
@ -14,8 +14,8 @@ reveal_type(x) # revealed: None | Literal[1]
|
|||
## `is` for other types
|
||||
|
||||
```py
|
||||
class A:
|
||||
...
|
||||
class A: ...
|
||||
|
||||
|
||||
x = A()
|
||||
y = x if flag else None
|
||||
|
|
|
@ -9,9 +9,11 @@ with the conditionally-defined type:
|
|||
def returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
if returns_bool():
|
||||
copyright = 1
|
||||
|
||||
|
||||
def f():
|
||||
reveal_type(copyright) # revealed: Literal[copyright] | Literal[1]
|
||||
```
|
||||
|
@ -24,9 +26,11 @@ Same is true if the name is annotated:
|
|||
def returns_bool() -> bool:
|
||||
return True
|
||||
|
||||
|
||||
if returns_bool():
|
||||
copyright: int = 1
|
||||
|
||||
|
||||
def f():
|
||||
reveal_type(copyright) # revealed: Literal[copyright] | int
|
||||
```
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
## Implicit error
|
||||
|
||||
```py
|
||||
class C: pass
|
||||
class C: ...
|
||||
|
||||
|
||||
C = 1 # error: "Implicit shadowing of class `C`; annotate to make it explicit if this is intentional"
|
||||
```
|
||||
|
||||
|
@ -12,6 +14,8 @@ C = 1 # error: "Implicit shadowing of class `C`; annotate to make it explicit i
|
|||
No diagnostic is raised in the case of explicit shadowing:
|
||||
|
||||
```py
|
||||
class C: pass
|
||||
class C: ...
|
||||
|
||||
|
||||
C: int = 1
|
||||
```
|
||||
|
|
|
@ -12,13 +12,17 @@ def f(x: str):
|
|||
## Implicit error
|
||||
|
||||
```py path=a.py
|
||||
def f(): pass
|
||||
def f(): ...
|
||||
|
||||
|
||||
f = 1 # error: "Implicit shadowing of function `f`; annotate to make it explicit if this is intentional"
|
||||
```
|
||||
|
||||
## Explicit shadowing
|
||||
|
||||
```py path=a.py
|
||||
def f(): pass
|
||||
def f(): ...
|
||||
|
||||
|
||||
f: int = 1
|
||||
```
|
||||
|
|
|
@ -7,5 +7,5 @@ if flag:
|
|||
x: str
|
||||
else:
|
||||
x: int
|
||||
x: bytes = b'foo'
|
||||
x: bytes = b"foo"
|
||||
```
|
||||
|
|
|
@ -6,5 +6,7 @@ In type stubs, classes can reference themselves in their base class definitions.
|
|||
|
||||
```py path=a.pyi
|
||||
class C(C): ...
|
||||
|
||||
|
||||
reveal_type(C) # revealed: Literal[C]
|
||||
```
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
## Simple
|
||||
|
||||
```py
|
||||
reveal_type(b'red' b'knot') # revealed: Literal[b"redknot"]
|
||||
reveal_type(b'hello') # revealed: Literal[b"hello"]
|
||||
reveal_type(b'world' + b'!') # revealed: Literal[b"world!"]
|
||||
reveal_type(b'\xff\x00') # revealed: Literal[b"\xff\x00"]
|
||||
reveal_type(b"red" b"knot") # revealed: Literal[b"redknot"]
|
||||
reveal_type(b"hello") # revealed: Literal[b"hello"]
|
||||
reveal_type(b"world" + b"!") # revealed: Literal[b"world!"]
|
||||
reveal_type(b"\xff\x00") # revealed: Literal[b"\xff\x00"]
|
||||
```
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
## Class getitem unbound
|
||||
|
||||
```py
|
||||
class NotSubscriptable: pass
|
||||
class NotSubscriptable: ...
|
||||
|
||||
|
||||
a = NotSubscriptable[0] # error: "Cannot subscript object of type `Literal[NotSubscriptable]` with no `__class_getitem__` method"
|
||||
```
|
||||
|
||||
|
@ -14,6 +16,7 @@ class Identity:
|
|||
def __class_getitem__(cls, item: int) -> str:
|
||||
return item
|
||||
|
||||
|
||||
reveal_type(Identity[0]) # revealed: str
|
||||
```
|
||||
|
||||
|
@ -22,15 +25,20 @@ reveal_type(Identity[0]) # revealed: str
|
|||
```py
|
||||
flag = True
|
||||
|
||||
class Identity:
|
||||
|
||||
class UnionClassGetItem:
|
||||
if flag:
|
||||
|
||||
def __class_getitem__(cls, item: int) -> str:
|
||||
return item
|
||||
|
||||
else:
|
||||
|
||||
def __class_getitem__(cls, item: int) -> int:
|
||||
return item
|
||||
|
||||
reveal_type(Identity[0]) # revealed: str | int
|
||||
|
||||
reveal_type(UnionClassGetItem[0]) # revealed: str | int
|
||||
```
|
||||
|
||||
## Class getitem with class union
|
||||
|
@ -38,21 +46,21 @@ reveal_type(Identity[0]) # revealed: str | int
|
|||
```py
|
||||
flag = True
|
||||
|
||||
class Identity1:
|
||||
|
||||
class A:
|
||||
def __class_getitem__(cls, item: int) -> str:
|
||||
return item
|
||||
|
||||
class Identity2:
|
||||
|
||||
class B:
|
||||
def __class_getitem__(cls, item: int) -> int:
|
||||
return item
|
||||
|
||||
if flag:
|
||||
a = Identity1
|
||||
else:
|
||||
a = Identity2
|
||||
|
||||
reveal_type(a) # revealed: Literal[Identity1, Identity2]
|
||||
reveal_type(a[0]) # revealed: str | int
|
||||
x = A if flag else B
|
||||
|
||||
reveal_type(x) # revealed: Literal[A, B]
|
||||
reveal_type(x[0]) # revealed: str | int
|
||||
```
|
||||
|
||||
## Class getitem with unbound method union
|
||||
|
@ -61,14 +69,19 @@ reveal_type(a[0]) # revealed: str | int
|
|||
flag = True
|
||||
|
||||
if flag:
|
||||
class Identity:
|
||||
def __class_getitem__(self, x: int) -> str:
|
||||
pass
|
||||
else:
|
||||
class Identity: pass
|
||||
|
||||
a = Identity[42] # error: [call-non-callable] "Method `__class_getitem__` of type `Literal[__class_getitem__] | Unbound` is not callable on object of type `Literal[Identity, Identity]`"
|
||||
reveal_type(a) # revealed: str | Unknown
|
||||
class Spam:
|
||||
def __class_getitem__(self, x: int) -> str:
|
||||
return "foo"
|
||||
|
||||
else:
|
||||
|
||||
class Spam: ...
|
||||
|
||||
|
||||
# error: [call-non-callable] "Method `__class_getitem__` of type `Literal[__class_getitem__] | Unbound` is not callable on object of type `Literal[Spam, Spam]`"
|
||||
# revealed: str | Unknown
|
||||
reveal_type(Spam[42])
|
||||
```
|
||||
|
||||
## TODO: Class getitem non-class union
|
||||
|
@ -77,13 +90,16 @@ reveal_type(a) # revealed: str | Unknown
|
|||
flag = True
|
||||
|
||||
if flag:
|
||||
class Identity:
|
||||
def __class_getitem__(self, x: int) -> str:
|
||||
pass
|
||||
else:
|
||||
Identity = 1
|
||||
|
||||
a = Identity[42] # error: "Cannot subscript object of type `Literal[Identity] | Literal[1]` with no `__getitem__` method"
|
||||
class Eggs:
|
||||
def __class_getitem__(self, x: int) -> str:
|
||||
return "foo"
|
||||
|
||||
else:
|
||||
Eggs = 1
|
||||
|
||||
a = Eggs[42] # error: "Cannot subscript object of type `Literal[Eggs] | Literal[1]` with no `__getitem__` method"
|
||||
|
||||
# TODO: should _probably_ emit `str | Unknown`
|
||||
reveal_type(a) # revealed: Unknown
|
||||
```
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
## Getitem unbound
|
||||
|
||||
```py
|
||||
class NotSubscriptable: pass
|
||||
class NotSubscriptable: ...
|
||||
|
||||
|
||||
a = NotSubscriptable()[0] # error: "Cannot subscript object of type `NotSubscriptable` with no `__getitem__` method"
|
||||
```
|
||||
|
||||
|
@ -13,6 +15,7 @@ a = NotSubscriptable()[0] # error: "Cannot subscript object of type `NotSubscri
|
|||
class NotSubscriptable:
|
||||
__getitem__ = None
|
||||
|
||||
|
||||
a = NotSubscriptable()[0] # error: "Method `__getitem__` of type `None` is not callable on object of type `NotSubscriptable`"
|
||||
```
|
||||
|
||||
|
@ -23,6 +26,7 @@ class Identity:
|
|||
def __getitem__(self, index: int) -> int:
|
||||
return index
|
||||
|
||||
|
||||
reveal_type(Identity()[0]) # revealed: int
|
||||
```
|
||||
|
||||
|
@ -31,13 +35,18 @@ reveal_type(Identity()[0]) # revealed: int
|
|||
```py
|
||||
flag = True
|
||||
|
||||
|
||||
class Identity:
|
||||
if flag:
|
||||
|
||||
def __getitem__(self, index: int) -> int:
|
||||
return index
|
||||
|
||||
else:
|
||||
|
||||
def __getitem__(self, index: int) -> str:
|
||||
return str(index)
|
||||
|
||||
|
||||
reveal_type(Identity()[0]) # revealed: int | str
|
||||
```
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Simple
|
||||
|
||||
```py
|
||||
s = 'abcde'
|
||||
s = "abcde"
|
||||
|
||||
reveal_type(s[0]) # revealed: Literal["a"]
|
||||
reveal_type(s[1]) # revealed: Literal["b"]
|
||||
|
@ -23,7 +23,8 @@ reveal_type(b) # revealed: Unknown
|
|||
def add(x: int, y: int) -> int:
|
||||
return x + y
|
||||
|
||||
a = 'abcde'[add(0, 1)]
|
||||
|
||||
a = "abcde"[add(0, 1)]
|
||||
# TODO: Support overloads... Should be `str`
|
||||
reveal_type(a) # revealed: @Todo
|
||||
```
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Basic
|
||||
|
||||
```py
|
||||
t = (1, 'a', 'b')
|
||||
t = (1, "a", "b")
|
||||
|
||||
reveal_type(t[0]) # revealed: Literal[1]
|
||||
reveal_type(t[1]) # revealed: Literal["a"]
|
||||
|
|
|
@ -12,9 +12,11 @@ reveal_type(not not None) # revealed: Literal[False]
|
|||
```py
|
||||
from typing import reveal_type
|
||||
|
||||
|
||||
def f():
|
||||
return 1
|
||||
|
||||
|
||||
reveal_type(not f) # revealed: Literal[False]
|
||||
# TODO Unknown should not be part of the type of typing.reveal_type
|
||||
# reveal_type(not reveal_type) revealed: Literal[False]
|
||||
|
@ -23,7 +25,8 @@ reveal_type(not f) # revealed: Literal[False]
|
|||
## Module
|
||||
|
||||
```py
|
||||
import b; import warnings
|
||||
import b
|
||||
import warnings
|
||||
|
||||
|
||||
reveal_type(not b) # revealed: Literal[False]
|
||||
|
|
|
@ -191,7 +191,7 @@ reveal_type(d) # revealed: Literal[2]
|
|||
### Simple unpacking
|
||||
|
||||
```py
|
||||
a, b = 'ab'
|
||||
a, b = "ab"
|
||||
reveal_type(a) # revealed: LiteralString
|
||||
reveal_type(b) # revealed: LiteralString
|
||||
```
|
||||
|
@ -200,7 +200,7 @@ reveal_type(b) # revealed: LiteralString
|
|||
|
||||
```py
|
||||
# TODO: Add diagnostic (there aren't enough values to unpack)
|
||||
a, b, c = 'ab'
|
||||
a, b, c = "ab"
|
||||
reveal_type(a) # revealed: LiteralString
|
||||
reveal_type(b) # revealed: LiteralString
|
||||
reveal_type(c) # revealed: Unknown
|
||||
|
@ -210,7 +210,7 @@ reveal_type(c) # revealed: Unknown
|
|||
|
||||
```py
|
||||
# TODO: Add diagnostic (too many values to unpack)
|
||||
a, b = 'abc'
|
||||
a, b = "abc"
|
||||
reveal_type(a) # revealed: LiteralString
|
||||
reveal_type(b) # revealed: LiteralString
|
||||
```
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue