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
@@ -21,7 +21,7 @@ from __future__ import annotations
21
21
 
22
22
  import dataclasses
23
23
  import math
24
- from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
24
+ from typing import Any, Sequence, TYPE_CHECKING
25
25
 
26
26
  import numpy as np
27
27
  import quimb.tensor as qtn
@@ -43,7 +43,7 @@ class MPSOptions:
43
43
  # How to split the tensor. Refer to the Quimb documentation for the exact meaning.
44
44
  method: str = 'svds'
45
45
  # If integer, the maxmimum number of singular values to keep, regardless of ``cutoff``.
46
- max_bond: Optional[int] = None
46
+ max_bond: int | None = None
47
47
  # Method with which to apply the cutoff threshold. Refer to the Quimb documentation.
48
48
  cutoff_mode: str = 'rsum2'
49
49
  # The threshold below which to discard singular values. Refer to the Quimb documentation.
@@ -63,7 +63,7 @@ class MPSSimulator(
63
63
  noise: cirq.NOISE_MODEL_LIKE = None,
64
64
  seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
65
65
  simulation_options: MPSOptions = MPSOptions(),
66
- grouping: Optional[Dict[cirq.Qid, int]] = None,
66
+ grouping: dict[cirq.Qid, int] | None = None,
67
67
  ):
68
68
  """Creates instance of `MPSSimulator`.
69
69
 
@@ -86,7 +86,7 @@ class MPSSimulator(
86
86
 
87
87
  def _create_partial_simulation_state(
88
88
  self,
89
- initial_state: Union[int, MPSState],
89
+ initial_state: int | MPSState,
90
90
  qubits: Sequence[cirq.Qid],
91
91
  classical_data: cirq.ClassicalDataStore,
92
92
  ) -> MPSState:
@@ -122,7 +122,7 @@ class MPSSimulator(
122
122
  def _create_simulator_trial_result(
123
123
  self,
124
124
  params: cirq.ParamResolver,
125
- measurements: Dict[str, np.ndarray],
125
+ measurements: dict[str, np.ndarray],
126
126
  final_simulator_state: cirq.SimulationStateBase[MPSState],
127
127
  ) -> MPSTrialResult:
128
128
  """Creates a single trial results with the measurements.
@@ -147,7 +147,7 @@ class MPSTrialResult(simulator_base.SimulationTrialResultBase['MPSState']):
147
147
  def __init__(
148
148
  self,
149
149
  params: cirq.ParamResolver,
150
- measurements: Dict[str, np.ndarray],
150
+ measurements: dict[str, np.ndarray],
151
151
  final_simulator_state: cirq.SimulationStateBase[MPSState],
152
152
  ) -> None:
153
153
  super().__init__(
@@ -212,11 +212,11 @@ class _MPSHandler(qis.QuantumStateRepresentation):
212
212
 
213
213
  def __init__(
214
214
  self,
215
- qid_shape: Tuple[int, ...],
216
- grouping: Dict[int, int],
217
- M: List[qtn.Tensor],
215
+ qid_shape: tuple[int, ...],
216
+ grouping: dict[int, int],
217
+ M: list[qtn.Tensor],
218
218
  format_i: str,
219
- estimated_gate_error_list: List[float],
219
+ estimated_gate_error_list: list[float],
220
220
  simulation_options: MPSOptions = MPSOptions(),
221
221
  ):
222
222
  """Creates an MPSQuantumState
@@ -241,8 +241,8 @@ class _MPSHandler(qis.QuantumStateRepresentation):
241
241
  def create(
242
242
  cls,
243
243
  *,
244
- qid_shape: Tuple[int, ...],
245
- grouping: Dict[int, int],
244
+ qid_shape: tuple[int, ...],
245
+ grouping: dict[int, int],
246
246
  initial_state: int = 0,
247
247
  simulation_options: MPSOptions = MPSOptions(),
248
248
  ):
@@ -342,7 +342,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
342
342
  sorted_ind = tuple(sorted(state_vector.inds))
343
343
  return state_vector.fuse({'i': sorted_ind}).data
344
344
 
345
- def partial_trace(self, keep_axes: Set[int]) -> np.ndarray:
345
+ def partial_trace(self, keep_axes: set[int]) -> np.ndarray:
346
346
  """Traces out all qubits except keep_axes.
347
347
 
348
348
  Args:
@@ -484,8 +484,8 @@ class _MPSHandler(qis.QuantumStateRepresentation):
484
484
 
485
485
  def _measure(
486
486
  self, axes: Sequence[int], prng: np.random.RandomState, collapse_state_vector=True
487
- ) -> List[int]:
488
- results: List[int] = []
487
+ ) -> list[int]:
488
+ results: list[int] = []
489
489
 
490
490
  if collapse_state_vector:
491
491
  state = self
@@ -523,7 +523,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
523
523
 
524
524
  def measure(
525
525
  self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None
526
- ) -> List[int]:
526
+ ) -> list[int]:
527
527
  """Measures the MPS.
528
528
 
529
529
  Args:
@@ -547,7 +547,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
547
547
  The samples in order.
548
548
  """
549
549
 
550
- measurements: List[List[int]] = []
550
+ measurements: list[list[int]] = []
551
551
  prng = value.parse_random_state(seed)
552
552
 
553
553
  for _ in range(repetitions):
@@ -566,9 +566,9 @@ class MPSState(SimulationState[_MPSHandler]):
566
566
  qubits: Sequence[cirq.Qid],
567
567
  prng: np.random.RandomState,
568
568
  simulation_options: MPSOptions = MPSOptions(),
569
- grouping: Optional[Dict[cirq.Qid, int]] = None,
569
+ grouping: dict[cirq.Qid, int] | None = None,
570
570
  initial_state: int = 0,
571
- classical_data: Optional[cirq.ClassicalDataStore] = None,
571
+ classical_data: cirq.ClassicalDataStore | None = None,
572
572
  ):
573
573
  """Creates and MPSState
574
574
 
@@ -622,7 +622,7 @@ class MPSState(SimulationState[_MPSHandler]):
622
622
  """
623
623
  return self._state.state_vector()
624
624
 
625
- def partial_trace(self, keep_qubits: Set[cirq.Qid]) -> np.ndarray:
625
+ def partial_trace(self, keep_qubits: set[cirq.Qid]) -> np.ndarray:
626
626
  """Traces out all qubits except keep_qubits.
627
627
 
628
628
  Args:
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import warnings
6
- from typing import cast, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
6
+ from typing import cast, Sequence, TYPE_CHECKING
7
7
 
8
8
  import quimb
9
9
  import quimb.tensor as qtn
@@ -30,10 +30,8 @@ QUIMB_VERSION = _get_quimb_version()
30
30
 
31
31
 
32
32
  def circuit_to_tensors(
33
- circuit: cirq.Circuit,
34
- qubits: Optional[Sequence[cirq.Qid]] = None,
35
- initial_state: Union[int, None] = 0,
36
- ) -> Tuple[List[qtn.Tensor], Dict[cirq.Qid, int], None]:
33
+ circuit: cirq.Circuit, qubits: Sequence[cirq.Qid] | None = None, initial_state: int | None = 0
34
+ ) -> tuple[list[qtn.Tensor], dict[cirq.Qid, int], None]:
37
35
  """Given a circuit, construct a tensor network representation.
38
36
 
39
37
  Indices are named "i{i}_q{x}" where i is a time index and x is a
@@ -67,7 +65,7 @@ def circuit_to_tensors(
67
65
 
68
66
  qubit_frontier = {q: 0 for q in qubits}
69
67
  positions = None
70
- tensors: List[qtn.Tensor] = []
68
+ tensors: list[qtn.Tensor] = []
71
69
 
72
70
  if initial_state == 0:
73
71
  for q in qubits:
@@ -94,7 +92,7 @@ def circuit_to_tensors(
94
92
 
95
93
 
96
94
  def tensor_state_vector(
97
- circuit: cirq.Circuit, qubits: Optional[Sequence[cirq.Qid]] = None
95
+ circuit: cirq.Circuit, qubits: Sequence[cirq.Qid] | None = None
98
96
  ) -> np.ndarray:
99
97
  """Given a circuit contract a tensor network into a final state vector."""
100
98
  if qubits is None:
@@ -107,9 +105,7 @@ def tensor_state_vector(
107
105
  return tn.to_dense(f_inds)
108
106
 
109
107
 
110
- def tensor_unitary(
111
- circuit: cirq.Circuit, qubits: Optional[Sequence[cirq.Qid]] = None
112
- ) -> np.ndarray:
108
+ def tensor_unitary(circuit: cirq.Circuit, qubits: Sequence[cirq.Qid] | None = None) -> np.ndarray:
113
109
  """Given a circuit contract a tensor network into a dense unitary
114
110
  of the circuit."""
115
111
  if qubits is None:
@@ -16,7 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import json
18
18
  import urllib.parse
19
- from typing import Any, cast, Iterable, List, Tuple
19
+ from typing import Any, cast, Iterable
20
20
 
21
21
  from cirq import circuits, devices, ops, protocols
22
22
  from cirq.contrib.quirk.linearize_circuit import linearize_circuit_qubits
@@ -42,7 +42,7 @@ def _try_convert_to_quirk_gate(op: ops.Operation, prefer_unknown_gate_to_failure
42
42
 
43
43
  def _to_quirk_cols(
44
44
  op: ops.Operation, prefer_unknown_gate_to_failure: bool
45
- ) -> Iterable[Tuple[List[Any], bool]]:
45
+ ) -> Iterable[tuple[list[Any], bool]]:
46
46
  gate = _try_convert_to_quirk_gate(op, prefer_unknown_gate_to_failure)
47
47
  qubits = cast(Iterable[devices.LineQubit], op.qubits)
48
48
 
@@ -78,7 +78,7 @@ def circuit_to_quirk_url(
78
78
  circuit = circuit.copy()
79
79
  linearize_circuit_qubits(circuit)
80
80
 
81
- cols: List[List[Any]] = []
81
+ cols: list[list[Any]] = []
82
82
  for moment in circuit:
83
83
  can_merges = []
84
84
  for op in moment.operations:
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Callable, cast, Dict, Optional, Union
17
+ from typing import Any, Callable, cast
18
18
 
19
19
  import numpy as np
20
20
  import sympy
@@ -70,7 +70,7 @@ def _is_supported_formula(formula: sympy.Basic) -> bool:
70
70
  return False
71
71
 
72
72
 
73
- def _val_to_quirk_formula(t: Union[float, sympy.Basic]) -> str:
73
+ def _val_to_quirk_formula(t: float | sympy.Basic) -> str:
74
74
  if isinstance(t, sympy.Basic):
75
75
  if not set(t.free_symbols) <= {sympy.Symbol('t')}:
76
76
  raise ValueError(f'Symbol other than "t": {t!r}.')
@@ -81,7 +81,7 @@ def _val_to_quirk_formula(t: Union[float, sympy.Basic]) -> str:
81
81
  return f'{float(t):.4f}'
82
82
 
83
83
 
84
- def angle_to_exponent_key(t: Union[float, sympy.Basic]) -> Optional[str]:
84
+ def angle_to_exponent_key(t: float | sympy.Basic) -> str | None:
85
85
  if isinstance(t, sympy.Basic):
86
86
  if t == sympy.Symbol('t'):
87
87
  return '^t'
@@ -109,7 +109,7 @@ def angle_to_exponent_key(t: Union[float, sympy.Basic]) -> Optional[str]:
109
109
  return None
110
110
 
111
111
 
112
- def single_qubit_matrix_gate(matrix: Optional[np.ndarray]) -> Optional[QuirkOp]:
112
+ def single_qubit_matrix_gate(matrix: np.ndarray | None) -> QuirkOp | None:
113
113
  if matrix is None or matrix.shape[0] != 2:
114
114
  return None
115
115
 
@@ -137,7 +137,7 @@ def single_qubit_matrix_gate(matrix: Optional[np.ndarray]) -> Optional[QuirkOp]:
137
137
  return QuirkOp({'id': '?', 'matrix': matrix_repr})
138
138
 
139
139
 
140
- def known_quirk_op_for_operation(op: ops.Operation) -> Optional[QuirkOp]:
140
+ def known_quirk_op_for_operation(op: ops.Operation) -> QuirkOp | None:
141
141
  if isinstance(op, ops.GateOperation):
142
142
  return _gate_to_quirk_op(op.gate)
143
143
  if isinstance(op, ops.ControlledOperation):
@@ -145,7 +145,7 @@ def known_quirk_op_for_operation(op: ops.Operation) -> Optional[QuirkOp]:
145
145
  return None
146
146
 
147
147
 
148
- def _gate_to_quirk_op(gate: ops.Gate) -> Optional[QuirkOp]:
148
+ def _gate_to_quirk_op(gate: ops.Gate) -> QuirkOp | None:
149
149
  for gate_type, func in _known_gate_conversions.items():
150
150
  if isinstance(gate, gate_type):
151
151
  return func(gate)
@@ -178,45 +178,45 @@ def z_to_quirk_op(gate: ops.ZPowGate) -> QuirkOp:
178
178
  return xyz_to_quirk_op('z', gate)
179
179
 
180
180
 
181
- def cz_to_quirk_op(gate: ops.CZPowGate) -> Optional[QuirkOp]:
181
+ def cz_to_quirk_op(gate: ops.CZPowGate) -> QuirkOp | None:
182
182
  return z_to_quirk_op(ops.Z**gate.exponent).controlled()
183
183
 
184
184
 
185
- def cnot_to_quirk_op(gate: ops.CXPowGate) -> Optional[QuirkOp]:
185
+ def cnot_to_quirk_op(gate: ops.CXPowGate) -> QuirkOp | None:
186
186
  return x_to_quirk_op(ops.X**gate.exponent).controlled()
187
187
 
188
188
 
189
- def h_to_quirk_op(gate: ops.HPowGate) -> Optional[QuirkOp]:
189
+ def h_to_quirk_op(gate: ops.HPowGate) -> QuirkOp | None:
190
190
  if gate.exponent == 1:
191
191
  return QuirkOp('H')
192
192
  return None
193
193
 
194
194
 
195
- def swap_to_quirk_op(gate: ops.SwapPowGate) -> Optional[QuirkOp]:
195
+ def swap_to_quirk_op(gate: ops.SwapPowGate) -> QuirkOp | None:
196
196
  if gate.exponent == 1:
197
197
  return QuirkOp('Swap', 'Swap', can_merge=False)
198
198
  return None
199
199
 
200
200
 
201
- def cswap_to_quirk_op(gate: ops.CSwapGate) -> Optional[QuirkOp]:
201
+ def cswap_to_quirk_op(gate: ops.CSwapGate) -> QuirkOp | None:
202
202
  return QuirkOp('•', 'Swap', 'Swap', can_merge=False)
203
203
 
204
204
 
205
- def ccx_to_quirk_op(gate: ops.CCXPowGate) -> Optional[QuirkOp]:
205
+ def ccx_to_quirk_op(gate: ops.CCXPowGate) -> QuirkOp | None:
206
206
  e = angle_to_exponent_key(gate.exponent)
207
207
  if e is None:
208
208
  return None
209
209
  return QuirkOp('•', '•', 'X' + e, can_merge=False)
210
210
 
211
211
 
212
- def ccz_to_quirk_op(gate: ops.CCZPowGate) -> Optional[QuirkOp]:
212
+ def ccz_to_quirk_op(gate: ops.CCZPowGate) -> QuirkOp | None:
213
213
  e = angle_to_exponent_key(gate.exponent)
214
214
  if e is None:
215
215
  return None
216
216
  return QuirkOp('•', '•', 'Z' + e, can_merge=False)
217
217
 
218
218
 
219
- def controlled_unwrap(op: ops.ControlledOperation) -> Optional[QuirkOp]:
219
+ def controlled_unwrap(op: ops.ControlledOperation) -> QuirkOp | None:
220
220
  sub = known_quirk_op_for_operation(op.sub_operation)
221
221
  if sub is None:
222
222
  return None
@@ -224,7 +224,7 @@ def controlled_unwrap(op: ops.ControlledOperation) -> Optional[QuirkOp]:
224
224
 
225
225
 
226
226
  _known_gate_conversions = cast(
227
- Dict[type, Callable[[ops.Gate], Optional[QuirkOp]]],
227
+ dict[type, Callable[[ops.Gate], QuirkOp | None]],
228
228
  {
229
229
  ops.CCXPowGate: ccx_to_quirk_op,
230
230
  ops.CCZPowGate: ccz_to_quirk_op,
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import itertools
18
- from typing import Dict, Iterable, Tuple
18
+ from typing import Iterable
19
19
 
20
20
  import networkx as nx
21
21
 
@@ -47,7 +47,7 @@ def _manhattan_distance(qubit1: cirq.GridQubit, qubit2: cirq.GridQubit) -> int:
47
47
  return abs(qubit1.row - qubit2.row) + abs(qubit1.col - qubit2.col)
48
48
 
49
49
 
50
- def nx_qubit_layout(graph: nx.Graph) -> Dict[cirq.Qid, Tuple[float, float]]:
50
+ def nx_qubit_layout(graph: nx.Graph) -> dict[cirq.Qid, tuple[float, float]]:
51
51
  """Return a layout for a graph for nodes which are qubits.
52
52
 
53
53
  This can be used in place of nx.spring_layout or other networkx layouts.
@@ -64,7 +64,7 @@ def nx_qubit_layout(graph: nx.Graph) -> Dict[cirq.Qid, Tuple[float, float]]:
64
64
  >>> nx.draw_networkx(g, pos=pos)
65
65
 
66
66
  """
67
- pos: Dict[cirq.Qid, Tuple[float, float]] = {}
67
+ pos: dict[cirq.Qid, tuple[float, float]] = {}
68
68
 
69
69
  _node_to_i_cache = None
70
70
  for node in graph.nodes:
@@ -15,18 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import itertools
18
- from typing import (
19
- Callable,
20
- cast,
21
- Dict,
22
- Iterable,
23
- List,
24
- Optional,
25
- Sequence,
26
- Set,
27
- Tuple,
28
- TYPE_CHECKING,
29
- )
18
+ from typing import Callable, cast, Iterable, Sequence, TYPE_CHECKING
30
19
 
31
20
  import networkx as nx
32
21
  import numpy as np
@@ -42,7 +31,7 @@ if TYPE_CHECKING:
42
31
  import cirq
43
32
 
44
33
  SWAP = cca.SwapPermutationGate()
45
- QidPair = Tuple[ops.Qid, ops.Qid]
34
+ QidPair = tuple[ops.Qid, ops.Qid]
46
35
 
47
36
 
48
37
  def route_circuit_greedily(
@@ -106,7 +95,7 @@ class _GreedyRouter:
106
95
  *,
107
96
  max_search_radius: int = 1,
108
97
  max_num_empty_steps: int = 5,
109
- initial_mapping: Optional[Dict[ops.Qid, ops.Qid]] = None,
98
+ initial_mapping: dict[ops.Qid, ops.Qid] | None = None,
110
99
  can_reorder: Callable[[ops.Operation, ops.Operation], bool] = lambda op1, op2: not set(
111
100
  op1.qubits
112
101
  )
@@ -117,7 +106,7 @@ class _GreedyRouter:
117
106
  self.prng = value.parse_random_state(random_state)
118
107
 
119
108
  self.device_graph = device_graph
120
- self.physical_distances: Dict[QidPair, int] = {
109
+ self.physical_distances: dict[QidPair, int] = {
121
110
  (a, b): d
122
111
  for a, neighbor_distances in nx.shortest_path_length(device_graph)
123
112
  for b, d in neighbor_distances.items()
@@ -126,9 +115,9 @@ class _GreedyRouter:
126
115
  self.remaining_dag = circuitdag.CircuitDag.from_circuit(circuit, can_reorder=can_reorder)
127
116
  self.logical_qubits = list(self.remaining_dag.all_qubits())
128
117
  self.physical_qubits = list(self.device_graph.nodes)
129
- self.edge_sets: Dict[int, List[Sequence[QidPair]]] = {}
118
+ self.edge_sets: dict[int, list[Sequence[QidPair]]] = {}
130
119
 
131
- self.physical_ops: List[ops.Operation] = []
120
+ self.physical_ops: list[ops.Operation] = []
132
121
 
133
122
  self.set_initial_mapping(initial_mapping)
134
123
 
@@ -155,7 +144,7 @@ class _GreedyRouter:
155
144
  logical qubits."""
156
145
  return (self._log_to_phys[q] for q in qubits)
157
146
 
158
- def phys_to_log(self, *qubits: cirq.Qid) -> Iterable[Optional[ops.Qid]]:
147
+ def phys_to_log(self, *qubits: cirq.Qid) -> Iterable[ops.Qid | None]:
159
148
  """Returns an iterator over the logical qubits that map to the given
160
149
  physical qubits."""
161
150
  return (self._phys_to_log[q] for q in qubits)
@@ -176,7 +165,7 @@ class _GreedyRouter:
176
165
  if l is not None:
177
166
  self._log_to_phys[l] = p
178
167
 
179
- def set_initial_mapping(self, initial_mapping: Optional[Dict[ops.Qid, ops.Qid]] = None):
168
+ def set_initial_mapping(self, initial_mapping: dict[ops.Qid, ops.Qid] | None = None):
180
169
  """Sets the internal state according to an initial mapping.
181
170
 
182
171
  Args:
@@ -237,7 +226,7 @@ class _GreedyRouter:
237
226
  logical qubits."""
238
227
  return self.physical_distances[cast(QidPair, tuple(self.log_to_phys(*edge)))]
239
228
 
240
- def swap_along_path(self, path: Tuple[ops.Qid]):
229
+ def swap_along_path(self, path: tuple[ops.Qid]):
241
230
  """Adds SWAPs to move a logical qubit along a specified path."""
242
231
  for i in range(len(path) - 1):
243
232
  self.apply_swap(cast(QidPair, path[i : i + 2]))
@@ -317,7 +306,7 @@ class _GreedyRouter:
317
306
  assert ops_are_consistent_with_device_graph(self.physical_ops, self.device_graph)
318
307
 
319
308
 
320
- def _get_dominated_indices(vectors: List[np.ndarray]) -> Set[int]:
309
+ def _get_dominated_indices(vectors: list[np.ndarray]) -> set[int]:
321
310
  """Get the indices of vectors that are element-wise at least some other
322
311
  vector.
323
312
  """
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import itertools
18
- from typing import cast, Dict, Hashable, TYPE_CHECKING
18
+ from typing import cast, Hashable, TYPE_CHECKING
19
19
 
20
20
  import networkx as nx
21
21
  from sortedcontainers import SortedDict, SortedSet
@@ -35,7 +35,7 @@ def get_initial_mapping(
35
35
  logical_graph: nx.Graph,
36
36
  device_graph: nx.Graph,
37
37
  random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
38
- ) -> Dict[ops.Qid, ops.Qid]:
38
+ ) -> dict[ops.Qid, ops.Qid]:
39
39
  """Gets an initial mapping of logical to physical qubits for routing.
40
40
 
41
41
  Args:
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Dict, Iterable, TYPE_CHECKING
17
+ from typing import Iterable, TYPE_CHECKING
18
18
 
19
19
  import cirq.contrib.acquaintance as cca
20
20
  from cirq import ops
@@ -37,13 +37,13 @@ class SwapNetwork:
37
37
  initial_mapping: The initial mapping from physical to logical qubits.
38
38
  """
39
39
 
40
- def __init__(self, circuit: cirq.Circuit, initial_mapping: Dict[cirq.Qid, cirq.Qid]) -> None:
40
+ def __init__(self, circuit: cirq.Circuit, initial_mapping: dict[cirq.Qid, cirq.Qid]) -> None:
41
41
  if not all(isinstance(i, ops.Qid) for I in initial_mapping.items() for i in I):
42
42
  raise ValueError('Mapping must be from Qids to Qids.')
43
43
  self.circuit = circuit
44
44
  self.initial_mapping = initial_mapping
45
45
 
46
- def final_mapping(self) -> Dict[cirq.Qid, cirq.Qid]:
46
+ def final_mapping(self) -> dict[cirq.Qid, cirq.Qid]:
47
47
  mapping = dict(self.initial_mapping)
48
48
  cca.update_mapping(mapping, self.circuit.all_operations())
49
49
  return mapping
@@ -16,7 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import operator
18
18
  import re
19
- from typing import Callable, Iterable, List, TYPE_CHECKING
19
+ from typing import Callable, Iterable, TYPE_CHECKING
20
20
 
21
21
  import networkx as nx
22
22
 
@@ -31,7 +31,7 @@ if TYPE_CHECKING:
31
31
  BINARY_OP_PREDICATE = Callable[[ops.Operation, ops.Operation], bool]
32
32
 
33
33
 
34
- def get_time_slices(dag: CircuitDag) -> List[nx.Graph]:
34
+ def get_time_slices(dag: CircuitDag) -> list[nx.Graph]:
35
35
  """Slices the DAG into logical graphs.
36
36
 
37
37
  Each time slice is a graph whose vertices are qubits and whose edges
@@ -17,7 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import time
20
- from typing import Dict, List, Optional, Tuple, TYPE_CHECKING, Union
20
+ from typing import TYPE_CHECKING
21
21
 
22
22
  import numpy as np
23
23
 
@@ -30,8 +30,8 @@ if TYPE_CHECKING:
30
30
 
31
31
  def _validate_input(
32
32
  input_circuits: list[circuits.Circuit],
33
- circuit_repetitions: Union[int, list[int]],
34
- rng_or_seed: Union[np.random.Generator, int],
33
+ circuit_repetitions: int | list[int],
34
+ rng_or_seed: np.random.Generator | int,
35
35
  num_random_bitstrings: int,
36
36
  readout_repetitions: int,
37
37
  ):
@@ -159,12 +159,12 @@ def _analyze_readout_results(
159
159
  def run_shuffled_with_readout_benchmarking(
160
160
  input_circuits: list[circuits.Circuit],
161
161
  sampler: work.Sampler,
162
- circuit_repetitions: Union[int, list[int]],
163
- rng_or_seed: Union[np.random.Generator, int],
162
+ circuit_repetitions: int | list[int],
163
+ rng_or_seed: np.random.Generator | int,
164
164
  num_random_bitstrings: int = 100,
165
165
  readout_repetitions: int = 1000,
166
- qubits: Optional[Union[List[ops.Qid], List[List[ops.Qid]]]] = None,
167
- ) -> tuple[list[ResultDict], Dict[Tuple[ops.Qid, ...], SingleQubitReadoutCalibrationResult]]:
166
+ qubits: list[ops.Qid] | list[list[ops.Qid]] | None = None,
167
+ ) -> tuple[list[ResultDict], dict[tuple[ops.Qid, ...], SingleQubitReadoutCalibrationResult]]:
168
168
  """Run the circuits in a shuffled order with readout error benchmarking.
169
169
 
170
170
  Args:
@@ -192,7 +192,7 @@ def run_shuffled_with_readout_benchmarking(
192
192
  )
193
193
 
194
194
  # If input qubits is None, extract qubits from input circuits
195
- qubits_to_measure: List[List[ops.Qid]] = []
195
+ qubits_to_measure: list[list[ops.Qid]] = []
196
196
  if qubits is None:
197
197
  qubits_set: set[ops.Qid] = set()
198
198
  for circuit in input_circuits:
cirq/contrib/svg/svg.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import cast, Dict, List, Tuple, TYPE_CHECKING
5
+ from typing import cast, TYPE_CHECKING
6
6
 
7
7
  import matplotlib.font_manager
8
8
  import matplotlib.textpath
@@ -63,7 +63,7 @@ def _text(x: float, y: float, text: str, fontsize: int = 14):
63
63
 
64
64
  def _fit_horizontal(
65
65
  tdd: cirq.TextDiagramDrawer, ref_boxwidth: float, col_padding: float
66
- ) -> Tuple[List[float], List[float]]:
66
+ ) -> tuple[list[float], list[float]]:
67
67
  """Figure out the horizontal spacing of columns to fit everything in.
68
68
 
69
69
  Returns:
@@ -93,7 +93,7 @@ def _fit_horizontal(
93
93
 
94
94
  def _fit_vertical(
95
95
  tdd: cirq.TextDiagramDrawer, ref_boxheight: float, row_padding: float
96
- ) -> Tuple[List[float], List[float], Dict[float, int]]:
96
+ ) -> tuple[list[float], list[float], dict[float, int]]:
97
97
  """Return data structures used to turn tdd vertical coordinates into
98
98
  well-spaced SVG coordinates.
99
99
 
@@ -16,7 +16,7 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import cast, FrozenSet, Iterable, Mapping, Optional, Tuple, TYPE_CHECKING
19
+ from typing import cast, Iterable, Mapping, TYPE_CHECKING
20
20
 
21
21
  import networkx as nx
22
22
 
@@ -33,10 +33,10 @@ class GridDeviceMetadata(device.DeviceMetadata):
33
33
 
34
34
  def __init__(
35
35
  self,
36
- qubit_pairs: Iterable[Tuple[cirq.GridQubit, cirq.GridQubit]],
36
+ qubit_pairs: Iterable[tuple[cirq.GridQubit, cirq.GridQubit]],
37
37
  gateset: cirq.Gateset,
38
- gate_durations: Optional[Mapping[cirq.GateFamily, cirq.Duration]] = None,
39
- all_qubits: Optional[Iterable[cirq.GridQubit]] = None,
38
+ gate_durations: Mapping[cirq.GateFamily, cirq.Duration] | None = None,
39
+ all_qubits: Iterable[cirq.GridQubit] | None = None,
40
40
  compilation_target_gatesets: Iterable[cirq.CompilationTargetGateset] = (),
41
41
  ):
42
42
  """Create a GridDeviceMetadata object.
@@ -118,16 +118,16 @@ class GridDeviceMetadata(device.DeviceMetadata):
118
118
  self._gate_durations = gate_durations
119
119
 
120
120
  @property
121
- def qubit_set(self) -> FrozenSet[cirq.GridQubit]:
121
+ def qubit_set(self) -> frozenset[cirq.GridQubit]:
122
122
  """Returns the set of grid qubits on the device.
123
123
 
124
124
  Returns:
125
125
  Frozenset of qubits on device.
126
126
  """
127
- return cast(FrozenSet['cirq.GridQubit'], super().qubit_set)
127
+ return cast(frozenset['cirq.GridQubit'], super().qubit_set)
128
128
 
129
129
  @property
130
- def qubit_pairs(self) -> FrozenSet[FrozenSet[cirq.GridQubit]]:
130
+ def qubit_pairs(self) -> frozenset[frozenset[cirq.GridQubit]]:
131
131
  """Returns the set of all couple-able qubits on the device.
132
132
 
133
133
  Each element in the outer frozenset is a 2-element frozenset representing a bidirectional
@@ -136,7 +136,7 @@ class GridDeviceMetadata(device.DeviceMetadata):
136
136
  return self._qubit_pairs
137
137
 
138
138
  @property
139
- def isolated_qubits(self) -> FrozenSet[cirq.GridQubit]:
139
+ def isolated_qubits(self) -> frozenset[cirq.GridQubit]:
140
140
  """Returns the set of all isolated qubits on the device (if applicable)."""
141
141
  return self._isolated_qubits
142
142
 
@@ -146,12 +146,12 @@ class GridDeviceMetadata(device.DeviceMetadata):
146
146
  return self._gateset
147
147
 
148
148
  @property
149
- def compilation_target_gatesets(self) -> Tuple[cirq.CompilationTargetGateset, ...]:
149
+ def compilation_target_gatesets(self) -> tuple[cirq.CompilationTargetGateset, ...]:
150
150
  """Returns a sequence of valid `cirq.CompilationTargetGateset`s for this device."""
151
151
  return self._compilation_target_gatesets
152
152
 
153
153
  @property
154
- def gate_durations(self) -> Optional[Mapping[cirq.GateFamily, cirq.Duration]]:
154
+ def gate_durations(self) -> Mapping[cirq.GateFamily, cirq.Duration] | None:
155
155
  """Get a dictionary mapping from gate family to duration for gates.
156
156
 
157
157
  To look up the duration of a specific gate instance / gate type / operation which is part of