mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-18 11:41:21 +00:00
[ty] Ensure annotation/type expressions in stub files are always deferred (#21401)
Some checks are pending
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (${{ github.repository == 'astral-sh/ruff' && 'depot-windows-2022-16' || 'windows-latest' }}) (push) Blocked by required conditions
CI / cargo test (macos-latest) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / benchmarks instrumented (ty) (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / ty completion evaluation (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks instrumented (ruff) (push) Blocked by required conditions
CI / benchmarks walltime (medium|multithreaded) (push) Blocked by required conditions
CI / benchmarks walltime (small|large) (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
Some checks are pending
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (${{ github.repository == 'astral-sh/ruff' && 'depot-windows-2022-16' || 'windows-latest' }}) (push) Blocked by required conditions
CI / cargo test (macos-latest) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / benchmarks instrumented (ty) (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / ty completion evaluation (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks instrumented (ruff) (push) Blocked by required conditions
CI / benchmarks walltime (medium|multithreaded) (push) Blocked by required conditions
CI / benchmarks walltime (small|large) (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
This commit is contained in:
parent
99694b6e4a
commit
90b32f3b3b
8 changed files with 115 additions and 5 deletions
|
|
@ -396,3 +396,34 @@ B = NewType("B", list[Any])
|
|||
T = TypeVar("T")
|
||||
C = NewType("C", list[T]) # TODO: should be "error: [invalid-newtype]"
|
||||
```
|
||||
|
||||
## Forward references in stub files
|
||||
|
||||
Stubs natively support forward references, so patterns that would raise `NameError` at runtime are
|
||||
allowed in stub files:
|
||||
|
||||
`stub.pyi`:
|
||||
|
||||
```pyi
|
||||
from typing import NewType
|
||||
|
||||
N = NewType("N", A)
|
||||
|
||||
class A: ...
|
||||
```
|
||||
|
||||
`main.py`:
|
||||
|
||||
```py
|
||||
from stub import N, A
|
||||
|
||||
n = N(A()) # fine
|
||||
|
||||
def f(x: A): ...
|
||||
|
||||
f(n) # fine
|
||||
|
||||
class Invalid: ...
|
||||
|
||||
bad = N(Invalid()) # error: [invalid-argument-type]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -266,7 +266,48 @@ from typing import TypeVar
|
|||
|
||||
# error: [invalid-legacy-type-variable]
|
||||
T = TypeVar("T", invalid_keyword=True)
|
||||
```
|
||||
|
||||
### Forward references in stubs
|
||||
|
||||
Stubs natively support forward references, so patterns that would raise `NameError` at runtime are
|
||||
allowed in stub files:
|
||||
|
||||
`stub.pyi`:
|
||||
|
||||
```pyi
|
||||
from typing import TypeVar
|
||||
|
||||
T = TypeVar("T", bound=A, default=B)
|
||||
U = TypeVar("U", C, D)
|
||||
|
||||
class A: ...
|
||||
class B(A): ...
|
||||
class C: ...
|
||||
class D: ...
|
||||
|
||||
def f(x: T) -> T: ...
|
||||
def g(x: U) -> U: ...
|
||||
```
|
||||
|
||||
`main.py`:
|
||||
|
||||
```py
|
||||
from stub import f, g, A, B, C, D
|
||||
|
||||
reveal_type(f(A())) # revealed: A
|
||||
reveal_type(f(B())) # revealed: B
|
||||
reveal_type(g(C())) # revealed: C
|
||||
reveal_type(g(D())) # revealed: D
|
||||
|
||||
# TODO: one diagnostic would probably be sufficient here...?
|
||||
#
|
||||
# error: [invalid-argument-type] "Argument type `C` does not satisfy upper bound `A` of type variable `T`"
|
||||
# error: [invalid-argument-type] "Argument to function `f` is incorrect: Expected `B`, found `C`"
|
||||
reveal_type(f(C())) # revealed: B
|
||||
|
||||
# error: [invalid-argument-type]
|
||||
reveal_type(g(A())) # revealed: Unknown
|
||||
```
|
||||
|
||||
### Constructor signature versioning
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ def _(x: int | str | bytes | memoryview | range):
|
|||
if isinstance(x, int | str):
|
||||
reveal_type(x) # revealed: int | str
|
||||
elif isinstance(x, bytes | memoryview):
|
||||
reveal_type(x) # revealed: bytes | memoryview[Unknown]
|
||||
reveal_type(x) # revealed: bytes | memoryview[int]
|
||||
else:
|
||||
reveal_type(x) # revealed: range
|
||||
```
|
||||
|
|
@ -242,11 +242,11 @@ def _(flag: bool):
|
|||
def _(flag: bool):
|
||||
x = 1 if flag else "a"
|
||||
|
||||
# error: [invalid-argument-type] "Argument to function `isinstance` is incorrect: Expected `type | UnionType | tuple[Unknown, ...]`, found `Literal["a"]"
|
||||
# error: [invalid-argument-type] "Argument to function `isinstance` is incorrect: Expected `type | UnionType | tuple[Divergent, ...]`, found `Literal["a"]"
|
||||
if isinstance(x, "a"):
|
||||
reveal_type(x) # revealed: Literal[1, "a"]
|
||||
|
||||
# error: [invalid-argument-type] "Argument to function `isinstance` is incorrect: Expected `type | UnionType | tuple[Unknown, ...]`, found `Literal["int"]"
|
||||
# error: [invalid-argument-type] "Argument to function `isinstance` is incorrect: Expected `type | UnionType | tuple[Divergent, ...]`, found `Literal["int"]"
|
||||
if isinstance(x, "int"):
|
||||
reveal_type(x) # revealed: Literal[1, "a"]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ def flag() -> bool:
|
|||
|
||||
t = int if flag() else str
|
||||
|
||||
# error: [invalid-argument-type] "Argument to function `issubclass` is incorrect: Expected `type | UnionType | tuple[Unknown, ...]`, found `Literal["str"]"
|
||||
# error: [invalid-argument-type] "Argument to function `issubclass` is incorrect: Expected `type | UnionType | tuple[Divergent, ...]`, found `Literal["str"]"
|
||||
if issubclass(t, "str"):
|
||||
reveal_type(t) # revealed: <class 'int'> | <class 'str'>
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,20 @@ Other values are invalid.
|
|||
P4 = ParamSpec("P4", default=int)
|
||||
```
|
||||
|
||||
### Forward references in stub files
|
||||
|
||||
Stubs natively support forward references, so patterns that would raise `NameError` at runtime are
|
||||
allowed in stub files:
|
||||
|
||||
```pyi
|
||||
from typing_extensions import ParamSpec
|
||||
|
||||
P = ParamSpec("P", default=[A, B])
|
||||
|
||||
class A: ...
|
||||
class B: ...
|
||||
```
|
||||
|
||||
### PEP 695
|
||||
|
||||
```toml
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue