diff --git a/python/src/com/jetbrains/python/PyNames.java b/python/src/com/jetbrains/python/PyNames.java index b55896b703e3..72f0645d9d4b 100644 --- a/python/src/com/jetbrains/python/PyNames.java +++ b/python/src/com/jetbrains/python/PyNames.java @@ -194,6 +194,7 @@ public class PyNames { // canonical names, not forced by interpreter public static final String CANONICAL_SELF = "self"; + public static final String BASESTRING = "basestring"; /** * Contains keywords as of CPython 2.5. diff --git a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java index 28e0aedcb2ee..de4107142087 100644 --- a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java +++ b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java @@ -5,7 +5,6 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiReference; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PyNames; @@ -332,7 +331,7 @@ public abstract class CompatibilityVisitor extends PyAnnotator { @Override public void visitPyPrintStatement(PyPrintStatement node) { super.visitPyPrintStatement(node); - if (myVersionsToProcess.contains(LanguageLevel.PYTHON30) || myVersionsToProcess.contains(LanguageLevel.PYTHON31)) { + if (shouldBeCompatibleWithPy3()) { boolean hasProblem = false; PsiElement[] arguments = node.getChildren(); for (PsiElement element : arguments) { @@ -400,6 +399,25 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } } + @Override + public void visitPyReferenceExpression(PyReferenceExpression node) { + super.visitPyElement(node); + if (shouldBeCompatibleWithPy3()) { + if (PyNames.BASESTRING.equals(node.getText())) { + PsiElement res = node.getReference().resolve(); + if (res != null) { + ProjectFileIndex ind = ProjectRootManager.getInstance(node.getProject()).getFileIndex(); + PsiFile file = res.getContainingFile(); + if (file != null && ind.isInLibraryClasses(file.getVirtualFile())) { + registerProblem(node, "basestring type is not available in py3"); + } + } else { + registerProblem(node, "basestring type is not available in py3"); + } + } + } + } + @Override public void visitPyCallExpression(PyCallExpression node) { super.visitPyCallExpression(node); @@ -422,31 +440,13 @@ public abstract class CompatibilityVisitor extends PyAnnotator { } commonRegisterProblem(message, " not support this syntax. super() should have arguments in Python 2", len, node, null); + } + private boolean shouldBeCompatibleWithPy3() { if (myVersionsToProcess.contains(LanguageLevel.PYTHON30) || myVersionsToProcess.contains(LanguageLevel.PYTHON31) - || myVersionsToProcess.contains(LanguageLevel.PYTHON32)) { - if (node.getCallee() != null && "isinstance".equals(node.getCallee().getText())) { - PyExpression[] args = node.getArguments(); - if (args.length > 1) { - PyExpression baseString = args[1]; - if ("basestring".equals(baseString.getText())) { - PsiReference ref = baseString.getReference(); - if (ref != null) { - PsiElement res = ref.resolve(); - if (res != null) { - ProjectFileIndex ind = ProjectRootManager.getInstance(node.getProject()).getFileIndex(); - PsiFile file = res.getContainingFile(); - if (file != null && ind.isInLibraryClasses(file.getVirtualFile())) { - registerProblem(baseString, "basestring type is not available in py3"); - } - } else { - registerProblem(baseString, "basestring type is not available in py3"); - } - } - } - } - } - } + || myVersionsToProcess.contains(LanguageLevel.PYTHON32)) + return true; + return false; } protected abstract void registerProblem(PsiElement node, String s, LocalQuickFix localQuickFix, boolean asError); diff --git a/python/testData/inspections/PyCompatibilityInspection/basestring.py b/python/testData/inspections/PyCompatibilityInspection/basestring.py new file mode 100644 index 000000000000..4d2a0c5209a1 --- /dev/null +++ b/python/testData/inspections/PyCompatibilityInspection/basestring.py @@ -0,0 +1,5 @@ +isinstance("str", basestring) +class basestring: + pass + +isinstance("str", basestring) \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java index 13d33888d677..a887888f0da8 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java @@ -102,6 +102,11 @@ public class PyCompatibilityInspectionTest extends PyLightFixtureTestCase { doTest(); } + public void testBasestring() { + doTest(); + } + + private void doTest() { myFixture.configureByFile("inspections/PyCompatibilityInspection/" + getTestName(true) + ".py"); myFixture.enableInspections(PyCompatibilityInspection.class);