PY-56268/PY-84930 go to type declaration: support callables

GitOrigin-RevId: d5e05b87ff1fc5670dfdeca7b13c6aee4661a519
This commit is contained in:
chbndrhnns
2026-02-16 11:17:01 +00:00
committed by intellij-monorepo-bot
parent 5d44e6ad04
commit 07082866c3
2 changed files with 37 additions and 1 deletions
@@ -4,6 +4,8 @@ package com.jetbrains.python.codeInsight
import com.intellij.codeInsight.navigation.actions.TypeDeclarationProvider
import com.intellij.psi.PsiElement
import com.jetbrains.python.psi.PyTypedElement
import com.jetbrains.python.psi.types.PyCallableType
import com.jetbrains.python.psi.types.PyClassType
import com.jetbrains.python.psi.types.PyTypeUtil.componentSequence
import com.jetbrains.python.psi.types.TypeEvalContext
@@ -12,7 +14,15 @@ class PyTypeDeclarationProvider : TypeDeclarationProvider {
override fun getSymbolTypeDeclarations(symbol: PsiElement): Array<out PsiElement>? {
if (symbol is PyTypedElement) {
val context = TypeEvalContext.userInitiated(symbol.project, symbol.containingFile)
return context.getType(symbol).componentSequence
// When the symbol is a function,
// navigate to the return type declaration instead of the function type itself.
val type = when (val type = context.getType(symbol)) {
is PyCallableType if type !is PyClassType -> type.getReturnType(context)
else -> type
}
return type.componentSequence
.filterNotNull()
.mapNotNull { it.declarationElement }
.distinct()
@@ -1,12 +1,15 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.testing
import com.intellij.codeInsight.navigation.actions.GotoTypeDeclarationAction
import com.intellij.idea.TestFor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPolyVariantReference
import com.intellij.psi.PsiReference
import com.intellij.psi.ResolveResult
import com.jetbrains.python.fixture.PythonCommonTestCase
import com.jetbrains.python.fixtures.PyTestCase
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.PyNamedParameter
import com.jetbrains.python.psi.resolve.ImportedResolveResult
import com.jetbrains.python.psi.types.TypeEvalContext
@@ -360,4 +363,27 @@ class PyTestFixtureResolvingTest : PyTestCase() {
fun testNamedParameterTypes() {
assertCorrectType(PARAMETRIZED_DIR, TEST_PARAMETER_TYPES, INT_STR_UNION)
}
@TestFor(issues = ["PY-56268"])
fun `test goto type declaration for fixture parameter`() {
myFixture.configureByText("test.py", """
import pytest
class A: pass
@pytest.fixture
def instance():
return A()
def test(inst<caret>ance):
assert instance
""")
val types = GotoTypeDeclarationAction.findSymbolTypes(myFixture.editor, myFixture.caretOffset)
assertNotNull("Go to Type Declaration should resolve the fixture parameter type", types)
assertEquals(1, types!!.size)
assertEquals((myFixture.file as PyFile).findTopLevelClass("A"), types.single())
}
}