refactor python: j2k PyTypingTypeProvider

GitOrigin-RevId: 69dae1b7df9761cbc375b3da89c6fc1c934d8bb8
This commit is contained in:
Morgan Bartholomew
2026-02-14 05:11:30 +00:00
committed by intellij-monorepo-bot
parent a3c83080dc
commit fca8fb36c8
14 changed files with 2778 additions and 2561 deletions
@@ -43,7 +43,7 @@ public interface PyClassStub extends NamedStub<PyClass>, PyVersionSpecificStub {
* @return literal text of expressions in the base classes list.
*/
@NotNull
List<String> getSuperClassesText();
List<@NotNull String> getSuperClassesText();
@ApiStatus.Internal
@@ -31,7 +31,7 @@ import org.jetbrains.annotations.ApiStatus
import java.util.concurrent.ConcurrentMap
import kotlin.concurrent.Volatile
open class TypeEvalContext private constructor(
sealed class TypeEvalContext(
/**
* @return context constraints (see [TypeEvalConstraints]
*/
@@ -267,7 +267,7 @@ open class TypeEvalContext private constructor(
get() = constraints.myOrigin
@ApiStatus.Internal
fun getContextTypeCache(): Map<Pair<PyExpression?, Any?>, PyType?> {
fun getContextTypeCache(): MutableMap<Pair<PyExpression?, Any?>, PyType?> {
return contextTypeCache
}
@@ -289,7 +289,7 @@ open class TypeEvalContext private constructor(
isSameVirtualFile(constraints.myOrigin, getContextFile(element))
}
object PyNullType : PyType {
private object PyNullType : PyType {
override fun resolveMember(
name: String,
location: PyExpression?,
@@ -315,6 +315,9 @@ open class TypeEvalContext private constructor(
}
}
private class TypeEvalContextImpl(allowDataFlow: Boolean, allowStubToAST: Boolean, allowCallContext: Boolean, origin: PsiFile?) :
TypeEvalContext(allowDataFlow, allowStubToAST, allowCallContext, origin)
private class AssumptionContext(val myParent: TypeEvalContext, element: PyTypedElement, type: PyType?) :
TypeEvalContext(myParent.constraints) {
init {
@@ -418,6 +421,7 @@ open class TypeEvalContext private constructor(
}
}
@ApiStatus.Internal
companion object {
private fun <T> getConcurrentMapForCaching(): ConcurrentMap<T & Any, PyType> {
// In the current implementation, this value is only used to initialize the map and is basically ignored
@@ -451,7 +455,7 @@ open class TypeEvalContext private constructor(
*/
@JvmStatic
fun codeCompletion(project: Project, origin: PsiFile?): TypeEvalContext {
return getContextFromCache(project, TypeEvalContext(true, true, true, origin))
return getContextFromCache(project, TypeEvalContextImpl(true, true, true, origin))
}
/**
@@ -465,7 +469,7 @@ open class TypeEvalContext private constructor(
*/
@JvmStatic
fun userInitiated(project: Project, origin: PsiFile?): TypeEvalContext {
return getContextFromCache(project, TypeEvalContext(true, true, false, origin))
return getContextFromCache(project, TypeEvalContextImpl(true, true, false, origin))
}
/**
@@ -489,7 +493,7 @@ open class TypeEvalContext private constructor(
*/
@JvmStatic
fun codeInsightFallback(project: Project?): TypeEvalContext {
val anchor = TypeEvalContext(false, false, false, null)
val anchor = TypeEvalContextImpl(false, false, false, null)
if (project != null) {
return getContextFromCache(project, anchor)
}
@@ -504,14 +508,14 @@ open class TypeEvalContext private constructor(
*/
@JvmStatic
fun deepCodeInsight(project: Project): TypeEvalContext {
return getContextFromCache(project, TypeEvalContext(false, true, false, null))
return getContextFromCache(project, TypeEvalContextImpl(false, true, false, null))
}
private fun buildCodeAnalysisContext(origin: PsiFile?): TypeEvalContext {
if (Registry.`is`("python.optimized.type.eval.context")) {
return OptimizedTypeEvalContext(false, false, false, origin)
}
return TypeEvalContext(false, false, false, origin)
return TypeEvalContextImpl(false, false, false, origin)
}
/**
@@ -3,7 +3,6 @@ package com.jetbrains.python.codeInsight.typing
import com.intellij.openapi.util.Ref
import com.jetbrains.python.PyNames
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.getReturnTypeAnnotation
import com.jetbrains.python.psi.PyCallable
import com.jetbrains.python.psi.PyFunction
import com.jetbrains.python.psi.PyNamedParameter
@@ -87,7 +86,7 @@ private fun getReturnTypeFromSupertype(function: PyFunction, context: TypeEvalCo
val overriddenFunction = getOverriddenFunction(function, context)
if (overriddenFunction != null) {
val superFunctionAnnotation = getReturnTypeAnnotation(overriddenFunction, context)
val superFunctionAnnotation = PyTypingTypeProvider.getReturnTypeAnnotation(overriddenFunction, context)
if (superFunctionAnnotation != null) {
val typeRef = PyTypingTypeProvider.getType(superFunctionAnnotation, context)
if (typeRef != null && function.isAsync == overriddenFunction.isAsync) {
@@ -3,8 +3,6 @@ package com.jetbrains.python.codeInsight.typing
import com.intellij.psi.util.contextOfType
import com.jetbrains.python.PyNames
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.PROTOCOL
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.PROTOCOL_EXT
import com.jetbrains.python.psi.PyClass
import com.jetbrains.python.psi.PyFunction
import com.jetbrains.python.psi.PyKnownDecorator.TYPING_RUNTIME
@@ -107,5 +105,5 @@ fun inspectProtocolSubclass(protocol: PyClassType, subclass: PyClassType, contex
private fun containsProtocol(types: List<PyClassLikeType?>) = types.any { type ->
val classQName = type?.classQName
PROTOCOL == classQName || PROTOCOL_EXT == classQName
PyTypingTypeProvider.PROTOCOL == classQName || PyTypingTypeProvider.PROTOCOL_EXT == classQName
}
@@ -13,12 +13,12 @@ import org.jetbrains.annotations.ApiStatus.Experimental
@Experimental
@ApiStatus.Internal
interface PyTypeHintProvider {
fun parseTypeHint(typeHint: PyExpression, alias: PyQualifiedNameOwner?, resolved: PsiElement, context: TypeEvalContext): Ref<PyType>?
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>? {
fun parseTypeHint(typeHint: PyExpression, alias: PyQualifiedNameOwner?, resolved: PsiElement, context: TypeEvalContext): Ref<PyType?>? {
return EP_NAME.extensionList.firstNotNullOfOrNull { it.parseTypeHint(typeHint, alias, resolved, context) }
}
}
@@ -6,17 +6,6 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.resolve.FileContextUtil
import com.jetbrains.python.PyCustomType
import com.jetbrains.python.PyNames
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.MAPPING_GET
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.NOT_REQUIRED
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.NOT_REQUIRED_EXT
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.READONLY
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.READONLY_EXT
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.REQUIRED
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.REQUIRED_EXT
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.TYPED_DICT
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.TYPED_DICT_EXT
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.getType
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.resolveToQualifiedNames
import com.jetbrains.python.psi.LanguageLevel
import com.jetbrains.python.psi.PyBoolLiteralExpression
import com.jetbrains.python.psi.PyCallExpression
@@ -72,15 +61,16 @@ class PyTypedDictTypeProvider : PyTypeProviderBase() {
}
companion object {
val nameIsTypedDict = { name: String? -> name == TYPED_DICT || name == TYPED_DICT_EXT }
val nameIsTypedDict = { name: String? -> name == PyTypingTypeProvider.TYPED_DICT || name == PyTypingTypeProvider.TYPED_DICT_EXT }
fun isGetMethodToOverride(call: PyCallExpression, context: TypeEvalContext): Boolean {
val callee = call.callee
return callee != null && resolveToQualifiedNames(callee, context).any { it == "dict.get" /* py3 */ || it == MAPPING_GET /* py2 */ }
return callee != null && PyTypingTypeProvider.resolveToQualifiedNames(callee, context)
.any { it == "dict.get" /* py3 */ || it == PyTypingTypeProvider.MAPPING_GET /* py2 */ }
}
fun isTypedDict(expression: PyExpression, context: TypeEvalContext): Boolean {
return resolveToQualifiedNames(expression, context).any(nameIsTypedDict)
return PyTypingTypeProvider.resolveToQualifiedNames(expression, context).any(nameIsTypedDict)
}
fun isTypingTypedDictInheritor(cls: PyClass, context: TypeEvalContext): Boolean {
@@ -266,14 +256,14 @@ class PyTypedDictTypeProvider : PyTypeProviderBase() {
val result = mutableListOf<TypedDictFieldQualifier>()
expression.accept(object : PyRecursiveElementVisitor() {
override fun visitPySubscriptionExpression(node: PySubscriptionExpression) {
val resolvedNames = resolveToQualifiedNames(node.operand, context)
if (resolvedNames.any { name -> REQUIRED == name || REQUIRED_EXT == name }) {
val resolvedNames = PyTypingTypeProvider.resolveToQualifiedNames(node.operand, context)
if (resolvedNames.any { name -> PyTypingTypeProvider.REQUIRED == name || PyTypingTypeProvider.REQUIRED_EXT == name }) {
result.add(TypedDictFieldQualifier.REQUIRED)
}
else if (resolvedNames.any { name -> NOT_REQUIRED == name || NOT_REQUIRED_EXT == name }) {
else if (resolvedNames.any { name -> PyTypingTypeProvider.NOT_REQUIRED == name || PyTypingTypeProvider.NOT_REQUIRED_EXT == name }) {
result.add(TypedDictFieldQualifier.NOT_REQUIRED)
}
else if (resolvedNames.any { name -> READONLY == name || READONLY_EXT == name }) {
else if (resolvedNames.any { name -> PyTypingTypeProvider.READONLY == name || PyTypingTypeProvider.READONLY_EXT == name }) {
result.add(TypedDictFieldQualifier.READ_ONLY)
}
super.visitPySubscriptionExpression(node)
@@ -367,7 +357,7 @@ class PyTypedDictTypeProvider : PyTypeProviderBase() {
if (expr is PySubscriptionExpression) {
qualifiers = parseTypedDictFieldQualifiers(expr, context)
}
return if (expr != null) Pair(getType(expr, context), qualifiers) else null
return if (expr != null) Pair(PyTypingTypeProvider.getType(expr, context), qualifiers) else null
}
}
}
@@ -18,14 +18,7 @@ import com.jetbrains.python.codeInsight.functionTypeComments.psi.PyFunctionTypeA
import com.jetbrains.python.codeInsight.functionTypeComments.psi.PyParameterTypeList
import com.jetbrains.python.codeInsight.parseDataclassParameters
import com.jetbrains.python.codeInsight.typeHints.PyTypeHintFile
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.CLASS_VAR
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.FINAL
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.FINAL_EXT
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.getFunctionTypeAnnotation
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.getReturnTypeAnnotation
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.isFinal
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.isInsideTypeHint
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.resolveToQualifiedNames
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
import com.jetbrains.python.psi.PyAnnotation
import com.jetbrains.python.psi.PyAnnotationOwner
import com.jetbrains.python.psi.PyAugAssignmentStatement
@@ -139,14 +132,14 @@ class PyFinalInspection : PyInspection() {
registerProblem(node.nameIdentifier, PyPsiBundle.message("INSP.final.non.method.function.could.not.be.marked.as.final"))
}
getFunctionTypeAnnotation(node)?.let { comment ->
PyTypingTypeProvider.getFunctionTypeAnnotation(node)?.let { comment ->
if (comment.parameterTypeList.parameterTypes.any { resolvesToFinal(if (it is PySubscriptionExpression) it.operand else it) }) {
registerProblem(node.typeComment,
PyPsiBundle.message("INSP.final.final.could.not.be.used.in.annotations.for.function.parameters"))
}
}
getReturnTypeAnnotation(node, myTypeEvalContext)?.let {
PyTypingTypeProvider.getReturnTypeAnnotation(node, myTypeEvalContext)?.let {
if (resolvesToFinal(if (it is PySubscriptionExpression) it.operand else it)) {
registerProblem(node.typeComment ?: node.annotation,
PyPsiBundle.message("INSP.final.final.could.not.be.used.in.annotation.for.function.return.value"))
@@ -463,7 +456,7 @@ class PyFinalInspection : PyInspection() {
return
}
if (isInsideTypeHint(node, myTypeEvalContext) && resolvesToFinal(node)) {
if (PyTypingTypeProvider.isInsideTypeHint(node, myTypeEvalContext) && resolvesToFinal(node)) {
registerProblem(node, PyPsiBundle.message("INSP.final.final.could.only.be.used.as.outermost.type"))
}
}
@@ -486,20 +479,21 @@ class PyFinalInspection : PyInspection() {
)
}
private fun isFinal(decoratable: PyDecoratable) = isFinal(decoratable, myTypeEvalContext)
private fun isFinal(decoratable: PyDecoratable) = PyTypingTypeProvider.isFinal(decoratable, myTypeEvalContext)
private fun <T> isFinal(node: T): Boolean where T : PyAnnotationOwner, T : PyTypeCommentOwner {
return isFinal(node, myTypeEvalContext)
return PyTypingTypeProvider.isFinal(node, myTypeEvalContext)
}
private fun resolvesToFinal(expression: PyExpression?): Boolean {
return expression is PyReferenceExpression &&
resolveToQualifiedNames(expression, myTypeEvalContext).any { it == FINAL || it == FINAL_EXT }
PyTypingTypeProvider.resolveToQualifiedNames(expression, myTypeEvalContext)
.any { it == PyTypingTypeProvider.FINAL || it == PyTypingTypeProvider.FINAL_EXT }
}
private fun resolvesToClassVar(expression: PyExpression): Boolean {
return (expression is PyReferenceExpression) &&
resolveToQualifiedNames(expression, myTypeEvalContext).any { it == CLASS_VAR }
PyTypingTypeProvider.resolveToQualifiedNames(expression, myTypeEvalContext).any { it == PyTypingTypeProvider.CLASS_VAR }
}
private fun resolvesToClassVarFinal(expression: PyExpression?): Boolean {
@@ -205,7 +205,7 @@ public class PyTypeCheckerInspection extends PyInspection {
final var annotatedGeneratorDesc = getGeneratorDescriptorFromAnnotation(function, node);
if (annotatedGeneratorDesc == null) return;
checkYieldType(annotatedGeneratorDesc.yieldType(), node, function);
checkYieldType(annotatedGeneratorDesc.yieldType, node, function);
}
private void visitDelegatingYieldExpression(@NotNull PyYieldExpression node, @NotNull PyFunction function) {
@@ -218,7 +218,7 @@ public class PyTypeCheckerInspection extends PyInspection {
if (delegateType == null) return;
var delegateDesc = GeneratorTypeDescriptor.fromGeneratorOrProtocol(delegateType, myTypeEvalContext);
if (delegateDesc != null && delegateDesc.isAsync()) {
if (delegateDesc != null && delegateDesc.isAsync) {
String delegateName = PythonDocumentationProvider.getTypeName(delegateType, myTypeEvalContext);
registerProblem(yieldExpr, PyPsiBundle.message("INSP.type.checker.yield.from.async.generator", delegateName));
return;
@@ -229,13 +229,13 @@ public class PyTypeCheckerInspection extends PyInspection {
final var annotatedGeneratorDesc = getGeneratorDescriptorFromAnnotation(function, node);
if (annotatedGeneratorDesc == null) return;
if (checkYieldType(annotatedGeneratorDesc.yieldType(), node, function)) return;
if (checkYieldType(annotatedGeneratorDesc.yieldType, node, function)) return;
// Reversed because SendType is contravariant
final PyType expectedSendType = annotatedGeneratorDesc.sendType();
if (delegateDesc != null && !PyTypeChecker.match(delegateDesc.sendType(), expectedSendType, myTypeEvalContext)) {
final PyType expectedSendType = annotatedGeneratorDesc.sendType;
if (delegateDesc != null && !PyTypeChecker.match(delegateDesc.sendType, expectedSendType, myTypeEvalContext)) {
String expectedName = PythonDocumentationProvider.getVerboseTypeName(expectedSendType, myTypeEvalContext);
String actualName = PythonDocumentationProvider.getTypeName(delegateDesc.sendType(), myTypeEvalContext);
String actualName = PythonDocumentationProvider.getTypeName(delegateDesc.sendType, myTypeEvalContext);
registerProblem(yieldExpr, PyPsiBundle.message("INSP.type.checker.yield.from.send.type.mismatch", expectedName, actualName));
}
}
@@ -286,7 +286,7 @@ public class PyTypeCheckerInspection extends PyInspection {
if (function.isGenerator()) {
final var generatorDesc = GeneratorTypeDescriptor.fromGeneratorOrProtocol(returnType, typeEvalContext);
if (generatorDesc != null) {
return generatorDesc.returnType();
return generatorDesc.returnType;
}
return null;
}
@@ -439,7 +439,7 @@ public class PyTypeCheckerInspection extends PyInspection {
if (node.isGenerator()) {
final var generatorDesc = GeneratorTypeDescriptor.fromGeneratorOrProtocol(annotatedType, myTypeEvalContext);
final boolean shouldBeAsync = node.isAsync() && node.isAsyncAllowed();
final boolean wrongSyncAsync = generatorDesc != null && generatorDesc.isAsync() != shouldBeAsync;
final boolean wrongSyncAsync = generatorDesc != null && generatorDesc.isAsync != shouldBeAsync;
final PyType inferredType = node.getInferredReturnType(myTypeEvalContext);
if (wrongSyncAsync || (generatorDesc == null && !PyTypeChecker.match(annotatedType, inferredType, myTypeEvalContext))) {
@@ -36,7 +36,6 @@ import com.jetbrains.python.codeInsight.imports.AddImportHelper
import com.jetbrains.python.codeInsight.imports.AddImportHelper.ImportPriority
import com.jetbrains.python.codeInsight.typeHints.PyTypeHintFile
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.isBitwiseOrUnionAvailable
import com.jetbrains.python.documentation.PythonDocumentationProvider
import com.jetbrains.python.inspections.quickfix.PyUnpackTypeVarTupleQuickFix
import com.jetbrains.python.psi.FutureFeature
@@ -709,7 +708,7 @@ class PyTypeHintsInspection : PyInspection() {
private fun checkInstanceAndClassChecksOn(base: PyExpression) {
if (base is PyBinaryExpression && base.operator == PyTokenTypes.OR) {
if (isBitwiseOrUnionAvailable(base)) {
if (PyTypingTypeProvider.isBitwiseOrUnionAvailable(base)) {
val left = base.leftExpression
val right = base.rightExpression
if (left != null) checkInstanceAndClassChecksOn(left)
@@ -820,7 +819,7 @@ class PyTypeHintsInspection : PyInspection() {
PyTypingTypeProvider.UNION,
PyTypingTypeProvider.OPTIONAL,
-> {
if (!isBitwiseOrUnionAvailable(base)) {
if (!PyTypingTypeProvider.isBitwiseOrUnionAvailable(base)) {
registerParametrizedGenericsProblem(qName, base)
}
else if (base is PySubscriptionExpression) {
@@ -31,7 +31,7 @@ public class PyYieldExpressionImpl extends PyElementImpl implements PyYieldExpre
final PyType type = e != null ? context.getType(e) : null;
var generatorDesc = PyTypingTypeProvider.GeneratorTypeDescriptor.fromGeneratorOrProtocol(type, context);
if (generatorDesc != null) {
return generatorDesc.returnType();
return generatorDesc.returnType;
}
return PyBuiltinCache.getInstance(this).getNoneType();
}
@@ -58,7 +58,7 @@ public class PyYieldExpressionImpl extends PyElementImpl implements PyYieldExpre
var returnType = context.getReturnType(function);
var generatorDesc = PyTypingTypeProvider.GeneratorTypeDescriptor.fromGeneratorOrProtocol(returnType, context);
if (generatorDesc != null) {
return generatorDesc.sendType();
return generatorDesc.sendType;
}
}
}
@@ -68,7 +68,7 @@ public class PyYieldExpressionImpl extends PyElementImpl implements PyYieldExpre
final PyType type = e != null ? context.getType(e) : null;
var generatorDesc = PyTypingTypeProvider.GeneratorTypeDescriptor.fromGeneratorOrProtocol(type, context);
if (generatorDesc != null) {
return generatorDesc.sendType();
return generatorDesc.sendType;
}
return PyBuiltinCache.getInstance(this).getNoneType();
}
@@ -439,7 +439,7 @@ object PyExpectedTypeJudgement {
val returnType = ctx.getReturnType(funScope)
val generatorDescriptor = PyTypingTypeProvider.GeneratorTypeDescriptor.fromGenerator(returnType)
val yieldType = generatorDescriptor?.yieldType()
val yieldType = generatorDescriptor?.yieldType
if (parent.isDelegating) {
return createIterableType(expr, yieldType)
}
@@ -455,7 +455,7 @@ object PyExpectedTypeJudgement {
if (funScope.isAsync) {
return PyTypingTypeProvider.unwrapCoroutineReturnType(returnType)?.get()
}
val generatorReturnType = PyTypingTypeProvider.GeneratorTypeDescriptor.fromGenerator(returnType)?.returnType()
val generatorReturnType = PyTypingTypeProvider.GeneratorTypeDescriptor.fromGenerator(returnType)?.returnType
return generatorReturnType ?: returnType
}
@@ -14,8 +14,7 @@ import com.intellij.codeInsight.hints.declarative.impl.PresentationTreeBuilderIm
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.REVEAL_TYPE
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.REVEAL_TYPE_EXT
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
import com.jetbrains.python.documentation.PythonDocumentationProvider
import com.jetbrains.python.psi.PyCallExpression
import com.jetbrains.python.psi.PyFunction
@@ -55,7 +54,8 @@ class PyTypeInlayHintsProvider : InlayHintsProvider {
val callable = element.multiResolveCalleeFunction(resolveContext).singleOrNull()
val typeEvalContext = resolveContext.typeEvalContext
if (callable is PyFunction && callable.qualifiedName in listOf(REVEAL_TYPE, REVEAL_TYPE_EXT)) {
if (callable is PyFunction && callable.qualifiedName in listOf(PyTypingTypeProvider.REVEAL_TYPE,
PyTypingTypeProvider.REVEAL_TYPE_EXT)) {
val args = element.getArguments()
if (args.size != 1) return
@@ -20,8 +20,7 @@ import com.intellij.util.ProcessingContext
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.toArray
import com.jetbrains.python.BaseReference
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.COROUTINE
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider.GENERATOR
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider
import com.jetbrains.python.psi.PyArgumentList
import com.jetbrains.python.psi.PyCallExpression
import com.jetbrains.python.psi.PyDecorator
@@ -143,10 +142,10 @@ class PyTextFixtureTypeProvider : PyTypeProviderBase() {
val classType = PyUtil.`as`(type, PyClassType::class.java)
if (genericType != null && classType != null) {
val qName = classType.getClassQName()
if (ArrayUtil.contains(qName, "typing.Awaitable", GENERATOR)) {
if (ArrayUtil.contains(qName, "typing.Awaitable", PyTypingTypeProvider.GENERATOR)) {
return Ref.create(ContainerUtil.getOrElse(genericType.getElementTypes(), 0, null))
}
if (COROUTINE == qName) {
if (PyTypingTypeProvider.COROUTINE == qName) {
return Ref.create(ContainerUtil.getOrElse(genericType.getElementTypes(), 2, null))
}
}