cirq-core 1.6.0.dev20250520054601__py3-none-any.whl → 1.6.0.dev20250520181654__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 (289) hide show
  1. cirq/_compat.py +15 -17
  2. cirq/_compat_test.py +6 -9
  3. cirq/_doc.py +2 -2
  4. cirq/_import.py +6 -6
  5. cirq/_version.py +1 -1
  6. cirq/_version_test.py +1 -1
  7. cirq/circuits/_block_diagram_drawer.py +9 -10
  8. cirq/circuits/_box_drawing_character_data.py +6 -8
  9. cirq/circuits/_bucket_priority_queue.py +7 -7
  10. cirq/circuits/circuit.py +118 -125
  11. cirq/circuits/circuit_operation.py +38 -52
  12. cirq/circuits/circuit_test.py +4 -4
  13. cirq/circuits/frozen_circuit.py +13 -23
  14. cirq/circuits/moment.py +23 -29
  15. cirq/circuits/optimization_pass.py +4 -4
  16. cirq/circuits/optimization_pass_test.py +4 -6
  17. cirq/circuits/qasm_output.py +11 -11
  18. cirq/circuits/text_diagram_drawer.py +21 -36
  19. cirq/contrib/acquaintance/bipartite.py +5 -8
  20. cirq/contrib/acquaintance/executor.py +5 -5
  21. cirq/contrib/acquaintance/executor_test.py +3 -3
  22. cirq/contrib/acquaintance/gates.py +16 -26
  23. cirq/contrib/acquaintance/gates_test.py +3 -3
  24. cirq/contrib/acquaintance/mutation_utils.py +4 -4
  25. cirq/contrib/acquaintance/optimizers.py +4 -4
  26. cirq/contrib/acquaintance/permutation.py +15 -27
  27. cirq/contrib/acquaintance/shift.py +3 -3
  28. cirq/contrib/acquaintance/shift_swap_network.py +4 -4
  29. cirq/contrib/acquaintance/strategies/cubic.py +2 -2
  30. cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
  31. cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
  32. cirq/contrib/circuitdag/circuit_dag.py +2 -2
  33. cirq/contrib/custom_simulators/custom_state_simulator.py +3 -3
  34. cirq/contrib/custom_simulators/custom_state_simulator_test.py +4 -4
  35. cirq/contrib/graph_device/graph_device.py +5 -5
  36. cirq/contrib/graph_device/hypergraph.py +12 -12
  37. cirq/contrib/graph_device/uniform_graph_device.py +4 -4
  38. cirq/contrib/paulistring/clifford_optimize.py +2 -2
  39. cirq/contrib/paulistring/clifford_target_gateset.py +7 -7
  40. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +31 -31
  41. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +23 -23
  42. cirq/contrib/paulistring/recombine.py +3 -3
  43. cirq/contrib/paulistring/separate.py +2 -2
  44. cirq/contrib/qasm_import/_parser.py +20 -32
  45. cirq/contrib/qcircuit/qcircuit_diagram_info.py +3 -5
  46. cirq/contrib/quantum_volume/quantum_volume.py +24 -24
  47. cirq/contrib/quimb/density_matrix.py +12 -14
  48. cirq/contrib/quimb/mps_simulator.py +20 -20
  49. cirq/contrib/quimb/state_vector.py +6 -10
  50. cirq/contrib/quirk/export_to_quirk.py +3 -3
  51. cirq/contrib/quirk/quirk_gate.py +15 -15
  52. cirq/contrib/routing/device.py +3 -3
  53. cirq/contrib/routing/greedy.py +10 -21
  54. cirq/contrib/routing/initialization.py +2 -2
  55. cirq/contrib/routing/swap_network.py +3 -3
  56. cirq/contrib/routing/utils.py +2 -2
  57. cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +8 -8
  58. cirq/contrib/svg/svg.py +3 -3
  59. cirq/devices/grid_device_metadata.py +10 -10
  60. cirq/devices/grid_qubit.py +20 -20
  61. cirq/devices/insertion_noise_model.py +5 -5
  62. cirq/devices/line_qubit.py +13 -13
  63. cirq/devices/named_topologies.py +18 -29
  64. cirq/devices/noise_model.py +3 -3
  65. cirq/devices/noise_properties.py +2 -2
  66. cirq/devices/noise_properties_test.py +1 -3
  67. cirq/devices/noise_utils.py +7 -7
  68. cirq/devices/superconducting_qubits_noise_properties.py +21 -21
  69. cirq/devices/superconducting_qubits_noise_properties_test.py +5 -7
  70. cirq/devices/thermal_noise_model.py +14 -14
  71. cirq/devices/unconstrained_device.py +2 -2
  72. cirq/experiments/benchmarking/parallel_xeb.py +29 -31
  73. cirq/experiments/n_qubit_tomography.py +5 -7
  74. cirq/experiments/qubit_characterizations.py +29 -40
  75. cirq/experiments/qubit_characterizations_test.py +1 -1
  76. cirq/experiments/random_quantum_circuit_generation.py +19 -33
  77. cirq/experiments/random_quantum_circuit_generation_test.py +6 -6
  78. cirq/experiments/readout_confusion_matrix.py +14 -14
  79. cirq/experiments/single_qubit_readout_calibration.py +12 -12
  80. cirq/experiments/t2_decay_experiment.py +7 -7
  81. cirq/experiments/two_qubit_xeb.py +32 -32
  82. cirq/experiments/two_qubit_xeb_test.py +5 -5
  83. cirq/experiments/xeb_fitting.py +25 -25
  84. cirq/experiments/xeb_sampling.py +22 -33
  85. cirq/experiments/xeb_simulation.py +5 -5
  86. cirq/experiments/xeb_simulation_test.py +3 -3
  87. cirq/experiments/z_phase_calibration.py +19 -19
  88. cirq/interop/quirk/cells/arithmetic_cells.py +23 -36
  89. cirq/interop/quirk/cells/cell.py +9 -21
  90. cirq/interop/quirk/cells/composite_cell.py +7 -22
  91. cirq/interop/quirk/cells/control_cells.py +8 -8
  92. cirq/interop/quirk/cells/input_cells.py +4 -4
  93. cirq/interop/quirk/cells/input_rotation_cells.py +5 -5
  94. cirq/interop/quirk/cells/parse.py +20 -23
  95. cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -3
  96. cirq/interop/quirk/cells/swap_cell.py +3 -3
  97. cirq/interop/quirk/cells/testing.py +5 -7
  98. cirq/interop/quirk/url_to_circuit.py +17 -33
  99. cirq/json_resolver_cache.py +6 -6
  100. cirq/linalg/decompositions.py +20 -31
  101. cirq/linalg/diagonalize.py +4 -4
  102. cirq/linalg/diagonalize_test.py +3 -4
  103. cirq/linalg/operator_spaces.py +5 -5
  104. cirq/linalg/predicates.py +7 -7
  105. cirq/linalg/transformations.py +20 -20
  106. cirq/ops/arithmetic_operation.py +13 -15
  107. cirq/ops/boolean_hamiltonian.py +17 -17
  108. cirq/ops/classically_controlled_operation.py +13 -25
  109. cirq/ops/clifford_gate.py +31 -35
  110. cirq/ops/clifford_gate_test.py +2 -3
  111. cirq/ops/common_channels.py +30 -32
  112. cirq/ops/common_gates.py +64 -74
  113. cirq/ops/control_values.py +12 -12
  114. cirq/ops/controlled_gate.py +15 -30
  115. cirq/ops/controlled_gate_test.py +5 -5
  116. cirq/ops/controlled_operation.py +12 -25
  117. cirq/ops/controlled_operation_test.py +5 -5
  118. cirq/ops/dense_pauli_string.py +23 -34
  119. cirq/ops/dense_pauli_string_test.py +1 -2
  120. cirq/ops/diagonal_gate.py +9 -20
  121. cirq/ops/diagonal_gate_test.py +1 -3
  122. cirq/ops/eigen_gate.py +11 -23
  123. cirq/ops/eigen_gate_test.py +6 -8
  124. cirq/ops/fourier_transform.py +5 -5
  125. cirq/ops/fsim_gate.py +14 -14
  126. cirq/ops/gate_operation.py +23 -44
  127. cirq/ops/gateset.py +23 -37
  128. cirq/ops/gateset_test.py +2 -2
  129. cirq/ops/global_phase_op.py +8 -10
  130. cirq/ops/greedy_qubit_manager.py +6 -6
  131. cirq/ops/identity.py +9 -9
  132. cirq/ops/kraus_channel.py +7 -7
  133. cirq/ops/linear_combinations.py +29 -48
  134. cirq/ops/matrix_gates.py +8 -8
  135. cirq/ops/measure_util.py +13 -14
  136. cirq/ops/measurement_gate.py +18 -29
  137. cirq/ops/mixed_unitary_channel.py +8 -8
  138. cirq/ops/named_qubit.py +10 -10
  139. cirq/ops/op_tree.py +7 -7
  140. cirq/ops/parallel_gate.py +5 -5
  141. cirq/ops/parity_gates.py +14 -14
  142. cirq/ops/pauli_gates.py +8 -10
  143. cirq/ops/pauli_interaction_gate.py +6 -6
  144. cirq/ops/pauli_measurement_gate.py +11 -23
  145. cirq/ops/pauli_string.py +35 -52
  146. cirq/ops/pauli_string_phasor.py +4 -14
  147. cirq/ops/pauli_string_raw_types.py +3 -3
  148. cirq/ops/pauli_sum_exponential.py +2 -2
  149. cirq/ops/permutation_gate.py +4 -4
  150. cirq/ops/phased_iswap_gate.py +9 -9
  151. cirq/ops/phased_x_gate.py +10 -10
  152. cirq/ops/phased_x_z_gate.py +11 -11
  153. cirq/ops/projector.py +6 -6
  154. cirq/ops/qubit_manager.py +6 -6
  155. cirq/ops/qubit_order.py +3 -3
  156. cirq/ops/random_gate_channel.py +4 -4
  157. cirq/ops/raw_types.py +48 -70
  158. cirq/ops/state_preparation_channel.py +3 -3
  159. cirq/ops/swap_gates.py +9 -9
  160. cirq/ops/tags.py +2 -4
  161. cirq/ops/three_qubit_gates.py +20 -38
  162. cirq/ops/two_qubit_diagonal_gate.py +5 -5
  163. cirq/ops/uniform_superposition_gate.py +2 -2
  164. cirq/ops/wait_gate.py +5 -5
  165. cirq/protocols/act_on_protocol_test.py +3 -3
  166. cirq/protocols/apply_channel_protocol.py +8 -14
  167. cirq/protocols/apply_mixture_protocol.py +14 -16
  168. cirq/protocols/apply_mixture_protocol_test.py +5 -6
  169. cirq/protocols/apply_unitary_protocol.py +17 -19
  170. cirq/protocols/circuit_diagram_info_protocol.py +19 -30
  171. cirq/protocols/decompose_protocol.py +30 -34
  172. cirq/protocols/inverse_protocol.py +7 -7
  173. cirq/protocols/json_serialization.py +32 -51
  174. cirq/protocols/json_serialization_test.py +9 -10
  175. cirq/protocols/kraus_protocol.py +4 -4
  176. cirq/protocols/kraus_protocol_test.py +3 -3
  177. cirq/protocols/measurement_key_protocol.py +11 -13
  178. cirq/protocols/mixture_protocol.py +4 -4
  179. cirq/protocols/qasm.py +11 -13
  180. cirq/protocols/qid_shape_protocol.py +6 -8
  181. cirq/qis/clifford_tableau.py +12 -12
  182. cirq/qis/measures.py +7 -7
  183. cirq/qis/quantum_state_representation.py +3 -3
  184. cirq/qis/states.py +51 -51
  185. cirq/sim/classical_simulator.py +10 -10
  186. cirq/sim/clifford/clifford_simulator.py +6 -6
  187. cirq/sim/clifford/clifford_tableau_simulation_state_test.py +1 -3
  188. cirq/sim/clifford/stabilizer_sampler.py +4 -4
  189. cirq/sim/clifford/stabilizer_state_ch_form.py +3 -3
  190. cirq/sim/density_matrix_simulation_state.py +15 -15
  191. cirq/sim/density_matrix_simulator.py +11 -11
  192. cirq/sim/density_matrix_utils.py +9 -9
  193. cirq/sim/mux.py +9 -9
  194. cirq/sim/simulation_product_state.py +9 -9
  195. cirq/sim/simulation_product_state_test.py +2 -2
  196. cirq/sim/simulation_state.py +14 -27
  197. cirq/sim/simulation_state_base.py +8 -24
  198. cirq/sim/simulation_utils.py +3 -4
  199. cirq/sim/simulator.py +28 -43
  200. cirq/sim/simulator_base.py +12 -25
  201. cirq/sim/simulator_base_test.py +6 -6
  202. cirq/sim/simulator_test.py +7 -7
  203. cirq/sim/sparse_simulator.py +8 -8
  204. cirq/sim/state_vector.py +8 -8
  205. cirq/sim/state_vector_simulation_state.py +17 -17
  206. cirq/sim/state_vector_simulator.py +4 -4
  207. cirq/study/flatten_expressions.py +12 -14
  208. cirq/study/resolver.py +9 -11
  209. cirq/study/result.py +11 -24
  210. cirq/study/sweepable.py +5 -5
  211. cirq/study/sweeps.py +27 -40
  212. cirq/testing/circuit_compare.py +5 -5
  213. cirq/testing/consistent_controlled_gate_op_test.py +7 -11
  214. cirq/testing/consistent_protocols.py +10 -10
  215. cirq/testing/consistent_protocols_test.py +7 -7
  216. cirq/testing/consistent_qasm.py +4 -4
  217. cirq/testing/consistent_qasm_test.py +2 -3
  218. cirq/testing/devices.py +4 -5
  219. cirq/testing/equals_tester.py +2 -2
  220. cirq/testing/equivalent_basis_map.py +4 -4
  221. cirq/testing/equivalent_repr_eval.py +3 -3
  222. cirq/testing/json.py +14 -14
  223. cirq/testing/logs.py +3 -3
  224. cirq/testing/no_identifier_qubit.py +2 -3
  225. cirq/testing/random_circuit.py +7 -7
  226. cirq/testing/random_circuit_test.py +3 -3
  227. cirq/transformers/analytical_decompositions/clifford_decomposition.py +16 -16
  228. cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +13 -13
  229. cirq/transformers/analytical_decompositions/cphase_to_fsim.py +5 -5
  230. cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +3 -3
  231. cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +3 -3
  232. cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +4 -4
  233. cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +6 -7
  234. cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +2 -2
  235. cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +7 -7
  236. cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +4 -4
  237. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +7 -7
  238. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +11 -11
  239. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +5 -5
  240. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +14 -14
  241. cirq/transformers/dynamical_decoupling.py +13 -13
  242. cirq/transformers/dynamical_decoupling_test.py +4 -4
  243. cirq/transformers/eject_phased_paulis.py +16 -16
  244. cirq/transformers/eject_z.py +5 -7
  245. cirq/transformers/gauge_compiling/gauge_compiling.py +38 -38
  246. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -2
  247. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +8 -8
  248. cirq/transformers/insertion_sort.py +5 -5
  249. cirq/transformers/measurement_transformers.py +14 -14
  250. cirq/transformers/merge_k_qubit_gates_test.py +1 -3
  251. cirq/transformers/merge_single_qubit_gates_test.py +1 -3
  252. cirq/transformers/qubit_management_transformers.py +5 -5
  253. cirq/transformers/routing/initial_mapper.py +4 -4
  254. cirq/transformers/routing/line_initial_mapper.py +9 -9
  255. cirq/transformers/routing/mapping_manager.py +7 -7
  256. cirq/transformers/routing/route_circuit_cqc.py +27 -27
  257. cirq/transformers/routing/visualize_routed_circuit.py +4 -4
  258. cirq/transformers/stratify.py +8 -8
  259. cirq/transformers/synchronize_terminal_measurements.py +6 -6
  260. cirq/transformers/target_gatesets/compilation_target_gateset.py +8 -8
  261. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -2
  262. cirq/transformers/target_gatesets/cz_gateset.py +4 -4
  263. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +5 -5
  264. cirq/transformers/transformer_api.py +11 -26
  265. cirq/transformers/transformer_primitives.py +24 -36
  266. cirq/transformers/transformer_primitives_test.py +3 -3
  267. cirq/value/classical_data.py +18 -18
  268. cirq/value/condition.py +8 -8
  269. cirq/value/digits.py +7 -7
  270. cirq/value/duration.py +12 -12
  271. cirq/value/linear_dict.py +8 -12
  272. cirq/value/measurement_key.py +8 -8
  273. cirq/value/product_state.py +9 -9
  274. cirq/value/value_equality_attr.py +4 -4
  275. cirq/vis/heatmap.py +23 -35
  276. cirq/work/collector.py +9 -17
  277. cirq/work/observable_grouping.py +4 -7
  278. cirq/work/observable_measurement.py +29 -41
  279. cirq/work/observable_measurement_data.py +14 -14
  280. cirq/work/observable_measurement_test.py +2 -2
  281. cirq/work/observable_settings.py +9 -10
  282. cirq/work/pauli_sum_collector.py +5 -5
  283. cirq/work/sampler.py +17 -17
  284. cirq/work/zeros_sampler.py +3 -3
  285. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/METADATA +1 -1
  286. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/RECORD +289 -289
  287. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/WHEEL +1 -1
  288. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/licenses/LICENSE +0 -0
  289. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Sequence, Tuple, Union
17
+ from typing import Sequence
18
18
 
19
19
  import numpy as np
20
20
  import pytest
@@ -34,8 +34,8 @@ def assert_sim_eq(circuit1: cirq.AbstractCircuit, circuit2: cirq.AbstractCircuit
34
34
 
35
35
  def assert_dd(
36
36
  input_circuit: cirq.AbstractCircuit,
37
- expected_circuit: Union[str, cirq.AbstractCircuit],
38
- schema: Union[str, Tuple[cirq.Gate, ...]] = 'DEFAULT',
37
+ expected_circuit: str | cirq.AbstractCircuit,
38
+ schema: str | tuple[cirq.Gate, ...] = 'DEFAULT',
39
39
  single_qubit_gate_moments_only: bool = True,
40
40
  ):
41
41
  transformed_circuit = add_dynamical_decoupling(
@@ -254,7 +254,7 @@ def test_pull_through_h_gate_case2(single_qubit_gate_moments_only: bool):
254
254
  ),
255
255
  ],
256
256
  )
257
- def test_invalid_dd_schema(schema: Union[str, Tuple[cirq.Gate, ...]], error_msg_regex):
257
+ def test_invalid_dd_schema(schema: str | tuple[cirq.Gate, ...], error_msg_regex):
258
258
  a = cirq.NamedQubit('a')
259
259
  input_circuit = cirq.Circuit(cirq.H(a))
260
260
  with pytest.raises(ValueError, match=error_msg_regex):
@@ -16,7 +16,7 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import cast, Dict, Iterable, Iterator, Optional, Tuple, TYPE_CHECKING, Union
19
+ from typing import cast, Iterable, Iterator, TYPE_CHECKING
20
20
 
21
21
  import numpy as np
22
22
  import sympy
@@ -33,7 +33,7 @@ if TYPE_CHECKING:
33
33
  def eject_phased_paulis(
34
34
  circuit: cirq.AbstractCircuit,
35
35
  *,
36
- context: Optional[cirq.TransformerContext] = None,
36
+ context: cirq.TransformerContext | None = None,
37
37
  atol: float = 1e-8,
38
38
  eject_parameterized: bool = False,
39
39
  ) -> cirq.Circuit:
@@ -59,7 +59,7 @@ def eject_phased_paulis(
59
59
  Returns:
60
60
  Copy of the transformed input circuit.
61
61
  """
62
- held_w_phases: Dict[ops.Qid, value.TParamVal] = {}
62
+ held_w_phases: dict[ops.Qid, value.TParamVal] = {}
63
63
  tags_to_ignore = set(context.tags_to_ignore) if context else set()
64
64
 
65
65
  def map_func(op: cirq.Operation, _: int) -> cirq.OP_TREE:
@@ -108,7 +108,7 @@ def eject_phased_paulis(
108
108
 
109
109
 
110
110
  def _absorb_z_into_w(
111
- op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal]
111
+ op: ops.Operation, held_w_phases: dict[ops.Qid, value.TParamVal]
112
112
  ) -> cirq.OP_TREE:
113
113
  """Absorbs a Z^t gate into a W(a) flip.
114
114
 
@@ -129,7 +129,7 @@ def _absorb_z_into_w(
129
129
 
130
130
 
131
131
  def _dump_held(
132
- qubits: Iterable[ops.Qid], held_w_phases: Dict[ops.Qid, value.TParamVal], atol: float
132
+ qubits: Iterable[ops.Qid], held_w_phases: dict[ops.Qid, value.TParamVal], atol: float
133
133
  ) -> Iterator[cirq.OP_TREE]:
134
134
  # Note: sorting is to avoid non-determinism in the insertion order.
135
135
  for q in sorted(qubits):
@@ -141,7 +141,7 @@ def _dump_held(
141
141
 
142
142
 
143
143
  def _dump_into_measurement(
144
- op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal]
144
+ op: ops.Operation, held_w_phases: dict[ops.Qid, value.TParamVal]
145
145
  ) -> cirq.OP_TREE:
146
146
  measurement = cast(ops.MeasurementGate, cast(ops.GateOperation, op).gate)
147
147
  new_measurement = measurement.with_bits_flipped(
@@ -153,7 +153,7 @@ def _dump_into_measurement(
153
153
 
154
154
 
155
155
  def _potential_cross_whole_w(
156
- op: ops.Operation, atol: float, held_w_phases: Dict[ops.Qid, value.TParamVal]
156
+ op: ops.Operation, atol: float, held_w_phases: dict[ops.Qid, value.TParamVal]
157
157
  ) -> cirq.OP_TREE:
158
158
  """Grabs or cancels a held W gate against an existing W gate.
159
159
 
@@ -167,7 +167,7 @@ def _potential_cross_whole_w(
167
167
  ≡ ───Z^2(b-a)───
168
168
  """
169
169
  _, phase_exponent = cast(
170
- Tuple[value.TParamVal, value.TParamVal], _try_get_known_phased_pauli(op)
170
+ tuple[value.TParamVal, value.TParamVal], _try_get_known_phased_pauli(op)
171
171
  )
172
172
  q = op.qubits[0]
173
173
  a = held_w_phases.get(q, None)
@@ -186,7 +186,7 @@ def _potential_cross_whole_w(
186
186
 
187
187
 
188
188
  def _potential_cross_partial_w(
189
- op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal], atol: float
189
+ op: ops.Operation, held_w_phases: dict[ops.Qid, value.TParamVal], atol: float
190
190
  ) -> cirq.OP_TREE:
191
191
  """Cross the held W over a partial W gate.
192
192
 
@@ -204,7 +204,7 @@ def _potential_cross_partial_w(
204
204
  if a is None:
205
205
  return op
206
206
  exponent, phase_exponent = cast(
207
- Tuple[value.TParamVal, value.TParamVal], _try_get_known_phased_pauli(op)
207
+ tuple[value.TParamVal, value.TParamVal], _try_get_known_phased_pauli(op)
208
208
  )
209
209
  gate = _phased_x_or_pauli_gate(
210
210
  exponent=exponent, phase_exponent=2 * a - phase_exponent, atol=atol
@@ -252,7 +252,7 @@ def _single_cross_over_cz(op: ops.Operation, qubit_with_w: cirq.Qid) -> cirq.OP_
252
252
 
253
253
 
254
254
  def _double_cross_over_cz(
255
- op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal]
255
+ op: ops.Operation, held_w_phases: dict[ops.Qid, value.TParamVal]
256
256
  ) -> cirq.OP_TREE:
257
257
  """Crosses two W flips over a partial CZ.
258
258
 
@@ -296,7 +296,7 @@ def _double_cross_over_cz(
296
296
 
297
297
  def _try_get_known_cz_half_turns(
298
298
  op: ops.Operation, no_symbolic: bool = False
299
- ) -> Optional[value.TParamVal]:
299
+ ) -> value.TParamVal | None:
300
300
  if not isinstance(op.gate, ops.CZPowGate):
301
301
  return None
302
302
  h = op.gate.exponent
@@ -307,7 +307,7 @@ def _try_get_known_cz_half_turns(
307
307
 
308
308
  def _try_get_known_phased_pauli(
309
309
  op: ops.Operation, no_symbolic: bool = False
310
- ) -> Optional[Tuple[value.TParamVal, value.TParamVal]]:
310
+ ) -> tuple[value.TParamVal, value.TParamVal] | None:
311
311
  if no_symbolic and protocols.is_parameterized(op):
312
312
  return None
313
313
  gate = op.gate
@@ -335,7 +335,7 @@ def _try_get_known_phased_pauli(
335
335
 
336
336
  def _try_get_known_z_half_turns(
337
337
  op: ops.Operation, no_symbolic: bool = False
338
- ) -> Optional[value.TParamVal]:
338
+ ) -> value.TParamVal | None:
339
339
  g = op.gate
340
340
  if (
341
341
  isinstance(g, ops.PhasedXZGate)
@@ -356,8 +356,8 @@ def _try_get_known_z_half_turns(
356
356
 
357
357
 
358
358
  def _phased_x_or_pauli_gate(
359
- exponent: Union[float, sympy.Expr], phase_exponent: Union[float, sympy.Expr], atol: float
360
- ) -> Union[cirq.PhasedXPowGate, cirq.XPowGate, cirq.YPowGate]:
359
+ exponent: float | sympy.Expr, phase_exponent: float | sympy.Expr, atol: float
360
+ ) -> cirq.PhasedXPowGate | cirq.XPowGate | cirq.YPowGate:
361
361
  """Return PhasedXPowGate or X or Y gate if equivalent within atol in z-axis turns."""
362
362
  if not isinstance(phase_exponent, sympy.Expr) or phase_exponent.is_constant():
363
363
  half_turns = value.canonicalize_half_turns(float(phase_exponent))
@@ -17,7 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  from collections import defaultdict
20
- from typing import Dict, Iterable, Iterator, Optional, Tuple, TYPE_CHECKING
20
+ from typing import Iterable, Iterator, TYPE_CHECKING
21
21
 
22
22
  import numpy as np
23
23
 
@@ -50,7 +50,7 @@ def _is_swaplike(gate: cirq.Gate):
50
50
  def eject_z(
51
51
  circuit: cirq.AbstractCircuit,
52
52
  *,
53
- context: Optional[cirq.TransformerContext] = None,
53
+ context: cirq.TransformerContext | None = None,
54
54
  atol: float = 0.0,
55
55
  eject_parameterized: bool = False,
56
56
  ) -> cirq.Circuit:
@@ -72,12 +72,10 @@ def eject_z(
72
72
  Copy of the transformed input circuit.
73
73
  """
74
74
  # Tracks qubit phases (in half turns; multiply by pi to get radians).
75
- qubit_phase: Dict[ops.Qid, float] = defaultdict(lambda: 0)
75
+ qubit_phase: dict[ops.Qid, float] = defaultdict(lambda: 0)
76
76
  tags_to_ignore = set(context.tags_to_ignore) if context else set()
77
- phased_xz_replacements: Dict[Tuple[int, ops.Operation], ops.PhasedXZGate] = {}
78
- last_phased_xz_op: Dict[ops.Qid, Optional[Tuple[int, ops.Operation]]] = defaultdict(
79
- lambda: None
80
- )
77
+ phased_xz_replacements: dict[tuple[int, ops.Operation], ops.PhasedXZGate] = {}
78
+ last_phased_xz_op: dict[ops.Qid, tuple[int, ops.Operation] | None] = defaultdict(lambda: None)
81
79
 
82
80
  def dump_tracked_phase(qubits: Iterable[ops.Qid]) -> Iterator[cirq.OP_TREE]:
83
81
  """Zeroes qubit_phase entries by emitting Z gates."""
@@ -21,7 +21,7 @@ import functools
21
21
  import itertools
22
22
  from dataclasses import dataclass
23
23
  from numbers import Real
24
- from typing import Callable, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
24
+ from typing import Callable, Sequence, TYPE_CHECKING
25
25
 
26
26
  import numpy as np
27
27
  import sympy
@@ -70,16 +70,16 @@ class ConstantGauge(Gauge):
70
70
  """A gauge that replaces a two qubit gate with a constant gauge."""
71
71
 
72
72
  two_qubit_gate: ops.Gate
73
- pre_q0: Tuple[ops.Gate, ...] = field(
73
+ pre_q0: tuple[ops.Gate, ...] = field(
74
74
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
75
75
  )
76
- pre_q1: Tuple[ops.Gate, ...] = field(
76
+ pre_q1: tuple[ops.Gate, ...] = field(
77
77
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
78
78
  )
79
- post_q0: Tuple[ops.Gate, ...] = field(
79
+ post_q0: tuple[ops.Gate, ...] = field(
80
80
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
81
81
  )
82
- post_q1: Tuple[ops.Gate, ...] = field(
82
+ post_q1: tuple[ops.Gate, ...] = field(
83
83
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
84
84
  )
85
85
  swap_qubits: bool = False
@@ -88,12 +88,12 @@ class ConstantGauge(Gauge):
88
88
  return self
89
89
 
90
90
  @property
91
- def pre(self) -> Tuple[Tuple[ops.Gate, ...], Tuple[ops.Gate, ...]]:
91
+ def pre(self) -> tuple[tuple[ops.Gate, ...], tuple[ops.Gate, ...]]:
92
92
  """A tuple (ops to apply to q0, ops to apply to q1)."""
93
93
  return self.pre_q0, self.pre_q1
94
94
 
95
95
  @property
96
- def post(self) -> Tuple[Tuple[ops.Gate, ...], Tuple[ops.Gate, ...]]:
96
+ def post(self) -> tuple[tuple[ops.Gate, ...], tuple[ops.Gate, ...]]:
97
97
  """A tuple (ops to apply to q0, ops to apply to q1)."""
98
98
  return self.post_q0, self.post_q1
99
99
 
@@ -108,16 +108,16 @@ class ConstantGauge(Gauge):
108
108
  class SameGateGauge(Gauge):
109
109
  """Same as ConstantGauge but the new two-qubit gate equals the old gate."""
110
110
 
111
- pre_q0: Tuple[ops.Gate, ...] = field(
111
+ pre_q0: tuple[ops.Gate, ...] = field(
112
112
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
113
113
  )
114
- pre_q1: Tuple[ops.Gate, ...] = field(
114
+ pre_q1: tuple[ops.Gate, ...] = field(
115
115
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
116
116
  )
117
- post_q0: Tuple[ops.Gate, ...] = field(
117
+ post_q0: tuple[ops.Gate, ...] = field(
118
118
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
119
119
  )
120
- post_q1: Tuple[ops.Gate, ...] = field(
120
+ post_q1: tuple[ops.Gate, ...] = field(
121
121
  default=(), converter=lambda g: (g,) if isinstance(g, ops.Gate) else tuple(g)
122
122
  )
123
123
  swap_qubits: bool = False
@@ -144,12 +144,12 @@ class TwoQubitGateSymbolizer:
144
144
  n_symbols: The number of symbols to use for parameterization.
145
145
  """
146
146
 
147
- symbolizer_fn: Callable[[ops.Gate, Sequence[sympy.Symbol]], Tuple[ops.Gate, Dict[str, Real]]]
147
+ symbolizer_fn: Callable[[ops.Gate, Sequence[sympy.Symbol]], tuple[ops.Gate, dict[str, Real]]]
148
148
  n_symbols: int
149
149
 
150
150
  def __call__(
151
151
  self, two_qubit_gate: ops.Gate, symbols: Sequence[sympy.Symbol]
152
- ) -> Tuple[ops.Gate, Dict[str, Real]]:
152
+ ) -> tuple[ops.Gate, dict[str, Real]]:
153
153
  """Symbolizes a two qubit gate to a parameterized gate.
154
154
 
155
155
  Args:
@@ -197,9 +197,9 @@ class GaugeTransformer:
197
197
  self,
198
198
  # target can be either a specific gate, gatefamily or gateset
199
199
  # which allows matching parametric gates.
200
- target: Union[ops.Gate, ops.Gateset, ops.GateFamily],
200
+ target: ops.Gate | ops.Gateset | ops.GateFamily,
201
201
  gauge_selector: Callable[[np.random.Generator], Gauge],
202
- two_qubit_gate_symbolizer: Optional[TwoQubitGateSymbolizer] = None,
202
+ two_qubit_gate_symbolizer: TwoQubitGateSymbolizer | None = None,
203
203
  ) -> None:
204
204
  """Constructs a GaugeTransformer.
205
205
 
@@ -217,8 +217,8 @@ class GaugeTransformer:
217
217
  self,
218
218
  circuit: circuits.AbstractCircuit,
219
219
  *,
220
- context: Optional[transformer_api.TransformerContext] = None,
221
- prng: Optional[np.random.Generator] = None,
220
+ context: transformer_api.TransformerContext | None = None,
221
+ prng: np.random.Generator | None = None,
222
222
  ) -> circuits.AbstractCircuit:
223
223
  rng = np.random.default_rng() if prng is None else prng
224
224
  if context is None:
@@ -226,12 +226,12 @@ class GaugeTransformer:
226
226
  if context.deep:
227
227
  raise ValueError('GaugeTransformer cannot be used with deep=True')
228
228
  new_moments = []
229
- left: List[List[ops.Operation]] = []
230
- right: List[List[ops.Operation]] = []
229
+ left: list[list[ops.Operation]] = []
230
+ right: list[list[ops.Operation]] = []
231
231
  for moment in circuit:
232
232
  left.clear()
233
233
  right.clear()
234
- center: List[ops.Operation] = []
234
+ center: list[ops.Operation] = []
235
235
  for op in moment:
236
236
  if isinstance(op, ops.TaggedOperation) and set(op.tags).intersection(
237
237
  context.tags_to_ignore
@@ -258,9 +258,9 @@ class GaugeTransformer:
258
258
  circuit: circuits.AbstractCircuit,
259
259
  *,
260
260
  N: int,
261
- context: Optional[transformer_api.TransformerContext] = None,
262
- prng: Optional[np.random.Generator] = None,
263
- ) -> Tuple[circuits.AbstractCircuit, cirq.Sweepable]:
261
+ context: transformer_api.TransformerContext | None = None,
262
+ prng: np.random.Generator | None = None,
263
+ ) -> tuple[circuits.AbstractCircuit, cirq.Sweepable]:
264
264
  """Generates a parameterized circuit with *N* sets of sweepable parameters.
265
265
 
266
266
  Args:
@@ -276,31 +276,31 @@ class GaugeTransformer:
276
276
  context = transformer_api.TransformerContext(deep=False)
277
277
  if context.deep:
278
278
  raise ValueError('GaugeTransformer cannot be used with deep=True')
279
- new_moments: List[List[ops.Operation]] = [] # Store parameterized circuits.
279
+ new_moments: list[list[ops.Operation]] = [] # Store parameterized circuits.
280
280
  phxz_sid = itertools.count()
281
281
  two_qubit_gate_sid = itertools.count()
282
282
  # Map from "((pre|post),$qid,$moment_id)" to gate parameters.
283
283
  # E.g., {(post,q1,2): {"x_exponent": "x1", "z_exponent": "z1", "axis_phase": "a1"}}
284
- phxz_symbols_by_locs: Dict[Tuple[str, ops.Qid, int], Dict[str, sympy.Symbol]] = {}
284
+ phxz_symbols_by_locs: dict[tuple[str, ops.Qid, int], dict[str, sympy.Symbol]] = {}
285
285
  # Map from "($q0,$q1,$moment_id)" to gate parameters.
286
286
  # E.g., {(q0,q1,0): ["s0"]}.
287
- two_qubit_gate_symbols_by_locs: Dict[Tuple[ops.Qid, ops.Qid, int], List[sympy.Symbol]] = {}
287
+ two_qubit_gate_symbols_by_locs: dict[tuple[ops.Qid, ops.Qid, int], list[sympy.Symbol]] = {}
288
288
 
289
- def single_qubit_next_symbol() -> Dict[str, sympy.Symbol]:
289
+ def single_qubit_next_symbol() -> dict[str, sympy.Symbol]:
290
290
  sid = next(phxz_sid)
291
291
  return _parameterize_to_phxz(sid)
292
292
 
293
- def two_qubit_gate_next_symbol_list(n: int) -> List[sympy.Symbol]:
293
+ def two_qubit_gate_next_symbol_list(n: int) -> list[sympy.Symbol]:
294
294
  """Returns symbols for 2 qubit gate parameterization."""
295
295
  sid = next(two_qubit_gate_sid)
296
- symbols: List[sympy.Symbol] = [sympy.Symbol(f"s{sid}_{sub}") for sub in range(n)]
296
+ symbols: list[sympy.Symbol] = [sympy.Symbol(f"s{sid}_{sub}") for sub in range(n)]
297
297
  return symbols
298
298
 
299
299
  # Build parameterized circuit.
300
300
  for moment_id, moment in enumerate(circuit):
301
- center_moment: List[ops.Operation] = []
302
- left_moment: List[ops.Operation] = []
303
- right_moment: List[ops.Operation] = []
301
+ center_moment: list[ops.Operation] = []
302
+ left_moment: list[ops.Operation] = []
303
+ right_moment: list[ops.Operation] = []
304
304
  for op in moment:
305
305
  if isinstance(op, ops.TaggedOperation) and set(op.tags).intersection(
306
306
  context.tags_to_ignore
@@ -342,7 +342,7 @@ class GaugeTransformer:
342
342
  )
343
343
 
344
344
  # Initialize the map from symbol names to their N values.
345
- values_by_params: Dict[str, List[float]] = {
345
+ values_by_params: dict[str, list[float]] = {
346
346
  **{
347
347
  str(symbol): []
348
348
  for symbols_by_names in phxz_symbols_by_locs.values()
@@ -389,14 +389,14 @@ class GaugeTransformer:
389
389
  for key, value in phxz_params.items():
390
390
  values_by_params[key].append(float(value))
391
391
 
392
- sweeps: List[Points] = [
392
+ sweeps: list[Points] = [
393
393
  Points(key=key, points=values) for key, values in values_by_params.items()
394
394
  ]
395
395
 
396
396
  return circuits.Circuit.from_moments(*new_moments), Zip(*sweeps)
397
397
 
398
398
 
399
- def _build_moments(operation_by_qubits: List[List[ops.Operation]]) -> List[List[ops.Operation]]:
399
+ def _build_moments(operation_by_qubits: list[list[ops.Operation]]) -> list[list[ops.Operation]]:
400
400
  """Builds moments from a list of operations grouped by qubits.
401
401
 
402
402
  Returns a list of moments from a list whose ith element is a list of operations applied
@@ -408,7 +408,7 @@ def _build_moments(operation_by_qubits: List[List[ops.Operation]]) -> List[List[
408
408
  return moments
409
409
 
410
410
 
411
- def _parameterize_to_phxz(symbol_id: int) -> Dict[str, sympy.Symbol]:
411
+ def _parameterize_to_phxz(symbol_id: int) -> dict[str, sympy.Symbol]:
412
412
  """Returns symbolized parameters for the gate."""
413
413
 
414
414
  # Parameterize single qubit gate to parameterized PhasedXZGate.
@@ -421,8 +421,8 @@ def _parameterize_to_phxz(symbol_id: int) -> Dict[str, sympy.Symbol]:
421
421
 
422
422
 
423
423
  def _gate_sequence_to_phxz_params(
424
- gates: Tuple[ops.Gate, ...], xza_by_symbols: Dict[str, sympy.Symbol]
425
- ) -> Dict[str, float]:
424
+ gates: tuple[ops.Gate, ...], xza_by_symbols: dict[str, sympy.Symbol]
425
+ ) -> dict[str, float]:
426
426
  identity_gate_in_phxz = {
427
427
  str(xza_by_symbols["x_exponent"]): 0.0,
428
428
  str(xza_by_symbols["z_exponent"]): 0.0,
@@ -18,7 +18,7 @@
18
18
  from __future__ import annotations
19
19
 
20
20
  from numbers import Real
21
- from typing import Dict, Sequence, Tuple, TYPE_CHECKING
21
+ from typing import Sequence, TYPE_CHECKING
22
22
 
23
23
  from cirq.ops import CZ, CZPowGate, Gate, Gateset, S, X
24
24
  from cirq.transformers.gauge_compiling.gauge_compiling import (
@@ -67,7 +67,7 @@ class SqrtCZGauge(Gauge):
67
67
 
68
68
  def _symbolize_as_cz_pow(
69
69
  two_qubit_gate: Gate, symbols: Sequence[sympy.Symbol]
70
- ) -> Tuple[Gate, Dict[str, Real]]:
70
+ ) -> tuple[Gate, dict[str, Real]]:
71
71
  """Symbolizes a CZPowGate to a parameterized CZPowGate."""
72
72
 
73
73
  if not isinstance(two_qubit_gate, CZPowGate) or not isinstance(two_qubit_gate.exponent, Real):
@@ -19,7 +19,7 @@ from __future__ import annotations
19
19
 
20
20
  from dataclasses import dataclass
21
21
  from functools import reduce
22
- from typing import List, NamedTuple, Sequence, Tuple
22
+ from typing import NamedTuple, Sequence
23
23
 
24
24
  import numpy as np
25
25
 
@@ -34,7 +34,7 @@ from cirq.transformers.heuristic_decompositions.gate_tabulation_math_utils impor
34
34
  weyl_chamber_mesh,
35
35
  )
36
36
 
37
- _SingleQubitGatePair = Tuple[np.ndarray, np.ndarray]
37
+ _SingleQubitGatePair = tuple[np.ndarray, np.ndarray]
38
38
 
39
39
 
40
40
  class TwoQubitGateTabulationResult(NamedTuple):
@@ -61,7 +61,7 @@ class TwoQubitGateTabulationResult(NamedTuple):
61
61
 
62
62
  base_gate_unitary: np.ndarray
63
63
  target_gate: np.ndarray
64
- local_unitaries: Tuple[_SingleQubitGatePair, ...]
64
+ local_unitaries: tuple[_SingleQubitGatePair, ...]
65
65
  actual_gate: np.ndarray
66
66
  success: bool
67
67
 
@@ -82,7 +82,7 @@ class TwoQubitGateTabulation:
82
82
  summary: str # Text summarizing the results of the tabulation procedure.
83
83
  # Any KAK vectors which are expected to be compilable (within infidelity
84
84
  # max_expected_infidelity) using 2 or 3 base gates.
85
- missed_points: Tuple[np.ndarray, ...]
85
+ missed_points: tuple[np.ndarray, ...]
86
86
 
87
87
  def compile_two_qubit_gate(self, unitary: np.ndarray) -> TwoQubitGateTabulationResult:
88
88
  r"""Compute single qubit gates required to compile a desired unitary.
@@ -201,7 +201,7 @@ class TwoQubitGateTabulation:
201
201
 
202
202
  def _outer_locals_for_unitary(
203
203
  target: np.ndarray, base: np.ndarray
204
- ) -> Tuple[_SingleQubitGatePair, _SingleQubitGatePair, np.ndarray]:
204
+ ) -> tuple[_SingleQubitGatePair, _SingleQubitGatePair, np.ndarray]:
205
205
  """Local unitaries mapping between locally equivalent 2-local unitaries.
206
206
 
207
207
  Finds the left and right 1-local unitaries kL, kR such that
@@ -246,10 +246,10 @@ def _outer_locals_for_unitary(
246
246
 
247
247
  class _TabulationStepResult(NamedTuple):
248
248
  # Generated KAK vectors that are uniquely close to at least one mesh point.
249
- kept_kaks: List[np.ndarray]
249
+ kept_kaks: list[np.ndarray]
250
250
  # The corresponding single qubit unitaries required to obtain the desired
251
251
  # KAK vectors.
252
- kept_cycles: List[Tuple[_SingleQubitGatePair, ...]]
252
+ kept_cycles: list[tuple[_SingleQubitGatePair, ...]]
253
253
 
254
254
 
255
255
  def _tabulate_kak_vectors(
@@ -361,7 +361,7 @@ def two_qubit_gate_product_tabulation(
361
361
 
362
362
  # include the base gate itself
363
363
  kak_vecs = [cirq.kak_vector(base_gate, check_preconditions=False)]
364
- sq_cycles: List[Tuple[_SingleQubitGatePair, ...]] = [()]
364
+ sq_cycles: list[tuple[_SingleQubitGatePair, ...]] = [()]
365
365
 
366
366
  # Tabulate gates that are close to gates in the mesh
367
367
  u_locals_0 = random_qubit_unitary((num_samples,), rng=rng)
@@ -16,7 +16,7 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import Dict, List, Optional, TYPE_CHECKING
19
+ from typing import TYPE_CHECKING
20
20
 
21
21
  from cirq import circuits, protocols
22
22
  from cirq.transformers import transformer_api
@@ -27,7 +27,7 @@ if TYPE_CHECKING:
27
27
 
28
28
  @transformer_api.transformer(add_deep_support=True)
29
29
  def insertion_sort_transformer(
30
- circuit: cirq.AbstractCircuit, *, context: Optional[cirq.TransformerContext] = None
30
+ circuit: cirq.AbstractCircuit, *, context: cirq.TransformerContext | None = None
31
31
  ) -> cirq.Circuit:
32
32
  """Sorts the operations using their sorted `.qubits` property as comparison key.
33
33
 
@@ -37,11 +37,11 @@ def insertion_sort_transformer(
37
37
  circuit: input circuit.
38
38
  context: optional TransformerContext (not used),
39
39
  """
40
- final_operations: List[cirq.Operation] = []
41
- qubit_index: Dict[cirq.Qid, int] = {
40
+ final_operations: list[cirq.Operation] = []
41
+ qubit_index: dict[cirq.Qid, int] = {
42
42
  q: idx for idx, q in enumerate(sorted(circuit.all_qubits()))
43
43
  }
44
- cached_qubit_indices: Dict[int, List[int]] = {}
44
+ cached_qubit_indices: dict[int, list[int]] = {}
45
45
  for pos, op in enumerate(circuit.all_operations()):
46
46
  # here `pos` is at the append position of final_operations
47
47
  if (op_qubit_indices := cached_qubit_indices.get(id(op))) is None:
@@ -16,7 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import itertools
18
18
  from collections import defaultdict
19
- from typing import Any, cast, Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
19
+ from typing import Any, cast, Iterable, Sequence, TYPE_CHECKING
20
20
 
21
21
  import numpy as np
22
22
 
@@ -35,7 +35,7 @@ class _MeasurementQid(ops.Qid):
35
35
  Exactly one qubit will be created per qubit in the measurement gate.
36
36
  """
37
37
 
38
- def __init__(self, key: Union[str, cirq.MeasurementKey], qid: cirq.Qid, index: int = 0):
38
+ def __init__(self, key: str | cirq.MeasurementKey, qid: cirq.Qid, index: int = 0):
39
39
  """Initializes the qubit.
40
40
 
41
41
  Args:
@@ -65,7 +65,7 @@ class _MeasurementQid(ops.Qid):
65
65
 
66
66
  @transformer_api.transformer
67
67
  def defer_measurements(
68
- circuit: cirq.AbstractCircuit, *, context: Optional[cirq.TransformerContext] = None
68
+ circuit: cirq.AbstractCircuit, *, context: cirq.TransformerContext | None = None
69
69
  ) -> cirq.Circuit:
70
70
  """Implements the Deferred Measurement Principle.
71
71
 
@@ -96,7 +96,7 @@ def defer_measurements(
96
96
 
97
97
  circuit = transformer_primitives.unroll_circuit_op(circuit, deep=True, tags_to_check=None)
98
98
  terminal_measurements = {op for _, op in find_terminal_measurements(circuit)}
99
- measurement_qubits: Dict[cirq.MeasurementKey, List[Tuple[cirq.Qid, ...]]] = defaultdict(list)
99
+ measurement_qubits: dict[cirq.MeasurementKey, list[tuple[cirq.Qid, ...]]] = defaultdict(list)
100
100
 
101
101
  def defer(op: cirq.Operation, _) -> cirq.OP_TREE:
102
102
  if op in terminal_measurements:
@@ -169,8 +169,8 @@ def defer_measurements(
169
169
 
170
170
 
171
171
  def _all_possible_datastore_states(
172
- keys: Iterable[Tuple[cirq.MeasurementKey, int]],
173
- measurement_qubits: Dict[cirq.MeasurementKey, List[Tuple[cirq.Qid, ...]]],
172
+ keys: Iterable[tuple[cirq.MeasurementKey, int]],
173
+ measurement_qubits: dict[cirq.MeasurementKey, list[tuple[cirq.Qid, ...]]],
174
174
  ) -> Iterable[cirq.ClassicalDataStoreReader]:
175
175
  """The cartesian product of all possible DataStore states for the given keys."""
176
176
  # First we get the list of all possible values. So if we have a key mapped to qubits of shape
@@ -216,7 +216,7 @@ def _all_possible_datastore_states(
216
216
  def dephase_measurements(
217
217
  circuit: cirq.AbstractCircuit,
218
218
  *,
219
- context: Optional[cirq.TransformerContext] = transformer_api.TransformerContext(deep=True),
219
+ context: cirq.TransformerContext | None = transformer_api.TransformerContext(deep=True),
220
220
  ) -> cirq.Circuit:
221
221
  """Changes all measurements to a dephase operation.
222
222
 
@@ -259,7 +259,7 @@ def dephase_measurements(
259
259
  def drop_terminal_measurements(
260
260
  circuit: cirq.AbstractCircuit,
261
261
  *,
262
- context: Optional[cirq.TransformerContext] = transformer_api.TransformerContext(deep=True),
262
+ context: cirq.TransformerContext | None = transformer_api.TransformerContext(deep=True),
263
263
  ) -> cirq.Circuit:
264
264
  """Removes terminal measurements from a circuit.
265
265
 
@@ -426,20 +426,20 @@ class _ConfusionChannel(ops.Gate):
426
426
  self._confusion_map = confusion_map.copy()
427
427
  self._kraus = tuple(kraus)
428
428
 
429
- def _qid_shape_(self) -> Tuple[int, ...]:
429
+ def _qid_shape_(self) -> tuple[int, ...]:
430
430
  return self._shape
431
431
 
432
- def _kraus_(self) -> Tuple[np.ndarray, ...]:
432
+ def _kraus_(self) -> tuple[np.ndarray, ...]:
433
433
  return self._kraus
434
434
 
435
435
  def _apply_channel_(self, args: cirq.ApplyChannelArgs):
436
- configs: List[transformations._BuildFromSlicesArgs] = []
436
+ configs: list[transformations._BuildFromSlicesArgs] = []
437
437
  for i in range(np.prod(self._shape) ** 2):
438
438
  scale = cast(complex, self._confusion_map.flat[i])
439
439
  if scale == 0:
440
440
  continue
441
441
  index: Any = np.unravel_index(i, self._shape * 2)
442
- slices: List[transformations._SliceConfig] = []
442
+ slices: list[transformations._SliceConfig] = []
443
443
  axis_count = len(args.left_axes)
444
444
  for j in range(axis_count):
445
445
  s1 = transformations._SliceConfig(
@@ -469,13 +469,13 @@ class _ModAdd(ops.ArithmeticGate):
469
469
  def __init__(self, dimension: int):
470
470
  self._dimension = dimension
471
471
 
472
- def registers(self) -> Tuple[Tuple[int], Tuple[int]]:
472
+ def registers(self) -> tuple[tuple[int], tuple[int]]:
473
473
  return (self._dimension,), (self._dimension,)
474
474
 
475
475
  def with_registers(self, *new_registers) -> _ModAdd:
476
476
  raise NotImplementedError()
477
477
 
478
- def apply(self, *register_values: int) -> Tuple[int, int]:
478
+ def apply(self, *register_values: int) -> tuple[int, int]:
479
479
  return register_values[0], sum(register_values)
480
480
 
481
481
  def _value_equality_values_(self) -> int:
@@ -16,8 +16,6 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import List
20
-
21
19
  import numpy as np
22
20
  import pytest
23
21
 
@@ -26,7 +24,7 @@ import cirq
26
24
 
27
25
  def assert_optimizes(optimized: cirq.AbstractCircuit, expected: cirq.AbstractCircuit):
28
26
  # Ignore differences that would be caught by follow-up optimizations.
29
- followup_transformers: List[cirq.TRANSFORMER] = [
27
+ followup_transformers: list[cirq.TRANSFORMER] = [
30
28
  cirq.drop_negligible_operations,
31
29
  cirq.drop_empty_moments,
32
30
  ]
@@ -14,14 +14,12 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import List
18
-
19
17
  import cirq
20
18
 
21
19
 
22
20
  def assert_optimizes(optimized: cirq.AbstractCircuit, expected: cirq.AbstractCircuit):
23
21
  # Ignore differences that would be caught by follow-up optimizations.
24
- followup_transformers: List[cirq.TRANSFORMER] = [
22
+ followup_transformers: list[cirq.TRANSFORMER] = [
25
23
  cirq.drop_negligible_operations,
26
24
  cirq.drop_empty_moments,
27
25
  ]