diff --git a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java index 4829f2bd6e71..ad689b66681c 100644 --- a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java +++ b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java @@ -126,6 +126,19 @@ public class PyTypeModelBuilder { } } + static class TupleType extends TypeModel { + private final List members; + + public TupleType(List members) { + this.members = members; + } + + @Override + void accept(TypeVisitor visitor) { + visitor.tuple(this); + } + } + private static TypeModel _(String name) { return new NamedType(name); } @@ -228,6 +241,15 @@ public class PyTypeModelBuilder { else if (type instanceof PyCallableType && !(type instanceof PyClassLikeType)) { result = build((PyCallableType)type); } + else if (type instanceof PyTupleType) { + final List elementModels = new ArrayList(); + final PyTupleType tupleType = (PyTupleType)type; + for (int i = 0; i < tupleType.getElementCount(); i++) { + final PyType elementType = tupleType.getElementType(i); + elementModels.add(build(elementType, true)); + } + result = new TupleType(elementModels); + } if (result == null) { result = type != null ? _(type.getName()) : _(PyNames.UNKNOWN_TYPE); } @@ -284,6 +306,8 @@ public class PyTypeModelBuilder { void unknown(UnknownType type); void optional(OptionalType type); + + void tuple(TupleType type); } private static class TypeToStringVisitor extends TypeNameVisitor { @@ -446,5 +470,12 @@ public class PyTypeModelBuilder { type.type.accept(this); add("]"); } + + @Override + public void tuple(TupleType type) { + add("Tuple["); + processList(type.members, ", "); + add("]"); + } } } diff --git a/python/testData/inspections/PyTypeCheckerInspection/GenericUserFunctions.py b/python/testData/inspections/PyTypeCheckerInspection/GenericUserFunctions.py index 8858b9b7b79d..937bffc0fb05 100644 --- a/python/testData/inspections/PyTypeCheckerInspection/GenericUserFunctions.py +++ b/python/testData/inspections/PyTypeCheckerInspection/GenericUserFunctions.py @@ -43,4 +43,4 @@ def test(): f2(1, ['foo'], 'bar') result = f3(1, 'foo', True) - f4(result) + f4(result) diff --git a/python/testData/inspections/PyTypeCheckerInspection/ListTuple.py b/python/testData/inspections/PyTypeCheckerInspection/ListTuple.py index e47e9363ce5a..9face1ee5cf6 100644 --- a/python/testData/inspections/PyTypeCheckerInspection/ListTuple.py +++ b/python/testData/inspections/PyTypeCheckerInspection/ListTuple.py @@ -8,4 +8,4 @@ def f(spam, eggs): def test(): f([1, 2, 3], - (False, 2, '')) + (False, 2, '')) diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index a382972245a9..b5ca90ea407e 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -845,12 +845,12 @@ public class PyTypeTest extends PyTestCase { // PY-12801 public void testTupleConcatenation() { - doTest("(int, bool, str)", + doTest("Tuple[int, bool, str]", "expr = (1,) + (True, 'spam') + ()"); } public void testTupleMultiplication() { - doTest("(int, bool, int, bool)", + doTest("Tuple[int, bool, int, bool]", "expr = (1, False) * 2"); } diff --git a/python/testSrc/com/jetbrains/python/PyTypingTest.java b/python/testSrc/com/jetbrains/python/PyTypingTest.java index a4426afa96f2..48cee02c68d9 100644 --- a/python/testSrc/com/jetbrains/python/PyTypingTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypingTest.java @@ -124,7 +124,7 @@ public class PyTypingTest extends PyTestCase { } public void testBuiltinTupleWithParameters() { - doTest("(int, str)", + doTest("Tuple[int, str]", "from typing import Tuple\n" + "\n" + "def f(expr: Tuple[int, str]):\n" +