Interpret tuple default parameter value as a weak type (PY-10967)

This commit is contained in:
Andrey Vlasovskikh
2014-05-27 19:28:21 +04:00
parent 846b42a9ed
commit 06a130f93d
4 changed files with 20 additions and 2 deletions
@@ -239,7 +239,7 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
final PyType type = context.getType(defaultValue);
if (type != null && !(type instanceof PyNoneType)) {
if (type instanceof PyTupleType) {
return PyTypeParser.getTypeByName(this, "collections.Iterable");
return PyUnionType.createWeakType(type);
}
return type;
}
@@ -208,7 +208,7 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
final PyAssignmentStatement assignment = (PyAssignmentStatement)nextParent;
final PyExpression value = assignment.getAssignedValue();
if (value != null) {
final PyType assignedType = context.getType(value);
final PyType assignedType = PyTypeChecker.toNonWeakType(context.getType(value), context);
if (assignedType instanceof PyTupleType) {
final PyType t = getTypeFromTupleAssignment((PyTupleExpression)parent, (PyTupleType)assignedType);
if (t != null) {
@@ -215,6 +215,17 @@ public class PyTypeChecker {
return false;
}
@Nullable
public static PyType toNonWeakType(@Nullable PyType type, @NotNull TypeEvalContext context) {
if (type instanceof PyUnionType) {
final PyUnionType unionType = (PyUnionType)type;
if (unionType.isWeak()) {
return unionType.excludeNull(context);
}
}
return type;
}
public static boolean hasGenerics(@Nullable PyType type, @NotNull TypeEvalContext context) {
final Set<PyGenericType> collected = new HashSet<PyGenericType>();
collectGenerics(type, context, collected, new HashSet<PyType>());
@@ -805,6 +805,13 @@ public class PyTypeTest extends PyTestCase {
"expr = iter(xs).next()\n");
}
// PY-10967
public void testDefaultTupleParameterMember() {
doTest("int",
"def foo(xs=(1, 2)):\n" +
" expr, foo = xs\n");
}
private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) {
return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing();
}