mirror of https://github.com/astral-sh/ruff
check only for generic context
Signed-off-by: 11happy <bhuminjaysoni@gmail.com>
This commit is contained in:
parent
5af1ac3b35
commit
7948d895f6
|
|
@ -13,6 +13,13 @@ from typing import TypeVar, Generic
|
|||
T1 = TypeVar("T1", default=int)
|
||||
T2 = TypeVar("T2")
|
||||
T3 = TypeVar("T3")
|
||||
DefaultStrT = TypeVar("DefaultStrT", default=str)
|
||||
|
||||
class SubclassMe(Generic[T1, DefaultStrT]):
|
||||
x: DefaultStrT
|
||||
|
||||
class Baz(SubclassMe[int, DefaultStrT]):
|
||||
pass
|
||||
|
||||
class Foo(Generic[T1, T2]): # error: [invalid-type-param-order]
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -17,39 +17,46 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/invalid_type
|
|||
3 | T1 = TypeVar("T1", default=int)
|
||||
4 | T2 = TypeVar("T2")
|
||||
5 | T3 = TypeVar("T3")
|
||||
6 |
|
||||
7 | class Foo(Generic[T1, T2]): # error: [invalid-type-param-order]
|
||||
8 | pass
|
||||
9 |
|
||||
10 | class Bar(Generic[T2, T1, T3]): # error: [invalid-type-param-order]
|
||||
11 | pass
|
||||
6 | DefaultStrT = TypeVar("DefaultStrT", default=str)
|
||||
7 |
|
||||
8 | class SubclassMe(Generic[T1, DefaultStrT]):
|
||||
9 | x: DefaultStrT
|
||||
10 |
|
||||
11 | class Baz(SubclassMe[int, DefaultStrT]):
|
||||
12 | pass
|
||||
13 |
|
||||
14 | class Foo(Generic[T1, T2]): # error: [invalid-type-param-order]
|
||||
15 | pass
|
||||
16 |
|
||||
17 | class Bar(Generic[T2, T1, T3]): # error: [invalid-type-param-order]
|
||||
18 | pass
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
||||
```
|
||||
error[invalid-type-param-order]: Type parameter T2 without a default follows type parameter with a default
|
||||
--> src/mdtest_snippet.py:7:7
|
||||
|
|
||||
5 | T3 = TypeVar("T3")
|
||||
6 |
|
||||
7 | class Foo(Generic[T1, T2]): # error: [invalid-type-param-order]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
8 | pass
|
||||
|
|
||||
--> src/mdtest_snippet.py:14:7
|
||||
|
|
||||
12 | pass
|
||||
13 |
|
||||
14 | class Foo(Generic[T1, T2]): # error: [invalid-type-param-order]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
15 | pass
|
||||
|
|
||||
info: rule `invalid-type-param-order` is enabled by default
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
error[invalid-type-param-order]: Type parameter T3 without a default follows type parameter with a default
|
||||
--> src/mdtest_snippet.py:10:7
|
||||
--> src/mdtest_snippet.py:17:7
|
||||
|
|
||||
8 | pass
|
||||
9 |
|
||||
10 | class Bar(Generic[T2, T1, T3]): # error: [invalid-type-param-order]
|
||||
15 | pass
|
||||
16 |
|
||||
17 | class Bar(Generic[T2, T1, T3]): # error: [invalid-type-param-order]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
11 | pass
|
||||
18 | pass
|
||||
|
|
||||
info: rule `invalid-type-param-order` is enabled by default
|
||||
|
||||
|
|
|
|||
|
|
@ -951,22 +951,23 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
}
|
||||
|
||||
if self.context.is_lint_enabled(&INVALID_TYPE_PARAM_ORDER) {
|
||||
let type_vars = class.typevars_referenced_in_definition(self.db());
|
||||
let mut seen_default = false;
|
||||
for type_var in type_vars {
|
||||
let has_default = type_var
|
||||
.typevar(self.db())
|
||||
.default_type(self.db())
|
||||
.is_some();
|
||||
if seen_default && !has_default {
|
||||
report_invalid_type_param_order(
|
||||
&self.context,
|
||||
class,
|
||||
type_var.typevar(self.db()).name(self.db()).as_str(),
|
||||
);
|
||||
}
|
||||
if has_default {
|
||||
seen_default = true;
|
||||
if let Some(generic_context) = class.generic_context(self.db()) {
|
||||
let mut seen_default = false;
|
||||
|
||||
for bound_typevar in generic_context.variables(self.db()) {
|
||||
let typevar = bound_typevar.typevar(self.db());
|
||||
let has_default = typevar.default_type(self.db()).is_some();
|
||||
|
||||
if seen_default && !has_default {
|
||||
report_invalid_type_param_order(
|
||||
&self.context,
|
||||
class,
|
||||
typevar.name(self.db()).as_str(),
|
||||
);
|
||||
}
|
||||
if has_default {
|
||||
seen_default = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue