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
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import numpy as np
16
18
  import pytest
17
19
  import sympy
@@ -20,7 +22,7 @@ import cirq
20
22
  import cirq.testing
21
23
 
22
24
 
23
- def test_validation():
25
+ def test_validation() -> None:
24
26
  a = cirq.NamedQubit('a')
25
27
  b = cirq.NamedQubit('b')
26
28
  c = cirq.NamedQubit('c')
@@ -42,7 +44,7 @@ def test_validation():
42
44
  _ = cirq.Moment([cirq.CZ(a, c), cirq.CZ(c, d)])
43
45
 
44
46
 
45
- def test_equality():
47
+ def test_equality() -> None:
46
48
  a = cirq.NamedQubit('a')
47
49
  b = cirq.NamedQubit('b')
48
50
  c = cirq.NamedQubit('c')
@@ -69,7 +71,7 @@ def test_equality():
69
71
  eq.make_equality_group(lambda: cirq.Moment([cirq.CZ(a, c), cirq.CZ(b, d)]))
70
72
 
71
73
 
72
- def test_approx_eq():
74
+ def test_approx_eq() -> None:
73
75
  a = cirq.NamedQubit('a')
74
76
  b = cirq.NamedQubit('b')
75
77
 
@@ -95,7 +97,7 @@ def test_approx_eq():
95
97
  )
96
98
 
97
99
 
98
- def test_operates_on_single_qubit():
100
+ def test_operates_on_single_qubit() -> None:
99
101
  a = cirq.NamedQubit('a')
100
102
  b = cirq.NamedQubit('b')
101
103
  c = cirq.NamedQubit('c')
@@ -119,7 +121,7 @@ def test_operates_on_single_qubit():
119
121
  assert not cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on_single_qubit(c)
120
122
 
121
123
 
122
- def test_operates_on():
124
+ def test_operates_on() -> None:
123
125
  a = cirq.NamedQubit('a')
124
126
  b = cirq.NamedQubit('b')
125
127
  c = cirq.NamedQubit('c')
@@ -155,7 +157,7 @@ def test_operates_on():
155
157
  assert cirq.Moment([cirq.X(a), cirq.X(b)]).operates_on([a, b, c])
156
158
 
157
159
 
158
- def test_operation_at():
160
+ def test_operation_at() -> None:
159
161
  a = cirq.NamedQubit('a')
160
162
  b = cirq.NamedQubit('b')
161
163
  c = cirq.NamedQubit('c')
@@ -170,14 +172,14 @@ def test_operation_at():
170
172
  assert cirq.Moment([cirq.CZ(a, b), cirq.X(c)]).operation_at(a) == cirq.CZ(a, b)
171
173
 
172
174
 
173
- def test_from_ops():
175
+ def test_from_ops() -> None:
174
176
  a = cirq.NamedQubit('a')
175
177
  b = cirq.NamedQubit('b')
176
178
 
177
179
  assert cirq.Moment.from_ops(cirq.X(a), cirq.Y(b)) == cirq.Moment(cirq.X(a), cirq.Y(b))
178
180
 
179
181
 
180
- def test_with_operation():
182
+ def test_with_operation() -> None:
181
183
  a = cirq.NamedQubit('a')
182
184
  b = cirq.NamedQubit('b')
183
185
 
@@ -202,7 +204,7 @@ def test_with_operation():
202
204
  _ = cirq.Moment([cirq.X(a), cirq.X(b)]).with_operation(cirq.X(b))
203
205
 
204
206
 
205
- def test_with_operations():
207
+ def test_with_operations() -> None:
206
208
  a = cirq.NamedQubit('a')
207
209
  b = cirq.NamedQubit('b')
208
210
  c = cirq.NamedQubit('c')
@@ -236,7 +238,7 @@ def test_with_operations():
236
238
  _ = cirq.Moment([cirq.X(a), cirq.X(b)]).with_operations(cirq.X(b))
237
239
 
238
240
 
239
- def test_without_operations_touching():
241
+ def test_without_operations_touching() -> None:
240
242
  a = cirq.NamedQubit('a')
241
243
  b = cirq.NamedQubit('b')
242
244
  c = cirq.NamedQubit('c')
@@ -282,14 +284,14 @@ def test_without_operations_touching():
282
284
  )
283
285
 
284
286
 
285
- def test_is_parameterized():
287
+ def test_is_parameterized() -> None:
286
288
  a, b = cirq.LineQubit.range(2)
287
289
  moment = cirq.Moment(cirq.X(a) ** sympy.Symbol('v'), cirq.Y(b) ** sympy.Symbol('w'))
288
290
  assert cirq.is_parameterized(moment)
289
291
  assert not cirq.is_parameterized(cirq.Moment(cirq.X(a), cirq.Y(b)))
290
292
 
291
293
 
292
- def test_resolve_parameters():
294
+ def test_resolve_parameters() -> None:
293
295
  a, b = cirq.LineQubit.range(2)
294
296
  moment = cirq.Moment(cirq.X(a) ** sympy.Symbol('v'), cirq.Y(b) ** sympy.Symbol('w'))
295
297
  resolved_moment = cirq.resolve_parameters(moment, cirq.ParamResolver({'v': 0.1, 'w': 0.2}))
@@ -299,12 +301,13 @@ def test_resolve_parameters():
299
301
  resolved_moment = cirq.resolve_parameters(moment, {'pi': np.pi})
300
302
  assert resolved_moment == cirq.Moment(cirq.Rz(rads=np.pi).on(a))
301
303
  resolved_gate = resolved_moment.operations[0].gate
304
+ assert isinstance(resolved_gate, cirq.Rz)
302
305
  assert not isinstance(resolved_gate.exponent, sympy.Basic)
303
306
  assert isinstance(resolved_gate.exponent, float)
304
307
  assert not cirq.is_parameterized(resolved_moment)
305
308
 
306
309
 
307
- def test_resolve_parameters_no_change():
310
+ def test_resolve_parameters_no_change() -> None:
308
311
  a, b = cirq.LineQubit.range(2)
309
312
  moment = cirq.Moment(cirq.X(a), cirq.Y(b))
310
313
  resolved_moment = cirq.resolve_parameters(moment, cirq.ParamResolver({'v': 0.1, 'w': 0.2}))
@@ -315,14 +318,14 @@ def test_resolve_parameters_no_change():
315
318
  assert resolved_moment is moment
316
319
 
317
320
 
318
- def test_parameter_names():
321
+ def test_parameter_names() -> None:
319
322
  a, b = cirq.LineQubit.range(2)
320
323
  moment = cirq.Moment(cirq.X(a) ** sympy.Symbol('v'), cirq.Y(b) ** sympy.Symbol('w'))
321
324
  assert cirq.parameter_names(moment) == {'v', 'w'}
322
325
  assert cirq.parameter_names(cirq.Moment(cirq.X(a), cirq.Y(b))) == set()
323
326
 
324
327
 
325
- def test_with_measurement_keys():
328
+ def test_with_measurement_keys() -> None:
326
329
  a, b = cirq.LineQubit.range(2)
327
330
  m = cirq.Moment(cirq.measure(a, key='m1'), cirq.measure(b, key='m2'))
328
331
 
@@ -332,7 +335,7 @@ def test_with_measurement_keys():
332
335
  assert new_moment.operations[1] == cirq.measure(b, key='p2')
333
336
 
334
337
 
335
- def test_with_key_path():
338
+ def test_with_key_path() -> None:
336
339
  a, b = cirq.LineQubit.range(2)
337
340
  m = cirq.Moment(cirq.measure(a, key='m1'), cirq.measure(b, key='m2'))
338
341
 
@@ -346,7 +349,7 @@ def test_with_key_path():
346
349
  )
347
350
 
348
351
 
349
- def test_with_key_path_prefix():
352
+ def test_with_key_path_prefix() -> None:
350
353
  a, b, c = cirq.LineQubit.range(3)
351
354
  m = cirq.Moment(cirq.measure(a, key='m1'), cirq.measure(b, key='m2'), cirq.X(c))
352
355
  mb = cirq.with_key_path_prefix(m, ('b',))
@@ -356,7 +359,7 @@ def test_with_key_path_prefix():
356
359
  assert mab.operations[2] is m.operations[2]
357
360
 
358
361
 
359
- def test_copy():
362
+ def test_copy() -> None:
360
363
  a = cirq.NamedQubit('a')
361
364
  b = cirq.NamedQubit('b')
362
365
  original = cirq.Moment([cirq.CZ(a, b)])
@@ -365,7 +368,7 @@ def test_copy():
365
368
  assert id(original) != id(copy)
366
369
 
367
370
 
368
- def test_qubits():
371
+ def test_qubits() -> None:
369
372
  a = cirq.NamedQubit('a')
370
373
  b = cirq.NamedQubit('b')
371
374
 
@@ -374,7 +377,7 @@ def test_qubits():
374
377
  assert cirq.Moment([cirq.CZ(a, b)]).qubits == {a, b}
375
378
 
376
379
 
377
- def test_container_methods():
380
+ def test_container_methods() -> None:
378
381
  a = cirq.NamedQubit('a')
379
382
  b = cirq.NamedQubit('b')
380
383
  m = cirq.Moment([cirq.H(a), cirq.H(b)])
@@ -387,14 +390,14 @@ def test_container_methods():
387
390
  assert len(m) == 2
388
391
 
389
392
 
390
- def test_decompose():
393
+ def test_decompose() -> None:
391
394
  a = cirq.NamedQubit('a')
392
395
  b = cirq.NamedQubit('b')
393
396
  m = cirq.Moment(cirq.X(a), cirq.X(b))
394
397
  assert list(cirq.decompose(m)) == list(m.operations)
395
398
 
396
399
 
397
- def test_measurement_keys():
400
+ def test_measurement_keys() -> None:
398
401
  a = cirq.NamedQubit('a')
399
402
  b = cirq.NamedQubit('b')
400
403
  m = cirq.Moment(cirq.X(a), cirq.X(b))
@@ -407,7 +410,7 @@ def test_measurement_keys():
407
410
  assert cirq.is_measurement(m2)
408
411
 
409
412
 
410
- def test_measurement_key_objs_caching():
413
+ def test_measurement_key_objs_caching() -> None:
411
414
  q0, q1, q2, q3 = cirq.LineQubit.range(4)
412
415
  m = cirq.Moment(cirq.measure(q0, key='foo'))
413
416
  assert m._measurement_key_objs is None
@@ -430,7 +433,7 @@ def test_measurement_key_objs_caching():
430
433
  }
431
434
 
432
435
 
433
- def test_control_keys_caching():
436
+ def test_control_keys_caching() -> None:
434
437
  q0, q1, q2, q3 = cirq.LineQubit.range(4)
435
438
  m = cirq.Moment(cirq.X(q0).with_classical_controls('foo'))
436
439
  assert m._control_keys is None
@@ -452,13 +455,13 @@ def test_control_keys_caching():
452
455
  }
453
456
 
454
457
 
455
- def test_bool():
458
+ def test_bool() -> None:
456
459
  assert not cirq.Moment()
457
460
  a = cirq.NamedQubit('a')
458
461
  assert cirq.Moment([cirq.X(a)])
459
462
 
460
463
 
461
- def test_repr():
464
+ def test_repr() -> None:
462
465
  a = cirq.NamedQubit('a')
463
466
  b = cirq.NamedQubit('b')
464
467
 
@@ -467,14 +470,14 @@ def test_repr():
467
470
  cirq.testing.assert_equivalent_repr(cirq.Moment(cirq.X(a), cirq.Y(b)))
468
471
 
469
472
 
470
- def test_json_dict():
473
+ def test_json_dict() -> None:
471
474
  a = cirq.NamedQubit('a')
472
475
  b = cirq.NamedQubit('b')
473
476
  mom = cirq.Moment([cirq.CZ(a, b)])
474
477
  assert mom._json_dict_() == {'operations': (cirq.CZ(a, b),)}
475
478
 
476
479
 
477
- def test_inverse():
480
+ def test_inverse() -> None:
478
481
  a, b, c = cirq.LineQubit.range(3)
479
482
  m = cirq.Moment([cirq.S(a), cirq.CNOT(b, c)])
480
483
  assert m**1 is m
@@ -485,15 +488,15 @@ def test_inverse():
485
488
  assert cirq.inverse(cirq.Moment([cirq.measure(a)]), default=None) is None
486
489
 
487
490
 
488
- def test_immutable_moment():
491
+ def test_immutable_moment() -> None:
489
492
  with pytest.raises(AttributeError):
490
493
  q1, q2 = cirq.LineQubit.range(2)
491
494
  circuit = cirq.Circuit(cirq.X(q1))
492
495
  moment = circuit.moments[0]
493
- moment.operations += (cirq.Y(q2),)
496
+ moment.operations += (cirq.Y(q2),) # type: ignore[misc]
494
497
 
495
498
 
496
- def test_add():
499
+ def test_add() -> None:
497
500
  a, b, c = cirq.LineQubit.range(3)
498
501
  expected_circuit = cirq.Circuit([cirq.CNOT(a, b), cirq.X(a), cirq.Y(b)])
499
502
 
@@ -518,7 +521,7 @@ def test_add():
518
521
  assert m1 + [] is m1
519
522
 
520
523
 
521
- def test_sub():
524
+ def test_sub() -> None:
522
525
  a, b, c = cirq.LineQubit.range(3)
523
526
  m = cirq.Moment(cirq.X(a), cirq.Y(b))
524
527
  assert m - [] == m
@@ -537,7 +540,7 @@ def test_sub():
537
540
  assert m2 - cirq.Y(b) == cirq.Moment(cirq.X(a), cirq.Z(c))
538
541
 
539
542
 
540
- def test_op_tree():
543
+ def test_op_tree() -> None:
541
544
  eq = cirq.testing.EqualsTester()
542
545
  a, b = cirq.LineQubit.range(2)
543
546
 
@@ -550,7 +553,7 @@ def test_op_tree():
550
553
  eq.add_equality_group(cirq.Moment(cirq.X(a), cirq.Y(b)), cirq.Moment([cirq.X(a), cirq.Y(b)]))
551
554
 
552
555
 
553
- def test_indexes_by_qubit():
556
+ def test_indexes_by_qubit() -> None:
554
557
  a, b, c = cirq.LineQubit.range(3)
555
558
  moment = cirq.Moment([cirq.H(a), cirq.CNOT(b, c)])
556
559
 
@@ -559,7 +562,7 @@ def test_indexes_by_qubit():
559
562
  assert moment[c] == cirq.CNOT(b, c)
560
563
 
561
564
 
562
- def test_throws_when_indexed_by_unused_qubit():
565
+ def test_throws_when_indexed_by_unused_qubit() -> None:
563
566
  a, b = cirq.LineQubit.range(2)
564
567
  moment = cirq.Moment([cirq.H(a)])
565
568
 
@@ -567,7 +570,7 @@ def test_throws_when_indexed_by_unused_qubit():
567
570
  _ = moment[b]
568
571
 
569
572
 
570
- def test_indexes_by_list_of_qubits():
573
+ def test_indexes_by_list_of_qubits() -> None:
571
574
  q = cirq.LineQubit.range(4)
572
575
  moment = cirq.Moment([cirq.Z(q[0]), cirq.CNOT(q[1], q[2])])
573
576
 
@@ -582,7 +585,11 @@ def test_indexes_by_list_of_qubits():
582
585
  assert moment[q] == moment
583
586
 
584
587
 
585
- def test_moment_text_diagram():
588
+ def test_moment_text_diagram() -> None:
589
+ a: cirq.Qid
590
+ b: cirq.Qid
591
+ c: cirq.Qid
592
+ d: cirq.Qid
586
593
  a, b, c, d = cirq.GridQubit.rect(2, 2)
587
594
  m = cirq.Moment(cirq.CZ(a, b), cirq.CNOT(c, d))
588
595
  assert (
@@ -672,7 +679,7 @@ aa │
672
679
  )
673
680
 
674
681
 
675
- def test_text_diagram_does_not_depend_on_insertion_order():
682
+ def test_text_diagram_does_not_depend_on_insertion_order() -> None:
676
683
  q = cirq.LineQubit.range(4)
677
684
  ops = [cirq.CNOT(q[0], q[3]), cirq.CNOT(q[1], q[2])]
678
685
  m1, m2 = cirq.Moment(ops), cirq.Moment(ops[::-1])
@@ -680,7 +687,7 @@ def test_text_diagram_does_not_depend_on_insertion_order():
680
687
  assert str(m1) == str(m2)
681
688
 
682
689
 
683
- def test_commutes_moment_and_operation():
690
+ def test_commutes_moment_and_operation() -> None:
684
691
  a = cirq.NamedQubit('a')
685
692
  b = cirq.NamedQubit('b')
686
693
  c = cirq.NamedQubit('c')
@@ -710,7 +717,7 @@ def test_commutes_moment_and_operation():
710
717
  assert cirq.commutes(moment, cirq.XX(a, b))
711
718
 
712
719
 
713
- def test_commutes_moment_and_moment():
720
+ def test_commutes_moment_and_moment() -> None:
714
721
  a = cirq.NamedQubit('a')
715
722
  b = cirq.NamedQubit('b')
716
723
  c = cirq.NamedQubit('c')
@@ -731,7 +738,7 @@ def test_commutes_moment_and_moment():
731
738
  )
732
739
 
733
740
 
734
- def test_commutes_moment_with_controls():
741
+ def test_commutes_moment_with_controls() -> None:
735
742
  a, b = cirq.LineQubit.range(2)
736
743
  assert cirq.commutes(
737
744
  cirq.Moment(cirq.measure(a, key='k0')), cirq.Moment(cirq.X(b).with_classical_controls('k1'))
@@ -759,7 +766,7 @@ def test_commutes_moment_with_controls():
759
766
  )
760
767
 
761
768
 
762
- def test_commutes_moment_and_moment_comprehensive():
769
+ def test_commutes_moment_and_moment_comprehensive() -> None:
763
770
  a, b, c, d = cirq.LineQubit.range(4)
764
771
 
765
772
  # Basic Z⊗Z commuting with XX at different angles
@@ -788,7 +795,7 @@ def test_commutes_moment_and_moment_comprehensive():
788
795
  assert not cirq.commutes(m1, m2) # Z⊗Z⊗Z doesn't commute with XX⊗X
789
796
 
790
797
 
791
- def test_commutes_handles_non_unitary_operation():
798
+ def test_commutes_handles_non_unitary_operation() -> None:
792
799
  a = cirq.NamedQubit('a')
793
800
  op_damp_a = cirq.AmplitudeDampingChannel(gamma=0.1).on(a)
794
801
  assert cirq.commutes(cirq.Moment(cirq.X(a)), op_damp_a, default=None) is None
@@ -796,7 +803,7 @@ def test_commutes_handles_non_unitary_operation():
796
803
  assert cirq.commutes(cirq.Moment(op_damp_a), cirq.Moment(op_damp_a))
797
804
 
798
805
 
799
- def test_transform_qubits():
806
+ def test_transform_qubits() -> None:
800
807
  a, b = cirq.LineQubit.range(2)
801
808
  x, y = cirq.GridQubit.rect(2, 1, 10, 20)
802
809
 
@@ -804,12 +811,17 @@ def test_transform_qubits():
804
811
  modified = cirq.Moment([cirq.X(x), cirq.Y(y)])
805
812
 
806
813
  assert original.transform_qubits({a: x, b: y}) == modified
807
- assert original.transform_qubits(lambda q: cirq.GridQubit(10 + q.x, 20)) == modified
814
+ assert (
815
+ original.transform_qubits(
816
+ lambda q: cirq.GridQubit(10 + q.x, 20) # type: ignore[attr-defined]
817
+ )
818
+ == modified
819
+ )
808
820
  with pytest.raises(TypeError, match='must be a function or dict'):
809
- _ = original.transform_qubits('bad arg')
821
+ _ = original.transform_qubits('bad arg') # type: ignore[arg-type]
810
822
 
811
823
 
812
- def test_expand_to():
824
+ def test_expand_to() -> None:
813
825
  a, b = cirq.LineQubit.range(2)
814
826
  m1 = cirq.Moment(cirq.H(a))
815
827
  m2 = m1.expand_to({a})
@@ -824,7 +836,7 @@ def test_expand_to():
824
836
  _ = m1.expand_to({b})
825
837
 
826
838
 
827
- def test_kraus():
839
+ def test_kraus() -> None:
828
840
  I = np.eye(2)
829
841
  X = np.array([[0, 1], [1, 0]])
830
842
  Y = np.array([[0, -1j], [1j, 0]])
@@ -872,7 +884,7 @@ def test_kraus():
872
884
  assert np.allclose(k[3], np.sqrt(p * q) * np.kron(X, Z))
873
885
 
874
886
 
875
- def test_kraus_too_big():
887
+ def test_kraus_too_big() -> None:
876
888
  m = cirq.Moment(cirq.IdentityGate(11).on(*cirq.LineQubit.range(11)))
877
889
  assert not cirq.has_kraus(m)
878
890
  assert not m._has_superoperator_()
@@ -881,7 +893,7 @@ def test_kraus_too_big():
881
893
  assert cirq.kraus(m, default=None) is None
882
894
 
883
895
 
884
- def test_op_has_no_kraus():
896
+ def test_op_has_no_kraus() -> None:
885
897
  class EmptyGate(cirq.testing.SingleQubitGate):
886
898
  pass
887
899
 
@@ -893,7 +905,7 @@ def test_op_has_no_kraus():
893
905
  assert cirq.kraus(m, default=None) is None
894
906
 
895
907
 
896
- def test_superoperator():
908
+ def test_superoperator() -> None:
897
909
  cnot = cirq.unitary(cirq.CNOT)
898
910
 
899
911
  a, b = cirq.LineQubit.range(2)
@@ -927,3 +939,68 @@ def test_superoperator():
927
939
  assert m._has_superoperator_()
928
940
  s = m._superoperator_()
929
941
  assert np.allclose(s, np.array([[1, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0], [1, 0, 0, 1]]) / 2)
942
+
943
+
944
+ def test_moment_with_tags() -> None:
945
+ q0 = cirq.LineQubit(0)
946
+ q1 = cirq.LineQubit(1)
947
+ op1 = cirq.X(q0)
948
+ op2 = cirq.Y(q1)
949
+
950
+ # Test initialization with no tags
951
+ moment_no_tags = cirq.Moment(op1)
952
+ assert moment_no_tags.tags == ()
953
+
954
+ # Test initialization with tags
955
+ moment_with_tags = cirq.Moment(op1, op2, tags=("initial_tag_1", "initial_tag_2"))
956
+ assert moment_with_tags.tags == ("initial_tag_1", "initial_tag_2")
957
+
958
+ # Test with_tags method to add new tags
959
+ new_moment = moment_with_tags.with_tags("new_tag_1", "new_tag_2")
960
+
961
+ # Ensure the original moment's tags are unchanged
962
+ assert moment_with_tags.tags == ("initial_tag_1", "initial_tag_2")
963
+
964
+ # Ensure the new moment has both old and new tags
965
+ assert new_moment.tags == ("initial_tag_1", "initial_tag_2", "new_tag_1", "new_tag_2")
966
+
967
+ # Test with_tags on a moment that initially had no tags
968
+ new_moment_from_no_tags = moment_no_tags.with_tags("single_new_tag")
969
+ assert new_moment_from_no_tags.tags == ("single_new_tag",)
970
+
971
+ # Test adding no new tags
972
+ same_moment_tags = moment_with_tags.with_tags()
973
+ assert same_moment_tags.tags == ("initial_tag_1", "initial_tag_2")
974
+
975
+ class CustomTag:
976
+ """Example Hashable Tag"""
977
+
978
+ def __init__(self, value):
979
+ self.value = value
980
+
981
+ def __hash__(self):
982
+ return hash(self.value) # pragma: nocover
983
+
984
+ def __eq__(self, other):
985
+ return isinstance(other, CustomTag) and self.value == other.value # pragma: nocover
986
+
987
+ def __repr__(self):
988
+ return f"CustomTag({self.value})" # pragma: nocover
989
+
990
+ tag_obj = CustomTag("complex_tag")
991
+ moment_with_custom_tag = cirq.Moment(op1, tags=("string_tag", 123, tag_obj))
992
+ assert moment_with_custom_tag.tags == ("string_tag", 123, tag_obj)
993
+
994
+ new_moment_with_custom_tag = moment_with_custom_tag.with_tags(456)
995
+ assert new_moment_with_custom_tag.tags == ("string_tag", 123, tag_obj, 456)
996
+
997
+ # Test that tags are dropped if the Moment is changed.
998
+ moment = cirq.Moment.from_ops(op1, tags=(tag_obj,))
999
+ assert moment.tags == (tag_obj,)
1000
+ assert moment.with_operation(op2).tags == ()
1001
+ assert moment.with_operations(op2).tags == ()
1002
+ assert moment.without_operations_touching([q0]).tags == ()
1003
+
1004
+ # Test that tags are retained if the Moment is unchanged.
1005
+ assert moment.with_operations().tags == (tag_obj,)
1006
+ assert moment.without_operations_touching([q1]).tags == (tag_obj,)
@@ -18,7 +18,7 @@ from __future__ import annotations
18
18
 
19
19
  import abc
20
20
  from collections import defaultdict
21
- from typing import Callable, cast, Dict, Iterable, Optional, Sequence, Tuple, TYPE_CHECKING
21
+ from typing import Callable, cast, Iterable, Sequence, TYPE_CHECKING
22
22
 
23
23
  from cirq import ops
24
24
 
@@ -106,7 +106,7 @@ class PointOptimizer:
106
106
  @abc.abstractmethod
107
107
  def optimization_at(
108
108
  self, circuit: cirq.Circuit, index: int, op: cirq.Operation
109
- ) -> Optional[cirq.PointOptimizationSummary]:
109
+ ) -> cirq.PointOptimizationSummary | None:
110
110
  """Describes how to change operations near the given location.
111
111
 
112
112
  For example, this method could realize that the given operation is an
@@ -126,8 +126,8 @@ class PointOptimizer:
126
126
  change should be made.
127
127
  """
128
128
 
129
- def optimize_circuit(self, circuit: cirq.Circuit):
130
- frontier: Dict[cirq.Qid, int] = defaultdict(lambda: 0)
129
+ def optimize_circuit(self, circuit: cirq.Circuit) -> None:
130
+ frontier: dict[cirq.Qid, int] = defaultdict(lambda: 0)
131
131
  i = 0
132
132
  while i < len(circuit): # Note: circuit may mutate as we go.
133
133
  for op in circuit[i].operations:
@@ -150,7 +150,7 @@ class PointOptimizer:
150
150
  circuit.clear_operations_touching(
151
151
  opt.clear_qubits, [e for e in range(i, i + opt.clear_span)]
152
152
  )
153
- new_operations = self.post_clean_up(cast(Tuple[ops.Operation], opt.new_operations))
153
+ new_operations = self.post_clean_up(cast(tuple[ops.Operation], opt.new_operations))
154
154
 
155
155
  flat_new_operations = tuple(ops.flatten_to_ops(new_operations))
156
156
 
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import List, Optional, Set
15
+ from __future__ import annotations
16
16
 
17
17
  import pytest
18
18
 
@@ -21,7 +21,7 @@ from cirq import Operation, PointOptimizationSummary, PointOptimizer
21
21
  from cirq.testing import EqualsTester
22
22
 
23
23
 
24
- def test_equality():
24
+ def test_equality() -> None:
25
25
  a = cirq.NamedQubit('a')
26
26
  b = cirq.NamedQubit('b')
27
27
  xa = cirq.X(a)
@@ -62,7 +62,7 @@ class ReplaceWithXGates(PointOptimizer):
62
62
 
63
63
  def optimization_at(
64
64
  self, circuit: cirq.Circuit, index: int, op: cirq.Operation
65
- ) -> Optional[cirq.PointOptimizationSummary]:
65
+ ) -> cirq.PointOptimizationSummary | None:
66
66
  end = index + 1
67
67
  new_ops = [cirq.X(q) for q in op.qubits]
68
68
  done = False
@@ -70,8 +70,8 @@ class ReplaceWithXGates(PointOptimizer):
70
70
  n = circuit.next_moment_operating_on(op.qubits, end)
71
71
  if n is None:
72
72
  break
73
- next_ops: Set[Optional[Operation]] = {circuit.operation_at(q, n) for q in op.qubits}
74
- next_ops_list: List[Operation] = [e for e in next_ops if e]
73
+ next_ops: set[Operation | None] = {circuit.operation_at(q, n) for q in op.qubits}
74
+ next_ops_list: list[Operation] = [e for e in next_ops if e]
75
75
  next_ops_sorted = sorted(next_ops_list, key=lambda e: str(e.qubits))
76
76
  for next_op in next_ops_sorted:
77
77
  if next_op:
@@ -86,7 +86,7 @@ class ReplaceWithXGates(PointOptimizer):
86
86
  )
87
87
 
88
88
 
89
- def test_point_optimizer_can_write_new_gates_inline():
89
+ def test_point_optimizer_can_write_new_gates_inline() -> None:
90
90
  x = cirq.NamedQubit('x')
91
91
  y = cirq.NamedQubit('y')
92
92
  z = cirq.NamedQubit('z')
@@ -116,7 +116,7 @@ z: ───────────────────X───X───
116
116
  assert actual_text_diagram == expected_text_diagram
117
117
 
118
118
 
119
- def test_point_optimizer_post_clean_up():
119
+ def test_point_optimizer_post_clean_up() -> None:
120
120
  x = cirq.NamedQubit('x')
121
121
  y = cirq.NamedQubit('y')
122
122
  z = cirq.NamedQubit('z')
@@ -150,13 +150,13 @@ z: ─────────────────────────
150
150
  assert actual_text_diagram == expected_text_diagram
151
151
 
152
152
 
153
- def test_point_optimizer_raises_on_gates_changing_qubits():
153
+ def test_point_optimizer_raises_on_gates_changing_qubits() -> None:
154
154
  class EverythingIs42(cirq.PointOptimizer):
155
155
  """Changes all single qubit operations to act on LineQubit(42)"""
156
156
 
157
157
  def optimization_at(
158
158
  self, circuit: cirq.Circuit, index: int, op: cirq.Operation
159
- ) -> Optional[cirq.PointOptimizationSummary]:
159
+ ) -> cirq.PointOptimizationSummary | None:
160
160
  new_op = op
161
161
  if len(op.qubits) == 1 and isinstance(op, cirq.GateOperation):
162
162
  new_op = op.gate(cirq.LineQubit(42))
@@ -171,7 +171,7 @@ def test_point_optimizer_raises_on_gates_changing_qubits():
171
171
  EverythingIs42().optimize_circuit(c)
172
172
 
173
173
 
174
- def test_repr():
174
+ def test_repr() -> None:
175
175
  assert (
176
176
  repr(cirq.PointOptimizationSummary(clear_span=0, clear_qubits=[], new_operations=[]))
177
177
  == 'cirq.PointOptimizationSummary(0, (), ())'