Repository: adamchainz/flake8-comprehensions (python)

Issue:
C416 false positive with sequences as comprehension elements
The example below produces a C416 ("Unnecessary list comprehension - rewrite using list()"):
```py
input = [
    (1, 1),
    (1, 1),
    (1, 1),
]
output = [(x, y, 1) for x, y in input]
```
I suspect it is because both an input and output element is a tuple. I don't think it should happen since the shapes of the tuples differ.

It feels rather tricky to analyze the shape, so maybe in this case the check should be disabled.

Pull request description:
Fix false positives in C416 for list comprehensions returning tuples
Fixes #198.

Patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index 93287ab..3d066a2 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -2,6 +2,12 @@
 History
 =======
 
+Pending
+-------
+
+* Fix false positives in ``C416`` rule for list comprehensions returning
+  tuples.
+
 3.1.1 (2019-11-16)
 ------------------
 
diff --git a/src/flake8_comprehensions.py b/src/flake8_comprehensions.py
index 5ca4e80..e1ea322 100644
--- a/src/flake8_comprehensions.py
+++ b/src/flake8_comprehensions.py
@@ -296,6 +296,10 @@ class ComprehensionChecker:
                         or (
                             isinstance(node.elt, ast.Tuple)
                             and isinstance(node.generators[0].target, ast.Tuple)
+                            and (
+                                len(node.elt.elts)
+                                == len(node.generators[0].target.elts)
+                            )
                             and all(
                                 isinstance(a, ast.Name)
                                 and isinstance(b, ast.Name)
@@ -329,6 +333,7 @@ if sys.version_info >= (3, 7):
     def is_async_generator(node):
         return node.is_async
 
+
 else:
 
     def is_async_generator(node):


Test patch:
diff --git a/tests/test_flake8_comprehensions.py b/tests/test_flake8_comprehensions.py
index 60c4e18..c52109b 100644
--- a/tests/test_flake8_comprehensions.py
+++ b/tests/test_flake8_comprehensions.py
@@ -942,12 +942,18 @@ def test_C416_pass_2_async_list(flake8dir):
 
 
 @python_3_7_plus
-def test_C416_pass_2_async_set(flake8dir):
+def test_C416_pass_3_async_set(flake8dir):
     flake8dir.make_example_py("{x async for x in range(5)}")
     result = flake8dir.run_flake8()
     assert result.out_lines == []
 
 
+def test_C416_pass_4_tuples(flake8dir):
+    flake8dir.make_example_py("[(x, y, 1) for x, y in []]")
+    result = flake8dir.run_flake8()
+    assert result.out_lines == []
+
+
 def test_C416_fail_1(flake8dir):
     flake8dir.make_example_py(
         """