mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
respect annotation-only declarations in infer_place_load
This commit is contained in:
parent
893f5727e5
commit
3b4667ec32
2 changed files with 10 additions and 10 deletions
|
@ -31,17 +31,17 @@ def f():
|
|||
reveal_type(x) # revealed: Unknown | Literal[1]
|
||||
```
|
||||
|
||||
## Skips annotation-only assignment
|
||||
## Reads respect annotation-only declarations
|
||||
|
||||
```py
|
||||
def f():
|
||||
x = 1
|
||||
x: int = 1
|
||||
def g():
|
||||
# it's pretty weird to have an annotated assignment in a function where the
|
||||
# name is otherwise not defined; maybe should be an error?
|
||||
x: int
|
||||
# TODO: This example should actually be an unbound variable error. However to avoid false
|
||||
# positives, we'd need to analyze `nonlocal x` statements in other inner functions.
|
||||
x: str
|
||||
def h():
|
||||
reveal_type(x) # revealed: Unknown | Literal[1]
|
||||
reveal_type(x) # revealed: str
|
||||
```
|
||||
|
||||
## The `nonlocal` keyword
|
||||
|
@ -229,7 +229,7 @@ def f():
|
|||
nonlocal x # error: [invalid-syntax] "no binding for nonlocal `x` found"
|
||||
```
|
||||
|
||||
## `nonlocal` bindings respect declared types from the defining scope, even without a binding
|
||||
## Assigning to a `nonlocal` respects the declared type from its defining scope, even without a binding in that scope
|
||||
|
||||
```py
|
||||
def f():
|
||||
|
|
|
@ -1618,8 +1618,8 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
// here and just bail out of this loop.
|
||||
break;
|
||||
}
|
||||
// We found the closest definition. Note that (unlike in `infer_place_load`) this
|
||||
// does *not* need to be a binding. It could be just `x: int`.
|
||||
// We found the closest definition. Note that (as in `infer_place_load`) this does
|
||||
// *not* need to be a binding. It could be just a declaration, e.g. `x: int`.
|
||||
nonlocal_use_def_map = self.index.use_def_map(enclosing_scope_file_id);
|
||||
declarations = nonlocal_use_def_map.end_of_scope_declarations(enclosing_place_id);
|
||||
is_local = false;
|
||||
|
@ -6079,7 +6079,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
let Some(enclosing_place) = enclosing_place_table.place_by_expr(expr) else {
|
||||
continue;
|
||||
};
|
||||
if enclosing_place.is_bound() {
|
||||
if enclosing_place.is_bound() || enclosing_place.is_declared() {
|
||||
// We can return early here, because the nearest function-like scope that
|
||||
// defines a name must be the only source for the nonlocal reference (at
|
||||
// runtime, it is the scope that creates the cell for our closure.) If the name
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue