@@ -582,6 +582,111 @@ def new_func():
582582 mod2 .read (),
583583 )
584584
585+ def test_renaming_external_import_preserves_imported_name (self ):
586+ self .project .prefs .add ("extension_modules" , "builtins" )
587+ code = "from builtins import zip\n result = list(zip([1], [2]))\n "
588+ refactored = self ._local_rename (code , code .rindex ("zip" ), "pairs" )
589+ self .assertEqual (
590+ "from builtins import zip as pairs\n result = list(pairs([1], [2]))\n " ,
591+ refactored ,
592+ )
593+ namespace = {}
594+ exec (refactored , namespace )
595+ self .assertEqual ([(1 , 2 )], namespace ["result" ])
596+
597+ def test_renaming_external_import_with_same_alias (self ):
598+ code = "from builtins import zip as zip\n result = zip([], [])\n "
599+ refactored = self ._local_rename (code , code .rindex ("zip" ), "pairs" )
600+ self .assertEqual (
601+ "from builtins import zip as pairs\n result = pairs([], [])\n " ,
602+ refactored ,
603+ )
604+
605+ def test_renaming_external_import_with_different_alias (self ):
606+ code = "from builtins import zip as pairs\n result = pairs([], [])\n "
607+ refactored = self ._local_rename (code , code .rindex ("pairs" ), "new_pairs" )
608+ self .assertEqual (
609+ "from builtins import zip as new_pairs\n result = new_pairs([], [])\n " ,
610+ refactored ,
611+ )
612+
613+ def test_renaming_multiline_external_import_after_unicode (self ):
614+ code = dedent ("""\
615+ café = 1; from builtins import (
616+ zip as # Keep the imported name.
617+ zip,
618+ )
619+ result = zip([], [])
620+ """ )
621+ refactored = self ._local_rename (code , code .rindex ("zip" ), "pairs" )
622+ self .assertEqual (
623+ dedent ("""\
624+ café = 1; from builtins import (
625+ zip as # Keep the imported name.
626+ pairs,
627+ )
628+ result = pairs([], [])
629+ """ ),
630+ refactored ,
631+ )
632+
633+ def test_renaming_conditional_external_import_from_another_module (self ):
634+ compat = testutils .create_module (self .project , "compat" )
635+ compat .write (dedent ("""\
636+ import sys
637+ if sys.version_info[0] >= 3:
638+ from builtins import map, zip
639+ else:
640+ zip = lambda *args: None
641+ """ ))
642+ mod = testutils .create_module (self .project , "mod" )
643+ mod .write ("from compat import zip\n result = list(zip([1], [2]))\n " )
644+ self ._rename (mod , mod .read ().rindex ("zip" ), "pairs" )
645+ self .assertEqual (
646+ dedent ("""\
647+ import sys
648+ if sys.version_info[0] >= 3:
649+ from builtins import map, zip as pairs
650+ else:
651+ pairs = lambda *args: None
652+ """ ),
653+ compat .read (),
654+ )
655+ self .assertEqual (
656+ "from compat import pairs\n result = list(pairs([1], [2]))\n " ,
657+ mod .read (),
658+ )
659+
660+ def test_renaming_import_from_external_python_module (self ):
661+ external_project = testutils .sample_project ()
662+ self .addCleanup (testutils .remove_project , external_project )
663+ external = testutils .create_module (external_project , "external" )
664+ external .write ("value = 42\n " )
665+ self .project .prefs .add ("python_path" , external_project .address )
666+ code = "from external import value\n result = value\n "
667+ refactored = self ._local_rename (code , code .rindex ("value" ), "new_value" )
668+ self .assertEqual (
669+ "from external import value as new_value\n result = new_value\n " ,
670+ refactored ,
671+ )
672+ self .assertEqual ("value = 42\n " , external .read ())
673+
674+ def test_renaming_external_import_does_not_resolve_unrelated_import (self ):
675+ invalid = testutils .create_module (self .project , "invalid" )
676+ invalid .write ("def broken(:\n " )
677+ code = (
678+ "from invalid import other\n "
679+ "from builtins import zip\n "
680+ "result = zip([], [])\n "
681+ )
682+ refactored = self ._local_rename (code , code .rindex ("zip" ), "pairs" )
683+ self .assertEqual (
684+ "from invalid import other\n "
685+ "from builtins import zip as pairs\n "
686+ "result = pairs([], [])\n " ,
687+ refactored ,
688+ )
689+
585690 def test_applying_all_changes_together (self ):
586691 mod1 = testutils .create_module (self .project , "mod1" )
587692 mod1 .write (dedent ("""\
0 commit comments