mirror of
https://github.com/astral-sh/ruff.git
synced 2026-05-06 08:56:57 -04:00
Restrict PYI034 for in-place operations to enclosing class (#24511)
## Summary
In `.py` and `.pyi` files, we now only flag cases in which the return
type is the enclosing class, like:
```python
class A:
def __iadd__(self) -> A:
return self
```
As opposed to:
```python
class A:
def __iadd__(self) -> int:
return self
```
Closes https://github.com/astral-sh/ruff/issues/24462.
This commit is contained in:
@@ -392,3 +392,8 @@ class UsesStringizedForwardReferences:
|
||||
def __enter__(self) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
async def __aenter__(self) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
def __iadd__(self, other) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
|
||||
|
||||
class InPlaceOperationReturningOtherTypeAtRuntime:
|
||||
def __iadd__(self, other: int) -> int:
|
||||
return 1
|
||||
|
||||
@@ -277,3 +277,7 @@ class MetaclassInWhichSelfCannotBeUsed7(django.db.models.base.ModelBase):
|
||||
class MetaclassInWhichSelfCannotBeUsed8(django.db.models.base.ModelBase):
|
||||
def __new__(cls, name: builtins.str, bases: tuple, attributes: dict, /, **kw) -> MetaclassInWhichSelfCannotBeUsed8:
|
||||
...
|
||||
|
||||
|
||||
class StubInPlaceOperationReturningOtherType:
|
||||
def __iadd__(self, other: int) -> int: ...
|
||||
|
||||
@@ -42,7 +42,8 @@ use ruff_text_size::Ranged;
|
||||
/// Specifically, this check enforces that the return type of the following
|
||||
/// methods is `Self`:
|
||||
///
|
||||
/// 1. In-place binary-operation dunder methods, like `__iadd__`, `__imul__`, etc.
|
||||
/// 1. In-place binary-operation dunder methods, like `__iadd__`, `__imul__`, etc.,
|
||||
/// if those methods return the class name.
|
||||
/// 1. `__new__`, `__enter__`, and `__aenter__`, if those methods return the
|
||||
/// class name.
|
||||
/// 1. `__iter__` methods that return `Iterator`, despite the class inheriting
|
||||
@@ -192,7 +193,7 @@ pub(crate) fn non_self_return_type(
|
||||
|
||||
// In-place methods that are expected to return `Self`.
|
||||
if is_inplace_bin_op(name) {
|
||||
if !is_self(returns, checker) {
|
||||
if is_name_or_stringized_name(returns, &class_def.name, checker) {
|
||||
add_diagnostic(checker, stmt, returns, class_def, name);
|
||||
}
|
||||
return;
|
||||
@@ -330,13 +331,6 @@ fn is_name_or_stringized_name(expr: &ast::Expr, name: &str, checker: &Checker) -
|
||||
checker.match_maybe_stringized_annotation(expr, |expr| is_name(expr, name))
|
||||
}
|
||||
|
||||
/// Return `true` if the given expression resolves to `typing.Self`.
|
||||
fn is_self(expr: &ast::Expr, checker: &Checker) -> bool {
|
||||
checker.match_maybe_stringized_annotation(expr, |expr| {
|
||||
checker.semantic().match_typing_expr(expr, "Self")
|
||||
})
|
||||
}
|
||||
|
||||
/// Return `true` if the given class extends `collections.abc.Iterator`.
|
||||
fn subclasses_iterator(class_def: &ast::StmtClassDef, semantic: &SemanticModel) -> bool {
|
||||
analyze::class::any_qualified_base_class(class_def, semantic, |qualified_name| {
|
||||
|
||||
+6
@@ -511,6 +511,7 @@ help: Use `Self` as return type
|
||||
392 + def __enter__(self) -> typing.Self: ... # PYI034
|
||||
393 | async def __aenter__(self) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
394 | def __iadd__(self, other) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
395 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PYI034 [*] `__aenter__` methods in classes like `UsesStringizedForwardReferences` usually return `self` at runtime
|
||||
@@ -529,6 +530,8 @@ help: Use `Self` as return type
|
||||
- async def __aenter__(self) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
393 + async def __aenter__(self) -> typing.Self: ... # PYI034
|
||||
394 | def __iadd__(self, other) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
395 |
|
||||
396 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PYI034 [*] `__iadd__` methods in classes like `UsesStringizedForwardReferences` usually return `self` at runtime
|
||||
@@ -545,4 +548,7 @@ help: Use `Self` as return type
|
||||
393 | async def __aenter__(self) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
- def __iadd__(self, other) -> "UsesStringizedForwardReferences": ... # PYI034
|
||||
394 + def __iadd__(self, other) -> typing.Self: ... # PYI034
|
||||
395 |
|
||||
396 |
|
||||
397 | class InPlaceOperationReturningOtherTypeAtRuntime:
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
Reference in New Issue
Block a user