cirq-core 1.5.0.dev20250409222543__py3-none-any.whl → 1.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cirq-core might be problematic. Click here for more details.

Files changed (732) hide show
  1. cirq/__init__.py +16 -17
  2. cirq/_compat.py +21 -20
  3. cirq/_compat_test.py +14 -34
  4. cirq/_doc.py +4 -2
  5. cirq/_import.py +8 -6
  6. cirq/_import_test.py +4 -2
  7. cirq/_version.py +6 -6
  8. cirq/_version_test.py +2 -2
  9. cirq/circuits/_block_diagram_drawer.py +11 -10
  10. cirq/circuits/_block_diagram_drawer_test.py +8 -6
  11. cirq/circuits/_box_drawing_character_data.py +8 -8
  12. cirq/circuits/_box_drawing_character_data_test.py +3 -1
  13. cirq/circuits/_bucket_priority_queue.py +9 -7
  14. cirq/circuits/_bucket_priority_queue_test.py +22 -20
  15. cirq/circuits/circuit.py +248 -172
  16. cirq/circuits/circuit_operation.py +73 -83
  17. cirq/circuits/circuit_operation_test.py +128 -90
  18. cirq/circuits/circuit_test.py +211 -151
  19. cirq/circuits/frozen_circuit.py +23 -60
  20. cirq/circuits/frozen_circuit_test.py +31 -8
  21. cirq/circuits/insert_strategy.py +7 -5
  22. cirq/circuits/insert_strategy_test.py +4 -2
  23. cirq/circuits/moment.py +88 -40
  24. cirq/circuits/moment_test.py +128 -51
  25. cirq/circuits/optimization_pass.py +5 -5
  26. cirq/circuits/optimization_pass_test.py +10 -10
  27. cirq/circuits/qasm_output.py +11 -11
  28. cirq/circuits/qasm_output_test.py +25 -22
  29. cirq/circuits/text_diagram_drawer.py +23 -38
  30. cirq/circuits/text_diagram_drawer_test.py +19 -17
  31. cirq/conftest.py +4 -3
  32. cirq/contrib/__init__.py +4 -4
  33. cirq/contrib/acquaintance/__init__.py +1 -1
  34. cirq/contrib/acquaintance/bipartite.py +5 -8
  35. cirq/contrib/acquaintance/bipartite_test.py +18 -13
  36. cirq/contrib/acquaintance/devices.py +2 -2
  37. cirq/contrib/acquaintance/devices_test.py +5 -3
  38. cirq/contrib/acquaintance/executor.py +5 -5
  39. cirq/contrib/acquaintance/executor_test.py +13 -9
  40. cirq/contrib/acquaintance/gates.py +18 -28
  41. cirq/contrib/acquaintance/gates_test.py +24 -20
  42. cirq/contrib/acquaintance/inspection_utils.py +8 -4
  43. cirq/contrib/acquaintance/inspection_utils_test.py +4 -2
  44. cirq/contrib/acquaintance/mutation_utils.py +4 -4
  45. cirq/contrib/acquaintance/mutation_utils_test.py +4 -2
  46. cirq/contrib/acquaintance/optimizers.py +4 -4
  47. cirq/contrib/acquaintance/optimizers_test.py +4 -1
  48. cirq/contrib/acquaintance/permutation.py +15 -27
  49. cirq/contrib/acquaintance/permutation_test.py +26 -17
  50. cirq/contrib/acquaintance/shift.py +4 -4
  51. cirq/contrib/acquaintance/shift_swap_network.py +4 -4
  52. cirq/contrib/acquaintance/shift_swap_network_test.py +9 -6
  53. cirq/contrib/acquaintance/shift_test.py +8 -6
  54. cirq/contrib/acquaintance/strategies/cubic.py +2 -2
  55. cirq/contrib/acquaintance/strategies/cubic_test.py +4 -2
  56. cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
  57. cirq/contrib/acquaintance/strategies/quartic_paired_test.py +10 -6
  58. cirq/contrib/acquaintance/testing.py +2 -0
  59. cirq/contrib/acquaintance/topological_sort.py +2 -2
  60. cirq/contrib/acquaintance/topological_sort_test.py +3 -1
  61. cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
  62. cirq/contrib/bayesian_network/bayesian_network_gate_test.py +14 -9
  63. cirq/contrib/circuitdag/circuit_dag.py +4 -4
  64. cirq/contrib/circuitdag/circuit_dag_test.py +17 -15
  65. cirq/contrib/custom_simulators/custom_state_simulator.py +5 -5
  66. cirq/contrib/custom_simulators/custom_state_simulator_test.py +22 -17
  67. cirq/contrib/graph_device/graph_device.py +12 -11
  68. cirq/contrib/graph_device/graph_device_test.py +18 -14
  69. cirq/contrib/graph_device/hypergraph.py +16 -14
  70. cirq/contrib/graph_device/hypergraph_test.py +13 -11
  71. cirq/contrib/graph_device/uniform_graph_device.py +6 -4
  72. cirq/contrib/graph_device/uniform_graph_device_test.py +11 -3
  73. cirq/contrib/hacks/disable_validation.py +6 -1
  74. cirq/contrib/hacks/disable_validation_test.py +3 -1
  75. cirq/contrib/json.py +31 -5
  76. cirq/contrib/json_test.py +6 -3
  77. cirq/contrib/json_test_data/DampedReadoutNoiseModel.json +12 -0
  78. cirq/contrib/json_test_data/DampedReadoutNoiseModel.repr +4 -0
  79. cirq/contrib/json_test_data/DepolarizingNoiseModel.json +12 -0
  80. cirq/contrib/json_test_data/DepolarizingNoiseModel.repr +4 -0
  81. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.json +6 -0
  82. cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.repr +1 -0
  83. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.json +5 -0
  84. cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.repr +1 -0
  85. cirq/contrib/json_test_data/ReadoutNoiseModel.json +12 -0
  86. cirq/contrib/json_test_data/ReadoutNoiseModel.repr +4 -0
  87. cirq/contrib/json_test_data/__init__.py +17 -0
  88. cirq/contrib/json_test_data/spec.py +32 -0
  89. cirq/contrib/noise_models/noise_models.py +119 -5
  90. cirq/contrib/noise_models/noise_models_test.py +37 -9
  91. cirq/contrib/paulistring/clifford_optimize.py +6 -4
  92. cirq/contrib/paulistring/clifford_optimize_test.py +6 -5
  93. cirq/contrib/paulistring/clifford_target_gateset.py +10 -10
  94. cirq/contrib/paulistring/clifford_target_gateset_test.py +13 -11
  95. cirq/contrib/paulistring/optimize.py +2 -0
  96. cirq/contrib/paulistring/optimize_test.py +4 -3
  97. cirq/contrib/paulistring/pauli_string_dag.py +2 -0
  98. cirq/contrib/paulistring/pauli_string_dag_test.py +3 -1
  99. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +255 -120
  100. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +398 -19
  101. cirq/contrib/paulistring/pauli_string_optimize.py +7 -1
  102. cirq/contrib/paulistring/pauli_string_optimize_test.py +5 -3
  103. cirq/contrib/paulistring/recombine.py +6 -4
  104. cirq/contrib/paulistring/recombine_test.py +3 -1
  105. cirq/contrib/paulistring/separate.py +9 -6
  106. cirq/contrib/paulistring/separate_test.py +3 -1
  107. cirq/contrib/qasm_import/_lexer.py +3 -2
  108. cirq/contrib/qasm_import/_lexer_test.py +49 -13
  109. cirq/contrib/qasm_import/_parser.py +547 -83
  110. cirq/contrib/qasm_import/_parser_test.py +988 -97
  111. cirq/contrib/qasm_import/exception.py +2 -0
  112. cirq/contrib/qasm_import/qasm.py +8 -2
  113. cirq/contrib/qasm_import/qasm_test.py +7 -4
  114. cirq/contrib/qcircuit/qcircuit_diagram_info.py +5 -5
  115. cirq/contrib/qcircuit/qcircuit_diagram_info_test.py +4 -1
  116. cirq/contrib/qcircuit/qcircuit_pdf.py +7 -3
  117. cirq/contrib/qcircuit/qcircuit_pdf_test.py +3 -1
  118. cirq/contrib/qcircuit/qcircuit_test.py +10 -8
  119. cirq/contrib/quantum_volume/quantum_volume.py +31 -27
  120. cirq/contrib/quantum_volume/quantum_volume_test.py +19 -16
  121. cirq/contrib/quimb/density_matrix.py +15 -14
  122. cirq/contrib/quimb/density_matrix_test.py +10 -7
  123. cirq/contrib/quimb/grid_circuits.py +5 -2
  124. cirq/contrib/quimb/grid_circuits_test.py +3 -0
  125. cirq/contrib/quimb/mps_simulator.py +20 -20
  126. cirq/contrib/quimb/mps_simulator_test.py +3 -0
  127. cirq/contrib/quimb/state_vector.py +12 -11
  128. cirq/contrib/quimb/state_vector_test.py +3 -0
  129. cirq/contrib/quirk/export_to_quirk.py +5 -3
  130. cirq/contrib/quirk/export_to_quirk_test.py +18 -16
  131. cirq/contrib/quirk/linearize_circuit.py +2 -0
  132. cirq/contrib/quirk/quirk_gate.py +18 -17
  133. cirq/contrib/routing/device.py +5 -3
  134. cirq/contrib/routing/device_test.py +2 -0
  135. cirq/contrib/routing/greedy.py +10 -21
  136. cirq/contrib/routing/greedy_test.py +4 -2
  137. cirq/contrib/routing/initialization.py +2 -2
  138. cirq/contrib/routing/initialization_test.py +5 -3
  139. cirq/contrib/routing/router.py +9 -5
  140. cirq/contrib/routing/router_test.py +2 -0
  141. cirq/contrib/routing/swap_network.py +3 -3
  142. cirq/contrib/routing/swap_network_test.py +3 -1
  143. cirq/contrib/routing/utils.py +2 -2
  144. cirq/contrib/routing/utils_test.py +3 -0
  145. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +15 -9
  146. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +3 -0
  147. cirq/contrib/svg/svg.py +3 -3
  148. cirq/contrib/svg/svg_test.py +8 -5
  149. cirq/devices/device.py +4 -4
  150. cirq/devices/device_test.py +7 -4
  151. cirq/devices/grid_device_metadata.py +10 -10
  152. cirq/devices/grid_device_metadata_test.py +3 -0
  153. cirq/devices/grid_qubit.py +29 -21
  154. cirq/devices/grid_qubit_test.py +3 -0
  155. cirq/devices/insertion_noise_model.py +7 -7
  156. cirq/devices/insertion_noise_model_test.py +7 -5
  157. cirq/devices/line_qubit.py +13 -13
  158. cirq/devices/line_qubit_test.py +2 -0
  159. cirq/devices/named_topologies.py +18 -29
  160. cirq/devices/named_topologies_test.py +13 -10
  161. cirq/devices/noise_model.py +3 -3
  162. cirq/devices/noise_model_test.py +19 -15
  163. cirq/devices/noise_properties.py +15 -6
  164. cirq/devices/noise_properties_test.py +34 -3
  165. cirq/devices/noise_utils.py +11 -9
  166. cirq/devices/noise_utils_test.py +2 -0
  167. cirq/devices/superconducting_qubits_noise_properties.py +23 -22
  168. cirq/devices/superconducting_qubits_noise_properties_test.py +6 -6
  169. cirq/devices/thermal_noise_model.py +107 -37
  170. cirq/devices/thermal_noise_model_test.py +21 -0
  171. cirq/devices/unconstrained_device.py +5 -3
  172. cirq/devices/unconstrained_device_test.py +2 -0
  173. cirq/experiments/__init__.py +4 -2
  174. cirq/experiments/benchmarking/__init__.py +17 -0
  175. cirq/experiments/benchmarking/parallel_xeb.py +677 -0
  176. cirq/experiments/benchmarking/parallel_xeb_test.py +447 -0
  177. cirq/experiments/fidelity_estimation.py +14 -8
  178. cirq/experiments/fidelity_estimation_test.py +3 -0
  179. cirq/experiments/n_qubit_tomography.py +17 -16
  180. cirq/experiments/n_qubit_tomography_test.py +8 -5
  181. cirq/experiments/purity_estimation.py +2 -0
  182. cirq/experiments/purity_estimation_test.py +2 -0
  183. cirq/experiments/qubit_characterizations.py +207 -103
  184. cirq/experiments/qubit_characterizations_test.py +40 -12
  185. cirq/experiments/random_quantum_circuit_generation.py +56 -70
  186. cirq/experiments/random_quantum_circuit_generation_test.py +11 -8
  187. cirq/experiments/readout_confusion_matrix.py +24 -22
  188. cirq/experiments/readout_confusion_matrix_test.py +2 -0
  189. cirq/experiments/single_qubit_readout_calibration.py +30 -15
  190. cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
  191. cirq/experiments/t1_decay_experiment.py +9 -7
  192. cirq/experiments/t1_decay_experiment_test.py +13 -11
  193. cirq/experiments/t2_decay_experiment.py +16 -13
  194. cirq/experiments/t2_decay_experiment_test.py +2 -0
  195. cirq/experiments/two_qubit_xeb.py +64 -57
  196. cirq/experiments/two_qubit_xeb_test.py +10 -6
  197. cirq/experiments/xeb_fitting.py +39 -35
  198. cirq/experiments/xeb_sampling.py +37 -44
  199. cirq/experiments/xeb_sampling_test.py +3 -0
  200. cirq/experiments/xeb_simulation.py +14 -10
  201. cirq/experiments/xeb_simulation_test.py +5 -5
  202. cirq/experiments/z_phase_calibration.py +32 -29
  203. cirq/experiments/z_phase_calibration_test.py +3 -4
  204. cirq/interop/quirk/cells/__init__.py +1 -1
  205. cirq/interop/quirk/cells/all_cells.py +7 -2
  206. cirq/interop/quirk/cells/arithmetic_cells.py +29 -41
  207. cirq/interop/quirk/cells/arithmetic_cells_test.py +17 -14
  208. cirq/interop/quirk/cells/cell.py +19 -28
  209. cirq/interop/quirk/cells/cell_test.py +3 -0
  210. cirq/interop/quirk/cells/composite_cell.py +13 -28
  211. cirq/interop/quirk/cells/composite_cell_test.py +2 -0
  212. cirq/interop/quirk/cells/control_cells.py +15 -15
  213. cirq/interop/quirk/cells/control_cells_test.py +7 -5
  214. cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
  215. cirq/interop/quirk/cells/frequency_space_cells_test.py +3 -1
  216. cirq/interop/quirk/cells/ignored_cells.py +3 -0
  217. cirq/interop/quirk/cells/ignored_cells_test.py +3 -1
  218. cirq/interop/quirk/cells/input_cells.py +7 -5
  219. cirq/interop/quirk/cells/input_cells_test.py +7 -5
  220. cirq/interop/quirk/cells/input_rotation_cells.py +15 -13
  221. cirq/interop/quirk/cells/input_rotation_cells_test.py +9 -7
  222. cirq/interop/quirk/cells/measurement_cells.py +5 -2
  223. cirq/interop/quirk/cells/measurement_cells_test.py +3 -1
  224. cirq/interop/quirk/cells/parse.py +22 -23
  225. cirq/interop/quirk/cells/parse_test.py +12 -10
  226. cirq/interop/quirk/cells/qubit_permutation_cells.py +5 -3
  227. cirq/interop/quirk/cells/qubit_permutation_cells_test.py +9 -7
  228. cirq/interop/quirk/cells/scalar_cells.py +4 -1
  229. cirq/interop/quirk/cells/scalar_cells_test.py +3 -1
  230. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
  231. cirq/interop/quirk/cells/single_qubit_rotation_cells_test.py +5 -3
  232. cirq/interop/quirk/cells/swap_cell.py +8 -6
  233. cirq/interop/quirk/cells/swap_cell_test.py +6 -4
  234. cirq/interop/quirk/cells/testing.py +6 -6
  235. cirq/interop/quirk/cells/testing_test.py +8 -6
  236. cirq/interop/quirk/cells/unsupported_cells.py +3 -0
  237. cirq/interop/quirk/cells/unsupported_cells_test.py +4 -2
  238. cirq/interop/quirk/url_to_circuit.py +23 -36
  239. cirq/interop/quirk/url_to_circuit_test.py +4 -1
  240. cirq/json_resolver_cache.py +14 -12
  241. cirq/linalg/__init__.py +4 -6
  242. cirq/linalg/combinators.py +7 -5
  243. cirq/linalg/combinators_test.py +10 -7
  244. cirq/linalg/decompositions.py +24 -35
  245. cirq/linalg/decompositions_test.py +3 -1
  246. cirq/linalg/diagonalize.py +6 -4
  247. cirq/linalg/diagonalize_test.py +15 -14
  248. cirq/linalg/operator_spaces.py +14 -14
  249. cirq/linalg/operator_spaces_test.py +13 -11
  250. cirq/linalg/predicates.py +18 -9
  251. cirq/linalg/predicates_test.py +5 -0
  252. cirq/linalg/tolerance.py +6 -3
  253. cirq/linalg/tolerance_test.py +6 -4
  254. cirq/linalg/transformations.py +23 -20
  255. cirq/linalg/transformations_test.py +73 -43
  256. cirq/neutral_atoms/convert_to_neutral_atom_gates.py +9 -3
  257. cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +3 -1
  258. cirq/neutral_atoms/neutral_atom_devices.py +2 -0
  259. cirq/ops/__init__.py +2 -0
  260. cirq/ops/arithmetic_operation.py +21 -21
  261. cirq/ops/arithmetic_operation_test.py +7 -8
  262. cirq/ops/boolean_hamiltonian.py +23 -22
  263. cirq/ops/boolean_hamiltonian_test.py +12 -9
  264. cirq/ops/classically_controlled_operation.py +31 -36
  265. cirq/ops/classically_controlled_operation_test.py +121 -117
  266. cirq/ops/clifford_gate.py +98 -81
  267. cirq/ops/clifford_gate_test.py +72 -57
  268. cirq/ops/common_channels.py +44 -44
  269. cirq/ops/common_channels_test.py +83 -81
  270. cirq/ops/common_gate_families.py +9 -7
  271. cirq/ops/common_gate_families_test.py +11 -7
  272. cirq/ops/common_gates.py +164 -183
  273. cirq/ops/common_gates_test.py +135 -95
  274. cirq/ops/control_values.py +23 -26
  275. cirq/ops/control_values_test.py +22 -20
  276. cirq/ops/controlled_gate.py +64 -112
  277. cirq/ops/controlled_gate_test.py +130 -35
  278. cirq/ops/controlled_operation.py +24 -35
  279. cirq/ops/controlled_operation_test.py +8 -6
  280. cirq/ops/dense_pauli_string.py +38 -49
  281. cirq/ops/dense_pauli_string_test.py +4 -2
  282. cirq/ops/diagonal_gate.py +18 -31
  283. cirq/ops/diagonal_gate_test.py +13 -13
  284. cirq/ops/eigen_gate.py +29 -29
  285. cirq/ops/eigen_gate_test.py +45 -28
  286. cirq/ops/fourier_transform.py +14 -20
  287. cirq/ops/fourier_transform_test.py +15 -12
  288. cirq/ops/fsim_gate.py +43 -42
  289. cirq/ops/fsim_gate_test.py +29 -29
  290. cirq/ops/gate_features.py +2 -0
  291. cirq/ops/gate_features_test.py +5 -3
  292. cirq/ops/gate_operation.py +43 -65
  293. cirq/ops/gate_operation_test.py +46 -42
  294. cirq/ops/gateset.py +28 -40
  295. cirq/ops/gateset_test.py +4 -2
  296. cirq/ops/global_phase_op.py +45 -20
  297. cirq/ops/global_phase_op_test.py +44 -20
  298. cirq/ops/greedy_qubit_manager.py +10 -8
  299. cirq/ops/greedy_qubit_manager_test.py +5 -3
  300. cirq/ops/identity.py +14 -12
  301. cirq/ops/identity_test.py +24 -20
  302. cirq/ops/kraus_channel.py +11 -8
  303. cirq/ops/kraus_channel_test.py +14 -11
  304. cirq/ops/linear_combinations.py +65 -77
  305. cirq/ops/linear_combinations_test.py +14 -9
  306. cirq/ops/matrix_gates.py +21 -18
  307. cirq/ops/matrix_gates_test.py +16 -0
  308. cirq/ops/measure_util.py +15 -20
  309. cirq/ops/measure_util_test.py +2 -0
  310. cirq/ops/measurement_gate.py +26 -37
  311. cirq/ops/measurement_gate_test.py +2 -0
  312. cirq/ops/mixed_unitary_channel.py +12 -9
  313. cirq/ops/mixed_unitary_channel_test.py +14 -11
  314. cirq/ops/named_qubit.py +16 -13
  315. cirq/ops/named_qubit_test.py +15 -13
  316. cirq/ops/op_tree.py +9 -7
  317. cirq/ops/op_tree_test.py +22 -19
  318. cirq/ops/parallel_gate.py +15 -17
  319. cirq/ops/parallel_gate_test.py +18 -16
  320. cirq/ops/parity_gates.py +23 -25
  321. cirq/ops/parity_gates_test.py +36 -32
  322. cirq/ops/pauli_gates.py +22 -21
  323. cirq/ops/pauli_gates_test.py +29 -20
  324. cirq/ops/pauli_interaction_gate.py +15 -19
  325. cirq/ops/pauli_interaction_gate_test.py +10 -8
  326. cirq/ops/pauli_measurement_gate.py +23 -35
  327. cirq/ops/pauli_measurement_gate_test.py +2 -0
  328. cirq/ops/pauli_string.py +92 -120
  329. cirq/ops/pauli_string_phasor.py +52 -45
  330. cirq/ops/pauli_string_phasor_test.py +4 -5
  331. cirq/ops/pauli_string_raw_types.py +9 -7
  332. cirq/ops/pauli_string_raw_types_test.py +2 -0
  333. cirq/ops/pauli_string_test.py +31 -154
  334. cirq/ops/pauli_sum_exponential.py +12 -12
  335. cirq/ops/pauli_sum_exponential_test.py +12 -10
  336. cirq/ops/permutation_gate.py +8 -6
  337. cirq/ops/permutation_gate_test.py +10 -8
  338. cirq/ops/phased_iswap_gate.py +16 -16
  339. cirq/ops/phased_iswap_gate_test.py +17 -15
  340. cirq/ops/phased_x_gate.py +16 -17
  341. cirq/ops/phased_x_gate_test.py +18 -16
  342. cirq/ops/phased_x_z_gate.py +24 -22
  343. cirq/ops/phased_x_z_gate_test.py +17 -11
  344. cirq/ops/projector.py +16 -11
  345. cirq/ops/projector_test.py +19 -16
  346. cirq/ops/qid_util.py +7 -5
  347. cirq/ops/qid_util_test.py +2 -0
  348. cirq/ops/qubit_manager.py +11 -9
  349. cirq/ops/qubit_manager_test.py +6 -4
  350. cirq/ops/qubit_order.py +11 -14
  351. cirq/ops/qubit_order_or_list.py +4 -2
  352. cirq/ops/qubit_order_test.py +12 -10
  353. cirq/ops/random_gate_channel.py +12 -10
  354. cirq/ops/random_gate_channel_test.py +14 -11
  355. cirq/ops/raw_types.py +109 -129
  356. cirq/ops/raw_types_test.py +63 -57
  357. cirq/ops/state_preparation_channel.py +7 -7
  358. cirq/ops/state_preparation_channel_test.py +11 -9
  359. cirq/ops/swap_gates.py +13 -15
  360. cirq/ops/swap_gates_test.py +19 -17
  361. cirq/ops/tags.py +5 -3
  362. cirq/ops/tags_test.py +4 -2
  363. cirq/ops/three_qubit_gates.py +43 -76
  364. cirq/ops/three_qubit_gates_test.py +19 -17
  365. cirq/ops/two_qubit_diagonal_gate.py +13 -13
  366. cirq/ops/two_qubit_diagonal_gate_test.py +10 -8
  367. cirq/ops/uniform_superposition_gate.py +5 -3
  368. cirq/ops/uniform_superposition_gate_test.py +5 -3
  369. cirq/ops/wait_gate.py +17 -14
  370. cirq/ops/wait_gate_test.py +9 -6
  371. cirq/protocols/__init__.py +0 -3
  372. cirq/protocols/act_on_protocol.py +8 -6
  373. cirq/protocols/act_on_protocol_test.py +15 -12
  374. cirq/protocols/apply_channel_protocol.py +10 -14
  375. cirq/protocols/apply_channel_protocol_test.py +2 -0
  376. cirq/protocols/apply_mixture_protocol.py +13 -42
  377. cirq/protocols/apply_mixture_protocol_test.py +7 -5
  378. cirq/protocols/apply_unitary_protocol.py +39 -34
  379. cirq/protocols/apply_unitary_protocol_test.py +4 -1
  380. cirq/protocols/approximate_equality_protocol.py +2 -0
  381. cirq/protocols/approximate_equality_protocol_test.py +2 -0
  382. cirq/protocols/circuit_diagram_info_protocol.py +58 -42
  383. cirq/protocols/circuit_diagram_info_protocol_test.py +70 -12
  384. cirq/protocols/commutes_protocol.py +8 -7
  385. cirq/protocols/commutes_protocol_test.py +2 -0
  386. cirq/protocols/control_key_protocol.py +6 -4
  387. cirq/protocols/control_key_protocol_test.py +3 -1
  388. cirq/protocols/decompose_protocol.py +49 -48
  389. cirq/protocols/decompose_protocol_test.py +27 -16
  390. cirq/protocols/equal_up_to_global_phase_protocol.py +2 -0
  391. cirq/protocols/equal_up_to_global_phase_protocol_test.py +9 -6
  392. cirq/protocols/has_stabilizer_effect_protocol.py +7 -5
  393. cirq/protocols/has_stabilizer_effect_protocol_test.py +7 -5
  394. cirq/protocols/has_unitary_protocol.py +10 -6
  395. cirq/protocols/has_unitary_protocol_test.py +13 -8
  396. cirq/protocols/hash_from_pickle_test.py +2 -11
  397. cirq/protocols/inverse_protocol.py +13 -16
  398. cirq/protocols/inverse_protocol_test.py +5 -3
  399. cirq/protocols/json_serialization.py +35 -54
  400. cirq/protocols/json_serialization_test.py +14 -21
  401. cirq/protocols/json_test_data/CXSWAP.json +46 -0
  402. cirq/protocols/json_test_data/CXSWAP.repr +13 -0
  403. cirq/protocols/json_test_data/CZSWAP.json +46 -0
  404. cirq/protocols/json_test_data/CZSWAP.repr +13 -0
  405. cirq/protocols/json_test_data/CircuitOperation.json +6 -3
  406. cirq/protocols/json_test_data/CircuitOperation.repr_inward +4 -2
  407. cirq/protocols/json_test_data/Moment.json +24 -1
  408. cirq/protocols/json_test_data/Moment.repr +6 -1
  409. cirq/protocols/json_test_data/ThermalNoiseModel.json +32 -0
  410. cirq/protocols/json_test_data/ThermalNoiseModel.repr +1 -0
  411. cirq/protocols/json_test_data/spec.py +6 -2
  412. cirq/protocols/kraus_protocol.py +47 -7
  413. cirq/protocols/kraus_protocol_test.py +86 -12
  414. cirq/protocols/measurement_key_protocol.py +15 -16
  415. cirq/protocols/measurement_key_protocol_test.py +13 -11
  416. cirq/protocols/mixture_protocol.py +7 -5
  417. cirq/protocols/mixture_protocol_test.py +4 -2
  418. cirq/protocols/mul_protocol.py +2 -3
  419. cirq/protocols/mul_protocol_test.py +2 -0
  420. cirq/protocols/pauli_expansion_protocol.py +6 -3
  421. cirq/protocols/pauli_expansion_protocol_test.py +5 -3
  422. cirq/protocols/phase_protocol.py +2 -0
  423. cirq/protocols/phase_protocol_test.py +3 -1
  424. cirq/protocols/pow_protocol.py +11 -16
  425. cirq/protocols/pow_protocol_test.py +2 -0
  426. cirq/protocols/qasm.py +14 -20
  427. cirq/protocols/qasm_test.py +6 -3
  428. cirq/protocols/qid_shape_protocol.py +8 -8
  429. cirq/protocols/qid_shape_protocol_test.py +3 -1
  430. cirq/protocols/resolve_parameters.py +5 -3
  431. cirq/protocols/resolve_parameters_test.py +8 -7
  432. cirq/protocols/trace_distance_bound.py +6 -4
  433. cirq/protocols/trace_distance_bound_test.py +3 -1
  434. cirq/protocols/unitary_protocol.py +17 -7
  435. cirq/protocols/unitary_protocol_test.py +12 -2
  436. cirq/qis/channels.py +6 -2
  437. cirq/qis/channels_test.py +20 -16
  438. cirq/qis/clifford_tableau.py +21 -19
  439. cirq/qis/clifford_tableau_test.py +2 -2
  440. cirq/qis/entropy.py +14 -3
  441. cirq/qis/entropy_test.py +3 -1
  442. cirq/qis/measures.py +13 -13
  443. cirq/qis/measures_test.py +20 -14
  444. cirq/qis/noise_utils.py +2 -0
  445. cirq/qis/noise_utils_test.py +9 -7
  446. cirq/qis/quantum_state_representation.py +7 -8
  447. cirq/qis/states.py +58 -56
  448. cirq/qis/states_test.py +2 -0
  449. cirq/sim/classical_simulator.py +23 -22
  450. cirq/sim/classical_simulator_test.py +2 -0
  451. cirq/sim/clifford/clifford_simulator.py +23 -21
  452. cirq/sim/clifford/clifford_simulator_test.py +7 -4
  453. cirq/sim/clifford/clifford_tableau_simulation_state.py +10 -7
  454. cirq/sim/clifford/clifford_tableau_simulation_state_test.py +5 -5
  455. cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +8 -6
  456. cirq/sim/clifford/stabilizer_ch_form_simulation_state_test.py +8 -6
  457. cirq/sim/clifford/stabilizer_sampler.py +9 -7
  458. cirq/sim/clifford/stabilizer_sampler_test.py +4 -2
  459. cirq/sim/clifford/stabilizer_simulation_state.py +14 -13
  460. cirq/sim/clifford/stabilizer_simulation_state_test.py +6 -4
  461. cirq/sim/clifford/stabilizer_state_ch_form.py +13 -11
  462. cirq/sim/clifford/stabilizer_state_ch_form_test.py +4 -2
  463. cirq/sim/density_matrix_simulation_state.py +26 -27
  464. cirq/sim/density_matrix_simulation_state_test.py +10 -8
  465. cirq/sim/density_matrix_simulator.py +30 -28
  466. cirq/sim/density_matrix_simulator_test.py +48 -48
  467. cirq/sim/density_matrix_utils.py +13 -11
  468. cirq/sim/density_matrix_utils_test.py +38 -36
  469. cirq/sim/mux.py +33 -31
  470. cirq/sim/mux_test.py +3 -0
  471. cirq/sim/simulation_product_state.py +15 -15
  472. cirq/sim/simulation_product_state_test.py +29 -26
  473. cirq/sim/simulation_state.py +29 -38
  474. cirq/sim/simulation_state_base.py +21 -32
  475. cirq/sim/simulation_state_test.py +15 -13
  476. cirq/sim/simulation_utils.py +5 -2
  477. cirq/sim/simulation_utils_test.py +5 -2
  478. cirq/sim/simulator.py +90 -106
  479. cirq/sim/simulator_base.py +33 -45
  480. cirq/sim/simulator_base_test.py +20 -15
  481. cirq/sim/simulator_test.py +23 -14
  482. cirq/sim/sparse_simulator.py +19 -17
  483. cirq/sim/sparse_simulator_test.py +41 -40
  484. cirq/sim/state_vector.py +15 -12
  485. cirq/sim/state_vector_simulation_state.py +31 -31
  486. cirq/sim/state_vector_simulation_state_test.py +16 -14
  487. cirq/sim/state_vector_simulator.py +17 -14
  488. cirq/sim/state_vector_simulator_test.py +2 -0
  489. cirq/sim/state_vector_test.py +6 -3
  490. cirq/study/flatten_expressions.py +16 -15
  491. cirq/study/flatten_expressions_test.py +13 -11
  492. cirq/study/resolver.py +18 -17
  493. cirq/study/resolver_test.py +22 -20
  494. cirq/study/result.py +17 -27
  495. cirq/study/result_test.py +2 -0
  496. cirq/study/sweepable.py +12 -10
  497. cirq/study/sweepable_test.py +3 -0
  498. cirq/study/sweeps.py +42 -61
  499. cirq/study/sweeps_test.py +33 -0
  500. cirq/testing/__init__.py +7 -11
  501. cirq/testing/_compat_test_data/module_a/__init__.py +1 -0
  502. cirq/testing/_compat_test_data/module_a/module_b/__init__.py +1 -0
  503. cirq/testing/_compat_test_data/module_a/sub/__init__.py +1 -0
  504. cirq/testing/circuit_compare.py +8 -17
  505. cirq/testing/circuit_compare_test.py +2 -0
  506. cirq/testing/consistent_act_on.py +13 -11
  507. cirq/testing/consistent_act_on_test.py +5 -3
  508. cirq/testing/consistent_channels.py +2 -0
  509. cirq/testing/consistent_channels_test.py +10 -8
  510. cirq/testing/consistent_controlled_gate_op.py +5 -5
  511. cirq/testing/consistent_controlled_gate_op_test.py +18 -18
  512. cirq/testing/consistent_decomposition.py +2 -2
  513. cirq/testing/consistent_decomposition_test.py +4 -2
  514. cirq/testing/consistent_pauli_expansion.py +2 -0
  515. cirq/testing/consistent_pauli_expansion_test.py +3 -1
  516. cirq/testing/consistent_phase_by.py +2 -0
  517. cirq/testing/consistent_phase_by_test.py +3 -1
  518. cirq/testing/consistent_protocols.py +14 -20
  519. cirq/testing/consistent_protocols_test.py +13 -11
  520. cirq/testing/consistent_qasm.py +6 -4
  521. cirq/testing/consistent_qasm_test.py +7 -7
  522. cirq/testing/consistent_resolve_parameters.py +2 -0
  523. cirq/testing/consistent_specified_has_unitary.py +2 -2
  524. cirq/testing/consistent_specified_has_unitary_test.py +6 -4
  525. cirq/testing/consistent_unitary.py +1 -0
  526. cirq/testing/consistent_unitary_test.py +4 -2
  527. cirq/testing/deprecation.py +5 -2
  528. cirq/testing/deprecation_test.py +5 -2
  529. cirq/testing/devices.py +7 -4
  530. cirq/testing/devices_test.py +7 -4
  531. cirq/testing/equals_tester.py +4 -2
  532. cirq/testing/equals_tester_test.py +21 -17
  533. cirq/testing/equivalent_basis_map.py +6 -4
  534. cirq/testing/equivalent_basis_map_test.py +6 -4
  535. cirq/testing/equivalent_repr_eval.py +6 -4
  536. cirq/testing/equivalent_repr_eval_test.py +5 -3
  537. cirq/testing/gate_features.py +2 -0
  538. cirq/testing/gate_features_test.py +7 -5
  539. cirq/testing/json.py +19 -15
  540. cirq/testing/json_test.py +5 -3
  541. cirq/testing/lin_alg_utils.py +10 -11
  542. cirq/testing/lin_alg_utils_test.py +14 -12
  543. cirq/testing/logs.py +7 -6
  544. cirq/testing/logs_test.py +9 -7
  545. cirq/testing/no_identifier_qubit.py +4 -2
  546. cirq/testing/no_identifier_qubit_test.py +5 -3
  547. cirq/testing/op_tree.py +2 -0
  548. cirq/testing/op_tree_test.py +4 -1
  549. cirq/testing/order_tester.py +2 -0
  550. cirq/testing/order_tester_test.py +8 -6
  551. cirq/testing/pytest_utils.py +2 -0
  552. cirq/testing/pytest_utils_test.py +4 -2
  553. cirq/testing/random_circuit.py +21 -20
  554. cirq/testing/random_circuit_test.py +12 -9
  555. cirq/testing/repr_pretty_tester.py +1 -0
  556. cirq/testing/repr_pretty_tester_test.py +5 -3
  557. cirq/testing/routing_devices.py +4 -1
  558. cirq/testing/routing_devices_test.py +9 -6
  559. cirq/testing/sample_circuits.py +4 -1
  560. cirq/testing/sample_circuits_test.py +3 -1
  561. cirq/testing/sample_gates.py +3 -0
  562. cirq/testing/sample_gates_test.py +5 -2
  563. cirq/transformers/__init__.py +11 -4
  564. cirq/transformers/align.py +9 -7
  565. cirq/transformers/align_test.py +2 -0
  566. cirq/transformers/analytical_decompositions/__init__.py +3 -6
  567. cirq/transformers/analytical_decompositions/clifford_decomposition.py +18 -16
  568. cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +2 -0
  569. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +19 -16
  570. cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
  571. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +11 -9
  572. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +5 -3
  573. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +5 -3
  574. cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +5 -3
  575. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +141 -44
  576. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +35 -1
  577. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +8 -7
  578. cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +2 -0
  579. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +7 -4
  580. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +3 -0
  581. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +11 -19
  582. cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +8 -33
  583. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +9 -11
  584. cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -0
  585. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +91 -27
  586. cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +36 -7
  587. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +20 -21
  588. cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +8 -6
  589. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +13 -15
  590. cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +3 -1
  591. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +39 -41
  592. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -0
  593. cirq/transformers/drop_empty_moments.py +5 -3
  594. cirq/transformers/drop_empty_moments_test.py +4 -2
  595. cirq/transformers/drop_negligible_operations.py +7 -5
  596. cirq/transformers/drop_negligible_operations_test.py +2 -0
  597. cirq/transformers/dynamical_decoupling.py +49 -42
  598. cirq/transformers/dynamical_decoupling_test.py +223 -205
  599. cirq/transformers/eject_phased_paulis.py +28 -26
  600. cirq/transformers/eject_phased_paulis_test.py +12 -9
  601. cirq/transformers/eject_z.py +12 -12
  602. cirq/transformers/eject_z_test.py +2 -2
  603. cirq/transformers/expand_composite.py +6 -4
  604. cirq/transformers/expand_composite_test.py +3 -1
  605. cirq/transformers/gauge_compiling/__init__.py +3 -1
  606. cirq/transformers/gauge_compiling/cphase_gauge.py +2 -0
  607. cirq/transformers/gauge_compiling/cphase_gauge_test.py +2 -0
  608. cirq/transformers/gauge_compiling/cz_gauge.py +2 -0
  609. cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
  610. cirq/transformers/gauge_compiling/gauge_compiling.py +45 -41
  611. cirq/transformers/gauge_compiling/gauge_compiling_test.py +2 -0
  612. cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +1 -0
  613. cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +5 -1
  614. cirq/transformers/gauge_compiling/iswap_gauge.py +2 -0
  615. cirq/transformers/gauge_compiling/iswap_gauge_test.py +1 -0
  616. cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -0
  617. cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +2 -0
  618. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +7 -6
  619. cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +2 -0
  620. cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +2 -0
  621. cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +2 -0
  622. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +6 -3
  623. cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +3 -0
  624. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +12 -9
  625. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +9 -7
  626. cirq/transformers/insertion_sort.py +8 -6
  627. cirq/transformers/insertion_sort_test.py +3 -1
  628. cirq/transformers/measurement_transformers.py +29 -29
  629. cirq/transformers/measurement_transformers_test.py +2 -0
  630. cirq/transformers/merge_k_qubit_gates.py +12 -10
  631. cirq/transformers/merge_k_qubit_gates_test.py +18 -18
  632. cirq/transformers/merge_single_qubit_gates.py +197 -20
  633. cirq/transformers/merge_single_qubit_gates_test.py +177 -5
  634. cirq/transformers/noise_adding.py +5 -3
  635. cirq/transformers/noise_adding_test.py +2 -0
  636. cirq/transformers/optimize_for_target_gateset.py +19 -17
  637. cirq/transformers/optimize_for_target_gateset_test.py +11 -8
  638. cirq/transformers/qubit_management_transformers.py +13 -11
  639. cirq/transformers/qubit_management_transformers_test.py +5 -3
  640. cirq/transformers/randomized_measurements.py +16 -14
  641. cirq/transformers/randomized_measurements_test.py +10 -4
  642. cirq/transformers/routing/initial_mapper.py +6 -4
  643. cirq/transformers/routing/initial_mapper_test.py +2 -0
  644. cirq/transformers/routing/line_initial_mapper.py +16 -14
  645. cirq/transformers/routing/line_initial_mapper_test.py +9 -7
  646. cirq/transformers/routing/mapping_manager.py +10 -10
  647. cirq/transformers/routing/mapping_manager_test.py +2 -0
  648. cirq/transformers/routing/route_circuit_cqc.py +33 -31
  649. cirq/transformers/routing/route_circuit_cqc_test.py +15 -13
  650. cirq/transformers/routing/visualize_routed_circuit.py +8 -7
  651. cirq/transformers/routing/visualize_routed_circuit_test.py +4 -2
  652. cirq/transformers/stratify.py +17 -15
  653. cirq/transformers/stratify_test.py +3 -0
  654. cirq/transformers/symbolize.py +103 -0
  655. cirq/transformers/symbolize_test.py +62 -0
  656. cirq/transformers/synchronize_terminal_measurements.py +10 -10
  657. cirq/transformers/synchronize_terminal_measurements_test.py +12 -10
  658. cirq/transformers/tag_transformers.py +97 -0
  659. cirq/transformers/tag_transformers_test.py +103 -0
  660. cirq/transformers/target_gatesets/compilation_target_gateset.py +21 -19
  661. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +20 -16
  662. cirq/transformers/target_gatesets/cz_gateset.py +7 -5
  663. cirq/transformers/target_gatesets/cz_gateset_test.py +21 -19
  664. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +9 -7
  665. cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +25 -25
  666. cirq/transformers/transformer_api.py +34 -47
  667. cirq/transformers/transformer_api_test.py +9 -8
  668. cirq/transformers/transformer_primitives.py +39 -49
  669. cirq/transformers/transformer_primitives_test.py +10 -17
  670. cirq/value/abc_alt.py +6 -4
  671. cirq/value/abc_alt_test.py +5 -3
  672. cirq/value/angle.py +11 -12
  673. cirq/value/angle_test.py +5 -3
  674. cirq/value/classical_data.py +27 -27
  675. cirq/value/classical_data_test.py +11 -8
  676. cirq/value/condition.py +26 -24
  677. cirq/value/condition_test.py +2 -0
  678. cirq/value/digits.py +14 -11
  679. cirq/value/digits_test.py +2 -0
  680. cirq/value/duration.py +23 -20
  681. cirq/value/duration_test.py +2 -0
  682. cirq/value/linear_dict.py +25 -30
  683. cirq/value/linear_dict_test.py +10 -8
  684. cirq/value/measurement_key.py +12 -12
  685. cirq/value/measurement_key_test.py +2 -0
  686. cirq/value/periodic_value.py +4 -4
  687. cirq/value/periodic_value_test.py +11 -7
  688. cirq/value/probability.py +3 -1
  689. cirq/value/probability_test.py +4 -2
  690. cirq/value/product_state.py +15 -13
  691. cirq/value/product_state_test.py +4 -1
  692. cirq/value/random_state.py +2 -0
  693. cirq/value/random_state_test.py +5 -3
  694. cirq/value/timestamp.py +11 -7
  695. cirq/value/timestamp_test.py +14 -12
  696. cirq/value/type_alias.py +4 -4
  697. cirq/value/value_equality_attr.py +8 -9
  698. cirq/value/value_equality_attr_test.py +14 -11
  699. cirq/vis/density_matrix.py +3 -3
  700. cirq/vis/density_matrix_test.py +20 -17
  701. cirq/vis/heatmap.py +24 -37
  702. cirq/vis/heatmap_test.py +3 -0
  703. cirq/vis/histogram.py +9 -6
  704. cirq/vis/histogram_test.py +5 -2
  705. cirq/vis/state_histogram.py +10 -8
  706. cirq/vis/state_histogram_test.py +7 -5
  707. cirq/vis/vis_utils.py +4 -1
  708. cirq/vis/vis_utils_test.py +4 -1
  709. cirq/work/collector.py +12 -18
  710. cirq/work/collector_test.py +15 -10
  711. cirq/work/observable_grouping.py +6 -7
  712. cirq/work/observable_grouping_test.py +10 -9
  713. cirq/work/observable_measurement.py +47 -45
  714. cirq/work/observable_measurement_data.py +22 -17
  715. cirq/work/observable_measurement_data_test.py +4 -1
  716. cirq/work/observable_measurement_test.py +48 -29
  717. cirq/work/observable_readout_calibration.py +5 -2
  718. cirq/work/observable_readout_calibration_test.py +5 -2
  719. cirq/work/observable_settings.py +13 -22
  720. cirq/work/observable_settings_test.py +9 -7
  721. cirq/work/pauli_sum_collector.py +12 -10
  722. cirq/work/pauli_sum_collector_test.py +9 -9
  723. cirq/work/sampler.py +42 -43
  724. cirq/work/sampler_test.py +31 -24
  725. cirq/work/zeros_sampler.py +6 -4
  726. cirq/work/zeros_sampler_test.py +7 -5
  727. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/METADATA +7 -8
  728. cirq_core-1.6.0.dist-info/RECORD +1241 -0
  729. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
  730. cirq_core-1.5.0.dev20250409222543.dist-info/RECORD +0 -1216
  731. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
  732. {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
@@ -11,8 +11,10 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
14
17
  import unittest.mock as mock
15
- from typing import Optional
16
18
 
17
19
  import numpy as np
18
20
  import pytest
@@ -20,13 +22,13 @@ import sympy
20
22
 
21
23
  import cirq
22
24
  import cirq.circuits.circuit_operation as circuit_operation
23
- from cirq import _compat
25
+ from cirq import _compat, protocols
24
26
  from cirq.circuits.circuit_operation import _full_join_string_lists
25
27
 
26
28
  ALL_SIMULATORS = (cirq.Simulator(), cirq.DensityMatrixSimulator(), cirq.CliffordSimulator())
27
29
 
28
30
 
29
- def test_properties():
31
+ def test_properties() -> None:
30
32
  a, b, c = cirq.LineQubit.range(3)
31
33
  circuit = cirq.FrozenCircuit(
32
34
  cirq.X(a),
@@ -48,7 +50,7 @@ def test_properties():
48
50
  assert op == circuit.to_op()
49
51
 
50
52
 
51
- def test_circuit_type():
53
+ def test_circuit_type() -> None:
52
54
  a, b, c = cirq.LineQubit.range(3)
53
55
  circuit = cirq.Circuit(
54
56
  cirq.X(a),
@@ -58,10 +60,10 @@ def test_circuit_type():
58
60
  cirq.measure(a, b, c, key='m'),
59
61
  )
60
62
  with pytest.raises(TypeError, match='Expected circuit of type FrozenCircuit'):
61
- _ = cirq.CircuitOperation(circuit)
63
+ _ = cirq.CircuitOperation(circuit) # type: ignore[arg-type]
62
64
 
63
65
 
64
- def test_non_invertible_circuit():
66
+ def test_non_invertible_circuit() -> None:
65
67
  a, b, c = cirq.LineQubit.range(3)
66
68
  circuit = cirq.FrozenCircuit(
67
69
  cirq.X(a),
@@ -74,7 +76,7 @@ def test_non_invertible_circuit():
74
76
  _ = cirq.CircuitOperation(circuit, repetitions=-2)
75
77
 
76
78
 
77
- def test_repetitions_and_ids_length_mismatch():
79
+ def test_repetitions_and_ids_length_mismatch() -> None:
78
80
  a, b, c = cirq.LineQubit.range(3)
79
81
  circuit = cirq.FrozenCircuit(
80
82
  cirq.X(a),
@@ -87,7 +89,7 @@ def test_repetitions_and_ids_length_mismatch():
87
89
  _ = cirq.CircuitOperation(circuit, repetitions=2, repetition_ids=['a', 'b', 'c'])
88
90
 
89
91
 
90
- def test_is_measurement_memoization():
92
+ def test_is_measurement_memoization() -> None:
91
93
  a = cirq.LineQubit(0)
92
94
  circuit = cirq.FrozenCircuit(cirq.measure(a, key='m'))
93
95
  c_op = cirq.CircuitOperation(circuit)
@@ -98,7 +100,7 @@ def test_is_measurement_memoization():
98
100
  assert hasattr(circuit, cache_name)
99
101
 
100
102
 
101
- def test_invalid_measurement_keys():
103
+ def test_invalid_measurement_keys() -> None:
102
104
  a = cirq.LineQubit(0)
103
105
  circuit = cirq.FrozenCircuit(cirq.measure(a, key='m'))
104
106
  c_op = cirq.CircuitOperation(circuit)
@@ -118,7 +120,7 @@ def test_invalid_measurement_keys():
118
120
  _ = cirq.CircuitOperation(circuit, measurement_key_map={'m:a': 'ma'})
119
121
 
120
122
 
121
- def test_invalid_qubit_mapping():
123
+ def test_invalid_qubit_mapping() -> None:
122
124
  q = cirq.LineQubit(0)
123
125
  q3 = cirq.LineQid(1, dimension=3)
124
126
 
@@ -136,7 +138,7 @@ def test_invalid_qubit_mapping():
136
138
  _ = c_op.with_qubit_mapping(lambda q: q3)
137
139
 
138
140
 
139
- def test_circuit_sharing():
141
+ def test_circuit_sharing() -> None:
140
142
  a, b, c = cirq.LineQubit.range(3)
141
143
  circuit = cirq.FrozenCircuit(
142
144
  cirq.X(a),
@@ -156,7 +158,7 @@ def test_circuit_sharing():
156
158
  assert hash(op1) == hash(op3)
157
159
 
158
160
 
159
- def test_with_qubits():
161
+ def test_with_qubits() -> None:
160
162
  a, b, c, d = cirq.LineQubit.range(4)
161
163
  circuit = cirq.FrozenCircuit(cirq.H(a), cirq.CX(a, b))
162
164
  op_base = cirq.CircuitOperation(circuit)
@@ -193,10 +195,10 @@ def test_with_qubits():
193
195
  _ = op_base.with_qubit_mapping(lambda q: b)
194
196
  # with_qubit_mapping requires exactly one argument.
195
197
  with pytest.raises(TypeError, match='must be a function or dict'):
196
- _ = op_base.with_qubit_mapping('bad arg')
198
+ _ = op_base.with_qubit_mapping('bad arg') # type: ignore[arg-type]
197
199
 
198
200
 
199
- def test_with_measurement_keys():
201
+ def test_with_measurement_keys() -> None:
200
202
  a, b = cirq.LineQubit.range(2)
201
203
  circuit = cirq.FrozenCircuit(cirq.X(a), cirq.measure(b, key='mb'), cirq.measure(a, key='ma'))
202
204
  op_base = cirq.CircuitOperation(circuit)
@@ -213,7 +215,7 @@ def test_with_measurement_keys():
213
215
  _ = op_base.with_measurement_key_mapping({'ma': 'mb'})
214
216
 
215
217
 
216
- def test_with_params():
218
+ def test_with_params() -> None:
217
219
  a = cirq.LineQubit(0)
218
220
  z_exp = sympy.Symbol('z_exp')
219
221
  x_exp = sympy.Symbol('x_exp')
@@ -240,7 +242,7 @@ def test_with_params():
240
242
  )
241
243
 
242
244
 
243
- def test_recursive_params():
245
+ def test_recursive_params() -> None:
244
246
  q = cirq.LineQubit(0)
245
247
  a, a2, b, b2 = sympy.symbols('a a2 b b2')
246
248
  circuitop = cirq.CircuitOperation(
@@ -291,18 +293,18 @@ def test_repeat(add_measurements: bool, use_default_ids_for_initial_rep: bool) -
291
293
  _ = op_base.repeat(initial_repetitions)
292
294
  initial_repetitions = abs(initial_repetitions)
293
295
 
294
- op_with_reps: Optional[cirq.CircuitOperation] = None
296
+ op_with_reps: cirq.CircuitOperation | None = None
295
297
  rep_ids = []
296
298
  if use_default_ids_for_initial_rep:
297
- op_with_reps = op_base.repeat(initial_repetitions)
298
299
  rep_ids = ['0', '1', '2']
299
- assert op_base**initial_repetitions == op_with_reps
300
+ op_with_reps = op_base.repeat(initial_repetitions, use_repetition_ids=True)
300
301
  else:
301
302
  rep_ids = ['a', 'b', 'c']
302
303
  op_with_reps = op_base.repeat(initial_repetitions, rep_ids)
303
- assert op_base**initial_repetitions != op_with_reps
304
- assert (op_base**initial_repetitions).replace(repetition_ids=rep_ids) == op_with_reps
304
+ assert op_base**initial_repetitions != op_with_reps
305
+ assert (op_base**initial_repetitions).replace(repetition_ids=rep_ids) == op_with_reps
305
306
  assert op_with_reps.repetitions == initial_repetitions
307
+ assert op_with_reps.use_repetition_ids
306
308
  assert op_with_reps.repetition_ids == rep_ids
307
309
  assert op_with_reps.repeat(1) is op_with_reps
308
310
 
@@ -332,8 +334,6 @@ def test_repeat(add_measurements: bool, use_default_ids_for_initial_rep: bool) -
332
334
  assert op_base.repeat(2.99999999999).repetitions == 3
333
335
 
334
336
 
335
- # TODO: #7232 - enable and fix immediately after the 1.5.0 release
336
- @pytest.mark.xfail(reason='broken by rollback of use_repetition_ids for #7232')
337
337
  def test_replace_repetition_ids() -> None:
338
338
  a, b = cirq.LineQubit.range(2)
339
339
  circuit = cirq.Circuit(cirq.H(a), cirq.CX(a, b), cirq.M(b, key='mb'), cirq.M(a, key='ma'))
@@ -359,7 +359,7 @@ def test_replace_repetition_ids() -> None:
359
359
  @pytest.mark.parametrize('add_measurements', [True, False])
360
360
  @pytest.mark.parametrize('use_repetition_ids', [True, False])
361
361
  @pytest.mark.parametrize('initial_reps', [0, 1, 2, 3])
362
- def test_repeat_zero_times(add_measurements, use_repetition_ids, initial_reps):
362
+ def test_repeat_zero_times(add_measurements, use_repetition_ids, initial_reps) -> None:
363
363
  q = cirq.LineQubit(0)
364
364
  subcircuit = cirq.Circuit(cirq.X(q))
365
365
  if add_measurements:
@@ -374,7 +374,7 @@ def test_repeat_zero_times(add_measurements, use_repetition_ids, initial_reps):
374
374
  assert np.allclose(result.state_vector(), [1, 0])
375
375
 
376
376
 
377
- def test_no_repetition_ids():
377
+ def test_no_repetition_ids() -> None:
378
378
  def default_repetition_ids(self): # pragma: no cover
379
379
  assert False, "Should not call default_repetition_ids"
380
380
 
@@ -395,7 +395,7 @@ def test_no_repetition_ids():
395
395
  assert op2.repetition_ids is None
396
396
 
397
397
 
398
- def test_parameterized_repeat():
398
+ def test_parameterized_repeat() -> None:
399
399
  q = cirq.LineQubit(0)
400
400
  op = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(q))) ** sympy.Symbol('a')
401
401
  assert cirq.parameter_names(op) == {'a'}
@@ -455,11 +455,12 @@ def test_parameterized_repeat():
455
455
  cirq.Simulator().simulate(cirq.Circuit(op))
456
456
 
457
457
 
458
- def test_parameterized_repeat_side_effects():
458
+ def test_parameterized_repeat_side_effects() -> None:
459
459
  q = cirq.LineQubit(0)
460
460
  op = cirq.CircuitOperation(
461
461
  cirq.FrozenCircuit(cirq.X(q).with_classical_controls('c'), cirq.measure(q, key='m')),
462
462
  repetitions=sympy.Symbol('a'),
463
+ use_repetition_ids=True,
463
464
  )
464
465
 
465
466
  # Control keys can be calculated because they only "lift" if there's a matching
@@ -519,7 +520,7 @@ def test_parameterized_repeat_side_effects():
519
520
  )
520
521
 
521
522
 
522
- def test_parameterized_repeat_side_effects_when_not_using_rep_ids():
523
+ def test_parameterized_repeat_side_effects_when_not_using_rep_ids() -> None:
523
524
  q = cirq.LineQubit(0)
524
525
  op = cirq.CircuitOperation(
525
526
  cirq.FrozenCircuit(cirq.X(q).with_classical_controls('c'), cirq.measure(q, key='m')),
@@ -545,7 +546,7 @@ def test_parameterized_repeat_side_effects_when_not_using_rep_ids():
545
546
  op.repeat(repetition_ids=['x', 'y'])
546
547
 
547
548
 
548
- def test_qid_shape():
549
+ def test_qid_shape() -> None:
549
550
  circuit = cirq.FrozenCircuit(
550
551
  cirq.IdentityGate(qid_shape=(q.dimension,)).on(q)
551
552
  for q in cirq.LineQid.for_qid_shape((1, 2, 3, 4))
@@ -560,7 +561,7 @@ def test_qid_shape():
560
561
  assert cirq.num_qubits(id_op) == 3
561
562
 
562
563
 
563
- def test_string_format():
564
+ def test_string_format() -> None:
564
565
  x, y, z = cirq.LineQubit.range(3)
565
566
 
566
567
  fc0 = cirq.FrozenCircuit()
@@ -610,7 +611,7 @@ cirq.CircuitOperation(
610
611
  cirq.measure(cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2), key=cirq.MeasurementKey(name='m')),
611
612
  ),
612
613
  ]),
613
- )"""
614
+ )""" # noqa: E501
614
615
  )
615
616
 
616
617
  fc2 = cirq.FrozenCircuit(cirq.X(x), cirq.H(y), cirq.CX(y, x))
@@ -713,7 +714,6 @@ cirq.CircuitOperation(
713
714
  ),
714
715
  ),
715
716
  ]),
716
- use_repetition_ids=False,
717
717
  )"""
718
718
  )
719
719
  op7 = cirq.CircuitOperation(
@@ -730,13 +730,12 @@ cirq.CircuitOperation(
730
730
  cirq.measure(cirq.LineQubit(0), key=cirq.MeasurementKey(name='a')),
731
731
  ),
732
732
  ]),
733
- use_repetition_ids=False,
734
733
  repeat_until=cirq.KeyCondition(cirq.MeasurementKey(name='a')),
735
734
  )"""
736
735
  )
737
736
 
738
737
 
739
- def test_json_dict():
738
+ def test_json_dict() -> None:
740
739
  a, b, c = cirq.LineQubit.range(3)
741
740
  circuit = cirq.FrozenCircuit(
742
741
  cirq.X(a),
@@ -761,10 +760,11 @@ def test_json_dict():
761
760
  'param_resolver': op.param_resolver,
762
761
  'parent_path': op.parent_path,
763
762
  'repetition_ids': None,
763
+ 'use_repetition_ids': False,
764
764
  }
765
765
 
766
766
 
767
- def test_terminal_matches():
767
+ def test_terminal_matches() -> None:
768
768
  a, b = cirq.LineQubit.range(2)
769
769
  fc = cirq.FrozenCircuit(cirq.H(a), cirq.measure(b, key='m1'))
770
770
  op = cirq.CircuitOperation(fc)
@@ -802,23 +802,23 @@ def test_terminal_matches():
802
802
  assert c.are_any_measurements_terminal()
803
803
 
804
804
 
805
- def test_nonterminal_in_subcircuit():
805
+ def test_nonterminal_in_subcircuit() -> None:
806
806
  a, b = cirq.LineQubit.range(2)
807
807
  fc = cirq.FrozenCircuit(cirq.H(a), cirq.measure(b, key='m1'), cirq.X(b))
808
- op = cirq.CircuitOperation(fc)
809
- c = cirq.Circuit(cirq.X(a), op)
810
- assert isinstance(op, cirq.CircuitOperation)
808
+ circuit_op = cirq.CircuitOperation(fc)
809
+ c = cirq.Circuit(cirq.X(a), circuit_op)
810
+ assert isinstance(circuit_op, cirq.CircuitOperation)
811
811
  assert not c.are_all_measurements_terminal()
812
812
  assert not c.are_any_measurements_terminal()
813
813
 
814
- op = op.with_tags('test')
814
+ op = circuit_op.with_tags('test')
815
815
  c = cirq.Circuit(cirq.X(a), op)
816
816
  assert not isinstance(op, cirq.CircuitOperation)
817
817
  assert not c.are_all_measurements_terminal()
818
818
  assert not c.are_any_measurements_terminal()
819
819
 
820
820
 
821
- def test_decompose_applies_maps():
821
+ def test_decompose_applies_maps() -> None:
822
822
  a, b, c = cirq.LineQubit.range(3)
823
823
  exp = sympy.Symbol('exp')
824
824
  theta = sympy.Symbol('theta')
@@ -846,7 +846,7 @@ def test_decompose_applies_maps():
846
846
  assert cirq.Circuit(cirq.decompose_once(op)) == expected_circuit
847
847
 
848
848
 
849
- def test_decompose_loops():
849
+ def test_decompose_loops() -> None:
850
850
  a, b = cirq.LineQubit.range(2)
851
851
  circuit = cirq.FrozenCircuit(cirq.H(a), cirq.CX(a, b))
852
852
  base_op = cirq.CircuitOperation(circuit)
@@ -862,11 +862,31 @@ def test_decompose_loops():
862
862
  assert cirq.Circuit(cirq.decompose_once(op)) == expected_circuit
863
863
 
864
864
 
865
- def test_decompose_loops_with_measurements():
865
+ def test_decompose_loops_with_measurements() -> None:
866
866
  a, b = cirq.LineQubit.range(2)
867
867
  circuit = cirq.FrozenCircuit(cirq.H(a), cirq.CX(a, b), cirq.measure(a, b, key='m'))
868
868
  base_op = cirq.CircuitOperation(circuit)
869
869
 
870
+ op = base_op.with_qubits(b, a).repeat(3)
871
+ expected_circuit = cirq.Circuit(
872
+ cirq.H(b),
873
+ cirq.CX(b, a),
874
+ cirq.measure(b, a, key=cirq.MeasurementKey.parse_serialized('m')),
875
+ cirq.H(b),
876
+ cirq.CX(b, a),
877
+ cirq.measure(b, a, key=cirq.MeasurementKey.parse_serialized('m')),
878
+ cirq.H(b),
879
+ cirq.CX(b, a),
880
+ cirq.measure(b, a, key=cirq.MeasurementKey.parse_serialized('m')),
881
+ )
882
+ assert cirq.Circuit(cirq.decompose_once(op)) == expected_circuit
883
+
884
+
885
+ def test_decompose_loops_with_measurements_use_rep_ids() -> None:
886
+ a, b = cirq.LineQubit.range(2)
887
+ circuit = cirq.FrozenCircuit(cirq.H(a), cirq.CX(a, b), cirq.measure(a, b, key='m'))
888
+ base_op = cirq.CircuitOperation(circuit, use_repetition_ids=True)
889
+
870
890
  op = base_op.with_qubits(b, a).repeat(3)
871
891
  expected_circuit = cirq.Circuit(
872
892
  cirq.H(b),
@@ -882,7 +902,7 @@ def test_decompose_loops_with_measurements():
882
902
  assert cirq.Circuit(cirq.decompose_once(op)) == expected_circuit
883
903
 
884
904
 
885
- def test_decompose_nested():
905
+ def test_decompose_nested() -> None:
886
906
  a, b, c, d = cirq.LineQubit.range(4)
887
907
  exp1 = sympy.Symbol('exp1')
888
908
  exp_half = sympy.Symbol('exp_half')
@@ -962,7 +982,7 @@ def test_decompose_nested():
962
982
  assert final_op.mapped_circuit(deep=True) == expected_circuit
963
983
 
964
984
 
965
- def test_decompose_repeated_nested_measurements():
985
+ def test_decompose_repeated_nested_measurements() -> None:
966
986
  # Details of this test described at
967
987
  # https://tinyurl.com/measurement-repeated-circuitop#heading=h.sbgxcsyin9wt.
968
988
  a = cirq.LineQubit(0)
@@ -1014,7 +1034,7 @@ def test_decompose_repeated_nested_measurements():
1014
1034
  assert op3.mapped_circuit(deep=True) == expected_circuit
1015
1035
 
1016
1036
 
1017
- def test_keys_under_parent_path():
1037
+ def test_keys_under_parent_path() -> None:
1018
1038
  a = cirq.LineQubit(0)
1019
1039
  op1 = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.measure(a, key='A')))
1020
1040
  assert cirq.measurement_key_names(op1) == {'A'}
@@ -1023,10 +1043,12 @@ def test_keys_under_parent_path():
1023
1043
  op3 = cirq.with_key_path_prefix(op2, ('C',))
1024
1044
  assert cirq.measurement_key_names(op3) == {'C:B:A'}
1025
1045
  op4 = op3.repeat(2)
1026
- assert cirq.measurement_key_names(op4) == {'C:B:0:A', 'C:B:1:A'}
1046
+ assert cirq.measurement_key_names(op4) == {'C:B:A'}
1047
+ op4_rep = op3.repeat(2).replace(use_repetition_ids=True)
1048
+ assert cirq.measurement_key_names(op4_rep) == {'C:B:0:A', 'C:B:1:A'}
1027
1049
 
1028
1050
 
1029
- def test_mapped_circuit_preserves_moments():
1051
+ def test_mapped_circuit_preserves_moments() -> None:
1030
1052
  q0, q1 = cirq.LineQubit.range(2)
1031
1053
  fc = cirq.FrozenCircuit(cirq.Moment(cirq.X(q0)), cirq.Moment(cirq.X(q1)))
1032
1054
  op = cirq.CircuitOperation(fc)
@@ -1034,7 +1056,7 @@ def test_mapped_circuit_preserves_moments():
1034
1056
  assert op.repeat(3).mapped_circuit(deep=True) == fc * 3
1035
1057
 
1036
1058
 
1037
- def test_mapped_op():
1059
+ def test_mapped_op() -> None:
1038
1060
  q0, q1 = cirq.LineQubit.range(2)
1039
1061
  a, b = (sympy.Symbol(x) for x in 'ab')
1040
1062
  fc1 = cirq.FrozenCircuit(cirq.X(q0) ** a, cirq.measure(q0, q1, key='m'))
@@ -1050,14 +1072,14 @@ def test_mapped_op():
1050
1072
  assert op1.mapped_op() == op2
1051
1073
 
1052
1074
 
1053
- def test_tag_propagation():
1075
+ def test_tag_propagation() -> None:
1054
1076
  # Tags are not propagated from the CircuitOperation to its components.
1055
1077
  # TODO: support tag propagation for better serialization.
1056
1078
  a, b, c = cirq.LineQubit.range(3)
1057
1079
  circuit = cirq.FrozenCircuit(cirq.X(a), cirq.H(b), cirq.H(c), cirq.CZ(a, c))
1058
- op = cirq.CircuitOperation(circuit)
1080
+ circuit_op = cirq.CircuitOperation(circuit)
1059
1081
  test_tag = 'test_tag'
1060
- op = op.with_tags(test_tag)
1082
+ op = circuit_op.with_tags(test_tag)
1061
1083
 
1062
1084
  assert test_tag in op.tags
1063
1085
 
@@ -1067,13 +1089,15 @@ def test_tag_propagation():
1067
1089
  assert test_tag not in op.tags
1068
1090
 
1069
1091
 
1070
- def test_mapped_circuit_keeps_keys_under_parent_path():
1092
+ def test_mapped_circuit_keeps_keys_under_parent_path() -> None:
1071
1093
  q = cirq.LineQubit(0)
1094
+ bit_flip = cirq.bit_flip(0.5)
1095
+ assert isinstance(bit_flip, cirq.BitFlipChannel)
1072
1096
  op1 = cirq.CircuitOperation(
1073
1097
  cirq.FrozenCircuit(
1074
1098
  cirq.measure(q, key='A'),
1075
1099
  cirq.measure_single_paulistring(cirq.X(q), key='B'),
1076
- cirq.MixedUnitaryChannel.from_mixture(cirq.bit_flip(0.5), key='C').on(q),
1100
+ cirq.MixedUnitaryChannel.from_mixture(bit_flip, key='C').on(q),
1077
1101
  cirq.KrausChannel.from_channel(cirq.phase_damp(0.5), key='D').on(q),
1078
1102
  )
1079
1103
  )
@@ -1081,7 +1105,7 @@ def test_mapped_circuit_keeps_keys_under_parent_path():
1081
1105
  assert cirq.measurement_key_names(op2.mapped_circuit()) == {'X:A', 'X:B', 'X:C', 'X:D'}
1082
1106
 
1083
1107
 
1084
- def test_mapped_circuit_allows_repeated_keys():
1108
+ def test_mapped_circuit_allows_repeated_keys() -> None:
1085
1109
  q = cirq.LineQubit(0)
1086
1110
  op1 = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.measure(q, key='A')))
1087
1111
  op2 = cirq.CircuitOperation(cirq.FrozenCircuit(op1, op1))
@@ -1089,37 +1113,33 @@ def test_mapped_circuit_allows_repeated_keys():
1089
1113
  cirq.testing.assert_has_diagram(
1090
1114
  circuit, "0: ───M('A')───M('A')───", use_unicode_characters=True
1091
1115
  )
1092
- op1 = cirq.measure(q, key='A')
1093
- op2 = cirq.CircuitOperation(cirq.FrozenCircuit(op1, op1))
1094
- circuit = op2.mapped_circuit()
1116
+ op3 = cirq.measure(q, key='A')
1117
+ op4 = cirq.CircuitOperation(cirq.FrozenCircuit(op3, op3))
1118
+ circuit = op4.mapped_circuit()
1095
1119
  cirq.testing.assert_has_diagram(
1096
1120
  circuit, "0: ───M('A')───M('A')───", use_unicode_characters=True
1097
1121
  )
1098
1122
 
1099
1123
 
1100
1124
  @pytest.mark.parametrize('sim', ALL_SIMULATORS)
1101
- def test_simulate_no_repetition_ids_both_levels(sim):
1125
+ def test_simulate_no_repetition_ids_both_levels(sim) -> None:
1102
1126
  q = cirq.LineQubit(0)
1103
1127
  inner = cirq.Circuit(cirq.measure(q, key='a'))
1104
- middle = cirq.Circuit(
1105
- cirq.CircuitOperation(inner.freeze(), repetitions=2, use_repetition_ids=False)
1106
- )
1107
- outer_subcircuit = cirq.CircuitOperation(
1108
- middle.freeze(), repetitions=2, use_repetition_ids=False
1109
- )
1128
+ middle = cirq.Circuit(cirq.CircuitOperation(inner.freeze(), repetitions=2))
1129
+ outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
1110
1130
  circuit = cirq.Circuit(outer_subcircuit)
1111
1131
  result = sim.run(circuit)
1112
1132
  assert result.records['a'].shape == (1, 4, 1)
1113
1133
 
1114
1134
 
1115
1135
  @pytest.mark.parametrize('sim', ALL_SIMULATORS)
1116
- def test_simulate_no_repetition_ids_outer(sim):
1136
+ def test_simulate_no_repetition_ids_outer(sim) -> None:
1117
1137
  q = cirq.LineQubit(0)
1118
1138
  inner = cirq.Circuit(cirq.measure(q, key='a'))
1119
- middle = cirq.Circuit(cirq.CircuitOperation(inner.freeze(), repetitions=2))
1120
- outer_subcircuit = cirq.CircuitOperation(
1121
- middle.freeze(), repetitions=2, use_repetition_ids=False
1139
+ middle = cirq.Circuit(
1140
+ cirq.CircuitOperation(inner.freeze(), repetitions=2, use_repetition_ids=True)
1122
1141
  )
1142
+ outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
1123
1143
  circuit = cirq.Circuit(outer_subcircuit)
1124
1144
  result = sim.run(circuit)
1125
1145
  assert result.records['0:a'].shape == (1, 2, 1)
@@ -1127,13 +1147,13 @@ def test_simulate_no_repetition_ids_outer(sim):
1127
1147
 
1128
1148
 
1129
1149
  @pytest.mark.parametrize('sim', ALL_SIMULATORS)
1130
- def test_simulate_no_repetition_ids_inner(sim):
1150
+ def test_simulate_no_repetition_ids_inner(sim) -> None:
1131
1151
  q = cirq.LineQubit(0)
1132
1152
  inner = cirq.Circuit(cirq.measure(q, key='a'))
1133
- middle = cirq.Circuit(
1134
- cirq.CircuitOperation(inner.freeze(), repetitions=2, use_repetition_ids=False)
1153
+ middle = cirq.Circuit(cirq.CircuitOperation(inner.freeze(), repetitions=2))
1154
+ outer_subcircuit = cirq.CircuitOperation(
1155
+ middle.freeze(), repetitions=2, use_repetition_ids=True
1135
1156
  )
1136
- outer_subcircuit = cirq.CircuitOperation(middle.freeze(), repetitions=2)
1137
1157
  circuit = cirq.Circuit(outer_subcircuit)
1138
1158
  result = sim.run(circuit)
1139
1159
  assert result.records['0:a'].shape == (1, 2, 1)
@@ -1141,14 +1161,13 @@ def test_simulate_no_repetition_ids_inner(sim):
1141
1161
 
1142
1162
 
1143
1163
  @pytest.mark.parametrize('sim', ALL_SIMULATORS)
1144
- def test_repeat_until(sim):
1164
+ def test_repeat_until(sim) -> None:
1145
1165
  q = cirq.LineQubit(0)
1146
1166
  key = cirq.MeasurementKey('m')
1147
1167
  c = cirq.Circuit(
1148
1168
  cirq.X(q),
1149
1169
  cirq.CircuitOperation(
1150
1170
  cirq.FrozenCircuit(cirq.X(q), cirq.measure(q, key=key)),
1151
- use_repetition_ids=False,
1152
1171
  repeat_until=cirq.KeyCondition(key),
1153
1172
  ),
1154
1173
  )
@@ -1159,11 +1178,10 @@ def test_repeat_until(sim):
1159
1178
 
1160
1179
 
1161
1180
  @pytest.mark.parametrize('sim', ALL_SIMULATORS)
1162
- def test_repeat_until_sympy(sim):
1181
+ def test_repeat_until_sympy(sim) -> None:
1163
1182
  q1, q2 = cirq.LineQubit.range(2)
1164
1183
  circuitop = cirq.CircuitOperation(
1165
1184
  cirq.FrozenCircuit(cirq.X(q2), cirq.measure(q2, key='b')),
1166
- use_repetition_ids=False,
1167
1185
  repeat_until=cirq.SympyCondition(sympy.Eq(sympy.Symbol('a'), sympy.Symbol('b'))),
1168
1186
  )
1169
1187
  c = cirq.Circuit(cirq.measure(q1, key='a'), circuitop)
@@ -1177,13 +1195,12 @@ def test_repeat_until_sympy(sim):
1177
1195
 
1178
1196
 
1179
1197
  @pytest.mark.parametrize('sim', [cirq.Simulator(), cirq.DensityMatrixSimulator()])
1180
- def test_post_selection(sim):
1198
+ def test_post_selection(sim) -> None:
1181
1199
  q = cirq.LineQubit(0)
1182
1200
  key = cirq.MeasurementKey('m')
1183
1201
  c = cirq.Circuit(
1184
1202
  cirq.CircuitOperation(
1185
1203
  cirq.FrozenCircuit(cirq.X(q) ** 0.2, cirq.measure(q, key=key)),
1186
- use_repetition_ids=False,
1187
1204
  repeat_until=cirq.KeyCondition(key),
1188
1205
  )
1189
1206
  )
@@ -1193,26 +1210,25 @@ def test_post_selection(sim):
1193
1210
  assert result.records['m'][0][i] == (0,)
1194
1211
 
1195
1212
 
1196
- def test_repeat_until_diagram():
1213
+ def test_repeat_until_diagram() -> None:
1197
1214
  q = cirq.LineQubit(0)
1198
1215
  key = cirq.MeasurementKey('m')
1199
1216
  c = cirq.Circuit(
1200
1217
  cirq.CircuitOperation(
1201
1218
  cirq.FrozenCircuit(cirq.X(q) ** 0.2, cirq.measure(q, key=key)),
1202
- use_repetition_ids=False,
1203
1219
  repeat_until=cirq.KeyCondition(key),
1204
1220
  )
1205
1221
  )
1206
1222
  cirq.testing.assert_has_diagram(
1207
1223
  c,
1208
1224
  """
1209
- 0: ───[ 0: ───X^0.2───M('m')─── ](no_rep_ids, until=m)───
1225
+ 0: ───[ 0: ───X^0.2───M('m')─── ](until=m)───
1210
1226
  """,
1211
1227
  use_unicode_characters=True,
1212
1228
  )
1213
1229
 
1214
1230
 
1215
- def test_repeat_until_error():
1231
+ def test_repeat_until_error() -> None:
1216
1232
  q = cirq.LineQubit(0)
1217
1233
  with pytest.raises(ValueError, match='Cannot use repetitions with repeat_until'):
1218
1234
  cirq.CircuitOperation(
@@ -1223,18 +1239,15 @@ def test_repeat_until_error():
1223
1239
  with pytest.raises(ValueError, match='Infinite loop'):
1224
1240
  cirq.CircuitOperation(
1225
1241
  cirq.FrozenCircuit(cirq.measure(q, key='m')),
1226
- use_repetition_ids=False,
1227
1242
  repeat_until=cirq.KeyCondition(cirq.MeasurementKey('a')),
1228
1243
  )
1229
1244
 
1230
1245
 
1231
- def test_repeat_until_protocols():
1246
+ def test_repeat_until_protocols() -> None:
1232
1247
  q = cirq.LineQubit(0)
1233
1248
  op = cirq.CircuitOperation(
1234
1249
  cirq.FrozenCircuit(cirq.H(q) ** sympy.Symbol('p'), cirq.measure(q, key='a')),
1235
1250
  repeat_until=cirq.SympyCondition(sympy.Eq(sympy.Symbol('a'), 0)),
1236
- # TODO: #7232 - remove immediately after the 1.5.0 release
1237
- use_repetition_ids=False,
1238
1251
  )
1239
1252
  scoped = cirq.with_rescoped_keys(op, ('0',))
1240
1253
  # Ensure the _repeat_until has been mapped, the measurement has been mapped to the same key,
@@ -1261,14 +1274,12 @@ def test_repeat_until_protocols():
1261
1274
  assert not cirq.control_keys(resolved)
1262
1275
 
1263
1276
 
1264
- def test_inner_repeat_until_simulate():
1277
+ def test_inner_repeat_until_simulate() -> None:
1265
1278
  sim = cirq.Simulator()
1266
1279
  q = cirq.LineQubit(0)
1267
1280
  inner_loop = cirq.CircuitOperation(
1268
1281
  cirq.FrozenCircuit(cirq.H(q), cirq.measure(q, key="inner_loop")),
1269
1282
  repeat_until=cirq.SympyCondition(sympy.Eq(sympy.Symbol("inner_loop"), 0)),
1270
- # TODO: #7232 - remove immediately after the 1.5.0 release
1271
- use_repetition_ids=False,
1272
1283
  )
1273
1284
  outer_loop = cirq.Circuit(inner_loop, cirq.X(q), cirq.measure(q, key="outer_loop"))
1274
1285
  circuit = cirq.Circuit(
@@ -1286,3 +1297,30 @@ def test_inner_repeat_until_simulate():
1286
1297
 
1287
1298
 
1288
1299
  # TODO: Operation has a "gate" property. What is this for a CircuitOperation?
1300
+
1301
+
1302
+ def test_has_unitary_protocol_returns_true_if_all_common_gates() -> None:
1303
+ q = cirq.LineQubit(0)
1304
+ op = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(q), cirq.Y(q), cirq.Z(q)))
1305
+ assert protocols.has_unitary(op)
1306
+
1307
+
1308
+ def test_has_unitary_protocol_returns_false_if_measurement_gate() -> None:
1309
+ q = cirq.LineQubit(0)
1310
+ key = cirq.MeasurementKey('m')
1311
+ op = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(q) ** 0.2, cirq.measure(q, key=key)))
1312
+ assert not protocols.has_unitary(op)
1313
+
1314
+
1315
+ def test_has_unitary_protocol_returns_false_if_parametrized() -> None:
1316
+ q = cirq.LineQubit(0)
1317
+ exp = sympy.Symbol('exp')
1318
+ op = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(q) ** exp))
1319
+ assert not protocols.has_unitary(op)
1320
+
1321
+
1322
+ def test_has_unitary_protocol_returns_true_if_all_params_resolve() -> None:
1323
+ q = cirq.LineQubit(0)
1324
+ exp = sympy.Symbol('exp')
1325
+ op = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(q) ** exp), param_resolver={exp: 0.5})
1326
+ assert protocols.has_unitary(op)