Skip to content

Commit

Permalink
Improve mdtests style (#14884)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Waygood <[email protected]>
  • Loading branch information
InSyncWithFoo and AlexWaygood authored Dec 10, 2024
1 parent 7a0e9b3 commit 15fe540
Show file tree
Hide file tree
Showing 55 changed files with 1,482 additions and 2,062 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ If you define your own class named `Any`, using that in a type expression refers
isn't a spelling of the Any type.

```py
class Any:
pass
class Any: ...

x: Any

Expand All @@ -59,17 +58,14 @@ assignable to `int`.
```py
from typing import Any

class Subclass(Any):
pass
class Subclass(Any): ...

reveal_type(Subclass.__mro__) # revealed: tuple[Literal[Subclass], Any, Literal[object]]

x: Subclass = 1 # error: [invalid-assignment]
# TODO: no diagnostic
y: int = Subclass() # error: [invalid-assignment]

def f() -> Subclass:
pass

reveal_type(f()) # revealed: Subclass
def _(s: Subclass):
reveal_type(s) # revealed: Subclass
```
Original file line number Diff line number Diff line change
Expand Up @@ -89,28 +89,26 @@ vice versa.
```py
from typing_extensions import Literal, LiteralString

def coinflip() -> bool:
return True
def _(flag: bool):
foo_1: Literal["foo"] = "foo"
bar_1: LiteralString = foo_1 # fine

foo_1: Literal["foo"] = "foo"
bar_1: LiteralString = foo_1 # fine
foo_2 = "foo" if flag else "bar"
reveal_type(foo_2) # revealed: Literal["foo", "bar"]
bar_2: LiteralString = foo_2 # fine

foo_2 = "foo" if coinflip() else "bar"
reveal_type(foo_2) # revealed: Literal["foo", "bar"]
bar_2: LiteralString = foo_2 # fine
foo_3: LiteralString = "foo" * 1_000_000_000
bar_3: str = foo_2 # fine

foo_3: LiteralString = "foo" * 1_000_000_000
bar_3: str = foo_2 # fine
baz_1: str = str()
qux_1: LiteralString = baz_1 # error: [invalid-assignment]

baz_1: str = str()
qux_1: LiteralString = baz_1 # error: [invalid-assignment]
baz_2: LiteralString = "baz" * 1_000_000_000
qux_2: Literal["qux"] = baz_2 # error: [invalid-assignment]

baz_2: LiteralString = "baz" * 1_000_000_000
qux_2: Literal["qux"] = baz_2 # error: [invalid-assignment]

baz_3 = "foo" if coinflip() else 1
reveal_type(baz_3) # revealed: Literal["foo"] | Literal[1]
qux_3: LiteralString = baz_3 # error: [invalid-assignment]
baz_3 = "foo" if flag else 1
reveal_type(baz_3) # revealed: Literal["foo"] | Literal[1]
qux_3: LiteralString = baz_3 # error: [invalid-assignment]
```

### Narrowing
Expand Down
146 changes: 51 additions & 95 deletions crates/red_knot_python_semantic/resources/mdtest/annotations/string.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,152 +3,109 @@
## Simple

```py
def f() -> "int":
return 1

reveal_type(f()) # revealed: int
def f(v: "int"):
reveal_type(v) # revealed: int
```

## Nested

```py
def f() -> "'int'":
return 1

reveal_type(f()) # revealed: int
def f(v: "'int'"):
reveal_type(v) # revealed: int
```

## Type expression

```py
def f1() -> "int | str":
return 1

def f2() -> "tuple[int, str]":
return 1

reveal_type(f1()) # revealed: int | str
reveal_type(f2()) # revealed: tuple[int, str]
def f1(v: "int | str", w: "tuple[int, str]"):
reveal_type(v) # revealed: int | str
reveal_type(w) # revealed: tuple[int, str]
```

## Partial

```py
def f() -> tuple[int, "str"]:
return 1

reveal_type(f()) # revealed: tuple[int, str]
def f(v: tuple[int, "str"]):
reveal_type(v) # revealed: tuple[int, str]
```

## Deferred

```py
def f() -> "Foo":
return Foo()

class Foo:
pass
def f(v: "Foo"):
reveal_type(v) # revealed: Foo

reveal_type(f()) # revealed: Foo
class Foo: ...
```

## Deferred (undefined)

```py
# error: [unresolved-reference]
def f() -> "Foo":
pass

reveal_type(f()) # revealed: Unknown
def f(v: "Foo"):
reveal_type(v) # revealed: Unknown
```

## Partial deferred

```py
def f() -> int | "Foo":
return 1

class Foo:
pass
def f(v: int | "Foo"):
reveal_type(v) # revealed: int | Foo

reveal_type(f()) # revealed: int | Foo
class Foo: ...
```

## `typing.Literal`

```py
from typing import Literal

def f1() -> Literal["Foo", "Bar"]:
return "Foo"

def f2() -> 'Literal["Foo", "Bar"]':
return "Foo"
def f1(v: Literal["Foo", "Bar"], w: 'Literal["Foo", "Bar"]'):
reveal_type(v) # revealed: Literal["Foo", "Bar"]
reveal_type(w) # revealed: Literal["Foo", "Bar"]

class Foo:
pass

reveal_type(f1()) # revealed: Literal["Foo", "Bar"]
reveal_type(f2()) # revealed: Literal["Foo", "Bar"]
class Foo: ...
```

## Various string kinds

```py
# error: [annotation-raw-string] "Type expressions cannot use raw string literal"
def f1() -> r"int":
return 1

# error: [annotation-f-string] "Type expressions cannot use f-strings"
def f2() -> f"int":
return 1

# error: [annotation-byte-string] "Type expressions cannot use bytes literal"
def f3() -> b"int":
return 1

def f4() -> "int":
return 1

# error: [annotation-implicit-concat] "Type expressions cannot span multiple string literals"
def f5() -> "in" "t":
return 1

# error: [annotation-escape-character] "Type expressions cannot contain escape characters"
def f6() -> "\N{LATIN SMALL LETTER I}nt":
return 1

# error: [annotation-escape-character] "Type expressions cannot contain escape characters"
def f7() -> "\x69nt":
return 1

def f8() -> """int""":
return 1

# error: [annotation-byte-string] "Type expressions cannot use bytes literal"
def f9() -> "b'int'":
return 1

reveal_type(f1()) # revealed: Unknown
reveal_type(f2()) # revealed: Unknown
reveal_type(f3()) # revealed: Unknown
reveal_type(f4()) # revealed: int
reveal_type(f5()) # revealed: Unknown
reveal_type(f6()) # revealed: Unknown
reveal_type(f7()) # revealed: Unknown
reveal_type(f8()) # revealed: int
reveal_type(f9()) # revealed: Unknown
def f1(
# error: [annotation-raw-string] "Type expressions cannot use raw string literal"
a: r"int",
# error: [annotation-f-string] "Type expressions cannot use f-strings"
b: f"int",
# error: [annotation-byte-string] "Type expressions cannot use bytes literal"
c: b"int",
d: "int",
# error: [annotation-implicit-concat] "Type expressions cannot span multiple string literals"
e: "in" "t",
# error: [annotation-escape-character] "Type expressions cannot contain escape characters"
f: "\N{LATIN SMALL LETTER I}nt",
# error: [annotation-escape-character] "Type expressions cannot contain escape characters"
g: "\x69nt",
h: """int""",
# error: [annotation-byte-string] "Type expressions cannot use bytes literal"
i: "b'int'",
):
reveal_type(a) # revealed: Unknown
reveal_type(b) # revealed: Unknown
reveal_type(c) # revealed: Unknown
reveal_type(d) # revealed: int
reveal_type(e) # revealed: Unknown
reveal_type(f) # revealed: Unknown
reveal_type(g) # revealed: Unknown
reveal_type(h) # revealed: int
reveal_type(i) # revealed: Unknown
```

## Various string kinds in `typing.Literal`

```py
from typing import Literal

def f() -> Literal["a", r"b", b"c", "d" "e", "\N{LATIN SMALL LETTER F}", "\x67", """h"""]:
return "normal"

reveal_type(f()) # revealed: Literal["a", "b", "de", "f", "g", "h"] | Literal[b"c"]
def f(v: Literal["a", r"b", b"c", "d" "e", "\N{LATIN SMALL LETTER F}", "\x67", """h"""]):
reveal_type(v) # revealed: Literal["a", "b", "de", "f", "g", "h"] | Literal[b"c"]
```

## Class variables
Expand All @@ -175,8 +132,7 @@ c: "Foo"
# error: [invalid-assignment] "Object of type `Literal[1]` is not assignable to `Foo`"
d: "Foo" = 1

class Foo:
pass
class Foo: ...

c = Foo()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,10 @@ c: tuple[str | int, str] = ([], "foo")
## PEP-604 annotations are supported

```py
def foo() -> str | int | None:
return None

reveal_type(foo()) # revealed: str | int | None

def bar() -> str | str | None:
return None

reveal_type(bar()) # revealed: str | None

def baz() -> str | str:
return "Hello, world!"

reveal_type(baz()) # revealed: str
def foo(v: str | int | None, w: str | str | None, x: str | str):
reveal_type(v) # revealed: str | int | None
reveal_type(w) # revealed: str | None
reveal_type(x) # revealed: str
```

## Attribute expressions in type annotations are understood
Expand All @@ -118,8 +108,7 @@ from __future__ import annotations

x: Foo

class Foo:
pass
class Foo: ...

x = Foo()
reveal_type(x) # revealed: Foo
Expand All @@ -130,8 +119,7 @@ reveal_type(x) # revealed: Foo
```pyi path=main.pyi
x: Foo

class Foo:
pass
class Foo: ...

x = Foo()
reveal_type(x) # revealed: Foo
Expand Down
Loading

0 comments on commit 15fe540

Please sign in to comment.