scripts/tests/reproduction_utils/test_remove_imported_name.py
scripts/tests/reproduction_utils/test_remove_imported_name.pyBrowse 41 files
1,806 tokens
6,334 bytes
Token encoding: o200k_base
Snapshot a9fb1c3
← Back to SKILL.md
1import subprocess2import sys3from pathlib import Path4 5import pytest6 7sys.path.insert(0, str(Path(__file__).resolve().parents[2]))8 9import mechanical_refactor_reproduction_utils as rr10from mechanical_refactor_reproduction_utils import (11 Repro,12 _def_span,13 _find_class,14 _find_def,15 _replace_span,16 _slice_span,17 dedent,18 exec_command,19 git_add_and_commit,20 verify_mechanical_refactor,21)22from reproduction_testlib import _apply, _commit, _git, _write # noqa: F40123 24# --- remove_imported_name ------------------------------------------------------25 26 27def test_remove_imported_name_drops_one_name_from_a_multi_name_import(28 tmp_path: Path,29) -> None:30 """One name is dropped from a `from m import a, b, c`; the others stay on the line."""31 (tmp_path / "m.py").write_text("from pkg import a, moved, b\n\nx = a + b\n")32 r = Repro("b", "t").remove_imported_name("m.py", module="pkg", name="moved")33 _apply(r, tmp_path)34 assert (tmp_path / "m.py").read_text() == "from pkg import a, b\n\nx = a + b\n"35 36 37def test_remove_imported_name_drops_whole_statement_when_sole_name(38 tmp_path: Path,39) -> None:40 """Dropping the only name removes the whole `from` statement."""41 (tmp_path / "m.py").write_text("from pkg import moved\nimport os\n\nx = 1\n")42 r = Repro("b", "t").remove_imported_name("m.py", module="pkg", name="moved")43 _apply(r, tmp_path)44 assert (tmp_path / "m.py").read_text() == "import os\n\nx = 1\n"45 46 47def test_remove_imported_name_drops_a_plain_import_with_module_none(48 tmp_path: Path,49) -> None:50 """With module=None a plain `import name` statement is removed."""51 (tmp_path / "m.py").write_text("import gc\nimport os\n\nx = 1\n")52 r = Repro("b", "t").remove_imported_name("m.py", module=None, name="gc")53 _apply(r, tmp_path)54 assert (tmp_path / "m.py").read_text() == "import os\n\nx = 1\n"55 56 57def test_remove_imported_name_matches_an_asname(tmp_path: Path) -> None:58 """The alias is matched on both the name and the asname, so `import numpy as np` is found."""59 (tmp_path / "m.py").write_text("import numpy as np\nimport os\n\nx = 1\n")60 r = Repro("b", "t").remove_imported_name(61 "m.py", module=None, name="numpy", asname="np"62 )63 _apply(r, tmp_path)64 assert (tmp_path / "m.py").read_text() == "import os\n\nx = 1\n"65 66 67def test_remove_imported_name_asserts_when_absent(tmp_path: Path) -> None:68 """Removing a name that is not imported raises, so a wrong recipe fails loudly."""69 (tmp_path / "m.py").write_text("from pkg import a, b\n")70 r = Repro("b", "t").remove_imported_name("m.py", module="pkg", name="missing")71 with pytest.raises(AssertionError):72 _apply(r, tmp_path)73 74 75# --- add_import ----------------------------------------------------------------76 77 78def test_remove_imported_name_preserves_the_multiline_form(79 tmp_path: Path,80) -> None:81 """Pruning a name from an exploded import deletes only that line, so the parens and the82 magic trailing comma survive and the formatter keeps it multi-line (a flat rebuild would83 collapse an import the target left multi-line)."""84 (tmp_path / "m.py").write_text(85 "from pkg import (\n a,\n moved,\n b,\n)\n\nx = a + b\n"86 )87 r = Repro("b", "t").remove_imported_name("m.py", module="pkg", name="moved")88 _apply(r, tmp_path)89 assert (90 tmp_path / "m.py"91 ).read_text() == "from pkg import (\n a,\n b,\n)\n\nx = a + b\n"92 93 94def test_remove_imported_name_multiline_down_to_one_collapses(95 tmp_path: Path,96) -> None:97 """Pruning an exploded import down to a single surviving name collapses it to one line:98 the formatter does not keep a lone name exploded, so a preserved-multiline form would99 not match the target."""100 (tmp_path / "m.py").write_text(101 "from pkg import (\n moved,\n a,\n)\n\nx = a\n"102 )103 r = Repro("b", "t").remove_imported_name("m.py", module="pkg", name="moved")104 _apply(r, tmp_path)105 assert (tmp_path / "m.py").read_text() == "from pkg import a\n\nx = a\n"106 107 108def test_remove_imported_name_down_to_one_with_a_comment_stays_exploded(109 tmp_path: Path,110) -> None:111 """A lone survivor that carries a comment stays exploded (a rebuild would drop the112 comment); only its own line is deleted."""113 (tmp_path / "m.py").write_text(114 "from pkg import (\n moved,\n a, # keep me\n)\n\nx = a\n"115 )116 r = Repro("b", "t").remove_imported_name("m.py", module="pkg", name="moved")117 _apply(r, tmp_path)118 assert (119 tmp_path / "m.py"120 ).read_text() == "from pkg import (\n a, # keep me\n)\n\nx = a\n"121 122 123def test_remove_imported_name_matches_a_relative_module(tmp_path: Path) -> None:124 """A relative `from .pkg import` is matched via its level dots."""125 (tmp_path / "m.py").write_text("from .pkg import a, moved\n\nx = a\n")126 r = Repro("b", "t").remove_imported_name("m.py", module=".pkg", name="moved")127 _apply(r, tmp_path)128 assert (tmp_path / "m.py").read_text() == "from .pkg import a\n\nx = a\n"129 130 131def test_remove_imported_name_preserves_comments_in_a_multiline_import(132 tmp_path: Path,133) -> None:134 """Comments on surviving lines of a pruned parenthesized import must not vanish."""135 (tmp_path / "m.py").write_text(136 "from pkg import (\n"137 " a, # used by frobnicator\n"138 " moved,\n"139 " b,\n"140 ")\n"141 "\n"142 "x = a + b\n"143 )144 r = Repro("b", "t").remove_imported_name("m.py", module="pkg", name="moved")145 _apply(r, tmp_path)146 assert "# used by frobnicator" in (tmp_path / "m.py").read_text()147 148 149def test_remove_imported_name_keep_exploded_holds_a_lone_survivor_multiline(150 tmp_path: Path,151) -> None:152 """With keep_exploded, pruning down to a single survivor deletes only the removed line,153 so the survivor keeps its magic trailing comma and the import stays multi-line (the154 author's choice, which the source cannot reveal). A regenerating impl would collapse.155 """156 (tmp_path / "m.py").write_text(157 "from pkg import (\n moved,\n a,\n)\n\nx = a\n"158 )159 r = Repro("b", "t").remove_imported_name(160 "m.py", module="pkg", name="moved", keep_exploded=True161 )162 _apply(r, tmp_path)163 assert (tmp_path / "m.py").read_text() == "from pkg import (\n a,\n)\n\nx = a\n"164