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
@@ -19,7 +19,7 @@ from __future__ import annotations
19
19
  import abc
20
20
  import warnings
21
21
  from functools import cached_property
22
- from typing import Any, Dict, Generic, Iterator, Sequence, Type, TYPE_CHECKING, TypeVar
22
+ from typing import Any, Generic, Iterator, Sequence, TYPE_CHECKING, TypeVar
23
23
 
24
24
  import numpy as np
25
25
 
@@ -50,7 +50,7 @@ class SimulatesIntermediateStateVector(
50
50
  def __init__(
51
51
  self,
52
52
  *,
53
- dtype: Type[np.complexfloating] = np.complex64,
53
+ dtype: type[np.complexfloating] = np.complex64,
54
54
  noise: cirq.NOISE_MODEL_LIKE = None,
55
55
  seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
56
56
  split_untangled_states: bool = False,
@@ -62,7 +62,7 @@ class SimulatesIntermediateStateVector(
62
62
  def _create_simulator_trial_result(
63
63
  self,
64
64
  params: cirq.ParamResolver,
65
- measurements: Dict[str, np.ndarray],
65
+ measurements: dict[str, np.ndarray],
66
66
  final_simulator_state: cirq.SimulationStateBase[cirq.StateVectorSimulationState],
67
67
  ) -> cirq.StateVectorTrialResult:
68
68
  return StateVectorTrialResult(
@@ -116,7 +116,7 @@ class StateVectorTrialResult(
116
116
  def __init__(
117
117
  self,
118
118
  params: cirq.ParamResolver,
119
- measurements: Dict[str, np.ndarray],
119
+ measurements: dict[str, np.ndarray],
120
120
  final_simulator_state: cirq.SimulationStateBase[cirq.StateVectorSimulationState],
121
121
  ) -> None:
122
122
  super().__init__(
@@ -17,7 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import numbers
20
- from typing import Any, Callable, List, Optional, Tuple, TYPE_CHECKING, Union
20
+ from typing import Any, Callable, TYPE_CHECKING
21
21
 
22
22
  import sympy
23
23
 
@@ -28,7 +28,7 @@ if TYPE_CHECKING:
28
28
  import cirq
29
29
 
30
30
 
31
- def flatten(val: Any) -> Tuple[Any, ExpressionMap]:
31
+ def flatten(val: Any) -> tuple[Any, ExpressionMap]:
32
32
  """Creates a copy of `val` with any symbols or expressions replaced with
33
33
  new symbols. `val` can be a `Circuit`, `Gate`, `Operation`, or other
34
34
  type.
@@ -114,8 +114,8 @@ def flatten(val: Any) -> Tuple[Any, ExpressionMap]:
114
114
 
115
115
 
116
116
  def flatten_with_sweep(
117
- val: Any, sweep: Union[sweeps.Sweep, List[resolver.ParamResolver]]
118
- ) -> Tuple[Any, sweeps.Sweep]:
117
+ val: Any, sweep: sweeps.Sweep | list[resolver.ParamResolver]
118
+ ) -> tuple[Any, sweeps.Sweep]:
119
119
  """Creates a copy of `val` with any symbols or expressions replaced with
120
120
  new symbols. `val` can be a `Circuit`, `Gate`, `Operation`, or other
121
121
  type. Also transforms a sweep over the symbols in `val` to a sweep over the
@@ -149,7 +149,7 @@ def flatten_with_sweep(
149
149
 
150
150
  def flatten_with_params(
151
151
  val: Any, params: resolver.ParamResolverOrSimilarType
152
- ) -> Tuple[Any, resolver.ParamDictType]:
152
+ ) -> tuple[Any, resolver.ParamDictType]:
153
153
  """Creates a copy of `val` with any symbols or expressions replaced with
154
154
  new symbols. `val` can be a `Circuit`, `Gate`, `Operation`, or other
155
155
  type. Also transforms a dictionary of symbol values for `val` to an
@@ -201,9 +201,9 @@ class _ParamFlattener(resolver.ParamResolver):
201
201
 
202
202
  def __init__(
203
203
  self,
204
- param_dict: Optional[resolver.ParamResolverOrSimilarType] = None,
204
+ param_dict: resolver.ParamResolverOrSimilarType | None = None,
205
205
  *, # Force keyword args
206
- get_param_name: Optional[Callable[[sympy.Expr], str]] = None,
206
+ get_param_name: Callable[[sympy.Expr], str] | None = None,
207
207
  ):
208
208
  """Initializes a new _ParamFlattener.
209
209
 
@@ -253,7 +253,7 @@ class _ParamFlattener(resolver.ParamResolver):
253
253
  return symbol
254
254
 
255
255
  def value_of(
256
- self, value: Union[cirq.TParamKey, cirq.TParamValComplex], recursive: bool = False
256
+ self, value: cirq.TParamKey | cirq.TParamValComplex, recursive: bool = False
257
257
  ) -> cirq.TParamValComplex:
258
258
  """Resolves a symbol or expression to a new symbol unique to that value.
259
259
 
@@ -329,9 +329,7 @@ class ExpressionMap(dict):
329
329
  """
330
330
  super().__init__(*args, **kwargs)
331
331
 
332
- def transform_sweep(
333
- self, sweep: Union[sweeps.Sweep, List[resolver.ParamResolver]]
334
- ) -> sweeps.Sweep:
332
+ def transform_sweep(self, sweep: sweeps.Sweep | list[resolver.ParamResolver]) -> sweeps.Sweep:
335
333
  """Returns a sweep to use with a circuit flattened earlier with
336
334
  `cirq.flatten`.
337
335
 
@@ -346,7 +344,7 @@ class ExpressionMap(dict):
346
344
  sweep: The sweep to transform.
347
345
  """
348
346
  sweep = sweepable.to_sweep(sweep)
349
- param_list: List[resolver.ParamDictType] = []
347
+ param_list: list[resolver.ParamDictType] = []
350
348
  for r in sweep:
351
349
  param_dict: resolver.ParamDictType = {}
352
350
  for formula, sym in self.items():
@@ -383,8 +381,8 @@ class ExpressionMap(dict):
383
381
 
384
382
 
385
383
  def _ensure_not_str(
386
- param: Union[sympy.Expr, cirq.TParamValComplex, str],
387
- ) -> Union[sympy.Expr, cirq.TParamValComplex]:
384
+ param: sympy.Expr | cirq.TParamValComplex | str,
385
+ ) -> sympy.Expr | cirq.TParamValComplex:
388
386
  if isinstance(param, str):
389
387
  return sympy.Symbol(param)
390
388
  return param
cirq/study/resolver.py CHANGED
@@ -17,7 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import numbers
20
- from typing import Any, cast, Dict, Iterator, Mapping, Optional, TYPE_CHECKING, Union
20
+ from typing import Any, cast, Iterator, Mapping, TYPE_CHECKING, Union
21
21
 
22
22
  import numpy as np
23
23
  import sympy
@@ -30,7 +30,7 @@ if TYPE_CHECKING:
30
30
  import cirq
31
31
 
32
32
 
33
- ParamDictType = Dict['cirq.TParamKey', 'cirq.TParamValComplex']
33
+ ParamDictType = dict['cirq.TParamKey', 'cirq.TParamValComplex']
34
34
  ParamMappingType = Mapping['cirq.TParamKey', 'cirq.TParamValComplex']
35
35
  document(ParamDictType, """Dictionary from symbols to values.""")
36
36
  document(ParamMappingType, """Immutable map from symbols to values.""")
@@ -73,7 +73,7 @@ class ParamResolver:
73
73
  if hasattr(self, 'param_dict'):
74
74
  return # Already initialized. Got wrapped as part of the __new__.
75
75
 
76
- self._param_hash: Optional[int] = None
76
+ self._param_hash: int | None = None
77
77
  self._param_dict = cast(ParamDictType, {} if param_dict is None else param_dict)
78
78
  for key in self._param_dict:
79
79
  if isinstance(key, sympy.Expr) and not isinstance(key, sympy.Symbol):
@@ -85,7 +85,7 @@ class ParamResolver:
85
85
  return self._param_dict
86
86
 
87
87
  def value_of(
88
- self, value: Union[cirq.TParamKey, cirq.TParamValComplex], recursive: bool = True
88
+ self, value: cirq.TParamKey | cirq.TParamValComplex, recursive: bool = True
89
89
  ) -> cirq.TParamValComplex:
90
90
  """Attempt to resolve a parameter to its assigned value.
91
91
 
@@ -217,7 +217,7 @@ class ParamResolver:
217
217
  return self._deep_eval_map[value]
218
218
 
219
219
  def _resolve_parameters_(self, resolver: ParamResolver, recursive: bool) -> ParamResolver:
220
- new_dict: Dict[cirq.TParamKey, Union[float, str, sympy.Symbol, sympy.Expr]] = {
220
+ new_dict: dict[cirq.TParamKey, float | str | sympy.Symbol | sympy.Expr] = {
221
221
  k: k for k in resolver
222
222
  }
223
223
  new_dict.update({k: self.value_of(k, recursive) for k in self})
@@ -228,15 +228,13 @@ class ParamResolver:
228
228
  return ParamResolver()._resolve_parameters_(new_resolver, recursive=True)
229
229
  return ParamResolver(cast(ParamDictType, new_dict))
230
230
 
231
- def __iter__(self) -> Iterator[Union[str, sympy.Expr]]:
231
+ def __iter__(self) -> Iterator[str | sympy.Expr]:
232
232
  return iter(self._param_dict)
233
233
 
234
234
  def __bool__(self) -> bool:
235
235
  return bool(self._param_dict)
236
236
 
237
- def __getitem__(
238
- self, key: Union[cirq.TParamKey, cirq.TParamValComplex]
239
- ) -> cirq.TParamValComplex:
237
+ def __getitem__(self, key: cirq.TParamKey | cirq.TParamValComplex) -> cirq.TParamValComplex:
240
238
  return self.value_of(key)
241
239
 
242
240
  def __hash__(self) -> int:
@@ -244,7 +242,7 @@ class ParamResolver:
244
242
  self._param_hash = hash(frozenset(self._param_dict.items()))
245
243
  return self._param_hash
246
244
 
247
- def __getstate__(self) -> Dict[str, Any]:
245
+ def __getstate__(self) -> dict[str, Any]:
248
246
  # clear cached hash value when pickling, see #6674
249
247
  state = self.__dict__
250
248
  if state["_param_hash"] is not None:
@@ -268,7 +266,7 @@ class ParamResolver:
268
266
  )
269
267
  return f'cirq.ParamResolver({param_dict_repr})'
270
268
 
271
- def _json_dict_(self) -> Dict[str, Any]:
269
+ def _json_dict_(self) -> dict[str, Any]:
272
270
  return {
273
271
  # JSON requires mappings to have keys of basic types.
274
272
  'param_dict': list(self._param_dict.items())
cirq/study/result.py CHANGED
@@ -19,20 +19,7 @@ from __future__ import annotations
19
19
  import abc
20
20
  import collections
21
21
  import io
22
- from typing import (
23
- Any,
24
- Callable,
25
- cast,
26
- Dict,
27
- Iterable,
28
- Mapping,
29
- Optional,
30
- Sequence,
31
- Tuple,
32
- TYPE_CHECKING,
33
- TypeVar,
34
- Union,
35
- )
22
+ from typing import Any, Callable, cast, Iterable, Mapping, Sequence, TYPE_CHECKING, TypeVar, Union
36
23
 
37
24
  import numpy as np
38
25
  import pandas as pd
@@ -48,7 +35,7 @@ T = TypeVar('T')
48
35
  TMeasurementKey = Union[str, 'cirq.Qid', Iterable['cirq.Qid']]
49
36
 
50
37
 
51
- def _tuple_of_big_endian_int(bit_groups: Iterable[Any]) -> Tuple[int, ...]:
38
+ def _tuple_of_big_endian_int(bit_groups: Iterable[Any]) -> tuple[int, ...]:
52
39
  """Returns the big-endian integers specified by groups of bits.
53
40
 
54
41
  Args:
@@ -170,7 +157,7 @@ class Result(abc.ABC):
170
157
  self,
171
158
  *, # Forces keyword args.
172
159
  keys: Iterable[TMeasurementKey],
173
- fold_func: Callable[[Tuple], T] = cast(Callable[[Tuple], T], _tuple_of_big_endian_int),
160
+ fold_func: Callable[[tuple], T] = cast(Callable[[tuple], T], _tuple_of_big_endian_int),
174
161
  ) -> collections.Counter:
175
162
  """Counts the number of times combined measurement results occurred.
176
163
 
@@ -229,7 +216,7 @@ class Result(abc.ABC):
229
216
  self,
230
217
  *, # Forces keyword args.
231
218
  key: TMeasurementKey,
232
- fold_func: Callable[[Tuple], T] = cast(Callable[[Tuple], T], value.big_endian_bits_to_int),
219
+ fold_func: Callable[[tuple], T] = cast(Callable[[tuple], T], value.big_endian_bits_to_int),
233
220
  ) -> collections.Counter:
234
221
  """Counts the number of times a measurement result occurred.
235
222
 
@@ -291,7 +278,7 @@ class Result(abc.ABC):
291
278
  raise ValueError(
292
279
  f'Cannot add results with different measurement shapes: {shape} != {other_shape}'
293
280
  )
294
- all_records: Dict[str, np.ndarray] = {}
281
+ all_records: dict[str, np.ndarray] = {}
295
282
  for key in other.records:
296
283
  all_records[key] = np.append(self.records[key], other.records[key], axis=0)
297
284
  return ResultDict(params=self.params, records=all_records)
@@ -312,9 +299,9 @@ class ResultDict(Result):
312
299
  def __init__(
313
300
  self,
314
301
  *, # Forces keyword args.
315
- params: Optional[resolver.ParamResolver] = None,
316
- measurements: Optional[Mapping[str, np.ndarray]] = None,
317
- records: Optional[Mapping[str, np.ndarray]] = None,
302
+ params: resolver.ParamResolver | None = None,
303
+ measurements: Mapping[str, np.ndarray] | None = None,
304
+ records: Mapping[str, np.ndarray] | None = None,
318
305
  ) -> None:
319
306
  """Inits Result.
320
307
 
@@ -341,7 +328,7 @@ class ResultDict(Result):
341
328
  self._params = params
342
329
  self._measurements = measurements
343
330
  self._records = records
344
- self._data: Optional[pd.DataFrame] = None
331
+ self._data: pd.DataFrame | None = None
345
332
 
346
333
  @property
347
334
  def params(self) -> cirq.ParamResolver:
@@ -435,7 +422,7 @@ class ResultDict(Result):
435
422
  return cls._from_packed_records(params=params, records=kwargs['records'])
436
423
 
437
424
 
438
- def _pack_digits(digits: np.ndarray, pack_bits: str = 'auto') -> Tuple[str, bool]:
425
+ def _pack_digits(digits: np.ndarray, pack_bits: str = 'auto') -> tuple[str, bool]:
439
426
  """Returns a string of packed digits and a boolean indicating whether the
440
427
  digits were packed as binary values.
441
428
 
@@ -474,7 +461,7 @@ def _pack_bits(bits: np.ndarray) -> str:
474
461
 
475
462
 
476
463
  def _unpack_digits(
477
- packed_digits: str, binary: bool, dtype: Union[None, str], shape: Union[None, Sequence[int]]
464
+ packed_digits: str, binary: bool, dtype: None | str, shape: None | Sequence[int]
478
465
  ) -> np.ndarray:
479
466
  """The opposite of `_pack_digits`.
480
467
 
cirq/study/sweepable.py CHANGED
@@ -17,7 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import warnings
20
- from typing import cast, Iterable, Iterator, List, Optional, Sequence, Union
20
+ from typing import cast, Iterable, Iterator, Sequence, Union
21
21
 
22
22
  from typing_extensions import Protocol
23
23
 
@@ -25,7 +25,7 @@ from cirq._doc import document
25
25
  from cirq.study.resolver import ParamResolver, ParamResolverOrSimilarType
26
26
  from cirq.study.sweeps import dict_to_product_sweep, ListSweep, Points, Sweep, UnitSweep, Zip
27
27
 
28
- SweepLike = Union[ParamResolverOrSimilarType, Sweep]
28
+ SweepLike = ParamResolverOrSimilarType | Sweep
29
29
  document(SweepLike, """An object similar to an iterable of parameter resolvers.""")
30
30
 
31
31
 
@@ -37,7 +37,7 @@ class _Sweepable(Protocol):
37
37
  pass
38
38
 
39
39
 
40
- Sweepable = Union[SweepLike, _Sweepable]
40
+ Sweepable = SweepLike | _Sweepable
41
41
  document(Sweepable, """An object or collection of objects representing a parameter sweep.""")
42
42
 
43
43
 
@@ -47,7 +47,7 @@ def to_resolvers(sweepable: Sweepable) -> Iterator[ParamResolver]:
47
47
  yield from sweep
48
48
 
49
49
 
50
- def to_sweeps(sweepable: Sweepable, metadata: Optional[dict] = None) -> List[Sweep]:
50
+ def to_sweeps(sweepable: Sweepable, metadata: dict | None = None) -> list[Sweep]:
51
51
  """Converts a Sweepable to a list of Sweeps."""
52
52
  if sweepable is None:
53
53
  return [UnitSweep]
@@ -101,7 +101,7 @@ def to_sweep(
101
101
  raise TypeError(f'Unexpected sweep-like value: {sweep_or_resolver_list}')
102
102
 
103
103
 
104
- def _resolver_to_sweep(resolver: ParamResolver, metadata: Optional[dict]) -> Sweep:
104
+ def _resolver_to_sweep(resolver: ParamResolver, metadata: dict | None) -> Sweep:
105
105
  params = resolver.param_dict
106
106
  if not params:
107
107
  return UnitSweep
cirq/study/sweeps.py CHANGED
@@ -17,20 +17,7 @@ from __future__ import annotations
17
17
  import abc
18
18
  import collections
19
19
  import itertools
20
- from typing import (
21
- Any,
22
- cast,
23
- Dict,
24
- Iterable,
25
- Iterator,
26
- List,
27
- Optional,
28
- overload,
29
- Sequence,
30
- Tuple,
31
- TYPE_CHECKING,
32
- Union,
33
- )
20
+ from typing import Any, cast, Iterable, Iterator, overload, Sequence, TYPE_CHECKING, Union
34
21
 
35
22
  import sympy
36
23
 
@@ -41,8 +28,8 @@ from cirq.study import resolver
41
28
  if TYPE_CHECKING:
42
29
  import cirq
43
30
 
44
- Params = Iterable[Tuple['cirq.TParamKey', 'cirq.TParamVal']]
45
- ProductOrZipSweepLike = Dict['cirq.TParamKey', Union['cirq.TParamVal', Sequence['cirq.TParamVal']]]
31
+ Params = Iterable[tuple['cirq.TParamKey', 'cirq.TParamVal']]
32
+ ProductOrZipSweepLike = dict['cirq.TParamKey', Union['cirq.TParamVal', Sequence['cirq.TParamVal']]]
46
33
 
47
34
 
48
35
  def _check_duplicate_keys(sweeps):
@@ -75,7 +62,7 @@ class Sweep(metaclass=abc.ABCMeta):
75
62
  """
76
63
 
77
64
  def __mul__(self, other: Sweep) -> Sweep:
78
- factors: List[Sweep] = []
65
+ factors: list[Sweep] = []
79
66
  if isinstance(self, Product):
80
67
  factors.extend(self.factors)
81
68
  else:
@@ -89,7 +76,7 @@ class Sweep(metaclass=abc.ABCMeta):
89
76
  return Product(*factors)
90
77
 
91
78
  def __add__(self, other: Sweep) -> Sweep:
92
- sweeps: List[Sweep] = []
79
+ sweeps: list[Sweep] = []
93
80
  if isinstance(self, Zip):
94
81
  sweeps.extend(self.sweeps)
95
82
  else:
@@ -111,7 +98,7 @@ class Sweep(metaclass=abc.ABCMeta):
111
98
 
112
99
  @property
113
100
  @abc.abstractmethod
114
- def keys(self) -> List[cirq.TParamKey]:
101
+ def keys(self) -> list[cirq.TParamKey]:
115
102
  """The keys for the all of the sympy.Symbols that are resolved."""
116
103
 
117
104
  @abc.abstractmethod
@@ -131,7 +118,7 @@ class Sweep(metaclass=abc.ABCMeta):
131
118
  def __getitem__(self, val: slice) -> Sweep:
132
119
  pass
133
120
 
134
- def __getitem__(self, val: Union[int, slice]) -> Union[resolver.ParamResolver, Sweep]:
121
+ def __getitem__(self, val: int | slice) -> resolver.ParamResolver | Sweep:
135
122
  n = len(self)
136
123
  if isinstance(val, int):
137
124
  if val < -n or val >= n:
@@ -142,7 +129,7 @@ class Sweep(metaclass=abc.ABCMeta):
142
129
  if not isinstance(val, slice):
143
130
  raise TypeError(f'Sweep indices must be either int or slices, not {type(val)}')
144
131
 
145
- inds_map: Dict[int, int] = {
132
+ inds_map: dict[int, int] = {
146
133
  sweep_i: slice_i for slice_i, sweep_i in enumerate(range(n)[val])
147
134
  }
148
135
  results = [resolver.ParamResolver()] * len(inds_map)
@@ -189,7 +176,7 @@ class _Unit(Sweep):
189
176
  return True
190
177
 
191
178
  @property
192
- def keys(self) -> List[cirq.TParamKey]:
179
+ def keys(self) -> list[cirq.TParamKey]:
193
180
  return []
194
181
 
195
182
  def __len__(self) -> int:
@@ -201,7 +188,7 @@ class _Unit(Sweep):
201
188
  def __repr__(self) -> str:
202
189
  return 'cirq.UnitSweep'
203
190
 
204
- def _json_dict_(self) -> Dict[str, Any]:
191
+ def _json_dict_(self) -> dict[str, Any]:
205
192
  return {}
206
193
 
207
194
 
@@ -236,7 +223,7 @@ class Product(Sweep):
236
223
  return hash(tuple(self.factors))
237
224
 
238
225
  @property
239
- def keys(self) -> List[cirq.TParamKey]:
226
+ def keys(self) -> list[cirq.TParamKey]:
240
227
  return list(itertools.chain.from_iterable(factor.keys for factor in self.factors))
241
228
 
242
229
  def __len__(self) -> int:
@@ -272,7 +259,7 @@ class Product(Sweep):
272
259
  factor_strs.append(factor_str)
273
260
  return ' * '.join(factor_strs)
274
261
 
275
- def _json_dict_(self) -> Dict[str, Any]:
262
+ def _json_dict_(self) -> dict[str, Any]:
276
263
  return protocols.obj_to_dict_helper(self, ['factors'])
277
264
 
278
265
  @classmethod
@@ -311,7 +298,7 @@ class Concat(Sweep):
311
298
  return hash(tuple(self.sweeps))
312
299
 
313
300
  @property
314
- def keys(self) -> List[cirq.TParamKey]:
301
+ def keys(self) -> list[cirq.TParamKey]:
315
302
  return self.sweeps[0].keys
316
303
 
317
304
  def __len__(self) -> int:
@@ -329,7 +316,7 @@ class Concat(Sweep):
329
316
  sweeps_repr = ', '.join(repr(s) for s in self.sweeps)
330
317
  return f'Concat({sweeps_repr})'
331
318
 
332
- def _json_dict_(self) -> Dict[str, Any]:
319
+ def _json_dict_(self) -> dict[str, Any]:
333
320
  return protocols.obj_to_dict_helper(self, ['sweeps'])
334
321
 
335
322
  @classmethod
@@ -364,7 +351,7 @@ class Zip(Sweep):
364
351
  return hash(tuple(self.sweeps))
365
352
 
366
353
  @property
367
- def keys(self) -> List[cirq.TParamKey]:
354
+ def keys(self) -> list[cirq.TParamKey]:
368
355
  return list(itertools.chain.from_iterable(sweep.keys for sweep in self.sweeps))
369
356
 
370
357
  def __len__(self) -> int:
@@ -386,7 +373,7 @@ class Zip(Sweep):
386
373
  return 'Zip()'
387
374
  return ' + '.join(str(s) if isinstance(s, Product) else repr(s) for s in self.sweeps)
388
375
 
389
- def _json_dict_(self) -> Dict[str, Any]:
376
+ def _json_dict_(self) -> dict[str, Any]:
390
377
  return protocols.obj_to_dict_helper(self, ['sweeps'])
391
378
 
392
379
  @classmethod
@@ -466,11 +453,11 @@ class SingleSweep(Sweep):
466
453
  return hash((self.__class__, self._tuple()))
467
454
 
468
455
  @abc.abstractmethod
469
- def _tuple(self) -> Tuple[Any, ...]:
456
+ def _tuple(self) -> tuple[Any, ...]:
470
457
  pass
471
458
 
472
459
  @property
473
- def keys(self) -> List[cirq.TParamKey]:
460
+ def keys(self) -> list[cirq.TParamKey]:
474
461
  return [self.key]
475
462
 
476
463
  def param_tuples(self) -> Iterator[Params]:
@@ -486,7 +473,7 @@ class Points(SingleSweep):
486
473
  """A simple sweep with explicitly supplied values."""
487
474
 
488
475
  def __init__(
489
- self, key: cirq.TParamKey, points: Sequence[float], metadata: Optional[Any] = None
476
+ self, key: cirq.TParamKey, points: Sequence[float], metadata: Any | None = None
490
477
  ) -> None:
491
478
  """Creates a sweep on a variable with supplied values.
492
479
 
@@ -503,7 +490,7 @@ class Points(SingleSweep):
503
490
  self.points = points
504
491
  self.metadata = metadata
505
492
 
506
- def _tuple(self) -> Tuple[Union[str, sympy.Expr], Sequence[float]]:
493
+ def _tuple(self) -> tuple[str | sympy.Expr, Sequence[float]]:
507
494
  return self.key, tuple(self.points)
508
495
 
509
496
  def __len__(self) -> int:
@@ -516,7 +503,7 @@ class Points(SingleSweep):
516
503
  metadata_repr = f', metadata={self.metadata!r}' if self.metadata is not None else ""
517
504
  return f'cirq.Points({self.key!r}, {self.points!r}{metadata_repr})'
518
505
 
519
- def _json_dict_(self) -> Dict[str, Any]:
506
+ def _json_dict_(self) -> dict[str, Any]:
520
507
  if self.metadata is not None:
521
508
  return protocols.obj_to_dict_helper(self, ["key", "points", "metadata"])
522
509
  return protocols.obj_to_dict_helper(self, ["key", "points"])
@@ -531,7 +518,7 @@ class Linspace(SingleSweep):
531
518
  start: float,
532
519
  stop: float,
533
520
  length: int,
534
- metadata: Optional[Any] = None,
521
+ metadata: Any | None = None,
535
522
  ) -> None:
536
523
  """Creates a linear-spaced sweep for a given key.
537
524
 
@@ -552,7 +539,7 @@ class Linspace(SingleSweep):
552
539
  self.length = length
553
540
  self.metadata = metadata
554
541
 
555
- def _tuple(self) -> Tuple[Union[str, sympy.Expr], float, float, int]:
542
+ def _tuple(self) -> tuple[str | sympy.Expr, float, float, int]:
556
543
  return (self.key, self.start, self.stop, self.length)
557
544
 
558
545
  def __len__(self) -> int:
@@ -573,7 +560,7 @@ class Linspace(SingleSweep):
573
560
  f'stop={self.stop!r}, length={self.length!r}{metadata_repr})'
574
561
  )
575
562
 
576
- def _json_dict_(self) -> Dict[str, Any]:
563
+ def _json_dict_(self) -> dict[str, Any]:
577
564
  if self.metadata is not None:
578
565
  return protocols.obj_to_dict_helper(
579
566
  self, ["key", "start", "stop", "length", "metadata"]
@@ -595,7 +582,7 @@ class ListSweep(Sweep):
595
582
  TypeError: If `resolver_list` is not a `cirq.ParamResolver` or a
596
583
  dict.
597
584
  """
598
- self.resolver_list: List[resolver.ParamResolver] = []
585
+ self.resolver_list: list[resolver.ParamResolver] = []
599
586
  for r in resolver_list:
600
587
  if not isinstance(r, (dict, resolver.ParamResolver)):
601
588
  raise TypeError(f'Not a ParamResolver or dict: <{r!r}>')
@@ -610,7 +597,7 @@ class ListSweep(Sweep):
610
597
  return not self == other
611
598
 
612
599
  @property
613
- def keys(self) -> List[cirq.TParamKey]:
600
+ def keys(self) -> list[cirq.TParamKey]:
614
601
  if not self.resolver_list:
615
602
  return []
616
603
  return list(map(str, self.resolver_list[0].param_dict))
@@ -625,7 +612,7 @@ class ListSweep(Sweep):
625
612
  def __repr__(self) -> str:
626
613
  return f'cirq.ListSweep({self.resolver_list!r})'
627
614
 
628
- def _json_dict_(self) -> Dict[str, Any]:
615
+ def _json_dict_(self) -> dict[str, Any]:
629
616
  return protocols.obj_to_dict_helper(self, ["resolver_list"])
630
617
 
631
618
 
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
  import itertools
18
18
  import random
19
19
  from collections import defaultdict
20
- from typing import Any, Dict, Iterable, List, Optional, Sequence, Union
20
+ from typing import Any, Iterable, Sequence
21
21
 
22
22
  import numpy as np
23
23
  import sympy
@@ -80,7 +80,7 @@ def _measurement_subspaces(
80
80
  measurement_mask |= 1 << i
81
81
 
82
82
  # Keyed by computational basis state with lowest index.
83
- measurement_subspaces: Dict[int, List[int]] = defaultdict(list)
83
+ measurement_subspaces: dict[int, list[int]] = defaultdict(list)
84
84
  computational_basis = range(1 << n_qubits)
85
85
 
86
86
  for basis_state in computational_basis:
@@ -215,7 +215,7 @@ def assert_same_circuits(
215
215
 
216
216
  def _first_differing_moment_index(
217
217
  circuit1: circuits.AbstractCircuit, circuit2: circuits.AbstractCircuit
218
- ) -> Optional[int]:
218
+ ) -> int | None:
219
219
  for i, (m1, m2) in enumerate(itertools.zip_longest(circuit1, circuit2)):
220
220
  if m1 != m2:
221
221
  return i
@@ -225,7 +225,7 @@ def _first_differing_moment_index(
225
225
  def assert_circuits_have_same_unitary_given_final_permutation(
226
226
  actual: circuits.AbstractCircuit,
227
227
  expected: circuits.AbstractCircuit,
228
- qubit_map: Dict[ops.Qid, ops.Qid],
228
+ qubit_map: dict[ops.Qid, ops.Qid],
229
229
  ) -> None:
230
230
  """Asserts two circuits have the same unitary up to a final permutation of qubits.
231
231
 
@@ -257,7 +257,7 @@ def assert_circuits_have_same_unitary_given_final_permutation(
257
257
 
258
258
 
259
259
  def assert_has_diagram(
260
- actual: Union[circuits.AbstractCircuit, circuits.Moment], desired: str, **kwargs
260
+ actual: circuits.AbstractCircuit | circuits.Moment, desired: str, **kwargs
261
261
  ) -> None:
262
262
  """Determines if a given circuit has the desired text diagram.
263
263
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Collection, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
17
+ from typing import Collection, Sequence, TYPE_CHECKING
18
18
 
19
19
  import numpy as np
20
20
  import pytest
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
26
26
 
27
27
 
28
28
  class GoodGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
29
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]: # pragma: no cover
29
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]: # pragma: no cover
30
30
  return [(0, np.diag([1, 0])), (1, np.diag([0, 1]))]
31
31
 
32
32
 
@@ -34,15 +34,13 @@ class BadGateOperation(cirq.GateOperation):
34
34
  def controlled_by(
35
35
  self,
36
36
  *control_qubits: cirq.Qid,
37
- control_values: Optional[
38
- Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
39
- ] = None,
37
+ control_values: cv.AbstractControlValues | Sequence[int | Collection[int]] | None = None,
40
38
  ) -> cirq.Operation:
41
39
  return cirq.ControlledOperation(control_qubits, self, control_values)
42
40
 
43
41
 
44
42
  class BadGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
45
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
43
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
46
44
  return [(0, np.diag([1, 0])), (1, np.diag([0, 1]))]
47
45
 
48
46
  def on(self, *qubits: cirq.Qid) -> cirq.Operation:
@@ -50,11 +48,9 @@ class BadGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
50
48
 
51
49
  def controlled(
52
50
  self,
53
- num_controls: Optional[int] = None,
54
- control_values: Optional[
55
- Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
56
- ] = None,
57
- control_qid_shape: Optional[Tuple[int, ...]] = None,
51
+ num_controls: int | None = None,
52
+ control_values: cv.AbstractControlValues | Sequence[int | Collection[int]] | None = None,
53
+ control_qid_shape: tuple[int, ...] | None = None,
58
54
  ) -> cirq.Gate:
59
55
  ret = super().controlled(num_controls, control_values, control_qid_shape)
60
56
  if num_controls == 1 and control_values is None: