diff --git a/python/src/com/jetbrains/python/codeInsight/imports/PyImportOptimizer.java b/python/src/com/jetbrains/python/codeInsight/imports/PyImportOptimizer.java index 2aff60a1af4e..dd516ccc5c82 100644 --- a/python/src/com/jetbrains/python/codeInsight/imports/PyImportOptimizer.java +++ b/python/src/com/jetbrains/python/codeInsight/imports/PyImportOptimizer.java @@ -46,6 +46,15 @@ import static com.jetbrains.python.psi.PyUtil.as; */ public class PyImportOptimizer implements ImportOptimizer { + private boolean mySortImports = true; + + @NotNull + public static PyImportOptimizer onlyRemoveUnused() { + final PyImportOptimizer optimizer = new PyImportOptimizer(); + optimizer.mySortImports = false; + return optimizer; + } + @Override public boolean supports(PsiFile file) { return true; @@ -67,7 +76,7 @@ public class PyImportOptimizer implements ImportOptimizer { }); return () -> { visitor.optimizeImports(); - if (file instanceof PyFile) { + if (mySortImports && file instanceof PyFile) { new ImportSorter((PyFile)file).run(); } }; diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java index f5380a858f9a..5aa49466bcca 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java @@ -29,7 +29,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.psi.util.QualifiedName; import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.NotNullPredicate; @@ -568,7 +567,7 @@ public final class PyClassRefactoringUtil { * @param file file to optimize imports */ public static void optimizeImports(@NotNull final PsiFile file) { - new PyImportOptimizer().processFile(file).run(); + PyImportOptimizer.onlyRemoveUnused().processFile(file).run(); } /** diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java b/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java index 8c1ceabb94f1..f9e722ec5429 100644 --- a/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java +++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveFileHandler.java @@ -281,7 +281,7 @@ public class PyMoveFileHandler extends MoveFileHandler { } } if (!updatedFiles.isEmpty()) { - final PyImportOptimizer optimizer = new PyImportOptimizer(); + final PyImportOptimizer optimizer = PyImportOptimizer.onlyRemoveUnused(); for (PsiFile file : updatedFiles) { final boolean injectedFragment = InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file); if (!injectedFragment) { diff --git a/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/main.py b/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/main.py index 67efa660972e..9d377957d553 100644 --- a/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/main.py +++ b/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/main.py @@ -1,5 +1,5 @@ -from lib import C from lib import D +from lib import C class C3: diff --git a/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use1.py b/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use1.py index 8d4b5e36fda9..4322ccc478bf 100644 --- a/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use1.py +++ b/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use1.py @@ -1,5 +1,5 @@ -from lib import A, C from lib import B +from lib import A, C from other import C1, C2 print(C1, C2, A, B, C) diff --git a/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use2.py b/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use2.py index ecc3d4ad39b2..66fe92a1d1f5 100644 --- a/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use2.py +++ b/python/testData/refactoring/move/cleanupImportsAfterMove/after/src/use2.py @@ -1,6 +1,6 @@ -from lib import A, C -from lib import B from main import * +from lib import B +from lib import A, C from other import C1, C2 print(C1, C2, C3, A, B, C) \ No newline at end of file diff --git a/python/testData/refactoring/move/module/after/src/a.py b/python/testData/refactoring/move/module/after/src/a.py index 9e7a4b733d13..7db1d18a8ba9 100644 --- a/python/testData/refactoring/move/module/after/src/a.py +++ b/python/testData/refactoring/move/module/after/src/a.py @@ -1,6 +1,6 @@ -import p1 from p1 import m1 from p1.m1 import foo +import p1 p1.m1.foo m1.bar diff --git a/python/testData/refactoring/move/moduleToNonPackage/after/src/a.py b/python/testData/refactoring/move/moduleToNonPackage/after/src/a.py index 2bf66e2e5c79..ca4143ce7442 100644 --- a/python/testData/refactoring/move/moduleToNonPackage/after/src/a.py +++ b/python/testData/refactoring/move/moduleToNonPackage/after/src/a.py @@ -1,6 +1,6 @@ -import nonp3.m1 from nonp3 import m1 from nonp3.m1 import foo +import nonp3.m1 nonp3.m1.foo m1.bar diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/a.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/a.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/c.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/c.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/mod.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/mod.py new file mode 100644 index 000000000000..767cd8c95186 --- /dev/null +++ b/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/mod.py @@ -0,0 +1,5 @@ +import c +from pkg import b +import a + +print(a, b, c) diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/pkg/__init__.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/pkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/pkg/b.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/after/src/pkg/b.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/a.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/a.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/b.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/b.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/c.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/c.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/mod.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/mod.py new file mode 100644 index 000000000000..861f9ce242dd --- /dev/null +++ b/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/mod.py @@ -0,0 +1,5 @@ +import c +import b +import a + +print(a, b, c) diff --git a/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/pkg/__init__.py b/python/testData/refactoring/move/moveFileDoesntReorderImports/before/src/pkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/a.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/a.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/b.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/b.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/c.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/c.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/main.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/main.py new file mode 100644 index 000000000000..6788760947df --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/main.py @@ -0,0 +1,4 @@ +import c +import a + +print(a, c) diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/other.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/other.py new file mode 100644 index 000000000000..53f083bccdcb --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/after/src/other.py @@ -0,0 +1,5 @@ +import b + + +def func(): + print(b) \ No newline at end of file diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/a.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/a.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/b.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/b.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/c.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/c.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/main.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/main.py new file mode 100644 index 000000000000..e73e56603d61 --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/main.py @@ -0,0 +1,10 @@ +import c +import a +import b + + +def func(): + print(b) + + +print(a, c) diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/other.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInOriginFile/before/src/other.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/a.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/a.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/b.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/b.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/main.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/main.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/main.py @@ -0,0 +1 @@ + diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/other.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/other.py new file mode 100644 index 000000000000..06075aebd98e --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/other.py @@ -0,0 +1,2 @@ +def func(): + pass \ No newline at end of file diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/usage.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/usage.py new file mode 100644 index 000000000000..c880023945ee --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/after/src/usage.py @@ -0,0 +1,5 @@ +import b +import a +from other import func + +print(func, a, b) \ No newline at end of file diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/a.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/a.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/b.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/b.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/main.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/main.py new file mode 100644 index 000000000000..b9bfa6f12339 --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/main.py @@ -0,0 +1,2 @@ +def func(): + pass diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/other.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/other.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/usage.py b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/usage.py new file mode 100644 index 000000000000..fa3f2dde4db2 --- /dev/null +++ b/python/testData/refactoring/move/moveSymbolDoesntReorderImportsInUsageFile/before/src/usage.py @@ -0,0 +1,5 @@ +from main import * +import b +import a + +print(func, a, b) \ No newline at end of file diff --git a/python/testData/refactoring/move/optimizeImportsAfterMoveInvalidatesMembersToBeMoved/after/src/src.py b/python/testData/refactoring/move/optimizeImportsAfterMoveInvalidatesMembersToBeMoved/after/src/src.py index 5988d1e0e873..1bc2fd45db35 100644 --- a/python/testData/refactoring/move/optimizeImportsAfterMoveInvalidatesMembersToBeMoved/after/src/src.py +++ b/python/testData/refactoring/move/optimizeImportsAfterMoveInvalidatesMembersToBeMoved/after/src/src.py @@ -16,9 +16,11 @@ # You should have received a copy of the GNU General Public License # along with Serviceform. If not, see . import datetime - -import logging import string +import logging +from enum import Enum +from typing import Tuple, Set, Optional, Sequence, Iterator, Iterable, TYPE_CHECKING + from colorful.fields import RGBColorField from django.conf import settings from django.contrib.contenttypes.fields import GenericRelation @@ -30,19 +32,19 @@ from django.utils import timezone from django.utils.functional import cached_property from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ -from enum import Enum from guardian.shortcuts import get_users_with_perms from select2 import fields as select2_fields -from serviceform.tasks.models import Task -from typing import Tuple, Set, Optional, Sequence, Iterator, Iterable, TYPE_CHECKING -from .email import EmailTemplate -from .mixins import CopyMixin -from .participation import QuestionAnswer -from .people import Participant, ResponsibilityPerson +from serviceform.tasks.models import Task + from .. import emails, utils from ..utils import ColorStr +from .mixins import CopyMixin +from .people import Participant, ResponsibilityPerson +from .email import EmailTemplate +from .participation import QuestionAnswer + if TYPE_CHECKING: from .participation import ParticipationActivity, ParticipationActivityChoice diff --git a/python/testData/refactoring/move/relativeImportsInsideMovedModule/after/src/subpkg1/mod1.py b/python/testData/refactoring/move/relativeImportsInsideMovedModule/after/src/subpkg1/mod1.py index dfeddbb5c665..e9cea1c3d39b 100644 --- a/python/testData/refactoring/move/relativeImportsInsideMovedModule/after/src/subpkg1/mod1.py +++ b/python/testData/refactoring/move/relativeImportsInsideMovedModule/after/src/subpkg1/mod1.py @@ -1,15 +1,15 @@ -import -# malformed imports -from -from - -# absolute imports -import pkg1.subpkg2 as foo from pkg1 import subpkg2 -from pkg1 import subpkg2 as bar -from pkg1.subpkg2 import from pkg1.subpkg2 import mod2 from pkg1.subpkg2.mod2 import VAR from . import mod3 +# malformed imports +from +from import +from pkg1.subpkg2 import + +# absolute imports +import pkg1.subpkg2 as foo +from pkg1 import subpkg2 as bar + print(subpkg2, mod3, mod2, foo, bar, VAR) diff --git a/python/testData/refactoring/move/relativeImportsToModulesInSameMovedPackageNotUpdated/after/src/subpkg/m1.py b/python/testData/refactoring/move/relativeImportsToModulesInSameMovedPackageNotUpdated/after/src/subpkg/m1.py index 0f20d9f414da..4a40476cffa0 100644 --- a/python/testData/refactoring/move/relativeImportsToModulesInSameMovedPackageNotUpdated/after/src/subpkg/m1.py +++ b/python/testData/refactoring/move/relativeImportsToModulesInSameMovedPackageNotUpdated/after/src/subpkg/m1.py @@ -1,8 +1,8 @@ +from . import m2 import m3 import subsubpkg as foo -from pkg import m5 -from . import m2 from . import subsubpkg as bar from .subsubpkg import m4 +from pkg import m5 print(m2, m3, m4, m5, foo, bar) diff --git a/python/testData/refactoring/pullup/fieldMove/Class.after.py b/python/testData/refactoring/pullup/fieldMove/Class.after.py index e717954de1e0..5775da7f999a 100644 --- a/python/testData/refactoring/pullup/fieldMove/Class.after.py +++ b/python/testData/refactoring/pullup/fieldMove/Class.after.py @@ -1,6 +1,5 @@ from SuperClass import SuperClass - class AnyClass(SuperClass): def __init__(self): diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java index 88daa78d30b5..2db733c9c84f 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyMoveTest.java @@ -403,6 +403,21 @@ public class PyMoveTest extends PyTestCase { doMoveSymbolsTest("other.py", "C1", "C2"); } + // PY-18216 + public void testMoveSymbolDoesntReorderImportsInOriginFile() { + doMoveSymbolTest("func", "other.py"); + } + + // PY-18216 + public void testMoveSymbolDoesntReorderImportsInUsageFile() { + doMoveSymbolTest("func", "other.py"); + } + + // PY-18216 + public void testMoveFileDoesntReorderImports() { + doMoveFileTest("b.py", "pkg"); + } + private void doMoveFileTest(String fileName, String toDirName) { Project project = myFixture.getProject(); PsiManager manager = PsiManager.getInstance(project);