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
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
  import abc
18
18
  import functools
19
19
  import weakref
20
- from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, TYPE_CHECKING, Union
20
+ from typing import Any, Iterable, TYPE_CHECKING
21
21
 
22
22
  import numpy as np
23
23
  from typing_extensions import Self
@@ -35,7 +35,7 @@ class _BaseGridQid(ops.Qid):
35
35
  _row: int
36
36
  _col: int
37
37
  _dimension: int
38
- _comp_key: Optional[Tuple[int, int]] = None
38
+ _comp_key: tuple[int, int] | None = None
39
39
  _hash: int
40
40
 
41
41
  def __hash__(self) -> int:
@@ -116,7 +116,7 @@ class _BaseGridQid(ops.Qid):
116
116
  and abs(self._row - other._row) + abs(self._col - other._col) == 1
117
117
  )
118
118
 
119
- def neighbors(self, qids: Optional[Iterable[ops.Qid]] = None) -> Set[_BaseGridQid]:
119
+ def neighbors(self, qids: Iterable[ops.Qid] | None = None) -> set[_BaseGridQid]:
120
120
  """Returns qubits that are potential neighbors to this GridQid
121
121
 
122
122
  Args:
@@ -135,7 +135,7 @@ class _BaseGridQid(ops.Qid):
135
135
  def __complex__(self) -> complex:
136
136
  return self._col + 1j * self._row
137
137
 
138
- def __add__(self, other: Union[Tuple[int, int], Self]) -> Self:
138
+ def __add__(self, other: tuple[int, int] | Self) -> Self:
139
139
  if isinstance(other, _BaseGridQid):
140
140
  if self.dimension != other.dimension:
141
141
  raise TypeError(
@@ -154,7 +154,7 @@ class _BaseGridQid(ops.Qid):
154
154
  )
155
155
  return self._with_row_col(row=self._row + other[0], col=self._col + other[1])
156
156
 
157
- def __sub__(self, other: Union[Tuple[int, int], Self]) -> Self:
157
+ def __sub__(self, other: tuple[int, int] | Self) -> Self:
158
158
  if isinstance(other, _BaseGridQid):
159
159
  if self.dimension != other.dimension:
160
160
  raise TypeError(
@@ -173,10 +173,10 @@ class _BaseGridQid(ops.Qid):
173
173
  )
174
174
  return self._with_row_col(row=self._row - other[0], col=self._col - other[1])
175
175
 
176
- def __radd__(self, other: Tuple[int, int]) -> Self:
176
+ def __radd__(self, other: tuple[int, int]) -> Self:
177
177
  return self + other
178
178
 
179
- def __rsub__(self, other: Tuple[int, int]) -> Self:
179
+ def __rsub__(self, other: tuple[int, int]) -> Self:
180
180
  return -self + other
181
181
 
182
182
  def __neg__(self) -> Self:
@@ -204,7 +204,7 @@ class GridQid(_BaseGridQid):
204
204
 
205
205
  # Cache of existing GridQid instances, returned by __new__ if available.
206
206
  # Holds weak references so instances can still be garbage collected.
207
- _cache = weakref.WeakValueDictionary[Tuple[int, int, int], 'cirq.GridQid']()
207
+ _cache = weakref.WeakValueDictionary[tuple[int, int, int], 'cirq.GridQid']()
208
208
 
209
209
  def __new__(cls, row: int, col: int, *, dimension: int) -> cirq.GridQid:
210
210
  """Creates a grid qid at the given row, col coordinate
@@ -233,14 +233,14 @@ class GridQid(_BaseGridQid):
233
233
  return (self._row, self._col), {"dimension": self._dimension}
234
234
 
235
235
  # avoid pickling the _hash value, attributes are already stored with __getnewargs_ex__
236
- def __getstate__(self) -> Dict[str, Any]:
236
+ def __getstate__(self) -> dict[str, Any]:
237
237
  return {}
238
238
 
239
239
  def _with_row_col(self, row: int, col: int) -> GridQid:
240
240
  return GridQid(row, col, dimension=self._dimension)
241
241
 
242
242
  @staticmethod
243
- def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) -> List[GridQid]:
243
+ def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) -> list[GridQid]:
244
244
  """Returns a square of GridQid.
245
245
 
246
246
  Args:
@@ -256,7 +256,7 @@ class GridQid(_BaseGridQid):
256
256
  return GridQid.rect(diameter, diameter, top=top, left=left, dimension=dimension)
257
257
 
258
258
  @staticmethod
259
- def rect(rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int) -> List[GridQid]:
259
+ def rect(rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int) -> list[GridQid]:
260
260
  """Returns a rectangle of GridQid.
261
261
 
262
262
  Args:
@@ -277,7 +277,7 @@ class GridQid(_BaseGridQid):
277
277
  ]
278
278
 
279
279
  @staticmethod
280
- def from_diagram(diagram: str, dimension: int) -> List[GridQid]:
280
+ def from_diagram(diagram: str, dimension: int) -> list[GridQid]:
281
281
  """Parse ASCII art device layout into a device.
282
282
 
283
283
  As an example, the below diagram will create a list of GridQid in a
@@ -342,7 +342,7 @@ class GridQid(_BaseGridQid):
342
342
  wire_symbols=(f"({self._row}, {self._col}) (d={self._dimension})",)
343
343
  )
344
344
 
345
- def _json_dict_(self) -> Dict[str, Any]:
345
+ def _json_dict_(self) -> dict[str, Any]:
346
346
  return protocols.obj_to_dict_helper(self, ['row', 'col', 'dimension'])
347
347
 
348
348
 
@@ -367,7 +367,7 @@ class GridQubit(_BaseGridQid):
367
367
 
368
368
  # Cache of existing GridQubit instances, returned by __new__ if available.
369
369
  # Holds weak references so instances can still be garbage collected.
370
- _cache = weakref.WeakValueDictionary[Tuple[int, int], 'cirq.GridQubit']()
370
+ _cache = weakref.WeakValueDictionary[tuple[int, int], 'cirq.GridQubit']()
371
371
 
372
372
  def __new__(cls, row: int, col: int) -> cirq.GridQubit:
373
373
  """Creates a grid qubit at the given row, col coordinate
@@ -391,14 +391,14 @@ class GridQubit(_BaseGridQid):
391
391
  return (self._row, self._col)
392
392
 
393
393
  # avoid pickling the _hash value, attributes are already stored with __getnewargs__
394
- def __getstate__(self) -> Dict[str, Any]:
394
+ def __getstate__(self) -> dict[str, Any]:
395
395
  return {}
396
396
 
397
397
  def _with_row_col(self, row: int, col: int) -> GridQubit:
398
398
  return GridQubit(row, col)
399
399
 
400
400
  @staticmethod
401
- def square(diameter: int, top: int = 0, left: int = 0) -> List[GridQubit]:
401
+ def square(diameter: int, top: int = 0, left: int = 0) -> list[GridQubit]:
402
402
  """Returns a square of GridQubits.
403
403
 
404
404
  Args:
@@ -412,7 +412,7 @@ class GridQubit(_BaseGridQid):
412
412
  return GridQubit.rect(diameter, diameter, top=top, left=left)
413
413
 
414
414
  @staticmethod
415
- def rect(rows: int, cols: int, top: int = 0, left: int = 0) -> List[GridQubit]:
415
+ def rect(rows: int, cols: int, top: int = 0, left: int = 0) -> list[GridQubit]:
416
416
  """Returns a rectangle of GridQubits.
417
417
 
418
418
  Args:
@@ -431,7 +431,7 @@ class GridQubit(_BaseGridQid):
431
431
  ]
432
432
 
433
433
  @staticmethod
434
- def from_diagram(diagram: str) -> List[GridQubit]:
434
+ def from_diagram(diagram: str) -> list[GridQubit]:
435
435
  """Parse ASCII art into device layout info.
436
436
 
437
437
  As an example, the below diagram will create a list of
@@ -491,11 +491,11 @@ class GridQubit(_BaseGridQid):
491
491
  def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
492
492
  return protocols.CircuitDiagramInfo(wire_symbols=(f"({self._row}, {self._col})",))
493
493
 
494
- def _json_dict_(self) -> Dict[str, Any]:
494
+ def _json_dict_(self) -> dict[str, Any]:
495
495
  return protocols.obj_to_dict_helper(self, ['row', 'col'])
496
496
 
497
497
 
498
- def _ascii_diagram_to_coords(diagram: str) -> List[Tuple[int, int]]:
498
+ def _ascii_diagram_to_coords(diagram: str) -> list[tuple[int, int]]:
499
499
  """Parse ASCII art device layout into info about qids coordinates
500
500
 
501
501
  Args:
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import dataclasses
18
- from typing import Any, Dict, List, Optional, Sequence, TYPE_CHECKING
18
+ from typing import Any, Sequence, TYPE_CHECKING
19
19
 
20
20
  from cirq import devices
21
21
  from cirq.devices import noise_utils
@@ -44,21 +44,21 @@ class InsertionNoiseModel(devices.NoiseModel):
44
44
  with PHYSICAL_GATE_TAG.
45
45
  """
46
46
 
47
- ops_added: Dict[noise_utils.OpIdentifier, cirq.Operation] = dataclasses.field(
47
+ ops_added: dict[noise_utils.OpIdentifier, cirq.Operation] = dataclasses.field(
48
48
  default_factory=dict
49
49
  )
50
50
  prepend: bool = False
51
51
  require_physical_tag: bool = True
52
52
 
53
53
  def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
54
- noise_ops: List[cirq.Operation] = []
54
+ noise_ops: list[cirq.Operation] = []
55
55
  candidate_ops = [
56
56
  op
57
57
  for op in moment
58
58
  if (not self.require_physical_tag) or noise_utils.PHYSICAL_GATE_TAG in op.tags
59
59
  ]
60
60
  for op in candidate_ops:
61
- match_id: Optional[noise_utils.OpIdentifier] = None
61
+ match_id: noise_utils.OpIdentifier | None = None
62
62
  candidate_ids = [op_id for op_id in self.ops_added if op in op_id]
63
63
  for op_id in candidate_ids:
64
64
  if match_id is None or op_id.is_proper_subtype_of(match_id):
@@ -82,7 +82,7 @@ class InsertionNoiseModel(devices.NoiseModel):
82
82
  + f' require_physical_tag={self.require_physical_tag})'
83
83
  )
84
84
 
85
- def _json_dict_(self) -> Dict[str, Any]:
85
+ def _json_dict_(self) -> dict[str, Any]:
86
86
  return {
87
87
  'ops_added': list(self.ops_added.items()),
88
88
  'prepend': self.prepend,
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
  import abc
18
18
  import functools
19
19
  import weakref
20
- from typing import Any, Dict, Iterable, List, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
20
+ from typing import Any, Iterable, Sequence, TYPE_CHECKING
21
21
 
22
22
  from typing_extensions import Self
23
23
 
@@ -108,7 +108,7 @@ class _BaseLineQid(ops.Qid):
108
108
  """
109
109
  return isinstance(other, _BaseLineQid) and abs(self._x - other._x) == 1
110
110
 
111
- def neighbors(self, qids: Optional[Iterable[ops.Qid]] = None) -> Set[_BaseLineQid]:
111
+ def neighbors(self, qids: Iterable[ops.Qid] | None = None) -> set[_BaseLineQid]:
112
112
  """Returns qubits that are potential neighbors to this LineQubit
113
113
 
114
114
  Args:
@@ -120,7 +120,7 @@ class _BaseLineQid(ops.Qid):
120
120
  def _with_x(self, x: int) -> Self:
121
121
  """Returns a qubit with the same type but a different value of `x`."""
122
122
 
123
- def __add__(self, other: Union[int, Self]) -> Self:
123
+ def __add__(self, other: int | Self) -> Self:
124
124
  if isinstance(other, _BaseLineQid):
125
125
  if self._dimension != other._dimension:
126
126
  raise TypeError(
@@ -132,7 +132,7 @@ class _BaseLineQid(ops.Qid):
132
132
  raise TypeError(f"Can only add ints and {type(self).__name__}. Instead was {other}")
133
133
  return self._with_x(self._x + other)
134
134
 
135
- def __sub__(self, other: Union[int, Self]) -> Self:
135
+ def __sub__(self, other: int | Self) -> Self:
136
136
  if isinstance(other, _BaseLineQid):
137
137
  if self._dimension != other._dimension:
138
138
  raise TypeError(
@@ -184,7 +184,7 @@ class LineQid(_BaseLineQid):
184
184
 
185
185
  # Cache of existing LineQid instances, returned by __new__ if available.
186
186
  # Holds weak references so instances can still be garbage collected.
187
- _cache = weakref.WeakValueDictionary[Tuple[int, int], 'cirq.LineQid']()
187
+ _cache = weakref.WeakValueDictionary[tuple[int, int], 'cirq.LineQid']()
188
188
 
189
189
  def __new__(cls, x: int, dimension: int) -> cirq.LineQid:
190
190
  """Initializes a line qid at the given x coordinate.
@@ -211,14 +211,14 @@ class LineQid(_BaseLineQid):
211
211
  return (self._x, self._dimension)
212
212
 
213
213
  # avoid pickling the _hash value, attributes are already stored with __getnewargs__
214
- def __getstate__(self) -> Dict[str, Any]:
214
+ def __getstate__(self) -> dict[str, Any]:
215
215
  return {}
216
216
 
217
217
  def _with_x(self, x: int) -> LineQid:
218
218
  return LineQid(x, dimension=self._dimension)
219
219
 
220
220
  @staticmethod
221
- def range(*range_args, dimension: int) -> List[LineQid]:
221
+ def range(*range_args, dimension: int) -> list[LineQid]:
222
222
  """Returns a range of line qids.
223
223
 
224
224
  Args:
@@ -232,7 +232,7 @@ class LineQid(_BaseLineQid):
232
232
  return [LineQid(i, dimension=dimension) for i in range(*range_args)]
233
233
 
234
234
  @staticmethod
235
- def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) -> List[LineQid]:
235
+ def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) -> list[LineQid]:
236
236
  """Returns a range of line qids for each entry in `qid_shape` with
237
237
  matching dimension.
238
238
 
@@ -246,7 +246,7 @@ class LineQid(_BaseLineQid):
246
246
  ]
247
247
 
248
248
  @staticmethod
249
- def for_gate(val: Any, start: int = 0, step: int = 1) -> List[LineQid]:
249
+ def for_gate(val: Any, start: int = 0, step: int = 1) -> list[LineQid]:
250
250
  """Returns a range of line qids with the same qid shape as the gate.
251
251
 
252
252
  Args:
@@ -269,7 +269,7 @@ class LineQid(_BaseLineQid):
269
269
  def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
270
270
  return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x} (d={self._dimension})",))
271
271
 
272
- def _json_dict_(self) -> Dict[str, Any]:
272
+ def _json_dict_(self) -> dict[str, Any]:
273
273
  return protocols.obj_to_dict_helper(self, ['x', 'dimension'])
274
274
 
275
275
 
@@ -315,14 +315,14 @@ class LineQubit(_BaseLineQid):
315
315
  return (self._x,)
316
316
 
317
317
  # avoid pickling the _hash value, attributes are already stored with __getnewargs__
318
- def __getstate__(self) -> Dict[str, Any]:
318
+ def __getstate__(self) -> dict[str, Any]:
319
319
  return {}
320
320
 
321
321
  def _with_x(self, x: int) -> LineQubit:
322
322
  return LineQubit(x)
323
323
 
324
324
  @staticmethod
325
- def range(*range_args) -> List[LineQubit]:
325
+ def range(*range_args) -> list[LineQubit]:
326
326
  """Returns a range of line qubits.
327
327
 
328
328
  Args:
@@ -342,5 +342,5 @@ class LineQubit(_BaseLineQid):
342
342
  def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
343
343
  return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x}",))
344
344
 
345
- def _json_dict_(self) -> Dict[str, Any]:
345
+ def _json_dict_(self) -> dict[str, Any]:
346
346
  return protocols.obj_to_dict_helper(self, ['x'])
@@ -17,18 +17,7 @@ from __future__ import annotations
17
17
  import abc
18
18
  import warnings
19
19
  from dataclasses import dataclass
20
- from typing import (
21
- Any,
22
- Callable,
23
- Dict,
24
- Iterable,
25
- List,
26
- Optional,
27
- Sequence,
28
- Tuple,
29
- TYPE_CHECKING,
30
- Union,
31
- )
20
+ from typing import Any, Callable, Iterable, Sequence, TYPE_CHECKING, Union
32
21
 
33
22
  import networkx as nx
34
23
  from matplotlib import pyplot as plt
@@ -59,12 +48,12 @@ class NamedTopology(metaclass=abc.ABCMeta):
59
48
  """A networkx graph representation of the topology."""
60
49
 
61
50
 
62
- _GRIDLIKE_NODE = Union['cirq.GridQubit', Tuple[int, int]]
51
+ _GRIDLIKE_NODE = Union['cirq.GridQubit', tuple[int, int]]
63
52
 
64
53
 
65
54
  def _node_and_coordinates(
66
55
  nodes: Iterable[_GRIDLIKE_NODE],
67
- ) -> Iterable[Tuple[_GRIDLIKE_NODE, Tuple[int, int]]]:
56
+ ) -> Iterable[tuple[_GRIDLIKE_NODE, tuple[int, int]]]:
68
57
  """Yield tuples whose first element is the input node and the second is guaranteed to be a tuple
69
58
  of two integers. The input node can be a tuple of ints or a GridQubit."""
70
59
  for node in nodes:
@@ -76,8 +65,8 @@ def _node_and_coordinates(
76
65
 
77
66
 
78
67
  def draw_gridlike(
79
- graph: nx.Graph, ax: Optional[plt.Axes] = None, tilted: bool = True, **kwargs
80
- ) -> Dict[Any, Tuple[int, int]]:
68
+ graph: nx.Graph, ax: plt.Axes | None = None, tilted: bool = True, **kwargs
69
+ ) -> dict[Any, tuple[int, int]]:
81
70
  """Draw a grid-like graph using Matplotlib.
82
71
 
83
72
  This wraps nx.draw_networkx to produce a matplotlib drawing of the graph. Nodes
@@ -129,11 +118,11 @@ class LineTopology(NamedTopology):
129
118
  )
130
119
  object.__setattr__(self, 'graph', graph)
131
120
 
132
- def nodes_as_linequbits(self) -> List[cirq.LineQubit]:
121
+ def nodes_as_linequbits(self) -> list[cirq.LineQubit]:
133
122
  """Get the graph nodes as cirq.LineQubit"""
134
123
  return [LineQubit(x) for x in sorted(self.graph.nodes)]
135
124
 
136
- def draw(self, ax=None, tilted: bool = True, **kwargs) -> Dict[Any, Tuple[int, int]]:
125
+ def draw(self, ax=None, tilted: bool = True, **kwargs) -> dict[Any, tuple[int, int]]:
137
126
  """Draw this graph using Matplotlib.
138
127
 
139
128
  Args:
@@ -144,7 +133,7 @@ class LineTopology(NamedTopology):
144
133
  g2 = nx.relabel_nodes(self.graph, {n: (n, 1) for n in self.graph.nodes})
145
134
  return draw_gridlike(g2, ax=ax, tilted=tilted, **kwargs)
146
135
 
147
- def nodes_to_linequbits(self, offset: int = 0) -> Dict[int, cirq.LineQubit]:
136
+ def nodes_to_linequbits(self, offset: int = 0) -> dict[int, cirq.LineQubit]:
148
137
  """Return a mapping from graph nodes to `cirq.LineQubit`
149
138
 
150
139
  Args:
@@ -152,7 +141,7 @@ class LineTopology(NamedTopology):
152
141
  """
153
142
  return dict(enumerate(LineQubit.range(offset, offset + self.n_nodes)))
154
143
 
155
- def _json_dict_(self) -> Dict[str, Any]:
144
+ def _json_dict_(self) -> dict[str, Any]:
156
145
  return dataclass_json_dict(self)
157
146
 
158
147
  def __repr__(self) -> str:
@@ -242,11 +231,11 @@ class TiltedSquareLattice(NamedTopology):
242
231
  """
243
232
  return draw_gridlike(self.graph, ax=ax, tilted=tilted, **kwargs)
244
233
 
245
- def nodes_as_gridqubits(self) -> List[cirq.GridQubit]:
234
+ def nodes_as_gridqubits(self) -> list[cirq.GridQubit]:
246
235
  """Get the graph nodes as cirq.GridQubit"""
247
236
  return [GridQubit(r, c) for r, c in sorted(self.graph.nodes)]
248
237
 
249
- def nodes_to_gridqubits(self, offset=(0, 0)) -> Dict[Tuple[int, int], cirq.GridQubit]:
238
+ def nodes_to_gridqubits(self, offset=(0, 0)) -> dict[tuple[int, int], cirq.GridQubit]:
250
239
  """Return a mapping from graph nodes to `cirq.GridQubit`
251
240
 
252
241
  Args:
@@ -255,7 +244,7 @@ class TiltedSquareLattice(NamedTopology):
255
244
  """
256
245
  return {(r, c): GridQubit(r, c) + offset for r, c in self.graph.nodes}
257
246
 
258
- def _json_dict_(self) -> Dict[str, Any]:
247
+ def _json_dict_(self) -> dict[str, Any]:
259
248
  return dataclass_json_dict(self)
260
249
 
261
250
  def __repr__(self) -> str:
@@ -264,7 +253,7 @@ class TiltedSquareLattice(NamedTopology):
264
253
 
265
254
  def get_placements(
266
255
  big_graph: nx.Graph, small_graph: nx.Graph, max_placements=100_000
267
- ) -> List[Dict]:
256
+ ) -> list[dict]:
268
257
  """Get 'placements' mapping small_graph nodes onto those of `big_graph`.
269
258
 
270
259
  This function considers monomorphisms with a restriction: we restrict only to unique set
@@ -311,7 +300,7 @@ def get_placements(
311
300
 
312
301
 
313
302
  def _is_valid_placement_helper(
314
- big_graph: nx.Graph, small_mapped: nx.Graph, small_to_big_mapping: Dict
303
+ big_graph: nx.Graph, small_mapped: nx.Graph, small_to_big_mapping: dict
315
304
  ):
316
305
  """Helper function for `is_valid_placement` that assumes the mapping of `small_graph` has
317
306
  already occurred.
@@ -322,7 +311,7 @@ def _is_valid_placement_helper(
322
311
  return (subgraph.nodes == small_mapped.nodes) and (subgraph.edges == small_mapped.edges)
323
312
 
324
313
 
325
- def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_mapping: Dict):
314
+ def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_mapping: dict):
326
315
  """Return whether the given placement is a valid placement of small_graph onto big_graph.
327
316
 
328
317
  This is done by making sure all the nodes and edges on the mapped version of `small_graph`
@@ -344,11 +333,11 @@ def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_
344
333
  def draw_placements(
345
334
  big_graph: nx.Graph,
346
335
  small_graph: nx.Graph,
347
- small_to_big_mappings: Sequence[Dict],
336
+ small_to_big_mappings: Sequence[dict],
348
337
  max_plots: int = 20,
349
- axes: Optional[Sequence[plt.Axes]] = None,
338
+ axes: Sequence[plt.Axes] | None = None,
350
339
  tilted: bool = True,
351
- bad_placement_callback: Optional[Callable[[plt.Axes, int], None]] = None,
340
+ bad_placement_callback: Callable[[plt.Axes, int], None] | None = None,
352
341
  ):
353
342
  """Draw a visualization of placements from small_graph onto big_graph using Matplotlib.
354
343
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Callable, Dict, Iterable, Sequence, TYPE_CHECKING, Union
17
+ from typing import Any, Callable, Iterable, Sequence, TYPE_CHECKING, Union
18
18
 
19
19
  from cirq import ops, protocols, value
20
20
  from cirq._doc import document
@@ -196,7 +196,7 @@ class _NoNoiseModel(NoiseModel):
196
196
  def __repr__(self) -> str:
197
197
  return 'cirq.NO_NOISE'
198
198
 
199
- def _json_dict_(self) -> Dict[str, Any]:
199
+ def _json_dict_(self) -> dict[str, Any]:
200
200
  return protocols.obj_to_dict_helper(self, [])
201
201
 
202
202
  def _has_unitary_(self) -> bool:
@@ -247,7 +247,7 @@ class ConstantQubitNoiseModel(NoiseModel):
247
247
  ]
248
248
  return output[::-1] if self._prepend else output
249
249
 
250
- def _json_dict_(self) -> Dict[str, Any]:
250
+ def _json_dict_(self) -> dict[str, Any]:
251
251
  return protocols.obj_to_dict_helper(self, ['qubit_noise_gate'])
252
252
 
253
253
  def _has_unitary_(self) -> bool:
@@ -22,7 +22,7 @@ noise models to produce a single noise model which replicates device noise.
22
22
  from __future__ import annotations
23
23
 
24
24
  import abc
25
- from typing import Iterable, List, Sequence, TYPE_CHECKING
25
+ from typing import Iterable, Sequence, TYPE_CHECKING
26
26
 
27
27
  from cirq import _import, devices, ops, protocols
28
28
  from cirq.devices.noise_utils import PHYSICAL_GATE_TAG
@@ -37,7 +37,7 @@ class NoiseProperties(abc.ABC):
37
37
  """Noise-defining properties for a quantum device."""
38
38
 
39
39
  @abc.abstractmethod
40
- def build_noise_models(self) -> List[cirq.NoiseModel]:
40
+ def build_noise_models(self) -> list[cirq.NoiseModel]:
41
41
  """Construct all NoiseModels associated with this NoiseProperties."""
42
42
 
43
43
 
@@ -14,8 +14,6 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import List, Tuple
18
-
19
17
  import cirq
20
18
  from cirq.devices.insertion_noise_model import InsertionNoiseModel
21
19
  from cirq.devices.noise_properties import NoiseModelFromNoiseProperties, NoiseProperties
@@ -25,7 +23,7 @@ from cirq.devices.noise_utils import OpIdentifier, PHYSICAL_GATE_TAG
25
23
  # These properties are for testing purposes only - they are not representative
26
24
  # of device behavior for any existing hardware.
27
25
  class SampleNoiseProperties(NoiseProperties):
28
- def __init__(self, system_qubits: List[cirq.Qid], qubit_pairs: List[Tuple[cirq.Qid, cirq.Qid]]):
26
+ def __init__(self, system_qubits: list[cirq.Qid], qubit_pairs: list[tuple[cirq.Qid, cirq.Qid]]):
29
27
  self.qubits = system_qubits
30
28
  self.qubit_pairs = qubit_pairs
31
29
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Dict, Tuple, Type, TYPE_CHECKING, Union
17
+ from typing import Any, TYPE_CHECKING
18
18
 
19
19
  from cirq import ops, protocols, qis, value
20
20
  from cirq._compat import deprecated, proper_repr
@@ -31,18 +31,18 @@ PHYSICAL_GATE_TAG = 'physical_gate'
31
31
  class OpIdentifier:
32
32
  """Identifies an operation by gate and (optionally) target qubits."""
33
33
 
34
- def __init__(self, gate_type: Type[cirq.Gate], *qubits: cirq.Qid):
34
+ def __init__(self, gate_type: type[cirq.Gate], *qubits: cirq.Qid):
35
35
  self._gate_type = gate_type
36
36
  self._gate_family = ops.GateFamily(gate_type)
37
- self._qubits: Tuple[cirq.Qid, ...] = tuple(qubits)
37
+ self._qubits: tuple[cirq.Qid, ...] = tuple(qubits)
38
38
 
39
39
  @property
40
- def gate_type(self) -> Type[cirq.Gate]:
40
+ def gate_type(self) -> type[cirq.Gate]:
41
41
  # set to a type during initialization, never modified
42
42
  return self._gate_type
43
43
 
44
44
  @property
45
- def qubits(self) -> Tuple[cirq.Qid, ...]:
45
+ def qubits(self) -> tuple[cirq.Qid, ...]:
46
46
  return self._qubits
47
47
 
48
48
  def _predicate(self, *args, **kwargs):
@@ -67,7 +67,7 @@ class OpIdentifier:
67
67
  else:
68
68
  return False
69
69
 
70
- def __contains__(self, item: Union[ops.Gate, ops.Operation]) -> bool:
70
+ def __contains__(self, item: ops.Gate | ops.Operation) -> bool:
71
71
  if isinstance(item, ops.Gate):
72
72
  return (not self._qubits) and self._predicate(item)
73
73
  return (
@@ -86,7 +86,7 @@ class OpIdentifier:
86
86
  def _value_equality_values_(self) -> Any:
87
87
  return (self.gate_type, self.qubits)
88
88
 
89
- def _json_dict_(self) -> Dict[str, Any]:
89
+ def _json_dict_(self) -> dict[str, Any]:
90
90
  if hasattr(self.gate_type, '__name__'):
91
91
  return {'gate_type': protocols.json_cirq_type(self._gate_type), 'qubits': self._qubits}
92
92
  return {'gate_type': self._gate_type, 'qubits': self._qubits}