diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/ConvertFormatOperatorToMethodIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/ConvertFormatOperatorToMethodIntention.java index 3df0a3edf390..0ba35edad8bf 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/ConvertFormatOperatorToMethodIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/ConvertFormatOperatorToMethodIntention.java @@ -290,7 +290,10 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction } } else target.append("(").append(paramText).append(")"); // tuple is ok as is - element.replace(elementGenerator.createExpressionFromText(LanguageLevel.forElement(element), target.toString())); + // Correctly handle multiline implicitly concatenated string literals (PY-9176) + target.insert(0, '(').append(')'); + final PyExpression parenthesized = elementGenerator.createExpressionFromText(LanguageLevel.forElement(element), target.toString()); + element.replace(sure(((PyParenthesizedExpression)parenthesized).getContainedExpression())); } private static String getSeparator(PyStringLiteralExpression leftExpression) { diff --git a/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/concatenated.py b/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/concatenated.py new file mode 100644 index 000000000000..9ba6589ffc37 --- /dev/null +++ b/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/concatenated.py @@ -0,0 +1,2 @@ +print('%(quantity)s pounds of ' + '%(type)s' % dict(quantity=42, type='spam')) \ No newline at end of file diff --git a/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/concatenated_after.py b/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/concatenated_after.py new file mode 100644 index 000000000000..804f15ca373d --- /dev/null +++ b/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/concatenated_after.py @@ -0,0 +1,2 @@ +print('{quantity:s} pounds of ' + '{type:s}'.format(quantity=42, type='spam')) \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/intentions/PyConvertFormatOperatorToMethodIntentionTest.java b/python/testSrc/com/jetbrains/python/intentions/PyConvertFormatOperatorToMethodIntentionTest.java index 3dfa4a39bc85..833f71e8452a 100644 --- a/python/testSrc/com/jetbrains/python/intentions/PyConvertFormatOperatorToMethodIntentionTest.java +++ b/python/testSrc/com/jetbrains/python/intentions/PyConvertFormatOperatorToMethodIntentionTest.java @@ -38,4 +38,9 @@ public class PyConvertFormatOperatorToMethodIntentionTest extends PyIntentionTes public void testUnicode() { doTest(PyBundle.message("INTN.replace.with.method"), LanguageLevel.PYTHON26); } + + // PY-9176 + public void testConcatenated() { + doTest(PyBundle.message("INTN.replace.with.method"), LanguageLevel.PYTHON26); + } } \ No newline at end of file