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
@@ -18,7 +18,7 @@ from __future__ import annotations
18
18
 
19
19
  import io
20
20
  import itertools
21
- from typing import Dict, Optional, Sequence
21
+ from typing import Sequence
22
22
 
23
23
  import matplotlib.pyplot as plt
24
24
  import networkx as nx
@@ -90,7 +90,7 @@ def test_parallel_two_qubit_xeb_simulator_without_processor_fails():
90
90
  ),
91
91
  ],
92
92
  )
93
- def test_parallel_two_qubit_xeb(sampler: cirq.Sampler, qubits: Optional[Sequence[cirq.GridQubit]]):
93
+ def test_parallel_two_qubit_xeb(sampler: cirq.Sampler, qubits: Sequence[cirq.GridQubit] | None):
94
94
  res = cirq.experiments.parallel_two_qubit_xeb(
95
95
  sampler=sampler,
96
96
  qubits=qubits,
@@ -162,7 +162,7 @@ def test_pauli_error(q0: cirq.GridQubit, q1: cirq.GridQubit, pauli: float):
162
162
 
163
163
 
164
164
  class MockParallelRandomizedBenchmarkingResult(ParallelRandomizedBenchmarkingResult):
165
- def pauli_error(self) -> Dict[cirq.Qid, float]:
165
+ def pauli_error(self) -> dict[cirq.Qid, float]:
166
166
  return {
167
167
  cirq.GridQubit(4, 4): 0.01,
168
168
  cirq.GridQubit(5, 4): 0.02,
@@ -294,8 +294,8 @@ def test_inferred_plots(ax, target_error, kind):
294
294
  )
295
295
  def test_run_rb_and_xeb(
296
296
  sampler: cirq.Sampler,
297
- qubits: Optional[Sequence[cirq.GridQubit]],
298
- pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]],
297
+ qubits: Sequence[cirq.GridQubit] | None,
298
+ pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None,
299
299
  ):
300
300
  res = cirq.experiments.run_rb_and_xeb(
301
301
  sampler=sampler,
@@ -18,7 +18,7 @@ from __future__ import annotations
18
18
 
19
19
  import dataclasses
20
20
  from abc import ABC, abstractmethod
21
- from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING
21
+ from typing import Iterable, Sequence, TYPE_CHECKING
22
22
 
23
23
  import numpy as np
24
24
  import pandas as pd
@@ -46,9 +46,9 @@ THETA_SYMBOL, ZETA_SYMBOL, CHI_SYMBOL, GAMMA_SYMBOL, PHI_SYMBOL = sympy.symbols(
46
46
  def benchmark_2q_xeb_fidelities(
47
47
  sampled_df: pd.DataFrame,
48
48
  circuits: Sequence[cirq.Circuit],
49
- cycle_depths: Optional[Sequence[int]] = None,
49
+ cycle_depths: Sequence[int] | None = None,
50
50
  param_resolver: cirq.ParamResolverOrSimilarType = None,
51
- pool: Optional[multiprocessing.pool.Pool] = None,
51
+ pool: multiprocessing.pool.Pool | None = None,
52
52
  ) -> pd.DataFrame:
53
53
  """Simulate and benchmark two-qubit XEB circuits.
54
54
 
@@ -158,11 +158,11 @@ class XEBCharacterizationOptions(ABC):
158
158
  @abstractmethod
159
159
  def get_initial_simplex_and_names(
160
160
  self, initial_simplex_step_size: float = 0.1
161
- ) -> Tuple[np.ndarray, List[str]]:
161
+ ) -> tuple[np.ndarray, list[str]]:
162
162
  """Return an initial Nelder-Mead simplex and the names for each parameter."""
163
163
 
164
164
 
165
- def _try_defaults_from_unitary(gate: cirq.Gate) -> Optional[Dict[str, cirq.TParamVal]]:
165
+ def _try_defaults_from_unitary(gate: cirq.Gate) -> dict[str, cirq.TParamVal] | None:
166
166
  r"""Try to figure out the PhasedFSim angles from the unitary of the gate.
167
167
 
168
168
  The unitary of a PhasedFSimGate has the form:
@@ -225,10 +225,10 @@ def _try_defaults_from_unitary(gate: cirq.Gate) -> Optional[Dict[str, cirq.TPara
225
225
  return None
226
226
 
227
227
 
228
- def phased_fsim_angles_from_gate(gate: cirq.Gate) -> Dict[str, cirq.TParamVal]:
228
+ def phased_fsim_angles_from_gate(gate: cirq.Gate) -> dict[str, cirq.TParamVal]:
229
229
  """For a given gate, return a dictionary mapping '{angle}_default' to its noiseless value
230
230
  for the five PhasedFSim angles."""
231
- defaults: Dict[str, cirq.TParamVal] = {
231
+ defaults: dict[str, cirq.TParamVal] = {
232
232
  'theta_default': 0.0,
233
233
  'zeta_default': 0.0,
234
234
  'chi_default': 0.0,
@@ -288,13 +288,13 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
288
288
  characterize_gamma: bool = True
289
289
  characterize_phi: bool = True
290
290
 
291
- theta_default: Optional[float] = None
292
- zeta_default: Optional[float] = None
293
- chi_default: Optional[float] = None
294
- gamma_default: Optional[float] = None
295
- phi_default: Optional[float] = None
291
+ theta_default: float | None = None
292
+ zeta_default: float | None = None
293
+ chi_default: float | None = None
294
+ gamma_default: float | None = None
295
+ phi_default: float | None = None
296
296
 
297
- def _iter_angles(self) -> Iterable[Tuple[bool, Optional[float], sympy.Symbol]]:
297
+ def _iter_angles(self) -> Iterable[tuple[bool, float | None, sympy.Symbol]]:
298
298
  yield from (
299
299
  (self.characterize_theta, self.theta_default, THETA_SYMBOL),
300
300
  (self.characterize_zeta, self.zeta_default, ZETA_SYMBOL),
@@ -303,7 +303,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
303
303
  (self.characterize_phi, self.phi_default, PHI_SYMBOL),
304
304
  )
305
305
 
306
- def _iter_angles_for_characterization(self) -> Iterable[Tuple[Optional[float], sympy.Symbol]]:
306
+ def _iter_angles_for_characterization(self) -> Iterable[tuple[float | None, sympy.Symbol]]:
307
307
  yield from (
308
308
  (default, symbol)
309
309
  for characterize, default, symbol in self._iter_angles()
@@ -312,7 +312,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
312
312
 
313
313
  def get_initial_simplex_and_names(
314
314
  self, initial_simplex_step_size: float = 0.1
315
- ) -> Tuple[np.ndarray, List[str]]:
315
+ ) -> tuple[np.ndarray, list[str]]:
316
316
  """Get an initial simplex and parameter names for the optimization implied by these options.
317
317
 
318
318
  The initial simplex initiates the Nelder-Mead optimization parameter. We
@@ -403,7 +403,7 @@ def SqrtISwapXEBOptions(*args, **kwargs):
403
403
  def parameterize_circuit(
404
404
  circuit: cirq.Circuit,
405
405
  options: XEBCharacterizationOptions,
406
- target_gatefamily: Optional[ops.GateFamily] = None,
406
+ target_gatefamily: ops.GateFamily | None = None,
407
407
  ) -> cirq.Circuit:
408
408
  """Parameterize PhasedFSim-like gates in a given circuit according to
409
409
  `phased_fsim_options`.
@@ -421,7 +421,7 @@ def parameterize_circuit(
421
421
  )
422
422
 
423
423
 
424
- QPair_T = Tuple['cirq.Qid', 'cirq.Qid']
424
+ QPair_T = tuple['cirq.Qid', 'cirq.Qid']
425
425
 
426
426
 
427
427
  @dataclasses.dataclass(frozen=True)
@@ -436,21 +436,21 @@ class XEBCharacterizationResult:
436
436
  fitting the characterization.
437
437
  """
438
438
 
439
- optimization_results: Dict[QPair_T, scipy.optimize.OptimizeResult]
440
- final_params: Dict[QPair_T, Dict[str, float]]
439
+ optimization_results: dict[QPair_T, scipy.optimize.OptimizeResult]
440
+ final_params: dict[QPair_T, dict[str, float]]
441
441
  fidelities_df: pd.DataFrame
442
442
 
443
443
 
444
444
  def characterize_phased_fsim_parameters_with_xeb(
445
445
  sampled_df: pd.DataFrame,
446
- parameterized_circuits: List[cirq.Circuit],
446
+ parameterized_circuits: list[cirq.Circuit],
447
447
  cycle_depths: Sequence[int],
448
448
  options: XEBCharacterizationOptions,
449
449
  initial_simplex_step_size: float = 0.1,
450
450
  xatol: float = 1e-3,
451
451
  fatol: float = 1e-3,
452
452
  verbose: bool = True,
453
- pool: Optional[multiprocessing.pool.Pool] = None,
453
+ pool: multiprocessing.pool.Pool | None = None,
454
454
  ) -> XEBCharacterizationResult:
455
455
  """Run a classical optimization to fit phased fsim parameters to experimental data, and
456
456
  thereby characterize PhasedFSim-like gates.
@@ -516,7 +516,7 @@ class _CharacterizePhasedFsimParametersWithXebClosure:
516
516
  """A closure object to wrap `characterize_phased_fsim_parameters_with_xeb` for use in
517
517
  multiprocessing."""
518
518
 
519
- parameterized_circuits: List[cirq.Circuit]
519
+ parameterized_circuits: list[cirq.Circuit]
520
520
  cycle_depths: Sequence[int]
521
521
  options: XEBCharacterizationOptions
522
522
  initial_simplex_step_size: float = 0.1
@@ -539,13 +539,13 @@ class _CharacterizePhasedFsimParametersWithXebClosure:
539
539
 
540
540
  def characterize_phased_fsim_parameters_with_xeb_by_pair(
541
541
  sampled_df: pd.DataFrame,
542
- parameterized_circuits: List[cirq.Circuit],
542
+ parameterized_circuits: list[cirq.Circuit],
543
543
  cycle_depths: Sequence[int],
544
544
  options: XEBCharacterizationOptions,
545
545
  initial_simplex_step_size: float = 0.1,
546
546
  xatol: float = 1e-3,
547
547
  fatol: float = 1e-3,
548
- pool: Optional[multiprocessing.pool.Pool] = None,
548
+ pool: multiprocessing.pool.Pool | None = None,
549
549
  ) -> XEBCharacterizationResult:
550
550
  """Run a classical optimization to fit phased fsim parameters to experimental data, and
551
551
  thereby characterize PhasedFSim-like gates grouped by pairs.
@@ -618,7 +618,7 @@ def exponential_decay(cycle_depths: np.ndarray, a: float, layer_fid: float) -> n
618
618
 
619
619
  def _fit_exponential_decay(
620
620
  cycle_depths: np.ndarray, fidelities: np.ndarray
621
- ) -> Tuple[float, float, float, float]:
621
+ ) -> tuple[float, float, float, float]:
622
622
  """Fit an exponential model fidelity = a * layer_fid**x using nonlinear least squares.
623
623
 
624
624
  This uses `exponential_decay` as the function to fit with parameters `a` and `layer_fid`.
@@ -20,18 +20,7 @@ import os
20
20
  import time
21
21
  import uuid
22
22
  from dataclasses import dataclass
23
- from typing import (
24
- Any,
25
- Callable,
26
- ContextManager,
27
- Dict,
28
- List,
29
- Optional,
30
- Sequence,
31
- Set,
32
- Tuple,
33
- TYPE_CHECKING,
34
- )
23
+ from typing import Any, Callable, ContextManager, Sequence, TYPE_CHECKING
35
24
 
36
25
  import numpy as np
37
26
  import pandas as pd
@@ -57,7 +46,7 @@ class _Sample2qXEBTask:
57
46
  layer_i: int
58
47
  combination_i: int
59
48
  prepared_circuit: cirq.AbstractCircuit
60
- combination: List[int]
49
+ combination: list[int]
61
50
 
62
51
 
63
52
  class _SampleInBatches:
@@ -65,7 +54,7 @@ class _SampleInBatches:
65
54
  self,
66
55
  sampler: cirq.Sampler,
67
56
  repetitions: int,
68
- combinations_by_layer: List[CircuitLibraryCombination],
57
+ combinations_by_layer: list[CircuitLibraryCombination],
69
58
  ):
70
59
  """This closure will execute a list of `tasks` with one call to
71
60
  `run_batch` on the provided sampler for a given number of repetitions.
@@ -80,7 +69,7 @@ class _SampleInBatches:
80
69
  self.repetitions = repetitions
81
70
  self.combinations_by_layer = combinations_by_layer
82
71
 
83
- def __call__(self, tasks: List[_Sample2qXEBTask]) -> List[Dict[str, Any]]:
72
+ def __call__(self, tasks: list[_Sample2qXEBTask]) -> list[dict[str, Any]]:
84
73
  prepared_circuits = [task.prepared_circuit for task in tasks]
85
74
  results = self.sampler.run_batch(prepared_circuits, repetitions=self.repetitions)
86
75
  timestamp = time.time()
@@ -113,7 +102,7 @@ class _SampleInBatches:
113
102
 
114
103
  def _verify_and_get_two_qubits_from_circuits(circuits: Sequence[cirq.Circuit]):
115
104
  """Make sure each of the provided circuits uses the same two qubits and return them."""
116
- all_qubits_set: Set[cirq.Qid] = set()
105
+ all_qubits_set: set[cirq.Qid] = set()
117
106
  all_qubits_set = all_qubits_set.union(*(circuit.all_qubits() for circuit in circuits))
118
107
  all_qubits_list = sorted(all_qubits_set)
119
108
  if len(all_qubits_list) != 2:
@@ -170,15 +159,15 @@ class _ZippedCircuit:
170
159
  """
171
160
 
172
161
  wide_circuit: cirq.Circuit
173
- pairs: List[Tuple[cirq.Qid, cirq.Qid]]
174
- combination: List[int]
162
+ pairs: list[tuple[cirq.Qid, cirq.Qid]]
163
+ combination: list[int]
175
164
  layer_i: int
176
165
  combination_i: int
177
166
 
178
167
 
179
168
  def _get_combinations_by_layer_for_isolated_xeb(
180
169
  circuits: Sequence[cirq.Circuit],
181
- ) -> Tuple[List[CircuitLibraryCombination], List[cirq.Circuit]]:
170
+ ) -> tuple[list[CircuitLibraryCombination], list[cirq.Circuit]]:
182
171
  """Helper function used in `sample_2q_xeb_circuits`.
183
172
 
184
173
  This creates a CircuitLibraryCombination object for isolated XEB. First, the qubits
@@ -199,8 +188,8 @@ def _get_combinations_by_layer_for_isolated_xeb(
199
188
 
200
189
 
201
190
  def _zip_circuits(
202
- circuits: Sequence[cirq.Circuit], combinations_by_layer: List[CircuitLibraryCombination]
203
- ) -> List[_ZippedCircuit]:
191
+ circuits: Sequence[cirq.Circuit], combinations_by_layer: list[CircuitLibraryCombination]
192
+ ) -> list[_ZippedCircuit]:
204
193
  """Helper function used in `sample_2q_xeb_circuits` to zip together circuits.
205
194
 
206
195
  This takes a sequence of narrow `circuits` and "zips" them together according to the
@@ -214,7 +203,7 @@ def _zip_circuits(
214
203
  ):
215
204
  raise ValueError("`combinations_by_layer` has invalid indices.")
216
205
 
217
- zipped_circuits: List[_ZippedCircuit] = []
206
+ zipped_circuits: list[_ZippedCircuit] = []
218
207
  for layer_i, layer_combinations in enumerate(combinations_by_layer):
219
208
  for combination_i, combination in enumerate(layer_combinations.combinations):
220
209
  wide_circuit = Circuit.zip(
@@ -236,10 +225,10 @@ def _zip_circuits(
236
225
 
237
226
 
238
227
  def _generate_sample_2q_xeb_tasks(
239
- zipped_circuits: List[_ZippedCircuit], cycle_depths: Sequence[int]
240
- ) -> List[_Sample2qXEBTask]:
228
+ zipped_circuits: list[_ZippedCircuit], cycle_depths: Sequence[int]
229
+ ) -> list[_Sample2qXEBTask]:
241
230
  """Helper function used in `sample_2q_xeb_circuits` to prepare circuits in sampling tasks."""
242
- tasks: List[_Sample2qXEBTask] = []
231
+ tasks: list[_Sample2qXEBTask] = []
243
232
  for cycle_depth in cycle_depths:
244
233
  for zipped_circuit in zipped_circuits:
245
234
  circuit_depth = cycle_depth * 2 + 1
@@ -263,14 +252,14 @@ def _generate_sample_2q_xeb_tasks(
263
252
 
264
253
 
265
254
  def _execute_sample_2q_xeb_tasks_in_batches(
266
- tasks: List[_Sample2qXEBTask],
255
+ tasks: list[_Sample2qXEBTask],
267
256
  sampler: cirq.Sampler,
268
- combinations_by_layer: List[CircuitLibraryCombination],
257
+ combinations_by_layer: list[CircuitLibraryCombination],
269
258
  repetitions: int,
270
259
  batch_size: int,
271
260
  progress_bar: Callable[..., ContextManager],
272
- dataset_directory: Optional[str] = None,
273
- ) -> List[Dict[str, Any]]:
261
+ dataset_directory: str | None = None,
262
+ ) -> list[dict[str, Any]]:
274
263
  """Helper function used in `sample_2q_xeb_circuits` to batch and execute sampling tasks."""
275
264
  n_tasks = len(tasks)
276
265
  batched_tasks = [tasks[i : i + batch_size] for i in range(0, n_tasks, batch_size)]
@@ -298,10 +287,10 @@ def sample_2q_xeb_circuits(
298
287
  *,
299
288
  repetitions: int = 10_000,
300
289
  batch_size: int = 9,
301
- progress_bar: Optional[Callable[..., ContextManager]] = tqdm.tqdm,
302
- combinations_by_layer: Optional[List[CircuitLibraryCombination]] = None,
303
- shuffle: Optional[cirq.RANDOM_STATE_OR_SEED_LIKE] = None,
304
- dataset_directory: Optional[str] = None,
290
+ progress_bar: Callable[..., ContextManager] | None = tqdm.tqdm,
291
+ combinations_by_layer: list[CircuitLibraryCombination] | None = None,
292
+ shuffle: cirq.RANDOM_STATE_OR_SEED_LIKE | None = None,
293
+ dataset_directory: str | None = None,
305
294
  ):
306
295
  """Sample two-qubit XEB circuits given a sampler.
307
296
 
@@ -17,7 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  from dataclasses import dataclass
20
- from typing import Any, Dict, List, Optional, Sequence, TYPE_CHECKING
20
+ from typing import Any, Sequence, TYPE_CHECKING
21
21
 
22
22
  import numpy as np
23
23
  import pandas as pd
@@ -46,7 +46,7 @@ class _Simulate_2q_XEB_Circuit:
46
46
  def __init__(self, simulator: cirq.SimulatesIntermediateState):
47
47
  self.simulator = simulator
48
48
 
49
- def __call__(self, task: _Simulate2qXEBTask) -> List[Dict[str, Any]]:
49
+ def __call__(self, task: _Simulate2qXEBTask) -> list[dict[str, Any]]:
50
50
  """Helper function for simulating a given (circuit, cycle_depth)."""
51
51
  circuit_i = task.circuit_i
52
52
  cycle_depths = set(task.cycle_depths)
@@ -57,7 +57,7 @@ class _Simulate_2q_XEB_Circuit:
57
57
  if max(cycle_depths) > circuit_max_cycle_depth:
58
58
  raise ValueError("`circuit` was not long enough to compute all `cycle_depths`.")
59
59
 
60
- records: List[Dict[str, Any]] = []
60
+ records: list[dict[str, Any]] = []
61
61
  for moment_i, step_result in enumerate(
62
62
  self.simulator.simulate_moment_steps(circuit=circuit, param_resolver=param_resolver)
63
63
  ):
@@ -84,8 +84,8 @@ def simulate_2q_xeb_circuits(
84
84
  circuits: Sequence[cirq.Circuit],
85
85
  cycle_depths: Sequence[int],
86
86
  param_resolver: cirq.ParamResolverOrSimilarType = None,
87
- pool: Optional[multiprocessing.pool.Pool] = None,
88
- simulator: Optional[cirq.SimulatesIntermediateState] = None,
87
+ pool: multiprocessing.pool.Pool | None = None,
88
+ simulator: cirq.SimulatesIntermediateState | None = None,
89
89
  ):
90
90
  """Simulate two-qubit XEB circuits.
91
91
 
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import multiprocessing
18
- from typing import Any, Dict, Iterator, Optional, Sequence
18
+ from typing import Any, Iterator, Sequence
19
19
 
20
20
  import numpy as np
21
21
  import pandas as pd
@@ -74,7 +74,7 @@ def test_simulate_circuit_length_validation():
74
74
  _ = simulate_2q_xeb_circuits(circuits=circuits, cycle_depths=cycle_depths)
75
75
 
76
76
 
77
- def _ref_simulate_2q_xeb_circuit(task: Dict[str, Any]):
77
+ def _ref_simulate_2q_xeb_circuit(task: dict[str, Any]):
78
78
  """Helper function for simulating a given (circuit, cycle_depth)."""
79
79
  circuit_i = task['circuit_i']
80
80
  cycle_depth = task['cycle_depth']
@@ -98,7 +98,7 @@ def _ref_simulate_2q_xeb_circuits(
98
98
  circuits: Sequence[cirq.Circuit],
99
99
  cycle_depths: Sequence[int],
100
100
  param_resolver: cirq.ParamResolverOrSimilarType = None,
101
- pool: Optional[multiprocessing.pool.Pool] = None,
101
+ pool: multiprocessing.pool.Pool | None = None,
102
102
  ):
103
103
  """Reference implementation for `simulate_2q_xeb_circuits` that
104
104
  does each circuit independently instead of using intermediate states.
@@ -18,7 +18,7 @@ from __future__ import annotations
18
18
 
19
19
  import multiprocessing
20
20
  import multiprocessing.pool
21
- from typing import Any, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
21
+ from typing import Any, Sequence, TYPE_CHECKING
22
22
 
23
23
  import matplotlib.pyplot as plt
24
24
  import numpy as np
@@ -36,19 +36,19 @@ if TYPE_CHECKING:
36
36
 
37
37
  def z_phase_calibration_workflow(
38
38
  sampler: cirq.Sampler,
39
- qubits: Optional[Sequence[cirq.GridQubit]] = None,
39
+ qubits: Sequence[cirq.GridQubit] | None = None,
40
40
  two_qubit_gate: cirq.Gate = ops.CZ,
41
- options: Optional[xeb_fitting.XEBPhasedFSimCharacterizationOptions] = None,
41
+ options: xeb_fitting.XEBPhasedFSimCharacterizationOptions | None = None,
42
42
  n_repetitions: int = 10**4,
43
43
  n_combinations: int = 10,
44
44
  n_circuits: int = 20,
45
45
  cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
46
46
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
47
47
  atol: float = 1e-3,
48
- num_workers_or_pool: Union[int, multiprocessing.pool.Pool] = -1,
49
- pairs: Optional[Sequence[Tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
48
+ num_workers_or_pool: int | multiprocessing.pool.Pool = -1,
49
+ pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
50
50
  tags: Sequence[Any] = (),
51
- ) -> Tuple[xeb_fitting.XEBCharacterizationResult, pd.DataFrame]:
51
+ ) -> tuple[xeb_fitting.XEBCharacterizationResult, pd.DataFrame]:
52
52
  """Perform z-phase calibration for excitation-preserving gates.
53
53
 
54
54
  For a given excitation-preserving two-qubit gate we assume an error model that can be described
@@ -91,7 +91,7 @@ def z_phase_calibration_workflow(
91
91
  - A `pd.DataFrame` comparing the before and after fidelities.
92
92
  """
93
93
 
94
- pool: Optional[multiprocessing.pool.Pool] = None
94
+ pool: multiprocessing.pool.Pool | None = None
95
95
  local_pool = False
96
96
  if isinstance(num_workers_or_pool, multiprocessing.pool.Pool):
97
97
  pool = num_workers_or_pool # pragma: no cover
@@ -149,19 +149,19 @@ def z_phase_calibration_workflow(
149
149
 
150
150
  def calibrate_z_phases(
151
151
  sampler: cirq.Sampler,
152
- qubits: Optional[Sequence[cirq.GridQubit]] = None,
152
+ qubits: Sequence[cirq.GridQubit] | None = None,
153
153
  two_qubit_gate: cirq.Gate = ops.CZ,
154
- options: Optional[xeb_fitting.XEBPhasedFSimCharacterizationOptions] = None,
154
+ options: xeb_fitting.XEBPhasedFSimCharacterizationOptions | None = None,
155
155
  n_repetitions: int = 10**4,
156
156
  n_combinations: int = 10,
157
157
  n_circuits: int = 20,
158
158
  cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
159
159
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
160
160
  atol: float = 1e-3,
161
- num_workers_or_pool: Union[int, multiprocessing.pool.Pool] = -1,
162
- pairs: Optional[Sequence[Tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
161
+ num_workers_or_pool: int | multiprocessing.pool.Pool = -1,
162
+ pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
163
163
  tags: Sequence[Any] = (),
164
- ) -> Dict[Tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate]:
164
+ ) -> dict[tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate]:
165
165
  """Perform z-phase calibration for excitation-preserving gates.
166
166
 
167
167
  For a given excitation-preserving two-qubit gate we assume an error model that can be described
@@ -242,11 +242,11 @@ def calibrate_z_phases(
242
242
 
243
243
  def plot_z_phase_calibration_result(
244
244
  before_after_df: pd.DataFrame,
245
- axes: Optional[np.ndarray[Tuple[int, int], np.dtype[np.object_]]] = None,
246
- pairs: Optional[Sequence[Tuple[cirq.Qid, cirq.Qid]]] = None,
245
+ axes: np.ndarray[tuple[int, int], np.dtype[np.object_]] | None = None,
246
+ pairs: Sequence[tuple[cirq.Qid, cirq.Qid]] | None = None,
247
247
  *,
248
248
  with_error_bars: bool = False,
249
- ) -> np.ndarray[Tuple[int, int], np.dtype[np.object_]]:
249
+ ) -> np.ndarray[tuple[int, int], np.dtype[np.object_]]:
250
250
  """A helper method to plot the result of running z-phase calibration.
251
251
 
252
252
  Note that the plotted fidelity is a statistical estimate of the true fidelity and as a result
@@ -290,7 +290,7 @@ def plot_z_phase_calibration_result(
290
290
  return axes
291
291
 
292
292
 
293
- def _z_angles(old: ops.PhasedFSimGate, new: ops.PhasedFSimGate) -> Tuple[float, float, float]:
293
+ def _z_angles(old: ops.PhasedFSimGate, new: ops.PhasedFSimGate) -> tuple[float, float, float]:
294
294
  """Computes a set of possible 3 z-phases that result in the change in gamma, zeta, and chi."""
295
295
  # This procedure is the inverse of PhasedFSimGate.from_fsim_rz
296
296
  delta_gamma = new.gamma - old.gamma
@@ -305,7 +305,7 @@ class CalibrationTransformer:
305
305
  def __init__(
306
306
  self,
307
307
  target: cirq.Gate,
308
- calibration_map: Dict[Tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate],
308
+ calibration_map: dict[tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate],
309
309
  ):
310
310
  """Create a CalibrationTransformer.
311
311
 
@@ -332,7 +332,7 @@ class CalibrationTransformer:
332
332
  self,
333
333
  circuit: cirq.AbstractCircuit,
334
334
  *,
335
- context: Optional[transformer_api.TransformerContext] = None,
335
+ context: transformer_api.TransformerContext | None = None,
336
336
  ) -> cirq.Circuit:
337
337
  """Adds 3 ZPowGates around each calibrated gate to cancel the effect of Z phases.
338
338
 
@@ -343,7 +343,7 @@ class CalibrationTransformer:
343
343
  Returns:
344
344
  New circuit with the extra ZPowGates.
345
345
  """
346
- new_moments: List[Union[List[cirq.Operation], cirq.Moment]] = []
346
+ new_moments: list[list[cirq.Operation] | cirq.Moment] = []
347
347
  for moment in circuit:
348
348
  before = []
349
349
  after = []
@@ -15,20 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import inspect
18
- from typing import (
19
- Any,
20
- Callable,
21
- cast,
22
- Dict,
23
- Iterable,
24
- Iterator,
25
- List,
26
- Optional,
27
- Sequence,
28
- Tuple,
29
- TYPE_CHECKING,
30
- Union,
31
- )
18
+ from typing import Any, Callable, cast, Iterable, Iterator, Sequence, TYPE_CHECKING
32
19
 
33
20
  from cirq import ops, value
34
21
  from cirq.interop.quirk.cells.cell import Cell, CELL_SIZES, CellMaker
@@ -52,7 +39,7 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
52
39
  """
53
40
 
54
41
  def __init__(
55
- self, identifier: str, target: Sequence[int], inputs: Sequence[Union[Sequence[int], int]]
42
+ self, identifier: str, target: Sequence[int], inputs: Sequence[Sequence[int] | int]
56
43
  ):
57
44
  """Inits QuirkArithmeticGate.
58
45
 
@@ -68,8 +55,8 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
68
55
  too small modulus.
69
56
  """
70
57
  self.identifier = identifier
71
- self.target: Tuple[int, ...] = tuple(target)
72
- self.inputs: Tuple[Union[Sequence[int], int], ...] = tuple(
58
+ self.target: tuple[int, ...] = tuple(target)
59
+ self.inputs: tuple[Sequence[int] | int, ...] = tuple(
73
60
  e if isinstance(e, int) else tuple(e) for e in inputs
74
61
  )
75
62
 
@@ -89,10 +76,10 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
89
76
  def _value_equality_values_(self) -> Any:
90
77
  return self.identifier, self.target, self.inputs
91
78
 
92
- def registers(self) -> Sequence[Union[int, Sequence[int]]]:
79
+ def registers(self) -> Sequence[int | Sequence[int]]:
93
80
  return [self.target, *self.inputs]
94
81
 
95
- def with_registers(self, *new_registers: Union[int, Sequence[int]]) -> QuirkArithmeticGate:
82
+ def with_registers(self, *new_registers: int | Sequence[int]) -> QuirkArithmeticGate:
96
83
  if len(new_registers) != len(self.inputs) + 1:
97
84
  raise ValueError(
98
85
  'Wrong number of registers.\n'
@@ -109,13 +96,13 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
109
96
 
110
97
  return QuirkArithmeticGate(self.identifier, new_registers[0], new_registers[1:])
111
98
 
112
- def apply(self, *registers: int) -> Union[int, Iterable[int]]:
99
+ def apply(self, *registers: int) -> int | Iterable[int]:
113
100
  return self.operation(*registers)
114
101
 
115
- def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> List[str]:
102
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> list[str]:
116
103
  lettered_args = list(zip(self.operation.letters, self.inputs))
117
104
 
118
- result: List[str] = []
105
+ result: list[str] = []
119
106
 
120
107
  # Target register labels.
121
108
  consts = ''.join(
@@ -141,12 +128,12 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
141
128
  )
142
129
 
143
130
 
144
- _IntsToIntCallable = Union[
145
- Callable[[int], int],
146
- Callable[[int, int], int],
147
- Callable[[int, int, int], int],
148
- Callable[[int, int, int, int], int],
149
- ]
131
+ _IntsToIntCallable = (
132
+ Callable[[int], int]
133
+ | Callable[[int, int], int]
134
+ | Callable[[int, int, int], int]
135
+ | Callable[[int, int, int, int], int]
136
+ )
150
137
 
151
138
 
152
139
  class _QuirkArithmeticCallable:
@@ -161,7 +148,7 @@ class _QuirkArithmeticCallable:
161
148
  self.func = func
162
149
 
163
150
  # The lambda parameter names indicate the input letter to match.
164
- letters: List[str] = list(inspect.signature(self.func).parameters)
151
+ letters: list[str] = list(inspect.signature(self.func).parameters)
165
152
  # The target is always first, and should be ignored.
166
153
  assert letters and letters[0] == 'x'
167
154
  self.letters = tuple(letters[1:])
@@ -187,7 +174,7 @@ class ArithmeticCell(Cell):
187
174
  self,
188
175
  identifier: str,
189
176
  target: Sequence[cirq.Qid],
190
- inputs: Sequence[Union[None, Sequence[cirq.Qid], int]],
177
+ inputs: Sequence[None | Sequence[cirq.Qid] | int],
191
178
  ):
192
179
  self.identifier = identifier
193
180
  self.target = tuple(target)
@@ -207,7 +194,7 @@ class ArithmeticCell(Cell):
207
194
  f'\n {self.inputs!r})'
208
195
  )
209
196
 
210
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
197
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
211
198
  return ArithmeticCell(
212
199
  identifier=self.identifier,
213
200
  target=Cell._replace_qubits(self.target, qubits),
@@ -221,7 +208,7 @@ class ArithmeticCell(Cell):
221
208
  def operation(self):
222
209
  return ARITHMETIC_OP_TABLE[self.identifier]
223
210
 
224
- def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> ArithmeticCell:
211
+ def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> ArithmeticCell:
225
212
  new_inputs = [
226
213
  reg if letter != reg_letter else register
227
214
  for reg, reg_letter in zip(self.inputs, self.operation.letters)
@@ -235,7 +222,7 @@ class ArithmeticCell(Cell):
235
222
  if missing_inputs:
236
223
  raise ValueError(f'Missing input: {sorted(missing_inputs)}')
237
224
 
238
- inputs = cast(Sequence[Union[Sequence['cirq.Qid'], int]], self.inputs)
225
+ inputs = cast(Sequence[Sequence['cirq.Qid'] | int], self.inputs)
239
226
  qubits = self.target + tuple(q for i in self.inputs if isinstance(i, Sequence) for q in i)
240
227
  return QuirkArithmeticGate(
241
228
  self.identifier,
@@ -304,7 +291,7 @@ def _generate_helper() -> Iterator[CellMaker]:
304
291
  )
305
292
 
306
293
 
307
- def _extended_gcd(a: int, b: int) -> Tuple[int, int, int]:
294
+ def _extended_gcd(a: int, b: int) -> tuple[int, int, int]:
308
295
  if a == 0:
309
296
  return b, 0, 1
310
297
  gcd, y, x = _extended_gcd(b % a, a)
@@ -360,9 +347,9 @@ def _arithmetic_gate(identifier: str, size: int, func: _IntsToIntCallable) -> Ce
360
347
  )
361
348
 
362
349
 
363
- ARITHMETIC_OP_TABLE: Dict[str, _QuirkArithmeticCallable] = {}
350
+ ARITHMETIC_OP_TABLE: dict[str, _QuirkArithmeticCallable] = {}
364
351
  # Caching is necessary in order to avoid overwriting entries in the table.
365
- _cached_cells: Optional[Tuple[CellMaker, ...]] = None
352
+ _cached_cells: tuple[CellMaker, ...] | None = None
366
353
 
367
354
 
368
355
  def generate_all_arithmetic_cell_makers() -> Iterable[CellMaker]: