From 1f0fc1de9809e30d031d2e537e9d8fd0510bebca Mon Sep 17 00:00:00 2001 From: Dave Bacon Date: Tue, 9 Nov 2021 07:55:53 +0000 Subject: [PATCH] More lint documentation fixes. (#4641) Continuing the battle versus #3388 --- .../cirq/contrib/acquaintance/executor.py | 8 +- cirq-core/cirq/contrib/acquaintance/shift.py | 20 +- .../acquaintance/strategies/complete.py | 3 - .../cirq/contrib/qcircuit/qcircuit_pdf.py | 8 +- cirq-core/cirq/contrib/quimb/mps_simulator.py | 23 ++- cirq-core/cirq/contrib/routing/router.py | 14 +- cirq-core/cirq/ion/ion_gates.py | 8 +- cirq-core/cirq/ops/matrix_gates.py | 13 +- cirq-core/cirq/ops/permutation_gate.py | 12 +- cirq-core/cirq/ops/qubit_order.py | 14 +- cirq-core/cirq/ops/wait_gate.py | 12 +- .../optimizers/three_qubit_decomposition.py | 10 +- .../cirq/optimizers/two_qubit_to_fsim.py | 13 +- cirq-core/cirq/study/resolver_test.py | 14 +- .../optimizers/convert_to_sycamore_gates.py | 176 ++++++++---------- .../serialization/circuit_serializer.py | 32 ++-- .../serialization/serializable_gate_set.py | 32 ++-- .../serializable_gate_set_test.py | 2 +- .../cirq_web/bloch_sphere/bloch_sphere.py | 7 +- dev_tools/incremental_coverage.py | 23 +-- examples/hhl.py | 112 +++++------ examples/quantum_fourier_transform.py | 11 +- 22 files changed, 257 insertions(+), 310 deletions(-) diff --git a/cirq-core/cirq/contrib/acquaintance/executor.py b/cirq-core/cirq/contrib/acquaintance/executor.py index ec0f60f8c33..eab04835d24 100644 --- a/cirq-core/cirq/contrib/acquaintance/executor.py +++ b/cirq-core/cirq/contrib/acquaintance/executor.py @@ -131,9 +131,6 @@ class GreedyExecutionStrategy(ExecutionStrategy): qubits in any order are inserted. """ - # TODO(#3388) Add documentation for Args. - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-param-doc,missing-raises-doc def __init__( self, gates: LogicalGates, initial_mapping: LogicalMapping, device: 'cirq.Device' = None ) -> None: @@ -142,6 +139,10 @@ def __init__( Args: gates: The gates to insert. initial_mapping: The initial mapping of qubits to logical indices. + device: The device upon which to execute the strategy. + + Raises: + NotImplementedError: If not all gates are of the same arity. """ if len(set(len(indices) for indices in gates)) > 1: @@ -152,7 +153,6 @@ def __init__( self._initial_mapping = initial_mapping.copy() self._device = device or devices.UNCONSTRAINED_DEVICE - # pylint: enable=missing-param-doc,missing-raises-doc @property def initial_mapping(self) -> LogicalMapping: return self._initial_mapping diff --git a/cirq-core/cirq/contrib/acquaintance/shift.py b/cirq-core/cirq/contrib/acquaintance/shift.py index 8b2d2c5aba5..29a8b01622f 100644 --- a/cirq-core/cirq/contrib/acquaintance/shift.py +++ b/cirq-core/cirq/contrib/acquaintance/shift.py @@ -22,19 +22,18 @@ import cirq -# TODO(#3388) Add documentation for Args. -# pylint: disable=missing-param-doc @value.value_equality class CircularShiftGate(PermutationGate): - """Performs a cyclical permutation of the qubits to the left by a specified - amount. - - Args: - shift: how many positions to circularly left shift the qubits. - swap_gate: the gate to use when decomposing. - """ + """Performs a cyclical permutation of the qubits to the left by a specified amount.""" def __init__(self, num_qubits: int, shift: int, swap_gate: 'cirq.Gate' = ops.SWAP) -> None: + """Construct a circular shift gate. + + Args: + num_qubits: The number of qubits to shift. + shift: The number of positions to circularly left shift the qubits. + swap_gate: The gate to use when decomposing. + """ super(CircularShiftGate, self).__init__(num_qubits, swap_gate) self.shift = shift @@ -75,6 +74,3 @@ def permutation(self) -> Dict[int, int]: shift = self.shift % self.num_qubits() permuted_indices = itertools.chain(range(shift, self.num_qubits()), range(shift)) return {s: i for i, s in enumerate(permuted_indices)} - - -# pylint: enable=missing-param-doc diff --git a/cirq-core/cirq/contrib/acquaintance/strategies/complete.py b/cirq-core/cirq/contrib/acquaintance/strategies/complete.py index 948156baa3a..b036d37a055 100755 --- a/cirq-core/cirq/contrib/acquaintance/strategies/complete.py +++ b/cirq-core/cirq/contrib/acquaintance/strategies/complete.py @@ -27,9 +27,6 @@ import cirq -# TODO(#3388) Add summary line to docstring. -# TODO(#3388) Add documentation for Raises. -# pylint: disable=docstring-first-line-empty,missing-raises-doc def complete_acquaintance_strategy( qubit_order: Sequence['cirq.Qid'], acquaintance_size: int = 0, swap_gate: 'cirq.Gate' = ops.SWAP ) -> 'cirq.Circuit': diff --git a/cirq-core/cirq/contrib/qcircuit/qcircuit_pdf.py b/cirq-core/cirq/contrib/qcircuit/qcircuit_pdf.py index f841c518e8c..9d3955c63c0 100644 --- a/cirq-core/cirq/contrib/qcircuit/qcircuit_pdf.py +++ b/cirq-core/cirq/contrib/qcircuit/qcircuit_pdf.py @@ -23,8 +23,6 @@ from cirq.contrib.qcircuit.qcircuit_diagram import circuit_to_latex_using_qcircuit -# TODO(#3388) Add documentation for Raises. -# pylint: disable=missing-raises-doc def circuit_to_pdf_using_qcircuit_via_tex( circuit: circuits.Circuit, filepath: str, @@ -45,6 +43,9 @@ def circuit_to_pdf_using_qcircuit_via_tex( default, latexmk is used with the '-pdfps' flag, which produces intermediary dvi and ps files. documentclass: The documentclass of the latex file. + + Raises: + OSError, IOError: If cleanup fails. """ pdf_kwargs = { 'compiler': 'latexmk', @@ -65,6 +66,3 @@ def circuit_to_pdf_using_qcircuit_via_tex( except (OSError, IOError) as e: if e.errno != errno.ENOENT: raise - - -# pylint: enable=missing-raises-doc diff --git a/cirq-core/cirq/contrib/quimb/mps_simulator.py b/cirq-core/cirq/contrib/quimb/mps_simulator.py index 6f14cda30ac..babab61e894 100644 --- a/cirq-core/cirq/contrib/quimb/mps_simulator.py +++ b/cirq-core/cirq/contrib/quimb/mps_simulator.py @@ -58,8 +58,6 @@ class MPSSimulator( ): """An efficient simulator for MPS circuits.""" - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def __init__( self, noise: 'cirq.NOISE_MODEL_LIKE' = None, @@ -74,6 +72,9 @@ def __init__( seed: The random seed to use for this simulator. simulation_options: Numerical options for the simulation. grouping: How to group qubits together, if None all are individual. + + Raises: + ValueError: If the noise model is not unitary or a mixture. """ self.init = True noise_model = devices.NoiseModel.from_noise_model_like(noise) @@ -86,9 +87,6 @@ def __init__( seed=seed, ) - # pylint: enable=missing-raises-doc - # TODO(#3388) Add documentation for Args. - # pylint: disable=missing-param-doc def _create_partial_act_on_args( self, initial_state: Union[int, 'MPSState'], @@ -103,6 +101,7 @@ def _create_partial_act_on_args( qubits: Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. + logs: A mutable object that measurements are recorded into. Returns: MPSState args for simulating the Circuit. @@ -119,7 +118,6 @@ def _create_partial_act_on_args( log_of_measurement_results=logs, ) - # pylint: enable=missing-param-doc def _create_step_result( self, sim_state: 'cirq.OperationTarget[MPSState]', @@ -211,8 +209,6 @@ def _simulator_state(self): class MPSState(ActOnArgs): """A state of the MPS simulation.""" - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def __init__( self, qubits: Sequence['cirq.Qid'], @@ -234,6 +230,9 @@ def __init__( initial_state: An integer representing the initial state. log_of_measurement_results: A mutable object that measurements are being recorded into. + + Raises: + ValueError: If the grouping does not cover the qubits. """ super().__init__(prng, qubits, log_of_measurement_results) qubit_map = self.qubit_map @@ -272,7 +271,6 @@ def __init__( self.simulation_options = simulation_options self.estimated_gate_error_list: List[float] = [] - # pylint: enable=missing-raises-doc def i_str(self, i: int) -> str: # Returns the index name for the i'th qid. return self.format_i.format(i) @@ -464,8 +462,6 @@ def estimation_stats(self): "estimated_fidelity": estimated_fidelity, } - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def perform_measurement( self, qubits: Sequence[ops.Qid], prng: np.random.RandomState, collapse_state_vector=True ) -> List[int]: @@ -476,6 +472,10 @@ def perform_measurement( prng: A random number generator, used to simulate measurements. collapse_state_vector: A Boolean specifying whether we should mutate the state after the measurement. + + Raises: + ValueError: If the probabilities for the measurements differ too much from one for the + tolerance specified in simulation options. """ results: List[int] = [] @@ -515,7 +515,6 @@ def perform_measurement( return results - # pylint: enable=missing-raises-doc def _perform_measurement(self, qubits: Sequence['cirq.Qid']) -> List[int]: """Measures the axes specified by the simulator.""" return self.perform_measurement(qubits, self.prng) diff --git a/cirq-core/cirq/contrib/routing/router.py b/cirq-core/cirq/contrib/routing/router.py index e41dc05e30b..cf8955382b8 100644 --- a/cirq-core/cirq/contrib/routing/router.py +++ b/cirq-core/cirq/contrib/routing/router.py @@ -25,8 +25,6 @@ } -# TODO(#3388) Add documentation for Raises. -# pylint: disable=missing-raises-doc def route_circuit( circuit: circuits.Circuit, device_graph: nx.Graph, @@ -41,11 +39,16 @@ def route_circuit( Args: circuit: The circuit to route. - device_graph: The device's graph, in which each vertex is a qubit and - each edge indicates the ability to do an operation on those qubits. + device_graph: The device's graph, in which each vertex is a qubit and each edge indicates + the ability to do an operation on those qubits. algo_name: The name of a routing algorithm. Must be in ROUTERS. router: The function that actually does the routing. **kwargs: Arguments to pass to the routing algorithm. + + Raises: + ValueError: If the circuit contains operations on more than two qubits, the number of + qubits in the circuit are more than those of the device, both `algo_name` and `router` + are specified, or no routing algorithm is specified. """ if any(protocols.num_qubits(op) > 2 for op in circuit.all_operations()): @@ -61,6 +64,3 @@ def route_circuit( elif router is None: raise ValueError(f'No routing algorithm specified.') return router(circuit, device_graph, **kwargs) - - -# pylint: enable=missing-raises-doc diff --git a/cirq-core/cirq/ion/ion_gates.py b/cirq-core/cirq/ion/ion_gates.py index 161cab3719d..df94418514d 100644 --- a/cirq-core/cirq/ion/ion_gates.py +++ b/cirq-core/cirq/ion/ion_gates.py @@ -69,10 +69,9 @@ def _from_json_dict_(cls, rads: float, **kwargs: Any) -> 'MSGate': return cls(rads=rads) -# TODO(#3388) Add summary line to docstring. -# pylint: disable=docstring-first-line-empty def ms(rads: float) -> MSGate: - """ + """A helper to construct the `cirq.MSGate` for the given angle specified in radians. + Args: rads: The rotation angle in radians. @@ -80,6 +79,3 @@ def ms(rads: float) -> MSGate: Mølmer–Sørensen gate rotating by the desired amount. """ return MSGate(rads=rads) - - -# pylint: enable=docstring-first-line-empty diff --git a/cirq-core/cirq/ops/matrix_gates.py b/cirq-core/cirq/ops/matrix_gates.py index 3c17e80d045..a9286a89ecd 100644 --- a/cirq-core/cirq/ops/matrix_gates.py +++ b/cirq-core/cirq/ops/matrix_gates.py @@ -29,9 +29,6 @@ class MatrixGate(raw_types.Gate): """A unitary qubit or qudit gate defined entirely by its matrix.""" - # TODO(#3388) Add documentation for Args. - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-param-doc,missing-raises-doc def __init__( self, matrix: np.ndarray, @@ -49,6 +46,15 @@ def __init__( qid_shape: The shape of state tensor that the matrix applies to. If not specified, this value is inferred by assuming that the matrix is supposed to apply to qubits. + unitary_check_rtol: The relative tolerance for checking whether the supplied matrix + is unitary. See `cirq.is_unitary`. + unitary_check_atol: The absolute tolerance for checking whether the supplied matrix + is unitary. See `cirq.is_unitary`. + + Raises: + ValueError: If the matrix is not a square numpy array, if the matrix does not match + the `qid_shape`, if `qid_shape` is not supplied and the matrix dimension is + not a power of 2, or if the matrix not unitary (to the supplied precisions). """ if len(matrix.shape) != 2 or matrix.shape[0] != matrix.shape[1]: raise ValueError('`matrix` must be a square 2d numpy array.') @@ -76,7 +82,6 @@ def __init__( if not linalg.is_unitary(matrix, rtol=unitary_check_rtol, atol=unitary_check_atol): raise ValueError(f'Not a unitary matrix: {self._matrix}') - # pylint: enable=missing-param-doc,missing-raises-doc def _json_dict_(self) -> Dict[str, Any]: return { 'cirq_type': self.__class__.__name__, diff --git a/cirq-core/cirq/ops/permutation_gate.py b/cirq-core/cirq/ops/permutation_gate.py index a82af77a631..2633371bd14 100644 --- a/cirq-core/cirq/ops/permutation_gate.py +++ b/cirq-core/cirq/ops/permutation_gate.py @@ -25,15 +25,17 @@ class QubitPermutationGate(raw_types.Gate): """A qubit permutation gate specified by a permutation list.""" - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def __init__(self, permutation: Sequence[int]): - """Inits QubitPermutationGate. + """Create a `cirq.QubitPermutationGate`. Args: permutation: A shuffled sequence of integers from 0 to len(permutation) - 1. The entry at offset `i` is the result of permuting `i`. + + Raises: + ValueError: If the supplied permutation is not valid (empty, repeated indices, indices + out of range). """ if not permutation: raise ValueError(f"Invalid permutation (empty): {permutation}") @@ -44,14 +46,12 @@ def __init__(self, permutation: Sequence[int]): invalid_indices = [x for x in permutation if not 0 <= x < len(permutation)] if len(invalid_indices) > 0: raise ValueError( - f"All indices have to satisfy " - f"0 <= i < {len(permutation)}. " + f"All indices have to satisfy 0 <= i < {len(permutation)}.\n" f"Invalid indices: {invalid_indices}" ) self.permutation = tuple(permutation) - # pylint: enable=missing-raises-doc def _value_equality_values_(self): return self.permutation diff --git a/cirq-core/cirq/ops/qubit_order.py b/cirq-core/cirq/ops/qubit_order.py index a5048c7aafd..b8b79cb517f 100644 --- a/cirq-core/cirq/ops/qubit_order.py +++ b/cirq-core/cirq/ops/qubit_order.py @@ -49,8 +49,6 @@ def __init__( it is the x coordinate of the qubit). """ - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc @staticmethod def explicit( fixed_qubits: Iterable[raw_types.Qid], fallback: Optional['QubitOrder'] = None @@ -67,6 +65,10 @@ def explicit( Returns: A Basis instance that forces the given qubits in the given order. + + Raises: + ValueError: If a qubit appears twice in `fixed_qubits`, or there were is no fallback + specified but there are extra qubits. """ result = tuple(fixed_qubits) if len(set(result)) < len(result): @@ -82,7 +84,6 @@ def func(qubits): return QubitOrder(func) - # pylint: enable=missing-raises-doc @staticmethod def sorted_by(key: Callable[[raw_types.Qid], Any]) -> 'QubitOrder': """A basis that orders qubits ascending based on a key function. @@ -91,7 +92,6 @@ def sorted_by(key: Callable[[raw_types.Qid], Any]) -> 'QubitOrder': key: A function that takes a qubit and returns a key value. The basis will be ordered ascending according to these key values. - Returns: A basis that orders qubits ascending based on a key function. """ @@ -111,8 +111,6 @@ def order_for(self, qubits: Iterable[raw_types.Qid]) -> Tuple[raw_types.Qid, ... """ return self._explicit_func(qubits) - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc @staticmethod def as_qubit_order(val: 'qubit_order_or_list.QubitOrderOrList') -> 'QubitOrder': """Converts a value into a basis. @@ -122,6 +120,9 @@ def as_qubit_order(val: 'qubit_order_or_list.QubitOrderOrList') -> 'QubitOrder': Returns: The basis implied by the value. + + Raises: + ValueError: If `val` is not an iterable or a `QubitOrder`. """ if isinstance(val, Iterable): return QubitOrder.explicit(val) @@ -129,7 +130,6 @@ def as_qubit_order(val: 'qubit_order_or_list.QubitOrderOrList') -> 'QubitOrder': return val raise ValueError(f"Don't know how to interpret <{val}> as a Basis.") - # pylint: enable=missing-raises-doc def map( self, internalize: Callable[[TExternalQubit], TInternalQubit], diff --git a/cirq-core/cirq/ops/wait_gate.py b/cirq-core/cirq/ops/wait_gate.py index 304d5f3c41d..c2de2f9455e 100644 --- a/cirq-core/cirq/ops/wait_gate.py +++ b/cirq-core/cirq/ops/wait_gate.py @@ -30,9 +30,6 @@ class WaitGate(raw_types.Gate): simulators and noise models may insert more error for longer waits. """ - # TODO(#3388) Add documentation for Args. - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-param-doc,missing-raises-doc def __init__( self, duration: 'cirq.DURATION_LIKE', @@ -44,6 +41,14 @@ def __init__( Args: duration: A constant or parameterized wait duration. This can be an instance of `datetime.timedelta` or `cirq.Duration`. + num_qubits: The number of qubits the gate operates on. If None and `qid_shape` is None, + this defaults to one qubit. + qid_shape: Can be specified instead of `num_qubits` for the case that the gate should + act on qudits. + + Raises: + ValueError: If the `qid_shape` provided is empty or `num_qubits` contradicts + `qid_shape`. """ self.duration = value.Duration(duration) if not protocols.is_parameterized(self.duration) and self.duration < 0: @@ -62,7 +67,6 @@ def __init__( raise ValueError('len(qid_shape) != num_qubits') self._qid_shape = qid_shape - # pylint: enable=missing-param-doc,missing-raises-doc def _is_parameterized_(self) -> bool: return protocols.is_parameterized(self.duration) diff --git a/cirq-core/cirq/optimizers/three_qubit_decomposition.py b/cirq-core/cirq/optimizers/three_qubit_decomposition.py index ae6bbfae4b6..ab6a611d4ac 100644 --- a/cirq-core/cirq/optimizers/three_qubit_decomposition.py +++ b/cirq-core/cirq/optimizers/three_qubit_decomposition.py @@ -21,8 +21,6 @@ from cirq import optimizers as opt -# TODO(#3388) Add documentation for Raises. -# pylint: disable=missing-raises-doc def three_qubit_matrix_to_operations( q0: ops.Qid, q1: ops.Qid, q2: ops.Qid, u: np.ndarray, atol: float = 1e-8 ) -> Sequence[ops.Operation]: @@ -46,6 +44,8 @@ def three_qubit_matrix_to_operations( Raises: ValueError: If the u matrix is non-unitary or not of shape (8,8). + ImportError: If the decomposition cannot be done because the SciPy version is less than + 1.5.0 and so does not contain the required `cossin` method. """ if np.shape(u) != (8, 8): raise ValueError(f"Expected unitary matrix with shape (8,8) got {np.shape(u)}") @@ -85,7 +85,6 @@ def three_qubit_matrix_to_operations( return list(cirq.Circuit(vdh_ops + cs_ops + ud_ops).all_operations()) -# pylint: enable=missing-raises-doc def _cs_to_ops(q0: ops.Qid, q1: ops.Qid, q2: ops.Qid, theta: np.ndarray) -> List[ops.Operation]: """Converts theta angles based Cosine Sine matrix to operations. @@ -118,8 +117,6 @@ def _cs_to_ops(q0: ops.Qid, q1: ops.Qid, q2: ops.Qid, theta: np.ndarray) -> List return _optimize_multiplexed_angles_circuit(ops) -# TODO(#3388) Add documentation for Args. -# pylint: disable=missing-param-doc def _two_qubit_multiplexor_to_ops( q0: ops.Qid, q1: ops.Qid, @@ -167,6 +164,8 @@ def _two_qubit_multiplexor_to_ops( u2: two-qubit operation on b,c for a = |1> shift_left: return the extracted diagonal or not diagonal: an incoming diagonal to be merged with + atol: the absolute tolerance for the two-qubit sub-decompositions. + Returns: The circuit implementing the two qubit multiplexor consisting only of known two-qubit and single qubit gates @@ -199,7 +198,6 @@ def _two_qubit_multiplexor_to_ops( return d_w, circuit_u1u2_l + circuit_u1u2_mid + circuit_u1u2_r -# pylint: enable=missing-param-doc def _optimize_multiplexed_angles_circuit(operations: Sequence[ops.Operation]): """Removes two qubit gates that amount to identity. Exploiting the specific multiplexed structure, this methods looks ahead diff --git a/cirq-core/cirq/optimizers/two_qubit_to_fsim.py b/cirq-core/cirq/optimizers/two_qubit_to_fsim.py index 45ac8becbbb..fe8876563a9 100644 --- a/cirq-core/cirq/optimizers/two_qubit_to_fsim.py +++ b/cirq-core/cirq/optimizers/two_qubit_to_fsim.py @@ -18,8 +18,6 @@ import cirq -# TODO(#3388) Add documentation for Raises. -# pylint: disable=missing-raises-doc def decompose_two_qubit_interaction_into_four_fsim_gates( interaction: Union['cirq.Operation', 'cirq.Gate', np.ndarray, Any], *, @@ -52,6 +50,10 @@ def decompose_two_qubit_interaction_into_four_fsim_gates( A list of operations implementing the desired two qubit unitary. The list will include four operations of the given fsim gate, various single qubit operations, and a global phase operation. + + Raises: + ValueError: If the `fsim_gate` has invalid angles (as specified in arg above), + or if the gate acts on more than two qubits. """ if isinstance(fsim_gate, ops.ISwapPowGate): mapped_gate = ops.FSimGate(-fsim_gate.exponent * np.pi / 2, 0) @@ -86,7 +88,6 @@ def decompose_two_qubit_interaction_into_four_fsim_gates( return result -# pylint: enable=missing-raises-doc def _sticky_0_to_1(v: float, *, atol: float) -> Optional[float]: if 0 <= v <= 1: return v @@ -201,12 +202,11 @@ def _decompose_b_gate_into_two_fsims( ) -# TODO(#3388) Add summary line to docstring. -# pylint: disable=docstring-first-line-empty def _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops( qubits: Sequence['cirq.Qid'], kak_interaction_coefficients: Iterable[float] ) -> List['cirq.Operation']: - """ + """Decompose using a minimal construction of two-qubit operations. + References: Minimum construction of two-qubit quantum operations https://arxiv.org/abs/quant-ph/0312193 @@ -238,7 +238,6 @@ def _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops( ] -# pylint: enable=docstring-first-line-empty def _fix_single_qubit_gates_around_kak_interaction( *, desired: 'cirq.KakDecomposition', diff --git a/cirq-core/cirq/study/resolver_test.py b/cirq-core/cirq/study/resolver_test.py index f5fccea9335..877023b1030 100644 --- a/cirq-core/cirq/study/resolver_test.py +++ b/cirq-core/cirq/study/resolver_test.py @@ -155,10 +155,9 @@ def test_param_dict_iter(): assert list(r) == ['a', 'b'] -# TODO(#3388) Add summary line to docstring. -# pylint: disable=docstring-first-line-empty def test_formulas_in_param_dict(): - """ + """Test formulas in a `param_dict`. + Param dicts are allowed to have str or sympy.Symbol as keys and floats or sympy.Symbol as values. This should not be a common use case, but this tests makes sure something reasonable is returned when @@ -180,7 +179,6 @@ def test_formulas_in_param_dict(): assert sympy.Eq(r.value_of('d'), 2 * e) -# pylint: enable=docstring-first-line-empty def test_recursive_evaluation(): a = sympy.Symbol('a') b = sympy.Symbol('b') @@ -271,13 +269,8 @@ def _resolved_value_(self): assert r.value_of(c) == 'Baz' -# TODO(#3388) Add summary line to docstring. -# pylint: disable=docstring-first-line-empty def test_compose(): - """ - Calling cirq.resolve_paramters on a ParamResolver composes that resolver - with the provided resolver. - """ + """Tests that cirq.resolve_parameters on a ParamResolver composes.""" a = sympy.Symbol('a') b = sympy.Symbol('b') c = sympy.Symbol('c') @@ -299,7 +292,6 @@ def test_compose(): assert r13.value_of('a') == b -# pylint: enable=docstring-first-line-empty @pytest.mark.parametrize( 'p1, p2, p3', [ diff --git a/cirq-google/cirq_google/optimizers/convert_to_sycamore_gates.py b/cirq-google/cirq_google/optimizers/convert_to_sycamore_gates.py index 4f7da19c9a5..7b7d47cdbbe 100644 --- a/cirq-google/cirq_google/optimizers/convert_to_sycamore_gates.py +++ b/cirq-google/cirq_google/optimizers/convert_to_sycamore_gates.py @@ -37,18 +37,15 @@ class ConvertToSycamoreGates(cirq.PointOptimizer): First, checks if the given operation is already a native sycamore operation. - Second, checks if the operation has a known unitary. If so, and the gate - is a 1-qubit or 2-qubit gate, then performs circuit synthesis of the - operation. + Second, checks if the operation has a known unitary. If so, and the gate is a 1-qubit or + 2-qubit gate, then performs circuit synthesis of the operation. Third, attempts to `cirq.decompose` to the operation. - Fourth, if ignore_failures is set, gives up and returns the gate unchanged. - Otherwise raises a TypeError. + Fourth, if ignore_failures is set, gives up and returns the gate unchanged. Otherwise raises + a TypeError. """ - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def __init__(self, tabulation: Optional[GateTabulation] = None, ignore_failures=False) -> None: """Inits ConvertToSycamoreGates. @@ -60,14 +57,16 @@ def __init__(self, tabulation: Optional[GateTabulation] = None, ignore_failures= usually cirq_google.SYC) and a maximum infidelity. ignore_failures: If set, gates that fail to convert are forwarded unchanged. If not set, conversion failures raise a TypeError. + + Raises: + ValueError: If the tabulation is not a `GateTabulation`. """ super().__init__() self.ignore_failures = ignore_failures if tabulation is not None and not isinstance(tabulation, GateTabulation): - raise ValueError("provided tabulation must be of type GateTabulation") + raise ValueError("Provided tabulation must be of type GateTabulation.") self.tabulation = tabulation - # pylint: enable=missing-raises-doc def _is_native_sycamore_op(self, op: cirq.Operation) -> bool: """Check if the given operation is native to a Sycamore device. @@ -106,15 +105,8 @@ def _is_native_sycamore_op(self, op: cirq.Operation) -> bool: return False - # TODO(#3388) Add summary line to docstring. - # pylint: disable=docstring-first-line-empty def _convert_one(self, op: cirq.Operation) -> cirq.OP_TREE: - """ - Decomposer intercept: Upon cirq.protocols.decompose catch and - return new OP_Tree - - This should decompose based on number of qubits. - """ + """The main conversion step for the PointOptimizer.""" if len(op.qubits) == 1: return _phased_x_z_ops(cirq.unitary(op, None), op.qubits[0]) elif len(op.qubits) == 2: @@ -123,7 +115,6 @@ def _convert_one(self, op: cirq.Operation) -> cirq.OP_TREE: ) return NotImplemented - # pylint: enable=docstring-first-line-empty def convert(self, op: cirq.Operation) -> List[cirq.Operation]: def on_stuck_raise(bad): return TypeError( @@ -181,26 +172,27 @@ def optimization_at( ) -# TODO(#3388) Add documentation for Raises. -# pylint: disable=missing-raises-doc def known_two_q_operations_to_sycamore_operations( qubit_a: cirq.Qid, qubit_b: cirq.Qid, op: cirq.Operation, tabulation: Optional[GateTabulation] = None, ) -> cirq.OP_TREE: - """Synthesizes a known gate operation to a sycamore operation. + """Synthesizes a known gate operation to a Sycamore operation. - This function dispatches based on gate type + This function dispatches based on gate type. Args: - qubit_a: first qubit of GateOperation - qubit_b: second qubit of GateOperation - op: operation to decompose - tabulation: A tabulation for the Sycamore gate to use for - decomposing gates. + qubit_a: First qubit of GateOperation. + qubit_b: Second qubit of GateOperation. + op: Operation to decompose. + tabulation: A tabulation for the Sycamore gate to use for decomposing gates. Returns: - New operations iterable object + The operations that yield the gate using Sycamores. + + Raises: + ValueError: If the gate is a `PhasedISwapPowGate` with an exponent of 0.25 or 1.0, + or the gate is not recognized. """ gate = op.gate if isinstance(gate, cirq.PhasedISwapPowGate): @@ -242,24 +234,21 @@ def known_two_q_operations_to_sycamore_operations( raise ValueError(f"Unrecognized gate: {op!r}") -# pylint: enable=missing-raises-doc def decompose_phased_iswap_into_syc( phase_exponent: float, a: cirq.Qid, b: cirq.Qid ) -> cirq.OP_TREE: """Decompose PhasedISwap with an exponent of 1. This should only be called if the Gate has an exponent of 1 - otherwise, - decompose_phased_iswap_into_syc_precomputed should be used instead. The - advantage of using this function is that the resulting circuit will be - smaller. + `decompose_phased_iswap_into_syc_precomputed` should be used instead. The advantage of using + this function is that the resulting circuit will be smaller. Args: phase_exponent: The exponent on the Z gates. - a: First qubit id to operate on - b: Second qubit id to operate on - Returns: - a Cirq program implementing the Phased ISWAP gate - + a: First qubit id to operate on. + b: Second qubit id to operate on. + Yields: + A `cirq.OP_TREE` implementing the Phased ISWAP gate. """ yield cirq.Z(a) ** phase_exponent, @@ -274,23 +263,20 @@ def decompose_phased_iswap_into_syc_precomputed( ) -> cirq.OP_TREE: """Decompose PhasedISwap into sycamore gates using precomputed coefficients. - This should only be called if the Gate has a phase_exponent of .25. If the - gate has an exponent of 1, decompose_phased_iswap_into_syc should be used - instead. Converting PhasedISwap gates to Sycamore is not supported if - neither of these constraints are satisfied. + This should only be called if the Gate has a phase_exponent of .25. If the gate has an + exponent of 1, decompose_phased_iswap_into_syc should be used instead. Converting PhasedISwap + gates to Sycamore is not supported if neither of these constraints are satisfied. - This synthesize a PhasedISwap in terms of four sycamore gates. This - compilation converts the gate into a circuit involving two CZ gates, which - themselves are each represented as two Sycamore gates and single-qubit - rotations + This synthesize a PhasedISwap in terms of four sycamore gates. This compilation converts the + gate into a circuit involving two CZ gates, which themselves are each represented as two + Sycamore gates and single-qubit rotations Args: - theta: rotation parameter - a: First qubit id to operate on - b: Second qubit id to operate on - Returns: - a Cirq program implementing the Phased ISWAP gate - + theta: Rotation parameter for the phased ISWAP. + a: First qubit id to operate on. + b: Second qubit id to operate on. + Yields: + A `cirq.OP_TREE` that implements Phased ISWAP gate """ yield cirq.PhasedXPowGate(phase_exponent=0.41175161497166024, exponent=0.5653807577895922).on(a) @@ -322,16 +308,15 @@ def decompose_phased_iswap_into_syc_precomputed( def decompose_arbitrary_into_syc_tabulation( qubit_a: cirq.Qid, qubit_b: cirq.Qid, op: cirq.Operation, tabulation: GateTabulation ) -> cirq.OP_TREE: - """Synthesize an arbitrary 2 qubit operation to a sycamore operation using - the given Tabulation. + """Synthesize an arbitrary 2 qubit operation to a Sycamore operation using the given Tabulation. Args: - qubit_a: first qubit of the operation - qubit_b: second qubit of the operation - op: operation to decompose + qubit_a: First qubit of the operation. + qubit_b: second qubit of the operation. + op: Operation to decompose. tabulation: A tabulation for the Sycamore gate. - Returns: - New operations iterable object + Yields: + A `cirq.OP_TREE` that perform the given operation using Sycamore operations. """ result = tabulation.compile_two_qubit_gate(cirq.unitary(op)) local_gates = result.local_unitaries @@ -345,16 +330,15 @@ def decompose_arbitrary_into_syc_tabulation( def decompose_arbitrary_into_syc_analytic( qubit_a: cirq.Qid, qubit_b: cirq.Qid, op: cirq.Operation ) -> cirq.OP_TREE: - """Synthesize an arbitrary 2 qubit operation to a sycamore operation using - the given Tabulation. - - Args: - qubit_a: first qubit of the operation - qubit_b: second qubit of the operation - op: operation to decompose - tabulation: A tabulation for the Sycamore gate. - Returns: - New operations iterable object + """Synthesize an arbitrary 2 qubit operation to a Sycamore operation using the given Tabulation. + + Args: + qubit_a: First qubit of the operation. + qubit_b: Second qubit of the operation. + op: Operation to decompose. + tabulation: A tabulation for the Sycamore gate. + Yields: + A `cirq.OP_TREE` which produces the given operation using Sycamores. """ new_ops = cirq.two_qubit_matrix_to_operations(qubit_a, qubit_b, op, allow_partial_czs=True) for new_op in new_ops: @@ -370,7 +354,7 @@ def decompose_arbitrary_into_syc_analytic( def decompose_cz_into_syc(a: cirq.Qid, b: cirq.Qid): - """Decompose CZ into sycamore gates using precomputed coefficients""" + """Decompose CZ into sycamore gates using precomputed coefficients.""" yield cirq.PhasedXPowGate(phase_exponent=0.5678998743900456, exponent=0.5863459345743176).on(a) yield cirq.PhasedXPowGate(phase_exponent=0.3549946157441739).on(b) yield google.SYC.on(a, b) @@ -385,7 +369,7 @@ def decompose_cz_into_syc(a: cirq.Qid, b: cirq.Qid): def decompose_iswap_into_syc(a: cirq.Qid, b: cirq.Qid): - """Decompose ISWAP into sycamore gates using precomputed coefficients""" + """Decompose ISWAP into sycamore gates using precomputed coefficients.""" yield cirq.PhasedXPowGate(phase_exponent=-0.27250925776964596, exponent=0.2893438375555899).on( a ) @@ -421,24 +405,22 @@ def decompose_swap_into_syc(a: cirq.Qid, b: cirq.Qid): yield (cirq.Z ** -0.7034535141382525).on(a) -# TODO(#3388) Add summary line to docstring. -# pylint: disable=docstring-first-line-empty def find_local_equivalents(unitary1: np.ndarray, unitary2: np.ndarray): - """ - Given two unitaries with the same interaction coefficients but different - local unitary rotations determine the local unitaries that turns - one type of gate into another. + """Determine the local unitaries that turn one unitary into the other. + + Given two unitaries with the same interaction coefficients but different local unitary + rotations determine the local unitaries that turns one type of gate into another. 1) perform the kak decomp on each unitary and confirm interaction terms are equivalent 2) identify the elements of SU(2) to transform unitary2 into unitary1 Args: - unitary1: unitary that we target - unitary2: unitary that we transform the local gates to the target + unitary1: The unitary that we target. + unitary2: The unitary that we transform the local gates to the target. + Returns: - four 2x2 unitaries. first two are pre-rotations last two are post - rotations. + Four 2x2 unitaries. The first two are pre-rotations last two are post rotations. """ kak_u1 = cirq.kak_decomposition(unitary1) kak_u2 = cirq.kak_decomposition(unitary2) @@ -456,7 +438,6 @@ def find_local_equivalents(unitary1: np.ndarray, unitary2: np.ndarray): return v_0, v_1, u_0, u_1 -# pylint: enable=docstring-first-line-empty def create_corrected_circuit( target_unitary: np.ndarray, program: cirq.Circuit, q0: cirq.Qid, q1: cirq.Qid ) -> cirq.OP_TREE: @@ -490,10 +471,8 @@ def rzz(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.OP_TREE: theta: rotation parameter q0: First qubit id to operate on q1: Second qubit id to operate on - Returns: - a Cirq program implementing the Ising gate - rtype: - cirq.OP_Tree + Yields: + The `cirq.OP_TREE` that produce the Ising gate with Sycamore gates. """ phi = -np.pi / 24 c_phi = np.cos(2 * phi) @@ -515,16 +494,15 @@ def rzz(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.OP_TREE: def cphase(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.OP_TREE: """Implements a cphase using the Ising gate generated from 2 Sycamore gates. - A CPHASE gate has the matrix diag([1, 1, 1, exp(1j * theta)]) and can - be mapped to the Ising gate by prep and post rotations of Z-pi/4. - We drop the global phase shift of theta/4. + A CPHASE gate has the matrix diag([1, 1, 1, exp(1j * theta)]) and can be mapped to the Ising + gate by prep and post rotations of Z - pi/4. We drop the global phase shift of theta / 4. Args: - theta: exp(1j * theta ) - q0: First qubit id to operate on - q1: Second qubit id to operate on - returns: - a cirq program implementing cphase + theta: The phase to apply, exp(1j * theta). + q0: First qubit id to operate on. + q1: Second qubit id to operate on. + Yields: + The gates the perform the cphase using Sycamore gates. """ yield rzz(-theta / 4, q0, q1) yield cirq.rz(theta / 2).on(q0) @@ -534,15 +512,15 @@ def cphase(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.OP_TREE: def swap_rzz(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.OP_TREE: """An implementation of SWAP * EXP(1j theta ZZ) using three sycamore gates. - This builds off of the zztheta method. A sycamore gate following the + This builds off of the zztheta method. A Sycamore gate following the zz-gate is a SWAP EXP(1j (THETA - pi/24) ZZ). Args: - theta: exp(1j * theta ) - q0: First qubit id to operate on - q1: Second qubit id to operate on - Returns: - The circuit that implements ZZ followed by a swap + theta: The phase in the cphase gate, exp(1j * theta ) + q0: First qubit id to operate on. + q1: Second qubit id to operate on. + Yields: + The `cirq.OP_TREE`` that implements ZZ followed by a swap. """ # Set interaction part. diff --git a/cirq-google/cirq_google/serialization/circuit_serializer.py b/cirq-google/cirq_google/serialization/circuit_serializer.py index 7ebdc4fc458..58a3ae44e91 100644 --- a/cirq-google/cirq_google/serialization/circuit_serializer.py +++ b/cirq-google/cirq_google/serialization/circuit_serializer.py @@ -48,8 +48,6 @@ def __init__( """ super().__init__(gate_set_name) - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def serialize( self, program: cirq.AbstractCircuit, @@ -65,6 +63,9 @@ def serialize( results. arg_function_language: The `arg_function_language` field from `Program.Language`. + + Raises: + NotImplementedError: If the program is of a type that is supported. """ if not isinstance(program, cirq.Circuit): raise NotImplementedError(f'Unrecognized program type: {type(program)}') @@ -84,7 +85,6 @@ def serialize( ) return msg - # pylint: enable=missing-raises-doc def _serialize_circuit( self, circuit: cirq.AbstractCircuit, @@ -117,8 +117,6 @@ def _serialize_circuit( raw_constants=raw_constants, ) - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def _serialize_gate_op( self, op: cirq.Operation, @@ -142,6 +140,9 @@ def _serialize_gate_op( Returns: The cirq.google.api.v2.Operation proto. + + Raises: + ValueError: If the operation cannot be serialized. """ gate = op.gate @@ -259,7 +260,6 @@ def _serialize_gate_op( raw_constants[tag.token] = msg.token_constant_index return msg - # TODO(#3388) Add documentation for Raises. def _serialize_circuit_op( self, op: cirq.CircuitOperation, @@ -283,6 +283,9 @@ def _serialize_circuit_op( Returns: The cirq.google.api.v2.CircuitOperation proto. + + Raises: + ValueError: If `constant` or `raw_constants` are not specified. """ circuit = op.circuit if constants is None or raw_constants is None: @@ -310,7 +313,6 @@ def _serialize_circuit_op( raw_constants=raw_constants, ) - # TODO(#3388) Add documentation for Raises. def deserialize( self, proto: v2.program_pb2.Program, device: Optional[cirq.Device] = None ) -> cirq.Circuit: @@ -322,8 +324,13 @@ def deserialize( Otherwise optional. Returns: - The deserialized Circuit, with a device if device was - not None. + The deserialized Circuit, with a device if device was not None. + + Raises: + ValueError: If the given proto has no language or the langauge gate set mismatches + that specified in as the name of this serialized gate set. Also if deserializing + a schedule is attempted. + NotImplementedError: If the program proto does not contain a circuit or schedule. """ if not proto.HasField('language') or not proto.language.gate_set: raise ValueError('Missing gate set specification.') @@ -366,7 +373,6 @@ def deserialize( raise NotImplementedError('Program proto does not contain a circuit.') - # pylint: enable=missing-raises-doc def _deserialize_circuit( self, circuit_proto: v2.program_pb2.Circuit, @@ -399,8 +405,6 @@ def _deserialize_circuit( moments.append(cirq.Moment(moment_ops)) return cirq.Circuit(moments) - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def _deserialize_gate_op( self, operation_proto: v2.program_pb2.Operation, @@ -423,6 +427,9 @@ def _deserialize_gate_op( Returns: The deserialized Operation. + + Raises: + ValueError: If the operation cannot be deserialized. """ if deserialized_constants is not None: qubits = [deserialized_constants[q] for q in operation_proto.qubit_constant_index] @@ -572,7 +579,6 @@ def _deserialize_gate_op( return op - # pylint: enable=missing-raises-doc def _deserialize_circuit_op( self, operation_proto: v2.program_pb2.CircuitOperation, diff --git a/cirq-google/cirq_google/serialization/serializable_gate_set.py b/cirq-google/cirq_google/serialization/serializable_gate_set.py index 2680c76cf26..e4a08a41855 100644 --- a/cirq-google/cirq_google/serialization/serializable_gate_set.py +++ b/cirq-google/cirq_google/serialization/serializable_gate_set.py @@ -33,7 +33,7 @@ class SerializableGateSet(serializer.Serializer): """A class for serializing and deserializing programs and operations. - This class is for cirq_google.api.v2. protos. + This class is for cirq_google.api.v2 protos. """ def __init__( @@ -104,8 +104,6 @@ def is_supported_operation(self, op: cirq.Operation) -> bool: for serializer in self.serializers.get(gate_type, []) ) - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def serialize( self, program: cirq.AbstractCircuit, @@ -124,6 +122,9 @@ def serialize( `Program.Language`. use_constants: Whether to use constants in serialization. This is required to be True for serializing CircuitOperations. + + Raises: + NotImplementedError: If the program type is not supported. """ if msg is None: msg = v2.program_pb2.Program() @@ -169,8 +170,6 @@ def serialize_op( return self.serialize_circuit_op(op, msg, **kwargs) raise ValueError(f'Operation proto is of an unrecognized type: {msg!r}') - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def serialize_gate_op( self, op: cirq.Operation, @@ -274,7 +273,6 @@ def serialize_circuit_op( return proto_msg raise ValueError(f'Cannot serialize CircuitOperation {op!r}') - # TODO(#3388) Add documentation for Raises. def deserialize( self, proto: v2.program_pb2.Program, device: Optional[cirq.Device] = None ) -> cirq.Circuit: @@ -288,6 +286,12 @@ def deserialize( Returns: The deserialized Circuit, with a device if device was not None. + + Raises: + ValueError: If the given proto has no language specified or it mismatched the + name specified for this serializable gate set. In addition if the program + is a schedule and no device was specified. + NotImplementedError: If the program does not contain a circuit or schedule. """ if not proto.HasField('language') or not proto.language.gate_set: raise ValueError('Missing gate set specification.') @@ -345,8 +349,6 @@ def deserialize_op( raise ValueError(f'Operation proto has unknown type: {type(operation_proto)}.') - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def deserialize_gate_op( self, operation_proto: v2.program_pb2.Operation, @@ -369,6 +371,9 @@ def deserialize_gate_op( Returns: The deserialized Operation. + + Raises: + ValueError: If the gate cannot be deserialized. """ if not operation_proto.gate.id: raise ValueError('Operation proto does not have a gate.') @@ -388,7 +393,6 @@ def deserialize_gate_op( deserialized_constants=deserialized_constants, ) - # TODO(#3388) Add documentation for Raises. def deserialize_circuit_op( self, operation_proto: v2.program_pb2.CircuitOperation, @@ -397,8 +401,7 @@ def deserialize_circuit_op( constants: Optional[List[v2.program_pb2.Constant]] = None, deserialized_constants: Optional[List[Any]] = None, ) -> cirq.CircuitOperation: - """Deserialize a CircuitOperation from a - cirq.google.api.v2.CircuitOperation. + """Deserialize a CircuitOperation from a cirq.google.api.v2.CircuitOperation. Args: operation_proto: A dictionary representing a @@ -411,11 +414,15 @@ def deserialize_circuit_op( Returns: The deserialized CircuitOperation. + + Raises: + ValueError: If the deserializer does not support deserializing `CircuitOperation`. """ deserializer = self.deserializers.get('circuit', None) if deserializer is None: raise ValueError( - f'Unsupported serialized CircuitOperation.\n\noperation_proto:\n{operation_proto}' + 'Unsupported deserialized of a CircuitOperation.\n\noperation_proto:\n' + f'{operation_proto}' ) if not isinstance(deserializer, op_deserializer.CircuitOpDeserializer): @@ -431,7 +438,6 @@ def deserialize_circuit_op( deserialized_constants=deserialized_constants, ) - # pylint: enable=missing-raises-doc def _serialize_circuit( self, circuit: cirq.AbstractCircuit, diff --git a/cirq-google/cirq_google/serialization/serializable_gate_set_test.py b/cirq-google/cirq_google/serialization/serializable_gate_set_test.py index 5ebc995504d..e91672ef61d 100644 --- a/cirq-google/cirq_google/serialization/serializable_gate_set_test.py +++ b/cirq-google/cirq_google/serialization/serializable_gate_set_test.py @@ -536,7 +536,7 @@ def test_deserialize_circuit_op_errors(): serializers=[X_SERIALIZER], deserializers=[X_DESERIALIZER], ) - with pytest.raises(ValueError, match='Unsupported serialized CircuitOperation'): + with pytest.raises(ValueError, match='Unsupported deserialized of a CircuitOperation'): NO_CIRCUIT_OP_GATE_SET.deserialize_op( proto, constants=constants, deserialized_constants=deserialized_constants ) diff --git a/cirq-web/cirq_web/bloch_sphere/bloch_sphere.py b/cirq-web/cirq_web/bloch_sphere/bloch_sphere.py index c18ac511965..3d95cb5e01e 100644 --- a/cirq-web/cirq_web/bloch_sphere/bloch_sphere.py +++ b/cirq-web/cirq_web/bloch_sphere/bloch_sphere.py @@ -19,8 +19,6 @@ class BlochSphere(widget.Widget): - # TODO(#3388) Add documentation for Raises. - # pylint: disable=missing-raises-doc def __init__( self, sphere_radius: int = 5, @@ -34,6 +32,10 @@ def __init__( sphere_radius: the radius of the bloch sphere in the three.js diagram. The default value is 5. state_vector: a state vector to pass in to be represented. + + Raises: + ValueError: If the `sphere_radius` is not positive or the `state_vector` is not + supplied. """ super().__init__() if sphere_radius <= 0: @@ -44,7 +46,6 @@ def __init__( raise ValueError('No state vector given in BlochSphere initialization') self.bloch_vector = bloch_vector_from_state_vector(state_vector, 0) - # pylint: enable=missing-raises-doc def get_client_code(self) -> str: return f"""