diff --git a/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java b/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java index 223de92ae5d4..4e2bbd10f85c 100644 --- a/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java +++ b/python/python-common-tests/com/jetbrains/python/PythonCommonFormatterTest.java @@ -1570,4 +1570,11 @@ public abstract class PythonCommonFormatterTest extends PythonCommonTestCase { getCodeStyleSettings().CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; doTest(); } + + // PY-31689 + public void testDoNotWrapListsAndTuplesInsideSubscriptionExpressions() { + getPythonCodeStyleSettings().TUPLE_WRAPPING = CommonCodeStyleSettings.WRAP_ALWAYS; + getPythonCodeStyleSettings().LIST_WRAPPING = CommonCodeStyleSettings.WRAP_ALWAYS; + doTest(); + } } diff --git a/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java b/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java index ef26d5c4613f..810c02c5af15 100644 --- a/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/python-syntax-core/src/com/jetbrains/python/formatter/PyBlock.java @@ -513,13 +513,13 @@ public class PyBlock implements ASTBlock { if (childType != PyTokenTypes.COMMA && childType != PyTokenTypes.END_OF_LINE_COMMENT) { // (...) if (childType != PyTokenTypes.LPAR && childType != PyTokenTypes.RPAR) { - if (parentType == PyElementTypes.TUPLE_EXPRESSION) return myTupleWrapping; if (parentType == PyElementTypes.PARAMETER_LIST) return myParameterListWrapping; if (parentType == PyElementTypes.ARGUMENT_LIST) return myArgumentListWrapping; + if (parentType == PyElementTypes.TUPLE_EXPRESSION && !isInsideSubscriptionExpression(child)) return myTupleWrapping; } // [...] if (childType != PyTokenTypes.LBRACKET && childType != PyTokenTypes.RBRACKET) { - if (parentType == PyElementTypes.LIST_LITERAL_EXPRESSION) return myListWrapping; + if (parentType == PyElementTypes.LIST_LITERAL_EXPRESSION && !isInsideSubscriptionExpression(child)) return myListWrapping; } // {...} if (childType != PyTokenTypes.LBRACE && childType != PyTokenTypes.RBRACE) { @@ -532,6 +532,10 @@ public class PyBlock implements ASTBlock { return childWrap; } + private static boolean isInsideSubscriptionExpression(ASTNode child) { + return PsiTreeUtil.getParentOfType(child.getPsi(), PyAstSubscriptionExpression.class) != null; + } + private static boolean isInsideWithStatementParentheses(@NotNull ASTNode withStatement, @NotNull ASTNode node) { ASTNode openingParenthesis = withStatement.findChildByType(PyTokenTypes.LPAR); if (openingParenthesis == null) { diff --git a/python/testData/formatter/doNotWrapListsAndTuplesInsideSubscriptionExpressions.py b/python/testData/formatter/doNotWrapListsAndTuplesInsideSubscriptionExpressions.py new file mode 100644 index 000000000000..836d312cac11 --- /dev/null +++ b/python/testData/formatter/doNotWrapListsAndTuplesInsideSubscriptionExpressions.py @@ -0,0 +1,2 @@ +Callable[[str, int, Iterator[str]], bool] +ParamSpec[(str, int, bool, Iterator[str])] diff --git a/python/testData/formatter/doNotWrapListsAndTuplesInsideSubscriptionExpressions_after.py b/python/testData/formatter/doNotWrapListsAndTuplesInsideSubscriptionExpressions_after.py new file mode 100644 index 000000000000..836d312cac11 --- /dev/null +++ b/python/testData/formatter/doNotWrapListsAndTuplesInsideSubscriptionExpressions_after.py @@ -0,0 +1,2 @@ +Callable[[str, int, Iterator[str]], bool] +ParamSpec[(str, int, bool, Iterator[str])]