From 3b991b20caacae9b0809b658b0a905e14d57ef7e Mon Sep 17 00:00:00 2001 From: Lada Gagina Date: Thu, 30 May 2019 14:36:50 +0300 Subject: [PATCH] PY-36009 Add support of '=' for debugging in f-strings GitOrigin-RevId: 79314512860158a4c535103ee2ac9fee43d30d0d --- .../jetbrains/python/formatter/PyBlock.java | 19 +- .../python/parsing/ExpressionParsing.java | 6 +- .../validation/CompatibilityVisitor.java | 11 + ...spacesAroundEqualsSignInFStringFragment.py | 8 + ...AroundEqualsSignInFStringFragment_after.py | 8 + .../equalitySignInFStrings.py | 3 + python/testData/psi/FStringEqualitySign.py | 19 ++ python/testData/psi/FStringEqualitySign.txt | 319 ++++++++++++++++++ .../com/jetbrains/python/PyFormatterTest.java | 5 + .../jetbrains/python/PythonParsingTest.java | 5 + .../PyCompatibilityInspectionTest.java | 5 + 11 files changed, 406 insertions(+), 2 deletions(-) create mode 100644 python/testData/formatter/spacesAroundEqualsSignInFStringFragment.py create mode 100644 python/testData/formatter/spacesAroundEqualsSignInFStringFragment_after.py create mode 100644 python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py create mode 100644 python/testData/psi/FStringEqualitySign.py create mode 100644 python/testData/psi/FStringEqualitySign.txt diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java index 9a627e37d3c2..11e6933ec6b4 100644 --- a/python/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/src/com/jetbrains/python/formatter/PyBlock.java @@ -28,6 +28,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PyTokenTypes; +import com.jetbrains.python.PythonDialectsTokenSetProvider; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyPsiUtils; import org.jetbrains.annotations.NotNull; @@ -446,7 +447,7 @@ public class PyBlock implements ASTBlock { if (TreeUtil.findParent(child, PyElementTypes.FSTRING_FRAGMENT) != null) { childWrap = Wrap.createWrap(WrapType.NONE, false); } - + return new PyBlock(this, child, childAlignment, childIndent, childWrap, myContext); } @@ -829,6 +830,10 @@ public class PyBlock implements ASTBlock { final IElementType childType2 = psi2.getNode().getElementType(); child2 = getSubBlockByNode(node2); + if (isInsideFStringFragmentWithEqualsSign(myNode)) { + return Spacing.getReadOnlySpacing(); + } + if ((childType1 == PyTokenTypes.EQ || childType2 == PyTokenTypes.EQ)) { final PyNamedParameter namedParameter = as(myNode.getPsi(), PyNamedParameter.class); if (namedParameter != null && namedParameter.getAnnotation() != null) { @@ -1171,4 +1176,16 @@ public class PyBlock implements ASTBlock { public boolean isLeaf() { return myNode.getFirstChildNode() == null; } + + private static final TokenSet stopAtTokens = TokenSet.orSet(TokenSet.create(PyElementTypes.FSTRING_NODE), + PythonDialectsTokenSetProvider.INSTANCE.getStatementTokens()); + + private static boolean isInsideFStringFragmentWithEqualsSign(@NotNull ASTNode node) { + final ASTNode fStringFragmentParent = node.getElementType() == PyElementTypes.FSTRING_FRAGMENT + ? node + : TreeUtil.findParent(node, TokenSet.create(PyElementTypes.FSTRING_FRAGMENT), + stopAtTokens); + if (fStringFragmentParent == null) return false; + return fStringFragmentParent.findChildByType(PyTokenTypes.EQ) != null; + } } diff --git a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java index 568af6d58d1a..4203ba3dc0b7 100644 --- a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java +++ b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java @@ -172,7 +172,8 @@ public class ExpressionParsing extends Parsing { PyTokenTypes.FSTRING_FRAGMENT_FORMAT_START, PyTokenTypes.FSTRING_FRAGMENT_END, PyTokenTypes.FSTRING_END, - PyTokenTypes.STATEMENT_BREAK)) { + PyTokenTypes.STATEMENT_BREAK, + PyTokenTypes.EQ)) { nextToken(); recovery = true; } @@ -183,6 +184,8 @@ public class ExpressionParsing extends Parsing { else { recoveryMarker.drop(); } + + matchToken(PyTokenTypes.EQ); final boolean hasTypeConversion = matchToken(PyTokenTypes.FSTRING_FRAGMENT_TYPE_CONVERSION); final boolean hasFormatPart = atToken(PyTokenTypes.FSTRING_FRAGMENT_FORMAT_START); if (hasFormatPart) { @@ -195,6 +198,7 @@ public class ExpressionParsing extends Parsing { errorMessage = "type conversion, " + errorMessage; } } + checkMatches(PyTokenTypes.FSTRING_FRAGMENT_END, errorMessage); marker.setCustomEdgeTokenBinders(null, CONSUME_COMMENTS_AND_SPACES_TO_LEFT); marker.done(PyElementTypes.FSTRING_FRAGMENT); diff --git a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java index ff54c9a57364..b6254b2a3a52 100644 --- a/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java +++ b/python/src/com/jetbrains/python/validation/CompatibilityVisitor.java @@ -691,4 +691,15 @@ public abstract class CompatibilityVisitor extends PyAnnotator { " not support positional-only parameters", node); } + + @Override + public void visitPyFStringFragment(PyFStringFragment node) { + super.visitPyFStringFragment(node); + + final ASTNode equalitySignInFStringFragment = node.getNode().findChildByType(PyTokenTypes.EQ); + if (equalitySignInFStringFragment != null) { + registerForAllMatchingVersions(level -> level.isOlderThan(LanguageLevel.PYTHON38) && registerForLanguageLevel(level), + " not support equality signs in f-strings", equalitySignInFStringFragment.getPsi()); + } + } } diff --git a/python/testData/formatter/spacesAroundEqualsSignInFStringFragment.py b/python/testData/formatter/spacesAroundEqualsSignInFStringFragment.py new file mode 100644 index 000000000000..2b3d0a47c7b1 --- /dev/null +++ b/python/testData/formatter/spacesAroundEqualsSignInFStringFragment.py @@ -0,0 +1,8 @@ +print(f'{ math.pi = :.2f }') +s1 = f'{math.pi = :.2f}' +s2 = f'{f"{3.1415=:.1f}":*^20}' +s3 = f'{ 0 == 1 }' +s4 = f'{ 12345 + x = }' +s5 = f'''{ + 3 + = }''' \ No newline at end of file diff --git a/python/testData/formatter/spacesAroundEqualsSignInFStringFragment_after.py b/python/testData/formatter/spacesAroundEqualsSignInFStringFragment_after.py new file mode 100644 index 000000000000..b5ac3de290c0 --- /dev/null +++ b/python/testData/formatter/spacesAroundEqualsSignInFStringFragment_after.py @@ -0,0 +1,8 @@ +print(f'{ math.pi = :.2f }') +s1 = f'{math.pi = :.2f}' +s2 = f'{f"{3.1415=:.1f}":*^20}' +s3 = f'{0 == 1}' +s4 = f'{ 12345 + x = }' +s5 = f'''{ + 3 + = }''' diff --git a/python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py b/python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py new file mode 100644 index 000000000000..d5212da63f0a --- /dev/null +++ b/python/testData/inspections/PyCompatibilityInspection/equalitySignInFStrings.py @@ -0,0 +1,3 @@ +import math +print(f'{math.pi =:.2f}') +print(f'{f"{3.1415=:.1f}":*^20}') \ No newline at end of file diff --git a/python/testData/psi/FStringEqualitySign.py b/python/testData/psi/FStringEqualitySign.py new file mode 100644 index 000000000000..34ec4dcabdb3 --- /dev/null +++ b/python/testData/psi/FStringEqualitySign.py @@ -0,0 +1,19 @@ +import math +s1 = f'{math.pi = :.2f}' +s2 = f'{f"{3.1415=:.1f}":*^20}' +s3 = f'{0 == 1}' +x = 'A string' +s4 = f'{x=!s}' +x = 2.71828 +s5 = f'{x=:.2f}' +s6 = f'{x=:}' +s7 = f'{x=!r:^20}' +s8 = f'{x=!s:^20}' +s9 = f'{x= !a:^20}' +s10 = f'{3 * x + 15=}' +pi = 'π' +s11 = f'alpha α {pi = } ω omega' +s12 = f'''{ + 3 + =}''' +s13 = f'{"="}' \ No newline at end of file diff --git a/python/testData/psi/FStringEqualitySign.txt b/python/testData/psi/FStringEqualitySign.txt new file mode 100644 index 000000000000..fd8ae03707a2 --- /dev/null +++ b/python/testData/psi/FStringEqualitySign.txt @@ -0,0 +1,319 @@ +PyFile:FStringEqualitySign.py + PyImportStatement + PsiElement(Py:IMPORT_KEYWORD)('import') + PsiWhiteSpace(' ') + PyImportElement:math + PyReferenceExpression: math + PsiElement(Py:IDENTIFIER)('math') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s1 + PsiElement(Py:IDENTIFIER)('s1') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {math.pi = :.2f} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: pi + PyReferenceExpression: math + PsiElement(Py:IDENTIFIER)('math') + PsiElement(Py:DOT)('.') + PsiElement(Py:IDENTIFIER)('pi') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_TEXT)('.2f') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s2 + PsiElement(Py:IDENTIFIER)('s2') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {f"{3.1415=:.1f}":*^20} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyStringLiteralExpression: {3.1415=:.1f} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f"') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyNumericLiteralExpression + PsiElement(Py:FLOAT_LITERAL)('3.1415') + PsiElement(Py:EQ)('=') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_TEXT)('.1f') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)('"') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_TEXT)('*^20') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s3 + PsiElement(Py:IDENTIFIER)('s3') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {0 == 1} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyBinaryExpression + PyNumericLiteralExpression + PsiElement(Py:INTEGER_LITERAL)('0') + PsiWhiteSpace(' ') + PsiElement(Py:EQEQ)('==') + PsiWhiteSpace(' ') + PyNumericLiteralExpression + PsiElement(Py:INTEGER_LITERAL)('1') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: A string + PsiElement(Py:SINGLE_QUOTED_STRING)(''A string'') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s4 + PsiElement(Py:IDENTIFIER)('s4') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {x=!s} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiElement(Py:EQ)('=') + PsiElement(Py:FSTRING_FRAGMENT_TYPE_CONVERSION)('!s') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyNumericLiteralExpression + PsiElement(Py:FLOAT_LITERAL)('2.71828') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s5 + PsiElement(Py:IDENTIFIER)('s5') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {x=:.2f} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiElement(Py:EQ)('=') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_TEXT)('.2f') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s6 + PsiElement(Py:IDENTIFIER)('s6') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {x=:} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiElement(Py:EQ)('=') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s7 + PsiElement(Py:IDENTIFIER)('s7') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {x=!r:^20} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiElement(Py:EQ)('=') + PsiElement(Py:FSTRING_FRAGMENT_TYPE_CONVERSION)('!r') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_TEXT)('^20') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s8 + PsiElement(Py:IDENTIFIER)('s8') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {x=!s:^20} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiElement(Py:EQ)('=') + PsiElement(Py:FSTRING_FRAGMENT_TYPE_CONVERSION)('!s') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_TEXT)('^20') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s9 + PsiElement(Py:IDENTIFIER)('s9') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {x= !a:^20} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PsiElement(Py:FSTRING_FRAGMENT_TYPE_CONVERSION)('!a') + PyFStringFragmentFormatPart + PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':') + PsiElement(Py:FSTRING_TEXT)('^20') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s10 + PsiElement(Py:IDENTIFIER)('s10') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {3 * x + 15=} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyBinaryExpression + PyBinaryExpression + PyNumericLiteralExpression + PsiElement(Py:INTEGER_LITERAL)('3') + PsiWhiteSpace(' ') + PsiElement(Py:MULT)('*') + PsiWhiteSpace(' ') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiWhiteSpace(' ') + PsiElement(Py:PLUS)('+') + PsiWhiteSpace(' ') + PyNumericLiteralExpression + PsiElement(Py:INTEGER_LITERAL)('15') + PsiElement(Py:EQ)('=') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: pi + PsiElement(Py:IDENTIFIER)('pi') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: π + PsiElement(Py:SINGLE_QUOTED_STRING)(''π'') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s11 + PsiElement(Py:IDENTIFIER)('s11') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: alpha α {pi = } ω omega + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PsiElement(Py:FSTRING_TEXT)('alpha α ') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyReferenceExpression: pi + PsiElement(Py:IDENTIFIER)('pi') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_TEXT)(' ω omega') + PsiElement(Py:FSTRING_END)(''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s12 + PsiElement(Py:IDENTIFIER)('s12') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: { + 3 + =} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'''') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PsiWhiteSpace('\n ') + PyNumericLiteralExpression + PsiElement(Py:INTEGER_LITERAL)('3') + PsiWhiteSpace('\n ') + PsiElement(Py:EQ)('=') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''''') + PsiWhiteSpace('\n') + PyAssignmentStatement + PyTargetExpression: s13 + PsiElement(Py:IDENTIFIER)('s13') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyStringLiteralExpression: {"="} + PyFormattedStringElement + PsiElement(Py:FSTRING_START)('f'') + PyFStringFragment + PsiElement(Py:FSTRING_FRAGMENT_START)('{') + PyStringLiteralExpression: = + PsiElement(Py:SINGLE_QUOTED_STRING)('"="') + PsiElement(Py:FSTRING_FRAGMENT_END)('}') + PsiElement(Py:FSTRING_END)(''') \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java index 18e31ff5366b..da922afd7515 100644 --- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java +++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java @@ -954,4 +954,9 @@ public class PyFormatterTest extends PyTestCase { public void testSpacesAroundFStringFragmentExpressionStripped() { runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest); } + + // PY-36009 + public void testSpacesAroundEqualsSignInFStringFragment() { + doTest(); + } } diff --git a/python/testSrc/com/jetbrains/python/PythonParsingTest.java b/python/testSrc/com/jetbrains/python/PythonParsingTest.java index da529b973460..1b4d6aee04b5 100644 --- a/python/testSrc/com/jetbrains/python/PythonParsingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonParsingTest.java @@ -901,6 +901,11 @@ public class PythonParsingTest extends ParsingTestCase { doTest(LanguageLevel.PYTHON38); } + // PY-36009 + public void testFStringEqualitySign() { + doTest(LanguageLevel.PYTHON37); + } + public void doTest() { doTest(LanguageLevel.PYTHON26); } diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java index b331df12110a..3828507ef1ce 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java @@ -215,6 +215,11 @@ public class PyCompatibilityInspectionTest extends PyInspectionTestCase { doTest(LanguageLevel.PYTHON34); } + // PY-36009 + public void testEqualitySignInFStrings() { + doTest(LanguageLevel.PYTHON38); + } + public void testInputFromSixLib() { doTest(LanguageLevel.PYTHON27); }