mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:10 +00:00
Rename Red Knot (#17820)
This commit is contained in:
parent
e6a798b962
commit
b51c4f82ea
1564 changed files with 1598 additions and 1578 deletions
47
crates/ty_python_semantic/resources/mdtest/stubs/class.md
Normal file
47
crates/ty_python_semantic/resources/mdtest/stubs/class.md
Normal file
|
@ -0,0 +1,47 @@
|
|||
# Class definitions in stubs
|
||||
|
||||
## Cyclical class definition
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.12"
|
||||
```
|
||||
|
||||
In type stubs, classes can reference themselves in their base class definitions. For example, in
|
||||
`typeshed`, we have `class str(Sequence[str]): ...`.
|
||||
|
||||
```pyi
|
||||
class Foo[T]: ...
|
||||
|
||||
class Bar(Foo[Bar]): ...
|
||||
|
||||
reveal_type(Bar) # revealed: Literal[Bar]
|
||||
reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Literal[Foo[Bar]], Literal[object]]
|
||||
```
|
||||
|
||||
## Access to attributes declared in stubs
|
||||
|
||||
Unlike regular Python modules, stub files often omit the right-hand side in declarations, including
|
||||
in class scope. However, from the perspective of the type checker, we have to treat them as bindings
|
||||
too. That is, `symbol: type` is the same as `symbol: type = ...`.
|
||||
|
||||
One implication of this is that we'll always treat symbols in class scope as safe to be accessed
|
||||
from the class object itself. We'll never infer a "pure instance attribute" from a stub.
|
||||
|
||||
`b.pyi`:
|
||||
|
||||
```pyi
|
||||
from typing import ClassVar
|
||||
|
||||
class C:
|
||||
class_or_instance_var: int
|
||||
```
|
||||
|
||||
```py
|
||||
from typing import ClassVar, Literal
|
||||
|
||||
from b import C
|
||||
|
||||
# No error here, since we treat `class_or_instance_var` as bound on the class.
|
||||
reveal_type(C.class_or_instance_var) # revealed: int
|
||||
```
|
78
crates/ty_python_semantic/resources/mdtest/stubs/ellipsis.md
Normal file
78
crates/ty_python_semantic/resources/mdtest/stubs/ellipsis.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
# Ellipsis
|
||||
|
||||
## Function and methods
|
||||
|
||||
The ellipsis literal `...` can be used as a placeholder default value for a function parameter, in a
|
||||
stub file only, regardless of the type of the parameter.
|
||||
|
||||
```pyi
|
||||
def f(x: int = ...) -> None:
|
||||
reveal_type(x) # revealed: int
|
||||
|
||||
def f2(x: str = ...) -> None:
|
||||
reveal_type(x) # revealed: str
|
||||
```
|
||||
|
||||
## Class and module symbols
|
||||
|
||||
The ellipsis literal can be assigned to a class or module symbol, regardless of its declared type,
|
||||
in a stub file only.
|
||||
|
||||
```pyi
|
||||
y: bytes = ...
|
||||
reveal_type(y) # revealed: bytes
|
||||
x = ...
|
||||
reveal_type(x) # revealed: Unknown
|
||||
|
||||
class Foo:
|
||||
y: int = ...
|
||||
|
||||
reveal_type(Foo.y) # revealed: int
|
||||
```
|
||||
|
||||
## Unpacking ellipsis literal in assignment
|
||||
|
||||
No diagnostic is emitted if an ellipsis literal is "unpacked" in a stub file as part of an
|
||||
assignment statement:
|
||||
|
||||
```pyi
|
||||
x, y = ...
|
||||
reveal_type(x) # revealed: Unknown
|
||||
reveal_type(y) # revealed: Unknown
|
||||
```
|
||||
|
||||
## Unpacking ellipsis literal in for loops
|
||||
|
||||
Iterating over an ellipsis literal as part of a `for` loop in a stub is invalid, however, and
|
||||
results in a diagnostic:
|
||||
|
||||
```pyi
|
||||
# error: [not-iterable] "Object of type `ellipsis` is not iterable"
|
||||
for a, b in ...:
|
||||
reveal_type(a) # revealed: Unknown
|
||||
reveal_type(b) # revealed: Unknown
|
||||
```
|
||||
|
||||
## Ellipsis usage in non stub file
|
||||
|
||||
In a non-stub file, there's no special treatment of ellipsis literals. An ellipsis literal can only
|
||||
be assigned if `EllipsisType` is actually assignable to the annotated type.
|
||||
|
||||
```py
|
||||
# error: 7 [invalid-parameter-default] "Default value of type `ellipsis` is not assignable to annotated parameter type `int`"
|
||||
def f(x: int = ...) -> None: ...
|
||||
|
||||
# error: 1 [invalid-assignment] "Object of type `ellipsis` is not assignable to `int`"
|
||||
a: int = ...
|
||||
b = ...
|
||||
reveal_type(b) # revealed: ellipsis
|
||||
```
|
||||
|
||||
## Use of `Ellipsis` symbol
|
||||
|
||||
There is no special treatment of the builtin name `Ellipsis` in stubs, only of `...` literals.
|
||||
|
||||
```pyi
|
||||
# error: 7 [invalid-parameter-default] "Default value of type `ellipsis` is not assignable to annotated parameter type `int`"
|
||||
def f(x: int = Ellipsis) -> None: ...
|
||||
```
|
17
crates/ty_python_semantic/resources/mdtest/stubs/locals.md
Normal file
17
crates/ty_python_semantic/resources/mdtest/stubs/locals.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Declarations in stubs
|
||||
|
||||
Unlike regular Python modules, stub files often declare module-global variables without initializing
|
||||
them. If these symbols are then used in the same stub, applying regular logic would lead to an
|
||||
undefined variable access error.
|
||||
|
||||
However, from the perspective of the type checker, we should treat something like `symbol: type` the
|
||||
same as `symbol: type = ...`. In other words, assume these are bindings too.
|
||||
|
||||
```pyi
|
||||
from typing import Literal
|
||||
|
||||
CONSTANT: Literal[42]
|
||||
|
||||
# No error here, even though the variable is not initialized.
|
||||
uses_constant: int = CONSTANT
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue