prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve error message if on_each gets a list
  When you do `cirq.H.on_each([q0, q1])` instead of the unpacked version  `cirq.H.on_each(q0, q1)` for some qubits `q0` and `q1`, the error message you get is **Gate was called with type different than Qid**. 
  
  Maybe either flatten (because most of the time you'll have your qubits in a list or a list of lists), or give a more descriptive error message.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `cirq/ops/gate_features.py`
  Content:
  ```
  1 # Copyright 2018 The Cirq Developers
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #     https://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 """Marker classes for indicating which additional features gates support.
  16 
  17 For example: some gates are reversible, some have known matrices, etc.
  18 """
  19 
  20 import abc
  21 
  22 from cirq.ops import op_tree, raw_types
  23 
  24 
  25 class InterchangeableQubitsGate(metaclass=abc.ABCMeta):
  26     """Indicates operations should be equal under some qubit permutations."""
  27 
  28     def qubit_index_to_equivalence_group_key(self, index: int) -> int:
  29         """Returns a key that differs between non-interchangeable qubits."""
  30         return 0
  31 
  32 
  33 class SingleQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):
  34     """A gate that must be applied to exactly one qubit."""
  35     def num_qubits(self) -> int:
  36         return 1
  37 
  38     def on_each(self, *targets: raw_types.Qid) -> op_tree.OP_TREE:
  39         """Returns a list of operations apply this gate to each of the targets.
  40 
  41         Args:
  42             *targets: The qubits to apply this gate to.
  43 
  44         Returns:
  45             Operations applying this gate to the target qubits.
  46 
  47         Raises:
  48             ValueError if targets are not instances of Qid.
  49         """
  50         return [self.on(target) for target in targets]
  51 
  52 
  53 class TwoQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):
  54     """A gate that must be applied to exactly two qubits."""
  55     def num_qubits(self) -> int:
  56         return 2
  57 
  58 
  59 class ThreeQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):
  60     """A gate that must be applied to exactly three qubits."""
  61     def num_qubits(self) -> int:
  62         return 3
  63
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/cirq/ops/gate_features.py b/cirq/ops/gate_features.py
  --- a/cirq/ops/gate_features.py
  +++ b/cirq/ops/gate_features.py
  @@ -18,8 +18,10 @@
   """
   
   import abc
  +import collections
  +from typing import Union, Iterable, Any, List
   
  -from cirq.ops import op_tree, raw_types
  +from cirq.ops import raw_types
   
   
   class InterchangeableQubitsGate(metaclass=abc.ABCMeta):
  @@ -35,7 +37,8 @@
       def num_qubits(self) -> int:
           return 1
   
  -    def on_each(self, *targets: raw_types.Qid) -> op_tree.OP_TREE:
  +    def on_each(self, *targets: Union[raw_types.Qid, Iterable[Any]]
  +               ) -> List[raw_types.Operation]:
           """Returns a list of operations apply this gate to each of the targets.
   
           Args:
  @@ -45,9 +48,20 @@
               Operations applying this gate to the target qubits.
   
           Raises:
  -            ValueError if targets are not instances of Qid.
  +            ValueError if targets are not instances of Qid or List[Qid].
           """
  -        return [self.on(target) for target in targets]
  +        operations = []  # type: List[raw_types.Operation]
  +        for target in targets:
  +            if isinstance(target,
  +                          collections.Iterable) and not isinstance(target, str):
  +                operations.extend(self.on_each(*target))
  +            elif isinstance(target, raw_types.Qid):
  +                operations.append(self.on(target))
  +            else:
  +                raise ValueError(
  +                    'Gate was called with type different than Qid. Type: {}'.
  +                    format(type(target)))
  +        return operations
   
   
   class TwoQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):
  
verification_info: {"golden_diff": "diff --git a/cirq/ops/gate_features.py b/cirq/ops/gate_features.py\n--- a/cirq/ops/gate_features.py\n+++ b/cirq/ops/gate_features.py\n@@ -18,8 +18,10 @@\n \"\"\"\n \n import abc\n+import collections\n+from typing import Union, Iterable, Any, List\n \n-from cirq.ops import op_tree, raw_types\n+from cirq.ops import raw_types\n \n \n class InterchangeableQubitsGate(metaclass=abc.ABCMeta):\n@@ -35,7 +37,8 @@\n     def num_qubits(self) -> int:\n         return 1\n \n-    def on_each(self, *targets: raw_types.Qid) -> op_tree.OP_TREE:\n+    def on_each(self, *targets: Union[raw_types.Qid, Iterable[Any]]\n+               ) -> List[raw_types.Operation]:\n         \"\"\"Returns a list of operations apply this gate to each of the targets.\n \n         Args:\n@@ -45,9 +48,20 @@\n             Operations applying this gate to the target qubits.\n \n         Raises:\n-            ValueError if targets are not instances of Qid.\n+            ValueError if targets are not instances of Qid or List[Qid].\n         \"\"\"\n-        return [self.on(target) for target in targets]\n+        operations = []  # type: List[raw_types.Operation]\n+        for target in targets:\n+            if isinstance(target,\n+                          collections.Iterable) and not isinstance(target, str):\n+                operations.extend(self.on_each(*target))\n+            elif isinstance(target, raw_types.Qid):\n+                operations.append(self.on(target))\n+            else:\n+                raise ValueError(\n+                    'Gate was called with type different than Qid. Type: {}'.\n+                    format(type(target)))\n+        return operations\n \n \n class TwoQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):\n", "issue": "Improve error message if on_each gets a list\nWhen you do `cirq.H.on_each([q0, q1])` instead of the unpacked version  `cirq.H.on_each(q0, q1)` for some qubits `q0` and `q1`, the error message you get is **Gate was called with type different than Qid**. \r\n\r\nMaybe either flatten (because most of the time you'll have your qubits in a list or a list of lists), or give a more descriptive error message.\n", "before_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Marker classes for indicating which additional features gates support.\n\nFor example: some gates are reversible, some have known matrices, etc.\n\"\"\"\n\nimport abc\n\nfrom cirq.ops import op_tree, raw_types\n\n\nclass InterchangeableQubitsGate(metaclass=abc.ABCMeta):\n    \"\"\"Indicates operations should be equal under some qubit permutations.\"\"\"\n\n    def qubit_index_to_equivalence_group_key(self, index: int) -> int:\n        \"\"\"Returns a key that differs between non-interchangeable qubits.\"\"\"\n        return 0\n\n\nclass SingleQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):\n    \"\"\"A gate that must be applied to exactly one qubit.\"\"\"\n    def num_qubits(self) -> int:\n        return 1\n\n    def on_each(self, *targets: raw_types.Qid) -> op_tree.OP_TREE:\n        \"\"\"Returns a list of operations apply this gate to each of the targets.\n\n        Args:\n            *targets: The qubits to apply this gate to.\n\n        Returns:\n            Operations applying this gate to the target qubits.\n\n        Raises:\n            ValueError if targets are not instances of Qid.\n        \"\"\"\n        return [self.on(target) for target in targets]\n\n\nclass TwoQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):\n    \"\"\"A gate that must be applied to exactly two qubits.\"\"\"\n    def num_qubits(self) -> int:\n        return 2\n\n\nclass ThreeQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):\n    \"\"\"A gate that must be applied to exactly three qubits.\"\"\"\n    def num_qubits(self) -> int:\n        return 3\n", "path": "cirq/ops/gate_features.py"}], "after_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Marker classes for indicating which additional features gates support.\n\nFor example: some gates are reversible, some have known matrices, etc.\n\"\"\"\n\nimport abc\nimport collections\nfrom typing import Union, Iterable, Any, List\n\nfrom cirq.ops import raw_types\n\n\nclass InterchangeableQubitsGate(metaclass=abc.ABCMeta):\n    \"\"\"Indicates operations should be equal under some qubit permutations.\"\"\"\n\n    def qubit_index_to_equivalence_group_key(self, index: int) -> int:\n        \"\"\"Returns a key that differs between non-interchangeable qubits.\"\"\"\n        return 0\n\n\nclass SingleQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):\n    \"\"\"A gate that must be applied to exactly one qubit.\"\"\"\n    def num_qubits(self) -> int:\n        return 1\n\n    def on_each(self, *targets: Union[raw_types.Qid, Iterable[Any]]\n               ) -> List[raw_types.Operation]:\n        \"\"\"Returns a list of operations apply this gate to each of the targets.\n\n        Args:\n            *targets: The qubits to apply this gate to.\n\n        Returns:\n            Operations applying this gate to the target qubits.\n\n        Raises:\n            ValueError if targets are not instances of Qid or List[Qid].\n        \"\"\"\n        operations = []  # type: List[raw_types.Operation]\n        for target in targets:\n            if isinstance(target,\n                          collections.Iterable) and not isinstance(target, str):\n                operations.extend(self.on_each(*target))\n            elif isinstance(target, raw_types.Qid):\n                operations.append(self.on(target))\n            else:\n                raise ValueError(\n                    'Gate was called with type different than Qid. Type: {}'.\n                    format(type(target)))\n        return operations\n\n\nclass TwoQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):\n    \"\"\"A gate that must be applied to exactly two qubits.\"\"\"\n    def num_qubits(self) -> int:\n        return 2\n\n\nclass ThreeQubitGate(raw_types.Gate, metaclass=abc.ABCMeta):\n    \"\"\"A gate that must be applied to exactly three qubits.\"\"\"\n    def num_qubits(self) -> int:\n        return 3\n", "path": "cirq/ops/gate_features.py"}]}