From e87b053584194a8ad2bc9771eccf96d94ecde0e3 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Mon, 7 Nov 2016 21:05:42 +0300 Subject: [PATCH] PY-21350 Fixed: Wrong return type for input() in Python 3 Add skeletons for raw_input() in Python 2 and input() for both Pythons. Update PyUserSkeletonsTypeProvider to wrap callable's return type even if it's null. --- python/helpers/python-skeletons/__builtin__.py | 16 ++++++++++++++++ python/helpers/python-skeletons/builtins.py | 8 ++++++++ .../PyUserSkeletonsTypeProvider.java | 5 +---- .../PyTypeCheckerInspection/BuiltinInputPy2.py | 6 ++++++ .../PyTypeCheckerInspection/BuiltinInputPy3.py | 6 ++++++ .../PyTypeCheckerInspection/BuiltinRawInput.py | 6 ++++++ .../com/jetbrains/python/Py3TypeTest.java | 8 +++++++- .../testSrc/com/jetbrains/python/PyTypeTest.java | 12 ++++++++++++ .../Py3TypeCheckerInspectionTest.java | 5 +++++ .../inspections/PyTypeCheckerInspectionTest.java | 10 ++++++++++ 10 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy2.py create mode 100644 python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy3.py create mode 100644 python/testData/inspections/PyTypeCheckerInspection/BuiltinRawInput.py diff --git a/python/helpers/python-skeletons/__builtin__.py b/python/helpers/python-skeletons/__builtin__.py index 5276f485f2b3..a2961466aa2e 100644 --- a/python/helpers/python-skeletons/__builtin__.py +++ b/python/helpers/python-skeletons/__builtin__.py @@ -2944,3 +2944,19 @@ class __method(object): if sys.version_info >= (2, 6): self.__func__ = None self.__self__ = None + + +def input(prompt=None): + """ + :type prompt: Any + :rtype: Any + """ + pass + + +def raw_input(prompt=None): + """ + :type prompt: Any + :rtype: str + """ + pass \ No newline at end of file diff --git a/python/helpers/python-skeletons/builtins.py b/python/helpers/python-skeletons/builtins.py index 07a50074679a..d453590a4087 100644 --- a/python/helpers/python-skeletons/builtins.py +++ b/python/helpers/python-skeletons/builtins.py @@ -2577,3 +2577,11 @@ class __method(object): def __init__(self): self.__func__ = None self.__self__ = None + + +def input(prompt=None): + """ + :type prompt: Any + :rtype: str + """ + pass diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java index 6551be926f96..a78c7113369d 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsTypeProvider.java @@ -54,10 +54,7 @@ public class PyUserSkeletonsTypeProvider extends PyTypeProviderBase { public Ref getReturnType(@NotNull PyCallable callable, @NotNull TypeEvalContext context) { final PyCallable callableSkeleton = PyUserSkeletonsUtil.getUserSkeletonWithContext(callable, context); if (callableSkeleton != null) { - final PyType type = context.getReturnType(callableSkeleton); - if (type != null) { - return Ref.create(type); - } + return Ref.create(context.getReturnType(callableSkeleton)); } return null; } diff --git a/python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy2.py b/python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy2.py new file mode 100644 index 000000000000..2a95d4c40449 --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy2.py @@ -0,0 +1,6 @@ +class A: + pass + +input(A()) +input(b"b") +input(u"u") \ No newline at end of file diff --git a/python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy3.py b/python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy3.py new file mode 100644 index 000000000000..2a95d4c40449 --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/BuiltinInputPy3.py @@ -0,0 +1,6 @@ +class A: + pass + +input(A()) +input(b"b") +input(u"u") \ No newline at end of file diff --git a/python/testData/inspections/PyTypeCheckerInspection/BuiltinRawInput.py b/python/testData/inspections/PyTypeCheckerInspection/BuiltinRawInput.py new file mode 100644 index 000000000000..882999fd022d --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/BuiltinRawInput.py @@ -0,0 +1,6 @@ +class A: + pass + +raw_input(A()) +raw_input(b"b") +raw_input(u"u") \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/Py3TypeTest.java b/python/testSrc/com/jetbrains/python/Py3TypeTest.java index c8cb9818b708..124bf1d04c59 100644 --- a/python/testSrc/com/jetbrains/python/Py3TypeTest.java +++ b/python/testSrc/com/jetbrains/python/Py3TypeTest.java @@ -443,7 +443,7 @@ public class Py3TypeTest extends PyTestCase { // PY-20073 public void testMapReturnType() { - doTest("int", + doTest("int", "for x in map(lambda x: 42, 'foo'):\n" + " expr = x"); } @@ -459,6 +459,12 @@ public class Py3TypeTest extends PyTestCase { "expr = get_value([])"); } + // PY-21350 + public void testBuiltinInput() { + doTest("str", + "expr = input()"); + } + private void doTest(final String expectedType, final String text) { myFixture.configureByText(PythonFileType.INSTANCE, text); final PyExpression expr = myFixture.findElementByText("expr", PyExpression.class); diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 35f94842e56f..85e51acfef67 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -1416,6 +1416,18 @@ public class PyTypeTest extends PyTestCase { "expr = get_value([])"); } + // PY-21350 + public void testBuiltinInput() { + doTest("Any", + "expr = input()"); + } + + // PY-21350 + public void testBuiltinRawInput() { + doTest("str", + "expr = raw_input()"); + } + private static List getTypeEvalContexts(@NotNull PyExpression element) { return ImmutableList.of(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).withTracing(), TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).withTracing()); diff --git a/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java index d6c0f4eaa6ce..8896eddb717c 100644 --- a/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java @@ -178,4 +178,9 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase { public void testMapArgumentsInOppositeOrder() { doTest(); } + + // PY-21350 + public void testBuiltinInputPy3() { + doTest(); + } } diff --git a/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java index 32f4f7ff39a1..84be3ae87dd6 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyTypeCheckerInspectionTest.java @@ -350,4 +350,14 @@ public class PyTypeCheckerInspectionTest extends PyTestCase { public void testPositionalArguments() { doTest(); } + + // PY-21350 + public void testBuiltinInputPy2() { + doTest(); + } + + // PY-21350 + public void testBuiltinRawInput() { + doTest(); + } }