Compare commits
2 Commits
charlie/di
...
PYI034
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
947e1a4e4d | ||
|
|
33945a5517 |
@@ -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!(
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__(
|
||||
|
||||
Reference in New Issue
Block a user