classiq 0.93.0__py3-none-any.whl → 0.94.0__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 classiq might be problematic. Click here for more details.

Files changed (261) hide show
  1. classiq/__init__.py +6 -19
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
  3. classiq/_analyzer_extras/interactive_hardware.py +19 -12
  4. classiq/_internals/api_wrapper.py +38 -52
  5. classiq/_internals/async_utils.py +4 -7
  6. classiq/_internals/authentication/auth0.py +3 -3
  7. classiq/_internals/authentication/device.py +4 -4
  8. classiq/_internals/authentication/password_manager.py +13 -13
  9. classiq/_internals/authentication/token_manager.py +4 -5
  10. classiq/_internals/client.py +17 -44
  11. classiq/_internals/config.py +1 -2
  12. classiq/_internals/help.py +1 -2
  13. classiq/_internals/host_checker.py +3 -3
  14. classiq/_internals/jobs.py +14 -14
  15. classiq/_internals/type_validation.py +3 -3
  16. classiq/analyzer/analyzer.py +18 -18
  17. classiq/analyzer/rb.py +17 -8
  18. classiq/applications/chemistry/__init__.py +0 -30
  19. classiq/applications/chemistry/op_utils.py +4 -4
  20. classiq/applications/chemistry/problems.py +3 -3
  21. classiq/applications/chemistry/ucc.py +1 -2
  22. classiq/applications/chemistry/z2_symmetries.py +4 -4
  23. classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
  24. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
  25. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
  26. classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
  27. classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
  28. classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
  29. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
  30. classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
  31. classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
  32. classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
  33. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
  34. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
  35. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
  36. classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
  37. classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
  38. classiq/applications/iqae/iqae.py +8 -8
  39. classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
  40. classiq/applications/qnn/datasets/dataset_parity.py +6 -6
  41. classiq/applications/qnn/qlayer.py +8 -7
  42. classiq/applications/qnn/torch_utils.py +3 -4
  43. classiq/applications/qnn/types.py +2 -1
  44. classiq/applications/qsp/qsp.py +5 -4
  45. classiq/applications/qsvm/qsvm_data_generation.py +1 -2
  46. classiq/evaluators/classical_expression.py +0 -4
  47. classiq/evaluators/parameter_types.py +7 -8
  48. classiq/evaluators/qmod_annotated_expression.py +24 -26
  49. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
  50. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
  51. classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
  52. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +4 -4
  53. classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
  54. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
  55. classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
  56. classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
  57. classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
  58. classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
  59. classiq/execution/execution_session.py +18 -19
  60. classiq/execution/jobs.py +26 -26
  61. classiq/execution/qnn.py +1 -2
  62. classiq/execution/user_budgets.py +52 -7
  63. classiq/executor.py +1 -3
  64. classiq/interface/_version.py +1 -1
  65. classiq/interface/analyzer/analysis_params.py +4 -4
  66. classiq/interface/analyzer/cytoscape_graph.py +3 -3
  67. classiq/interface/analyzer/result.py +4 -4
  68. classiq/interface/applications/qsvm.py +5 -8
  69. classiq/interface/ast_node.py +3 -3
  70. classiq/interface/backend/backend_preferences.py +16 -16
  71. classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
  72. classiq/interface/chemistry/ansatz_library.py +3 -5
  73. classiq/interface/chemistry/operator.py +3 -3
  74. classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
  75. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
  76. classiq/interface/compression_utils.py +2 -3
  77. classiq/interface/debug_info/debug_info.py +7 -7
  78. classiq/interface/exceptions.py +2 -3
  79. classiq/interface/execution/iqcc.py +1 -3
  80. classiq/interface/execution/primitives.py +6 -6
  81. classiq/interface/executor/estimate_cost.py +1 -1
  82. classiq/interface/executor/execution_preferences.py +3 -5
  83. classiq/interface/executor/execution_request.py +10 -10
  84. classiq/interface/executor/execution_result.py +1 -2
  85. classiq/interface/executor/quantum_code.py +8 -8
  86. classiq/interface/executor/result.py +28 -18
  87. classiq/interface/executor/user_budget.py +2 -3
  88. classiq/interface/executor/vqe_result.py +5 -6
  89. classiq/interface/generator/ansatz_library.py +6 -8
  90. classiq/interface/generator/application_apis/__init__.py +0 -2
  91. classiq/interface/generator/arith/arithmetic.py +2 -2
  92. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
  93. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
  94. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
  95. classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
  96. classiq/interface/generator/arith/arithmetic_operations.py +4 -6
  97. classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
  98. classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
  99. classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
  100. classiq/interface/generator/arith/binary_ops.py +7 -36
  101. classiq/interface/generator/arith/logical_ops.py +2 -3
  102. classiq/interface/generator/arith/number_utils.py +2 -2
  103. classiq/interface/generator/arith/register_user_input.py +2 -2
  104. classiq/interface/generator/arith/unary_ops.py +2 -2
  105. classiq/interface/generator/circuit_code/circuit_code.py +8 -10
  106. classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
  107. classiq/interface/generator/complex_type.py +2 -2
  108. classiq/interface/generator/copy.py +1 -3
  109. classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
  110. classiq/interface/generator/expressions/evaluated_expression.py +2 -3
  111. classiq/interface/generator/expressions/expression.py +2 -2
  112. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
  113. classiq/interface/generator/function_param_list.py +0 -20
  114. classiq/interface/generator/function_params.py +5 -6
  115. classiq/interface/generator/functions/classical_function_declaration.py +2 -2
  116. classiq/interface/generator/functions/classical_type.py +3 -3
  117. classiq/interface/generator/functions/type_modifier.py +0 -14
  118. classiq/interface/generator/functions/type_name.py +2 -2
  119. classiq/interface/generator/generated_circuit_data.py +12 -13
  120. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
  121. classiq/interface/generator/hardware/hardware_data.py +8 -8
  122. classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
  123. classiq/interface/generator/mcu.py +3 -3
  124. classiq/interface/generator/mcx.py +3 -3
  125. classiq/interface/generator/model/constraints.py +34 -5
  126. classiq/interface/generator/model/preferences/preferences.py +15 -21
  127. classiq/interface/generator/model/quantum_register.py +7 -10
  128. classiq/interface/generator/noise_properties.py +3 -7
  129. classiq/interface/generator/parameters.py +1 -1
  130. classiq/interface/generator/partitioned_register.py +1 -2
  131. classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
  132. classiq/interface/generator/qsvm.py +2 -2
  133. classiq/interface/generator/quantum_function_call.py +8 -11
  134. classiq/interface/generator/quantum_program.py +12 -15
  135. classiq/interface/generator/range_types.py +3 -3
  136. classiq/interface/generator/slice_parsing_utils.py +4 -5
  137. classiq/interface/generator/standard_gates/standard_gates.py +2 -4
  138. classiq/interface/generator/state_preparation/state_preparation.py +6 -8
  139. classiq/interface/generator/synthesis_execution_parameter.py +1 -3
  140. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
  141. classiq/interface/generator/transpiler_basis_gates.py +2 -4
  142. classiq/interface/generator/types/builtin_enum_declarations.py +0 -136
  143. classiq/interface/generator/types/compilation_metadata.py +12 -1
  144. classiq/interface/generator/types/enum_declaration.py +2 -1
  145. classiq/interface/generator/validations/flow_graph.py +3 -3
  146. classiq/interface/generator/visitor.py +10 -12
  147. classiq/interface/hardware.py +2 -2
  148. classiq/interface/helpers/classproperty.py +2 -2
  149. classiq/interface/helpers/custom_encoders.py +2 -1
  150. classiq/interface/helpers/custom_pydantic_types.py +1 -1
  151. classiq/interface/helpers/text_utils.py +1 -4
  152. classiq/interface/ide/visual_model.py +5 -5
  153. classiq/interface/jobs.py +3 -3
  154. classiq/interface/model/allocate.py +4 -4
  155. classiq/interface/model/block.py +2 -2
  156. classiq/interface/model/bounds.py +3 -3
  157. classiq/interface/model/control.py +1 -1
  158. classiq/interface/model/inplace_binary_operation.py +2 -2
  159. classiq/interface/model/model.py +4 -4
  160. classiq/interface/model/parameter.py +1 -3
  161. classiq/interface/model/port_declaration.py +1 -1
  162. classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
  163. classiq/interface/model/quantum_function_call.py +3 -6
  164. classiq/interface/model/quantum_function_declaration.py +1 -0
  165. classiq/interface/model/quantum_lambda_function.py +4 -4
  166. classiq/interface/model/quantum_statement.py +4 -4
  167. classiq/interface/model/quantum_type.py +14 -14
  168. classiq/interface/model/validation_handle.py +2 -3
  169. classiq/interface/model/variable_declaration_statement.py +2 -2
  170. classiq/interface/pretty_print/expression_to_qmod.py +3 -4
  171. classiq/interface/server/routes.py +0 -4
  172. classiq/interface/source_reference.py +3 -4
  173. classiq/model_expansions/arithmetic.py +6 -7
  174. classiq/model_expansions/arithmetic_compute_result_attrs.py +4 -5
  175. classiq/model_expansions/capturing/captured_vars.py +3 -3
  176. classiq/model_expansions/capturing/mangling_utils.py +1 -2
  177. classiq/model_expansions/closure.py +12 -11
  178. classiq/model_expansions/function_builder.py +14 -6
  179. classiq/model_expansions/generative_functions.py +1 -4
  180. classiq/model_expansions/interpreters/base_interpreter.py +2 -6
  181. classiq/model_expansions/interpreters/generative_interpreter.py +5 -3
  182. classiq/model_expansions/quantum_operations/allocate.py +4 -4
  183. classiq/model_expansions/quantum_operations/assignment_result_processor.py +2 -4
  184. classiq/model_expansions/quantum_operations/call_emitter.py +31 -37
  185. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
  186. classiq/model_expansions/quantum_operations/emitter.py +3 -5
  187. classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
  188. classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
  189. classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
  190. classiq/model_expansions/scope.py +7 -7
  191. classiq/model_expansions/scope_initialization.py +4 -0
  192. classiq/model_expansions/visitors/symbolic_param_inference.py +3 -3
  193. classiq/model_expansions/visitors/uncomputation_signature_inference.py +317 -0
  194. classiq/model_expansions/visitors/variable_references.py +15 -14
  195. classiq/open_library/functions/__init__.py +6 -0
  196. classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
  197. classiq/open_library/functions/grover.py +8 -10
  198. classiq/open_library/functions/modular_exponentiation.py +96 -8
  199. classiq/qmod/__init__.py +5 -2
  200. classiq/qmod/builtins/classical_execution_primitives.py +4 -11
  201. classiq/qmod/builtins/classical_functions.py +1 -42
  202. classiq/qmod/builtins/enums.py +0 -136
  203. classiq/qmod/builtins/functions/__init__.py +0 -13
  204. classiq/qmod/builtins/functions/allocation.py +4 -4
  205. classiq/qmod/builtins/functions/arithmetic.py +22 -27
  206. classiq/qmod/builtins/functions/standard_gates.py +27 -27
  207. classiq/qmod/builtins/operations.py +35 -58
  208. classiq/qmod/builtins/structs.py +2 -58
  209. classiq/qmod/cfunc.py +3 -2
  210. classiq/qmod/classical_function.py +2 -1
  211. classiq/qmod/cparam.py +2 -8
  212. classiq/qmod/create_model_function.py +7 -7
  213. classiq/qmod/declaration_inferrer.py +33 -30
  214. classiq/qmod/model_state_container.py +2 -2
  215. classiq/qmod/native/pretty_printer.py +25 -14
  216. classiq/qmod/pretty_print/expression_to_python.py +5 -3
  217. classiq/qmod/pretty_print/pretty_printer.py +39 -17
  218. classiq/qmod/python_classical_type.py +40 -13
  219. classiq/qmod/qfunc.py +139 -16
  220. classiq/qmod/qmod_constant.py +2 -2
  221. classiq/qmod/qmod_parameter.py +5 -2
  222. classiq/qmod/qmod_variable.py +47 -43
  223. classiq/qmod/quantum_callable.py +18 -13
  224. classiq/qmod/quantum_expandable.py +31 -26
  225. classiq/qmod/quantum_function.py +51 -32
  226. classiq/qmod/semantics/annotation/call_annotation.py +2 -2
  227. classiq/qmod/semantics/error_manager.py +5 -6
  228. classiq/qmod/semantics/lambdas.py +1 -2
  229. classiq/qmod/semantics/validation/types_validation.py +1 -2
  230. classiq/qmod/symbolic.py +2 -4
  231. classiq/qmod/utilities.py +13 -10
  232. classiq/qmod/write_qmod.py +3 -4
  233. classiq/quantum_program.py +1 -3
  234. classiq/synthesis.py +11 -7
  235. {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/METADATA +2 -3
  236. {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/RECORD +238 -260
  237. classiq/applications/chemistry/ansatz_parameters.py +0 -29
  238. classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
  239. classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
  240. classiq/applications/chemistry/ground_state_problem.py +0 -42
  241. classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
  242. classiq/interface/chemistry/elements.py +0 -120
  243. classiq/interface/chemistry/fermionic_operator.py +0 -208
  244. classiq/interface/chemistry/ground_state_problem.py +0 -132
  245. classiq/interface/chemistry/ground_state_result.py +0 -8
  246. classiq/interface/chemistry/molecule.py +0 -71
  247. classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
  248. classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
  249. classiq/interface/generator/chemistry_function_params.py +0 -50
  250. classiq/interface/generator/entangler_params.py +0 -72
  251. classiq/interface/generator/entanglers.py +0 -14
  252. classiq/interface/generator/hartree_fock.py +0 -26
  253. classiq/interface/generator/hva.py +0 -22
  254. classiq/interface/generator/linear_pauli_rotations.py +0 -92
  255. classiq/interface/generator/qft.py +0 -37
  256. classiq/interface/generator/ucc.py +0 -74
  257. classiq/interface/helpers/backward_compatibility.py +0 -9
  258. classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
  259. classiq/qmod/builtins/functions/chemistry.py +0 -123
  260. {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/WHEEL +0 -0
  261. {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,15 +1,13 @@
1
1
  import inspect
2
2
  from abc import ABC
3
- from collections.abc import Generator, Iterable
3
+ from collections.abc import Callable, Generator, Iterable
4
4
  from dataclasses import is_dataclass
5
5
  from enum import Enum as PythonEnum
6
6
  from types import TracebackType
7
7
  from typing import (
8
8
  TYPE_CHECKING,
9
9
  Any,
10
- Callable,
11
10
  ClassVar,
12
- Optional,
13
11
  Union,
14
12
  cast,
15
13
  overload,
@@ -56,7 +54,11 @@ from classiq.interface.model.variable_declaration_statement import (
56
54
  )
57
55
  from classiq.interface.source_reference import SourceReference
58
56
 
59
- from classiq.qmod.generative import generative_mode_context, is_generative_mode
57
+ from classiq.qmod.generative import (
58
+ generative_mode_context,
59
+ interpret_expression,
60
+ is_generative_mode,
61
+ )
60
62
  from classiq.qmod.global_declarative_switch import get_global_declarative_switch
61
63
  from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
62
64
  from classiq.qmod.qmod_constant import QConstant
@@ -107,9 +109,9 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
107
109
 
108
110
  def __exit__(
109
111
  self,
110
- exc_type: Optional[type[BaseException]],
111
- exc_val: Optional[BaseException],
112
- exc_tb: Optional[TracebackType],
112
+ exc_type: type[BaseException] | None,
113
+ exc_val: BaseException | None,
114
+ exc_tb: TracebackType | None,
113
115
  ) -> None:
114
116
  assert QExpandable.STACK.pop() is self
115
117
  QCallable.CURRENT_EXPANDABLE = (
@@ -125,14 +127,14 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
125
127
  with self, generative_mode_context(False):
126
128
  self._py_callable(*self._get_positional_args())
127
129
 
128
- def infer_rename_params(self) -> Optional[list[str]]:
130
+ def infer_rename_params(self) -> list[str] | None:
129
131
  return None
130
132
 
131
133
  def add_local_handle(
132
134
  self,
133
135
  name: str,
134
136
  qtype: QuantumType,
135
- source_ref: Optional[SourceReference] = None,
137
+ source_ref: SourceReference | None = None,
136
138
  ) -> None:
137
139
  self.append_statement_to_body(
138
140
  VariableDeclarationStatement(
@@ -219,8 +221,8 @@ class QTerminalCallable(QCallable):
219
221
  def __init__(
220
222
  self,
221
223
  decl: QuantumFunctionDeclaration,
222
- param_idx: Optional[int] = None,
223
- index_: Optional[Union[int, CParamScalar]] = None,
224
+ param_idx: int | None = None,
225
+ index_: int | CParamScalar | None = None,
224
226
  ) -> None:
225
227
  pass
226
228
 
@@ -229,22 +231,22 @@ class QTerminalCallable(QCallable):
229
231
  self,
230
232
  decl: AnonQuantumFunctionDeclaration,
231
233
  param_idx: int,
232
- index_: Optional[Union[int, CParamScalar]] = None,
234
+ index_: int | CParamScalar | None = None,
233
235
  ) -> None:
234
236
  pass
235
237
 
236
238
  def __init__(
237
239
  self,
238
240
  decl: AnonQuantumFunctionDeclaration,
239
- param_idx: Optional[int] = None,
240
- index_: Optional[Union[int, CParamScalar]] = None,
241
+ param_idx: int | None = None,
242
+ index_: int | CParamScalar | None = None,
241
243
  ) -> None:
242
244
  self._decl = self._override_decl_name(decl, param_idx)
243
245
  self._index = index_
244
246
 
245
247
  @staticmethod
246
248
  def _override_decl_name(
247
- decl: AnonQuantumFunctionDeclaration, param_idx: Optional[int]
249
+ decl: AnonQuantumFunctionDeclaration, param_idx: int | None
248
250
  ) -> QuantumFunctionDeclaration:
249
251
  if (
250
252
  not isinstance(QCallable.CURRENT_EXPANDABLE, QLambdaFunction)
@@ -260,7 +262,7 @@ class QTerminalCallable(QCallable):
260
262
  isinstance(self._decl, AnonQuantumOperandDeclaration) and self._decl.is_list
261
263
  )
262
264
 
263
- def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
265
+ def __getitem__(self, key: slice | int | CInt) -> "QTerminalCallable":
264
266
  if not self.is_list:
265
267
  raise ClassiqValueError("Cannot index a non-list operand")
266
268
  if isinstance(key, slice):
@@ -287,6 +289,9 @@ class QTerminalCallable(QCallable):
287
289
  def len(self) -> CParamScalar:
288
290
  if not self.is_list:
289
291
  raise ClassiqValueError("Cannot get length of a non-list operand")
292
+ if is_generative_mode():
293
+ with generative_mode_context(False):
294
+ return interpret_expression(str(self.len))
290
295
  return CParamScalar(f"{self.func_decl.name}.len")
291
296
 
292
297
  @property
@@ -315,25 +320,25 @@ class QTerminalCallable(QCallable):
315
320
  @overload
316
321
  def prepare_arg(
317
322
  arg_decl: AnonPositionalArg,
318
- val: Union[QCallable, Callable[..., None]],
319
- func_name: Optional[str],
323
+ val: QCallable | Callable[..., None],
324
+ func_name: str | None,
320
325
  param_name: str,
321
326
  ) -> QuantumLambdaFunction: ...
322
327
 
323
328
 
324
329
  @overload
325
330
  def prepare_arg(
326
- arg_decl: AnonPositionalArg, val: Any, func_name: Optional[str], param_name: str
331
+ arg_decl: AnonPositionalArg, val: Any, func_name: str | None, param_name: str
327
332
  ) -> ArgValue: ...
328
333
 
329
334
 
330
335
  def prepare_arg(
331
- arg_decl: AnonPositionalArg, val: Any, func_name: Optional[str], param_name: str
336
+ arg_decl: AnonPositionalArg, val: Any, func_name: str | None, param_name: str
332
337
  ) -> ArgValue:
333
338
  from classiq.qmod.quantum_function import BaseQFunc, GenerativeQFunc, QFunc
334
339
 
335
340
  if get_global_declarative_switch() and isinstance(val, GenerativeQFunc):
336
- val = QFunc(val._py_callable)
341
+ val = QFunc(val._py_callable, permutation=val.permutation)
337
342
  if isinstance(val, BaseQFunc):
338
343
  val.add_function_dependencies()
339
344
  if isinstance(val, GenerativeQFunc):
@@ -391,7 +396,7 @@ def prepare_arg(
391
396
 
392
397
 
393
398
  def _validate_classical_arg(
394
- arg: Any, arg_decl: AnonClassicalParameterDeclaration, func_name: Optional[str]
399
+ arg: Any, arg_decl: AnonClassicalParameterDeclaration, func_name: str | None
395
400
  ) -> None:
396
401
  is_native_or_compatible_type = (
397
402
  not isinstance(
@@ -504,8 +509,8 @@ def _validate_argument_names(
504
509
 
505
510
  def _create_quantum_function_call(
506
511
  decl_: QuantumFunctionDeclaration,
507
- index_: Optional[Union[CParamScalar, int]] = None,
508
- source_ref_: Optional[SourceReference] = None,
512
+ index_: CParamScalar | int | None = None,
513
+ source_ref_: SourceReference | None = None,
509
514
  *args: Any,
510
515
  **kwargs: Any,
511
516
  ) -> QuantumFunctionCall:
@@ -513,7 +518,7 @@ def _create_quantum_function_call(
513
518
  _validate_argument_names(decl_, arg_list, kwargs)
514
519
  prepared_args = _prepare_args(decl_, arg_list, kwargs)
515
520
 
516
- function_ident: Union[str, OperandIdentifier] = decl_.name
521
+ function_ident: str | OperandIdentifier = decl_.name
517
522
  if index_ is not None:
518
523
  function_ident = OperandIdentifier(
519
524
  index=Expression(expr=str(index_)), name=function_ident
@@ -541,7 +546,7 @@ def _is_legal_iterable_element(arg: Any) -> bool:
541
546
  return True
542
547
 
543
548
 
544
- def _try_preparing_handles_list(val: Any) -> Optional[HandlesList]:
549
+ def _try_preparing_handles_list(val: Any) -> HandlesList | None:
545
550
  if not isinstance(val, list):
546
551
  return None
547
552
  items = [
@@ -2,10 +2,11 @@ import ast
2
2
  import functools
3
3
  import warnings
4
4
  from abc import abstractmethod
5
+ from collections.abc import Callable
5
6
  from dataclasses import is_dataclass
6
7
  from enum import EnumMeta
7
8
  from inspect import isclass
8
- from typing import Any, Callable, Optional, get_origin
9
+ from typing import Any, get_origin
9
10
 
10
11
  from classiq.interface.exceptions import ClassiqDeprecationWarning, ClassiqError
11
12
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
@@ -30,7 +31,7 @@ from classiq.qmod.generative import set_frontend_interpreter
30
31
  from classiq.qmod.global_declarative_switch import get_global_declarative_switch
31
32
  from classiq.qmod.qmod_constant import QConstant
32
33
  from classiq.qmod.qmod_parameter import CArray, CParamList
33
- from classiq.qmod.quantum_callable import QCallable, QCallableList
34
+ from classiq.qmod.quantum_callable import QCallable, QCallableList, QPerm, QPermList
34
35
  from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
35
36
  from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
36
37
  from classiq.qmod.semantics.validation.main_validation import validate_main_function
@@ -41,11 +42,13 @@ class BaseQFunc(QExpandable):
41
42
  def __init__(
42
43
  self,
43
44
  py_callable: Callable,
44
- compilation_metadata: Optional[CompilationMetadata] = None,
45
+ compilation_metadata: CompilationMetadata | None = None,
46
+ permutation: bool = False,
45
47
  ) -> None:
46
48
  super().__init__(py_callable)
47
49
  functools.update_wrapper(self, py_callable)
48
50
  self.compilation_metadata = compilation_metadata
51
+ self.permutation = permutation
49
52
 
50
53
  @property
51
54
  def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
@@ -84,10 +87,10 @@ class BaseQFunc(QExpandable):
84
87
  @abstractmethod
85
88
  def create_model(
86
89
  self,
87
- constraints: Optional[Constraints] = None,
88
- execution_preferences: Optional[ExecutionPreferences] = None,
89
- preferences: Optional[Preferences] = None,
90
- classical_execution_function: Optional[CFunc] = None,
90
+ constraints: Constraints | None = None,
91
+ execution_preferences: ExecutionPreferences | None = None,
92
+ preferences: Preferences | None = None,
93
+ classical_execution_function: CFunc | None = None,
91
94
  ) -> Model:
92
95
  pass
93
96
 
@@ -98,13 +101,17 @@ class QFunc(BaseQFunc):
98
101
  def __init__(
99
102
  self,
100
103
  py_callable: Callable,
101
- compilation_metadata: Optional[CompilationMetadata] = None,
104
+ compilation_metadata: CompilationMetadata | None = None,
105
+ permutation: bool = False,
102
106
  ) -> None:
103
107
  _validate_no_gen_params(py_callable.__annotations__)
104
- super().__init__(py_callable, compilation_metadata)
105
- if compilation_metadata is not None and compilation_metadata.unchecked:
106
- self.compilation_metadata: Optional[CompilationMetadata] = (
107
- CompilationMetadata(unchecked=compilation_metadata.unchecked)
108
+ super().__init__(py_callable, compilation_metadata, permutation)
109
+ if (
110
+ compilation_metadata is not None
111
+ and compilation_metadata.has_user_directives
112
+ ):
113
+ self.compilation_metadata: CompilationMetadata | None = (
114
+ compilation_metadata.copy_user_directives()
108
115
  )
109
116
  else:
110
117
  self.compilation_metadata = None
@@ -114,7 +121,9 @@ class QFunc(BaseQFunc):
114
121
  name = self._py_callable.__name__
115
122
  if name in self._qmodule.native_defs:
116
123
  return self._qmodule.native_defs[name]
117
- return infer_func_decl(self._py_callable, qmodule=self._qmodule)
124
+ return infer_func_decl(
125
+ self._py_callable, qmodule=self._qmodule, permutation=self.permutation
126
+ )
118
127
 
119
128
  def __call__(self, *args: Any, **kwargs: Any) -> None:
120
129
  self.expand()
@@ -122,10 +131,10 @@ class QFunc(BaseQFunc):
122
131
 
123
132
  def create_model(
124
133
  self,
125
- constraints: Optional[Constraints] = None,
126
- execution_preferences: Optional[ExecutionPreferences] = None,
127
- preferences: Optional[Preferences] = None,
128
- classical_execution_function: Optional[CFunc] = None,
134
+ constraints: Constraints | None = None,
135
+ execution_preferences: ExecutionPreferences | None = None,
136
+ preferences: Preferences | None = None,
137
+ classical_execution_function: CFunc | None = None,
129
138
  ) -> Model:
130
139
  self._qmodule.reset()
131
140
  QConstant.set_current_model(self._qmodule)
@@ -222,9 +231,10 @@ class ExternalQFunc(QTerminalCallable):
222
231
  FRAME_DEPTH = 2 # FIXME: Remove (CLS-2912)
223
232
  _decl: NamedParamsQuantumFunctionDeclaration
224
233
 
225
- def __init__(self, py_callable: Callable) -> None:
234
+ def __init__(self, py_callable: Callable, permutation: bool = False) -> None:
226
235
  self._py_callable = py_callable
227
- decl = infer_func_decl(py_callable)
236
+ self.permutation = permutation
237
+ decl = infer_func_decl(py_callable, permutation=permutation)
228
238
 
229
239
  py_callable.__annotations__.pop("return", None)
230
240
  if py_callable.__annotations__.keys() != {
@@ -289,41 +299,48 @@ class GenerativeQFunc(BaseQFunc):
289
299
  def __init__(
290
300
  self,
291
301
  py_callable: Callable,
292
- func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
293
- compilation_metadata: Optional[CompilationMetadata] = None,
302
+ func_decl: NamedParamsQuantumFunctionDeclaration | None = None,
303
+ compilation_metadata: CompilationMetadata | None = None,
304
+ permutation: bool = False,
294
305
  ) -> None:
295
- super().__init__(py_callable, compilation_metadata)
306
+ super().__init__(py_callable, compilation_metadata, permutation)
296
307
  self._func_decl = func_decl
297
- self._inferred_func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None
308
+ self._inferred_func_decl: NamedParamsQuantumFunctionDeclaration | None = None
298
309
 
299
310
  @property
300
311
  def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
301
312
  if self._func_decl is not None:
302
313
  return self._func_decl
303
314
  if self._inferred_func_decl is None:
304
- self._inferred_func_decl = infer_func_decl(self._py_callable, self._qmodule)
315
+ self._inferred_func_decl = infer_func_decl(
316
+ self._py_callable, self._qmodule, permutation=self.permutation
317
+ )
305
318
  return self._inferred_func_decl
306
319
 
307
320
  def __call__(self, *args: Any, **kwargs: Any) -> None:
308
321
  if get_global_declarative_switch():
309
- return QFunc(self._py_callable, self.compilation_metadata)(*args, **kwargs)
322
+ return QFunc(
323
+ self._py_callable,
324
+ self.compilation_metadata,
325
+ permutation=self.permutation,
326
+ )(*args, **kwargs)
310
327
  if self.func_decl.name not in self._qmodule.generative_functions:
311
328
  self._qmodule.generative_functions[self.func_decl.name] = self
312
329
  if self._func_decl is None:
313
330
  self._inferred_func_decl = infer_func_decl(
314
- self._py_callable, self._qmodule
331
+ self._py_callable, self._qmodule, permutation=self.permutation
315
332
  )
316
333
  super().__call__(*args, **kwargs)
317
334
 
318
335
  def create_model(
319
336
  self,
320
- constraints: Optional[Constraints] = None,
321
- execution_preferences: Optional[ExecutionPreferences] = None,
322
- preferences: Optional[Preferences] = None,
323
- classical_execution_function: Optional[CFunc] = None,
337
+ constraints: Constraints | None = None,
338
+ execution_preferences: ExecutionPreferences | None = None,
339
+ preferences: Preferences | None = None,
340
+ classical_execution_function: CFunc | None = None,
324
341
  ) -> Model:
325
342
  if get_global_declarative_switch():
326
- return QFunc(self._py_callable).create_model(
343
+ return QFunc(self._py_callable, permutation=self.permutation).create_model(
327
344
  constraints,
328
345
  execution_preferences,
329
346
  preferences,
@@ -338,7 +355,7 @@ class GenerativeQFunc(BaseQFunc):
338
355
 
339
356
  _dec_main.__annotations__ = self._py_callable.__annotations__
340
357
 
341
- return QFunc(_dec_main).create_model(
358
+ return QFunc(_dec_main, permutation=self.permutation).create_model(
342
359
  constraints=constraints,
343
360
  execution_preferences=execution_preferences,
344
361
  preferences=preferences,
@@ -371,6 +388,8 @@ def _validate_no_gen_params(annotations: dict[str, Any]) -> None:
371
388
  or get_origin(annotation) is CArray
372
389
  or (get_origin(annotation) or annotation) is QCallable
373
390
  or (get_origin(annotation) or annotation) is QCallableList
391
+ or (get_origin(annotation) or annotation) is QPerm
392
+ or (get_origin(annotation) or annotation) is QPermList
374
393
  or is_qvar(annotation)
375
394
  )
376
395
  }
@@ -1,6 +1,6 @@
1
1
  from collections.abc import Iterator, Mapping
2
2
  from contextlib import contextmanager
3
- from typing import Any, Optional
3
+ from typing import Any
4
4
 
5
5
  from classiq.interface.exceptions import ClassiqError
6
6
  from classiq.interface.model.model import Model
@@ -81,7 +81,7 @@ class _CallLambdaAnnotator(ModelVisitor):
81
81
 
82
82
  def resolve_function_calls(
83
83
  root: Any,
84
- quantum_function_dict: Optional[Mapping[str, QuantumFunctionDeclaration]] = None,
84
+ quantum_function_dict: Mapping[str, QuantumFunctionDeclaration] | None = None,
85
85
  annotate_types: bool = True,
86
86
  ) -> None:
87
87
  if quantum_function_dict is None:
@@ -1,6 +1,5 @@
1
1
  from collections.abc import Iterator
2
2
  from contextlib import contextmanager
3
- from typing import Optional
4
3
 
5
4
  from classiq.interface.ast_node import ASTNode
6
5
  from classiq.interface.exceptions import CLASSIQ_SLACK_COMMUNITY_LINK
@@ -24,7 +23,7 @@ class ErrorManager:
24
23
  self._ignore_errors: bool = False
25
24
 
26
25
  @property
27
- def _current_source_ref(self) -> Optional[SourceReference]:
26
+ def _current_source_ref(self) -> SourceReference | None:
28
27
  if self._current_nodes_stack:
29
28
  return self._current_nodes_stack[-1].source_ref
30
29
  return None
@@ -50,8 +49,8 @@ class ErrorManager:
50
49
  self,
51
50
  error: str,
52
51
  *,
53
- source_ref: Optional[SourceReference] = None,
54
- function: Optional[str] = None,
52
+ source_ref: SourceReference | None = None,
53
+ function: str | None = None,
55
54
  warning: bool = False,
56
55
  ) -> None:
57
56
  if self._ignore_errors:
@@ -93,7 +92,7 @@ class ErrorManager:
93
92
  return len(self._warnings) > 0
94
93
 
95
94
  def report_errors(
96
- self, error_type: type[Exception], mask: Optional[list[int]] = None
95
+ self, error_type: type[Exception], mask: list[int] | None = None
97
96
  ) -> None:
98
97
  if self.has_errors():
99
98
  errors = (
@@ -105,7 +104,7 @@ class ErrorManager:
105
104
  raise error_type("\n\t" + "\n\t".join(errors))
106
105
 
107
106
  @property
108
- def current_function(self) -> Optional[str]:
107
+ def current_function(self) -> str | None:
109
108
  return self._call_stack[-1] if self._call_stack else None
110
109
 
111
110
  @contextmanager
@@ -1,4 +1,3 @@
1
- from classiq.interface.helpers.backward_compatibility import zip_strict
2
1
  from classiq.interface.model.port_declaration import PortDeclaration
3
2
  from classiq.interface.model.quantum_function_declaration import (
4
3
  AnonQuantumOperandDeclaration,
@@ -15,7 +14,7 @@ def get_renamed_parameters(
15
14
  renamed_parameters: list[str] = []
16
15
  renamed_operands: dict[str, QuantumOperandDeclaration] = {}
17
16
  renamed_ports: list[PortDeclaration] = []
18
- for param, param_name in zip_strict(
17
+ for param, param_name in zip(
19
18
  lambda_func.func_decl.positional_arg_declarations,
20
19
  lambda_func.pos_rename_params,
21
20
  strict=False,
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Sequence
2
- from typing import Union
3
2
 
4
3
  from classiq.interface.exceptions import ClassiqExpansionError
5
4
  from classiq.interface.generator.functions.type_name import TypeName
@@ -16,7 +15,7 @@ TYPE_EXISTS_ERROR_MESSAGE = "Type {!r} already exists"
16
15
 
17
16
 
18
17
  def check_duplicate_types(
19
- types: Sequence[Union[EnumDeclaration, StructDeclaration, QStructDeclaration]],
18
+ types: Sequence[EnumDeclaration | StructDeclaration | QStructDeclaration],
20
19
  ) -> None:
21
20
  known_types = {type_.name for type_ in BUILTIN_ENUM_DECLARATIONS.values()}
22
21
  known_types |= {type_.name for type_ in BUILTIN_STRUCT_DECLARATIONS.values()}
classiq/qmod/symbolic.py CHANGED
@@ -2,9 +2,7 @@ import sys
2
2
  from typing import (
3
3
  TYPE_CHECKING,
4
4
  Any,
5
- Optional,
6
5
  TypeVar,
7
- Union,
8
6
  overload,
9
7
  )
10
8
 
@@ -52,7 +50,7 @@ def symbolic_function(*args: Any, return_type: None = None) -> CParamScalar: ...
52
50
  def symbolic_function(*args: Any, return_type: type[T]) -> T: ...
53
51
 
54
52
 
55
- def symbolic_function(*args: Any, return_type: Optional[type[T]] = None) -> CParam:
53
+ def symbolic_function(*args: Any, return_type: type[T] | None = None) -> CParam:
56
54
  qmodule = (
57
55
  model_state_container.QMODULE
58
56
  ) # FIXME: https://classiq.atlassian.net/browse/CAD-15126
@@ -321,7 +319,7 @@ def _subscript_to_str(index: Any) -> str:
321
319
 
322
320
 
323
321
  def subscript(
324
- array: Union[list, CArray[CReal], np.ndarray],
322
+ array: list | CArray[CReal] | np.ndarray,
325
323
  index: Any,
326
324
  ) -> CParamScalar:
327
325
  return CParamScalar(
classiq/qmod/utilities.py CHANGED
@@ -4,16 +4,14 @@ import itertools
4
4
  import keyword
5
5
  import sys
6
6
  from collections import Counter
7
- from collections.abc import Iterable
7
+ from collections.abc import Callable, Iterable
8
8
  from enum import Enum as PythonEnum
9
9
  from types import FrameType
10
10
  from typing import (
11
11
  TYPE_CHECKING,
12
12
  Any,
13
- Callable,
14
13
  ForwardRef,
15
14
  Literal,
16
- Optional,
17
15
  Union,
18
16
  get_args,
19
17
  get_origin,
@@ -49,7 +47,7 @@ def unmangle_keyword(name: None) -> None:
49
47
  pass
50
48
 
51
49
 
52
- def unmangle_keyword(name: Optional[str]) -> Optional[str]:
50
+ def unmangle_keyword(name: str | None) -> str | None:
53
51
  if name is None:
54
52
  return None
55
53
  if name[-1] == "_" and keyword.iskeyword(name[:-1]):
@@ -60,10 +58,7 @@ def unmangle_keyword(name: Optional[str]) -> Optional[str]:
60
58
  def version_portable_get_args(py_type: type) -> tuple:
61
59
  if get_origin(py_type) is None:
62
60
  return tuple()
63
- if sys.version_info[0:2] < (3, 10):
64
- type_args = get_args(py_type) # The result of __class_getitem__
65
- else:
66
- type_args = get_args(py_type)[0]
61
+ type_args = get_args(py_type)[0]
67
62
  if not isinstance(type_args, tuple):
68
63
  return (type_args,)
69
64
  return tuple(
@@ -76,6 +71,12 @@ def version_portable_get_args(py_type: type) -> tuple:
76
71
  )
77
72
 
78
73
 
74
+ def type_to_str(py_type: Any) -> str:
75
+ if isinstance(py_type, type):
76
+ return py_type.__name__
77
+ return str(py_type)
78
+
79
+
79
80
  def get_source_ref(frame: FrameType) -> SourceReference:
80
81
  filename = inspect.getfile(frame)
81
82
  lineno = frame.f_lineno
@@ -101,6 +102,8 @@ def get_source_ref(frame: FrameType) -> SourceReference:
101
102
 
102
103
 
103
104
  def qmod_val_to_expr_str(val: Any) -> str:
105
+ from classiq.qmod.qmod_parameter import CParamList
106
+
104
107
  if isinstance(val, sympy.Basic):
105
108
  return str(val)
106
109
 
@@ -122,7 +125,7 @@ def qmod_val_to_expr_str(val: Any) -> str:
122
125
  )
123
126
  return f"struct_literal({val.struct_declaration.name}, {kwargs_str})"
124
127
 
125
- if isinstance(val, Iterable):
128
+ if isinstance(val, Iterable) and not isinstance(val, CParamList):
126
129
  elements_str = ", ".join([qmod_val_to_expr_str(elem) for elem in val])
127
130
  return f"[{elements_str}]"
128
131
 
@@ -138,7 +141,7 @@ def unwrap_forward_ref(x: Any) -> Any:
138
141
  return x
139
142
 
140
143
 
141
- def varname(depth: int) -> Optional[str]:
144
+ def varname(depth: int) -> str | None:
142
145
  frame = sys._getframe(depth)
143
146
  codes = inspect.getframeinfo(frame).code_context
144
147
  if codes is None or len(codes) != 1:
@@ -1,6 +1,5 @@
1
1
  import json
2
2
  from pathlib import Path
3
- from typing import Optional, Union
4
3
 
5
4
  from classiq.interface.constants import DEFAULT_DECIMAL_PRECISION
6
5
  from classiq.interface.model.model import Model, SerializedModel
@@ -14,9 +13,9 @@ _SYNTHESIS_OPTIONS_SUFFIX = "synthesis_options.json"
14
13
 
15
14
 
16
15
  def write_qmod(
17
- model: Union[SerializedModel, QFunc, GenerativeQFunc],
16
+ model: SerializedModel | QFunc | GenerativeQFunc,
18
17
  name: str,
19
- directory: Optional[Path] = None,
18
+ directory: Path | None = None,
20
19
  decimal_precision: int = DEFAULT_DECIMAL_PRECISION,
21
20
  symbolic_only: bool = True,
22
21
  ) -> None:
@@ -58,7 +57,7 @@ def write_qmod(
58
57
 
59
58
 
60
59
  def prepare_write_qmod_model(
61
- model: Union[SerializedModel, QFunc, GenerativeQFunc], symbolic_only: bool
60
+ model: SerializedModel | QFunc | GenerativeQFunc, symbolic_only: bool
62
61
  ) -> Model:
63
62
  if isinstance(model, str) and hasattr(model, "entry_point") and symbolic_only:
64
63
  model_obj = Model.model_validate_json(model)
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from classiq.interface.executor.quantum_program_params import (
4
2
  ParameterAssignmentsParams,
5
3
  TranspilationParams,
@@ -19,7 +17,7 @@ async def transpile_async(params: TranspilationParams) -> QuantumProgram:
19
17
 
20
18
 
21
19
  def transpile(
22
- quantum_program: QuantumProgram, preferences: Optional[Preferences] = None
20
+ quantum_program: QuantumProgram, preferences: Preferences | None = None
23
21
  ) -> QuantumProgram:
24
22
  """
25
23
  Transpiles a quantum program.
classiq/synthesis.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional, Union
1
+ from typing import Any
2
2
 
3
3
  from classiq.interface.analyzer.result import QasmCode, QmodCode
4
4
  from classiq.interface.exceptions import ClassiqError, ClassiqValueError
@@ -62,10 +62,10 @@ async def synthesize_async(
62
62
 
63
63
 
64
64
  def synthesize(
65
- model: Union[SerializedModel, BaseQFunc],
65
+ model: SerializedModel | BaseQFunc,
66
66
  auto_show: bool = False,
67
- constraints: Optional[Constraints] = None,
68
- preferences: Optional[Preferences] = None,
67
+ constraints: Constraints | None = None,
68
+ preferences: Preferences | None = None,
69
69
  ) -> QuantumProgram:
70
70
  """
71
71
  Synthesize a model with the Classiq engine to receive a quantum program.
@@ -112,6 +112,10 @@ def qasm_to_qmod(qasm: str, qmod_format: QmodFormat) -> str:
112
112
  """
113
113
  Decompiles QASM to Native/Python Qmod.
114
114
 
115
+ Returns Qmod code as a string. Native Qmod can be synthesized in the Classiq IDE,
116
+ while Python Qmod can be copy-pasted to a Python file (`.py`) and synthesized by
117
+ calling `synthesize(main)`.
118
+
115
119
  Args:
116
120
  qasm: QASM 2 or QASM 3 code
117
121
  qmod_format: The requested output format
@@ -129,7 +133,7 @@ def qasm_to_qmod(qasm: str, qmod_format: QmodFormat) -> str:
129
133
 
130
134
  def set_preferences(
131
135
  serialized_model: SerializedModel,
132
- preferences: Optional[Preferences] = None,
136
+ preferences: Preferences | None = None,
133
137
  **kwargs: Any,
134
138
  ) -> SerializedModel:
135
139
  """
@@ -177,7 +181,7 @@ def update_preferences(
177
181
 
178
182
  def set_constraints(
179
183
  serialized_model: SerializedModel,
180
- constraints: Optional[Constraints] = None,
184
+ constraints: Constraints | None = None,
181
185
  **kwargs: Any,
182
186
  ) -> SerializedModel:
183
187
  """
@@ -225,7 +229,7 @@ def update_constraints(
225
229
 
226
230
  def set_execution_preferences(
227
231
  serialized_model: SerializedModel,
228
- execution_preferences: Optional[ExecutionPreferences] = None,
232
+ execution_preferences: ExecutionPreferences | None = None,
229
233
  **kwargs: Any,
230
234
  ) -> SerializedModel:
231
235
  """