internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: quantumlib/Cirq

Issue:
PauliString constructor should accept (but filter out) cirq.I (identity) values



Discussion:
I think this shows how PauliString is broken.

I think instead you should make Pauli String know about identities.  I mean it already knows about qubits.  I think we are making the mistake of "implicit" identities being used (which is fine, as far as it goes), and then the current situation where "I" is somehow special.

It's pretty common for data structures to have a canonical form that they normalize to. In this case our canonical form is "identities are omitted, because otherwise it makes equality and hash codes slower".

Are you advocating for `print(cirq.I(a) * cirq.X(b))` to print out `I(a) * X(b)` instead of `X(b)`?
@Strilanc Is this right?

```python
>>> import cirq
>>> a = cirq.LineQubit(1)
>>> b = cirq.LineQubit(2)
>>> print(cirq.I(a) * cirq.X(b))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'GateOperation' and 'SingleQubitPauliStringGateOperation'
```

That's an example of what should start working to fix this issue.
I just submitted #1765 
Does #1765 actually address this, specifically during construction of the `PauliString`?

Resolving patch:
diff --git a/cirq/ops/pauli_string.py b/cirq/ops/pauli_string.py
--- a/cirq/ops/pauli_string.py
+++ b/cirq/ops/pauli_string.py
@@ -44,6 +44,11 @@ def __init__(self,
                  coefficient: Union[int, float, complex] = 1) -> None:
         if qubit_pauli_map is None:
             qubit_pauli_map = {}
+        qubit_pauli_map = {
+            q: p
+            for q, p in qubit_pauli_map.items()
+            if not isinstance(p, common_gates.IdentityGate)
+        }
         for p in qubit_pauli_map.values():
             if not isinstance(p, pauli_gates.Pauli):
                 raise TypeError(f'{p} is not a Pauli')


Test patch:
diff --git a/cirq/ops/pauli_string_test.py b/cirq/ops/pauli_string_test.py
--- a/cirq/ops/pauli_string_test.py
+++ b/cirq/ops/pauli_string_test.py
@@ -697,3 +697,9 @@ def test_cannot_multiply_by_non_paulis():
         _ = cirq.Z(q)**0.5 * cirq.X(q)
     with pytest.raises(TypeError):
         _ = cirq.Y(q) * cirq.S(q)
+
+
+def test_filters_identities():
+    q1, q2 = cirq.LineQubit.range(2)
+    assert cirq.PauliString({q1: cirq.I, q2: cirq.X}) == \
+           cirq.PauliString({q2: cirq.X})
Repository: quantumlib/Cirq

Issue:
ValueError for PhasedXPowGate with integer phase_exponent
`PhasedXPowGate._circuit_diagram_info_` contains a format string that throws a `ValueError` when `phase_exponent` is an `int`.  I know the type annotation specifies `float` but mypy allows int.

```
c = cirq.Circuit.from_ops(
    cirq.PhasedXPowGate(phase_exponent=1)(cirq.LineQubit(0)),
)
print(c)
```
Output:
```
...
~/docs/cirq/cirq/ops/phased_x_gate.py in _circuit_diagram_info_(self, args)
    154         else:
    155             s = 'PhasedX({{:.{}}})'.format(args.precision).format(
--> 156                 self.phase_exponent)
    157         return protocols.CircuitDiagramInfo(
    158             wire_symbols=(s,),

ValueError: Precision not allowed in integer format specifier
```


Discussion:
Saw this one today too

Resolving patch:
diff --git a/cirq/ops/phased_x_gate.py b/cirq/ops/phased_x_gate.py
--- a/cirq/ops/phased_x_gate.py
+++ b/cirq/ops/phased_x_gate.py
@@ -152,7 +152,7 @@ def _circuit_diagram_info_(self, args: protocols.CircuitDiagramInfoArgs
                 args.precision is None):
             s = 'PhasedX({})'.format(self.phase_exponent)
         else:
-            s = 'PhasedX({{:.{}}})'.format(args.precision).format(
+            s = 'PhasedX({{:.{}f}})'.format(args.precision).format(
                 self.phase_exponent)
         return protocols.CircuitDiagramInfo(
             wire_symbols=(s,),


Test patch:
diff --git a/cirq/ops/phased_x_gate_test.py b/cirq/ops/phased_x_gate_test.py
--- a/cirq/ops/phased_x_gate_test.py
+++ b/cirq/ops/phased_x_gate_test.py
@@ -184,11 +184,12 @@ def test_diagram():
     c = cirq.Circuit.from_ops(
         cirq.PhasedXPowGate(phase_exponent=sympy.Symbol('a'),
                             exponent=sympy.Symbol('b')).on(q),
-        cirq.PhasedXPowGate(phase_exponent=0.25,
-                            exponent=1).on(q)
+        cirq.PhasedXPowGate(phase_exponent=0.25, exponent=1).on(q),
+        cirq.PhasedXPowGate(phase_exponent=1, exponent=1).on(q),
     )
-    cirq.testing.assert_has_diagram(c, """
-q: ───PhasedX(a)^b───PhasedX(0.25)───
+    cirq.testing.assert_has_diagram(
+        c, """
+q: ───PhasedX(a)^b───PhasedX(0.25)───PhasedX(1.0)───
 """)
Repository: quantumlib/Cirq

Issue:
pytest fails but travis says green
https://travis-ci.com/quantumlib/Cirq/jobs/225040090

```
4 failed, 7087 passed, 26 skipped, 3 warnings in 96.07 seconds
The command "check/pytest --ignore=cirq/contrib --benchmark-skip --actually-quiet" exited with 0.
```


Discussion:
This has been a problem at least since #1937 and there were test failures in #1937 when it was merged.
The --actually-quiet flag is causing check/pytest to always exit with 0 (success).
ha was just reading that code.  guess today is bash script day
is it because while the pytest fails the grep suceeds?
Yes.  I'm making a PR for my fix.

Resolving patch:
diff --git a/cirq/ops/phased_x_gate.py b/cirq/ops/phased_x_gate.py
--- a/cirq/ops/phased_x_gate.py
+++ b/cirq/ops/phased_x_gate.py
@@ -151,8 +151,10 @@ def _circuit_diagram_info_(self, args: protocols.CircuitDiagramInfoArgs
         if (isinstance(self.phase_exponent, sympy.Symbol) or
                 args.precision is None):
             s = 'PhasedX({})'.format(self.phase_exponent)
+        elif isinstance(self.phase_exponent, int):
+            s = 'PhasedX({})'.format(self.phase_exponent)
         else:
-            s = 'PhasedX({{:.{}f}})'.format(args.precision).format(
+            s = 'PhasedX({{:.{}}})'.format(args.precision).format(
                 self.phase_exponent)
         return protocols.CircuitDiagramInfo(
             wire_symbols=(s,),


Test patch:
diff --git a/cirq/ops/phased_x_gate_test.py b/cirq/ops/phased_x_gate_test.py
--- a/cirq/ops/phased_x_gate_test.py
+++ b/cirq/ops/phased_x_gate_test.py
@@ -189,7 +189,7 @@ def test_diagram():
     )
     cirq.testing.assert_has_diagram(
         c, """
-q: ───PhasedX(a)^b───PhasedX(0.25)───PhasedX(1.0)───
+q: ───PhasedX(a)^b───PhasedX(0.25)───PhasedX(1)───
 """)
Repository: quantumlib/Cirq

Issue:
Non-EigenGates don't have equality semantics
```python
assert cirq.CSwapGate() == cirq.CSwapGate()
```

```
Assertion failed
cirq.FREDKIN != cirq.FREDKIN

Expected :cirq.FREDKIN
Actual   :cirq.FREDKIN
```


Discussion:
`CSwapGate` needs to be decorated with `@value.value_equality()`.

Resolving patch:
diff --git a/cirq/ops/three_qubit_gates.py b/cirq/ops/three_qubit_gates.py
--- a/cirq/ops/three_qubit_gates.py
+++ b/cirq/ops/three_qubit_gates.py
@@ -26,8 +26,8 @@
     controlled_gate,
     eigen_gate,
     gate_features,
-    pauli_gates,
     op_tree,
+    pauli_gates,
     raw_types,
 )
 if TYPE_CHECKING:
@@ -35,6 +35,7 @@
     import cirq
 
 
+
 class CCZPowGate(eigen_gate.EigenGate,
                  gate_features.ThreeQubitGate,
                  gate_features.InterchangeableQubitsGate):
@@ -166,8 +167,8 @@ def __init__(self,
             diag_angles_radians: The list of angles on the diagonal in radians.
 
         """
-        self._diag_angles_radians = diag_angles_radians \
-        # type: List[Union[float, sympy.Basic]]
+        self._diag_angles_radians: List[
+            Union[float, sympy.Basic]] = diag_angles_radians
 
     def _is_parameterized_(self):
         return any(
@@ -380,6 +381,7 @@ def __str__(self) -> str:
         return 'TOFFOLI**{}'.format(self._exponent)
 
 
+@value.value_equality()
 class CSwapGate(gate_features.ThreeQubitGate,
                 gate_features.InterchangeableQubitsGate):
     """A controlled swap gate. The Fredkin gate."""
@@ -519,6 +521,9 @@ def _qasm_(self,
         return args.format('cswap {0},{1},{2};\n',
                            qubits[0], qubits[1], qubits[2])
 
+    def _value_equality_values_(self):
+        return ()
+
     def __str__(self) -> str:
         return 'FREDKIN'
 


Test patch:
diff --git a/cirq/ops/three_qubit_gates_test.py b/cirq/ops/three_qubit_gates_test.py
--- a/cirq/ops/three_qubit_gates_test.py
+++ b/cirq/ops/three_qubit_gates_test.py
@@ -142,6 +142,14 @@ def test_eq():
     eq.add_equality_group(cirq.CSWAP(b, a, c), cirq.CSWAP(b, c, a))
 
 
+def test_gate_equality():
+    eq = cirq.testing.EqualsTester()
+    eq.add_equality_group(cirq.CSwapGate(), cirq.CSwapGate())
+    eq.add_equality_group(cirq.CZPowGate(), cirq.CZPowGate())
+    eq.add_equality_group(cirq.CCXPowGate(), cirq.CCXPowGate())
+    eq.add_equality_group(cirq.CCZPowGate(), cirq.CCZPowGate())
+
+
 @pytest.mark.parametrize('op,max_two_cost', [
     (cirq.CCZ(*cirq.LineQubit.range(3)), 8),
     (cirq.CCX(*cirq.LineQubit.range(3)), 8),
Repository: quantumlib/Cirq

Issue:
ControlledOperation objects do not (un)pickle
Python version 3.6.8
Cirq Version = 0.6.0.dev (also in 0.5.0)

Attempting to unpickle any ops.ControlledOperation object, either by pickle or by dill, results in an error.

Code to reproduce:

```
import pickle
import cirq
import sympy

dump=pickle.dumps(cirq.Rx(sympy.Symbol('param')).on(cirq.LineQubit(0)).controlled_by(cirq.LineQubit(1)))
load=pickle.loads(dump)
```

Error message:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/sumneralperin-lea/anaconda3/envs/quantum/lib/python3.6/pickle.py", line 1558, in _loads
    encoding=encoding, errors=errors).load()
  File "/Users/sumneralperin-lea/anaconda3/envs/quantum/lib/python3.6/pickle.py", line 1050, in load
    dispatch[key[0]](self)
  File "/Users/sumneralperin-lea/anaconda3/envs/quantum/lib/python3.6/pickle.py", line 1323, in load_newobj
    obj = cls.__new__(cls, *args)
TypeError: __new__() missing 2 required positional arguments: 'controls' and 'sub_operation'
```
Extra info/commentary:

Though this issue doesn't reside exclusively in cirq, it does restrict the (full) use of cirq with some standard python modules. In my particular use case, it prevents use of the multiprocessing module to parallelize the simulation of circuits.




Discussion:
This is happening because ControlledOperation is doing custom object creation inside `__new__`.  In this case the logic in `ControlledOperation.__new__` could be moved to `__init__` to fix this issue.

Resolving patch:
diff --git a/cirq/ops/controlled_operation.py b/cirq/ops/controlled_operation.py
--- a/cirq/ops/controlled_operation.py
+++ b/cirq/ops/controlled_operation.py
@@ -23,21 +23,17 @@
 
 @value.value_equality
 class ControlledOperation(raw_types.Operation):
-    def __new__(cls,
-                controls: Sequence[raw_types.Qid],
-                sub_operation: raw_types.Operation):
-        """Auto-flatten nested controlled operations."""
-        if isinstance(sub_operation, ControlledOperation):
-            return ControlledOperation(
-                tuple(controls) + sub_operation.controls,
-                sub_operation.sub_operation)
-        return super().__new__(cls)
 
     def __init__(self,
                  controls: Sequence[raw_types.Qid],
                  sub_operation: raw_types.Operation):
-        self.controls = tuple(controls)
-        self.sub_operation = sub_operation
+        if not isinstance(sub_operation, ControlledOperation):
+            self.controls = tuple(controls)
+            self.sub_operation = sub_operation
+        else:
+            # Auto-flatten nested controlled operations.
+            self.controls = tuple(controls) + sub_operation.controls
+            self.sub_operation = sub_operation.sub_operation
 
     @property
     def qubits(self):


Test patch:
Repository: quantumlib/Cirq

Issue:
Squared ISWAP fails trace distance bound test
```
In [1]: import cirq

In [2]: cirq.testing.consistent_protocols.assert_has_consistent_trace_distance_bound(cirq.ISWAP**2)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-2-9d7942dfa2d6> in <module>
----> 1 cirq.testing.consistent_protocols.assert_has_consistent_trace_distance_bound(cirq.ISWAP**2)

~/src/Cirq/cirq/testing/consistent_protocols.py in assert_has_consistent_trace_distance_bound(val)
    109 
    110         assert val_from_trace >= val_from_unitary or np.isclose(
--> 111             val_from_trace, val_from_unitary)
    112 
    113 

AssertionError: 

In [3]: cirq.trace_distance_bound(cirq.ISWAP**2)
Out[3]: 1.2246467991473532e-16
```

I guess we really care about this near identity, but still the protocol explicitly says "Underestimates are not permitted.", so we should fix it in case it's relied on in future.

Other exponents in [1.0029..2.9971] also fail the check.


Discussion:
In error I added a special case that doesn't apply to ISWAP gate. If the `_trace_distance_bound_` method of the `ISwapPowGate` class is removed then the `EigenGate` version will be used instead which should return accurate results.

Resolving patch:
diff --git a/cirq/ops/common_gates.py b/cirq/ops/common_gates.py
--- a/cirq/ops/common_gates.py
+++ b/cirq/ops/common_gates.py
@@ -1287,11 +1287,6 @@ def _eigen_components(self):
                              [0, 0, 0, 0]])),
         ]
 
-    def _trace_distance_bound_(self) -> Optional[float]:
-        if self._is_parameterized_():
-            return None
-        return abs(np.sin(self._exponent * 0.5 * np.pi))
-
     def _decompose_(self, qubits):
         a, b = qubits
 


Test patch:
diff --git a/cirq/ops/common_gates_test.py b/cirq/ops/common_gates_test.py
--- a/cirq/ops/common_gates_test.py
+++ b/cirq/ops/common_gates_test.py
@@ -738,6 +738,11 @@ def test_iswap_unitary():
         atol=1e-8)
 
 
+def test_iswap_trace_distance():
+    for exp in np.linspace(0, 4, 20):
+        cirq.testing.assert_has_consistent_trace_distance_bound(cirq.ISWAP**exp)
+
+
 def test_iswap_decompose_diagram():
     a = cirq.NamedQubit('a')
     b = cirq.NamedQubit('b')
Repository: quantumlib/Cirq

Issue:
Support appending individual Operations to Circuits
Current behavior:

```
        circuit_with_measurements = circuit + cirq.measure(*qubit_order,
>                                                          key=MEASUREMENT_KEY)
E       TypeError: unsupported operand type(s) for +: 'Circuit' and 'GateOperation'
```




Discussion:

Resolving patch:
diff --git a/cirq/circuits/circuit.py b/cirq/circuits/circuit.py
--- a/cirq/circuits/circuit.py
+++ b/cirq/circuits/circuit.py
@@ -249,10 +249,12 @@ def __iadd__(self, other):
         return self
 
     def __add__(self, other):
-        if isinstance(other, list):
-            other = Circuit(other)
         if not isinstance(other, type(self)):
-            return NotImplemented
+            if not isinstance(other, (ops.Operation, Iterable)):
+                return NotImplemented
+            # Auto wrap OP_TREE inputs into a circuit.
+            other = Circuit(other)
+
         device = (self._device if other.device is devices.UNCONSTRAINED_DEVICE
                   else other.device)
         device_2 = (other.device if self._device is devices.UNCONSTRAINED_DEVICE
diff --git a/cirq/ops/op_tree.py b/cirq/ops/op_tree.py
--- a/cirq/ops/op_tree.py
+++ b/cirq/ops/op_tree.py
@@ -85,7 +85,7 @@ def flatten_to_ops(root: OP_TREE) -> Iterator[Operation]:
     """
     if isinstance(root, Operation):
         yield root
-    elif isinstance(root, Iterable):
+    elif isinstance(root, Iterable) and not isinstance(root, str):
         for subtree in root:
             yield from flatten_to_ops(subtree)
     else:
@@ -107,7 +107,7 @@ def flatten_to_ops_or_moments(root: OP_TREE
     """
     if isinstance(root, (Operation, Moment)):
         yield root
-    elif isinstance(root, Iterable):
+    elif isinstance(root, Iterable) and not isinstance(root, str):
         for subtree in root:
             yield from flatten_to_ops_or_moments(subtree)
     else:
@@ -143,7 +143,7 @@ def transform_op_tree(
     if preserve_moments and isinstance(root, Moment):
         return root
 
-    if isinstance(root, Iterable):
+    if isinstance(root, Iterable) and not isinstance(root, str):
         return iter_transformation(
             transform_op_tree(subtree,
                               op_transformation,


Test patch:
diff --git a/cirq/circuits/circuit_test.py b/cirq/circuits/circuit_test.py
--- a/cirq/circuits/circuit_test.py
+++ b/cirq/circuits/circuit_test.py
@@ -239,6 +239,14 @@ def test_add_op_tree():
         cirq.Moment([cirq.X(a), cirq.Y(b)]),
     ])
 
+    assert c + cirq.X(a) == cirq.Circuit(cirq.X(a))
+    assert c + [cirq.X(a)] == cirq.Circuit(cirq.X(a))
+    assert c + [[[cirq.X(a)], []]] == cirq.Circuit(cirq.X(a))
+    assert c + (cirq.X(a),) == cirq.Circuit(cirq.X(a))
+    assert c + (cirq.X(a) for _ in range(1)) == cirq.Circuit(cirq.X(a))
+    with pytest.raises(TypeError):
+        _ = c + cirq.X
+
 
 def test_bool():
     assert not cirq.Circuit()
Repository: quantumlib/Cirq

Issue:
Simulator modifies initial state
It seems that sparse_simulator modifies the initial_state argument in place during simulation. Is this a bug or a feature?


Discussion:
bug

Resolving patch:
diff --git a/cirq/sim/wave_function.py b/cirq/sim/wave_function.py
--- a/cirq/sim/wave_function.py
+++ b/cirq/sim/wave_function.py
@@ -356,7 +356,7 @@ def to_valid_state_vector(
                 'initial state was of size {} '
                 'but expected state for {} qubits with qid shape {}'.format(
                     len(state_rep), num_qubits, qid_shape))
-        state = state_rep
+        state = state_rep.copy()
     elif isinstance(state_rep, int):
         if state_rep < 0:
             raise ValueError('initial_state must be positive')


Test patch:
diff --git a/cirq/sim/sparse_simulator_test.py b/cirq/sim/sparse_simulator_test.py
--- a/cirq/sim/sparse_simulator_test.py
+++ b/cirq/sim/sparse_simulator_test.py
@@ -605,6 +605,30 @@ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs):
     assert not initial_state is result.state_vector()
 
 
+def test_does_not_modify_initial_state():
+    q0 = cirq.LineQubit(0)
+    simulator = cirq.Simulator()
+
+    class InPlaceUnitary(cirq.SingleQubitGate):
+
+        def _has_unitary_(self):
+            return True
+
+        def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs):
+            args.target_tensor[0], args.target_tensor[1] = (
+                args.target_tensor[1], args.target_tensor[0])
+            return args.target_tensor
+
+    circuit = cirq.Circuit(InPlaceUnitary()(q0))
+
+    initial_state = np.array([1, 0], dtype=np.complex64)
+    result = simulator.simulate(circuit, initial_state=initial_state)
+    np.testing.assert_array_almost_equal(np.array([1, 0], dtype=np.complex64),
+                                         initial_state)
+    np.testing.assert_array_almost_equal(result.state_vector(),
+                                         np.array([0, 1], dtype=np.complex64))
+
+
 def test_simulator_step_state_mixin():
     qubits = cirq.LineQubit.range(2)
     qubit_map = {qubits[i]: i for i in range(2)}
diff --git a/cirq/sim/wave_function_test.py b/cirq/sim/wave_function_test.py
--- a/cirq/sim/wave_function_test.py
+++ b/cirq/sim/wave_function_test.py
@@ -261,6 +261,12 @@ def test_to_valid_state_vector():
                                    np.array([0.0, 1.0, 0.0, 0.0]))
 
 
+def test_to_valid_state_vector_creates_new_copy():
+    state = np.array([1.0, 0.0, 0.0, 0.0], dtype=np.complex64)
+    out = cirq.to_valid_state_vector(state, 2)
+    assert out is not state
+
+
 def test_invalid_to_valid_state_vector():
     with pytest.raises(ValueError):
         _ = cirq.to_valid_state_vector(
Repository: quantumlib/Cirq

Issue:
bug in supremacy test circuit
I ran the function
```
generate_boixo_2018_supremacy_circuits_v2_bristlecone(
        n_rows: int, cz_depth: int, seed: int) -> circuits.Circuit
```
in `cirq.experiments.google_v2_supremacy_circuit` with `n_rows = 1` and got trapped in infinite loops.

I think this is because when we have `n_rows = 1`,  `_make_cz_layer` would never return any cz gate, since there's only one qubit, thus in ` _add_cz_layer`, the loop
```
while not cz_layer:
        qubits = cast(Iterable[devices.GridQubit], circuit.all_qubits())
        cz_layer = list(_make_cz_layer(qubits, layer_index))
        layer_index += 1
```
would never end.

My suggestion would be change `assert 1 <= n_rows <= 11` in `generate_boixo_2018_supremacy_circuits_v2_bristlecone` to `assert 2 <= n_rows <= 11`, since it does not make anysense to have one-qubit cz layer in the first place.


Discussion:

Resolving patch:
diff --git a/cirq/experiments/google_v2_supremacy_circuit.py b/cirq/experiments/google_v2_supremacy_circuit.py
--- a/cirq/experiments/google_v2_supremacy_circuit.py
+++ b/cirq/experiments/google_v2_supremacy_circuit.py
@@ -132,7 +132,7 @@ def count_neighbors(qubits, qubit):
                 ]
             return len(list(e for e in possibles if e in qubits))
 
-        assert 1 <= n_rows <= 11
+        assert 2 <= n_rows <= 11
         max_row = n_rows - 1
         dev = google.Bristlecone
         # we need a consistent order of qubits


Test patch:
Repository: quantumlib/Cirq

Issue:
Escape unicode characters when producing latex
Currently, the qcircuit to latex code passes through unicode characters like ↺ ↻. LaTeX may not be happy about this. We should replace the unicode characters with some that LaTeX is happy with. Or perhaps throw an error?


Discussion:
\usepackage[utf8]{inputenc} seems to do the trick.  Probably should only add it if there is unicode in the text.
Hi, could you please assign this to me?

Resolving patch:
diff --git a/cirq/contrib/qcircuit/qcircuit_pdf.py b/cirq/contrib/qcircuit/qcircuit_pdf.py
--- a/cirq/contrib/qcircuit/qcircuit_pdf.py
+++ b/cirq/contrib/qcircuit/qcircuit_pdf.py
@@ -50,6 +50,7 @@ def circuit_to_pdf_using_qcircuit_via_tex(circuit: circuits.Circuit,
     doc = Document(documentclass=documentclass, document_options='dvips')
     doc.packages.append(Package('amsmath'))
     doc.packages.append(Package('qcircuit'))
+    doc.preamble.append(Package('inputenc', options=['utf8']))
     doc.append(NoEscape(tex))
     doc.generate_pdf(filepath, **pdf_kwargs)
     for ext in clean_ext:


Test patch:
Repository: quantumlib/Cirq

Issue:
Cirq should ship a py.typed file
[PEP 561](https://www.python.org/dev/peps/pep-0561/) says that any packages that ship with type information should have a py.typed file in their package. Otherwise, type checkers like mypy can't find Cirq. (FWIW I just did `touch ~/.virtualenvs/.../cirq/py.typed`, and then mypy type-checks the file correctly.)

Other than that, Cirq seems pretty awesome so far :ok_hand:.
Cirq should ship a py.typed file
[PEP 561](https://www.python.org/dev/peps/pep-0561/) says that any packages that ship with type information should have a py.typed file in their package. Otherwise, type checkers like mypy can't find Cirq. (FWIW I just did `touch ~/.virtualenvs/.../cirq/py.typed`, and then mypy type-checks the file correctly.)

Other than that, Cirq seems pretty awesome so far :ok_hand:.


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -70,6 +70,7 @@
       long_description=long_description,
       packages=cirq_packages,
       package_data={
+          'cirq': ['py.typed'],
           'cirq.api.google.v1': ['*.proto'],
           'cirq.api.google.v2': ['*.proto'],
           'cirq.google.api.v1': ['*.proto'],


Test patch: