From 861247150d7a06b5fb7d2994f937dbda2be0df1b Mon Sep 17 00:00:00 2001 From: chbndrhnns Date: Fri, 21 Nov 2025 16:24:25 +1000 Subject: [PATCH] [PY-84659] Moving a symbol respects `PyCodeInsightSettings.PREFER_FROM_IMPORT` for qualified usages (cherry picked from commit 00c7867db4fa463c6a2eabb32bfa181bb25311d6) GitOrigin-RevId: 83c0b47a97bbbd8f74279766eecefc05b3381784 --- .../move/moduleMembers/PyMoveSymbolProcessor.java | 15 ++++++++++++--- .../after/src/client.py | 3 +++ .../after/src/lib/__init__.py | 0 .../after/src/lib/dst.py | 2 ++ .../after/src/lib/src.py | 1 + .../before/src/client.py | 3 +++ .../before/src/lib/__init__.py | 0 .../before/src/lib/src.py | 2 ++ .../jetbrains/python/refactoring/PyMoveTest.java | 13 +++++++++++++ 9 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/client.py create mode 100644 python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/__init__.py create mode 100644 python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/dst.py create mode 100644 python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/src.py create mode 100644 python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/client.py create mode 100644 python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/lib/__init__.py create mode 100644 python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/lib/src.py diff --git a/python/src/com/jetbrains/python/refactoring/move/moduleMembers/PyMoveSymbolProcessor.java b/python/src/com/jetbrains/python/refactoring/move/moduleMembers/PyMoveSymbolProcessor.java index 9d56af6d8f82..26a3623e0449 100644 --- a/python/src/com/jetbrains/python/refactoring/move/moduleMembers/PyMoveSymbolProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/move/moduleMembers/PyMoveSymbolProcessor.java @@ -11,6 +11,7 @@ import com.intellij.psi.util.QualifiedName; import com.intellij.usageView.UsageInfo; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyNames; +import com.jetbrains.python.codeInsight.PyCodeInsightSettings; import com.jetbrains.python.codeInsight.PyDunderAllReference; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; @@ -214,9 +215,17 @@ public class PyMoveSymbolProcessor { final LanguageLevel languageLevel = LanguageLevel.forElement(expression); if (srcFile != expression.getContainingFile()) { final QualifiedName qualifier = QualifiedNameFinder.findCanonicalImportPath(srcFile, expression); - PyPsiRefactoringUtil.insertImport(expression, srcFile, null, false); - final String newQualifiedReference = qualifier + "." + expression.getReferencedName(); - expression.replace(generator.createExpressionFromText(languageLevel, newQualifiedReference)); + if (PyCodeInsightSettings.getInstance().PREFER_FROM_IMPORT) { + PyPsiRefactoringUtil.insertImport(expression, srcFile, null, true); + final String moduleName = qualifier.getLastComponent(); + final String newQualifiedReference = moduleName + "." + expression.getReferencedName(); + expression.replace(generator.createExpressionFromText(languageLevel, newQualifiedReference)); + } + else { + PyPsiRefactoringUtil.insertImport(expression, srcFile, null, false); + final String newQualifiedReference = qualifier + "." + expression.getReferencedName(); + expression.replace(generator.createExpressionFromText(languageLevel, newQualifiedReference)); + } } else { expression.replace(generator.createExpressionFromText(languageLevel, expression.getReferencedName())); diff --git a/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/client.py b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/client.py new file mode 100644 index 000000000000..989b6dcbb770 --- /dev/null +++ b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/client.py @@ -0,0 +1,3 @@ +from lib import src, dst + +assert dst.C diff --git a/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/__init__.py b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/dst.py b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/dst.py new file mode 100644 index 000000000000..646b07aed7f4 --- /dev/null +++ b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/dst.py @@ -0,0 +1,2 @@ +class C: + pass diff --git a/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/src.py b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/src.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/after/src/lib/src.py @@ -0,0 +1 @@ + diff --git a/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/client.py b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/client.py new file mode 100644 index 000000000000..b08c3fb31a5b --- /dev/null +++ b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/client.py @@ -0,0 +1,3 @@ +from lib import src + +assert src.C diff --git a/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/lib/__init__.py b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/lib/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/lib/src.py b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/lib/src.py new file mode 100644 index 000000000000..646b07aed7f4 --- /dev/null +++ b/python/testData/refactoring/move/qualifiedUsageRespectsPreferFromImport/before/src/lib/src.py @@ -0,0 +1,2 @@ +class C: + pass diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java index c86b5c18faf5..da52b86564bc 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java @@ -3,6 +3,7 @@ package com.jetbrains.python.refactoring; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.idea.TestFor; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -282,6 +283,18 @@ public class PyMoveTest extends PyTestCase { } } + @TestFor(issues="PY-84659") + public void testQualifiedUsageRespectsPreferFromImport() { + final boolean defaultImportStyle = PyCodeInsightSettings.getInstance().PREFER_FROM_IMPORT; + try { + PyCodeInsightSettings.getInstance().PREFER_FROM_IMPORT = true; + doMoveSymbolTest("C", "lib/dst.py"); + } + finally { + PyCodeInsightSettings.getInstance().PREFER_FROM_IMPORT = defaultImportStyle; + } + } + // PY-10553 public void testMoveModuleWithSameNameAsSymbolInside() { doMoveFileTest("Animals/Carnivore.py", "Animals/test");