PY-87130 type engine: add ui

GitOrigin-RevId: ea1b074efb27a07ceccae85d92dda4806d4888eb
This commit is contained in:
Morgan Bartholomew
2026-02-16 20:27:54 +00:00
committed by intellij-monorepo-bot
parent cc50b5d607
commit c89964a84e
5 changed files with 26 additions and 16 deletions
@@ -229,6 +229,16 @@ settings.python.group.description=<html><body>Configure key Python development s
settings.python.tools.group.title=Tools
settings.python.tools.group.description=<html><body>Configure external Python tool settings.
# Type Engine Settings
configurable.PyTypeEngineConfigurable.display.name=Type Engine
configurable.PyTypeEngineConfigurable.engine.label=Type engine:
configurable.PyTypeEngineConfigurable.project.default=Project default
configurable.PyTypeEngineConfigurable.project.default.description=Use the project-level type engine setting for this module.
configurable.PyTypeEngineConfigurable.pycharm.description=A smart IDE type engine optimized for real world Python, including Django templates, SqlAlchemy models, and more.
configurable.PyTypeEngineConfigurable.pyrefly.description=Currently in Beta, Pyrefly provides fast and accurate type checking, with experimental support for Django and Pydantic.
configurable.PyTypeEngineConfigurable.ty.description=Currently in Beta, ty provides fast and accurate type checking designed to work well with untyped code. Supports advanced type analysis features.
configurable.PyTypeEngineConfigurable.open.settings=Type Engine Settings\u2026
runcfg.autodetect.display_name=Autodetect
runcfg.autodetect.parameters.group.name=Python test
@@ -42,7 +42,7 @@
interface="com.jetbrains.python.documentation.PythonDocumentationQuickInfoProvider"
dynamic="true"/>
<extensionPoint qualifiedName="Pythonid.typeEvalExternalTypeProvider"
interface="com.jetbrains.python.psi.types.external.ExternalPyTypeResolverProvider"
interface="com.jetbrains.python.psi.types.engine.PyTypeEngineProvider"
dynamic="true"/>
</extensionPoints>
</idea-plugin>
@@ -24,8 +24,8 @@ import com.jetbrains.python.psi.PyInstantTypeProvider
import com.jetbrains.python.psi.PyTypedElement
import com.jetbrains.python.psi.resolve.PyResolveContext
import com.jetbrains.python.psi.resolve.RatedResolveResult
import com.jetbrains.python.psi.types.external.ExternalPyTypeResolver
import com.jetbrains.python.psi.types.external.ExternalPyTypeResolverProvider.Companion.createTypeResolver
import com.jetbrains.python.psi.types.engine.PyTypeEngine
import com.jetbrains.python.psi.types.engine.PyTypeEngineProvider.Companion.createTypeResolver
import com.jetbrains.python.pyi.PyiLanguageDialect
import org.jetbrains.annotations.ApiStatus
import java.util.concurrent.ConcurrentMap
@@ -52,7 +52,7 @@ sealed class TypeEvalContext(
private val myProcessingContext = ThreadLocal.withInitial { ProcessingContext() }
private var externalTypeResolver: ExternalPyTypeResolver? = null
private var typeEngine: PyTypeEngine? = null
protected val myEvaluated: MutableMap<PyTypedElement?, PyType?> = getConcurrentMapForCaching()
protected val myEvaluatedReturn: MutableMap<PyCallable?, PyType?> = getConcurrentMapForCaching()
protected val contextTypeCache: ConcurrentMap<Pair<PyExpression?, Any?>, PyType> = getConcurrentMapForCaching()
@@ -63,7 +63,7 @@ sealed class TypeEvalContext(
init {
if (constraints.myOrigin != null) {
externalTypeResolver = createTypeResolver(constraints.myOrigin.project)
typeEngine = createTypeResolver(constraints.myOrigin.project)
}
}
@@ -196,8 +196,8 @@ sealed class TypeEvalContext(
return RecursionManager.doPreventingRecursion(element to this, false) {
val type: PyType?
if (externalTypeResolver != null && externalTypeResolver!!.isSupportedForResolve(element)) {
type = Ref.deref(externalTypeResolver!!.resolveType(element, this is LibraryTypeEvalContext))
if (typeEngine != null && typeEngine!!.isSupportedForResolve(element)) {
type = Ref.deref(typeEngine!!.resolveType(element, this is LibraryTypeEvalContext))
}
else {
type = element.getType(this, KeyImpl)
@@ -244,7 +244,7 @@ sealed class TypeEvalContext(
val origin: PsiFile? = constraints.myOrigin
val usesExternalTypeProvider: Boolean
get() = externalTypeResolver != null
get() = typeEngine != null
@ApiStatus.Internal
fun getContextTypeCache(): MutableMap<Pair<PyExpression?, Any?>, PyType?> {
@@ -1,5 +1,5 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.psi.types.external
package com.jetbrains.python.psi.types.engine
import com.intellij.openapi.util.Ref
import com.jetbrains.python.psi.PyTypedElement
@@ -7,7 +7,7 @@ import com.jetbrains.python.psi.types.PyType
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
interface ExternalPyTypeResolver {
interface PyTypeEngine {
fun isSupportedForResolve(pyTypedElement: PyTypedElement): Boolean
fun resolveType(pyTypedElement: PyTypedElement, isLibrary: Boolean): Ref<PyType?>?
}
@@ -1,5 +1,5 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.psi.types.external
package com.jetbrains.python.psi.types.engine
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
@@ -10,16 +10,16 @@ import org.jetbrains.annotations.ApiStatus
* Implementations may return `null` if they cannot provide a type for the given element.
*/
@ApiStatus.Internal
interface ExternalPyTypeResolverProvider {
fun createResolver(project: Project): ExternalPyTypeResolver? = null
interface PyTypeEngineProvider {
fun createResolver(project: Project): PyTypeEngine? = null
companion object {
private val EP_NAME: ExtensionPointName<ExternalPyTypeResolverProvider> =
ExtensionPointName.Companion.create("Pythonid.typeEvalExternalTypeProvider")
private val EP_NAME =
ExtensionPointName.create<PyTypeEngineProvider>("Pythonid.typeEvalExternalTypeProvider")
@JvmStatic
@ApiStatus.Internal
fun createTypeResolver(project: Project): ExternalPyTypeResolver? {
fun createTypeResolver(project: Project): PyTypeEngine? {
return EP_NAME.extensionList.firstNotNullOfOrNull { it.createResolver(project) }
}
}