check only for generic context

Signed-off-by: 11happy <bhuminjaysoni@gmail.com>
This commit is contained in:
11happy 2025-12-10 07:04:18 +00:00 committed by 11happy
parent 5af1ac3b35
commit 7948d895f6
3 changed files with 50 additions and 35 deletions

View File

@ -13,6 +13,13 @@ from typing import TypeVar, Generic
T1 = TypeVar("T1", default=int) T1 = TypeVar("T1", default=int)
T2 = TypeVar("T2") T2 = TypeVar("T2")
T3 = TypeVar("T3") 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] class Foo(Generic[T1, T2]): # error: [invalid-type-param-order]
pass pass

View File

@ -17,25 +17,32 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/diagnostics/invalid_type
3 | T1 = TypeVar("T1", default=int) 3 | T1 = TypeVar("T1", default=int)
4 | T2 = TypeVar("T2") 4 | T2 = TypeVar("T2")
5 | T3 = TypeVar("T3") 5 | T3 = TypeVar("T3")
6 | 6 | DefaultStrT = TypeVar("DefaultStrT", default=str)
7 | class Foo(Generic[T1, T2]): # error: [invalid-type-param-order] 7 |
8 | pass 8 | class SubclassMe(Generic[T1, DefaultStrT]):
9 | 9 | x: DefaultStrT
10 | class Bar(Generic[T2, T1, T3]): # error: [invalid-type-param-order] 10 |
11 | pass 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 # Diagnostics
``` ```
error[invalid-type-param-order]: Type parameter T2 without a default follows type parameter with a default error[invalid-type-param-order]: Type parameter T2 without a default follows type parameter with a default
--> src/mdtest_snippet.py:7:7 --> src/mdtest_snippet.py:14:7
| |
5 | T3 = TypeVar("T3") 12 | pass
6 | 13 |
7 | class Foo(Generic[T1, T2]): # error: [invalid-type-param-order] 14 | class Foo(Generic[T1, T2]): # error: [invalid-type-param-order]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
8 | pass 15 | pass
| |
info: rule `invalid-type-param-order` is enabled by default info: rule `invalid-type-param-order` is enabled by default
@ -43,13 +50,13 @@ 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 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 15 | pass
9 | 16 |
10 | class Bar(Generic[T2, T1, T3]): # error: [invalid-type-param-order] 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 info: rule `invalid-type-param-order` is enabled by default

View File

@ -951,18 +951,18 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
} }
if self.context.is_lint_enabled(&INVALID_TYPE_PARAM_ORDER) { if self.context.is_lint_enabled(&INVALID_TYPE_PARAM_ORDER) {
let type_vars = class.typevars_referenced_in_definition(self.db()); if let Some(generic_context) = class.generic_context(self.db()) {
let mut seen_default = false; let mut seen_default = false;
for type_var in type_vars {
let has_default = type_var for bound_typevar in generic_context.variables(self.db()) {
.typevar(self.db()) let typevar = bound_typevar.typevar(self.db());
.default_type(self.db()) let has_default = typevar.default_type(self.db()).is_some();
.is_some();
if seen_default && !has_default { if seen_default && !has_default {
report_invalid_type_param_order( report_invalid_type_param_order(
&self.context, &self.context,
class, class,
type_var.typevar(self.db()).name(self.db()).as_str(), typevar.name(self.db()).as_str(),
); );
} }
if has_default { if has_default {
@ -970,6 +970,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
} }
} }
} }
}
let scope = class.body_scope(self.db()).scope(self.db()); let scope = class.body_scope(self.db()).scope(self.db());
if self.context.is_lint_enabled(&INVALID_GENERIC_CLASS) if self.context.is_lint_enabled(&INVALID_GENERIC_CLASS)
&& let Some(parent) = scope.parent() && let Some(parent) = scope.parent()