PY-10553 Correctly update "from imports" if moved module and imported symbol share name

Check that reference to moved module is contained in PyImportElement
part of a "from import" statement before calling
PyClassRefactoringUtil#updateImportOfElement. Because this method
relies solely on name equality, it can accidentally replace "from
import" of particular symbol from module with the "from import" of that
module itself.
This commit is contained in:
Mikhail Golubev
2015-06-17 13:56:47 +03:00
parent 68c7b251c9
commit c628ec5221
11 changed files with 46 additions and 1 deletions
@@ -428,6 +428,14 @@ public final class PyClassRefactoringUtil {
});
}
/**
* Updates the import statement if the given PSI element <em>has the same name</em> as one of the import elements of that statement.
* It means that you should be careful it you actually want to update the source part of a "from import" statement, because in cases
* like {@code from foo import foo} this method may do not what you expect.
*
* @param importStatement parent import statement that contains reference to given element
* @param element PSI element reference to which should be updated
*/
public static void updateImportOfElement(@NotNull PyImportStatementBase importStatement, @NotNull PsiNamedElement element) {
final String name = getOriginalName(element);
if (name != null) {
@@ -178,7 +178,9 @@ public class PyMoveFileHandler extends MoveFileHandler {
// TODO: Retarget qualified expressions in docstrings
if (importStmt != null) {
updatedFiles.add(file);
PyClassRefactoringUtil.updateImportOfElement(importStmt, newElement);
if (PsiTreeUtil.getParentOfType(element, PyImportElement.class) != null) {
PyClassRefactoringUtil.updateImportOfElement(importStmt, newElement);
}
if (importStmt instanceof PyFromImportStatement && PsiTreeUtil.getParentOfType(element, PyImportElement.class) != null) {
continue;
}
@@ -0,0 +1,4 @@
from Animals.test.Carnivore import Carnivore
class Cat(Carnivore):
pass
@@ -0,0 +1,9 @@
# encoding: utf-8
#
#
#
# Author: Markus Thielen
#
# Copyright (c) 2013 thi.guten Software Development
#
__author__ = 'east825'
@@ -0,0 +1,2 @@
class Carnivore(object):
pass
@@ -0,0 +1,2 @@
class Carnivore(object):
pass
@@ -0,0 +1,4 @@
from Animals.Carnivore import Carnivore
class Cat(Carnivore):
pass
@@ -0,0 +1,9 @@
# encoding: utf-8
#
#
#
# Author: Markus Thielen
#
# Copyright (c) 2013 thi.guten Software Development
#
__author__ = 'east825'
@@ -314,6 +314,11 @@ public class PyMoveTest extends PyTestCase {
}
}
// PY-10553
public void testMoveModuleWithSameNameAsSymbolInside() {
doMoveFileTest("Animals/Carnivore.py", "Animals/test");
}
// PY-15324
public void testInterdependentSymbols() {
doMoveSymbolsTest("b.py", "f", "A");