void () { assertEquals("f'{}'", doTestTyping("f''", 2, '{')); } public void testEnterInMultilineFStringFragment() { doTestEnter("f'''{1 +<caret> 2}'''", "f'''{1 +\n" + " 2}'''"); } public void testEnterInSingleLineFStringFragment() { doTestEnter("f'foo{1 +<caret> 2}bar'", "f'foo{1 +\n" + " 2}bar'"); } public void testEnterInFStringTextPart() { doTestEnter("f'foo<caret>bar'", "f'foo' \\\n" + "f'bar'"); } // PY-31984 public void testEnterInFStringRightBeforeFragment() { doTestEnter("f'foo<caret>{42}bar'", "f'foo' \\\n" + "f'{42}bar'"); } // PY-32918 public void testEnterInFStringRightBeforeClosingQuote() { doTestEnter("(f'foo{42}bar<caret>')", "(f'foo{42}bar'\n" + " f'')"); } // PY-32873 public void testEnterInTripleQuotedFStringRightBeforeClosingQuotes() { doTestEnter("f\"\"\"<caret>\"\"\"", "f\"\"\"\n" + "<caret>\"\"\""); } // PY-32864 public void testIndentationOfTripleQuotedFStringContent() { doTestEnter(""" if True: s = f""\" SELECT<caret> ""\"""", """ if True: s = f""\" SELECT <caret> ""\"""" ); } public void testOvertypeFromInside() { assertEquals("''", doTestTyping("''", 1, '\'')); } public void testGreedyBackspace() { // PY-254 final EditorSettingsExternalizable settings = EditorSettingsExternalizable.getInstance(); boolean oldVSpaceValue = settings.isVirtualSpace(); try { settings.setVirtualSpace(true); doTestBackspace("py254", new LogicalPosition(4, 8)); } finally { settings.setVirtualSpace(oldVSpaceValue); } } public void testUnindentBackspace() { // PY-853 doTestBackspace("smartUnindent", new LogicalPosition(1, 4)); } public void testUnindentTab() { // PY-1270 doTestBackspace("unindentTab", new LogicalPosition(4, 4)); } private void doTestBackspace(final String fileName, final LogicalPosition pos) { myFixture.configureByFile("/editing/" + fileName + ".before.py"); myFixture.getEditor().getCaretModel().moveToLogicalPosition(pos); pressButton(IdeActions.ACTION_EDITOR_BACKSPACE); myFixture.checkResultByFile("/editing/" + fileName + ".after.py", true); } private void doTestBackspace(final String before, final String after) { myFixture.configureByText(PythonFileType.INSTANCE, before); pressButton(IdeActions.ACTION_EDITOR_BACKSPACE); myFixture.checkResult(after); } public void testUncommentWithSpace() { // PY-980 myFixture.configureByFile("/editing/uncommentWithSpace.before.py"); myFixture.getEditor().getCaretModel().moveToLogicalPosition(new LogicalPosition(0, 1)); PlatformTestUtil.invokeNamedAction(IdeActions.ACTION_COMMENT_LINE); myFixture.checkResultByFile("/editing/uncommentWithSpace.after.py", true); } public void testEnterInLineComment() { // PY-1739 doTestEnter("# foo <caret>bar", "# foo \n# <caret>bar"); } public void testEnterInPrefixString() { // PY-5058 doTestEnter("s = r'some <caret>string'", "s = r'some ' \\\n" + " r'string'"); } public void testEnterInStringFormatting() { // PY-7039 doTestEnter("foo += \"fooba<caret>r\" % foo\n", """ foo += "fooba" \\ "r" % foo """); } public void testEnterInStatement() { doTestEnter("if a <caret>and b: pass", "if a \\\n and b: pass"); } public void testEnterBeforeStatement() { doTestEnter("def foo(): <caret>pass", "def foo(): \n pass"); } public void testEnterInParameterList() { doTestEnter("def foo(a,<caret>b): pass", "def foo(a,\n b): pass"); } public void testEnterInTuple() { doTestEnter("for x in 'a', <caret>'b': pass", "for x in 'a', \\\n 'b': pass"); } public void testEnterInCodeWithErrorElements() { doTestEnter("z=1 <caret>2", "z=1 \n2"); } public void testEnterAtStartOfComment() { // PY-1958 doTestEnter("# bar\n<caret># foo", "# bar\n\n# foo"); } public void testEnterAtEndOfComment() { // PY-1958 doTestEnter("# bar<caret>\n# foo", "# bar\n\n# foo"); } public void testEnterAfterBackslash() { // PY-1960 doTestEnter("s = \\<caret>\n'some string'", "s = \\\n\n'some string'"); } public void testEnterBetweenCommentAndStatement() { // PY-1958 doTestEnter("def test(a):\n <caret># some comment\n if a: return", "def test(a):\n \n # some comment\n if a: return"); } public void testEnterBetweenDecoratorAndFunction() { // PY-1985 doTestEnter("@foo\n<caret>def bar(x): pass", "@foo\n\ndef bar(x): pass"); } public void testEnterInSliceExpression() { // PY-1992 doTestEnter("a = some_list[<caret>slice_start:slice_end]", "a = some_list[\n slice_start:slice_end]"); } public void testEnterInSubscriptionExpression() { // PY-1992 doTestEnter("a = some_list[<caret>slice_start]", "a = some_list[\n slice_start]"); } public void testEnterBeforeComment() { // PY-2138 doTestEnter("def x():\n if foo():<caret>\n #bar\n baz()", "def x():\n if foo():\n \n #bar\n baz()"); } public void testEnterInEmptyFile() { // PY-2194 doTestEnter(" <caret>\n", " \n \n"); } public void testEnterInDocstring() { // CR-PY-144 doTestEnter(" def foo():\n \"\"\" some comment<caret>\"\"\"\n pass", " def foo():\n \"\"\" some comment\n \"\"\"\n pass"); } public void testEnterStubInDocstring() { // CR-PY-144 runWithDocStringFormat(DocStringFormat.PLAIN, () -> doTestEnter("def foo():\n \"\"\"<caret>", """ def foo(): ""\" \s ""\"""")); } // PY-18486 public void testTripleQuotesThenEnterInsertsDocstring() { doDocStringTypingTest("\"\"\"\n", DocStringFormat.REST); } public void testEnterDocStringStubInClass() { doDocStringTypingTest("\n", DocStringFormat.REST); } public void testEnterDocStringStubInFile() { doDocStringTypingTest("\n", DocStringFormat.REST); } // PY-16656 public void testEnterDocStringStubInFunctionWithSelf() { doDocStringTypingTest("\n", DocStringFormat.REST); } // PY-16656 public void testEnterDocStringStubInStaticMethodWithSelf() { doDocStringTypingTest("\n", DocStringFormat.REST); } // PY-16828 public void testEnterDocStringStubWithStringPrefix() { doDocStringTypingTest("\n", DocStringFormat.REST); } // PY-3421 public void testSpaceDocStringStubInFunction() { doDocStringTypingTest(" ", DocStringFormat.REST); } // PY-3421 public void testSpaceDocStringStubInFile() { doDocStringTypingTest(" ", DocStringFormat.REST); } // PY-3421 public void testSpaceDocStringStubInClass() { doDocStringTypingTest(" ", DocStringFormat.REST); } // PY-16765 public void testSectionIndentInsideGoogleDocString() { doDocStringTypingTest("\nparam", DocStringFormat.GOOGLE); } // PY-16765 public void testSectionIndentInsideGoogleDocStringCustomIndent() { getIndentOptions().INDENT_SIZE = 2; doDocStringTypingTest("\nparam", DocStringFormat.GOOGLE); } // PY-17183 public void testEnterDocstringStubWhenFunctionDocstringBelow() { doDocStringTypingTest("\n", DocStringFormat.GOOGLE); } // PY-17183 public void testEnterDocstringStubWhenClassDocstringBelow() { doDocStringTypingTest("\n", DocStringFormat.GOOGLE); } // PY-17183 public void testEnterNoDocstringStubWhenCodeExampleInDocstring() { doDocStringTypingTest("\n", DocStringFormat.GOOGLE); } // PY-15332 public void testEnterDocstringStubNoReturnTagForInit() { doDocStringTypingTest("\n", DocStringFormat.REST); } // PY-15532 public void testSpaceDocstringStubNoReturnSectionForInit() { final PyCodeInsightSettings codeInsightSettings = PyCodeInsightSettings.getInstance(); final boolean oldInsertTypeDocStub = codeInsightSettings.INSERT_TYPE_DOCSTUB; codeInsightSettings.INSERT_TYPE_DOCSTUB = true; try { doDocStringTypingTest(" ", DocStringFormat.GOOGLE); } finally { codeInsightSettings.INSERT_TYPE_DOCSTUB = oldInsertTypeDocStub; } } public void testEnterInString() { // PY-1738 doTestEnter("a = \"some <caret>string\"", "a = \"some \" \\\n" + " \"string\""); } public void testEnterInImportWithParens() { // PY-2661 doTestEnter("from django.http import (HttpResponse,<caret>)", "from django.http import (HttpResponse,\n" + " )"); } public void testEnterInKeyword() { doTestEnter("imp<caret>ort django.http", "imp\n" + "ort django.http"); } public void testEnterInIdentifier() { doTestEnter("import dja<caret>ngo.http", "import dja\n"+ "ngo.http"); } public void testEnterAfterStringPrefix() { doTestEnter("r<caret>\"string\"", "r\n"+ "\"string\""); } public void testEnterInStringInParenth() { doTestEnter("a = (\"str<caret>ing\")", "a = (\"str\"\n" + " \"ing\")"); } public void testEnterEscapedQuote() { doTestEnter("a = 'some \\<caret>' string'", "a = 'some \\'' \\\n" + " ' string'"); } public void testEnterEscapedBackslash() { doTestEnter("a = 'some \\\\<caret> string'", "a = 'some \\\\' \\\n" + " ' string'"); } public void testEnterAfterSlash() { doTestEnter("a = 'some \\<caret> string'", "a = 'some \\\n" + " string'"); } public void testStringFormatting() { doTestEnter("print (\"foo<caret> %s\" % 1)", "print (\"foo\"\n" + " \" %s\" % 1)"); } public void testEndOfStringInParenth() { doTestEnter("print (\"foo\"<caret>\n" + " \"bar\")", """ print ("foo" \s "bar")"""); } public void testSlashAfterSlash() { doTestEnter("a = a+\\<caret>b", "a = a+\\\n" + " b"); } public void testComprehensionInReturn() { doTestEnter("def dbl():\n" + " return (<caret>(a, a) for a in [])", """ def dbl(): return ( (a, a) for a in [])"""); } public void testParenthesizedInIf() { doTestEnter("if isinstance(bz_value, list) and <caret>(isinstance(bz_value[0], str)):\n" + " pass", """ if isinstance(bz_value, list) and \\ (isinstance(bz_value[0], str)): pass"""); } public void testEmptyStringInParenthesis() { doTestEnter("a = ('<caret>')", "a = (''\n" + " '')"); } public void testEmptyStringInParenthesis2() { doTestEnter("a = (''\n" + " <caret>'')", """ a = ('' \s '')"""); } public void testBracesInString() { doTestEnter("a = 'test(<caret>)'", "a = 'test(' \\\n" + " ')'"); } public void testEnterAfterDefKeywordInFunction() { doTestEnter("def <caret>func():\n" + " pass", """ def \\ func(): pass"""); } public void testEnterBeforeColonInFunction() { doTestEnter("def func()<caret>:\n" + " pass", """ def func()\\ : pass"""); } // PY-15469 public void testEnterBeforeArrowInFunction() { runWithLanguageLevel(LanguageLevel.PYTHON34, () -> doTestEnter("def func() <caret>-> int:\n" + " pass", """ def func() \\ -> int: pass""")); } // PY-15469 public void testEnterAfterArrowInFunction() { runWithLanguageLevel(LanguageLevel.PYTHON34, () -> doTestEnter("def func() -><caret> int:\n" + " pass", """ def func() ->\\ int: pass""")); } // PY-15469 public void testEnterDoesNotInsertSlashInsideArrow() { runWithLanguageLevel(LanguageLevel.PYTHON34, () -> doTestEnter("def func() -<caret>> int:\n" + " pass", """ def func() - > int: pass""")); } private void doTestEnter(String before, final String after) { doTestEnter(before, after, false); } private void doTestEnter(String before, final String after, boolean parenthesiseOnEnter) { boolean initialValue = PyCodeInsightSettings.getInstance().PARENTHESISE_ON_ENTER; try { PyCodeInsightSettings.getInstance().PARENTHESISE_ON_ENTER = parenthesiseOnEnter; int pos = before.indexOf("<caret>"); before = before.replace("<caret>", ""); doTestTyping(before, pos, '\n'); myFixture.checkResult(after); } finally { PyCodeInsightSettings.getInstance().PARENTHESISE_ON_ENTER = initialValue; } } // PY-21478 public void testContinuationIndentForFunctionArguments() { getPythonCodeStyleSettings().USE_CONTINUATION_INDENT_FOR_ARGUMENTS = true; doTestEnter("func(<caret>)", """ func( <caret> )"""); } // PY-20909 public void testContinuationIndentInEmptyListLiteral() { getPythonCodeStyleSettings().USE_CONTINUATION_INDENT_FOR_COLLECTION_AND_COMPREHENSIONS = true; doTestEnter("[<caret>]", """ [ <caret> ]"""); } // PY-20909 public void testContinuationIndentInEmptyDictLiteral() { getPythonCodeStyleSettings().USE_CONTINUATION_INDENT_FOR_COLLECTION_AND_COMPREHENSIONS = true; doTestEnter("{<caret>}", """ { <caret> }"""); } // PY-20909 public void testContinuationIndentInEmptyTupleLiteral() { getPythonCodeStyleSettings().USE_CONTINUATION_INDENT_FOR_COLLECTION_AND_COMPREHENSIONS = true; doTestEnter("(<caret>)", """ ( <caret> )"""); } // PY-21840 public void testEditInjectedRegexpFragmentWithLongUnicodeEscape() { myFixture.configureByText(PythonFileType.INSTANCE, "import re\n" + "re.compile(ur'\\U00010000<caret>')"); myFixture.type("t"); myFixture.checkResult("import re\n" + "re.compile(ur'\\U00010000t')"); } // PY-21697 public void testTripleQuotesInsideTripleQuotedStringLiteral() { // TODO an extra quote is inserted due to PY-21993 doTypingTest("'"); } private String doTestTyping(final String text, final int offset, final char character) { final PsiFile file = myFixture.configureByText(PythonFileType.INSTANCE, text); myFixture.getEditor().getCaretModel().moveToOffset(offset); myFixture.type(character); return myFixture.getDocument(file).getText(); } private String doTestTyping(final String text, final int offset, final String characters) { final PsiFile file = myFixture.configureByText(PythonFileType.INSTANCE, text); myFixture.getEditor().getCaretModel().moveToOffset(offset); myFixture.type(characters); return myFixture.getDocument(file).getText(); } private void doTestTyping(@NotNull String before, @NotNull String typedText, @NotNull String after) { myFixture.configureByText("a.py", before); myFixture.type(typedText); myFixture.checkResult(after); } private void doTypingTest(final char character) { final String testName = "editing/" + getTestName(true); myFixture.configureByFile(testName + ".py"); myFixture.type(character); myFixture.checkResultByFile(testName + ".after.py"); } private void doTypingTest(@NotNull String text) { final String testName = "editing/" + getTestName(true); myFixture.configureByFile(testName + ".py"); myFixture.type(text); myFixture.checkResultByFile(testName + ".after.py"); } private void doDocStringTypingTest(final String text, @NotNull DocStringFormat format) { runWithDocStringFormat(format, () -> doTypingTest(text)); } public void testFirstParamClassmethod() { doTypingTest('('); } public void testFirstParamMetaClass() { doTypingTest('('); } public void testFirstParamMetaNew() { doTypingTest('('); } public void testFirstParamMetaSimple() { doTypingTest('('); } public void testFirstParamSimpleInit() { doTypingTest('('); } public void testFirstParamSimpleNew() { doTypingTest('('); } public void testFirstParamSimple() { doTypingTest('('); } public void testFirstParamStaticmethod() { doTypingTest('('); } public void testFirstParamDuplicateColon() { // PY-2652 doTypingTest('('); } // PY-21269 public void testFirstParamMultipleMethods() { doTypingTest('('); } // PY-15240 public void testFirstParamSpacesInsideParentheses() { getCommonCodeStyleSettings().SPACE_WITHIN_METHOD_PARENTHESES = true; doTypingTest('('); } // PY-15240 public void testFirstParamSpacesInsideEmptyParentheses() { getCommonCodeStyleSettings().SPACE_WITHIN_EMPTY_METHOD_PARENTHESES = true; doTypingTest('('); } // PY-21289 public void testPairedParenthesesMultipleCalls() { doTypingTest('('); } public void testEnterBeforeString() { // PY-3673 doTestEnter("<caret>''", "\n''"); } public void testEnterInUnicodeString() { doTestEnter("a = u\"some <caret>text\"", "a = u\"some \" \\\n" + " u\"<caret>text\""); } public void testBackslashInParenthesis() { // PY-5106 doTestEnter("(\"some <caret>string\", 1)", "(\"some \"\n" + " \"string\", 1)"); } // PY-15609 public void testEnterInStringInTupleWithoutParenthesis() { doTestEnter("def hello_world():\n" + " return bar, 'so<caret>me'", """ def hello_world(): return bar, 'so' \\ 'me'"""); } // PY-27178 public void testIncompleteFunctionTypeComment() { doTypingTest('.'); } // PY-10972 public void testEnterInIncompleteTupleLiteral() { doTypingTest("\n'baz'"); } // PY-10972 public void testEnterInIncompleteListLiteral() { doTypingTest("\n'baz'"); } // PY-10972 public void testEnterInIncompleteSetLiteral() { doTypingTest("\n'baz'"); } // PY-10972 public void testEnterInIncompleteDictLiteral() { doTypingTest("\n'baz'"); } // PY-10972 public void testEnterInIncompleteGluedStringLiteralInParentheses() { doTypingTest("\n'bar'"); } // PY-10972 public void testEnterInIncompleteListComprehension() { doTypingTest("\nfoo"); } // PY-10972 public void testEnterInIncompleteSetComprehension() { doTypingTest("\nfoo"); } // PY-10972 public void testEnterInIncompleteDictComprehension() { doTypingTest("\nfoo"); } // PY-10972 public void testEnterInIncompleteParenthesizedGenerator() { doTypingTest("\nfoo"); } // PY-10972 public void testEnterInIncompleteNestedListLiteral() { doTypingTest("\n'baz'"); } // PY-10972 public void testEnterInIncompleteNestedTupleLiteral() { doTypingTest("\n'baz'"); } // PY-10972 public void testEnterInIncompleteNestedGluedStringInParentheses() { doTypingTest("\n'baz'"); } public void testTabOutFromStringLiteral() { boolean savedValue = CodeInsightSettings.getInstance().TAB_EXITS_BRACKETS_AND_QUOTES; CodeInsightSettings.getInstance().TAB_EXITS_BRACKETS_AND_QUOTES = true; try { myFixture.configureByText(getTestName(true) + ".py", "def some():\n" + " print<caret>"); myFixture.type("(\""); myFixture.performEditorAction(IdeActions.ACTION_BRACE_OR_QUOTE_OUT); myFixture.checkResult("def some():\n" + " print(\"\"<caret>)"); myFixture.performEditorAction(IdeActions.ACTION_BRACE_OR_QUOTE_OUT); myFixture.checkResult("def some():\n" + " print(\"\")<caret>"); } finally { CodeInsightSettings.getInstance().TAB_EXITS_BRACKETS_AND_QUOTES = savedValue; } } // PY-31343 public void testInsertingColonRightBeforeParametersClosingParenthesisAtMultipleCarets() { doTestTyping(""" def alpha(foo<caret>): pass def bravo(foo<caret>): pass""", ":", """ def alpha(foo:): pass def bravo(foo:): pass"""); } public void testOverTypingColon() { doTestTyping("def func()<caret>: pass", ":", "def func():<caret> pass"); } public void testOverTypingColonInStringLiteral() { doTestTyping("s = 'def func()<caret>: pass'", ":", "s = 'def func():<caret>: pass'"); } public void testOverTypingColonInFStringFragment() { doTestTyping("s = f'{(lambda<caret>: 42)}'", ":", "s = f'{(lambda:<caret> 42)}'"); } public void testOverTypingFormatStartInFStringFragment() { doTestTyping("s = f'{42<caret>:3d}'", ":", "s = f'{42:<caret>:3d}'"); } // PY-48009 public void testEnterAfterColonOfMatchStatementWithoutClauses() { doTypingTest('\n'); } // PY-48009 public void testEnterAfterColonOfMatchStatementWithClauses() { doTypingTest('\n'); } // PY-48009 public void testEnterAfterColonOfCaseClauseWithoutBody() { doTypingTest('\n'); } // PY-48009 public void testEnterAfterColonOfCaseClauseWithBody() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInGroupPattern() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInClassPattern() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInSequencePattern() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInMappingPattern() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInStringLiteralInsideGroupPattern() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInStringLiteralInsideClassPattern() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInStringLiteralInsideSequencePattern() { doTypingTest('\n'); } // PY-49080 public void testNoBackslashOnEnterInStringLiteralInsideMappingPattern() { doTypingTest('\n'); } // PY-49080 public void testBackslashOnEnterInTopLevelStringLiteralPattern() { doTestEnter(""" match x: case 'foo<caret>bar': pass """, """ match x: case 'foo' \\ '<caret>bar': pass """ ); } // PY-42200 public void testParenthesizedWithItemsEnterBeforeExistingItem() { doTestEnter(""" with (<caret>foo() as baz, foo() as bar ): pass""", """ with ( foo() as baz, foo() as bar ): pass"""); doTestEnter(""" with ( foo() as baz,<caret>foo() as bar ): pass""", """ with ( foo() as baz, foo() as bar ): pass"""); doTestEnter("with (foo() as baz,<caret>foo() as bar):\n" + " pass", """ with (foo() as baz, foo() as bar): pass"""); } // PY-42200 public void testParenthesizedWithItemsEnterBeforeClosingParenthesis() { doTestEnter(""" with (foo(),\s foo()<caret>): pass""", """ with (foo(),\s foo() <caret>): pass"""); getPythonCodeStyleSettings().HANG_CLOSING_BRACKETS = false; doTestEnter(""" with ( foo() as baz, foo() as bar<caret>): pass""", """ with ( foo() as baz, foo() as bar ): pass"""); getPythonCodeStyleSettings().HANG_CLOSING_BRACKETS = true; doTestEnter(""" with ( foo() as baz, foo() as bar<caret>): pass""", """ with ( foo() as baz, foo() as bar ): pass"""); } // PY-42200 public void testParenthesizedWithItemsEnterBeforeNonExistingItem() { doTestEnter(""" with (foo(),<caret> bar()): pass""", """ with (foo(), <caret> bar()): pass"""); doTestEnter(""" with ( foo(),<caret> bar() ): pass""", """ with ( foo(), <caret> bar() ): pass"""); } // PY-42200 public void testParenthesizedWithItemsEnterBeforeComment() { doTestEnter(""" with ( foo(),<caret># comment bar() ): pass""", """ with ( foo(), <caret># comment bar() ): pass"""); doTestEnter(""" with (foo(),<caret># comment bar()): pass""", """ with (foo(), <caret># comment bar()): pass"""); } // PY-42200 public void testParenthesizedWithItemsEnterBeforeStatementList() { doTestEnter("with (foo(), foo()):<caret>", "with (foo(), foo()):\n" + " <caret>"); } public void testParenthesiseBinaryExpression() { doTestEnter( """ x = a + b + <caret>c + d """, """ x = (a + b +\s c + d) """, true); } public void testParenthesiseImportStatement() { doTestEnter( """ from collections import Hashable, Iterable, <caret>KeysView, Mapping, MutableMapping """, """ from collections import (Hashable, Iterable,\s KeysView, Mapping, MutableMapping) """, true); } public void testParenthesiseCallChain() { doTestEnter( """ result = str.capitalize()<caret>.foo().bar().baz() """, """ result = (str.capitalize() .foo().bar().baz()) """, true); } public void testParenthesiseConditionalExpression() { doTestEnter( """ x = 3 if a == 10 or<caret> b == 13 or c < 4 else 3 """, """ x = 3 if (a == 10 or b == 13 or c < 4) else 3 """, true); } public void testParenthesiseTupleExpression() { doTestEnter( """ for x in 'a',<caret> 'b', 'c': pass """, """ for x in ('a', 'b', 'c'): pass """, true); } public void testParenthesiseString() { doTestEnter( """ s = "str<caret>ing" """, """ s = ("str" "ing") """, true); } public void testStringNotParenthesisedRepeatedly() { doTestEnter( """ s = ("str<caret>ing") """, """ s = ("str" "ing") """, true); } public void testParenthesiseUnicodeString() { doTestEnter( """ s = u"uni<caret>code" """, """ s = (u"uni" u"code") """, true); } public void testParenthesiseEscapedQuote() { doTestEnter( """ a = 'some \\<caret>' string' """, """ a = ('some \\'' ' string') """, true); } public void testParenthesiseSequencePattern() { doTestEnter( """ match (1, 2): case int(),<caret> int(): pass """, """ match (1, 2): case (int(), int()): pass """, true); } public void testParenthesiseAttributeAccessInCallChain() { doTestEnter( """ C().m().m().m()<caret>.attr """, """ (C().m().m().m() .attr) """, true); } public void testParenthesiseWithStatement() { doTestEnter( """ with open('foo.txt') as foo, <caret>open('bar.txt') as bar: pass """, """ with (open('foo.txt') as foo,\s open('bar.txt') as bar): pass """, true); } // PY-61854 public void testEnterInsideTypeParameterListInTypeAliasStatement() { doTestEnter( """ type myType[A, B, C,<caret> D, E, F] = None """, """ type myType[A, B, C, D, E, F] = None """); } // PY-61854 public void testEnterInsideTypeParameterListInFunctionDeclaration() { doTestEnter( """ def foo[A, B, C,<caret> D, E, F](): pass """, """ def foo[A, B, C, D, E, F](): pass """); } // PY-61854 public void testEnterInsideTypeParameterListInClassDeclaration() { doTestEnter( """ class Clazz[A, B, C,<caret> D, E, F]: pass """, """ class Clazz[A, B, C, D, E, F]: pass """); } @NotNull private PyCodeStyleSettings getPythonCodeStyleSettings() { return getCodeStyleSettings().getCustomSettings(PyCodeStyleSettings.class); } }