From ecfced5e8fd166dd5a4f081a0f3f2f32a411997d Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Fri, 15 Aug 2025 17:09:07 +0300 Subject: [PATCH] PY-63319 Fix inverting comparisons in conditions when the left operand doesn't belong to a chained comparison GitOrigin-RevId: 75b988b6c53bd15d0001ede1f2ebc71153b1de5b --- .../src/com/jetbrains/python/codeInsight/ConditionUtil.kt | 2 +- .../nonChainableBinaryExpressionAsComparisonLeftOperand.py | 3 +++ ...ChainableBinaryExpressionAsComparisonLeftOperand_after.py | 4 ++++ .../python/intentions/PyInvertIfConditionIntentionTest.kt | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand.py create mode 100644 python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand_after.py diff --git a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/ConditionUtil.kt b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/ConditionUtil.kt index 280e588c019b..f2c5a2e0cad7 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/ConditionUtil.kt +++ b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/ConditionUtil.kt @@ -207,7 +207,7 @@ private fun getInvertedConditionExpression( val chainedExpressions = mutableListOf() var currentExpression = expression while (currentExpression is PyBinaryExpression && comparisonStrings.containsKey(currentExpression.operator)) { - val leftExpression = (currentExpression.leftExpression as? PyBinaryExpression)?.rightExpression + val leftExpression = (currentExpression.leftExpression as? PyBinaryExpression)?.takeIf { comparisonStrings.containsKey(it.operator) }?.rightExpression ?: currentExpression.leftExpression val invertedOperator = invertedComparisons.getValue(currentExpression.operator) val invertedExpression = generator.createBinaryExpression( diff --git a/python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand.py b/python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand.py new file mode 100644 index 000000000000..b4bf577553f4 --- /dev/null +++ b/python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand.py @@ -0,0 +1,3 @@ +def func(): + if 4 - 3 == 1: + print("hi") \ No newline at end of file diff --git a/python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand_after.py b/python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand_after.py new file mode 100644 index 000000000000..908007372615 --- /dev/null +++ b/python/testData/intentions/PyInvertIfConditionIntentionTest/nonChainableBinaryExpressionAsComparisonLeftOperand_after.py @@ -0,0 +1,4 @@ +def func(): + if 4 - 3 != 1: + return + print("hi") \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/intentions/PyInvertIfConditionIntentionTest.kt b/python/testSrc/com/jetbrains/python/intentions/PyInvertIfConditionIntentionTest.kt index 761157eabdc2..c1de38ffd826 100644 --- a/python/testSrc/com/jetbrains/python/intentions/PyInvertIfConditionIntentionTest.kt +++ b/python/testSrc/com/jetbrains/python/intentions/PyInvertIfConditionIntentionTest.kt @@ -495,6 +495,11 @@ class PyInvertIfConditionIntentionTest : PyIntentionTestCase() { doTest() } + // PY-63319 + fun testNonChainableBinaryExpressionAsComparisonLeftOperand() { + doTest() + } + private fun doTest() { doIntentionTest(PyPsiBundle.message("INTN.invert.if.condition")) }