@@ -32,11 +32,29 @@ def find_modules(self, typs: Iterable[types.Type]) -> set[str]:
32
32
self .modules = set ()
33
33
self .seen_fullnames = set ()
34
34
self .seen_aliases = set ()
35
- self ._visit (typs )
35
+ for typ in typs :
36
+ self ._visit (typ )
36
37
return self .modules
37
38
38
- def _visit (self , typ_or_typs : types .Type | Iterable [types .Type ]) -> None :
39
- typs = [typ_or_typs ] if isinstance (typ_or_typs , types .Type ) else typ_or_typs
39
+ def _visit (self , typ : types .Type ) -> None :
40
+ if isinstance (typ , types .TypeAliasType ):
41
+ # Avoid infinite recursion for recursive type aliases.
42
+ if typ not in self .seen_aliases :
43
+ self .seen_aliases .add (typ )
44
+ typ .accept (self )
45
+
46
+ def _visit_type_tuple (self , typs : tuple [types .Type , ...]) -> None :
47
+ # Micro-optimization: Specialized version of _visit for lists
48
+ for typ in typs :
49
+ if isinstance (typ , types .TypeAliasType ):
50
+ # Avoid infinite recursion for recursive type aliases.
51
+ if typ in self .seen_aliases :
52
+ continue
53
+ self .seen_aliases .add (typ )
54
+ typ .accept (self )
55
+
56
+ def _visit_type_list (self , typs : list [types .Type ]) -> None :
57
+ # Micro-optimization: Specialized version of _visit for tuples
40
58
for typ in typs :
41
59
if isinstance (typ , types .TypeAliasType ):
42
60
# Avoid infinite recursion for recursive type aliases.
@@ -50,7 +68,7 @@ def _visit_module_name(self, module_name: str) -> None:
50
68
self .modules .update (split_module_names (module_name ))
51
69
52
70
def visit_unbound_type (self , t : types .UnboundType ) -> None :
53
- self ._visit (t .args )
71
+ self ._visit_type_tuple (t .args )
54
72
55
73
def visit_any (self , t : types .AnyType ) -> None :
56
74
pass
@@ -68,7 +86,7 @@ def visit_deleted_type(self, t: types.DeletedType) -> None:
68
86
pass
69
87
70
88
def visit_type_var (self , t : types .TypeVarType ) -> None :
71
- self ._visit (t .values )
89
+ self ._visit_type_list (t .values )
72
90
self ._visit (t .upper_bound )
73
91
self ._visit (t .default )
74
92
@@ -84,10 +102,10 @@ def visit_unpack_type(self, t: types.UnpackType) -> None:
84
102
t .type .accept (self )
85
103
86
104
def visit_parameters (self , t : types .Parameters ) -> None :
87
- self ._visit (t .arg_types )
105
+ self ._visit_type_list (t .arg_types )
88
106
89
107
def visit_instance (self , t : types .Instance ) -> None :
90
- self ._visit (t .args )
108
+ self ._visit_type_tuple (t .args )
91
109
if t .type :
92
110
# Uses of a class depend on everything in the MRO,
93
111
# as changes to classes in the MRO can add types to methods,
@@ -98,7 +116,7 @@ def visit_instance(self, t: types.Instance) -> None:
98
116
self ._visit_module_name (t .type .metaclass_type .type .module_name )
99
117
100
118
def visit_callable_type (self , t : types .CallableType ) -> None :
101
- self ._visit (t .arg_types )
119
+ self ._visit_type_list (t .arg_types )
102
120
self ._visit (t .ret_type )
103
121
if t .definition is not None :
104
122
fullname = t .definition .fullname
@@ -107,22 +125,22 @@ def visit_callable_type(self, t: types.CallableType) -> None:
107
125
self .seen_fullnames .add (fullname )
108
126
109
127
def visit_overloaded (self , t : types .Overloaded ) -> None :
110
- self ._visit ( t .items )
128
+ self ._visit_type_list ( list ( t .items ) )
111
129
self ._visit (t .fallback )
112
130
113
131
def visit_tuple_type (self , t : types .TupleType ) -> None :
114
- self ._visit (t .items )
132
+ self ._visit_type_list (t .items )
115
133
self ._visit (t .partial_fallback )
116
134
117
135
def visit_typeddict_type (self , t : types .TypedDictType ) -> None :
118
- self ._visit ( t .items .values ())
136
+ self ._visit_type_list ( list ( t .items .values () ))
119
137
self ._visit (t .fallback )
120
138
121
139
def visit_literal_type (self , t : types .LiteralType ) -> None :
122
140
self ._visit (t .fallback )
123
141
124
142
def visit_union_type (self , t : types .UnionType ) -> None :
125
- self ._visit (t .items )
143
+ self ._visit_type_list (t .items )
126
144
127
145
def visit_partial_type (self , t : types .PartialType ) -> None :
128
146
pass
0 commit comments