[python] PY-85012 fix PyGotoDeclarationHandler for multi assigned local variables

(cherry picked from commit 27ae2bddd6c2b0b17a8bd2ace3c8da0229afc710)

IJ-MR-180935

GitOrigin-RevId: 02d9e5f80813fb326d0fa0c9aec38e0caec32bb5
This commit is contained in:
Morgan Bartholomew
2025-11-05 09:16:01 +00:00
committed by intellij-monorepo-bot
parent b92192cac0
commit bd2c7616a2
2 changed files with 27 additions and 1 deletions
@@ -18,10 +18,13 @@ package com.jetbrains.python.psi.impl
import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandlerBase
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.resolve.FileContextUtil
import com.jetbrains.python.PyUserInitiatedResolvableReference
import com.jetbrains.python.psi.PyElement
import com.jetbrains.python.psi.PyQualifiedExpression
import com.jetbrains.python.psi.PyReferenceOwner
import com.jetbrains.python.psi.PyTargetExpression
import com.jetbrains.python.psi.resolve.PyResolveContext
import com.jetbrains.python.psi.resolve.PyResolveUtil
import com.jetbrains.python.psi.types.TypeEvalContext
@@ -60,7 +63,15 @@ class PyGotoDeclarationHandler : GotoDeclarationHandlerBase() {
}
.filter { it !== referenceOwner }
.groupBy { it.containingFile }
.flatMap { if (it.key == sourceElement.containingFile) it.value else listOf(it.value.first()) }
.flatMap { (containingFile, declarations) ->
if (containingFile != sourceElement.containingFile)
declarations.take(1)
// if it's a qualified expression, then it could be a union, so go to the different declarations
// otherwise go to the most recent assignment
else if ((referenceOwner as? PyQualifiedExpression)?.isQualified == true)
declarations
else declarations.takeLast(1)
}
if (results.isNotEmpty()) {
return results.toTypedArray()
}
@@ -4,6 +4,7 @@ package com.jetbrains.python
import com.intellij.codeInsight.navigation.actions.GotoDeclarationOrUsageHandler2
import com.intellij.codeInsight.navigation.actions.GotoDeclarationOrUsageHandler2.GTDUOutcome
import com.intellij.ide.util.gotoByName.GotoSymbolModel2
import com.intellij.idea.TestFor
import com.intellij.psi.PsiElement
import com.intellij.psi.util.parentOfType
import com.intellij.testFramework.fixtures.CodeInsightTestUtil
@@ -423,6 +424,20 @@ class PyNavigationTest : PyTestCase() {
assertEquals("test.py", local.containingFile.name)
}
@TestFor(issues = ["PY-85012"])
fun `test gtd for local variable`() {
val (result) = checkMulti(
"""
a = 1
if bool():
a = 2
<caret>a
""".trimIndent(),
1,
)
assertEquals("a = 2", result.parent.text)
}
private fun doTestGotoDeclarationNavigatesToPyNotPyi() {
myFixture.copyDirectoryToProject(getTestName(true), "")
myFixture.configureByFile("test.py")