@@ -9,7 +9,7 @@ use ruff_python_ast::{
9
9
self as ast,
10
10
name:: Name ,
11
11
visitor:: { self , Visitor } ,
12
- Expr , ExprCall , ExprName , ExprSubscript , Identifier , Stmt , StmtAssign , TypeParam ,
12
+ Arguments , Expr , ExprCall , ExprName , ExprSubscript , Identifier , Stmt , StmtAssign , TypeParam ,
13
13
TypeParamParamSpec , TypeParamTypeVar , TypeParamTypeVarTuple ,
14
14
} ;
15
15
use ruff_python_semantic:: SemanticModel ;
@@ -26,7 +26,7 @@ mod non_pep695_generic_function;
26
26
mod non_pep695_type_alias;
27
27
28
28
#[ derive( Debug ) ]
29
- enum TypeVarRestriction < ' a > {
29
+ pub ( crate ) enum TypeVarRestriction < ' a > {
30
30
/// A type variable with a bound, e.g., `TypeVar("T", bound=int)`.
31
31
Bound ( & ' a Expr ) ,
32
32
/// A type variable with constraints, e.g., `TypeVar("T", int, str)`.
@@ -37,25 +37,25 @@ enum TypeVarRestriction<'a> {
37
37
}
38
38
39
39
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
40
- enum TypeParamKind {
40
+ pub ( crate ) enum TypeParamKind {
41
41
TypeVar ,
42
42
TypeVarTuple ,
43
43
ParamSpec ,
44
44
}
45
45
46
46
#[ derive( Debug ) ]
47
- struct TypeVar < ' a > {
48
- name : & ' a str ,
49
- restriction : Option < TypeVarRestriction < ' a > > ,
50
- kind : TypeParamKind ,
51
- default : Option < & ' a Expr > ,
47
+ pub ( crate ) struct TypeVar < ' a > {
48
+ pub ( crate ) name : & ' a str ,
49
+ pub ( crate ) restriction : Option < TypeVarRestriction < ' a > > ,
50
+ pub ( crate ) kind : TypeParamKind ,
51
+ pub ( crate ) default : Option < & ' a Expr > ,
52
52
}
53
53
54
54
/// Wrapper for formatting a sequence of [`TypeVar`]s for use as a generic type parameter (e.g. `[T,
55
55
/// *Ts, **P]`). See [`DisplayTypeVar`] for further details.
56
- struct DisplayTypeVars < ' a > {
57
- type_vars : & ' a [ TypeVar < ' a > ] ,
58
- source : & ' a str ,
56
+ pub ( crate ) struct DisplayTypeVars < ' a > {
57
+ pub ( crate ) type_vars : & ' a [ TypeVar < ' a > ] ,
58
+ pub ( crate ) source : & ' a str ,
59
59
}
60
60
61
61
impl Display for DisplayTypeVars < ' _ > {
@@ -79,7 +79,7 @@ impl Display for DisplayTypeVars<'_> {
79
79
80
80
/// Used for displaying `type_var`. `source` is the whole file, which will be sliced to recover the
81
81
/// `TypeVarRestriction` values for generic bounds and constraints.
82
- struct DisplayTypeVar < ' a > {
82
+ pub ( crate ) struct DisplayTypeVar < ' a > {
83
83
type_var : & ' a TypeVar < ' a > ,
84
84
source : & ' a str ,
85
85
}
@@ -190,6 +190,34 @@ impl<'a> From<&'a TypeVar<'a>> for TypeParam {
190
190
}
191
191
}
192
192
193
+ impl < ' a > From < & ' a TypeParam > for TypeVar < ' a > {
194
+ fn from ( param : & ' a TypeParam ) -> Self {
195
+ let ( kind, restriction) = match param {
196
+ TypeParam :: TypeVarTuple ( _) => ( TypeParamKind :: TypeVarTuple , None ) ,
197
+ TypeParam :: ParamSpec ( _) => ( TypeParamKind :: ParamSpec , None ) ,
198
+
199
+ TypeParam :: TypeVar ( param) => {
200
+ let restriction = match param. bound . as_deref ( ) {
201
+ None => None ,
202
+ Some ( Expr :: Tuple ( constraints) ) => Some ( TypeVarRestriction :: Constraint (
203
+ constraints. elts . iter ( ) . collect :: < Vec < _ > > ( ) ,
204
+ ) ) ,
205
+ Some ( bound) => Some ( TypeVarRestriction :: Bound ( bound) ) ,
206
+ } ;
207
+
208
+ ( TypeParamKind :: TypeVar , restriction)
209
+ }
210
+ } ;
211
+
212
+ Self {
213
+ name : param. name ( ) ,
214
+ kind,
215
+ restriction,
216
+ default : param. default ( ) ,
217
+ }
218
+ }
219
+ }
220
+
193
221
struct TypeVarReferenceVisitor < ' a > {
194
222
vars : Vec < TypeVar < ' a > > ,
195
223
semantic : & ' a SemanticModel < ' a > ,
@@ -240,7 +268,7 @@ impl<'a> Visitor<'a> for TypeVarReferenceVisitor<'a> {
240
268
}
241
269
}
242
270
243
- fn expr_name_to_type_var < ' a > (
271
+ pub ( crate ) fn expr_name_to_type_var < ' a > (
244
272
semantic : & ' a SemanticModel ,
245
273
name : & ' a ExprName ,
246
274
) -> Option < TypeVar < ' a > > {
@@ -347,3 +375,18 @@ fn check_type_vars(vars: Vec<TypeVar<'_>>) -> Option<Vec<TypeVar<'_>>> {
347
375
== vars. len ( ) )
348
376
. then_some ( vars)
349
377
}
378
+
379
+ /// Search `class_bases` for a `typing.Generic` base class. Returns the `Generic` expression (if
380
+ /// any), along with its index in the class's bases tuple.
381
+ pub ( crate ) fn find_generic < ' a > (
382
+ class_bases : & ' a Arguments ,
383
+ semantic : & SemanticModel ,
384
+ ) -> Option < ( usize , & ' a ExprSubscript ) > {
385
+ class_bases. args . iter ( ) . enumerate ( ) . find_map ( |( idx, expr) | {
386
+ expr. as_subscript_expr ( ) . and_then ( |sub_expr| {
387
+ semantic
388
+ . match_typing_expr ( & sub_expr. value , "Generic" )
389
+ . then_some ( ( idx, sub_expr) )
390
+ } )
391
+ } )
392
+ }
0 commit comments