MoveModule creates new top-level imports
Maintainer antworten meist innerhalb von 7 Tagen
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 42/100
Rechercherichtung
The extra top-level import comes from rope/refactor/move.py, around the lines the reporter links (roughly 594-596 and 769-773). Start by running the reproducer in the issue, which moves lazy.py into prefix/ while utils.py imports it inside a function, and check where the import is added to the module header. Done means the function-local import is rewritten in place and no new top-level import appears, with the existing move tests still passing.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Describe the bug
When MoveModule encounters an import statement inside a function (thus, evaluated at some unknown point later and maybe never), and the import statement concerns the module being moved, the calculated changes include both a modification of the original import statement and an extraneous import statement at the top of the file. This changes the order of imports and, in sufficiently cursed code-bases, may even result in a circular import.
Basically, the issue is that MoveModule appears to consider imports to be side effect-free, which sometimes they aren't.
The extra import is being added here:
https://github.com/python-rope/rope/blob/25586a6c6d4eb339fdf09188c195d24b43970efb/rope/refactor/move.py#L594-L596
https://github.com/python-rope/rope/blob/25586a6c6d4eb339fdf09188c195d24b43970efb/rope/refactor/move.py#L769-L773
To Reproduce
Steps to reproduce the behavior:
- Code before refactoring:
# a.py
def use_b_later():
import b
# b.py
import a
- Describe the refactoring you want to do
Rename (move) b into prefix.b.
- Expected code after refactoring:
# a.py
def use_b_later():
import prefix.b
# b.py
import a
- Describe the error or unexpected result that you are getting
# a.py
import prefix.b
def use_b_later():
import prefix.b
# b.py
import a
Reproducible example
$ python << EOF
import shutil
import tempfile
from contextlib import contextmanager
from os import walk
from pathlib import Path
from rope.base.project import Project
from rope.refactor.move import MoveModule
@contextmanager
def temp_tree():
path = tempfile.mkdtemp()
try:
yield Path(path)
finally:
shutil.rmtree(path, ignore_errors=True)
with temp_tree() as root:
(root / "utils.py").write_text(
"""
def use_lazy():
import lazy"""
)
(root / "lazy.py").write_text(
"""
import utils"""
)
(root / "prefix").mkdir()
(root / "prefix" / "__init__.py").touch()
project = Project(root)
new_package = project.get_folder("prefix")
lazy = project.get_module("lazy").get_resource()
print(MoveModule(project, lazy).get_changes(new_package).get_description())
EOF
Moving module <lazy>:
--- a/lazy.py
+++ b/lazy.py
@@ -1,2 +1 @@
-
-import utils+import utils
--- a/utils.py
+++ b/utils.py
@@ -1,3 +1,3 @@
-
+import prefix.lazy
def use_lazy():
- import lazy+ import prefix.lazy
rename from lazy.py
rename to prefix/lazy.py
Editor information (please complete the following information):
- Project Python version: 3.11
- Rope Python version: 3.11
- Rope version: 1.11.0 (also checked 1.9.0)
- Text editor/IDE and version: ...
Additional context
Context: trying to use Rope for some automation in https://github.com/SomeoneSerge/pkgs/blob/master/python-packages/by-name/pr/prefix-python-modules/prefix_python_modules.py
- Vorherrschende Sprache
- Python
- Sterne
- 2.2k
- Forks
- 197
- Ø Merge
- 2 T. 13 Std.
- Gemergte PRs (30 T.)
- 5
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus python-rope/rope
-
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 88/100
python-rope/rope#927 ·
Maintainer antworten meist innerhalb von 7 Tagen
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
python-rope/rope#926 ·
Maintainer antworten meist innerhalb von 7 Tagen
-
simplify.real_code blanks t-strings, so renames inside them edit the wrong offsetEvtl. vergeben @sean0407 hat das vor 10 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 83/100
python-rope/rope#913 ·
Maintainer antworten meist innerhalb von 7 Tagen
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 30/100
python-rope/rope#925 ·
Maintainer antworten meist innerhalb von 7 Tagen
-
Extract method/variable and introduce parameter don't check whether the new name is already in useOffen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 62/100
python-rope/rope#924 ·
Maintainer antworten meist innerhalb von 7 Tagen
Alle Issues in python-rope/rope
Ähnliche Issues
-
cost:cheap practicality:seen-in-the-wild severity:medium
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
fairagro/m4.2_advanced_middleware_api#620 ·
Maintainer antworten meist innerhalb von 1 Tag
-
area:security effort:S priority:P2 provider:local-libvirt status:ready type:docs
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
randomparity/kdive#3495 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
microsoft/markitdown#2820 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 2 Tagen