Compare commits

...

2 Commits

Author SHA1 Message Date
Charlie Marsh
947e1a4e4d Minor tweaks 2024-11-08 21:06:01 -05:00
InSyncWithFoo
33945a5517 [flake8-pyi] Add "replace with Self" fix (PYI034) 2024-11-08 23:51:45 +00:00
3 changed files with 312 additions and 80 deletions

View File

@@ -1,14 +1,15 @@
use ruff_python_ast::{self as ast, Decorator, Expr, Parameters, Stmt};
use ruff_diagnostics::{Diagnostic, Violation};
use crate::checkers::ast::Checker;
use crate::importer::ImportRequest;
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::map_subscript;
use ruff_python_ast::identifier::Identifier;
use ruff_python_semantic::analyze;
use ruff_python_semantic::analyze::visibility::{is_abstract, is_final, is_overload};
use ruff_python_semantic::{ScopeKind, SemanticModel};
use crate::checkers::ast::Checker;
use ruff_text_size::{Ranged, TextRange};
/// ## What it does
/// Checks for methods that are annotated with a fixed return type which
@@ -79,12 +80,15 @@ pub struct NonSelfReturnType {
}
impl Violation for NonSelfReturnType {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
let NonSelfReturnType {
class_name,
method_name,
} = self;
if matches!(class_name.as_str(), "__new__") {
"`__new__` methods usually return `self` at runtime".to_string()
} else {
@@ -93,7 +97,7 @@ impl Violation for NonSelfReturnType {
}
fn fix_title(&self) -> Option<String> {
Some("Consider using `typing_extensions.Self` as return type".to_string())
Some("Use `Self` as return type".to_string())
}
}
@@ -136,13 +140,7 @@ pub(crate) fn non_self_return_type(
&& is_name(returns, &class_def.name)
&& !is_final(&class_def.decorator_list, semantic)
{
checker.diagnostics.push(Diagnostic::new(
NonSelfReturnType {
class_name: class_def.name.to_string(),
method_name: name.to_string(),
},
stmt.identifier(),
));
add_diagnostic(checker, stmt, returns, class_def, name);
}
return;
}
@@ -150,13 +148,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) {
checker.diagnostics.push(Diagnostic::new(
NonSelfReturnType {
class_name: class_def.name.to_string(),
method_name: name.to_string(),
},
stmt.identifier(),
));
add_diagnostic(checker, stmt, returns, class_def, name);
}
return;
}
@@ -164,13 +156,7 @@ pub(crate) fn non_self_return_type(
if is_name(returns, &class_def.name) {
if matches!(name, "__enter__" | "__new__") && !is_final(&class_def.decorator_list, semantic)
{
checker.diagnostics.push(Diagnostic::new(
NonSelfReturnType {
class_name: class_def.name.to_string(),
method_name: name.to_string(),
},
stmt.identifier(),
));
add_diagnostic(checker, stmt, returns, class_def, name);
}
return;
}
@@ -180,32 +166,68 @@ pub(crate) fn non_self_return_type(
if is_iterable_or_iterator(returns, semantic)
&& subclasses_iterator(class_def, semantic)
{
checker.diagnostics.push(Diagnostic::new(
NonSelfReturnType {
class_name: class_def.name.to_string(),
method_name: name.to_string(),
},
stmt.identifier(),
));
add_diagnostic(checker, stmt, returns, class_def, name);
}
}
"__aiter__" => {
if is_async_iterable_or_iterator(returns, semantic)
&& subclasses_async_iterator(class_def, semantic)
{
checker.diagnostics.push(Diagnostic::new(
NonSelfReturnType {
class_name: class_def.name.to_string(),
method_name: name.to_string(),
},
stmt.identifier(),
));
add_diagnostic(checker, stmt, returns, class_def, name);
}
}
_ => {}
}
}
/// Add a diagnostic for the given method.
fn add_diagnostic(
checker: &mut Checker,
stmt: &Stmt,
returns: &Expr,
class_def: &ast::StmtClassDef,
method_name: &str,
) {
/// Return an [`Edit`] that imports `typing.Self` from `typing` or `typing_extensions`.
fn import_self(checker: &Checker, range: TextRange) -> Option<Edit> {
let target_version = checker.settings.target_version.as_tuple();
let source_module = if checker.source_type.is_stub() || target_version >= (3, 11) {
"typing"
} else {
"typing_extensions"
};
let (importer, semantic) = (checker.importer(), checker.semantic());
let request = ImportRequest::import_from(source_module, "Self");
let Ok((edit, ..)) = importer.get_or_import_symbol(&request, range.start(), semantic)
else {
return None;
};
Some(edit)
}
/// Generate a [`Fix`] that replaces the return type with `Self`.
fn replace_with_self(checker: &mut Checker, range: TextRange) -> Option<Fix> {
let import_self = import_self(checker, range)?;
let replace_with_self = Edit::range_replacement("Self".to_string(), range);
Some(Fix::unsafe_edits(import_self, [replace_with_self]))
}
let mut diagnostic = Diagnostic::new(
NonSelfReturnType {
class_name: class_def.name.to_string(),
method_name: method_name.to_string(),
},
stmt.identifier(),
);
if let Some(fix) = replace_with_self(checker, returns.range()) {
diagnostic.set_fix(fix);
}
checker.diagnostics.push(diagnostic);
}
/// Returns `true` if the method is an in-place binary operator.
fn is_inplace_bin_op(name: &str) -> bool {
matches!(

View File

@@ -1,7 +1,8 @@
---
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
snapshot_kind: text
---
PYI034.py:21:9: PYI034 `__new__` methods in classes like `Bad` usually return `self` at runtime
PYI034.py:21:9: PYI034 [*] `__new__` methods in classes like `Bad` usually return `self` at runtime
|
19 | object
20 | ): # Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3
@@ -9,9 +10,19 @@ PYI034.py:21:9: PYI034 `__new__` methods in classes like `Bad` usually return `s
| ^^^^^^^ PYI034
22 | ... # Y034 "__new__" methods usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__new__", e.g. "def __new__(cls, *args: Any, **kwargs: Any) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:36:9: PYI034 `__enter__` methods in classes like `Bad` usually return `self` at runtime
Unsafe fix
18 18 | class Bad(
19 19 | object
20 20 | ): # Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3
21 |- def __new__(cls, *args: Any, **kwargs: Any) -> Bad:
21 |+ def __new__(cls, *args: Any, **kwargs: Any) -> Self:
22 22 | ... # Y034 "__new__" methods usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__new__", e.g. "def __new__(cls, *args: Any, **kwargs: Any) -> Self: ..."
23 23 |
24 24 | def __repr__(self) -> str:
PYI034.py:36:9: PYI034 [*] `__enter__` methods in classes like `Bad` usually return `self` at runtime
|
34 | ... # Y032 Prefer "object" to "Any" for the second parameter in "__ne__" methods
35 |
@@ -19,9 +30,19 @@ PYI034.py:36:9: PYI034 `__enter__` methods in classes like `Bad` usually return
| ^^^^^^^^^ PYI034
37 | ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:39:15: PYI034 `__aenter__` methods in classes like `Bad` usually return `self` at runtime
Unsafe fix
33 33 | def __ne__(self, other: typing.Any) -> typing.Any:
34 34 | ... # Y032 Prefer "object" to "Any" for the second parameter in "__ne__" methods
35 35 |
36 |- def __enter__(self) -> Bad:
36 |+ def __enter__(self) -> Self:
37 37 | ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
38 38 |
39 39 | async def __aenter__(self) -> Bad:
PYI034.py:39:15: PYI034 [*] `__aenter__` methods in classes like `Bad` usually return `self` at runtime
|
37 | ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
38 |
@@ -29,9 +50,19 @@ PYI034.py:39:15: PYI034 `__aenter__` methods in classes like `Bad` usually retur
| ^^^^^^^^^^ PYI034
40 | ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:42:9: PYI034 `__iadd__` methods in classes like `Bad` usually return `self` at runtime
Unsafe fix
36 36 | def __enter__(self) -> Bad:
37 37 | ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
38 38 |
39 |- async def __aenter__(self) -> Bad:
39 |+ async def __aenter__(self) -> Self:
40 40 | ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
41 41 |
42 42 | def __iadd__(self, other: Bad) -> Bad:
PYI034.py:42:9: PYI034 [*] `__iadd__` methods in classes like `Bad` usually return `self` at runtime
|
40 | ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
41 |
@@ -39,18 +70,38 @@ PYI034.py:42:9: PYI034 `__iadd__` methods in classes like `Bad` usually return `
| ^^^^^^^^ PYI034
43 | ... # Y034 "__iadd__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__iadd__", e.g. "def __iadd__(self, other: Bad) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:165:9: PYI034 `__iter__` methods in classes like `BadIterator1` usually return `self` at runtime
Unsafe fix
39 39 | async def __aenter__(self) -> Bad:
40 40 | ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
41 41 |
42 |- def __iadd__(self, other: Bad) -> Bad:
42 |+ def __iadd__(self, other: Bad) -> Self:
43 43 | ... # Y034 "__iadd__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__iadd__", e.g. "def __iadd__(self, other: Bad) -> Self: ..."
44 44 |
45 45 |
PYI034.py:165:9: PYI034 [*] `__iter__` methods in classes like `BadIterator1` usually return `self` at runtime
|
164 | class BadIterator1(Iterator[int]):
165 | def __iter__(self) -> Iterator[int]:
| ^^^^^^^^ PYI034
166 | ... # Y034 "__iter__" methods in classes like "BadIterator1" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator1.__iter__", e.g. "def __iter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:172:9: PYI034 `__iter__` methods in classes like `BadIterator2` usually return `self` at runtime
Unsafe fix
162 162 |
163 163 |
164 164 | class BadIterator1(Iterator[int]):
165 |- def __iter__(self) -> Iterator[int]:
165 |+ def __iter__(self) -> Self:
166 166 | ... # Y034 "__iter__" methods in classes like "BadIterator1" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator1.__iter__", e.g. "def __iter__(self) -> Self: ..."
167 167 |
168 168 |
PYI034.py:172:9: PYI034 [*] `__iter__` methods in classes like `BadIterator2` usually return `self` at runtime
|
170 | typing.Iterator[int]
171 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
@@ -58,9 +109,19 @@ PYI034.py:172:9: PYI034 `__iter__` methods in classes like `BadIterator2` usuall
| ^^^^^^^^ PYI034
173 | ... # Y034 "__iter__" methods in classes like "BadIterator2" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator2.__iter__", e.g. "def __iter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:179:9: PYI034 `__iter__` methods in classes like `BadIterator3` usually return `self` at runtime
Unsafe fix
169 169 | class BadIterator2(
170 170 | typing.Iterator[int]
171 171 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
172 |- def __iter__(self) -> Iterator[int]:
172 |+ def __iter__(self) -> Self:
173 173 | ... # Y034 "__iter__" methods in classes like "BadIterator2" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator2.__iter__", e.g. "def __iter__(self) -> Self: ..."
174 174 |
175 175 |
PYI034.py:179:9: PYI034 [*] `__iter__` methods in classes like `BadIterator3` usually return `self` at runtime
|
177 | typing.Iterator[int]
178 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
@@ -68,9 +129,19 @@ PYI034.py:179:9: PYI034 `__iter__` methods in classes like `BadIterator3` usuall
| ^^^^^^^^ PYI034
180 | ... # Y034 "__iter__" methods in classes like "BadIterator3" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator3.__iter__", e.g. "def __iter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:185:9: PYI034 `__iter__` methods in classes like `BadIterator4` usually return `self` at runtime
Unsafe fix
176 176 | class BadIterator3(
177 177 | typing.Iterator[int]
178 178 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
179 |- def __iter__(self) -> collections.abc.Iterator[int]:
179 |+ def __iter__(self) -> Self:
180 180 | ... # Y034 "__iter__" methods in classes like "BadIterator3" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator3.__iter__", e.g. "def __iter__(self) -> Self: ..."
181 181 |
182 182 |
PYI034.py:185:9: PYI034 [*] `__iter__` methods in classes like `BadIterator4` usually return `self` at runtime
|
183 | class BadIterator4(Iterator[int]):
184 | # Note: *Iterable*, not *Iterator*, returned!
@@ -78,31 +149,71 @@ PYI034.py:185:9: PYI034 `__iter__` methods in classes like `BadIterator4` usuall
| ^^^^^^^^ PYI034
186 | ... # Y034 "__iter__" methods in classes like "BadIterator4" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator4.__iter__", e.g. "def __iter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:195:9: PYI034 `__aiter__` methods in classes like `BadAsyncIterator` usually return `self` at runtime
Unsafe fix
182 182 |
183 183 | class BadIterator4(Iterator[int]):
184 184 | # Note: *Iterable*, not *Iterator*, returned!
185 |- def __iter__(self) -> Iterable[int]:
185 |+ def __iter__(self) -> Self:
186 186 | ... # Y034 "__iter__" methods in classes like "BadIterator4" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator4.__iter__", e.g. "def __iter__(self) -> Self: ..."
187 187 |
188 188 |
PYI034.py:195:9: PYI034 [*] `__aiter__` methods in classes like `BadAsyncIterator` usually return `self` at runtime
|
194 | class BadAsyncIterator(collections.abc.AsyncIterator[str]):
195 | def __aiter__(self) -> typing.AsyncIterator[str]:
| ^^^^^^^^^ PYI034
196 | ... # Y034 "__aiter__" methods in classes like "BadAsyncIterator" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadAsyncIterator.__aiter__", e.g. "def __aiter__(self) -> Self: ..." # Y022 Use "collections.abc.AsyncIterator[T]" instead of "typing.AsyncIterator[T]" (PEP 585 syntax)
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:199:9: PYI034 `__iter__` methods in classes like `SubclassOfBadIterator3` usually return `self` at runtime
Unsafe fix
192 192 |
193 193 |
194 194 | class BadAsyncIterator(collections.abc.AsyncIterator[str]):
195 |- def __aiter__(self) -> typing.AsyncIterator[str]:
195 |+ def __aiter__(self) -> Self:
196 196 | ... # Y034 "__aiter__" methods in classes like "BadAsyncIterator" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadAsyncIterator.__aiter__", e.g. "def __aiter__(self) -> Self: ..." # Y022 Use "collections.abc.AsyncIterator[T]" instead of "typing.AsyncIterator[T]" (PEP 585 syntax)
197 197 |
198 198 | class SubclassOfBadIterator3(BadIterator3):
PYI034.py:199:9: PYI034 [*] `__iter__` methods in classes like `SubclassOfBadIterator3` usually return `self` at runtime
|
198 | class SubclassOfBadIterator3(BadIterator3):
199 | def __iter__(self) -> Iterator[int]: # Y034
| ^^^^^^^^ PYI034
200 | ...
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.py:203:9: PYI034 `__aiter__` methods in classes like `SubclassOfBadAsyncIterator` usually return `self` at runtime
Unsafe fix
196 196 | ... # Y034 "__aiter__" methods in classes like "BadAsyncIterator" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadAsyncIterator.__aiter__", e.g. "def __aiter__(self) -> Self: ..." # Y022 Use "collections.abc.AsyncIterator[T]" instead of "typing.AsyncIterator[T]" (PEP 585 syntax)
197 197 |
198 198 | class SubclassOfBadIterator3(BadIterator3):
199 |- def __iter__(self) -> Iterator[int]: # Y034
199 |+ def __iter__(self) -> Self: # Y034
200 200 | ...
201 201 |
202 202 | class SubclassOfBadAsyncIterator(BadAsyncIterator):
PYI034.py:203:9: PYI034 [*] `__aiter__` methods in classes like `SubclassOfBadAsyncIterator` usually return `self` at runtime
|
202 | class SubclassOfBadAsyncIterator(BadAsyncIterator):
203 | def __aiter__(self) -> collections.abc.AsyncIterator[str]: # Y034
| ^^^^^^^^^ PYI034
204 | ...
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
Unsafe fix
200 200 | ...
201 201 |
202 202 | class SubclassOfBadAsyncIterator(BadAsyncIterator):
203 |- def __aiter__(self) -> collections.abc.AsyncIterator[str]: # Y034
203 |+ def __aiter__(self) -> Self: # Y034
204 204 | ...
205 205 |
206 206 | class AsyncIteratorReturningAsyncIterable:

View File

@@ -1,7 +1,8 @@
---
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
snapshot_kind: text
---
PYI034.pyi:20:9: PYI034 `__new__` methods in classes like `Bad` usually return `self` at runtime
PYI034.pyi:20:9: PYI034 [*] `__new__` methods in classes like `Bad` usually return `self` at runtime
|
18 | object
19 | ): # Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3
@@ -10,9 +11,19 @@ PYI034.pyi:20:9: PYI034 `__new__` methods in classes like `Bad` usually return `
21 | cls, *args: Any, **kwargs: Any
22 | ) -> Bad: ... # Y034 "__new__" methods usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__new__", e.g. "def __new__(cls, *args: Any, **kwargs: Any) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:35:9: PYI034 `__enter__` methods in classes like `Bad` usually return `self` at runtime
Unsafe fix
19 19 | ): # Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3
20 20 | def __new__(
21 21 | cls, *args: Any, **kwargs: Any
22 |- ) -> Bad: ... # Y034 "__new__" methods usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__new__", e.g. "def __new__(cls, *args: Any, **kwargs: Any) -> Self: ..."
22 |+ ) -> Self: ... # Y034 "__new__" methods usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__new__", e.g. "def __new__(cls, *args: Any, **kwargs: Any) -> Self: ..."
23 23 | def __repr__(
24 24 | self,
25 25 | ) -> str: ... # Y029 Defining __repr__ or __str__ in a stub is almost always redundant
PYI034.pyi:35:9: PYI034 [*] `__enter__` methods in classes like `Bad` usually return `self` at runtime
|
33 | self, other: typing.Any
34 | ) -> typing.Any: ... # Y032 Prefer "object" to "Any" for the second parameter in "__ne__" methods
@@ -21,9 +32,19 @@ PYI034.pyi:35:9: PYI034 `__enter__` methods in classes like `Bad` usually return
36 | self,
37 | ) -> Bad: ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:38:15: PYI034 `__aenter__` methods in classes like `Bad` usually return `self` at runtime
Unsafe fix
34 34 | ) -> typing.Any: ... # Y032 Prefer "object" to "Any" for the second parameter in "__ne__" methods
35 35 | def __enter__(
36 36 | self,
37 |- ) -> Bad: ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
37 |+ ) -> Self: ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
38 38 | async def __aenter__(
39 39 | self,
40 40 | ) -> Bad: ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
PYI034.pyi:38:15: PYI034 [*] `__aenter__` methods in classes like `Bad` usually return `self` at runtime
|
36 | self,
37 | ) -> Bad: ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
@@ -32,9 +53,19 @@ PYI034.pyi:38:15: PYI034 `__aenter__` methods in classes like `Bad` usually retu
39 | self,
40 | ) -> Bad: ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:41:9: PYI034 `__iadd__` methods in classes like `Bad` usually return `self` at runtime
Unsafe fix
37 37 | ) -> Bad: ... # Y034 "__enter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__enter__", e.g. "def __enter__(self) -> Self: ..."
38 38 | async def __aenter__(
39 39 | self,
40 |- ) -> Bad: ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
40 |+ ) -> Self: ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
41 41 | def __iadd__(
42 42 | self, other: Bad
43 43 | ) -> Bad: ... # Y034 "__iadd__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__iadd__", e.g. "def __iadd__(self, other: Bad) -> Self: ..."
PYI034.pyi:41:9: PYI034 [*] `__iadd__` methods in classes like `Bad` usually return `self` at runtime
|
39 | self,
40 | ) -> Bad: ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
@@ -43,9 +74,19 @@ PYI034.pyi:41:9: PYI034 `__iadd__` methods in classes like `Bad` usually return
42 | self, other: Bad
43 | ) -> Bad: ... # Y034 "__iadd__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__iadd__", e.g. "def __iadd__(self, other: Bad) -> Self: ..."
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:104:9: PYI034 `__iter__` methods in classes like `BadIterator1` usually return `self` at runtime
Unsafe fix
40 40 | ) -> Bad: ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self) -> Self: ..."
41 41 | def __iadd__(
42 42 | self, other: Bad
43 |- ) -> Bad: ... # Y034 "__iadd__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__iadd__", e.g. "def __iadd__(self, other: Bad) -> Self: ..."
43 |+ ) -> Self: ... # Y034 "__iadd__" methods in classes like "Bad" usually return "self" at runtime. Consider using "typing_extensions.Self" in "Bad.__iadd__", e.g. "def __iadd__(self, other: Bad) -> Self: ..."
44 44 |
45 45 | class AlsoBad(
46 46 | int, builtins.object
PYI034.pyi:104:9: PYI034 [*] `__iter__` methods in classes like `BadIterator1` usually return `self` at runtime
|
103 | class BadIterator1(Iterator[int]):
104 | def __iter__(
@@ -53,9 +94,21 @@ PYI034.pyi:104:9: PYI034 `__iter__` methods in classes like `BadIterator1` usual
105 | self,
106 | ) -> Iterator[
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:113:9: PYI034 `__iter__` methods in classes like `BadIterator2` usually return `self` at runtime
Unsafe fix
103 103 | class BadIterator1(Iterator[int]):
104 104 | def __iter__(
105 105 | self,
106 |- ) -> Iterator[
107 |- int
108 |- ]: ... # Y034 "__iter__" methods in classes like "BadIterator1" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator1.__iter__", e.g. "def __iter__(self) -> Self: ..."
106 |+ ) -> Self: ... # Y034 "__iter__" methods in classes like "BadIterator1" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator1.__iter__", e.g. "def __iter__(self) -> Self: ..."
109 107 |
110 108 | class BadIterator2(
111 109 | typing.Iterator[int]
PYI034.pyi:113:9: PYI034 [*] `__iter__` methods in classes like `BadIterator2` usually return `self` at runtime
|
111 | typing.Iterator[int]
112 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
@@ -64,9 +117,21 @@ PYI034.pyi:113:9: PYI034 `__iter__` methods in classes like `BadIterator2` usual
114 | self,
115 | ) -> Iterator[
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:122:9: PYI034 `__iter__` methods in classes like `BadIterator3` usually return `self` at runtime
Unsafe fix
112 112 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
113 113 | def __iter__(
114 114 | self,
115 |- ) -> Iterator[
116 |- int
117 |- ]: ... # Y034 "__iter__" methods in classes like "BadIterator2" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator2.__iter__", e.g. "def __iter__(self) -> Self: ..."
115 |+ ) -> Self: ... # Y034 "__iter__" methods in classes like "BadIterator2" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator2.__iter__", e.g. "def __iter__(self) -> Self: ..."
118 116 |
119 117 | class BadIterator3(
120 118 | typing.Iterator[int]
PYI034.pyi:122:9: PYI034 [*] `__iter__` methods in classes like `BadIterator3` usually return `self` at runtime
|
120 | typing.Iterator[int]
121 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
@@ -75,9 +140,21 @@ PYI034.pyi:122:9: PYI034 `__iter__` methods in classes like `BadIterator3` usual
123 | self,
124 | ) -> collections.abc.Iterator[
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:130:9: PYI034 `__iter__` methods in classes like `BadIterator4` usually return `self` at runtime
Unsafe fix
121 121 | ): # Y022 Use "collections.abc.Iterator[T]" instead of "typing.Iterator[T]" (PEP 585 syntax)
122 122 | def __iter__(
123 123 | self,
124 |- ) -> collections.abc.Iterator[
125 |- int
126 |- ]: ... # Y034 "__iter__" methods in classes like "BadIterator3" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator3.__iter__", e.g. "def __iter__(self) -> Self: ..."
124 |+ ) -> Self: ... # Y034 "__iter__" methods in classes like "BadIterator3" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator3.__iter__", e.g. "def __iter__(self) -> Self: ..."
127 125 |
128 126 | class BadIterator4(Iterator[int]):
129 127 | # Note: *Iterable*, not *Iterator*, returned!
PYI034.pyi:130:9: PYI034 [*] `__iter__` methods in classes like `BadIterator4` usually return `self` at runtime
|
128 | class BadIterator4(Iterator[int]):
129 | # Note: *Iterable*, not *Iterator*, returned!
@@ -86,9 +163,21 @@ PYI034.pyi:130:9: PYI034 `__iter__` methods in classes like `BadIterator4` usual
131 | self,
132 | ) -> Iterable[
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
PYI034.pyi:144:9: PYI034 `__aiter__` methods in classes like `BadAsyncIterator` usually return `self` at runtime
Unsafe fix
129 129 | # Note: *Iterable*, not *Iterator*, returned!
130 130 | def __iter__(
131 131 | self,
132 |- ) -> Iterable[
133 |- int
134 |- ]: ... # Y034 "__iter__" methods in classes like "BadIterator4" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator4.__iter__", e.g. "def __iter__(self) -> Self: ..."
132 |+ ) -> Self: ... # Y034 "__iter__" methods in classes like "BadIterator4" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadIterator4.__iter__", e.g. "def __iter__(self) -> Self: ..."
135 133 |
136 134 | class IteratorReturningIterable:
137 135 | def __iter__(
PYI034.pyi:144:9: PYI034 [*] `__aiter__` methods in classes like `BadAsyncIterator` usually return `self` at runtime
|
143 | class BadAsyncIterator(collections.abc.AsyncIterator[str]):
144 | def __aiter__(
@@ -96,6 +185,16 @@ PYI034.pyi:144:9: PYI034 `__aiter__` methods in classes like `BadAsyncIterator`
145 | self,
146 | ) -> typing.AsyncIterator[
|
= help: Consider using `typing_extensions.Self` as return type
= help: Use `Self` as return type
Unsafe fix
143 143 | class BadAsyncIterator(collections.abc.AsyncIterator[str]):
144 144 | def __aiter__(
145 145 | self,
146 |- ) -> typing.AsyncIterator[
147 |- str
148 |- ]: ... # Y034 "__aiter__" methods in classes like "BadAsyncIterator" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadAsyncIterator.__aiter__", e.g. "def __aiter__(self) -> Self: ..." # Y022 Use "collections.abc.AsyncIterator[T]" instead of "typing.AsyncIterator[T]" (PEP 585 syntax)
146 |+ ) -> Self: ... # Y034 "__aiter__" methods in classes like "BadAsyncIterator" usually return "self" at runtime. Consider using "typing_extensions.Self" in "BadAsyncIterator.__aiter__", e.g. "def __aiter__(self) -> Self: ..." # Y022 Use "collections.abc.AsyncIterator[T]" instead of "typing.AsyncIterator[T]" (PEP 585 syntax)
149 147 |
150 148 | class AsyncIteratorReturningAsyncIterable:
151 149 | def __aiter__(