From 63f25e8e4d7baad38c16749b06ff5ab2f2824b12 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 29 Nov 2017 19:44:27 +0300 Subject: [PATCH] PY-27186 Use generic type information from .pyi stub in the respective .py file by implementing missing getGenericType() and getGenericSubstitutions() in PyiTypeProvider. --- .../jetbrains/python/pyi/PyiTypeProvider.java | 28 ++++++++++++++++--- .../GenericClassDefinitionInOtherFile.py | 3 ++ .../other.py | 6 ++++ .../other.pyi | 11 ++++++++ .../GenericClassDefinitionInSameFile.py | 9 ++++++ .../GenericClassDefinitionInSameFile.pyi | 11 ++++++++ .../com/jetbrains/python/pyi/PyiTypeTest.java | 9 ++++++ 7 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 python/testData/pyi/type/genericClassDefinitionInOtherFile/GenericClassDefinitionInOtherFile.py create mode 100644 python/testData/pyi/type/genericClassDefinitionInOtherFile/other.py create mode 100644 python/testData/pyi/type/genericClassDefinitionInOtherFile/other.pyi create mode 100644 python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.py create mode 100644 python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.pyi diff --git a/python/src/com/jetbrains/python/pyi/PyiTypeProvider.java b/python/src/com/jetbrains/python/pyi/PyiTypeProvider.java index 9280394a4eeb..de6a76a0486b 100644 --- a/python/src/com/jetbrains/python/pyi/PyiTypeProvider.java +++ b/python/src/com/jetbrains/python/pyi/PyiTypeProvider.java @@ -17,16 +17,16 @@ package com.jetbrains.python.pyi; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; +import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyCallExpressionHelper; import com.jetbrains.python.psi.types.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; + +import static com.jetbrains.python.psi.PyUtil.as; /** * @author vlan @@ -139,4 +139,24 @@ public class PyiTypeProvider extends PyTypeProviderBase { } return null; } + + @Nullable + @Override + public PyType getGenericType(@NotNull PyClass cls, @NotNull TypeEvalContext context) { + final PyClass classStub = as(PyiUtil.getPythonStub(cls), PyClass.class); + if (classStub != null) { + return new PyTypingTypeProvider().getGenericType(classStub, context); + } + return null; + } + + @NotNull + @Override + public Map getGenericSubstitutions(@NotNull PyClass cls, @NotNull TypeEvalContext context) { + final PyClass classStub = as(PyiUtil.getPythonStub(cls), PyClass.class); + if (classStub != null) { + return new PyTypingTypeProvider().getGenericSubstitutions(classStub, context); + } + return Collections.emptyMap(); + } } diff --git a/python/testData/pyi/type/genericClassDefinitionInOtherFile/GenericClassDefinitionInOtherFile.py b/python/testData/pyi/type/genericClassDefinitionInOtherFile/GenericClassDefinitionInOtherFile.py new file mode 100644 index 000000000000..666995a7af19 --- /dev/null +++ b/python/testData/pyi/type/genericClassDefinitionInOtherFile/GenericClassDefinitionInOtherFile.py @@ -0,0 +1,3 @@ +from other import Holder + +expr = Holder(42).get() diff --git a/python/testData/pyi/type/genericClassDefinitionInOtherFile/other.py b/python/testData/pyi/type/genericClassDefinitionInOtherFile/other.py new file mode 100644 index 000000000000..f7461201509b --- /dev/null +++ b/python/testData/pyi/type/genericClassDefinitionInOtherFile/other.py @@ -0,0 +1,6 @@ +class Holder: + def __init__(self, x): + self.x = x + + def get(self): + return self.x \ No newline at end of file diff --git a/python/testData/pyi/type/genericClassDefinitionInOtherFile/other.pyi b/python/testData/pyi/type/genericClassDefinitionInOtherFile/other.pyi new file mode 100644 index 000000000000..6666e9a4abfc --- /dev/null +++ b/python/testData/pyi/type/genericClassDefinitionInOtherFile/other.pyi @@ -0,0 +1,11 @@ +from typing import Generic, TypeVar + +T = TypeVar('T') + + +class Holder(Generic[T]): + def __init__(self, x: T): + pass + + def get(self) -> T: + pass \ No newline at end of file diff --git a/python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.py b/python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.py new file mode 100644 index 000000000000..0456a2e687c4 --- /dev/null +++ b/python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.py @@ -0,0 +1,9 @@ +class Holder: + def __init__(self, x): + self.x = x + + def get(self): + return self.x + + +expr = Holder(42).get() \ No newline at end of file diff --git a/python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.pyi b/python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.pyi new file mode 100644 index 000000000000..6666e9a4abfc --- /dev/null +++ b/python/testData/pyi/type/genericClassDefinitionInSameFile/GenericClassDefinitionInSameFile.pyi @@ -0,0 +1,11 @@ +from typing import Generic, TypeVar + +T = TypeVar('T') + + +class Holder(Generic[T]): + def __init__(self, x: T): + pass + + def get(self) -> T: + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/pyi/PyiTypeTest.java b/python/testSrc/com/jetbrains/python/pyi/PyiTypeTest.java index bc99c8b6af5e..d18173e58c12 100644 --- a/python/testSrc/com/jetbrains/python/pyi/PyiTypeTest.java +++ b/python/testSrc/com/jetbrains/python/pyi/PyiTypeTest.java @@ -133,4 +133,13 @@ public class PyiTypeTest extends PyTestCase { public void testOverloadedNotMatchedGenericType() { doTest("Union[Dict[str, Any], list]"); } + + public void testGenericClassDefinitionInOtherFile() { + doTest("int"); + } + + // PY-27186 + public void testGenericClassDefinitionInSameFile() { + doTest("int"); + } }