From 8cee7ea9a9d79e5152f0436efc4a1ce50c8b38d7 Mon Sep 17 00:00:00 2001 From: Dmitry Cheryasov Date: Sun, 5 Sep 2010 15:36:17 +0300 Subject: [PATCH] Inspection to warn about decorators nested over @{class,static}method. --- .../com/jetbrains/python/PyBundle.properties | 4 ++ .../PythonInspectionToolProvider.java | 3 +- .../PyNestedDecoratorsInspection/expected.xml | 28 ++++++++++ .../src/decorated.py | 51 +++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 python/testData/inspections/PyNestedDecoratorsInspection/expected.xml create mode 100644 python/testData/inspections/PyNestedDecoratorsInspection/src/decorated.py diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index d63ed09108c6..23a04dd1e616 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -135,6 +135,10 @@ INSP.usually.named.self=Usually first parameter of a method is named 'self' INSP.usually.named.cls=Usually first parameter of such methods is named 'cls' INSP.first.param.must.not.be.tuple=First parameter of a non-static method must not be a tuple +# PyNestedDecoratorsInspection +INSP.NAME.nested.decorators=Problematic nesting of decorators +INSP.decorator.receives.unexpected.builtin=This decorator will not receive a callable it may expect; the built-in decorator returns a special object + # PyRedeclarationInspection INSP.NAME.redeclaration=Names redeclared without usage INSP.shadows.same.named.$0.above=Shadows same-named {0} above diff --git a/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java b/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java index 0ca08d2fe75c..25f69bb19edd 100644 --- a/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java +++ b/python/src/com/jetbrains/python/inspections/PythonInspectionToolProvider.java @@ -43,7 +43,8 @@ public class PythonInspectionToolProvider implements InspectionToolProvider { PyCallingNonCallableInspection.class, PyPropertyAccessInspection.class, PyPropertyDefinitionInspection.class, - PyInconsistentIndentationInspection.class + PyInconsistentIndentationInspection.class, + PyNestedDecoratorsInspection.class, }; } } diff --git a/python/testData/inspections/PyNestedDecoratorsInspection/expected.xml b/python/testData/inspections/PyNestedDecoratorsInspection/expected.xml new file mode 100644 index 000000000000..6a34b87af84e --- /dev/null +++ b/python/testData/inspections/PyNestedDecoratorsInspection/expected.xml @@ -0,0 +1,28 @@ + + + + decorated.py + 25 + This decorator will not receive a callable it may expect; the built-in decorator returns a special object + + + decorated.py + 30 + This decorator will not receive a callable it may expect; the built-in decorator returns a special object + + + decorated.py + 35 + This decorator will not receive a callable it may expect; the built-in decorator returns a special object + + + decorated.py + 40 + This decorator will not receive a callable it may expect; the built-in decorator returns a special object + + + decorated.py + 47 + This decorator will not receive a callable it may expect; the built-in decorator returns a special object + + diff --git a/python/testData/inspections/PyNestedDecoratorsInspection/src/decorated.py b/python/testData/inspections/PyNestedDecoratorsInspection/src/decorated.py new file mode 100644 index 000000000000..0ab1114e90e3 --- /dev/null +++ b/python/testData/inspections/PyNestedDecoratorsInspection/src/decorated.py @@ -0,0 +1,51 @@ +def innocent(f): + "A transparent deco" + print("I'm innocent!") + return f + +class A(object): + def f1(self): # nothing + pass + + @innocent + @innocent + def f2(cls): # nothing + pass + + @classmethod + @innocent + def f2(cls): # nothing + pass + + @staticmethod + @innocent + def f4(): # nothing + pass + + @innocent # warn + @classmethod + def f3(cls): + pass + + @innocent # warn + @staticmethod + def f5(): + pass + + @classmethod # warn + @staticmethod + def f2(cls): + pass + + @innocent # warn + @classmethod + @innocent + def f2(cls): + pass + + @innocent + @innocent # warn + @classmethod + @innocent + def f2(cls): + pass