From b0b03f3a45e76faa3933c2a56930d2bca4390c35 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Sat, 28 Jan 2017 21:49:31 +0300 Subject: [PATCH] Don't use function annotations in overridden functions in Python 2 Python stubs use Python 3 syntax so it could be the case that a Python 2 class inherits a Python 3 class. --- .../override/PyOverrideImplementUtil.java | 28 +++++++++++++++++-- .../testData/override/instanceCheck_after.py | 4 +-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index 80daf2a82261..83eec5eb2369 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -204,14 +204,38 @@ public class PyOverrideImplementUtil { pyFunctionBuilder.decorate(PyNames.PROPERTY); } } + final LanguageLevel level = LanguageLevel.forElement(pyClass); PyAnnotation anno = baseFunction.getAnnotation(); - if (anno != null) { + if (anno != null && level.isAtLeast(LanguageLevel.PYTHON30)) { pyFunctionBuilder.annotation(anno.getText()); } final TypeEvalContext context = TypeEvalContext.userInitiated(baseFunction.getProject(), baseFunction.getContainingFile()); final List baseParams = PyUtil.getParameters(baseFunction, context); for (PyParameter parameter : baseParams) { - pyFunctionBuilder.parameter(parameter.getText()); + final PyNamedParameter namedParameter = parameter.getAsNamed(); + if (namedParameter != null) { + final StringBuilder parameterBuilder = new StringBuilder(); + if (namedParameter.isPositionalContainer()) { + parameterBuilder.append("*"); + } + else if (namedParameter.isKeywordContainer()) { + parameterBuilder.append("**"); + } + parameterBuilder.append(namedParameter.getName()); + final PyAnnotation annotation = namedParameter.getAnnotation(); + if (annotation != null && level.isAtLeast(LanguageLevel.PYTHON30)) { + parameterBuilder.append(annotation.getText()); + } + final PyExpression defaultValue = namedParameter.getDefaultValue(); + if (defaultValue != null) { + parameterBuilder.append("="); + parameterBuilder.append(defaultValue.getText()); + } + pyFunctionBuilder.parameter(parameterBuilder.toString()); + } + else { + pyFunctionBuilder.parameter(parameter.getText()); + } } PyClass baseClass = baseFunction.getContainingClass(); diff --git a/python/testData/override/instanceCheck_after.py b/python/testData/override/instanceCheck_after.py index 41bea75888a8..fbebd1f526c1 100644 --- a/python/testData/override/instanceCheck_after.py +++ b/python/testData/override/instanceCheck_after.py @@ -1,3 +1,3 @@ class MyType(type): - def __instancecheck__(cls, instance): - return super(MyType, cls).__instancecheck__(instance) + def __instancecheck__(self, instance): + return super(MyType, self).__instancecheck__(instance)