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,19 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import abc
18
- from typing import (
19
- Any,
20
- Callable,
21
- Dict,
22
- Iterable,
23
- List,
24
- NamedTuple,
25
- Optional,
26
- Sequence,
27
- Tuple,
28
- TYPE_CHECKING,
29
- Union,
30
- )
18
+ from typing import Any, Callable, Iterable, NamedTuple, Sequence, TYPE_CHECKING, Union
31
19
 
32
20
  from cirq import devices, ops, value
33
21
 
@@ -44,7 +32,7 @@ class Cell(metaclass=abc.ABCMeta):
44
32
  """
45
33
 
46
34
  @classmethod
47
- def _replace_qubit(cls, old_qubit: cirq.Qid, qubits: List[cirq.Qid]) -> cirq.Qid:
35
+ def _replace_qubit(cls, old_qubit: cirq.Qid, qubits: list[cirq.Qid]) -> cirq.Qid:
48
36
  if not isinstance(old_qubit, devices.LineQubit):
49
37
  raise ValueError(f'Can only map from line qubits, but got {old_qubit!r}.')
50
38
  if not 0 <= old_qubit.x < len(qubits):
@@ -53,12 +41,12 @@ class Cell(metaclass=abc.ABCMeta):
53
41
 
54
42
  @classmethod
55
43
  def _replace_qubits(
56
- cls, old_qubits: Iterable[cirq.Qid], qubits: List[cirq.Qid]
57
- ) -> Tuple[cirq.Qid, ...]:
44
+ cls, old_qubits: Iterable[cirq.Qid], qubits: list[cirq.Qid]
45
+ ) -> tuple[cirq.Qid, ...]:
58
46
  return tuple(Cell._replace_qubit(e, qubits) for e in old_qubits)
59
47
 
60
48
  @abc.abstractmethod
61
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
49
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
62
50
  """Returns the same cell, but targeting different qubits.
63
51
 
64
52
  It is assumed that the cell is currently targeting `LineQubit`
@@ -87,7 +75,7 @@ class Cell(metaclass=abc.ABCMeta):
87
75
  extremely adversarial conditions.
88
76
  """
89
77
 
90
- def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> Cell:
78
+ def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> Cell:
91
79
  """The same cell, but linked to an explicit input register or constant.
92
80
 
93
81
  If the cell doesn't need the input, it is returned unchanged.
@@ -146,7 +134,7 @@ class Cell(metaclass=abc.ABCMeta):
146
134
  """
147
135
  return ()
148
136
 
149
- def modify_column(self, column: List[Optional[Cell]]) -> None:
137
+ def modify_column(self, column: list[Cell | None]) -> None:
150
138
  """Applies this cell's modification to its column.
151
139
 
152
140
  For example, a control cell will add a control qubit to other operations
@@ -162,7 +150,7 @@ class Cell(metaclass=abc.ABCMeta):
162
150
  Nothing. The `column` argument is mutated in place.
163
151
  """
164
152
 
165
- def persistent_modifiers(self) -> Dict[str, Callable[[Cell], Cell]]:
153
+ def persistent_modifiers(self) -> dict[str, Callable[[Cell], Cell]]:
166
154
  """Overridable modifications to apply to the rest of the circuit.
167
155
 
168
156
  Persistent modifiers apply to all cells in the same column and also to
@@ -189,7 +177,7 @@ class ExplicitOperationsCell(Cell):
189
177
  def gate_count(self) -> int:
190
178
  return len(self._operations) + 2 * len(self._basis_change)
191
179
 
192
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
180
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
193
181
  return ExplicitOperationsCell(
194
182
  operations=tuple(
195
183
  op.with_qubits(*Cell._replace_qubits(op.qubits, qubits)) for op in self._operations
@@ -14,18 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import (
18
- Callable,
19
- cast,
20
- Iterable,
21
- Iterator,
22
- List,
23
- Optional,
24
- Sequence,
25
- TYPE_CHECKING,
26
- TypeVar,
27
- Union,
28
- )
17
+ from typing import Callable, cast, Iterable, Iterator, Sequence, TYPE_CHECKING, TypeVar
29
18
 
30
19
  from cirq import circuits
31
20
  from cirq.interop.quirk.cells.cell import Cell
@@ -41,11 +30,7 @@ class CompositeCell(Cell):
41
30
  """
42
31
 
43
32
  def __init__(
44
- self,
45
- height: int,
46
- sub_cell_cols_generator: Iterable[List[Optional[Cell]]],
47
- *,
48
- gate_count: int,
33
+ self, height: int, sub_cell_cols_generator: Iterable[list[Cell | None]], *, gate_count: int
49
34
  ):
50
35
  """Inits CompositeCell.
51
36
 
@@ -93,15 +78,15 @@ class CompositeCell(Cell):
93
78
  gate_count=self._gate_count,
94
79
  )
95
80
 
96
- def _sub_cell_cols_sealed(self) -> List[List[Optional[Cell]]]:
81
+ def _sub_cell_cols_sealed(self) -> list[list[Cell | None]]:
97
82
  if not isinstance(self._sub_cell_cols_generator, list):
98
83
  self._sub_cell_cols_generator = list(self._sub_cell_cols_generator)
99
- return cast(List[List[Optional[Cell]]], self._sub_cell_cols_generator)
84
+ return cast(list[list[Cell | None]], self._sub_cell_cols_generator)
100
85
 
101
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
86
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
102
87
  return self._transform_cells(lambda cell: cell.with_line_qubits_mapped_to(qubits))
103
88
 
104
- def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> CompositeCell:
89
+ def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> CompositeCell:
105
90
  return self._transform_cells(lambda cell: cell.with_input(letter, register))
106
91
 
107
92
  def controlled_by(self, qubit: cirq.Qid) -> CompositeCell:
@@ -129,7 +114,7 @@ T = TypeVar('T')
129
114
 
130
115
  def _iterator_to_iterable(iterator: Iterator[T]) -> Iterable[T]:
131
116
  done = False
132
- items: List[T] = []
117
+ items: list[T] = []
133
118
 
134
119
  class IterIntoItems:
135
120
  def __iter__(self):
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Iterable, Iterator, List, Optional, TYPE_CHECKING, Union
17
+ from typing import Any, Iterable, Iterator, TYPE_CHECKING
18
18
 
19
19
  from cirq import ops, value
20
20
  from cirq.interop.quirk.cells.cell import Cell, CellMaker
@@ -44,7 +44,7 @@ class ControlCell(Cell):
44
44
  def gate_count(self) -> int:
45
45
  return 0
46
46
 
47
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
47
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
48
48
  return ControlCell(
49
49
  qubit=Cell._replace_qubit(self.qubit, qubits),
50
50
  basis_change=tuple(
@@ -53,7 +53,7 @@ class ControlCell(Cell):
53
53
  ),
54
54
  )
55
55
 
56
- def modify_column(self, column: List[Optional[Cell]]):
56
+ def modify_column(self, column: list[Cell | None]):
57
57
  for i in range(len(column)):
58
58
  gate = column[i]
59
59
  if gate is not None:
@@ -88,7 +88,7 @@ class ParityControlCell(Cell):
88
88
  def gate_count(self) -> int:
89
89
  return 0
90
90
 
91
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
91
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
92
92
  return ParityControlCell(
93
93
  qubits=Cell._replace_qubits(self.qubits, qubits),
94
94
  basis_change=tuple(
@@ -97,7 +97,7 @@ class ParityControlCell(Cell):
97
97
  ),
98
98
  )
99
99
 
100
- def modify_column(self, column: List[Optional[Cell]]):
100
+ def modify_column(self, column: list[Cell | None]):
101
101
  for i in range(len(column)):
102
102
  gate = column[i]
103
103
  if gate is self:
@@ -134,7 +134,7 @@ def generate_all_control_cell_makers() -> Iterator[CellMaker]:
134
134
  yield _reg_parity_control("zpar", basis_change=None)
135
135
 
136
136
 
137
- def _reg_control(identifier: str, *, basis_change: Optional[cirq.Gate]) -> CellMaker:
137
+ def _reg_control(identifier: str, *, basis_change: cirq.Gate | None) -> CellMaker:
138
138
  return CellMaker(
139
139
  identifier=identifier,
140
140
  size=1,
@@ -144,7 +144,7 @@ def _reg_control(identifier: str, *, basis_change: Optional[cirq.Gate]) -> CellM
144
144
  )
145
145
 
146
146
 
147
- def _reg_parity_control(identifier: str, *, basis_change: Optional[cirq.Gate] = None) -> CellMaker:
147
+ def _reg_parity_control(identifier: str, *, basis_change: cirq.Gate | None = None) -> CellMaker:
148
148
  return CellMaker(
149
149
  identifier=identifier,
150
150
  size=1,
@@ -155,7 +155,7 @@ def _reg_parity_control(identifier: str, *, basis_change: Optional[cirq.Gate] =
155
155
 
156
156
 
157
157
  def _basis_else_empty(
158
- basis_change: Optional[cirq.Gate], qureg: Union[cirq.Qid, Iterable[cirq.Qid]]
158
+ basis_change: cirq.Gate | None, qureg: cirq.Qid | Iterable[cirq.Qid]
159
159
  ) -> Iterable[cirq.Operation]:
160
160
  if basis_change is None:
161
161
  return ()
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Iterable, Iterator, List, Optional, TYPE_CHECKING
17
+ from typing import Iterable, Iterator, TYPE_CHECKING
18
18
 
19
19
  from cirq.interop.quirk.cells.cell import Cell, CELL_SIZES, CellMaker
20
20
 
@@ -32,10 +32,10 @@ class InputCell(Cell):
32
32
  def gate_count(self) -> int:
33
33
  return 0
34
34
 
35
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
35
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
36
36
  return InputCell(qubits=Cell._replace_qubits(self.qubits, qubits), letter=self.letter)
37
37
 
38
- def modify_column(self, column: List[Optional[Cell]]):
38
+ def modify_column(self, column: list[Cell | None]):
39
39
  for i in range(len(column)):
40
40
  cell = column[i]
41
41
  if cell is not None:
@@ -52,7 +52,7 @@ class SetDefaultInputCell(Cell):
52
52
  def gate_count(self) -> int:
53
53
  return 0
54
54
 
55
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
55
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
56
56
  return self
57
57
 
58
58
  def persistent_modifiers(self):
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Iterable, Iterator, List, Optional, Sequence, Tuple, Union
17
+ from typing import Any, Iterable, Iterator, Sequence
18
18
 
19
19
  import numpy as np
20
20
 
@@ -30,7 +30,7 @@ class InputRotationCell(Cell):
30
30
  def __init__(
31
31
  self,
32
32
  identifier: str,
33
- register: Optional[Sequence[cirq.Qid]],
33
+ register: Sequence[cirq.Qid] | None,
34
34
  base_operation: cirq.Operation,
35
35
  exponent_sign: int,
36
36
  ):
@@ -54,7 +54,7 @@ class InputRotationCell(Cell):
54
54
  def gate_count(self) -> int:
55
55
  return 1
56
56
 
57
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
57
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
58
58
  return InputRotationCell(
59
59
  self.identifier,
60
60
  None if self.register is None else Cell._replace_qubits(self.register, qubits),
@@ -64,7 +64,7 @@ class InputRotationCell(Cell):
64
64
  exponent_sign=self.exponent_sign,
65
65
  )
66
66
 
67
- def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> Cell:
67
+ def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> Cell:
68
68
  # Parameterized rotations use input A as their parameter.
69
69
  if self.register is None and letter == 'a':
70
70
  if isinstance(register, int):
@@ -115,7 +115,7 @@ class QuirkInputRotationOperation(ops.Operation):
115
115
  return (self.identifier, self.register, self.base_operation, self.exponent_sign)
116
116
 
117
117
  @property
118
- def qubits(self) -> Tuple[cirq.Qid, ...]:
118
+ def qubits(self) -> tuple[cirq.Qid, ...]:
119
119
  return tuple(self.base_operation.qubits) + self.register
120
120
 
121
121
  def with_qubits(self, *new_qubits):
@@ -20,22 +20,19 @@ from typing import (
20
20
  Any,
21
21
  Callable,
22
22
  cast,
23
- Dict,
24
23
  Iterable,
25
24
  Iterator,
26
- List,
27
25
  Mapping,
28
- Optional,
29
26
  SupportsFloat,
27
+ TypeAlias,
30
28
  TypeVar,
31
- Union,
32
29
  )
33
30
 
34
31
  import numpy as np
35
32
  import sympy
36
33
 
37
34
 
38
- def _merge_scientific_float_tokens(tokens: Iterable[str]) -> List[str]:
35
+ def _merge_scientific_float_tokens(tokens: Iterable[str]) -> list[str]:
39
36
  tokens = list(tokens)
40
37
  i = 0
41
38
  while 'e' in tokens[i + 1 :]:
@@ -56,8 +53,8 @@ def _merge_scientific_float_tokens(tokens: Iterable[str]) -> List[str]:
56
53
  T = TypeVar('T')
57
54
 
58
55
 
59
- def _segment_by(seq: Iterable[T], *, key: Callable[[T], Any]) -> Iterator[List[T]]:
60
- group: List[T] = []
56
+ def _segment_by(seq: Iterable[T], *, key: Callable[[T], Any]) -> Iterator[list[T]]:
57
+ group: list[T] = []
61
58
  last_key = None
62
59
  for item in seq:
63
60
  item_key = key(item)
@@ -70,8 +67,8 @@ def _segment_by(seq: Iterable[T], *, key: Callable[[T], Any]) -> Iterator[List[T
70
67
  yield group
71
68
 
72
69
 
73
- def _tokenize(text: str) -> List[str]:
74
- def classify(e: str) -> Union[str, float]:
70
+ def _tokenize(text: str) -> list[str]:
71
+ def classify(e: str) -> str | float:
75
72
  assert e.strip() != '' # Because _segment_by drops empty entries.
76
73
  if re.match(r'[.0-9]', e):
77
74
  return "#"
@@ -87,14 +84,14 @@ def _tokenize(text: str) -> List[str]:
87
84
  return _merge_scientific_float_tokens(g for g in result if g.strip())
88
85
 
89
86
 
90
- _ResolvedToken = Union[sympy.Expr, complex]
87
+ _ResolvedToken: TypeAlias = sympy.Expr | complex
91
88
 
92
89
 
93
90
  class _CustomQuirkOperationToken:
94
91
  def __init__(
95
92
  self,
96
- unary_action: Optional[Callable[[_ResolvedToken], _ResolvedToken]],
97
- binary_action: Optional[Callable[[_ResolvedToken, _ResolvedToken], _ResolvedToken]],
93
+ unary_action: Callable[[_ResolvedToken], _ResolvedToken] | None,
94
+ binary_action: Callable[[_ResolvedToken, _ResolvedToken], _ResolvedToken] | None,
98
95
  priority: float,
99
96
  ):
100
97
  self.unary_action = unary_action
@@ -110,7 +107,7 @@ class _HangingNode:
110
107
  self.weight = weight
111
108
 
112
109
 
113
- _HangingToken = Union[_ResolvedToken, str, _CustomQuirkOperationToken]
110
+ _HangingToken: TypeAlias = _ResolvedToken | str | _CustomQuirkOperationToken
114
111
 
115
112
 
116
113
  def _translate_token(token_id: str, token_map: Mapping[str, _HangingToken]) -> _HangingToken:
@@ -124,10 +121,10 @@ def _translate_token(token_id: str, token_map: Mapping[str, _HangingToken]) -> _
124
121
 
125
122
 
126
123
  def _parse_formula_using_token_map(
127
- text: str, token_map: Dict[str, _HangingToken]
124
+ text: str, token_map: dict[str, _HangingToken]
128
125
  ) -> _ResolvedToken:
129
126
  """Parses a value from an infix arithmetic expression."""
130
- tokens: List[_HangingToken] = [_translate_token(e, token_map) for e in _tokenize(text)]
127
+ tokens: list[_HangingToken] = [_translate_token(e, token_map) for e in _tokenize(text)]
131
128
 
132
129
  # Cut off trailing operation, so parse fails less often as users are typing.
133
130
  if (
@@ -137,8 +134,8 @@ def _parse_formula_using_token_map(
137
134
  ):
138
135
  tokens = tokens[:-1]
139
136
 
140
- ops: List[Union[str, _HangingNode]] = []
141
- vals: List[Optional[_HangingToken]] = []
137
+ ops: list[str | _HangingNode] = []
138
+ vals: list[_HangingToken | None] = []
142
139
 
143
140
  # Hack: use the 'priority' field as a signal of 'is an operation'
144
141
  def is_valid_end_token(tok: _HangingToken) -> bool:
@@ -147,7 +144,7 @@ def _parse_formula_using_token_map(
147
144
  def is_valid_end_state() -> bool:
148
145
  return len(vals) == 1 and len(ops) == 0
149
146
 
150
- def apply(op: Union[str, _HangingNode]) -> None:
147
+ def apply(op: str | _HangingNode) -> None:
151
148
  assert isinstance(op, _HangingNode)
152
149
  if len(vals) < 2:
153
150
  raise ValueError("Bad expression: operated on nothing.\ntext={text!r}")
@@ -239,7 +236,7 @@ UNICODE_FRACTIONS = {
239
236
  "⅒": 1 / 10,
240
237
  }
241
238
 
242
- PARSE_COMPLEX_TOKEN_MAP_ALL: Dict[str, _HangingToken] = {
239
+ PARSE_COMPLEX_TOKEN_MAP_ALL: dict[str, _HangingToken] = {
243
240
  **UNICODE_FRACTIONS,
244
241
  'i': 1j,
245
242
  'e': sympy.E,
@@ -267,7 +264,7 @@ PARSE_COMPLEX_TOKEN_MAP_ALL: Dict[str, _HangingToken] = {
267
264
  }
268
265
  PARSE_COMPLEX_TOKEN_MAP_ALL["√"] = PARSE_COMPLEX_TOKEN_MAP_ALL["sqrt"]
269
266
 
270
- PARSE_COMPLEX_TOKEN_MAP_DEG: Dict[str, _HangingToken] = {
267
+ PARSE_COMPLEX_TOKEN_MAP_DEG: dict[str, _HangingToken] = {
271
268
  **PARSE_COMPLEX_TOKEN_MAP_ALL,
272
269
  "cos": _CustomQuirkOperationToken(
273
270
  unary_action=lambda e: sympy.cos(e * sympy.pi / 180), binary_action=None, priority=4
@@ -285,7 +282,7 @@ PARSE_COMPLEX_TOKEN_MAP_DEG: Dict[str, _HangingToken] = {
285
282
  PARSE_COMPLEX_TOKEN_MAP_DEG["arccos"] = PARSE_COMPLEX_TOKEN_MAP_DEG["acos"]
286
283
  PARSE_COMPLEX_TOKEN_MAP_DEG["arcsin"] = PARSE_COMPLEX_TOKEN_MAP_DEG["asin"]
287
284
 
288
- PARSE_COMPLEX_TOKEN_MAP_RAD: Dict[str, _HangingToken] = {
285
+ PARSE_COMPLEX_TOKEN_MAP_RAD: dict[str, _HangingToken] = {
289
286
  **PARSE_COMPLEX_TOKEN_MAP_ALL,
290
287
  "cos": _CustomQuirkOperationToken(
291
288
  unary_action=lambda e: sympy.cos(e) if isinstance(e, sympy.Basic) else cmath.cos(e),
@@ -339,12 +336,12 @@ def parse_complex(text: str) -> complex:
339
336
  raise ValueError(f'Failed to parse complex from {text!r}') from ex
340
337
 
341
338
 
342
- def parse_formula(formula: str) -> Union[float, sympy.Expr]:
339
+ def parse_formula(formula: str) -> float | sympy.Expr:
343
340
  """Attempts to parse formula text in exactly the same way as Quirk."""
344
341
  if not isinstance(formula, str):
345
342
  raise TypeError('formula must be a string')
346
343
 
347
- token_map: Dict[str, _HangingToken] = {**PARSE_COMPLEX_TOKEN_MAP_RAD, 't': sympy.Symbol('t')}
344
+ token_map: dict[str, _HangingToken] = {**PARSE_COMPLEX_TOKEN_MAP_RAD, 't': sympy.Symbol('t')}
348
345
  result = _parse_formula_using_token_map(formula, token_map)
349
346
 
350
347
  if isinstance(result, sympy.Basic):
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Callable, Iterator, Sequence, Tuple, TYPE_CHECKING
17
+ from typing import Callable, Iterator, Sequence, TYPE_CHECKING
18
18
 
19
19
  from cirq import ops, value
20
20
  from cirq.interop.quirk.cells.cell import CELL_SIZES, CellMaker
@@ -44,7 +44,7 @@ class QuirkQubitPermutationGate(ops.QubitPermutationGate):
44
44
  def _value_equality_values_(self):
45
45
  return self.identifier, self.name, self.permutation
46
46
 
47
- def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> Tuple[str, ...]:
47
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> tuple[str, ...]:
48
48
  return tuple(
49
49
  f'{self.name}[{i}>{self.permutation[i]}]' for i in range(len(self.permutation))
50
50
  )
@@ -74,7 +74,7 @@ def _permutation_family(
74
74
  yield _permutation(identifier_prefix + str(n), name, permutation)
75
75
 
76
76
 
77
- def _permutation(identifier: str, name: str, permutation: Tuple[int, ...]) -> CellMaker:
77
+ def _permutation(identifier: str, name: str, permutation: tuple[int, ...]) -> CellMaker:
78
78
  return CellMaker(
79
79
  identifier,
80
80
  size=len(permutation),
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Iterable, Iterator, List, Optional, TYPE_CHECKING
17
+ from typing import Any, Iterable, Iterator, TYPE_CHECKING
18
18
 
19
19
  from cirq import ops, value
20
20
  from cirq.interop.quirk.cells.cell import Cell, CellMaker
@@ -32,13 +32,13 @@ class SwapCell(Cell):
32
32
  def gate_count(self) -> int:
33
33
  return 1
34
34
 
35
- def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
35
+ def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
36
36
  return SwapCell(
37
37
  qubits=Cell._replace_qubits(self._qubits, qubits),
38
38
  controls=Cell._replace_qubits(self._controls, qubits),
39
39
  )
40
40
 
41
- def modify_column(self, column: List[Optional[Cell]]):
41
+ def modify_column(self, column: list[Cell | None]):
42
42
  # Swallow other swap cells.
43
43
  for i in range(len(column)):
44
44
  gate = column[i]
@@ -14,8 +14,6 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Dict, List, Optional
18
-
19
17
  import numpy as np
20
18
 
21
19
  import cirq
@@ -24,12 +22,12 @@ from cirq import quirk_url_to_circuit
24
22
 
25
23
  def assert_url_to_circuit_returns(
26
24
  json_text: str,
27
- circuit: Optional[cirq.Circuit] = None,
25
+ circuit: cirq.Circuit | None = None,
28
26
  *,
29
- unitary: Optional[np.ndarray] = None,
30
- diagram: Optional[str] = None,
31
- output_amplitudes_from_quirk: Optional[List[Dict[str, float]]] = None,
32
- maps: Optional[Dict[int, int]] = None,
27
+ unitary: np.ndarray | None = None,
28
+ diagram: str | None = None,
29
+ output_amplitudes_from_quirk: list[dict[str, float]] | None = None,
30
+ maps: dict[int, int] | None = None,
33
31
  ):
34
32
  """Assert that `quirk_url_to_circuit` functions correctly.
35
33
 
@@ -16,19 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import json
18
18
  import urllib.parse
19
- from typing import (
20
- Any,
21
- cast,
22
- Dict,
23
- Iterable,
24
- List,
25
- Mapping,
26
- Optional,
27
- Sequence,
28
- Tuple,
29
- TYPE_CHECKING,
30
- Union,
31
- )
19
+ from typing import Any, cast, Iterable, Mapping, Sequence, TYPE_CHECKING
32
20
 
33
21
  import numpy as np
34
22
 
@@ -50,10 +38,8 @@ if TYPE_CHECKING:
50
38
  def quirk_url_to_circuit(
51
39
  quirk_url: str,
52
40
  *,
53
- qubits: Optional[Sequence[cirq.Qid]] = None,
54
- extra_cell_makers: Union[
55
- Dict[str, cirq.Gate], Iterable[cirq.interop.quirk.cells.CellMaker]
56
- ] = (),
41
+ qubits: Sequence[cirq.Qid] | None = None,
42
+ extra_cell_makers: dict[str, cirq.Gate] | Iterable[cirq.interop.quirk.cells.CellMaker] = (),
57
43
  max_operation_count: int = 10**6,
58
44
  ) -> cirq.Circuit:
59
45
  """Parses a Cirq circuit out of a Quirk URL.
@@ -153,11 +139,9 @@ def quirk_url_to_circuit(
153
139
  def quirk_json_to_circuit(
154
140
  data: dict,
155
141
  *,
156
- qubits: Optional[Sequence[cirq.Qid]] = None,
157
- extra_cell_makers: Union[
158
- Dict[str, cirq.Gate], Iterable[cirq.interop.quirk.cells.CellMaker]
159
- ] = (),
160
- quirk_url: Optional[str] = None,
142
+ qubits: Sequence[cirq.Qid] | None = None,
143
+ extra_cell_makers: dict[str, cirq.Gate] | Iterable[cirq.interop.quirk.cells.CellMaker] = (),
144
+ quirk_url: str | None = None,
161
145
  max_operation_count: int = 10**6,
162
146
  ) -> cirq.Circuit:
163
147
  """Constructs a Cirq circuit from Quirk's JSON format.
@@ -258,9 +242,9 @@ def quirk_json_to_circuit(
258
242
 
259
243
 
260
244
  def _parse_cols_into_composite_cell(
261
- data: Dict[str, Any], registry: Dict[str, CellMaker]
245
+ data: dict[str, Any], registry: dict[str, CellMaker]
262
246
  ) -> CompositeCell:
263
- if not isinstance(data, Dict):
247
+ if not isinstance(data, dict):
264
248
  raise ValueError('Circuit JSON must be a dictionary.')
265
249
  if 'cols' not in data:
266
250
  raise ValueError(f'Circuit JSON dict must have a "cols" entry.\nJSON={data}')
@@ -269,7 +253,7 @@ def _parse_cols_into_composite_cell(
269
253
  raise ValueError(f'Circuit JSON cols must be a list.\nJSON={data}')
270
254
 
271
255
  # Parse column json into cells.
272
- parsed_cols: List[List[Optional[Cell]]] = []
256
+ parsed_cols: list[list[Cell | None]] = []
273
257
  height = 0
274
258
  for i, col in enumerate(cols):
275
259
  parsed_col, h = _parse_col_cells_with_height(registry, i, col)
@@ -303,8 +287,8 @@ def _parse_cols_into_composite_cell(
303
287
  return CompositeCell(height, parsed_cols, gate_count=gate_count)
304
288
 
305
289
 
306
- def _register_custom_gate(gate_json: Any, registry: Dict[str, CellMaker]):
307
- if not isinstance(gate_json, Dict):
290
+ def _register_custom_gate(gate_json: Any, registry: dict[str, CellMaker]):
291
+ if not isinstance(gate_json, dict):
308
292
  raise ValueError(f'Custom gate json must be a dictionary.\nCustom gate json={gate_json!r}.')
309
293
 
310
294
  if 'id' not in gate_json:
@@ -346,11 +330,11 @@ def _register_custom_gate(gate_json: Any, registry: Dict[str, CellMaker]):
346
330
  )
347
331
 
348
332
 
349
- def _init_ops(data: Dict[str, Any]) -> cirq.OP_TREE:
333
+ def _init_ops(data: dict[str, Any]) -> cirq.OP_TREE:
350
334
  if 'init' not in data:
351
335
  return []
352
336
  init = data['init']
353
- if not isinstance(init, List):
337
+ if not isinstance(init, list):
354
338
  raise ValueError(f'Circuit JSON init must be a list but was {init!r}.')
355
339
  init_ops = []
356
340
  for i in range(len(init)):
@@ -374,8 +358,8 @@ def _init_ops(data: Dict[str, Any]) -> cirq.OP_TREE:
374
358
 
375
359
 
376
360
  def _parse_col_cells_with_height(
377
- registry: Dict[str, CellMaker], col: int, col_data: Any
378
- ) -> Tuple[List[Optional[Cell]], int]:
361
+ registry: dict[str, CellMaker], col: int, col_data: Any
362
+ ) -> tuple[list[Cell | None], int]:
379
363
  if not isinstance(col_data, list):
380
364
  raise ValueError(f'col must be a list.\ncol: {col_data!r}')
381
365
  result = []
@@ -388,8 +372,8 @@ def _parse_col_cells_with_height(
388
372
 
389
373
 
390
374
  def _parse_cell_with_height(
391
- registry: Dict[str, CellMaker], row: int, col: int, entry: Any
392
- ) -> Tuple[Optional[Cell], int]:
375
+ registry: dict[str, CellMaker], row: int, col: int, entry: Any
376
+ ) -> tuple[Cell | None, int]:
393
377
  if entry == 1:
394
378
  return None, 0
395
379
 
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
 
18
18
  import datetime
19
19
  import functools
20
- from typing import Dict, List, NamedTuple, Optional, Tuple, TYPE_CHECKING
20
+ from typing import NamedTuple, TYPE_CHECKING
21
21
 
22
22
  if TYPE_CHECKING:
23
23
  import cirq
@@ -32,18 +32,18 @@ SpecklePurityPair = NamedTuple('SpecklePurityPair', [('num_cycle', int), ('purit
32
32
  CrossEntropyResult = NamedTuple(
33
33
  'CrossEntropyResult',
34
34
  [
35
- ('data', List[CrossEntropyPair]),
35
+ ('data', list[CrossEntropyPair]),
36
36
  ('repetitions', int),
37
- ('purity_data', Optional[List[SpecklePurityPair]]),
37
+ ('purity_data', list[SpecklePurityPair] | None),
38
38
  ],
39
39
  )
40
40
  CrossEntropyResultDict = NamedTuple(
41
- 'CrossEntropyResultDict', [('results', Dict[Tuple['cirq.Qid', ...], CrossEntropyResult])]
41
+ 'CrossEntropyResultDict', [('results', dict[tuple['cirq.Qid', ...], CrossEntropyResult])]
42
42
  )
43
43
 
44
44
 
45
45
  @functools.lru_cache()
46
- def _class_resolver_dictionary() -> Dict[str, ObjectFactory]:
46
+ def _class_resolver_dictionary() -> dict[str, ObjectFactory]:
47
47
  import numpy as np
48
48
  import pandas as pd
49
49
 
@@ -82,7 +82,7 @@ def _class_resolver_dictionary() -> Dict[str, ObjectFactory]:
82
82
  )
83
83
 
84
84
  def _cross_entropy_result_dict(
85
- results: List[Tuple[List[cirq.Qid], CrossEntropyResult]], **kwargs
85
+ results: list[tuple[list[cirq.Qid], CrossEntropyResult]], **kwargs
86
86
  ) -> CrossEntropyResultDict:
87
87
  return CrossEntropyResultDict(results={tuple(qubits): result for qubits, result in results})
88
88