PY-20844 PY-20773 Warn about '#' signs and backslashes inside f-strings
authorMikhail Golubev <mikhail.golubev@jetbrains.com>
Thu, 22 Sep 2016 12:39:39 +0000 (15:39 +0300)
committerMikhail Golubev <mikhail.golubev@jetbrains.com>
Mon, 26 Sep 2016 06:09:23 +0000 (09:09 +0300)
python/src/com/jetbrains/python/validation/FStringsAnnotator.java
python/testData/highlighting/fStringBackslashes.py [new file with mode: 0644]
python/testData/highlighting/fStringHashSigns.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/PythonHighlightingTest.java

index fe30e47388ad043ea3841d123053b708e6f4647e..3a44844937368276940145df4504b506cbc06e16 100644 (file)
@@ -49,6 +49,15 @@ public class FStringsAnnotator extends PyAnnotator {
           if (fragment.getRightBraceOffset() == -1) {
             hasUnclosedBrace = true;
           }
+          for (int i = fragment.getLeftBraceOffset() + 1; i < fragment.getContentEndOffset(); i++) {
+            final char c = nodeText.charAt(i);
+            if (c == '\\') {
+              reportCharacter(nodeOffset + i, "Expression fragments inside f-strings cannot include backslashes");
+            }
+            else if (c == '#') {
+              reportCharacter(nodeOffset + i, "Expressions fragments inside f-strings cannot include '#'");
+            }
+          }
           // Do not warn about illegal conversion character if '!' is right before closing quotes 
           if (fragContentEnd < nodeContentEnd && nodeText.charAt(fragContentEnd) == '!' && fragContentEnd + 1 < nodeContentEnd) {
             final char conversionChar = nodeText.charAt(fragContentEnd + 1);
diff --git a/python/testData/highlighting/fStringBackslashes.py b/python/testData/highlighting/fStringBackslashes.py
new file mode 100644 (file)
index 0000000..3713a5e
--- /dev/null
@@ -0,0 +1,5 @@
+f'{<error descr="Expression fragments inside f-strings cannot include backslashes">\</error>t}'
+f'{<error descr="Expression fragments inside f-strings cannot include backslashes">\</error>t<error descr="'}' is expected"></error>'
+f'{<error descr="Expression fragments inside f-strings cannot include backslashes">\</error>N{GREEK SMALL LETTER ALPHA}}'
+f'{Formatable():\n\t}'
+f'{42:{<error descr="Expression fragments inside f-strings cannot include backslashes">\</error>t}}'
\ No newline at end of file
diff --git a/python/testData/highlighting/fStringHashSigns.py b/python/testData/highlighting/fStringHashSigns.py
new file mode 100644 (file)
index 0000000..6201d36
--- /dev/null
@@ -0,0 +1,5 @@
+f'{<error descr="Expressions fragments inside f-strings cannot include '#'">#<error descr="'}' is expected"></error></error>'
+<error descr="Missing closing quote [']">f'{<error descr="Expressions fragments inside f-strings cannot include '#'">#<error descr="'}' is expected"></error></error></error>
+f'{<error descr="Expressions fragments inside f-strings cannot include '#'">#</error>foo<error descr="Expressions fragments inside f-strings cannot include '#'">#</error>}'
+f'{42:#}'
+f'{42:{<error descr="Expressions fragments inside f-strings cannot include '#'">#</error>}}'
\ No newline at end of file
index d6d5e88c11dbf74f4de06aa4d771d165d2155b59..1c5f58aa50a59427f279351305f811c508ea22a1 100644 (file)
@@ -320,6 +320,16 @@ public class PythonHighlightingTest extends PyTestCase {
     runWithLanguageLevel(LanguageLevel.PYTHON36, () -> doTest(true, false));
   }
 
+  // PY-20773
+  public void testFStringHashSigns() {
+    runWithLanguageLevel(LanguageLevel.PYTHON36, () -> doTest(true, false));
+  }
+  
+  // PY-20844
+  public void testFStringBackslashes() {
+    runWithLanguageLevel(LanguageLevel.PYTHON36, () -> doTest(true, false));
+  }
+  
   // ---
   private void doTest(final LanguageLevel languageLevel, final boolean checkWarnings, final boolean checkInfos) {
     PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), languageLevel);