We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
cirq.PauliInteractionGate's __repr__ output is not valid python
It returns things like "+X", which don't parse when you've imported cirq.

--- 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/pauli_interaction_gate.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 from typing import Hashable, List, Optional, Sequence, Tuple, Union
16 
17 import numpy as np
18 
19 from cirq import value
20 from cirq.ops import raw_types, gate_features, common_gates, eigen_gate, op_tree
21 from cirq.ops.pauli import Pauli
22 from cirq.ops.clifford_gate import SingleQubitCliffordGate
23 
24 
25 pauli_eigen_map = {
26     Pauli.X: (np.array([[0.5,  0.5 ], [0.5,   0.5]]),
27               np.array([[0.5, -0.5 ], [-0.5,  0.5]])),
28     Pauli.Y: (np.array([[0.5, -0.5j], [0.5j,  0.5]]),
29               np.array([[0.5,  0.5j], [-0.5j, 0.5]])),
30     Pauli.Z: (np.diag([1, 0]),
31               np.diag([0, 1])),
32 }
33 
34 
35 class PauliInteractionGate(eigen_gate.EigenGate,
36                            gate_features.CompositeGate,
37                            gate_features.InterchangeableQubitsGate,
38                            gate_features.TextDiagrammable):
39     CZ = None  # type: PauliInteractionGate
40     CNOT = None  # type: PauliInteractionGate
41 
42     def __init__(self,
43                  pauli0: Pauli, invert0: bool,
44                  pauli1: Pauli, invert1: bool,
45                  *,
46                  half_turns: Optional[Union[value.Symbol, float]] = None,
47                  rads: Optional[float] = None,
48                  degs: Optional[float] = None) -> None:
49         """At most one angle argument may be specified. If more are specified,
50         the result is considered ambiguous and an error is thrown. If no angle
51         argument is given, the default value of one half turn is used.
52 
53         Args:
54             half_turns: Relative phasing of the interaction's eigenstates, in
55                 half_turns.
56             rads: Relative phasing of the interaction's eigenstates, in radians.
57             degs: Relative phasing of the interaction's eigenstates, in degrees.
58         """
59         super().__init__(exponent=value.chosen_angle_to_half_turns(
60             half_turns=half_turns,
61             rads=rads,
62             degs=degs))
63         self.pauli0 = pauli0
64         self.invert0 = invert0
65         self.pauli1 = pauli1
66         self.invert1 = invert1
67 
68     def _eq_tuple(self) -> Tuple[Hashable, ...]:
69         return (PauliInteractionGate,
70                 self.pauli0, self.invert0,
71                 self.pauli1, self.invert1,
72                 self._exponent)
73 
74     def __eq__(self, other):
75         if not isinstance(other, type(self)):
76             return NotImplemented
77         return self._eq_tuple() == other._eq_tuple()
78 
79     def __ne__(self, other):
80         return not self == other
81 
82     def __hash__(self):
83         return hash(self._eq_tuple())
84 
85     def qubit_index_to_equivalence_group_key(self, index: int) -> int:
86         if self.pauli0 == self.pauli1 and self.invert0 == self.invert1:
87             return 0
88         else:
89             return index
90 
91     def _canonical_exponent_period(self) -> Optional[float]:
92         return 2
93 
94     def _with_exponent(self, exponent: Union[value.Symbol, float]
95                        ) -> 'PauliInteractionGate':
96         return PauliInteractionGate(self.pauli0, self.invert0,
97                                     self.pauli1, self.invert1,
98                                     half_turns=exponent)
99 
100     def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
101         comp1 = np.kron(pauli_eigen_map[self.pauli0][not self.invert0],
102                         pauli_eigen_map[self.pauli1][not self.invert1])
103         comp0 = np.eye(4) - comp1
104         return [(0, comp0), (1, comp1)]
105 
106     def default_decompose(self, qubits: Sequence[raw_types.QubitId]
107                           ) -> op_tree.OP_TREE:
108         q0, q1 = qubits
109         right_gate0 = SingleQubitCliffordGate.from_single_map(
110                                     z_to=(self.pauli0, self.invert0))
111         right_gate1 = SingleQubitCliffordGate.from_single_map(
112                                     z_to=(self.pauli1, self.invert1))
113         left_gate0 = right_gate0.inverse()
114         left_gate1 = right_gate1.inverse()
115         yield left_gate0(q0)
116         yield left_gate1(q1)
117         yield common_gates.Rot11Gate(half_turns=self._exponent)(q0, q1)
118         yield right_gate0(q0)
119         yield right_gate1(q1)
120 
121     def text_diagram_info(self, args: gate_features.TextDiagramInfoArgs
122                           ) -> gate_features.TextDiagramInfo:
123         labels = {Pauli.X: 'X', Pauli.Y: 'Y', Pauli.Z: '@'}
124         l0 = labels[self.pauli0]
125         l1 = labels[self.pauli1]
126         # Add brackets around letter if inverted
127         l0, l1 = ('(-{})'.format(l) if inv else l
128                   for l, inv in ((l0, self.invert0), (l1, self.invert1)))
129         return gate_features.TextDiagramInfo(
130             wire_symbols=(l0, l1),
131             exponent=self._exponent)
132 
133     def __repr__(self):
134         return 'cirq.PauliInteractionGate({}{!s}, {}{!s})'.format(
135                '+-'[self.invert0], self.pauli0, '+-'[self.invert1], self.pauli1)
136 
137 
138 PauliInteractionGate.CZ = PauliInteractionGate(Pauli.Z, False, Pauli.Z, False)
139 PauliInteractionGate.CNOT = PauliInteractionGate(Pauli.Z, False, Pauli.X, False)
140
```
--- 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()

```

diff --git a/cirq/ops/pauli_interaction_gate.py b/cirq/ops/pauli_interaction_gate.py
--- a/cirq/ops/pauli_interaction_gate.py
+++ b/cirq/ops/pauli_interaction_gate.py
@@ -23,8 +23,8 @@
 
 
 pauli_eigen_map = {
-    Pauli.X: (np.array([[0.5,  0.5 ], [0.5,   0.5]]),
-              np.array([[0.5, -0.5 ], [-0.5,  0.5]])),
+    Pauli.X: (np.array([[0.5,  0.5], [0.5,   0.5]]),
+              np.array([[0.5, -0.5], [-0.5,  0.5]])),
     Pauli.Y: (np.array([[0.5, -0.5j], [0.5j,  0.5]]),
               np.array([[0.5,  0.5j], [-0.5j, 0.5]])),
     Pauli.Z: (np.diag([1, 0]),
@@ -107,9 +107,9 @@
                           ) -> op_tree.OP_TREE:
         q0, q1 = qubits
         right_gate0 = SingleQubitCliffordGate.from_single_map(
-                                    z_to=(self.pauli0, self.invert0))
+            z_to=(self.pauli0, self.invert0))
         right_gate1 = SingleQubitCliffordGate.from_single_map(
-                                    z_to=(self.pauli1, self.invert1))
+            z_to=(self.pauli1, self.invert1))
         left_gate0 = right_gate0.inverse()
         left_gate1 = right_gate1.inverse()
         yield left_gate0(q0)
@@ -131,9 +131,10 @@
             exponent=self._exponent)
 
     def __repr__(self):
-        return 'cirq.PauliInteractionGate({}{!s}, {}{!s})'.format(
-               '+-'[self.invert0], self.pauli0, '+-'[self.invert1], self.pauli1)
+        return 'cirq.PauliInteractionGate(cirq.{}, {!s}, cirq.{}, {!s})'.format(
+            self.pauli0, self.invert0, self.pauli1, self.invert1)
 
 
 PauliInteractionGate.CZ = PauliInteractionGate(Pauli.Z, False, Pauli.Z, False)
-PauliInteractionGate.CNOT = PauliInteractionGate(Pauli.Z, False, Pauli.X, False)
+PauliInteractionGate.CNOT = PauliInteractionGate(
+    Pauli.Z, False, Pauli.X, False)

{"golden_diff": "diff --git a/cirq/ops/pauli_interaction_gate.py b/cirq/ops/pauli_interaction_gate.py\n--- a/cirq/ops/pauli_interaction_gate.py\n+++ b/cirq/ops/pauli_interaction_gate.py\n@@ -23,8 +23,8 @@\n \n \n pauli_eigen_map = {\n-    Pauli.X: (np.array([[0.5,  0.5 ], [0.5,   0.5]]),\n-              np.array([[0.5, -0.5 ], [-0.5,  0.5]])),\n+    Pauli.X: (np.array([[0.5,  0.5], [0.5,   0.5]]),\n+              np.array([[0.5, -0.5], [-0.5,  0.5]])),\n     Pauli.Y: (np.array([[0.5, -0.5j], [0.5j,  0.5]]),\n               np.array([[0.5,  0.5j], [-0.5j, 0.5]])),\n     Pauli.Z: (np.diag([1, 0]),\n@@ -107,9 +107,9 @@\n                           ) -> op_tree.OP_TREE:\n         q0, q1 = qubits\n         right_gate0 = SingleQubitCliffordGate.from_single_map(\n-                                    z_to=(self.pauli0, self.invert0))\n+            z_to=(self.pauli0, self.invert0))\n         right_gate1 = SingleQubitCliffordGate.from_single_map(\n-                                    z_to=(self.pauli1, self.invert1))\n+            z_to=(self.pauli1, self.invert1))\n         left_gate0 = right_gate0.inverse()\n         left_gate1 = right_gate1.inverse()\n         yield left_gate0(q0)\n@@ -131,9 +131,10 @@\n             exponent=self._exponent)\n \n     def __repr__(self):\n-        return 'cirq.PauliInteractionGate({}{!s}, {}{!s})'.format(\n-               '+-'[self.invert0], self.pauli0, '+-'[self.invert1], self.pauli1)\n+        return 'cirq.PauliInteractionGate(cirq.{}, {!s}, cirq.{}, {!s})'.format(\n+            self.pauli0, self.invert0, self.pauli1, self.invert1)\n \n \n PauliInteractionGate.CZ = PauliInteractionGate(Pauli.Z, False, Pauli.Z, False)\n-PauliInteractionGate.CNOT = PauliInteractionGate(Pauli.Z, False, Pauli.X, False)\n+PauliInteractionGate.CNOT = PauliInteractionGate(\n+    Pauli.Z, False, Pauli.X, False)\n", "issue": "cirq.PauliInteractionGate's __repr__ output is not valid python\nIt returns things like \"+X\", which don't parse when you've imported cirq.\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\nfrom typing import Hashable, List, Optional, Sequence, Tuple, Union\n\nimport numpy as np\n\nfrom cirq import value\nfrom cirq.ops import raw_types, gate_features, common_gates, eigen_gate, op_tree\nfrom cirq.ops.pauli import Pauli\nfrom cirq.ops.clifford_gate import SingleQubitCliffordGate\n\n\npauli_eigen_map = {\n    Pauli.X: (np.array([[0.5,  0.5 ], [0.5,   0.5]]),\n              np.array([[0.5, -0.5 ], [-0.5,  0.5]])),\n    Pauli.Y: (np.array([[0.5, -0.5j], [0.5j,  0.5]]),\n              np.array([[0.5,  0.5j], [-0.5j, 0.5]])),\n    Pauli.Z: (np.diag([1, 0]),\n              np.diag([0, 1])),\n}\n\n\nclass PauliInteractionGate(eigen_gate.EigenGate,\n                           gate_features.CompositeGate,\n                           gate_features.InterchangeableQubitsGate,\n                           gate_features.TextDiagrammable):\n    CZ = None  # type: PauliInteractionGate\n    CNOT = None  # type: PauliInteractionGate\n\n    def __init__(self,\n                 pauli0: Pauli, invert0: bool,\n                 pauli1: Pauli, invert1: bool,\n                 *,\n                 half_turns: Optional[Union[value.Symbol, float]] = None,\n                 rads: Optional[float] = None,\n                 degs: Optional[float] = None) -> None:\n        \"\"\"At most one angle argument may be specified. If more are specified,\n        the result is considered ambiguous and an error is thrown. If no angle\n        argument is given, the default value of one half turn is used.\n\n        Args:\n            half_turns: Relative phasing of the interaction's eigenstates, in\n                half_turns.\n            rads: Relative phasing of the interaction's eigenstates, in radians.\n            degs: Relative phasing of the interaction's eigenstates, in degrees.\n        \"\"\"\n        super().__init__(exponent=value.chosen_angle_to_half_turns(\n            half_turns=half_turns,\n            rads=rads,\n            degs=degs))\n        self.pauli0 = pauli0\n        self.invert0 = invert0\n        self.pauli1 = pauli1\n        self.invert1 = invert1\n\n    def _eq_tuple(self) -> Tuple[Hashable, ...]:\n        return (PauliInteractionGate,\n                self.pauli0, self.invert0,\n                self.pauli1, self.invert1,\n                self._exponent)\n\n    def __eq__(self, other):\n        if not isinstance(other, type(self)):\n            return NotImplemented\n        return self._eq_tuple() == other._eq_tuple()\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __hash__(self):\n        return hash(self._eq_tuple())\n\n    def qubit_index_to_equivalence_group_key(self, index: int) -> int:\n        if self.pauli0 == self.pauli1 and self.invert0 == self.invert1:\n            return 0\n        else:\n            return index\n\n    def _canonical_exponent_period(self) -> Optional[float]:\n        return 2\n\n    def _with_exponent(self, exponent: Union[value.Symbol, float]\n                       ) -> 'PauliInteractionGate':\n        return PauliInteractionGate(self.pauli0, self.invert0,\n                                    self.pauli1, self.invert1,\n                                    half_turns=exponent)\n\n    def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:\n        comp1 = np.kron(pauli_eigen_map[self.pauli0][not self.invert0],\n                        pauli_eigen_map[self.pauli1][not self.invert1])\n        comp0 = np.eye(4) - comp1\n        return [(0, comp0), (1, comp1)]\n\n    def default_decompose(self, qubits: Sequence[raw_types.QubitId]\n                          ) -> op_tree.OP_TREE:\n        q0, q1 = qubits\n        right_gate0 = SingleQubitCliffordGate.from_single_map(\n                                    z_to=(self.pauli0, self.invert0))\n        right_gate1 = SingleQubitCliffordGate.from_single_map(\n                                    z_to=(self.pauli1, self.invert1))\n        left_gate0 = right_gate0.inverse()\n        left_gate1 = right_gate1.inverse()\n        yield left_gate0(q0)\n        yield left_gate1(q1)\n        yield common_gates.Rot11Gate(half_turns=self._exponent)(q0, q1)\n        yield right_gate0(q0)\n        yield right_gate1(q1)\n\n    def text_diagram_info(self, args: gate_features.TextDiagramInfoArgs\n                          ) -> gate_features.TextDiagramInfo:\n        labels = {Pauli.X: 'X', Pauli.Y: 'Y', Pauli.Z: '@'}\n        l0 = labels[self.pauli0]\n        l1 = labels[self.pauli1]\n        # Add brackets around letter if inverted\n        l0, l1 = ('(-{})'.format(l) if inv else l\n                  for l, inv in ((l0, self.invert0), (l1, self.invert1)))\n        return gate_features.TextDiagramInfo(\n            wire_symbols=(l0, l1),\n            exponent=self._exponent)\n\n    def __repr__(self):\n        return 'cirq.PauliInteractionGate({}{!s}, {}{!s})'.format(\n               '+-'[self.invert0], self.pauli0, '+-'[self.invert1], self.pauli1)\n\n\nPauliInteractionGate.CZ = PauliInteractionGate(Pauli.Z, False, Pauli.Z, False)\nPauliInteractionGate.CNOT = PauliInteractionGate(Pauli.Z, False, Pauli.X, False)\n", "path": "cirq/ops/pauli_interaction_gate.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\nfrom typing import Hashable, List, Optional, Sequence, Tuple, Union\n\nimport numpy as np\n\nfrom cirq import value\nfrom cirq.ops import raw_types, gate_features, common_gates, eigen_gate, op_tree\nfrom cirq.ops.pauli import Pauli\nfrom cirq.ops.clifford_gate import SingleQubitCliffordGate\n\n\npauli_eigen_map = {\n    Pauli.X: (np.array([[0.5,  0.5], [0.5,   0.5]]),\n              np.array([[0.5, -0.5], [-0.5,  0.5]])),\n    Pauli.Y: (np.array([[0.5, -0.5j], [0.5j,  0.5]]),\n              np.array([[0.5,  0.5j], [-0.5j, 0.5]])),\n    Pauli.Z: (np.diag([1, 0]),\n              np.diag([0, 1])),\n}\n\n\nclass PauliInteractionGate(eigen_gate.EigenGate,\n                           gate_features.CompositeGate,\n                           gate_features.InterchangeableQubitsGate,\n                           gate_features.TextDiagrammable):\n    CZ = None  # type: PauliInteractionGate\n    CNOT = None  # type: PauliInteractionGate\n\n    def __init__(self,\n                 pauli0: Pauli, invert0: bool,\n                 pauli1: Pauli, invert1: bool,\n                 *,\n                 half_turns: Optional[Union[value.Symbol, float]] = None,\n                 rads: Optional[float] = None,\n                 degs: Optional[float] = None) -> None:\n        \"\"\"At most one angle argument may be specified. If more are specified,\n        the result is considered ambiguous and an error is thrown. If no angle\n        argument is given, the default value of one half turn is used.\n\n        Args:\n            half_turns: Relative phasing of the interaction's eigenstates, in\n                half_turns.\n            rads: Relative phasing of the interaction's eigenstates, in radians.\n            degs: Relative phasing of the interaction's eigenstates, in degrees.\n        \"\"\"\n        super().__init__(exponent=value.chosen_angle_to_half_turns(\n            half_turns=half_turns,\n            rads=rads,\n            degs=degs))\n        self.pauli0 = pauli0\n        self.invert0 = invert0\n        self.pauli1 = pauli1\n        self.invert1 = invert1\n\n    def _eq_tuple(self) -> Tuple[Hashable, ...]:\n        return (PauliInteractionGate,\n                self.pauli0, self.invert0,\n                self.pauli1, self.invert1,\n                self._exponent)\n\n    def __eq__(self, other):\n        if not isinstance(other, type(self)):\n            return NotImplemented\n        return self._eq_tuple() == other._eq_tuple()\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __hash__(self):\n        return hash(self._eq_tuple())\n\n    def qubit_index_to_equivalence_group_key(self, index: int) -> int:\n        if self.pauli0 == self.pauli1 and self.invert0 == self.invert1:\n            return 0\n        else:\n            return index\n\n    def _canonical_exponent_period(self) -> Optional[float]:\n        return 2\n\n    def _with_exponent(self, exponent: Union[value.Symbol, float]\n                       ) -> 'PauliInteractionGate':\n        return PauliInteractionGate(self.pauli0, self.invert0,\n                                    self.pauli1, self.invert1,\n                                    half_turns=exponent)\n\n    def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:\n        comp1 = np.kron(pauli_eigen_map[self.pauli0][not self.invert0],\n                        pauli_eigen_map[self.pauli1][not self.invert1])\n        comp0 = np.eye(4) - comp1\n        return [(0, comp0), (1, comp1)]\n\n    def default_decompose(self, qubits: Sequence[raw_types.QubitId]\n                          ) -> op_tree.OP_TREE:\n        q0, q1 = qubits\n        right_gate0 = SingleQubitCliffordGate.from_single_map(\n            z_to=(self.pauli0, self.invert0))\n        right_gate1 = SingleQubitCliffordGate.from_single_map(\n            z_to=(self.pauli1, self.invert1))\n        left_gate0 = right_gate0.inverse()\n        left_gate1 = right_gate1.inverse()\n        yield left_gate0(q0)\n        yield left_gate1(q1)\n        yield common_gates.Rot11Gate(half_turns=self._exponent)(q0, q1)\n        yield right_gate0(q0)\n        yield right_gate1(q1)\n\n    def text_diagram_info(self, args: gate_features.TextDiagramInfoArgs\n                          ) -> gate_features.TextDiagramInfo:\n        labels = {Pauli.X: 'X', Pauli.Y: 'Y', Pauli.Z: '@'}\n        l0 = labels[self.pauli0]\n        l1 = labels[self.pauli1]\n        # Add brackets around letter if inverted\n        l0, l1 = ('(-{})'.format(l) if inv else l\n                  for l, inv in ((l0, self.invert0), (l1, self.invert1)))\n        return gate_features.TextDiagramInfo(\n            wire_symbols=(l0, l1),\n            exponent=self._exponent)\n\n    def __repr__(self):\n        return 'cirq.PauliInteractionGate(cirq.{}, {!s}, cirq.{}, {!s})'.format(\n            self.pauli0, self.invert0, self.pauli1, self.invert1)\n\n\nPauliInteractionGate.CZ = PauliInteractionGate(Pauli.Z, False, Pauli.Z, False)\nPauliInteractionGate.CNOT = PauliInteractionGate(\n    Pauli.Z, False, Pauli.X, False)\n", "path": "cirq/ops/pauli_interaction_gate.py"}]}