mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[pycharm] PY-89747 Add DependenciesInspectionProvider impl for legacy Poetry
fixup! [pycharm] PY-89747 Add DependenciesInspectionProvider impl for legacy Poetry [pycharm] PY-89747 Add DependenciesInspectionProvider impl for legacy Poetry Co-authored-by: Morgan Bartholomew <morgan.bartholomew@jetbrains.com> Merge-request: IJ-MR-211850 Merged-by: David Lysenko <david.lysenko@jetbrains.com> (cherry picked from commit 147e19a3dea8c6a322f9a4a0dbf06b5972710819) IJ-MR-211850 GitOrigin-RevId: 8f5aa63e3381746ee70b216a5198524ad4bebdc6
This commit is contained in:
committed by
intellij-monorepo-bot
co-authored by
Morgan Bartholomew
parent
d84d493dc5
commit
032935307a
@@ -1407,6 +1407,8 @@ jvm_library(
|
||||
"//libraries/junit4:junit4_test_lib",
|
||||
"//plugins/toml/core",
|
||||
"//plugins/toml/core:core_test_lib",
|
||||
"//python/python-poetry/backend",
|
||||
"//python/python-poetry/backend:backend_test_lib",
|
||||
],
|
||||
)
|
||||
### auto-generated section `build intellij.python.community.tests` end
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.testIntegration.ui" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.libraries.junit4" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.toml.core" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.python.community.impl.poetry.backend" scope="TEST" />
|
||||
</component>
|
||||
<component name="TestModuleProperties" production-module="intellij.python.community.impl" />
|
||||
</module>
|
||||
@@ -55,10 +55,6 @@
|
||||
implementation="com.jetbrains.python.requirements.widget.PyDependenciesFileStatusBarWidgetFactory"
|
||||
order="after pythonInterpreterWidget, before git, before hg, before Notifications"/>
|
||||
|
||||
<localInspection language="TOML" enabledByDefault="true"
|
||||
implementationClass="com.jetbrains.python.sdk.poetry.PoetryPackageVersionsInspection"
|
||||
key="INSP.poetry.package.versions.display.name" bundle="messages.PyBundle" groupKey="INSP.GROUP.python"
|
||||
suppressId="PoetryPackageVersions" shortName="PoetryPackageVersionsInspection"/>
|
||||
<registryKey defaultValue="20" description="How often conda environments cache must be refreshed (seconds)"
|
||||
key="python.conda.envs.refresh.seconds" restartRequired="true"/>
|
||||
<registryKey defaultValue="60" description="TTL of conda environments cache (seconds)" key="python.conda.envs.cache.ttl.seconds"
|
||||
@@ -1309,5 +1305,7 @@
|
||||
implementation="com.jetbrains.python.conda.CondaDependenciesInspectionProvider"/>
|
||||
<python.inspections.dependencies.dependenciesInspectionProvider
|
||||
implementation="com.jetbrains.python.pipenv.PipEnvDependenciesInspectionProvider"/>
|
||||
<python.inspections.dependencies.dependenciesInspectionProvider
|
||||
implementation="com.jetbrains.python.sdk.poetry.LegacyPoetryDependenciesInspectionProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -1284,8 +1284,6 @@ INSP.settings.bdd.behave.specific=Incorrect BDD Behave-specific definitions
|
||||
INSP.settings.bdd.step.definition.arguments=Incorrect arguments in step definition functions
|
||||
python.compatibility.inspection.advertiser.notifications.group.title=Python compatibility inspection recommended
|
||||
python.compatibility.inspection.advertiser.notifications.title=Python versions compatibility
|
||||
INSP.poetry.package.versions.display.name=Outdated Poetry package versions
|
||||
INSP.uv.package.versions.display.name=Outdated uv package versions
|
||||
|
||||
# Both placeholders are Python versions like 2.7, 3.7, etc.
|
||||
python.compatibility.inspection.advertiser.version.stale.python3.version.warning.message=\
|
||||
|
||||
@@ -72,15 +72,30 @@ class DependenciesInspection : LocalInspectionTool() {
|
||||
return
|
||||
}
|
||||
|
||||
val (provider, dependencies) = DependenciesInspectionProviderData.providers.firstNotNullOfOrNull { provider ->
|
||||
provider.getDependencies(psiFile)?.let { provider to it }
|
||||
} ?: return
|
||||
val eligibleProviders =
|
||||
DependenciesInspectionProviderData
|
||||
.providers
|
||||
.mapNotNull { provider ->
|
||||
provider
|
||||
.getDependencies(psiFile)
|
||||
?.let { provider to it }
|
||||
}
|
||||
|
||||
if (psiFile.injectionParent() == null) {
|
||||
verifyNonEmptyFile(psiFile, provider, packageManager)
|
||||
if (eligibleProviders.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
packageManager.verifyPackageManager(dependencies)
|
||||
val finalDependenciesMap = mutableMapOf<PyRequirement, PsiElement>()
|
||||
|
||||
for ((provider, dependencies) in eligibleProviders) {
|
||||
if (psiFile.injectionParent() == null) {
|
||||
verifyNonEmptyFile(psiFile, provider, packageManager)
|
||||
}
|
||||
|
||||
finalDependenciesMap += dependencies
|
||||
}
|
||||
|
||||
packageManager.verifyPackageManager(finalDependenciesMap)
|
||||
}
|
||||
|
||||
private fun verifyNonEmptyFile(psiFile: PsiFile, provider: DependenciesInspectionProvider<*>, packageManager: PythonPackageManager) {
|
||||
@@ -88,12 +103,16 @@ class DependenciesInspection : LocalInspectionTool() {
|
||||
return
|
||||
}
|
||||
|
||||
val dependenciesExporter = packageManager.dependenciesExporter
|
||||
val fixes = dependenciesExporter?.let { arrayOf(ExportDependenciesQuickFix(it)) } ?: emptyArray()
|
||||
val fixes =
|
||||
packageManager
|
||||
.dependenciesExporter
|
||||
?.let { arrayOf(ExportDependenciesQuickFix(it)) }
|
||||
?: emptyArray()
|
||||
val inspectionMessage = provider.emptyFileInspectionMessage ?: return
|
||||
|
||||
holder.registerProblem(
|
||||
psiFile,
|
||||
provider.emptyFileInspectionMessage,
|
||||
inspectionMessage,
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
*fixes,
|
||||
)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ typealias DependenciesMap = Map<PyRequirement, PsiElement>
|
||||
@ApiStatus.Internal
|
||||
abstract class DependenciesInspectionProvider<T : PsiFile>(internal val `class`: Class<T>) {
|
||||
protected abstract fun provideDependencies(file: T): DependenciesMap?
|
||||
abstract val emptyFileInspectionMessage: @InspectionMessage String
|
||||
abstract val emptyFileInspectionMessage: @InspectionMessage String?
|
||||
|
||||
fun getDependencies(file: PsiFile): DependenciesMap? =
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
@@ -4,6 +4,15 @@ package com.jetbrains.python.psi
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.source.resolve.FileContextUtil
|
||||
import org.toml.lang.psi.TomlLiteral
|
||||
import org.toml.lang.psi.ext.TomlLiteralKind
|
||||
import org.toml.lang.psi.ext.kind
|
||||
|
||||
internal fun PsiFile.injectionParent(): PsiElement? =
|
||||
getUserData(FileContextUtil.INJECTED_IN_ELEMENT)?.element
|
||||
getUserData(FileContextUtil.INJECTED_IN_ELEMENT)?.element
|
||||
|
||||
internal fun TomlLiteral.getStringOrNull(): String? =
|
||||
when (val kind = kind) {
|
||||
is TomlLiteralKind.String -> kind.value
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -10,20 +10,16 @@ import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.jetbrains.python.inspections.dependencies.DependenciesMap
|
||||
import com.jetbrains.python.packaging.PyRequirement
|
||||
import com.jetbrains.python.packaging.PyRequirementParser
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import com.jetbrains.python.psi.getStringOrNull
|
||||
import org.toml.lang.psi.TomlFile
|
||||
import org.toml.lang.psi.TomlInlineTable
|
||||
import org.toml.lang.psi.TomlLiteral
|
||||
import org.toml.lang.psi.TomlTable
|
||||
import org.toml.lang.psi.ext.TomlLiteralKind
|
||||
import org.toml.lang.psi.ext.getValueByKey
|
||||
import org.toml.lang.psi.ext.kind
|
||||
|
||||
|
||||
private val dependencyHeaders = setOf("packages", "dev-packages")
|
||||
private const val versionKey = "version"
|
||||
|
||||
@ApiStatus.Internal
|
||||
internal object PipEnvParser {
|
||||
private val gson = Gson()
|
||||
|
||||
@@ -80,9 +76,3 @@ internal object PipEnvParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TomlLiteral.getStringOrNull(): String? =
|
||||
when (val kind = kind) {
|
||||
is TomlLiteralKind.String -> kind.value
|
||||
else -> null
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.sdk.poetry
|
||||
|
||||
import com.intellij.codeInspection.util.InspectionMessage
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.python.pyproject.PY_PROJECT_TOML
|
||||
import com.jetbrains.python.inspections.dependencies.DependenciesInspectionProvider
|
||||
import com.jetbrains.python.inspections.dependencies.DependenciesMap
|
||||
import com.jetbrains.python.packaging.PyRequirementParser
|
||||
import com.jetbrains.python.psi.getStringOrNull
|
||||
import com.jetbrains.python.requirements.getPythonSdk
|
||||
import org.toml.lang.psi.TomlFile
|
||||
import org.toml.lang.psi.TomlKeyValue
|
||||
import org.toml.lang.psi.TomlLiteral
|
||||
import org.toml.lang.psi.TomlTable
|
||||
|
||||
private val poetryGroupRegex = Regex("""^tool\.poetry\.group\.[^.]*\.dependencies$""")
|
||||
private val legacyPoetryDependencyHeaders = setOf("tool.poetry.dependencies", "tool.poetry.dev-dependencies")
|
||||
|
||||
internal class LegacyPoetryDependenciesInspectionProvider : DependenciesInspectionProvider<TomlFile>(TomlFile::class.java) {
|
||||
override fun provideDependencies(file: TomlFile): DependenciesMap? {
|
||||
if (file.name != PY_PROJECT_TOML || !isPoetryProject(file)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return file
|
||||
.children
|
||||
.filterIsInstance<TomlTable>()
|
||||
.filter {
|
||||
it.header.key?.text?.let { text ->
|
||||
text in legacyPoetryDependencyHeaders || poetryGroupRegex matches text
|
||||
} == true
|
||||
}
|
||||
.flatMap { it.children.filterIsInstance<TomlKeyValue>() }
|
||||
.mapNotNull { keyValue ->
|
||||
val versionString =
|
||||
(keyValue.value as? TomlLiteral)?.getStringOrNull()
|
||||
?: return@mapNotNull null
|
||||
|
||||
(PyRequirementParser.fromLine("${keyValue.key.text}${versionString}")
|
||||
?: PyRequirementParser.fromLine(keyValue.key.text))
|
||||
?.let { pyRequirement -> pyRequirement to keyValue }
|
||||
}
|
||||
.toMap()
|
||||
}
|
||||
|
||||
override val emptyFileInspectionMessage: @InspectionMessage String? = null
|
||||
|
||||
private fun isPoetryProject(psiFile: PsiFile) =
|
||||
getPythonSdk(psiFile)?.isPoetry == true
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.sdk.poetry
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionTool
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.progress.runBlockingMaybeCancellable
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.python.pyproject.PY_PROJECT_TOML
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.packaging.PyPackageName
|
||||
import com.jetbrains.python.packaging.management.PythonPackageManager
|
||||
import com.jetbrains.python.sdk.findAmongRoots
|
||||
import com.jetbrains.python.sdk.legacy.PythonSdkUtil
|
||||
import org.toml.lang.psi.TomlKeyValue
|
||||
import org.toml.lang.psi.TomlTable
|
||||
|
||||
/**
|
||||
* This source code is created by @koxudaxi Koudai Aono <koxudaxi@gmail.com>
|
||||
*/
|
||||
|
||||
internal class PoetryPackageVersionsInspection : LocalInspectionTool() {
|
||||
override fun buildVisitor(
|
||||
holder: ProblemsHolder,
|
||||
isOnTheFly: Boolean,
|
||||
session: LocalInspectionToolSession,
|
||||
): PsiElementVisitor {
|
||||
return PoetryFileVisitor(holder)
|
||||
}
|
||||
|
||||
class PoetryFileVisitor(
|
||||
val holder: ProblemsHolder,
|
||||
) : PsiElementVisitor() {
|
||||
@RequiresBackgroundThread
|
||||
private fun guessModule(element: PsiElement): Module? {
|
||||
return ModuleUtilCore.findModuleForPsiElement(element)
|
||||
?: ModuleManager.getInstance(element.project).modules.let { if (it.size != 1) null else it[0] }
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
private fun Module.pyProjectTomlBlocking(): VirtualFile? = runBlockingMaybeCancellable {
|
||||
findAmongRoots(this@pyProjectTomlBlocking, PY_PROJECT_TOML)
|
||||
}
|
||||
|
||||
val poetryGroupRegex = Regex("""^tool\.poetry\.group\.[^.]*\.dependencies$""")
|
||||
|
||||
@RequiresBackgroundThread
|
||||
override fun visitFile(psiFile: PsiFile) {
|
||||
val module = guessModule(psiFile) ?: return
|
||||
val sdk = PythonSdkUtil.findPythonSdk(module) ?: return
|
||||
if (!sdk.isPoetry) return
|
||||
if (psiFile.virtualFile != module.pyProjectTomlBlocking()) return
|
||||
psiFile.children
|
||||
.filter { element ->
|
||||
(element as? TomlTable)?.header?.key?.text?.let { key ->
|
||||
key in listOf("tool.poetry.dependencies", "tool.poetry.dev-dependencies") ||
|
||||
poetryGroupRegex matches key
|
||||
} ?: false
|
||||
}.flatMap {
|
||||
it.children.mapNotNull { line -> line as? TomlKeyValue }
|
||||
}.forEach { keyValue ->
|
||||
val packageName = PyPackageName.normalizePackageName(keyValue.key.text)
|
||||
val outdatedVersion = PythonPackageManager.forSdk(module.project, sdk).listOutdatedPackagesSnapshot()[packageName]
|
||||
if (outdatedVersion != null) {
|
||||
val message = PyBundle.message("python.sdk.inspection.message.version.outdated.latest",
|
||||
packageName, outdatedVersion.version, outdatedVersion.latestVersion)
|
||||
holder.registerProblem(keyValue, message, ProblemHighlightType.WARNING)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
[tool.poetry]
|
||||
name = "pythonproject15"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
<weak_warning descr="'django' version 1.3.1 is outdated (latest: 5.0.0)">django = "=1.3.1"</weak_warning>
|
||||
<warning descr="Package numpy is not installed">numpy = "*"</warning>
|
||||
<warning descr="Package pandas is not installed">pandas = "=1.0.0"</warning>
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
<weak_warning descr="'flask' version 1.0 is outdated (latest: 3.0.0)">flask = "=1.0"</weak_warning>
|
||||
requests = "=1.22.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
Vendored
-19
@@ -60,23 +60,4 @@ class CondaDependenciesInspectionProviderTest : PythonDependencyTestCase() {
|
||||
}
|
||||
|
||||
override fun getBasePath(): String = "/community/python/testData/conda/environmentYml/inspections/"
|
||||
|
||||
/**
|
||||
* Marks the SDK as tracking `environment.yml` as its declared-dependencies root (associating it with
|
||||
* the module dir that holds the file) so the package manager's dependency-file cache tracks it — the
|
||||
* gate in [com.jetbrains.python.inspections.dependencies.DependenciesInspection] reads that cache. The
|
||||
* real conda manager exposes `environment.yml` as its root unconditionally; the test manager keys this
|
||||
* off SDK user data. Init is then forced so the cache is seeded before highlighting runs.
|
||||
*/
|
||||
private fun markEnvironmentYmlAsDependencyRoot() {
|
||||
val sdk = myFixture.project.pythonSdk!!
|
||||
sdk.putUserData(TestPythonPackageManager.REQUIREMENTS_PROVIDER_KEY, RequirementsProviderType.ENVIRONMENT_YML)
|
||||
val moduleDir = myFixture.findFileInTempDir("environment.yml").parent
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
val modificator = sdk.sdkModificator
|
||||
(modificator.sdkAdditionalData as PythonSdkAdditionalData).associatedModulePath = moduleDir.path
|
||||
modificator.commitChanges()
|
||||
}
|
||||
runBlocking { PythonPackageManager.forSdk(myFixture.project, sdk).waitForInit() }
|
||||
}
|
||||
}
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.python.junit5Tests.env.poetry.legacy
|
||||
|
||||
import com.intellij.codeInspection.ex.InspectionProfileImpl
|
||||
import com.intellij.testFramework.TestDataPath
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.inspections.dependencies.DependenciesInspection
|
||||
import com.jetbrains.python.packaging.common.PythonOutdatedPackage
|
||||
import com.jetbrains.python.packaging.common.PythonPackage
|
||||
import com.jetbrains.python.packaging.management.RequirementsProviderType
|
||||
import com.jetbrains.python.packaging.management.TestPackageManagerProvider
|
||||
import com.jetbrains.python.requirements.PythonDependencyTestCase
|
||||
import com.jetbrains.python.sdk.PythonSdkAdditionalData
|
||||
import com.jetbrains.python.sdk.poetry.PyPoetrySdkAdditionalData
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
|
||||
@TestDataPath($$"$CONTENT_ROOT/../testData/poetry/legacy/inspections")
|
||||
internal class LegacyPoetryDependenciesInspectionProviderTest : PythonDependencyTestCase() {
|
||||
fun testLegacyPoetryDependenciesInspectionProvider() {
|
||||
val provider =
|
||||
TestPackageManagerProvider()
|
||||
.withPackageInstalled(
|
||||
PythonPackage("python", "3.9", false),
|
||||
PythonPackage("django", "1.3.1", false),
|
||||
PythonPackage("flask", "1.0", false),
|
||||
PythonPackage("requests", "1.22.0", false)
|
||||
)
|
||||
.withOutdatedPackages(
|
||||
PythonOutdatedPackage("django", "1.3.1", "5.0.0"),
|
||||
PythonOutdatedPackage("flask", "1.0", "3.0.0"),
|
||||
)
|
||||
initTestPackageManager(provider)
|
||||
|
||||
myFixture.copyDirectoryToProject(getTestName(false), "")
|
||||
setDependencyRoot(RequirementsProviderType.PYPROJECT_TOML)
|
||||
myFixture.configureFromTempProjectFile("pyproject.toml")
|
||||
|
||||
myFixture.enableInspections(DependenciesInspection::class.java)
|
||||
myFixture.checkHighlighting(true, false, true, false)
|
||||
|
||||
for (pkg in listOf("django", "flask")) {
|
||||
val offset = myFixture.editor.document.text.indexOf("$pkg =")
|
||||
myFixture.editor.caretModel.moveToOffset(offset)
|
||||
|
||||
val availableIntentions = myFixture.availableIntentions.map { it.text }
|
||||
val updateFixText = PyBundle.message("QFIX.NAME.update.requirement", pkg)
|
||||
|
||||
assertContainsElements(availableIntentions, updateFixText)
|
||||
assertContainsElements(availableIntentions, PyBundle.message("QFIX.NAME.update.all.requirements"))
|
||||
}
|
||||
|
||||
for (pkg in listOf("numpy")) {
|
||||
val offset = myFixture.editor.document.text.indexOf("$pkg =")
|
||||
myFixture.editor.caretModel.moveToOffset(offset)
|
||||
|
||||
val availableIntentions = myFixture.availableIntentions.map { it.text }
|
||||
val installFixText = PyBundle.message("QFIX.NAME.install.requirement", pkg)
|
||||
|
||||
assertContainsElements(availableIntentions, installFixText)
|
||||
assertContainsElements(availableIntentions, PyBundle.message("QFIX.NAME.install.all.requirements"))
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
InspectionProfileImpl.INIT_INSPECTIONS = true
|
||||
myFixture.project.pythonSdk = projectDescriptor.sdk
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
InspectionProfileImpl.INIT_INSPECTIONS = false
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
override val sdkAdditionalData: PythonSdkAdditionalData
|
||||
get() = PyPoetrySdkAdditionalData(null)
|
||||
|
||||
override fun getBasePath(): String = "/community/python/testData/poetry/legacy/inspections/"
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.testFramework.ExtensionTestUtil
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import com.jetbrains.env.python.testing.PythonNoseTestingTest
|
||||
import com.jetbrains.python.PyNames
|
||||
import com.jetbrains.python.PythonMockSdk
|
||||
import com.jetbrains.python.PythonTestUtil
|
||||
@@ -74,7 +75,7 @@ abstract class PythonDependencyTestCase : BasePlatformTestCase() {
|
||||
"${PythonTestUtil.getTestDataPath()}/MockSdk", PythonSdkType.getInstance(), languageLevel,
|
||||
*additionalRoots)
|
||||
sdk.sdkModificator.let {
|
||||
it.sdkAdditionalData = PythonSdkAdditionalData()
|
||||
it.sdkAdditionalData = sdkAdditionalData ?: PythonSdkAdditionalData()
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
it.commitChanges()
|
||||
}
|
||||
@@ -84,6 +85,8 @@ abstract class PythonDependencyTestCase : BasePlatformTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
open val sdkAdditionalData: PythonSdkAdditionalData? = null
|
||||
|
||||
override fun getBasePath(): String {
|
||||
return "/community/python/testData/requirements/"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user