diff --git a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java index 6220133d98ee..e8acbb991e62 100644 --- a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java +++ b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java @@ -216,10 +216,16 @@ public abstract class CompatibilityVisitor extends PyAnnotator { public void visitPyStringLiteralExpression(final PyStringLiteralExpression node) { super.visitPyStringLiteralExpression(node); + boolean seenBytes = false; + boolean seenNonBytes = false; for (PyStringElement element : node.getStringElements()) { final String prefix = element.getPrefix().toUpperCase(); if (prefix.isEmpty()) continue; + final boolean bytes = element.isBytes(); + seenBytes |= bytes; + seenNonBytes |= !bytes; + final int elementStart = element.getTextOffset(); registerForAllMatchingVersions(level -> !getSupportedStringPrefixes(level).contains(prefix), " not support a '" + prefix + "' prefix", @@ -228,6 +234,13 @@ public abstract class CompatibilityVisitor extends PyAnnotator { new RemovePrefixQuickFix(prefix), true); } + + if (seenBytes && seenNonBytes) { + registerForAllMatchingVersions(LanguageLevel::isPy3K, + " not allow to mix bytes and non-bytes literals", + node, + null); + } } @NotNull diff --git a/python/testData/highlighting/mixedBytesAndNonBytes.py b/python/testData/highlighting/mixedBytesAndNonBytes.py new file mode 100644 index 000000000000..cb5389001d8e --- /dev/null +++ b/python/testData/highlighting/mixedBytesAndNonBytes.py @@ -0,0 +1,3 @@ +b'qwe'u'asd' +b'qwe'r'asd' +b'qwe'f'asd' \ No newline at end of file diff --git a/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py b/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py index 8c2b46f5ee61..e36ebcc2df16 100644 --- a/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py +++ b/python/testData/inspections/PyCompatibilityInspection/stringLiteralExpression.py @@ -45,8 +45,10 @@ a = u"" a = r"" a = ur"" -# combined -b = u"" b"" +# combined, PY-32321 +b = u"" b"" +b = r"" b"" +b = f"" b"" # never was available a = rr"" diff --git a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java index 26f01065f8d1..333295c65d30 100644 --- a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java @@ -411,6 +411,11 @@ public class PythonHighlightingTest extends PyTestCase { doTest(LanguageLevel.PYTHON36, false, false); } + // PY-32321 + public void testMixedBytesAndNonBytes() { + doTest(LanguageLevel.PYTHON36, false, false); + } + @NotNull private static EditorColorsScheme createTemporaryColorScheme() { EditorColorsManager manager = EditorColorsManager.getInstance();