@@ -175,20 +175,25 @@ fn is_typevar(obj: &PyObjectRef) -> bool {
175
175
}
176
176
177
177
fn make_parameters ( args : & PyTupleRef , vm : & VirtualMachine ) -> PyTupleRef {
178
- let mut parameters: Vec < PyObjectRef > = vec ! [ ] ;
178
+ let mut parameters: Vec < PyObjectRef > = Vec :: with_capacity ( args . len ( ) ) ;
179
179
for arg in args. as_slice ( ) {
180
180
if is_typevar ( arg) {
181
- parameters. push ( arg. clone ( ) ) ;
182
- } else if let Ok ( tuple) = arg
181
+ if !parameters. iter ( ) . any ( |param| param. is ( arg) ) {
182
+ parameters. push ( arg. clone ( ) ) ;
183
+ }
184
+ } else if let Ok ( subparams) = arg
183
185
. clone ( )
184
186
. get_attr ( "__parameters__" , vm)
185
187
. and_then ( |obj| PyTupleRef :: try_from_object ( vm, obj) )
186
188
{
187
- for subparam in tuple. as_slice ( ) {
188
- parameters. push ( subparam. clone ( ) ) ;
189
+ for subparam in subparams. as_slice ( ) {
190
+ if !parameters. iter ( ) . any ( |param| param. is ( subparam) ) {
191
+ parameters. push ( subparam. clone ( ) ) ;
192
+ }
189
193
}
190
194
}
191
195
}
196
+ parameters. shrink_to_fit ( ) ;
192
197
193
198
PyTuple :: new_ref ( parameters, & vm. ctx )
194
199
}
@@ -204,27 +209,33 @@ fn subs_tvars(
204
209
argitems : & [ PyObjectRef ] ,
205
210
vm : & VirtualMachine ,
206
211
) -> PyResult {
207
- obj. clone_class ( )
208
- . get_attr ( "__parameters__" )
212
+ obj. clone ( )
213
+ . get_attr ( "__parameters__" , vm)
214
+ . ok ( )
209
215
. and_then ( |sub_params| {
210
216
PyTupleRef :: try_from_object ( vm, sub_params)
211
217
. ok ( )
212
218
. map ( |sub_params| {
213
- let sub_args = sub_params
214
- . as_slice ( )
215
- . iter ( )
216
- . map ( |arg| {
217
- if let Some ( idx) = tuple_index ( params, arg) {
218
- argitems[ idx] . clone ( )
219
- } else {
220
- arg. clone ( )
221
- }
222
- } )
223
- . collect :: < Vec < _ > > ( ) ;
224
- let sub_args: PyObjectRef = PyTuple :: new_ref ( sub_args, & vm. ctx ) . into ( ) ;
225
- obj. get_item ( sub_args, vm)
219
+ if sub_params. len ( ) > 0 {
220
+ let sub_args = sub_params
221
+ . as_slice ( )
222
+ . iter ( )
223
+ . map ( |arg| {
224
+ if let Some ( idx) = tuple_index ( params, arg) {
225
+ argitems[ idx] . clone ( )
226
+ } else {
227
+ arg. clone ( )
228
+ }
229
+ } )
230
+ . collect :: < Vec < _ > > ( ) ;
231
+ let sub_args: PyObjectRef = PyTuple :: new_ref ( sub_args, & vm. ctx ) . into ( ) ;
232
+ Some ( obj. get_item ( sub_args, vm) )
233
+ } else {
234
+ None
235
+ }
226
236
} )
227
237
} )
238
+ . flatten ( )
228
239
. unwrap_or ( Ok ( obj) )
229
240
}
230
241
0 commit comments