mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
[ty] Don't add incorrect subdiagnostic for unresolved reference (#18487)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Carl Meyer <carl@astral.sh>
This commit is contained in:
parent
57bd7d055d
commit
a3c79d8170
5 changed files with 422 additions and 73 deletions
|
@ -946,9 +946,9 @@ def _(flag1: bool, flag2: bool):
|
|||
|
||||
<!-- snapshot-diagnostics -->
|
||||
|
||||
If a non-declared variable is used and an attribute with the same name is defined and accessible,
|
||||
then we emit a subdiagnostic suggesting the use of `self.`.
|
||||
(`An attribute with the same name as 'x' is defined, consider using 'self.x'` in these cases)
|
||||
If an undefined variable is used in a method, and an attribute with the same name is defined and
|
||||
accessible, then we emit a subdiagnostic suggesting the use of `self.`. (These don't appear inline
|
||||
here; see the diagnostic snapshots.)
|
||||
|
||||
```py
|
||||
class Foo:
|
||||
|
@ -978,6 +978,107 @@ class Foo:
|
|||
y = x
|
||||
```
|
||||
|
||||
In a staticmethod, we don't suggest that it might be an attribute.
|
||||
|
||||
```py
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
self.x = 42
|
||||
|
||||
@staticmethod
|
||||
def static_method():
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
y = x
|
||||
```
|
||||
|
||||
In a classmethod, if the name matches a class attribute, we suggest `cls.`.
|
||||
|
||||
```py
|
||||
from typing import ClassVar
|
||||
|
||||
class Foo:
|
||||
x: ClassVar[int] = 42
|
||||
|
||||
@classmethod
|
||||
def class_method(cls):
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
y = x
|
||||
```
|
||||
|
||||
In a classmethod, if the name matches an instance-only attribute, we don't suggest anything.
|
||||
|
||||
```py
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
self.x = 42
|
||||
|
||||
@classmethod
|
||||
def class_method(cls):
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
y = x
|
||||
```
|
||||
|
||||
We also don't suggest anything if the method is (invalidly) decorated with both `@classmethod` and
|
||||
`@staticmethod`:
|
||||
|
||||
```py
|
||||
class Foo:
|
||||
x: ClassVar[int]
|
||||
|
||||
@classmethod
|
||||
@staticmethod
|
||||
def class_method(cls):
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
y = x
|
||||
```
|
||||
|
||||
In an instance method that uses some other parameter name in place of `self`, we use that parameter
|
||||
name in the sub-diagnostic.
|
||||
|
||||
```py
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
self.x = 42
|
||||
|
||||
def method(other):
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
y = x
|
||||
```
|
||||
|
||||
In a classmethod that uses some other parameter name in place of `cls`, we use that parameter name
|
||||
in the sub-diagnostic.
|
||||
|
||||
```py
|
||||
from typing import ClassVar
|
||||
|
||||
class Foo:
|
||||
x: ClassVar[int] = 42
|
||||
|
||||
@classmethod
|
||||
def class_method(c_other):
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
y = x
|
||||
```
|
||||
|
||||
We don't suggest anything if an instance method or a classmethod only has variadic arguments, or if
|
||||
the first parameter is keyword-only:
|
||||
|
||||
```py
|
||||
from typing import ClassVar
|
||||
|
||||
class Foo:
|
||||
x: ClassVar[int] = 42
|
||||
|
||||
def instance_method(*args, **kwargs):
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
print(x)
|
||||
|
||||
@classmethod
|
||||
def class_method(*, cls):
|
||||
# error: [unresolved-reference] "Name `x` used when not defined"
|
||||
y = x
|
||||
```
|
||||
|
||||
## Unions of attributes
|
||||
|
||||
If the (meta)class is a union type or if the attribute on the (meta) class has a union type, we
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue