nebius/SWE-bench-extra huggingface dataset:
Repository: ilevkivskyi/com2ann

Issue:
When using --wrap-signatures, return annotations with commas also get wrapped
For example:
```python
def func(arg1: SomeVeryLongType1,
         arg2: SomeVeryLongType2) -> Dict[str,
         int]:
    ...
```
This is not a syntax error, but looks ugly.

Comments:

Patch:
diff --git a/src/com2ann.py b/src/com2ann.py
index b1683e3..166672e 100644
--- a/src/com2ann.py
+++ b/src/com2ann.py
@@ -459,6 +459,7 @@ def wrap_function_header(header: str) -> List[str]:
     parts: List[str] = []
     next_part = ''
     nested = 0
+    complete = False  # Did we split all the arguments inside (...)?
     indent: Optional[int] = None
 
     for i, c in enumerate(header):
@@ -468,7 +469,9 @@ def wrap_function_header(header: str) -> List[str]:
                 indent = i + 1
         if c in ')]}':
             nested -= 1
-        if c == ',' and nested == 1:
+            if not nested:
+                complete = True
+        if c == ',' and nested == 1 and not complete:
             next_part += c
             parts.append(next_part)
             next_part = ''


Test patch:
diff --git a/src/test_com2ann.py b/src/test_com2ann.py
index fafb71c..6cef088 100644
--- a/src/test_com2ann.py
+++ b/src/test_com2ann.py
@@ -411,6 +411,19 @@ class FunctionTestCase(BaseTestCase):
                          *fake_receipts: str) -> None:
                 pass
             """, False, False, 10)
+        self.check(
+            """
+            def embezzle(self, account, funds=MANY, *fake_receipts):
+                # type: (str, int, *str) -> Dict[str, Dict[str, int]]
+                pass
+            """,
+            """
+            def embezzle(self,
+                         account: str,
+                         funds: int = MANY,
+                         *fake_receipts: str) -> Dict[str, Dict[str, int]]:
+                pass
+            """, False, False, 10)
 
     def test_decorator_body(self) -> None:
         self.check(
Repository: ilevkivskyi/com2ann

Issue:
Type comment left in place when expression is type ignored
Thanks for this tool, it's really useful :)

If you have code like this:
``` python
    foo = object()

    bar = (
        # Comment which explains why this ignored
        foo.quox   # type: ignore[attribute]
    )  # type: Mapping[str, Distribution]
```
Then after running `com2ann` you end up with:
``` python
    foo = object()

    bar: Mapping[str, int] = (
        # Comment which explains why this ignored
        foo.quox   # type: ignore[attribute]
    )  # type: Mapping[str, int]
```
which `mypy` then complains about due to the double signature.

The intermediate (explanatory) comment doesn't seem to be related, though the `type: ignore` comment is.

Comments:

Patch:
diff --git a/src/com2ann.py b/src/com2ann.py
index b3a892e..9e853bd 100644
--- a/src/com2ann.py
+++ b/src/com2ann.py
@@ -467,7 +467,8 @@ def process_assign(comment: AssignData, data: FileData,
     # We perform the tasks in order from larger line/columns to smaller ones
     # to avoid shuffling the line column numbers in following code.
     # First remove the type comment.
-    if re.search(TYPE_COM, lines[rv_end]):
+    match = re.search(TYPE_COM, lines[rv_end])
+    if match and not match.group(1).lstrip().startswith('ignore'):
         lines[rv_end] = strip_type_comment(lines[rv_end])
     else:
         # Special case: type comment moved to a separate continuation line.


Test patch:
diff --git a/src/test_com2ann.py b/src/test_com2ann.py
index 2b93328..37236ec 100644
--- a/src/test_com2ann.py
+++ b/src/test_com2ann.py
@@ -228,6 +228,23 @@ class AssignTestCase(BaseTestCase):
                 | {other}
             )
             """)
+        self.check(
+            """
+            foo = object()
+
+            bar = (
+                # Comment which explains why this ignored
+                foo.quox   # type: ignore[attribute]
+            )  # type: Mapping[str, Distribution]
+            """,
+            """
+            foo = object()
+
+            bar: Mapping[str, Distribution] = (
+                # Comment which explains why this ignored
+                foo.quox   # type: ignore[attribute]
+            )
+            """)
 
     def test_with_for(self) -> None:
         self.check(
Repository: ilevkivskyi/com2ann

Issue:
Multiple input files are generated to single file
When a command is called with multiple files (ex. `com2ann f1.py f2.py`), then the first file (`f1.py`) is chosen as output for both files.

This is especially problematic when `pre-commit` hook is used.

Comments:

Patch:
diff --git a/src/com2ann.py b/src/com2ann.py
index 5e41a5f..f6d0f48 100644
--- a/src/com2ann.py
+++ b/src/com2ann.py
@@ -936,8 +936,8 @@ def main() -> None:
     options = Options(**args)
 
     for infile in infiles:
-        outfile = outfile or infile
-        process_single_entry(in_path=infile, out_path=outfile, options=options)
+        cur_outfile = outfile or infile
+        process_single_entry(in_path=infile, out_path=cur_outfile, options=options)
 
 
 if __name__ == '__main__':


Test patch:
diff --git a/src/test_cli.py b/src/test_cli.py
index 29f63ef..abec360 100644
--- a/src/test_cli.py
+++ b/src/test_cli.py
@@ -2,6 +2,7 @@ from __future__ import annotations
 
 import os
 import pathlib
+from dataclasses import asdict
 from typing import Any, Callable, Iterable, TypedDict
 
 import pytest
@@ -216,3 +217,42 @@ def test_process_single_entry__dir(
             options=options,
         ),
     ]
+
+
+@pytest.fixture
+def parse_cli_args(
+    test_path: pathlib.Path,
+    mocker: Any,
+    options: com2ann.Options,
+) -> Any:
+    f1 = test_path / "f1.py"
+    f2 = test_path / "f2.py"
+
+    f1.write_text("f1 = True")
+    f2.write_text("f2 = False")
+
+    args = {'infiles': [f1, f2], 'outfile': None, **asdict(options)}
+    return mocker.patch("com2ann.parse_cli_args", return_value=args)
+
+
+def test_process_multiple_input_files(
+    test_path: pathlib.Path, translate_file: Any,
+    mocker: Any, parse_cli_args: Any,
+    options: com2ann.Options
+) -> None:
+    com2ann.main()
+
+    assert translate_file.mock_calls == [
+        mocker.call(
+            infile=str(test_path / "f1.py"),
+            outfile=str(test_path / "f1.py"),
+            options=options,
+        ),
+        mocker.call(
+            infile=str(test_path / "f2.py"),
+            outfile=str(test_path / "f2.py"),
+            options=options,
+        ),
+    ]
+    assert (test_path / "f1.py").read_text() == "f1 = True"
+    assert (test_path / "f2.py").read_text() == "f2 = False"
Repository: ilevkivskyi/typing_inspect

Issue:
Python 3.9 support breaks List
There was a regression in release 0.7.0 from 0.6.0.

Currently, 
```python
>>> from typing import List, Set
>>> from typing_inspect import get_args
>>> get_args(list[str])  # Yay this works! Great to see support for Python 3.9!
(<class 'str'>,)
>>> get_args(List)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jessemichel/Dependencies/miniconda3/envs/py39/lib/python3.9/site-packages/typing_inspect.py", line 471, in get_args
    res = tp.__args__
  File "/Users/jessemichel/Dependencies/miniconda3/envs/py39/lib/python3.9/typing.py", line 694, in __getattr__
    raise AttributeError(attr)
AttributeError: __args__
```

Previously, 
```python
>>> get_args(List)
(~T,)
```

I believe the fix would be changing this line:
https://github.com/ilevkivskyi/typing_inspect/blob/d1d46f4c2429dd0a60f902fa7b728d67bb2d1582/typing_inspect.py#L471
to
```python
res = tp.__args__ if hasattr(tp, '__args__') else ()
```

Comments:

Patch:
diff --git a/typing_inspect.py b/typing_inspect.py
index c11b856..4c765e3 100644
--- a/typing_inspect.py
+++ b/typing_inspect.py
@@ -467,7 +467,8 @@ def get_args(tp, evaluate=None):
     if NEW_TYPING:
         if evaluate is not None and not evaluate:
             raise ValueError('evaluate can only be True in Python >= 3.7')
-        if isinstance(tp, typingGenericAlias):
+        # Note special aliases on Python 3.9 don't have __args__.
+        if isinstance(tp, typingGenericAlias) and hasattr(tp, '__args__'):
             res = tp.__args__
             if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis:
                 res = (list(res[:-1]), res[-1])


Test patch:
diff --git a/test_typing_inspect.py b/test_typing_inspect.py
index 58a03ee..7e9d432 100644
--- a/test_typing_inspect.py
+++ b/test_typing_inspect.py
@@ -402,6 +402,8 @@ class GetUtilityTestCase(TestCase):
             self.assertEqual(get_args(list[int]), (int,))
             self.assertEqual(get_args(tuple[int, str]), (int, str))
             self.assertEqual(get_args(list[list[int]]), (list[int],))
+            # This would return (~T,) before Python 3.9.
+            self.assertEqual(get_args(List), ())
 
     def test_bound(self):
         T = TypeVar('T')
Repository: ilevkivskyi/typing_inspect

Issue:
`get_parameters` throws exception with non-indexed types from `typing` on python 3.10
**python 3.7**
```
>>> from typing import List
>>> from typing_inspect import get_parameters
>>> get_parameters(List)
(~T,)
```

**python 3.10.6**
```
>>> from typing import List
>>> from typing_inspect import get_parameters
>>> get_parameters(List)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/james.robson/code/pio_utilities/.venv/lib/python3.10/site-packages/typing_inspect.py", line 414, in get_parameters
    return tp.__parameters__
  File "/usr/lib/python3.10/typing.py", line 984, in __getattr__
    raise AttributeError(attr)
AttributeError: __parameters__
```

When you don't provide type parameters the `typing` classes lacks the `__parameters__`, `_paramspec_tvars` and `_typevar_types` members.



Comments:

Patch:
diff --git a/typing_inspect.py b/typing_inspect.py
index d786e96..0268b16 100644
--- a/typing_inspect.py
+++ b/typing_inspect.py
@@ -408,7 +408,11 @@ def get_parameters(tp):
         else:
             return ()
     elif NEW_TYPING:
-        if (isinstance(tp, typingGenericAlias) or
+        if (
+                (
+                    isinstance(tp, typingGenericAlias) and
+                    hasattr(tp, '__parameters__')
+                ) or
                 isinstance(tp, type) and issubclass(tp, Generic) and
                 tp is not Generic):
             return tp.__parameters__


Test patch:
diff --git a/test_typing_inspect.py b/test_typing_inspect.py
index 9f6be56..eaea460 100644
--- a/test_typing_inspect.py
+++ b/test_typing_inspect.py
@@ -14,6 +14,7 @@ from typing import (
     Union, Callable, Optional, TypeVar, Sequence, AnyStr, Mapping,
     MutableMapping, Iterable, Generic, List, Any, Dict, Tuple, NamedTuple,
 )
+from typing import T as typing_T
 
 from mypy_extensions import TypedDict as METypedDict
 from typing_extensions import TypedDict as TETypedDict
@@ -354,6 +355,10 @@ class GetUtilityTestCase(TestCase):
         self.assertEqual(get_parameters(Union), ())
         if not LEGACY_TYPING:
             self.assertEqual(get_parameters(List[int]), ())
+            if PY39:
+                self.assertEqual(get_parameters(List), ())
+            else:
+                self.assertEqual(get_parameters(List), (typing_T,))
         else:
             # in 3.5.3 a list has no __args__ and instead they are used in __parameters__
             # in 3.5.1 the behaviour is normal again.