diff --git a/python/python-psi-impl/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesVisitor.java b/python/python-psi-impl/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesVisitor.java
index d0b7e75f4068..4df3304a1c02 100644
--- a/python/python-psi-impl/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesVisitor.java
+++ b/python/python-psi-impl/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesVisitor.java
@@ -365,7 +365,7 @@ public abstract class PyUnresolvedReferencesVisitor extends PyInspectionVisitor
isAddedToInstallAllFix = true;
}
- ContainerUtil.addAll(fixes, getAddSourceRootQuickFix(node));
+ ContainerUtil.addIfNotNull(fixes, getAddSourceRootQuickFix(node));
if (reference instanceof PySubstitutionChunkReference) {
return;
diff --git a/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc.py b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc.py
new file mode 100644
index 000000000000..017367c3abf0
--- /dev/null
+++ b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc.py
@@ -0,0 +1 @@
+from qwerty.qwe import a_function
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_after.py b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_after.py
new file mode 100644
index 000000000000..435222297827
--- /dev/null
+++ b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_after.py
@@ -0,0 +1 @@
+from qwerty.qwe import a_function
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_no_src.py b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_no_src.py
new file mode 100644
index 000000000000..45b77864201c
--- /dev/null
+++ b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_no_src.py
@@ -0,0 +1 @@
+from qwejfknqweklfnjqlkjwnef.qwe import a_function
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_no_src_after.py b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_no_src_after.py
new file mode 100644
index 000000000000..45b77864201c
--- /dev/null
+++ b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/foo/abc_no_src_after.py
@@ -0,0 +1 @@
+from qwejfknqweklfnjqlkjwnef.qwe import a_function
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/qwerty/qwe.py b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/qwerty/qwe.py
new file mode 100644
index 000000000000..09c086952171
--- /dev/null
+++ b/python/testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest/mysrc/qwerty/qwe.py
@@ -0,0 +1,5 @@
+def a_function():
+ pass
+
+def abc():
+ pass
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest.kt b/python/testSrc/com/jetbrains/python/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest.kt
new file mode 100644
index 000000000000..0e6d0d898938
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest.kt
@@ -0,0 +1,49 @@
+// 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.quickFixes
+
+import com.intellij.openapi.roots.ModuleRootManager
+import com.intellij.testFramework.TestDataPath
+import com.jetbrains.python.PyQuickFixTestCase
+import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection
+
+@TestDataPath("\$CONTENT_ROOT/../testData/quickFixes/PyMarkDirectoryAsSourceRootQuickFixTest")
+class PyMarkDirectoryAsSourceRootQuickFixTest: PyQuickFixTestCase() {
+ @Throws(Exception::class)
+ override fun setUp() {
+ super.setUp()
+ myFixture.copyDirectoryToProject("", "")
+ }
+
+ fun testUpdatesSourceRoots() = doSourceRootTest(pyFilePath = "mysrc/foo/abc.py", expectedSourceRootPath = "mysrc")
+
+ fun testNoQuickFixBecauseSourceRootNotFound() = doSourceRootTest(pyFilePath = "mysrc/foo/abc_no_src.py", expectedSourceRootPath = null)
+
+ private fun doSourceRootTest(
+ pyFilePath: String,
+ expectedSourceRootPath: String?
+ ) {
+ myFixture.enableInspections(PyUnresolvedReferencesInspection::class.java)
+ myFixture.configureByFile(pyFilePath)
+ myFixture.checkHighlighting(true, false, false)
+ val intentionAction = myFixture.filterAvailableIntentions(QUICK_FIX_NAME_BEGINNING)
+ if (expectedSourceRootPath == null) {
+ assertEmpty(intentionAction)
+ return
+ }
+ assertSize(1, intentionAction)
+ myFixture.launchAction(intentionAction[0])
+ myFixture.checkResultByFile(pyFilePath.removeSuffix(".py") + "_after.py", true)
+
+ val moduleRootManager = ModuleRootManager.getInstance(myFixture.module)
+ val sourceRoot = moduleRootManager.sourceRoots.firstOrNull {
+ it.path == TEST_PROJECT_ROOT_PATH + expectedSourceRootPath
+ }
+ assertNotNull("Source root '${expectedSourceRootPath}' not found.", sourceRoot)
+ }
+
+ companion object {
+ private const val TEST_PROJECT_ROOT_PATH = "/src/"
+ // QFIX.add.source.root.for.unresolved.import.name
+ private const val QUICK_FIX_NAME_BEGINNING = "Mark '"
+ }
+}