From 405a2936d8b0c7fb60ca8b04308f68151dfa66d8 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Thu, 27 Jul 2017 15:54:00 +0300 Subject: [PATCH] PY-23552 Fixed: PyRedeclaration does not recognize static/class methods Ignore only functions with unknown or redeclaration decorators in PyRedeclarationInspection --- .../PyRedeclarationInspection.java | 3 ++- .../python/psi/PyKnownDecoratorUtil.java | 4 ++++ ...classMethodRedeclaresAnotherClassMethod.py | 8 ++++++++ .../classMethodRedeclaresInstanceMethod.py | 7 +++++++ ...aticMethodRedeclaresAnotherStaticMethod.py | 8 ++++++++ .../staticMethodRedeclaresInstanceMethod.py | 7 +++++++ .../PyRedeclarationInspectionTest.java | 20 +++++++++++++++++++ 7 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresAnotherClassMethod.py create mode 100644 python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresInstanceMethod.py create mode 100644 python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresAnotherStaticMethod.py create mode 100644 python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresInstanceMethod.py diff --git a/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java b/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java index 7f4f1d93f58d..e5e421990a68 100644 --- a/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java @@ -71,7 +71,8 @@ public class PyRedeclarationInspection extends PyInspection { @Override public void visitPyFunction(final PyFunction node) { - if (!isDecorated(node)) { + if (!PyKnownDecoratorUtil.hasUnknownDecorator(node, myTypeEvalContext) && + !PyKnownDecoratorUtil.hasRedeclarationDecorator(node, myTypeEvalContext)) { processElement(node); } } diff --git a/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java b/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java index 096a4c435a39..169355f939c6 100644 --- a/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java +++ b/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java @@ -234,6 +234,10 @@ public class PyKnownDecoratorUtil { return ContainerUtil.exists(getKnownDecorators(function, context), GENERATOR_BASED_COROUTINE_DECORATORS::contains); } + public static boolean hasRedeclarationDecorator(@NotNull PyFunction function, @NotNull TypeEvalContext context) { + return getKnownDecorators(function, context).contains(TYPING_OVERLOAD); + } + private static boolean allDecoratorsAreKnown(@NotNull PyDecoratable element, @NotNull List decorators) { final PyDecoratorList decoratorList = element.getDecoratorList(); return decoratorList == null ? decorators.isEmpty() : decoratorList.getDecorators().length == decorators.size(); diff --git a/python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresAnotherClassMethod.py b/python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresAnotherClassMethod.py new file mode 100644 index 000000000000..0167125e97b6 --- /dev/null +++ b/python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresAnotherClassMethod.py @@ -0,0 +1,8 @@ +class TestClass: + @classmethod + def foo(cls): + print(0) + + @classmethod + def foo(cls): + print(1) \ No newline at end of file diff --git a/python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresInstanceMethod.py b/python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresInstanceMethod.py new file mode 100644 index 000000000000..62efb08d73e0 --- /dev/null +++ b/python/testData/inspections/PyRedeclarationInspection/classMethodRedeclaresInstanceMethod.py @@ -0,0 +1,7 @@ +class TestClass: + def foo(self): + print(0) + + @classmethod + def foo(cls): + print(1) \ No newline at end of file diff --git a/python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresAnotherStaticMethod.py b/python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresAnotherStaticMethod.py new file mode 100644 index 000000000000..6855cd08b3b0 --- /dev/null +++ b/python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresAnotherStaticMethod.py @@ -0,0 +1,8 @@ +class TestClass: + @staticmethod + def foo(): + print(0) + + @staticmethod + def foo(): + print(1) \ No newline at end of file diff --git a/python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresInstanceMethod.py b/python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresInstanceMethod.py new file mode 100644 index 000000000000..a23709494411 --- /dev/null +++ b/python/testData/inspections/PyRedeclarationInspection/staticMethodRedeclaresInstanceMethod.py @@ -0,0 +1,7 @@ +class TestClass: + def foo(self): + print(0) + + @staticmethod + def foo(): + print(1) \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyRedeclarationInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyRedeclarationInspectionTest.java index 259c27d8b845..138fd54dee72 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyRedeclarationInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyRedeclarationInspectionTest.java @@ -104,6 +104,26 @@ public class PyRedeclarationInspectionTest extends PyTestCase { doTest(); } + // PY-23552 + public void testStaticMethodRedeclaresInstanceMethod() { + doTest(); + } + + // PY-23552 + public void testClassMethodRedeclaresInstanceMethod() { + doTest(); + } + + // PY-23552 + public void testStaticMethodRedeclaresAnotherStaticMethod() { + doTest(); + } + + // PY-23552 + public void testClassMethodRedeclaresAnotherClassMethod() { + doTest(); + } + private void doTest() { final String path = "inspections/PyRedeclarationInspection/" + getTestName(true) + ".py";