From 437b18316016fa1730ee83b17bdd6d6783a492c2 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Thu, 12 Apr 2018 17:03:24 +0300 Subject: [PATCH] Infer type for targets initialized through `TypeVar(...)` (PY-28227) --- .../codeInsight/typing/PyTypingTypeProvider.java | 8 ++++++++ python/testData/types/TypeVarTargetStub/a.py | 3 +++ .../testSrc/com/jetbrains/python/PyTypeTest.java | 14 ++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 python/testData/types/TypeVarTargetStub/a.py diff --git a/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java index cacc3955f760..2408aa0598f1 100644 --- a/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java @@ -491,6 +491,14 @@ public class PyTypingTypeProvider extends PyTypeProviderBase { return annotatedType; } + final PyExpression assignedValue = PyTypingAliasStubType.getAssignedValueStubLike(target); + if (assignedValue != null) { + final PyType type = getGenericTypeFromTypeVar(assignedValue, new Context(context)); + if (type != null) { + return Ref.create(type); + } + } + final String name = target.getReferencedName(); final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(target); if (name == null || scopeOwner == null) { diff --git a/python/testData/types/TypeVarTargetStub/a.py b/python/testData/types/TypeVarTargetStub/a.py new file mode 100644 index 000000000000..65b5ccfa7d2d --- /dev/null +++ b/python/testData/types/TypeVarTargetStub/a.py @@ -0,0 +1,3 @@ +from typing import TypeVar + +T = TypeVar('T') \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 36775cc5492b..17500d3eafea 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -3230,6 +3230,20 @@ public class PyTypeTest extends PyTestCase { doTest("float", "expr = round(True, 1)"); } + // PY-28227 + public void testTypeVarTargetAST() { + doTest("T", + "from typing import TypeVar\n" + + "expr = TypeVar('T')"); + } + + // PY-28227 + public void testTypeVarTargetStub() { + doMultiFileTest("T", + "from a import T\n" + + "expr = T"); + } + private static List getTypeEvalContexts(@NotNull PyExpression element) { return ImmutableList.of(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).withTracing(), TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).withTracing());