From bb9eaa515c480bc7956b138b7079efacb7684fbb Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Mon, 23 Feb 2026 21:48:05 +0100 Subject: [PATCH] PY-87889: Fix module root duplication. Apparently, the result of `createEntitySource` can't be reused. It acts as a key in a map, so using same source for different modules breaks everything. Test checks it, and we also need to disable external storage to store files in `.idea` (cherry picked from commit 796b582d4d3cde9158d9fcfae910cde54886c24b) IJ-CR-193095 GitOrigin-RevId: 8e117832070c1dff3e5ad6970908eb43208f73c4 --- .../openapi/project/ProjectUtilCore.kt | 19 ++++++++++++++++++- .../workspaceBridge/workspaceTools.kt | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.kt b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.kt index 51767bbba301..1c360856ca86 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.kt +++ b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.kt @@ -1,5 +1,6 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. @file:JvmName("ProjectUtilCore") + package com.intellij.openapi.project import com.intellij.ide.highlighter.ProjectFileType @@ -18,6 +19,7 @@ import com.intellij.util.PathUtil import com.intellij.util.PlatformUtils import com.intellij.util.io.URLUtil import com.intellij.workspaceModel.ide.presentableName +import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.TestOnly @NlsSafe @@ -106,6 +108,21 @@ val Project.isExternalStorageEnabled: Boolean */ @TestOnly fun doNotEnableExternalStorageByDefaultInTests(action: () -> Unit) { + doNotEnableExternalStorageByDefaultInTestsImpl(action) +} + +/** + * @see [doNotEnableExternalStorageByDefaultInTests] + */ +@ApiStatus.Internal +@TestOnly +suspend fun doNotEnableExternalStorageByDefaultInTestsSuspend(action: suspend () -> Unit) { + doNotEnableExternalStorageByDefaultInTestsImpl { + action() + } +} + +private inline fun doNotEnableExternalStorageByDefaultInTestsImpl(action: () -> Unit) { enableExternalStorageByDefaultInTests = false try { action() @@ -113,4 +130,4 @@ fun doNotEnableExternalStorageByDefaultInTests(action: () -> Unit) { finally { enableExternalStorageByDefaultInTests = true } -} +} \ No newline at end of file diff --git a/python/python-pyproject/src/com/intellij/python/pyproject/model/internal/workspaceBridge/workspaceTools.kt b/python/python-pyproject/src/com/intellij/python/pyproject/model/internal/workspaceBridge/workspaceTools.kt index 8f5305bac0cd..d119b901db02 100644 --- a/python/python-pyproject/src/com/intellij/python/pyproject/model/internal/workspaceBridge/workspaceTools.kt +++ b/python/python-pyproject/src/com/intellij/python/pyproject/model/internal/workspaceBridge/workspaceTools.kt @@ -212,9 +212,8 @@ private suspend fun createProjectModel( ): ImmutableEntityStorage = withContext(Dispatchers.Default) { val virtualFileUrlManager = project.workspaceModel.getVirtualFileUrlManager() val storage = MutableEntityStorage.create() - val entitySource = createEntitySource(project) for (pyProject in graph) { - val moduleEntity = storage addEntity ModuleEntity(pyProject.name.name, emptyList(), entitySource) { + val moduleEntity = storage addEntity ModuleEntity(pyProject.name.name, emptyList(), createEntitySource(project)) { dependencies += ModuleSourceDependency for (moduleName in pyProject.dependencies) { dependencies += ModuleDependency(ModuleId(moduleName.name), true, DependencyScope.COMPILE, false) @@ -312,6 +311,7 @@ private class ModuleAnchor(moduleEntity: ModuleEntity) { (theOnlyContentRoot != null && theOnlyContentRoot.url == o.theOnlyContentRoot?.url) } +// Warning: this entity must be unique for each model, it can't be reused internal fun createEntitySource(project: Project): EntitySource { val moduleRoot = project.stateStore.projectBasePath.resolve(DIRECTORY_STORE_FOLDER).toVirtualFileUrl(project.workspaceModel.getVirtualFileUrlManager())