fix make_parameters in GenericAlias

make_parameters must not push duplicated parameters
as cpython implementation.

See `tuple_add` function of `genericaliasobject.c` in cpython code
https://github.com/python/cpython/blob/main/Objects/genericaliasobject.c#L191

Signed-off-by: snowapril <sinjihng@gmail.com>
This commit is contained in:
snowapril
2021-10-27 15:25:01 +09:00
parent fe1e375a1f
commit 2e48ba3e17

View File

@@ -175,20 +175,25 @@ fn is_typevar(obj: &PyObjectRef) -> bool {
}
fn make_parameters(args: &PyTupleRef, vm: &VirtualMachine) -> PyTupleRef {
let mut parameters: Vec<PyObjectRef> = vec![];
let mut parameters: Vec<PyObjectRef> = Vec::with_capacity(args.len());
for arg in args.as_slice() {
if is_typevar(arg) {
parameters.push(arg.clone());
} else if let Ok(tuple) = arg
if !parameters.iter().any(|param| param.is(arg)) {
parameters.push(arg.clone());
}
} else if let Ok(subparams) = arg
.clone()
.get_attr("__parameters__", vm)
.and_then(|obj| PyTupleRef::try_from_object(vm, obj))
{
for subparam in tuple.as_slice() {
parameters.push(subparam.clone());
for subparam in subparams.as_slice() {
if !parameters.iter().any(|param| param.is(subparam)) {
parameters.push(subparam.clone());
}
}
}
}
parameters.shrink_to_fit();
PyTuple::new_ref(parameters, &vm.ctx)
}