Repository: asottile/pyupgrade

Issue:
Broken imports
When rewriting the following code

```python
from typing import Optional, Sequence as SequenceType
```

pyupgrade duplicates the `as SequenceType`:

```python
from typing import Optional as SequenceType
from collections.abc import Sequence as SequenceType
```

I've ran it with `pyupgrade --py39-plus tmp.py`.  Happens with both the current release (3.3.1) and the main branch.

Discussion:

Patch:
diff --git a/pyupgrade/_plugins/imports.py b/pyupgrade/_plugins/imports.py
index f6e0359..823d634 100644
--- a/pyupgrade/_plugins/imports.py
+++ b/pyupgrade/_plugins/imports.py
@@ -281,6 +281,7 @@ class FromImport(NamedTuple):
     mod_start: int
     mod_end: int
     names: tuple[int, ...]
+    ends: tuple[int, ...]
     end: int
 
     @classmethod
@@ -310,11 +311,14 @@ class FromImport(NamedTuple):
             for j in range(import_token + 1, end)
             if tokens[j].name == 'NAME'
         ]
+        ends_by_offset = {}
         for i in reversed(range(len(names))):
             if tokens[names[i]].src == 'as':
+                ends_by_offset[names[i - 1]] = names[i + 1]
                 del names[i:i + 2]
+        ends = tuple(ends_by_offset.get(pos, pos) for pos in names)
 
-        return cls(start, mod_start, mod_end + 1, tuple(names), end)
+        return cls(start, mod_start, mod_end + 1, tuple(names), ends, end)
 
     def remove_self(self, tokens: list[Token]) -> None:
         del tokens[self.start:self.end]
@@ -327,10 +331,10 @@ class FromImport(NamedTuple):
             if idx == 0:  # look forward until next name and del
                 del tokens[self.names[idx]:self.names[idx + 1]]
             else:  # look backward for comma and del
-                j = end = self.names[idx]
+                j = self.names[idx]
                 while tokens[j].src != ',':
                     j -= 1
-                del tokens[j:end + 1]
+                del tokens[j:self.ends[idx] + 1]
 
 
 def _alias_to_s(alias: ast.alias) -> str:


Test patch:
diff --git a/tests/features/import_replaces_test.py b/tests/features/import_replaces_test.py
index 386afdb..07bc228 100644
--- a/tests/features/import_replaces_test.py
+++ b/tests/features/import_replaces_test.py
@@ -305,6 +305,13 @@ def test_mock_noop_keep_mock():
             'from collections.abc import Callable\n',
             id='typing.Callable is rewritable in 3.10+ only',
         ),
+        pytest.param(
+            'from typing import Optional, Sequence as S\n',
+            (3, 10),
+            'from typing import Optional\n'
+            'from collections.abc import Sequence as S\n',
+            id='aliasing in multi from import',
+        ),
     ),
 )
 def test_import_replaces(s, min_version, expected):