cirq-core 1.6.0.dev20250520054601__py3-none-any.whl → 1.6.0.dev20250520183459__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 (290) 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/linear_dict_test.py +2 -2
  273. cirq/value/measurement_key.py +8 -8
  274. cirq/value/product_state.py +9 -9
  275. cirq/value/value_equality_attr.py +4 -4
  276. cirq/vis/heatmap.py +23 -35
  277. cirq/work/collector.py +9 -17
  278. cirq/work/observable_grouping.py +4 -7
  279. cirq/work/observable_measurement.py +29 -41
  280. cirq/work/observable_measurement_data.py +14 -14
  281. cirq/work/observable_measurement_test.py +2 -2
  282. cirq/work/observable_settings.py +9 -10
  283. cirq/work/pauli_sum_collector.py +5 -5
  284. cirq/work/sampler.py +17 -17
  285. cirq/work/zeros_sampler.py +3 -3
  286. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/METADATA +1 -1
  287. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/RECORD +290 -290
  288. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/WHEEL +1 -1
  289. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/licenses/LICENSE +0 -0
  290. {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from types import EllipsisType, NotImplementedType
18
- from typing import Any, cast, Optional, Sequence, Tuple, Union
18
+ from typing import Any, cast, Sequence, Union
19
19
 
20
20
  import numpy as np
21
21
  import pytest
@@ -25,7 +25,7 @@ import cirq
25
25
 
26
26
 
27
27
  class GateUsingWorkspaceForApplyUnitary(cirq.testing.SingleQubitGate):
28
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
28
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
29
29
  args.available_buffer[...] = args.target_tensor
30
30
  args.target_tensor[...] = 0
31
31
  return args.available_buffer
@@ -44,10 +44,10 @@ class GateAllocatingNewSpaceForResult(cirq.testing.SingleQubitGate):
44
44
  def __init__(self):
45
45
  self._matrix = cirq.testing.random_unitary(2, random_state=4321)
46
46
 
47
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
47
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
48
48
  assert len(args.axes) == 1
49
49
  a = args.axes[0]
50
- seed = cast(Tuple[Union[int, slice, EllipsisType], ...], (slice(None),))
50
+ seed = cast(tuple[Union[int, slice, EllipsisType], ...], (slice(None),))
51
51
  zero = seed * a + (0, Ellipsis)
52
52
  one = seed * a + (1, Ellipsis)
53
53
  result = np.zeros(args.target_tensor.shape, args.target_tensor.dtype)
@@ -475,7 +475,7 @@ def test_nontrivial_controlled_gate_is_consistent(
475
475
  def _test_controlled_gate_is_consistent(
476
476
  gate: cirq.Gate,
477
477
  should_decompose_to_target: bool,
478
- control_qid_shape: Optional[Sequence[int]] = None,
478
+ control_qid_shape: Sequence[int] | None = None,
479
479
  control_values: Any = None,
480
480
  ):
481
481
  cgate = cirq.ControlledGate(
@@ -15,18 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from types import EllipsisType, NotImplementedType
18
- from typing import (
19
- AbstractSet,
20
- Any,
21
- Collection,
22
- Dict,
23
- List,
24
- Optional,
25
- Sequence,
26
- Tuple,
27
- TYPE_CHECKING,
28
- Union,
29
- )
18
+ from typing import AbstractSet, Any, Collection, Sequence, TYPE_CHECKING
30
19
 
31
20
  import numpy as np
32
21
 
@@ -57,9 +46,7 @@ class ControlledOperation(raw_types.Operation):
57
46
  self,
58
47
  controls: Sequence[cirq.Qid],
59
48
  sub_operation: cirq.Operation,
60
- control_values: Optional[
61
- Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
62
- ] = None,
49
+ control_values: cv.AbstractControlValues | Sequence[int | Collection[int]] | None = None,
63
50
  ):
64
51
  """Initializes the controlled operation.
65
52
 
@@ -116,7 +103,7 @@ class ControlledOperation(raw_types.Operation):
116
103
  self._control_values = self._control_values & sub_operation.control_values
117
104
 
118
105
  @property
119
- def controls(self) -> Tuple[cirq.Qid, ...]:
106
+ def controls(self) -> tuple[cirq.Qid, ...]:
120
107
  return self._controls
121
108
 
122
109
  @property
@@ -128,7 +115,7 @@ class ControlledOperation(raw_types.Operation):
128
115
  return self._sub_operation
129
116
 
130
117
  @property
131
- def gate(self) -> Optional[cirq.ControlledGate]:
118
+ def gate(self) -> cirq.ControlledGate | None:
132
119
  if self.sub_operation.gate is None:
133
120
  return None
134
121
  return controlled_gate.ControlledGate(
@@ -150,7 +137,7 @@ class ControlledOperation(raw_types.Operation):
150
137
  def _decompose_(self):
151
138
  return self._decompose_with_context_()
152
139
 
153
- def _decompose_with_context_(self, context: Optional[cirq.DecompositionContext] = None):
140
+ def _decompose_with_context_(self, context: cirq.DecompositionContext | None = None):
154
141
  result = protocols.decompose_once_with_qubits(
155
142
  self.gate, self.qubits, NotImplemented, flatten=False, context=context
156
143
  )
@@ -183,7 +170,7 @@ class ControlledOperation(raw_types.Operation):
183
170
  sub_n = len(args.axes) - n
184
171
  sub_axes = args.axes[n:]
185
172
  for control_vals in self.control_values.expand():
186
- active: Tuple[Union[EllipsisType, slice], ...] = (
173
+ active: tuple[EllipsisType | slice, ...] = (
187
174
  ...,
188
175
  *(slice(v, v + 1) for v in control_vals),
189
176
  *(slice(None),) * sub_n,
@@ -209,7 +196,7 @@ class ControlledOperation(raw_types.Operation):
209
196
  def _has_unitary_(self) -> bool:
210
197
  return protocols.has_unitary(self.sub_operation)
211
198
 
212
- def _qasm_(self, args: cirq.QasmArgs) -> Optional[str]:
199
+ def _qasm_(self, args: cirq.QasmArgs) -> str | None:
213
200
  if (
214
201
  hasattr(self._sub_operation, "gate")
215
202
  and len(self._controls) == 1
@@ -246,7 +233,7 @@ class ControlledOperation(raw_types.Operation):
246
233
  tensor[active] = sub_tensor # type: ignore[index]
247
234
  return tensor.reshape((np.prod(qid_shape, dtype=np.int64).item(),) * 2)
248
235
 
249
- def _unitary_(self) -> Union[np.ndarray, NotImplementedType]:
236
+ def _unitary_(self) -> np.ndarray | NotImplementedType:
250
237
  sub_matrix = protocols.unitary(self.sub_operation, None)
251
238
  if sub_matrix is None:
252
239
  return NotImplemented
@@ -255,7 +242,7 @@ class ControlledOperation(raw_types.Operation):
255
242
  def _has_mixture_(self) -> bool:
256
243
  return protocols.has_mixture(self.sub_operation)
257
244
 
258
- def _mixture_(self) -> Optional[List[Tuple[float, np.ndarray]]]:
245
+ def _mixture_(self) -> list[tuple[float, np.ndarray]] | None:
259
246
  sub_mixture = protocols.mixture(self.sub_operation, None)
260
247
  if sub_mixture is None:
261
248
  return None
@@ -294,7 +281,7 @@ class ControlledOperation(raw_types.Operation):
294
281
  new_sub_op = protocols.resolve_parameters(self.sub_operation, resolver, recursive)
295
282
  return ControlledOperation(self.controls, new_sub_op, self.control_values)
296
283
 
297
- def _trace_distance_bound_(self) -> Optional[float]:
284
+ def _trace_distance_bound_(self) -> float | None:
298
285
  if self._is_parameterized_():
299
286
  return None
300
287
  u = protocols.unitary(self.sub_operation, default=None)
@@ -311,7 +298,7 @@ class ControlledOperation(raw_types.Operation):
311
298
 
312
299
  def _circuit_diagram_info_(
313
300
  self, args: cirq.CircuitDiagramInfoArgs
314
- ) -> Optional[protocols.CircuitDiagramInfo]:
301
+ ) -> protocols.CircuitDiagramInfo | None:
315
302
  n = len(self.controls)
316
303
 
317
304
  sub_args = protocols.CircuitDiagramInfoArgs(
@@ -346,7 +333,7 @@ class ControlledOperation(raw_types.Operation):
346
333
  exponent_qubit_index=exponent_qubit_index,
347
334
  )
348
335
 
349
- def _json_dict_(self) -> Dict[str, Any]:
336
+ def _json_dict_(self) -> dict[str, Any]:
350
337
  return {
351
338
  'controls': self.controls,
352
339
  'control_values': self.control_values,
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
  import itertools
18
18
  import re
19
19
  from types import EllipsisType, NotImplementedType
20
- from typing import cast, Tuple, Union
20
+ from typing import cast, Union
21
21
 
22
22
  import numpy as np
23
23
  import pytest
@@ -28,7 +28,7 @@ from cirq import protocols
28
28
 
29
29
 
30
30
  class GateUsingWorkspaceForApplyUnitary(cirq.testing.SingleQubitGate):
31
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
31
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
32
32
  args.available_buffer[...] = args.target_tensor
33
33
  args.target_tensor[...] = 0
34
34
  return args.available_buffer
@@ -47,10 +47,10 @@ class GateAllocatingNewSpaceForResult(cirq.testing.SingleQubitGate):
47
47
  def __init__(self):
48
48
  self._matrix = cirq.testing.random_unitary(2, random_state=1234)
49
49
 
50
- def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
50
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> np.ndarray | NotImplementedType:
51
51
  assert len(args.axes) == 1
52
52
  a = args.axes[0]
53
- seed = cast(Tuple[Union[int, slice, EllipsisType], ...], (slice(None),))
53
+ seed = cast(tuple[Union[int, slice, EllipsisType], ...], (slice(None),))
54
54
  zero = seed * a + (0, Ellipsis)
55
55
  one = seed * a + (1, Ellipsis)
56
56
  result = np.zeros(args.target_tensor.shape, args.target_tensor.dtype)
@@ -157,7 +157,7 @@ def test_str():
157
157
 
158
158
  class SingleQubitOp(cirq.Operation):
159
159
  @property
160
- def qubits(self) -> Tuple[cirq.Qid, ...]:
160
+ def qubits(self) -> tuple[cirq.Qid, ...]:
161
161
  return ()
162
162
 
163
163
  def with_qubits(self, *new_qubits: cirq.Qid):
@@ -22,16 +22,11 @@ from typing import (
22
22
  Any,
23
23
  Callable,
24
24
  cast,
25
- Dict,
26
25
  Iterable,
27
26
  Iterator,
28
- List,
29
- Optional,
30
27
  overload,
31
28
  Sequence,
32
- Tuple,
33
29
  TYPE_CHECKING,
34
- Union,
35
30
  )
36
31
 
37
32
  import numpy as np
@@ -47,7 +42,7 @@ if TYPE_CHECKING:
47
42
 
48
43
  # Order is important! Index equals numeric value.
49
44
  PAULI_CHARS = 'IXYZ'
50
- PAULI_GATES: List[Union[cirq.Pauli, cirq.IdentityGate]] = [
45
+ PAULI_GATES: list[cirq.Pauli | cirq.IdentityGate] = [
51
46
  identity.I,
52
47
  pauli_gates.X,
53
48
  pauli_gates.Y,
@@ -86,7 +81,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
86
81
 
87
82
  def __init__(
88
83
  self,
89
- pauli_mask: Union[Iterable[cirq.PAULI_GATE_LIKE], np.ndarray],
84
+ pauli_mask: Iterable[cirq.PAULI_GATE_LIKE] | np.ndarray,
90
85
  *,
91
86
  coefficient: cirq.TParamValComplex = 1,
92
87
  ):
@@ -105,7 +100,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
105
100
  values are supported.
106
101
  """
107
102
  self._pauli_mask = _as_pauli_mask(pauli_mask)
108
- self._coefficient: Union[complex, sympy.Expr] = (
103
+ self._coefficient: complex | sympy.Expr = (
109
104
  coefficient if isinstance(coefficient, sympy.Expr) else complex(coefficient)
110
105
  )
111
106
  if type(self) != MutableDensePauliString:
@@ -122,7 +117,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
122
117
  """A complex coefficient or symbol."""
123
118
  return self._coefficient
124
119
 
125
- def _json_dict_(self) -> Dict[str, Any]:
120
+ def _json_dict_(self) -> dict[str, Any]:
126
121
  return protocols.obj_to_dict_helper(self, ['pauli_mask', 'coefficient'])
127
122
 
128
123
  def _value_equality_values_(self):
@@ -165,14 +160,14 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
165
160
  return False
166
161
  return abs(1 - abs(cast(complex, self.coefficient))) < 1e-8
167
162
 
168
- def _unitary_(self) -> Union[np.ndarray, NotImplementedType]:
163
+ def _unitary_(self) -> np.ndarray | NotImplementedType:
169
164
  if not self._has_unitary_():
170
165
  return NotImplemented
171
166
  return self.coefficient * linalg.kron(
172
167
  *[protocols.unitary(PAULI_GATES[p]) for p in self.pauli_mask]
173
168
  )
174
169
 
175
- def _apply_unitary_(self, args) -> Union[np.ndarray, None, NotImplementedType]:
170
+ def _apply_unitary_(self, args) -> np.ndarray | None | NotImplementedType:
176
171
  if not self._has_unitary_():
177
172
  return NotImplemented
178
173
  from cirq import devices
@@ -181,7 +176,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
181
176
  decomposed_ops = cast(Iterable['cirq.OP_TREE'], self._decompose_(qubits))
182
177
  return protocols.apply_unitaries(decomposed_ops, qubits, args)
183
178
 
184
- def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Union[NotImplementedType, cirq.OP_TREE]:
179
+ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> NotImplementedType | cirq.OP_TREE:
185
180
  if not self._has_unitary_():
186
181
  return NotImplemented
187
182
  result = [PAULI_GATES[p].on(q) for p, q in zip(self.pauli_mask, qubits) if p]
@@ -203,7 +198,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
203
198
  def __pos__(self):
204
199
  return self
205
200
 
206
- def __pow__(self, power: float) -> Union[NotImplementedType, Self]:
201
+ def __pow__(self, power: float) -> NotImplementedType | Self:
207
202
  concrete_class = type(self)
208
203
  if isinstance(power, int):
209
204
  i_group = [1, +1j, -1, -1j]
@@ -218,7 +213,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
218
213
  return NotImplemented
219
214
 
220
215
  @overload
221
- def __getitem__(self, item: int) -> Union[cirq.Pauli, cirq.IdentityGate]:
216
+ def __getitem__(self, item: int) -> cirq.Pauli | cirq.IdentityGate:
222
217
  pass
223
218
 
224
219
  @overload
@@ -234,7 +229,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
234
229
 
235
230
  raise TypeError(f'indices must be integers or slices, not {type(item)}')
236
231
 
237
- def __iter__(self) -> Iterator[Union[cirq.Pauli, cirq.IdentityGate]]:
232
+ def __iter__(self) -> Iterator[cirq.Pauli | cirq.IdentityGate]:
238
233
  for i in range(len(self)):
239
234
  yield self[i]
240
235
 
@@ -326,7 +321,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
326
321
  def on(self, *qubits: cirq.Qid) -> cirq.PauliString:
327
322
  return self.sparse(qubits)
328
323
 
329
- def sparse(self, qubits: Optional[Sequence[cirq.Qid]] = None) -> cirq.PauliString:
324
+ def sparse(self, qubits: Sequence[cirq.Qid] | None = None) -> cirq.PauliString:
330
325
  """A `cirq.PauliString` version of this dense pauli string.
331
326
 
332
327
  Args:
@@ -373,9 +368,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
373
368
  f'coefficient={proper_repr(self.coefficient)})'
374
369
  )
375
370
 
376
- def _commutes_(
377
- self, other: Any, *, atol: float = 1e-8
378
- ) -> Union[bool, NotImplementedType, None]:
371
+ def _commutes_(self, other: Any, *, atol: float = 1e-8) -> bool | NotImplementedType | None:
379
372
  if isinstance(other, BaseDensePauliString):
380
373
  n = min(len(self.pauli_mask), len(other.pauli_mask))
381
374
  phase = _vectorized_pauli_mul_phase(self.pauli_mask[:n], other.pauli_mask[:n])
@@ -403,8 +396,8 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
403
396
  @abc.abstractmethod
404
397
  def copy(
405
398
  self,
406
- coefficient: Optional[cirq.TParamValComplex] = None,
407
- pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
399
+ coefficient: cirq.TParamValComplex | None = None,
400
+ pauli_mask: None | str | Iterable[int] | np.ndarray = None,
408
401
  ) -> Self:
409
402
  """Returns a copy with possibly modified contents.
410
403
 
@@ -459,8 +452,8 @@ class DensePauliString(BaseDensePauliString):
459
452
 
460
453
  def copy(
461
454
  self,
462
- coefficient: Optional[cirq.TParamValComplex] = None,
463
- pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
455
+ coefficient: cirq.TParamValComplex | None = None,
456
+ pauli_mask: None | str | Iterable[int] | np.ndarray = None,
464
457
  ) -> DensePauliString:
465
458
  if pauli_mask is None and (coefficient is None or coefficient == self.coefficient):
466
459
  return self
@@ -494,9 +487,7 @@ class MutableDensePauliString(BaseDensePauliString):
494
487
 
495
488
  @overload
496
489
  def __setitem__(
497
- self,
498
- key: slice,
499
- value: Union[Iterable[cirq.PAULI_GATE_LIKE], np.ndarray, BaseDensePauliString],
490
+ self, key: slice, value: Iterable[cirq.PAULI_GATE_LIKE] | np.ndarray | BaseDensePauliString
500
491
  ) -> Self:
501
492
  pass
502
493
 
@@ -559,8 +550,8 @@ class MutableDensePauliString(BaseDensePauliString):
559
550
 
560
551
  def copy(
561
552
  self,
562
- coefficient: Optional[cirq.TParamValComplex] = None,
563
- pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
553
+ coefficient: cirq.TParamValComplex | None = None,
554
+ pauli_mask: None | str | Iterable[int] | np.ndarray = None,
564
555
  ) -> MutableDensePauliString:
565
556
  return MutableDensePauliString(
566
557
  coefficient=self.coefficient if coefficient is None else coefficient,
@@ -574,7 +565,7 @@ class MutableDensePauliString(BaseDensePauliString):
574
565
  return self.coefficient, tuple(PAULI_CHARS[p] for p in self.pauli_mask)
575
566
 
576
567
  @classmethod
577
- def inline_gaussian_elimination(cls, rows: List[MutableDensePauliString]) -> None:
568
+ def inline_gaussian_elimination(cls, rows: list[MutableDensePauliString]) -> None:
578
569
  if not rows:
579
570
  return
580
571
 
@@ -616,13 +607,13 @@ def _pauli_index(val: cirq.PAULI_GATE_LIKE) -> int:
616
607
  return m[val]
617
608
 
618
609
 
619
- def _as_pauli_mask(val: Union[Iterable[cirq.PAULI_GATE_LIKE], np.ndarray]) -> np.ndarray:
610
+ def _as_pauli_mask(val: Iterable[cirq.PAULI_GATE_LIKE] | np.ndarray) -> np.ndarray:
620
611
  if isinstance(val, np.ndarray):
621
612
  return np.asarray(val, dtype=np.uint8)
622
613
  return np.array([_pauli_index(v) for v in val], dtype=np.uint8)
623
614
 
624
615
 
625
- def _attempt_value_to_pauli_index(v: cirq.Operation) -> Optional[Tuple[int, int]]:
616
+ def _attempt_value_to_pauli_index(v: cirq.Operation) -> tuple[int, int] | None:
626
617
  if not isinstance(v, raw_types.Operation):
627
618
  return None
628
619
 
@@ -641,9 +632,7 @@ def _attempt_value_to_pauli_index(v: cirq.Operation) -> Optional[Tuple[int, int]
641
632
  return pauli_string.PAULI_GATE_LIKE_TO_INDEX_MAP[v.gate], q.x
642
633
 
643
634
 
644
- def _vectorized_pauli_mul_phase(
645
- lhs: Union[int, np.ndarray], rhs: Union[int, np.ndarray]
646
- ) -> complex:
635
+ def _vectorized_pauli_mul_phase(lhs: int | np.ndarray, rhs: int | np.ndarray) -> complex:
647
636
  """Computes the leading coefficient of a pauli string multiplication.
648
637
 
649
638
  The two inputs must have the same length. They must follow the convention
@@ -15,7 +15,6 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import numbers
18
- from typing import List
19
18
 
20
19
  import numpy as np
21
20
  import pytest
@@ -547,7 +546,7 @@ def test_copy():
547
546
 
548
547
 
549
548
  def test_gaussian_elimination():
550
- def table(*rows: str) -> List[cirq.MutableDensePauliString]:
549
+ def table(*rows: str) -> list[cirq.MutableDensePauliString]:
551
550
  coefs = {'i': 1j, '-': -1, '+': 1}
552
551
  return [
553
552
  cirq.MutableDensePauliString(row[1:].replace('.', 'I'), coefficient=coefs[row[0]])
cirq/ops/diagonal_gate.py CHANGED
@@ -20,18 +20,7 @@ passed as a list.
20
20
 
21
21
  from __future__ import annotations
22
22
 
23
- from typing import (
24
- AbstractSet,
25
- Any,
26
- Dict,
27
- Iterator,
28
- List,
29
- Optional,
30
- Sequence,
31
- Tuple,
32
- TYPE_CHECKING,
33
- Union,
34
- )
23
+ from typing import AbstractSet, Any, Iterator, Sequence, TYPE_CHECKING
35
24
 
36
25
  import numpy as np
37
26
  import sympy
@@ -44,7 +33,7 @@ if TYPE_CHECKING:
44
33
  import cirq
45
34
 
46
35
 
47
- def _fast_walsh_hadamard_transform(a: Tuple[Any, ...]) -> np.ndarray:
36
+ def _fast_walsh_hadamard_transform(a: tuple[Any, ...]) -> np.ndarray:
48
37
  """Fast Walsh–Hadamard Transform of an array."""
49
38
  h = 1
50
39
  a_ = np.array(a)
@@ -59,7 +48,7 @@ def _fast_walsh_hadamard_transform(a: Tuple[Any, ...]) -> np.ndarray:
59
48
  return a_
60
49
 
61
50
 
62
- def _gen_gray_code(n: int) -> Iterator[Tuple[int, int]]:
51
+ def _gen_gray_code(n: int) -> Iterator[tuple[int, int]]:
63
52
  """Generate the Gray Code from 0 to 2^n-1.
64
53
 
65
54
  Each iteration yields a two-tuple, `(gray_code, bit_flip)`. `gray_code` is the decimal
@@ -94,10 +83,10 @@ class DiagonalGate(raw_types.Gate):
94
83
  If these values are $(x_0, x_1, \ldots , x_N)$ then the unitary
95
84
  has diagonal values $(e^{i x_0}, e^{i x_1}, \ldots, e^{i x_N})$.
96
85
  """
97
- self._diag_angles_radians: Tuple[cirq.TParamVal, ...] = tuple(diag_angles_radians)
86
+ self._diag_angles_radians: tuple[cirq.TParamVal, ...] = tuple(diag_angles_radians)
98
87
 
99
88
  @property
100
- def diag_angles_radians(self) -> Tuple[cirq.TParamVal, ...]:
89
+ def diag_angles_radians(self) -> tuple[cirq.TParamVal, ...]:
101
90
  return self._diag_angles_radians
102
91
 
103
92
  def _num_qubits_(self):
@@ -119,7 +108,7 @@ class DiagonalGate(raw_types.Gate):
119
108
  def _has_unitary_(self) -> bool:
120
109
  return not self._is_parameterized_()
121
110
 
122
- def _unitary_(self) -> Optional[np.ndarray]:
111
+ def _unitary_(self) -> np.ndarray | None:
123
112
  if self._is_parameterized_():
124
113
  return None
125
114
  return np.diag([np.exp(1j * angle) for angle in self._diag_angles_radians])
@@ -162,7 +151,7 @@ class DiagonalGate(raw_types.Gate):
162
151
 
163
152
  def _decompose_for_basis(
164
153
  self, index: int, bit_flip: int, theta: cirq.TParamVal, qubits: Sequence[cirq.Qid]
165
- ) -> Iterator[Union[cirq.ZPowGate, cirq.CXPowGate]]:
154
+ ) -> Iterator[cirq.ZPowGate | cirq.CXPowGate]:
166
155
  if index == 0:
167
156
  return
168
157
  largest_digit = self._num_qubits_() - (len(bin(index)) - 2)
@@ -200,14 +189,14 @@ class DiagonalGate(raw_types.Gate):
200
189
  # decomposed gates. On its own it is not physically observable. However, if using this
201
190
  # diagonal gate for sub-system like controlled gate, it is no longer equivalent. Hence,
202
191
  # we add global phase.
203
- decomposed_circ: List[Any] = [
192
+ decomposed_circ: list[Any] = [
204
193
  global_phase_op.global_phase_operation(1j ** (2 * hat_angles[0] / np.pi))
205
194
  ]
206
195
  for i, bit_flip in _gen_gray_code(n):
207
196
  decomposed_circ.extend(self._decompose_for_basis(i, bit_flip, -hat_angles[i], qubits))
208
197
  return decomposed_circ
209
198
 
210
- def _json_dict_(self) -> Dict[str, Any]:
199
+ def _json_dict_(self) -> dict[str, Any]:
211
200
  return protocols.obj_to_dict_helper(self, attribute_names=["diag_angles_radians"])
212
201
 
213
202
  def __repr__(self) -> str:
@@ -14,15 +14,13 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import List
18
-
19
17
  import numpy as np
20
18
  import pytest
21
19
  import sympy
22
20
 
23
21
  import cirq
24
22
 
25
- _candidate_angles: List[float] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53]
23
+ _candidate_angles: list[float] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53]
26
24
 
27
25
 
28
26
  @pytest.mark.parametrize(
cirq/ops/eigen_gate.py CHANGED
@@ -19,19 +19,7 @@ import fractions
19
19
  import math
20
20
  import numbers
21
21
  from types import NotImplementedType
22
- from typing import (
23
- AbstractSet,
24
- Any,
25
- cast,
26
- Dict,
27
- Iterable,
28
- List,
29
- NamedTuple,
30
- Optional,
31
- Tuple,
32
- TYPE_CHECKING,
33
- Union,
34
- )
22
+ from typing import AbstractSet, Any, cast, Iterable, NamedTuple, TYPE_CHECKING
35
23
 
36
24
  import numpy as np
37
25
  import sympy
@@ -219,7 +207,7 @@ class EigenGate(raw_types.Gate):
219
207
  return args.format_radians(radians=2 * pi * exponent / order)
220
208
 
221
209
  # virtual method
222
- def _eigen_shifts(self) -> List[float]:
210
+ def _eigen_shifts(self) -> list[float]:
223
211
  """Describes the eigenvalues of the gate's matrix.
224
212
 
225
213
  By default, this just extracts the shifts by calling
@@ -235,7 +223,7 @@ class EigenGate(raw_types.Gate):
235
223
  return [e[0] for e in self._eigen_components()]
236
224
 
237
225
  @abc.abstractmethod
238
- def _eigen_components(self) -> List[Union[EigenComponent, Tuple[float, np.ndarray]]]:
226
+ def _eigen_components(self) -> list[EigenComponent | tuple[float, np.ndarray]]:
239
227
  """Describes the eigendecomposition of the gate's matrix.
240
228
 
241
229
  Returns:
@@ -287,7 +275,7 @@ class EigenGate(raw_types.Gate):
287
275
  ]
288
276
  """
289
277
 
290
- def _period(self) -> Optional[float]:
278
+ def _period(self) -> float | None:
291
279
  """Determines how the exponent parameter is canonicalized when equating.
292
280
 
293
281
  Returns:
@@ -300,7 +288,7 @@ class EigenGate(raw_types.Gate):
300
288
  real_periods = [abs(2 / e) for e in exponents if e != 0]
301
289
  return _approximate_common_period(real_periods)
302
290
 
303
- def __pow__(self, exponent: Union[float, sympy.Symbol]) -> EigenGate:
291
+ def __pow__(self, exponent: float | sympy.Symbol) -> EigenGate:
304
292
  new_exponent = protocols.mul(self._exponent, exponent, NotImplemented)
305
293
  if new_exponent is NotImplemented:
306
294
  return NotImplemented # pragma: no cover
@@ -320,7 +308,7 @@ class EigenGate(raw_types.Gate):
320
308
  shifts = (f(self._exponent) * f(self._global_shift + e) for e in self._eigen_shifts())
321
309
  return tuple(s if symbolic(s) else value.PeriodicValue(f(s), 2) for s in shifts)
322
310
 
323
- def _trace_distance_bound_(self) -> Optional[float]:
311
+ def _trace_distance_bound_(self) -> float | None:
324
312
  if protocols.is_parameterized(self._exponent):
325
313
  return None
326
314
  angles = np.pi * (np.array(self._eigen_shifts()) * self._exponent % 2)
@@ -329,7 +317,7 @@ class EigenGate(raw_types.Gate):
329
317
  def _has_unitary_(self) -> bool:
330
318
  return not self._is_parameterized_()
331
319
 
332
- def _unitary_(self) -> Union[np.ndarray, NotImplementedType]:
320
+ def _unitary_(self) -> np.ndarray | NotImplementedType:
333
321
  if self._is_parameterized_():
334
322
  return NotImplemented
335
323
  e = cast(float, self._exponent)
@@ -372,7 +360,7 @@ class EigenGate(raw_types.Gate):
372
360
  other_without_phase._global_shift = 0
373
361
  return protocols.approx_eq(self_without_phase, other_without_phase, atol=atol)
374
362
 
375
- def _json_dict_(self) -> Dict[str, Any]:
363
+ def _json_dict_(self) -> dict[str, Any]:
376
364
  return protocols.obj_to_dict_helper(self, ['exponent', 'global_shift'])
377
365
 
378
366
  def _measurement_key_objs_(self):
@@ -387,8 +375,8 @@ def _lcm(vals: Iterable[int]) -> int:
387
375
 
388
376
 
389
377
  def _approximate_common_period(
390
- periods: List[float], approx_denom: int = 60, reject_atol: float = 1e-8
391
- ) -> Optional[float]:
378
+ periods: list[float], approx_denom: int = 60, reject_atol: float = 1e-8
379
+ ) -> float | None:
392
380
  """Finds a value that is nearly an integer multiple of multiple periods.
393
381
 
394
382
  The returned value should be the smallest non-negative number with this
@@ -432,7 +420,7 @@ def _approximate_common_period(
432
420
  return common
433
421
 
434
422
 
435
- def _common_rational_period(rational_periods: List[fractions.Fraction]) -> fractions.Fraction:
423
+ def _common_rational_period(rational_periods: list[fractions.Fraction]) -> fractions.Fraction:
436
424
  """Finds the least common integer multiple of some fractions.
437
425
 
438
426
  The solution is the smallest positive integer c such that there
@@ -14,8 +14,6 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import List, Tuple
18
-
19
17
  import numpy as np
20
18
  import pytest
21
19
  import sympy
@@ -43,7 +41,7 @@ class CExpZinGate(cirq.EigenGate, cirq.testing.TwoQubitGate):
43
41
  def _with_exponent(self, exponent):
44
42
  return CExpZinGate(exponent)
45
43
 
46
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
44
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
47
45
  return [
48
46
  (0, np.diag([1, 1, 0, 0])),
49
47
  (0.5, np.diag([0, 0, 1, 0])),
@@ -56,7 +54,7 @@ class ZGateDef(cirq.EigenGate, cirq.testing.SingleQubitGate):
56
54
  def exponent(self):
57
55
  return self._exponent
58
56
 
59
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
57
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
60
58
  return [(0, np.diag([1, 0])), (1, np.diag([0, 1]))]
61
59
 
62
60
 
@@ -210,7 +208,7 @@ def test_period():
210
208
  self.c = c
211
209
  self.d = d
212
210
 
213
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
211
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
214
212
  return [
215
213
  (self.a, np.diag([1, 0, 0, 0])),
216
214
  (self.b, np.diag([0, 1, 0, 0])),
@@ -261,7 +259,7 @@ def test_trace_distance_bound():
261
259
  def _num_qubits_(self): # pragma: no cover
262
260
  return 1
263
261
 
264
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
262
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
265
263
  return [(0, np.array([[1, 0], [0, 0]])), (12, np.array([[0, 0], [0, 1]]))]
266
264
 
267
265
  for numerator in range(13):
@@ -353,7 +351,7 @@ def test_resolve_parameters(resolve_fn):
353
351
 
354
352
  def test_diagram_period():
355
353
  class ShiftyGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
356
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
354
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
357
355
  raise NotImplementedError()
358
356
 
359
357
  def __init__(self, e, *shifts):
@@ -390,7 +388,7 @@ class WeightedZPowGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
390
388
  self.weight = weight
391
389
  super().__init__(**kwargs)
392
390
 
393
- def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
391
+ def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
394
392
  return [(0, np.diag([1, 0])), (self.weight, np.diag([0, 1]))]
395
393
 
396
394
  def _with_exponent(self, exponent):