mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
[red-knot] treat annotated assignments without RHS in stubs as bindings (#16409)
This commit is contained in:
parent
5ca6cc2cc8
commit
fdf0915283
7 changed files with 80 additions and 17 deletions
|
@ -15,3 +15,30 @@ class Bar(Foo[Bar]): ...
|
|||
reveal_type(Bar) # revealed: Literal[Bar]
|
||||
reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Unknown, Literal[object]]
|
||||
```
|
||||
|
||||
## Access to attributes declarated 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
|
||||
```
|
||||
|
|
|
@ -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