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
cirq/ops/identity.py CHANGED
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
 
18
18
  import numbers
19
19
  from types import NotImplementedType
20
- from typing import Any, Dict, Optional, Sequence, Tuple, TYPE_CHECKING, Union
20
+ from typing import Any, Sequence, TYPE_CHECKING
21
21
 
22
22
  import numpy as np
23
23
  import sympy
@@ -41,7 +41,7 @@ class IdentityGate(raw_types.Gate):
41
41
  """
42
42
 
43
43
  def __init__(
44
- self, num_qubits: Optional[int] = None, qid_shape: Optional[Tuple[int, ...]] = None
44
+ self, num_qubits: int | None = None, qid_shape: tuple[int, ...] | None = None
45
45
  ) -> None:
46
46
  """Inits IdentityGate.
47
47
 
@@ -68,7 +68,7 @@ class IdentityGate(raw_types.Gate):
68
68
  def _act_on_(self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]):
69
69
  return True
70
70
 
71
- def _qid_shape_(self) -> Tuple[int, ...]:
71
+ def _qid_shape_(self) -> tuple[int, ...]:
72
72
  return self._qid_shape
73
73
 
74
74
  def num_qubits(self) -> int:
@@ -79,7 +79,7 @@ class IdentityGate(raw_types.Gate):
79
79
  return self
80
80
  return NotImplemented
81
81
 
82
- def _commutes_(self, other: Any, *, atol: float = 1e-8) -> Union[bool, NotImplementedType]:
82
+ def _commutes_(self, other: Any, *, atol: float = 1e-8) -> bool | NotImplementedType:
83
83
  """The identity gate commutes with all other gates."""
84
84
  if not isinstance(other, raw_types.Gate):
85
85
  return NotImplemented
@@ -91,7 +91,7 @@ class IdentityGate(raw_types.Gate):
91
91
  def _unitary_(self) -> np.ndarray:
92
92
  return np.identity(np.prod(self._qid_shape, dtype=np.int64).item())
93
93
 
94
- def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
94
+ def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray | None:
95
95
  return args.target_tensor
96
96
 
97
97
  def _pauli_expansion_(self) -> value.LinearDict[str]:
@@ -120,13 +120,13 @@ class IdentityGate(raw_types.Gate):
120
120
  def _trace_distance_bound_(self) -> float:
121
121
  return 0.0
122
122
 
123
- def _json_dict_(self) -> Dict[str, Any]:
123
+ def _json_dict_(self) -> dict[str, Any]:
124
124
  other = {}
125
125
  if not all(d == 2 for d in self._qid_shape):
126
126
  other['qid_shape'] = self._qid_shape
127
127
  return {'num_qubits': len(self._qid_shape), **other}
128
128
 
129
- def _mul_with_qubits(self, qubits: Tuple[cirq.Qid, ...], other):
129
+ def _mul_with_qubits(self, qubits: tuple[cirq.Qid, ...], other):
130
130
  if isinstance(other, raw_types.Operation):
131
131
  return other
132
132
  if isinstance(other, numbers.Complex):
@@ -137,12 +137,12 @@ class IdentityGate(raw_types.Gate):
137
137
 
138
138
  _rmul_with_qubits = _mul_with_qubits
139
139
 
140
- def _circuit_diagram_info_(self, args) -> Tuple[str, ...]:
140
+ def _circuit_diagram_info_(self, args) -> tuple[str, ...]:
141
141
  if self.num_qubits() <= 0:
142
142
  return NotImplemented
143
143
  return ('I',) * self.num_qubits()
144
144
 
145
- def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
145
+ def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
146
146
  args.validate_version('2.0', '3.0')
147
147
  return ''.join([args.format('id {0};\n', qubit) for qubit in qubits])
148
148
 
cirq/ops/kraus_channel.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Dict, FrozenSet, Iterable, Mapping, Tuple, TYPE_CHECKING, Union
5
+ from typing import Any, Iterable, Mapping, TYPE_CHECKING
6
6
 
7
7
  import numpy as np
8
8
 
@@ -32,7 +32,7 @@ class KrausChannel(raw_types.Gate):
32
32
  def __init__(
33
33
  self,
34
34
  kraus_ops: Iterable[np.ndarray],
35
- key: Union[str, cirq.MeasurementKey, None] = None,
35
+ key: str | cirq.MeasurementKey | None = None,
36
36
  validate: bool = False,
37
37
  ):
38
38
  kraus_ops = list(kraus_ops)
@@ -59,7 +59,7 @@ class KrausChannel(raw_types.Gate):
59
59
  self._key = key
60
60
 
61
61
  @staticmethod
62
- def from_channel(channel: cirq.Gate, key: Union[str, cirq.MeasurementKey, None] = None):
62
+ def from_channel(channel: cirq.Gate, key: str | cirq.MeasurementKey | None = None):
63
63
  """Creates a copy of a channel with the given measurement key."""
64
64
  return KrausChannel(kraus_ops=list(protocols.kraus(channel)), key=key)
65
65
 
@@ -95,16 +95,16 @@ class KrausChannel(raw_types.Gate):
95
95
  return self
96
96
  return KrausChannel(kraus_ops=self._kraus_ops, key=key_map[str(self._key)])
97
97
 
98
- def _with_key_path_(self, path: Tuple[str, ...]):
98
+ def _with_key_path_(self, path: tuple[str, ...]):
99
99
  return KrausChannel(kraus_ops=self._kraus_ops, key=protocols.with_key_path(self._key, path))
100
100
 
101
- def _with_key_path_prefix_(self, prefix: Tuple[str, ...]):
101
+ def _with_key_path_prefix_(self, prefix: tuple[str, ...]):
102
102
  return KrausChannel(
103
103
  kraus_ops=self._kraus_ops, key=protocols.with_key_path_prefix(self._key, prefix)
104
104
  )
105
105
 
106
106
  def _with_rescoped_keys_(
107
- self, path: Tuple[str, ...], bindable_keys: FrozenSet[cirq.MeasurementKey]
107
+ self, path: tuple[str, ...], bindable_keys: frozenset[cirq.MeasurementKey]
108
108
  ):
109
109
  return KrausChannel(
110
110
  kraus_ops=self._kraus_ops,
@@ -122,7 +122,7 @@ class KrausChannel(raw_types.Gate):
122
122
  args.append(f'key=\'{self._key}\'')
123
123
  return f'cirq.KrausChannel({", ".join(args)})'
124
124
 
125
- def _json_dict_(self) -> Dict[str, Any]:
125
+ def _json_dict_(self) -> dict[str, Any]:
126
126
  return protocols.obj_to_dict_helper(self, ['_kraus_ops', '_key'])
127
127
 
128
128
  @classmethod
@@ -16,20 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import numbers
18
18
  from collections import defaultdict
19
- from typing import (
20
- AbstractSet,
21
- Any,
22
- DefaultDict,
23
- Dict,
24
- FrozenSet,
25
- Iterable,
26
- List,
27
- Mapping,
28
- Optional,
29
- Tuple,
30
- TYPE_CHECKING,
31
- Union,
32
- )
19
+ from typing import AbstractSet, Any, Iterable, Mapping, TYPE_CHECKING, Union
33
20
 
34
21
  import numpy as np
35
22
  import sympy
@@ -48,7 +35,7 @@ if TYPE_CHECKING:
48
35
 
49
36
  import cirq
50
37
 
51
- UnitPauliStringT = FrozenSet[Tuple[raw_types.Qid, pauli_gates.Pauli]]
38
+ UnitPauliStringT = frozenset[tuple[raw_types.Qid, pauli_gates.Pauli]]
52
39
  PauliSumLike = Union[
53
40
  complex, PauliString, 'PauliSum', pauli_string.SingleQubitPauliStringGateOperation
54
41
  ]
@@ -92,7 +79,7 @@ class LinearCombinationOfGates(value.LinearDict[raw_types.Gate]):
92
79
  """
93
80
  super().__init__(terms, validator=self._is_compatible)
94
81
 
95
- def num_qubits(self) -> Optional[int]:
82
+ def num_qubits(self) -> int | None:
96
83
  """Returns number of qubits in the domain if known, None if unknown."""
97
84
  if not self:
98
85
  return None
@@ -102,29 +89,25 @@ class LinearCombinationOfGates(value.LinearDict[raw_types.Gate]):
102
89
  def _is_compatible(self, gate: cirq.Gate) -> bool:
103
90
  return self.num_qubits() is None or self.num_qubits() == gate.num_qubits()
104
91
 
105
- def __add__(
106
- self, other: Union[raw_types.Gate, LinearCombinationOfGates]
107
- ) -> LinearCombinationOfGates:
92
+ def __add__(self, other: raw_types.Gate | LinearCombinationOfGates) -> LinearCombinationOfGates:
108
93
  if not isinstance(other, LinearCombinationOfGates):
109
94
  other = other.wrap_in_linear_combination()
110
95
  return super().__add__(other)
111
96
 
112
97
  def __iadd__(
113
- self, other: Union[raw_types.Gate, LinearCombinationOfGates]
98
+ self, other: raw_types.Gate | LinearCombinationOfGates
114
99
  ) -> LinearCombinationOfGates:
115
100
  if not isinstance(other, LinearCombinationOfGates):
116
101
  other = other.wrap_in_linear_combination()
117
102
  return super().__iadd__(other)
118
103
 
119
- def __sub__(
120
- self, other: Union[raw_types.Gate, LinearCombinationOfGates]
121
- ) -> LinearCombinationOfGates:
104
+ def __sub__(self, other: raw_types.Gate | LinearCombinationOfGates) -> LinearCombinationOfGates:
122
105
  if not isinstance(other, LinearCombinationOfGates):
123
106
  other = other.wrap_in_linear_combination()
124
107
  return super().__sub__(other)
125
108
 
126
109
  def __isub__(
127
- self, other: Union[raw_types.Gate, LinearCombinationOfGates]
110
+ self, other: raw_types.Gate | LinearCombinationOfGates
128
111
  ) -> LinearCombinationOfGates:
129
112
  if not isinstance(other, LinearCombinationOfGates):
130
113
  other = other.wrap_in_linear_combination()
@@ -239,7 +222,7 @@ class LinearCombinationOfOperations(value.LinearDict[raw_types.Operation]):
239
222
  return isinstance(operation, raw_types.Operation)
240
223
 
241
224
  @property
242
- def qubits(self) -> Tuple[raw_types.Qid, ...]:
225
+ def qubits(self) -> tuple[raw_types.Qid, ...]:
243
226
  """Returns qubits acted on self."""
244
227
  if not self:
245
228
  return ()
@@ -319,7 +302,7 @@ class LinearCombinationOfOperations(value.LinearDict[raw_types.Operation]):
319
302
  """Computes Pauli expansion of self from Pauli expansions of terms."""
320
303
 
321
304
  def extend_term(
322
- pauli_names: str, qubits: Tuple[cirq.Qid, ...], all_qubits: Tuple[cirq.Qid, ...]
305
+ pauli_names: str, qubits: tuple[cirq.Qid, ...], all_qubits: tuple[cirq.Qid, ...]
323
306
  ) -> str:
324
307
  """Extends Pauli product on qubits to product on all_qubits."""
325
308
  assert len(pauli_names) == len(qubits)
@@ -328,8 +311,8 @@ class LinearCombinationOfOperations(value.LinearDict[raw_types.Operation]):
328
311
 
329
312
  def extend(
330
313
  expansion: value.LinearDict[str],
331
- qubits: Tuple[cirq.Qid, ...],
332
- all_qubits: Tuple[cirq.Qid, ...],
314
+ qubits: tuple[cirq.Qid, ...],
315
+ all_qubits: tuple[cirq.Qid, ...],
333
316
  ) -> value.LinearDict[str]:
334
317
  """Extends Pauli expansion on qubits to expansion on all_qubits."""
335
318
  return value.LinearDict(
@@ -360,7 +343,7 @@ def _is_linear_dict_of_unit_pauli_string(linear_dict: value.LinearDict[UnitPauli
360
343
 
361
344
 
362
345
  def _pauli_string_from_unit(
363
- unit: UnitPauliStringT, coefficient: Union[int, float, cirq.TParamValComplex] = 1
346
+ unit: UnitPauliStringT, coefficient: int | float | cirq.TParamValComplex = 1
364
347
  ):
365
348
  return PauliString(qubit_pauli_map=dict(unit), coefficient=coefficient)
366
349
 
@@ -418,7 +401,7 @@ class PauliSum:
418
401
  4.0+0.0j
419
402
  """
420
403
 
421
- def __init__(self, linear_dict: Optional[value.LinearDict[UnitPauliStringT]] = None):
404
+ def __init__(self, linear_dict: value.LinearDict[UnitPauliStringT] | None = None):
422
405
  """Construct a PauliSum from a linear dictionary.
423
406
 
424
407
  Note, the preferred method of constructing PauliSum objects is either implicitly
@@ -470,7 +453,7 @@ class PauliSum:
470
453
  return PauliSum() + val
471
454
 
472
455
  @classmethod
473
- def from_pauli_strings(cls, terms: Union[PauliString, List[PauliString]]) -> PauliSum:
456
+ def from_pauli_strings(cls, terms: PauliString | list[PauliString]) -> PauliSum:
474
457
  """Returns a PauliSum by combining `cirq.PauliString` terms.
475
458
 
476
459
  Args:
@@ -482,7 +465,7 @@ class PauliSum:
482
465
  """
483
466
  if isinstance(terms, PauliString):
484
467
  terms = [terms]
485
- termdict: DefaultDict[UnitPauliStringT, value.Scalar] = defaultdict(lambda: 0)
468
+ termdict: defaultdict[UnitPauliStringT, value.Scalar] = defaultdict(lambda: 0)
486
469
  for pstring in terms:
487
470
  key = frozenset(pstring._qubit_pauli_map.items())
488
471
  termdict[key] += pstring.coefficient
@@ -490,7 +473,7 @@ class PauliSum:
490
473
 
491
474
  @classmethod
492
475
  def from_boolean_expression(
493
- cls, boolean_expr: sympy.Expr, qubit_map: Dict[str, cirq.Qid]
476
+ cls, boolean_expr: sympy.Expr, qubit_map: dict[str, cirq.Qid]
494
477
  ) -> PauliSum:
495
478
  """Builds the Hamiltonian representation of a Boolean expression.
496
479
 
@@ -542,7 +525,7 @@ class PauliSum:
542
525
  raise ValueError(f'Unsupported type: {type(boolean_expr)}')
543
526
 
544
527
  @property
545
- def qubits(self) -> Tuple[raw_types.Qid, ...]:
528
+ def qubits(self) -> tuple[raw_types.Qid, ...]:
546
529
  """The sorted list of qubits used in this PauliSum."""
547
530
  qs = {q for k in self._linear_dict.keys() for q, _ in k}
548
531
  return tuple(sorted(qs))
@@ -579,7 +562,7 @@ class PauliSum:
579
562
  factory = type(self)
580
563
  return factory(self._linear_dict.copy())
581
564
 
582
- def matrix(self, qubits: Optional[Iterable[raw_types.Qid]] = None) -> np.ndarray:
565
+ def matrix(self, qubits: Iterable[raw_types.Qid] | None = None) -> np.ndarray:
583
566
  """Returns the matrix of this PauliSum in computational basis of qubits.
584
567
 
585
568
  Args:
@@ -883,7 +866,7 @@ class ProjectorSum:
883
866
  """List of mappings representing a sum of projector operators."""
884
867
 
885
868
  def __init__(
886
- self, linear_dict: Optional[value.LinearDict[FrozenSet[Tuple[raw_types.Qid, int]]]] = None
869
+ self, linear_dict: value.LinearDict[frozenset[tuple[raw_types.Qid, int]]] | None = None
887
870
  ):
888
871
  """Constructor for ProjectorSum
889
872
 
@@ -892,7 +875,7 @@ class ProjectorSum:
892
875
  number. The tuple is a projector onto the qubit and the complex number is the
893
876
  weight of these projections.
894
877
  """
895
- self._linear_dict: value.LinearDict[FrozenSet[Tuple[raw_types.Qid, int]]] = (
878
+ self._linear_dict: value.LinearDict[frozenset[tuple[raw_types.Qid, int]]] = (
896
879
  linear_dict if linear_dict is not None else value.LinearDict({})
897
880
  )
898
881
 
@@ -900,11 +883,11 @@ class ProjectorSum:
900
883
  return self._linear_dict
901
884
 
902
885
  @property
903
- def qubits(self) -> Tuple[raw_types.Qid, ...]:
886
+ def qubits(self) -> tuple[raw_types.Qid, ...]:
904
887
  qs = {q for k in self._linear_dict.keys() for q, _ in k}
905
888
  return tuple(sorted(qs))
906
889
 
907
- def _json_dict_(self) -> Dict[str, Any]:
890
+ def _json_dict_(self) -> dict[str, Any]:
908
891
  linear_dict = []
909
892
  for projector_dict, scalar in dict(self._linear_dict).items():
910
893
  key = [[k, v] for k, v in dict(projector_dict).items()]
@@ -922,9 +905,7 @@ class ProjectorSum:
922
905
  return cls(linear_dict=value.LinearDict(converted_dict))
923
906
 
924
907
  @classmethod
925
- def from_projector_strings(
926
- cls, terms: Union[ProjectorString, List[ProjectorString]]
927
- ) -> ProjectorSum:
908
+ def from_projector_strings(cls, terms: ProjectorString | list[ProjectorString]) -> ProjectorSum:
928
909
  """Builds a ProjectorSum from one or more ProjectorString(s).
929
910
 
930
911
  Args:
@@ -935,7 +916,7 @@ class ProjectorSum:
935
916
  """
936
917
  if isinstance(terms, ProjectorString):
937
918
  terms = [terms]
938
- termdict: DefaultDict[FrozenSet[Tuple[raw_types.Qid, int]], value.Scalar] = defaultdict(
919
+ termdict: defaultdict[frozenset[tuple[raw_types.Qid, int]], value.Scalar] = defaultdict(
939
920
  lambda: 0.0
940
921
  )
941
922
  for pstring in terms:
@@ -946,7 +927,7 @@ class ProjectorSum:
946
927
  def copy(self) -> ProjectorSum:
947
928
  return ProjectorSum(self._linear_dict.copy())
948
929
 
949
- def matrix(self, projector_qids: Optional[Iterable[raw_types.Qid]] = None) -> csr_matrix:
930
+ def matrix(self, projector_qids: Iterable[raw_types.Qid] | None = None) -> csr_matrix:
950
931
  """Returns the matrix of self in computational basis of qubits.
951
932
 
952
933
  Args:
@@ -1024,7 +1005,7 @@ class ProjectorSum:
1024
1005
  def __bool__(self) -> bool:
1025
1006
  return bool(self._linear_dict)
1026
1007
 
1027
- def __iadd__(self, other: Union[ProjectorString, ProjectorSum]):
1008
+ def __iadd__(self, other: ProjectorString | ProjectorSum):
1028
1009
  if isinstance(other, ProjectorString):
1029
1010
  other = ProjectorSum.from_projector_strings(other)
1030
1011
  elif not isinstance(other, ProjectorSum):
@@ -1032,7 +1013,7 @@ class ProjectorSum:
1032
1013
  self._linear_dict += other._linear_dict
1033
1014
  return self
1034
1015
 
1035
- def __add__(self, other: Union[ProjectorString, ProjectorSum]):
1016
+ def __add__(self, other: ProjectorString | ProjectorSum):
1036
1017
  if isinstance(other, ProjectorString):
1037
1018
  other = ProjectorSum.from_projector_strings(other)
1038
1019
  elif not isinstance(other, ProjectorSum):
@@ -1041,7 +1022,7 @@ class ProjectorSum:
1041
1022
  result += other
1042
1023
  return result
1043
1024
 
1044
- def __isub__(self, other: Union[ProjectorString, ProjectorSum]):
1025
+ def __isub__(self, other: ProjectorString | ProjectorSum):
1045
1026
  if isinstance(other, ProjectorString):
1046
1027
  other = ProjectorSum.from_projector_strings(other)
1047
1028
  elif not isinstance(other, ProjectorSum):
@@ -1049,7 +1030,7 @@ class ProjectorSum:
1049
1030
  self._linear_dict -= other._linear_dict
1050
1031
  return self
1051
1032
 
1052
- def __sub__(self, other: Union[ProjectorString, ProjectorSum]):
1033
+ def __sub__(self, other: ProjectorString | ProjectorSum):
1053
1034
  if isinstance(other, ProjectorString):
1054
1035
  other = ProjectorSum.from_projector_strings(other)
1055
1036
  elif not isinstance(other, ProjectorSum):
cirq/ops/matrix_gates.py CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import Any, Dict, Iterable, List, Optional, Tuple, TYPE_CHECKING
19
+ from typing import Any, Iterable, TYPE_CHECKING
20
20
 
21
21
  import numpy as np
22
22
 
@@ -55,8 +55,8 @@ class MatrixGate(raw_types.Gate):
55
55
  self,
56
56
  matrix: np.ndarray,
57
57
  *,
58
- name: Optional[str] = None,
59
- qid_shape: Optional[Iterable[int]] = None,
58
+ name: str | None = None,
59
+ qid_shape: Iterable[int] | None = None,
60
60
  unitary_check: bool = True,
61
61
  unitary_check_rtol: float = 1e-5,
62
62
  unitary_check_atol: float = 1e-8,
@@ -115,7 +115,7 @@ class MatrixGate(raw_types.Gate):
115
115
  """Creates a new MatrixGate with the same matrix and a new name."""
116
116
  return MatrixGate(self._matrix, name=name, qid_shape=self._qid_shape, unitary_check=False)
117
117
 
118
- def _json_dict_(self) -> Dict[str, Any]:
118
+ def _json_dict_(self) -> dict[str, Any]:
119
119
  return {
120
120
  'matrix': self._matrix.tolist(),
121
121
  'qid_shape': self._qid_shape,
@@ -126,7 +126,7 @@ class MatrixGate(raw_types.Gate):
126
126
  def _from_json_dict_(cls, matrix, qid_shape, name=None, **kwargs):
127
127
  return cls(matrix=np.array(matrix), qid_shape=qid_shape, name=name)
128
128
 
129
- def _qid_shape_(self) -> Tuple[int, ...]:
129
+ def _qid_shape_(self) -> tuple[int, ...]:
130
130
  return self._qid_shape
131
131
 
132
132
  def __pow__(self, exponent: Any) -> MatrixGate:
@@ -149,10 +149,10 @@ class MatrixGate(raw_types.Gate):
149
149
  result[linalg.slice_for_qubits_equal_to([j], 1)] *= np.conj(p)
150
150
  return MatrixGate(matrix=result.reshape(self._matrix.shape), qid_shape=self._qid_shape)
151
151
 
152
- def _decompose_(self, qubits: Tuple[cirq.Qid, ...]) -> cirq.OP_TREE:
152
+ def _decompose_(self, qubits: tuple[cirq.Qid, ...]) -> cirq.OP_TREE:
153
153
  from cirq.circuits import Circuit
154
154
 
155
- decomposed: List[cirq.Operation] = NotImplemented
155
+ decomposed: list[cirq.Operation] = NotImplemented
156
156
  if self._qid_shape == (2,):
157
157
  decomposed = [
158
158
  g.on(qubits[0])
@@ -199,7 +199,7 @@ class MatrixGate(raw_types.Gate):
199
199
  rest = [f'#{i+1}' for i in range(1, n_qubits)]
200
200
  return protocols.CircuitDiagramInfo(wire_symbols=[main, *rest])
201
201
 
202
- def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
202
+ def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
203
203
  args.validate_version('2.0', '3.0')
204
204
  if self._qid_shape == (2,):
205
205
  return protocols.qasm(
cirq/ops/measure_util.py CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Callable, Dict, Iterable, List, Optional, overload, Tuple, TYPE_CHECKING, Union
17
+ from typing import Callable, Iterable, overload, TYPE_CHECKING
18
18
 
19
19
  import numpy as np
20
20
 
@@ -32,8 +32,7 @@ def _default_measurement_key(qubits: Iterable[raw_types.Qid]) -> str:
32
32
 
33
33
 
34
34
  def measure_single_paulistring(
35
- pauli_observable: pauli_string.PauliString,
36
- key: Optional[Union[str, cirq.MeasurementKey]] = None,
35
+ pauli_observable: pauli_string.PauliString, key: str | cirq.MeasurementKey | None = None
37
36
  ) -> raw_types.Operation:
38
37
  """Returns a single PauliMeasurementGate which measures the pauli observable
39
38
 
@@ -68,7 +67,7 @@ def measure_single_paulistring(
68
67
 
69
68
  def measure_paulistring_terms(
70
69
  pauli_basis: pauli_string.PauliString, key_func: Callable[[raw_types.Qid], str] = str
71
- ) -> List[raw_types.Operation]:
70
+ ) -> list[raw_types.Operation]:
72
71
  """Returns a list of operations individually measuring qubits in the pauli basis.
73
72
 
74
73
  Args:
@@ -97,8 +96,8 @@ def measure_paulistring_terms(
97
96
  @overload
98
97
  def measure(
99
98
  *target: raw_types.Qid,
100
- key: Optional[Union[str, cirq.MeasurementKey]] = None,
101
- invert_mask: Tuple[bool, ...] = (),
99
+ key: str | cirq.MeasurementKey | None = None,
100
+ invert_mask: tuple[bool, ...] = (),
102
101
  ) -> raw_types.Operation:
103
102
  pass
104
103
 
@@ -107,17 +106,17 @@ def measure(
107
106
  def measure(
108
107
  __target: Iterable[raw_types.Qid],
109
108
  *,
110
- key: Optional[Union[str, cirq.MeasurementKey]] = None,
111
- invert_mask: Tuple[bool, ...] = (),
109
+ key: str | cirq.MeasurementKey | None = None,
110
+ invert_mask: tuple[bool, ...] = (),
112
111
  ) -> raw_types.Operation:
113
112
  pass
114
113
 
115
114
 
116
115
  def measure(
117
116
  *target,
118
- key: Optional[Union[str, cirq.MeasurementKey]] = None,
119
- invert_mask: Tuple[bool, ...] = (),
120
- confusion_map: Optional[Dict[Tuple[int, ...], np.ndarray]] = None,
117
+ key: str | cirq.MeasurementKey | None = None,
118
+ invert_mask: tuple[bool, ...] = (),
119
+ confusion_map: dict[tuple[int, ...], np.ndarray] | None = None,
121
120
  ) -> raw_types.Operation:
122
121
  """Returns a single MeasurementGate applied to all the given qubits.
123
122
 
@@ -172,20 +171,20 @@ M = measure
172
171
  @overload
173
172
  def measure_each(
174
173
  *qubits: raw_types.Qid, key_func: Callable[[raw_types.Qid], str] = str
175
- ) -> List[raw_types.Operation]:
174
+ ) -> list[raw_types.Operation]:
176
175
  pass
177
176
 
178
177
 
179
178
  @overload
180
179
  def measure_each(
181
180
  __qubits: Iterable[raw_types.Qid], *, key_func: Callable[[raw_types.Qid], str] = str
182
- ) -> List[raw_types.Operation]:
181
+ ) -> list[raw_types.Operation]:
183
182
  pass
184
183
 
185
184
 
186
185
  def measure_each(
187
186
  *qubits, key_func: Callable[[raw_types.Qid], str] = str
188
- ) -> List[raw_types.Operation]:
187
+ ) -> list[raw_types.Operation]:
189
188
  """Returns a list of operations individually measuring the given qubits.
190
189
 
191
190
  The qubits are measured in the computational basis.
@@ -14,18 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import (
18
- Any,
19
- Dict,
20
- FrozenSet,
21
- Iterable,
22
- Mapping,
23
- Optional,
24
- Sequence,
25
- Tuple,
26
- TYPE_CHECKING,
27
- Union,
28
- )
17
+ from typing import Any, Iterable, Mapping, Sequence, TYPE_CHECKING
29
18
 
30
19
  import numpy as np
31
20
 
@@ -49,11 +38,11 @@ class MeasurementGate(raw_types.Gate):
49
38
 
50
39
  def __init__(
51
40
  self,
52
- num_qubits: Optional[int] = None,
53
- key: Union[str, cirq.MeasurementKey] = '',
54
- invert_mask: Tuple[bool, ...] = (),
55
- qid_shape: Optional[Tuple[int, ...]] = None,
56
- confusion_map: Optional[Dict[Tuple[int, ...], np.ndarray]] = None,
41
+ num_qubits: int | None = None,
42
+ key: str | cirq.MeasurementKey = '',
43
+ invert_mask: tuple[bool, ...] = (),
44
+ qid_shape: tuple[int, ...] | None = None,
45
+ confusion_map: dict[tuple[int, ...], np.ndarray] | None = None,
57
46
  ) -> None:
58
47
  """Inits MeasurementGate.
59
48
 
@@ -106,20 +95,20 @@ class MeasurementGate(raw_types.Gate):
106
95
  return self._mkey
107
96
 
108
97
  @property
109
- def invert_mask(self) -> Tuple[bool, ...]:
98
+ def invert_mask(self) -> tuple[bool, ...]:
110
99
  return self._invert_mask
111
100
 
112
101
  @property
113
- def confusion_map(self) -> Dict[Tuple[int, ...], np.ndarray]:
102
+ def confusion_map(self) -> dict[tuple[int, ...], np.ndarray]:
114
103
  return self._confusion_map
115
104
 
116
- def _qid_shape_(self) -> Tuple[int, ...]:
105
+ def _qid_shape_(self) -> tuple[int, ...]:
117
106
  return self._qid_shape
118
107
 
119
108
  def _has_unitary_(self) -> bool:
120
109
  return False
121
110
 
122
- def with_key(self, key: Union[str, cirq.MeasurementKey]) -> MeasurementGate:
111
+ def with_key(self, key: str | cirq.MeasurementKey) -> MeasurementGate:
123
112
  """Creates a measurement gate with a new key but otherwise identical."""
124
113
  if key == self.key:
125
114
  return self
@@ -131,14 +120,14 @@ class MeasurementGate(raw_types.Gate):
131
120
  confusion_map=self.confusion_map,
132
121
  )
133
122
 
134
- def _with_key_path_(self, path: Tuple[str, ...]):
123
+ def _with_key_path_(self, path: tuple[str, ...]):
135
124
  return self.with_key(self.mkey._with_key_path_(path))
136
125
 
137
- def _with_key_path_prefix_(self, prefix: Tuple[str, ...]):
126
+ def _with_key_path_prefix_(self, prefix: tuple[str, ...]):
138
127
  return self.with_key(self.mkey._with_key_path_prefix_(prefix))
139
128
 
140
129
  def _with_rescoped_keys_(
141
- self, path: Tuple[str, ...], bindable_keys: FrozenSet[cirq.MeasurementKey]
130
+ self, path: tuple[str, ...], bindable_keys: frozenset[cirq.MeasurementKey]
142
131
  ):
143
132
  return self.with_key(protocols.with_rescoped_keys(self.mkey, path, bindable_keys))
144
133
 
@@ -164,7 +153,7 @@ class MeasurementGate(raw_types.Gate):
164
153
  confusion_map=self.confusion_map,
165
154
  )
166
155
 
167
- def full_invert_mask(self) -> Tuple[bool, ...]:
156
+ def full_invert_mask(self) -> tuple[bool, ...]:
168
157
  """Returns the invert mask for all qubits.
169
158
 
170
159
  If the user supplies a partial invert_mask, this returns that mask
@@ -224,7 +213,7 @@ class MeasurementGate(raw_types.Gate):
224
213
 
225
214
  return protocols.CircuitDiagramInfo(symbols)
226
215
 
227
- def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
216
+ def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
228
217
  if self.confusion_map or not all(d == 2 for d in self._qid_shape):
229
218
  return NotImplemented
230
219
  args.validate_version('2.0', '3.0')
@@ -275,8 +264,8 @@ class MeasurementGate(raw_types.Gate):
275
264
  )
276
265
  return self.key, self.full_invert_mask(), self._qid_shape, hashable_cmap
277
266
 
278
- def _json_dict_(self) -> Dict[str, Any]:
279
- other: Dict[str, Any] = {}
267
+ def _json_dict_(self) -> dict[str, Any]:
268
+ other: dict[str, Any] = {}
280
269
  if not all(d == 2 for d in self._qid_shape):
281
270
  other['qid_shape'] = self._qid_shape
282
271
  if self.confusion_map:
@@ -301,7 +290,7 @@ class MeasurementGate(raw_types.Gate):
301
290
  confusion_map={tuple(k): np.array(v) for k, v in confusion_map or []},
302
291
  )
303
292
 
304
- def _has_stabilizer_effect_(self) -> Optional[bool]:
293
+ def _has_stabilizer_effect_(self) -> bool | None:
305
294
  return True
306
295
 
307
296
  def _act_on_(self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]) -> bool: