TupleMappingResults (@Nullable PyExpression argument, @NotNull PyTupleParameter parameter) { final List<PyCallableParameter> unmappedParameters = new ArrayList<>(); final List<PyExpression> unmappedArguments = new ArrayList<>(); final Map<PyExpression, PyCallableParameter> mappedParameters = new LinkedHashMap<>(); argument = PyPsiUtils.flattenParens(argument); if (argument instanceof PySequenceExpression sequenceExpr) { final PyExpression[] argumentComponents = sequenceExpr.getElements(); final PyParameter[] parameterComponents = parameter.getContents(); for (int i = 0; i < parameterComponents.length; i++) { final PyParameter param = parameterComponents[i]; if (i < argumentComponents.length) { final PyExpression arg = argumentComponents[i]; if (arg != null) { if (param instanceof PyNamedParameter) { mappedParameters.put(arg, PyCallableParameterImpl.psi(param)); } else if (param instanceof PyTupleParameter) { final TupleMappingResults nestedResults = mapComponentsOfTupleParameter(arg, (PyTupleParameter)param); mappedParameters.putAll(nestedResults.getParameters()); unmappedParameters.addAll(nestedResults.getUnmappedParameters()); unmappedArguments.addAll(nestedResults.getUnmappedArguments()); } else { unmappedArguments.add(arg); } } else { unmappedParameters.add(PyCallableParameterImpl.psi(param)); } } else { unmappedParameters.add(PyCallableParameterImpl.psi(param)); } } if (argumentComponents.length > parameterComponents.length) { for (int i = parameterComponents.length; i < argumentComponents.length; i++) { final PyExpression arg = argumentComponents[i]; if (arg != null) { unmappedArguments.add(arg); } } } } return new TupleMappingResults(mappedParameters, unmappedParameters, unmappedArguments); }