PY-39384: Introduce PyTypeHintProvider

`PyTypeHintProvider` allows providing type hints for resolved elements before the main logic of `PyTypingTypeProvider`.
See an example of `django-stubs`: https://github.com/typeddjango/django-stubs/pull/2335.
`_UserModel` type might be replaced with a custom user model, provided in `settings.py` (`AUTH_USER_MODEL`).

GitOrigin-RevId: 986fb91c800be3ccfbc002c73c673896efec8a1a
This commit is contained in:
Ilia Zakoulov
2024-12-17 14:12:23 +00:00
committed by intellij-monorepo-bot
parent 45a808fcdc
commit e044f9e441
3 changed files with 35 additions and 0 deletions
@@ -4,6 +4,7 @@
interface="com.jetbrains.python.psi.resolve.PyReferenceResolveProvider"
dynamic="true"/>
<extensionPoint qualifiedName="Pythonid.typeProvider" interface="com.jetbrains.python.psi.impl.PyTypeProvider" dynamic="true"/>
<extensionPoint qualifiedName="Pythonid.typeHintProvider" interface="com.jetbrains.python.codeInsight.typing.PyTypeHintProvider" dynamic="true"/>
<extensionPoint qualifiedName="Pythonid.pySuperMethodsSearch" interface="com.intellij.util.QueryExecutor" dynamic="true"/>
<extensionPoint qualifiedName="Pythonid.pyClassMembersProvider"
interface="com.jetbrains.python.psi.types.PyClassMembersProvider"
@@ -0,0 +1,25 @@
package com.jetbrains.python.codeInsight.typing
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.jetbrains.python.psi.PyExpression
import com.jetbrains.python.psi.PyQualifiedNameOwner
import com.jetbrains.python.psi.types.PyType
import com.jetbrains.python.psi.types.TypeEvalContext
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.ApiStatus.Experimental
@Experimental
@ApiStatus.Internal
interface PyTypeHintProvider {
fun parseTypeHint(typeHint: PyExpression, alias: PyQualifiedNameOwner?, resolved: PsiElement, context: TypeEvalContext): Ref<PyType>?
companion object {
private val EP_NAME: ExtensionPointName<PyTypeHintProvider> = ExtensionPointName.create("Pythonid.typeHintProvider");
fun parseTypeHint(typeHint: PyExpression, alias: PyQualifiedNameOwner?, resolved: PsiElement, context: TypeEvalContext): Ref<PyType>? {
return EP_NAME.extensionList.firstNotNullOfOrNull { it.parseTypeHint(typeHint, alias, resolved, context) }
}
}
}
@@ -865,6 +865,15 @@ public final class PyTypingTypeProvider extends PyTypeProviderWithCustomContext<
context.getTypeAliasStack().add(alias);
}
try {
final Ref<PyType> typeHintFromProvider = PyTypeHintProvider.Companion.parseTypeHint(
typeHint,
alias,
resolved,
context.getTypeContext()
);
if (typeHintFromProvider != null) {
return typeHintFromProvider;
}
final Ref<PyType> typeFromParenthesizedExpression = getTypeFromParenthesizedExpression(resolved, context);
if (typeFromParenthesizedExpression != null) {
return typeFromParenthesizedExpression;