classiq 0.93.0__py3-none-any.whl → 0.99.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.
Files changed (315) hide show
  1. classiq/__init__.py +11 -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 +31 -142
  5. classiq/_internals/async_utils.py +4 -7
  6. classiq/_internals/authentication/auth0.py +41 -15
  7. classiq/_internals/authentication/authorization_code.py +9 -0
  8. classiq/_internals/authentication/authorization_flow.py +41 -0
  9. classiq/_internals/authentication/device.py +33 -52
  10. classiq/_internals/authentication/hybrid_flow.py +19 -0
  11. classiq/_internals/authentication/password_manager.py +13 -13
  12. classiq/_internals/authentication/token_manager.py +9 -9
  13. classiq/_internals/client.py +17 -44
  14. classiq/_internals/config.py +19 -5
  15. classiq/_internals/help.py +1 -2
  16. classiq/_internals/host_checker.py +3 -3
  17. classiq/_internals/jobs.py +14 -14
  18. classiq/_internals/type_validation.py +3 -3
  19. classiq/analyzer/analyzer.py +18 -18
  20. classiq/analyzer/rb.py +17 -8
  21. classiq/analyzer/show_interactive_hack.py +1 -1
  22. classiq/applications/__init__.py +2 -2
  23. classiq/applications/chemistry/__init__.py +0 -30
  24. classiq/applications/chemistry/op_utils.py +4 -4
  25. classiq/applications/chemistry/problems.py +3 -3
  26. classiq/applications/chemistry/ucc.py +1 -2
  27. classiq/applications/chemistry/z2_symmetries.py +4 -4
  28. classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
  29. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
  30. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
  31. classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
  32. classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
  33. classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
  36. classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
  37. classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
  38. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
  39. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
  40. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
  41. classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
  42. classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
  43. classiq/applications/iqae/iqae.py +14 -11
  44. classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
  45. classiq/applications/qnn/datasets/dataset_parity.py +6 -6
  46. classiq/applications/qnn/gradients/simple_quantum_gradient.py +1 -1
  47. classiq/applications/qnn/qlayer.py +9 -8
  48. classiq/applications/qnn/torch_utils.py +5 -6
  49. classiq/applications/qnn/types.py +2 -1
  50. classiq/applications/qsp/__init__.py +20 -2
  51. classiq/applications/qsp/qsp.py +238 -10
  52. classiq/applications/qsvm/qsvm_data_generation.py +1 -2
  53. classiq/evaluators/classical_expression.py +0 -4
  54. classiq/evaluators/parameter_types.py +10 -8
  55. classiq/evaluators/qmod_annotated_expression.py +31 -26
  56. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
  57. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
  58. classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
  59. classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +4 -4
  60. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +14 -4
  61. classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
  62. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
  63. classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
  64. classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
  65. classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
  66. classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
  67. classiq/execution/__init__.py +0 -3
  68. classiq/execution/execution_session.py +28 -21
  69. classiq/execution/jobs.py +26 -26
  70. classiq/execution/qnn.py +1 -2
  71. classiq/execution/user_budgets.py +71 -37
  72. classiq/executor.py +1 -3
  73. classiq/interface/_version.py +1 -1
  74. classiq/interface/analyzer/analysis_params.py +4 -4
  75. classiq/interface/analyzer/cytoscape_graph.py +3 -3
  76. classiq/interface/analyzer/result.py +4 -4
  77. classiq/interface/ast_node.py +3 -3
  78. classiq/interface/backend/backend_preferences.py +26 -50
  79. classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
  80. classiq/interface/backend/provider_config/__init__.py +0 -0
  81. classiq/interface/backend/provider_config/provider_config.py +8 -0
  82. classiq/interface/backend/provider_config/providers/__init__.py +0 -0
  83. classiq/interface/backend/provider_config/providers/alice_bob.py +47 -0
  84. classiq/interface/backend/provider_config/providers/aqt.py +16 -0
  85. classiq/interface/backend/provider_config/providers/azure.py +37 -0
  86. classiq/interface/backend/provider_config/providers/braket.py +39 -0
  87. classiq/interface/backend/provider_config/providers/ibm.py +26 -0
  88. classiq/interface/backend/provider_config/providers/ionq.py +22 -0
  89. classiq/interface/backend/quantum_backend_providers.py +20 -2
  90. classiq/interface/chemistry/ansatz_library.py +3 -5
  91. classiq/interface/chemistry/operator.py +3 -3
  92. classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
  93. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
  94. classiq/interface/compression_utils.py +2 -3
  95. classiq/interface/debug_info/debug_info.py +8 -7
  96. classiq/interface/exceptions.py +6 -7
  97. classiq/interface/execution/primitives.py +6 -6
  98. classiq/interface/executor/estimate_cost.py +1 -1
  99. classiq/interface/executor/execution_preferences.py +3 -5
  100. classiq/interface/executor/execution_request.py +10 -10
  101. classiq/interface/executor/execution_result.py +1 -2
  102. classiq/interface/executor/quantum_code.py +8 -8
  103. classiq/interface/executor/result.py +28 -18
  104. classiq/interface/executor/user_budget.py +25 -17
  105. classiq/interface/executor/vqe_result.py +5 -6
  106. classiq/interface/generator/ansatz_library.py +6 -8
  107. classiq/interface/generator/application_apis/__init__.py +0 -3
  108. classiq/interface/generator/arith/arithmetic.py +2 -2
  109. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
  110. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
  111. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
  112. classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
  113. classiq/interface/generator/arith/arithmetic_operations.py +4 -6
  114. classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
  115. classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
  116. classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
  117. classiq/interface/generator/arith/binary_ops.py +15 -40
  118. classiq/interface/generator/arith/logical_ops.py +2 -3
  119. classiq/interface/generator/arith/number_utils.py +2 -2
  120. classiq/interface/generator/arith/register_user_input.py +3 -3
  121. classiq/interface/generator/arith/unary_ops.py +2 -2
  122. classiq/interface/generator/circuit_code/circuit_code.py +8 -10
  123. classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
  124. classiq/interface/generator/complex_type.py +2 -2
  125. classiq/interface/generator/copy.py +1 -3
  126. classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
  127. classiq/interface/generator/expressions/evaluated_expression.py +2 -3
  128. classiq/interface/generator/expressions/expression.py +2 -2
  129. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
  130. classiq/interface/generator/function_param_list.py +0 -40
  131. classiq/interface/generator/function_params.py +5 -6
  132. classiq/interface/generator/functions/classical_function_declaration.py +2 -2
  133. classiq/interface/generator/functions/classical_type.py +3 -3
  134. classiq/interface/generator/functions/type_modifier.py +0 -15
  135. classiq/interface/generator/functions/type_name.py +2 -2
  136. classiq/interface/generator/generated_circuit_data.py +14 -18
  137. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
  138. classiq/interface/generator/hardware/hardware_data.py +8 -8
  139. classiq/interface/generator/hardware_efficient_ansatz.py +9 -9
  140. classiq/interface/generator/mcu.py +3 -3
  141. classiq/interface/generator/mcx.py +3 -3
  142. classiq/interface/generator/model/constraints.py +34 -5
  143. classiq/interface/generator/model/preferences/preferences.py +15 -21
  144. classiq/interface/generator/model/quantum_register.py +7 -10
  145. classiq/interface/generator/noise_properties.py +3 -7
  146. classiq/interface/generator/parameters.py +1 -1
  147. classiq/interface/generator/partitioned_register.py +1 -2
  148. classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
  149. classiq/interface/generator/quantum_function_call.py +9 -12
  150. classiq/interface/generator/quantum_program.py +10 -23
  151. classiq/interface/generator/range_types.py +3 -3
  152. classiq/interface/generator/slice_parsing_utils.py +4 -5
  153. classiq/interface/generator/standard_gates/standard_gates.py +2 -4
  154. classiq/interface/generator/synthesis_execution_parameter.py +1 -3
  155. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +9 -0
  156. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
  157. classiq/interface/generator/transpiler_basis_gates.py +12 -4
  158. classiq/interface/generator/types/builtin_enum_declarations.py +0 -145
  159. classiq/interface/generator/types/compilation_metadata.py +12 -1
  160. classiq/interface/generator/types/enum_declaration.py +2 -1
  161. classiq/interface/generator/validations/flow_graph.py +3 -3
  162. classiq/interface/generator/visitor.py +10 -12
  163. classiq/interface/hardware.py +2 -3
  164. classiq/interface/helpers/classproperty.py +2 -2
  165. classiq/interface/helpers/custom_encoders.py +2 -1
  166. classiq/interface/helpers/custom_pydantic_types.py +1 -1
  167. classiq/interface/helpers/text_utils.py +1 -4
  168. classiq/interface/ide/visual_model.py +6 -5
  169. classiq/interface/interface_version.py +1 -1
  170. classiq/interface/jobs.py +3 -3
  171. classiq/interface/model/allocate.py +4 -4
  172. classiq/interface/model/block.py +6 -2
  173. classiq/interface/model/bounds.py +3 -3
  174. classiq/interface/model/classical_if.py +4 -0
  175. classiq/interface/model/control.py +8 -1
  176. classiq/interface/model/inplace_binary_operation.py +2 -2
  177. classiq/interface/model/invert.py +4 -0
  178. classiq/interface/model/model.py +4 -4
  179. classiq/interface/model/model_visitor.py +40 -1
  180. classiq/interface/model/parameter.py +1 -3
  181. classiq/interface/model/port_declaration.py +1 -1
  182. classiq/interface/model/power.py +4 -0
  183. classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
  184. classiq/interface/model/quantum_function_call.py +3 -6
  185. classiq/interface/model/quantum_function_declaration.py +1 -0
  186. classiq/interface/model/quantum_lambda_function.py +4 -4
  187. classiq/interface/model/quantum_statement.py +11 -4
  188. classiq/interface/model/quantum_type.py +14 -14
  189. classiq/interface/model/repeat.py +4 -0
  190. classiq/interface/model/skip_control.py +4 -0
  191. classiq/interface/model/validation_handle.py +2 -3
  192. classiq/interface/model/variable_declaration_statement.py +2 -2
  193. classiq/interface/model/within_apply_operation.py +4 -0
  194. classiq/interface/pretty_print/expression_to_qmod.py +3 -4
  195. classiq/interface/server/routes.py +0 -16
  196. classiq/interface/source_reference.py +3 -4
  197. classiq/model_expansions/arithmetic.py +11 -7
  198. classiq/model_expansions/arithmetic_compute_result_attrs.py +30 -27
  199. classiq/model_expansions/capturing/captured_vars.py +3 -3
  200. classiq/model_expansions/capturing/mangling_utils.py +1 -2
  201. classiq/model_expansions/closure.py +12 -11
  202. classiq/model_expansions/function_builder.py +14 -6
  203. classiq/model_expansions/generative_functions.py +7 -12
  204. classiq/model_expansions/interpreters/base_interpreter.py +3 -7
  205. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +2 -1
  206. classiq/model_expansions/interpreters/generative_interpreter.py +5 -3
  207. classiq/model_expansions/quantum_operations/allocate.py +4 -4
  208. classiq/model_expansions/quantum_operations/assignment_result_processor.py +2 -4
  209. classiq/model_expansions/quantum_operations/call_emitter.py +31 -37
  210. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
  211. classiq/model_expansions/quantum_operations/emitter.py +3 -5
  212. classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
  213. classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
  214. classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
  215. classiq/model_expansions/scope.py +7 -7
  216. classiq/model_expansions/scope_initialization.py +4 -0
  217. classiq/model_expansions/visitors/symbolic_param_inference.py +6 -6
  218. classiq/model_expansions/visitors/uncomputation_signature_inference.py +328 -0
  219. classiq/model_expansions/visitors/variable_references.py +15 -14
  220. classiq/open_library/functions/__init__.py +28 -11
  221. classiq/open_library/functions/amplitude_loading.py +81 -0
  222. classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
  223. classiq/open_library/functions/grover.py +8 -10
  224. classiq/open_library/functions/lcu.py +47 -18
  225. classiq/open_library/functions/modular_exponentiation.py +93 -8
  226. classiq/open_library/functions/qsvt.py +66 -79
  227. classiq/open_library/functions/qsvt_temp.py +536 -0
  228. classiq/open_library/functions/state_preparation.py +130 -27
  229. classiq/qmod/__init__.py +6 -4
  230. classiq/qmod/builtins/classical_execution_primitives.py +4 -23
  231. classiq/qmod/builtins/classical_functions.py +1 -42
  232. classiq/qmod/builtins/enums.py +15 -153
  233. classiq/qmod/builtins/functions/__init__.py +9 -18
  234. classiq/qmod/builtins/functions/allocation.py +25 -4
  235. classiq/qmod/builtins/functions/arithmetic.py +22 -27
  236. classiq/qmod/builtins/functions/exponentiation.py +51 -2
  237. classiq/qmod/builtins/functions/mcx_func.py +7 -0
  238. classiq/qmod/builtins/functions/standard_gates.py +46 -27
  239. classiq/qmod/builtins/operations.py +165 -79
  240. classiq/qmod/builtins/structs.py +24 -91
  241. classiq/qmod/cfunc.py +3 -2
  242. classiq/qmod/classical_function.py +2 -1
  243. classiq/qmod/cparam.py +2 -8
  244. classiq/qmod/create_model_function.py +7 -7
  245. classiq/qmod/declaration_inferrer.py +33 -30
  246. classiq/qmod/expression_query.py +7 -4
  247. classiq/qmod/model_state_container.py +2 -2
  248. classiq/qmod/native/pretty_printer.py +25 -14
  249. classiq/qmod/pretty_print/expression_to_python.py +5 -3
  250. classiq/qmod/pretty_print/pretty_printer.py +39 -17
  251. classiq/qmod/python_classical_type.py +40 -13
  252. classiq/qmod/qfunc.py +124 -19
  253. classiq/qmod/qmod_constant.py +2 -2
  254. classiq/qmod/qmod_parameter.py +5 -2
  255. classiq/qmod/qmod_variable.py +47 -46
  256. classiq/qmod/quantum_callable.py +18 -13
  257. classiq/qmod/quantum_expandable.py +31 -26
  258. classiq/qmod/quantum_function.py +84 -36
  259. classiq/qmod/semantics/annotation/call_annotation.py +5 -5
  260. classiq/qmod/semantics/error_manager.py +12 -14
  261. classiq/qmod/semantics/lambdas.py +1 -2
  262. classiq/qmod/semantics/validation/types_validation.py +1 -2
  263. classiq/qmod/symbolic.py +2 -4
  264. classiq/qmod/utilities.py +13 -20
  265. classiq/qmod/write_qmod.py +3 -4
  266. classiq/quantum_program.py +1 -3
  267. classiq/synthesis.py +11 -7
  268. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/METADATA +2 -3
  269. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/RECORD +271 -299
  270. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/WHEEL +1 -1
  271. classiq/applications/chemistry/ansatz_parameters.py +0 -29
  272. classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
  273. classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
  274. classiq/applications/chemistry/ground_state_problem.py +0 -42
  275. classiq/applications/qsvm/__init__.py +0 -8
  276. classiq/applications/qsvm/qsvm.py +0 -11
  277. classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
  278. classiq/execution/iqcc.py +0 -128
  279. classiq/interface/applications/qsvm.py +0 -117
  280. classiq/interface/chemistry/elements.py +0 -120
  281. classiq/interface/chemistry/fermionic_operator.py +0 -208
  282. classiq/interface/chemistry/ground_state_problem.py +0 -132
  283. classiq/interface/chemistry/ground_state_result.py +0 -8
  284. classiq/interface/chemistry/molecule.py +0 -71
  285. classiq/interface/execution/iqcc.py +0 -44
  286. classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
  287. classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
  288. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -6
  289. classiq/interface/generator/chemistry_function_params.py +0 -50
  290. classiq/interface/generator/entangler_params.py +0 -72
  291. classiq/interface/generator/entanglers.py +0 -14
  292. classiq/interface/generator/hamiltonian_evolution/qdrift.py +0 -27
  293. classiq/interface/generator/hartree_fock.py +0 -26
  294. classiq/interface/generator/hva.py +0 -22
  295. classiq/interface/generator/linear_pauli_rotations.py +0 -92
  296. classiq/interface/generator/qft.py +0 -37
  297. classiq/interface/generator/qsvm.py +0 -96
  298. classiq/interface/generator/state_preparation/__init__.py +0 -14
  299. classiq/interface/generator/state_preparation/bell_state_preparation.py +0 -27
  300. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +0 -28
  301. classiq/interface/generator/state_preparation/distributions.py +0 -53
  302. classiq/interface/generator/state_preparation/exponential_state_preparation.py +0 -14
  303. classiq/interface/generator/state_preparation/ghz_state_preparation.py +0 -14
  304. classiq/interface/generator/state_preparation/metrics.py +0 -41
  305. classiq/interface/generator/state_preparation/state_preparation.py +0 -113
  306. classiq/interface/generator/state_preparation/state_preparation_abc.py +0 -24
  307. classiq/interface/generator/state_preparation/uniform_distibution_state_preparation.py +0 -13
  308. classiq/interface/generator/state_preparation/w_state_preparation.py +0 -13
  309. classiq/interface/generator/ucc.py +0 -74
  310. classiq/interface/helpers/backward_compatibility.py +0 -9
  311. classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
  312. classiq/open_library/functions/lookup_table.py +0 -58
  313. classiq/qmod/builtins/functions/chemistry.py +0 -123
  314. classiq/qmod/builtins/functions/qsvm.py +0 -24
  315. {classiq-0.93.0.dist-info → classiq-0.99.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  import abc
2
2
  import sys
3
+ import warnings
3
4
  from collections.abc import Iterator, Mapping
4
5
  from contextlib import contextmanager
5
6
  from typing import ( # type: ignore[attr-defined]
@@ -10,10 +11,8 @@ from typing import ( # type: ignore[attr-defined]
10
11
  Generic,
11
12
  Literal,
12
13
  NoReturn,
13
- Optional,
14
14
  Protocol,
15
15
  TypeVar,
16
- Union,
17
16
  _GenericAlias,
18
17
  cast,
19
18
  get_args,
@@ -24,6 +23,7 @@ from typing import ( # type: ignore[attr-defined]
24
23
  from typing_extensions import ParamSpec, Self, _AnnotatedAlias
25
24
 
26
25
  from classiq.interface.exceptions import (
26
+ ClassiqDeprecationWarning,
27
27
  ClassiqInternalError,
28
28
  ClassiqNotImplementedError,
29
29
  ClassiqValueError,
@@ -109,9 +109,9 @@ class QVar(Symbolic):
109
109
 
110
110
  def __init__(
111
111
  self,
112
- origin: Union[None, str, HandleBinding] = None,
112
+ origin: None | str | HandleBinding = None,
113
113
  *,
114
- expr_str: Optional[str] = None,
114
+ expr_str: str | None = None,
115
115
  depth: int = 2,
116
116
  ) -> None:
117
117
  name = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
@@ -141,9 +141,9 @@ class QVar(Symbolic):
141
141
  @abc.abstractmethod
142
142
  def to_qvar(
143
143
  cls,
144
- origin: Union[str, HandleBinding],
144
+ origin: str | HandleBinding,
145
145
  type_hint: Any,
146
- expr_str: Optional[str],
146
+ expr_str: str | None,
147
147
  ) -> Self:
148
148
  raise NotImplementedError()
149
149
 
@@ -151,7 +151,7 @@ class QVar(Symbolic):
151
151
  return self._expr_str
152
152
 
153
153
  @property
154
- def size(self) -> Union[CParamScalar, int]:
154
+ def size(self) -> CParamScalar | int:
155
155
  if is_generative_mode():
156
156
  with generative_mode_context(False):
157
157
  return interpret_expression(str(self.size))
@@ -176,9 +176,6 @@ Input = Annotated[_Q, PortDeclarationDirection.Input]
176
176
  Const = Annotated[
177
177
  _Q, TypeModifier.Const
178
178
  ] # A constant variable, up to a phase dependent on the computational basis state
179
- Permutable = Annotated[
180
- _Q, TypeModifier.Permutable
181
- ] # A permutable ("quantum free") variable, up to a phase dependent on the computational basis state
182
179
 
183
180
 
184
181
  class QScalar(QVar, SymbolicExpr):
@@ -186,9 +183,9 @@ class QScalar(QVar, SymbolicExpr):
186
183
 
187
184
  def __init__(
188
185
  self,
189
- origin: Union[None, str, HandleBinding] = None,
186
+ origin: None | str | HandleBinding = None,
190
187
  *,
191
- _expr_str: Optional[str] = None,
188
+ _expr_str: str | None = None,
192
189
  depth: int = 2,
193
190
  ) -> None:
194
191
  origin = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
@@ -260,6 +257,13 @@ class QScalar(QVar, SymbolicExpr):
260
257
  return self
261
258
 
262
259
  def __imul__(self, other: Any) -> Self:
260
+ warnings.warn(
261
+ "The '*=' operator is deprecated and will no longer be supported "
262
+ "starting on 2025-12-03 at the earliest. Use the 'assign_amplitude_table' "
263
+ "function instead",
264
+ ClassiqDeprecationWarning,
265
+ stacklevel=2,
266
+ )
263
267
  if not isinstance(other, SYMBOLIC_TYPES):
264
268
  raise ClassiqValueError(
265
269
  f"Invalid argument {str(other)!r} for out of ampltiude encoding operation"
@@ -371,9 +375,9 @@ class QBit(QScalar):
371
375
  @classmethod
372
376
  def to_qvar(
373
377
  cls,
374
- origin: Union[str, HandleBinding],
378
+ origin: str | HandleBinding,
375
379
  type_hint: Any,
376
- expr_str: Optional[str],
380
+ expr_str: str | None,
377
381
  ) -> "QBit":
378
382
  return QBit(origin, _expr_str=expr_str)
379
383
 
@@ -428,11 +432,11 @@ class QNum(Generic[_P], QScalar):
428
432
 
429
433
  def __init__(
430
434
  self,
431
- name: Union[None, str, HandleBinding] = None,
432
- size: Union[int, CInt, Expression, SymbolicExpr, None] = None,
433
- is_signed: Union[bool, CBool, Expression, SymbolicExpr, None] = None,
434
- fraction_digits: Union[int, CInt, Expression, SymbolicExpr, None] = None,
435
- _expr_str: Optional[str] = None,
435
+ name: None | str | HandleBinding = None,
436
+ size: int | CInt | Expression | SymbolicExpr | None = None,
437
+ is_signed: bool | CBool | Expression | SymbolicExpr | None = None,
438
+ fraction_digits: int | CInt | Expression | SymbolicExpr | None = None,
439
+ _expr_str: str | None = None,
436
440
  ):
437
441
  if size is None and (is_signed is not None or fraction_digits is not None):
438
442
  raise ClassiqValueError(
@@ -466,9 +470,9 @@ class QNum(Generic[_P], QScalar):
466
470
  @classmethod
467
471
  def to_qvar(
468
472
  cls,
469
- origin: Union[str, HandleBinding],
473
+ origin: str | HandleBinding,
470
474
  type_hint: Any,
471
- expr_str: Optional[str],
475
+ expr_str: str | None,
472
476
  ) -> "QNum":
473
477
  return QNum(origin, *_get_qnum_attributes(type_hint), _expr_str=expr_str)
474
478
 
@@ -480,14 +484,14 @@ class QNum(Generic[_P], QScalar):
480
484
  )
481
485
 
482
486
  @property
483
- def fraction_digits(self) -> Union[CParamScalar, int]:
487
+ def fraction_digits(self) -> CParamScalar | int:
484
488
  if is_generative_mode():
485
489
  with generative_mode_context(False):
486
490
  return interpret_expression(str(self.fraction_digits))
487
491
  return CParamScalar(f"{self}.fraction_digits")
488
492
 
489
493
  @property
490
- def is_signed(self) -> Union[CParamScalar, bool]:
494
+ def is_signed(self) -> CParamScalar | bool:
491
495
  if is_generative_mode():
492
496
  with generative_mode_context(False):
493
497
  return interpret_expression(str(self.is_signed))
@@ -510,12 +514,6 @@ class QNum(Generic[_P], QScalar):
510
514
  fraction_places=self.fraction_digits,
511
515
  )
512
516
 
513
- # Support comma-separated generic args in older Python versions
514
- if sys.version_info[0:2] < (3, 10):
515
-
516
- def __class_getitem__(cls, args) -> _GenericAlias:
517
- return _GenericAlias(cls, args)
518
-
519
517
 
520
518
  class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
521
519
  CONSTRUCTOR_DEPTH: int = 3
@@ -523,10 +521,10 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
523
521
  # TODO [CAD-18620]: improve type hints
524
522
  def __init__(
525
523
  self,
526
- name: Union[None, str, HandleBinding] = None,
527
- element_type: Union[_GenericAlias, QuantumType] = QBit,
528
- length: Optional[Union[int, CInt, SymbolicExpr, Expression]] = None,
529
- _expr_str: Optional[str] = None,
524
+ name: None | str | HandleBinding = None,
525
+ element_type: _GenericAlias | QuantumType = QBit,
526
+ length: int | CInt | SymbolicExpr | Expression | None = None,
527
+ _expr_str: str | None = None,
530
528
  ) -> None:
531
529
  self._element_type = element_type
532
530
  self._length = (
@@ -536,7 +534,7 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
536
534
  )
537
535
  super().__init__(name, expr_str=_expr_str)
538
536
 
539
- def __getitem__(self, key: Union[slice, int, SymbolicExpr]) -> Any:
537
+ def __getitem__(self, key: slice | int | SymbolicExpr) -> Any:
540
538
  return (
541
539
  self._get_slice(key) if isinstance(key, slice) else self._get_subscript(key)
542
540
  )
@@ -544,7 +542,7 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
544
542
  def __setitem__(self, *args: Any) -> None:
545
543
  pass
546
544
 
547
- def _get_subscript(self, index: Union[slice, int, SymbolicExpr]) -> Any:
545
+ def _get_subscript(self, index: slice | int | SymbolicExpr) -> Any:
548
546
  if isinstance(index, SymbolicExpr) and index.is_quantum:
549
547
  raise ClassiqValueError("Non-classical parameter for slicing")
550
548
 
@@ -589,7 +587,7 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
589
587
  else:
590
588
 
591
589
  @property
592
- def len(self) -> Union[CParamScalar, int]:
590
+ def len(self) -> CParamScalar | int:
593
591
  if is_generative_mode():
594
592
  with generative_mode_context(False):
595
593
  return interpret_expression(str(self.len))
@@ -598,9 +596,9 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
598
596
  @classmethod
599
597
  def to_qvar(
600
598
  cls,
601
- origin: Union[str, HandleBinding],
599
+ origin: str | HandleBinding,
602
600
  type_hint: Any,
603
- expr_str: Optional[str],
601
+ expr_str: str | None,
604
602
  ) -> "QArray":
605
603
  return QArray(origin, *_get_qarray_attributes(type_hint), _expr_str=expr_str)
606
604
 
@@ -614,6 +612,9 @@ class QArray(ArrayBase[_P], QVar, NonSymbolicExpr):
614
612
  length=self._length,
615
613
  )
616
614
 
615
+ def __iter__(self) -> NoReturn:
616
+ raise TypeError(f"{type(self).__name__!r} object is not iterable")
617
+
617
618
 
618
619
  class QStruct(QVar):
619
620
  CONSTRUCTOR_DEPTH: int = 2
@@ -623,10 +624,10 @@ class QStruct(QVar):
623
624
 
624
625
  def __init__(
625
626
  self,
626
- origin: Union[None, str, HandleBinding] = None,
627
- _struct_name: Optional[str] = None,
628
- _fields: Optional[Mapping[str, QVar]] = None,
629
- _expr_str: Optional[str] = None,
627
+ origin: None | str | HandleBinding = None,
628
+ _struct_name: str | None = None,
629
+ _fields: Mapping[str, QVar] | None = None,
630
+ _expr_str: str | None = None,
630
631
  ) -> None:
631
632
  _register_qstruct(type(self), qmodule=QMODULE)
632
633
  name = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
@@ -654,9 +655,9 @@ class QStruct(QVar):
654
655
  @classmethod
655
656
  def to_qvar(
656
657
  cls,
657
- origin: Union[str, HandleBinding],
658
+ origin: str | HandleBinding,
658
659
  type_hint: Any,
659
- expr_str: Optional[str],
660
+ expr_str: str | None,
660
661
  ) -> "QStruct":
661
662
  field_types = {
662
663
  field_name: (_get_root_type(field_type), field_type)
@@ -699,7 +700,7 @@ def create_qvar_from_quantum_type(quantum_type: ConcreteQuantumType, name: str)
699
700
 
700
701
 
701
702
  def _create_qvar_for_qtype(
702
- qtype: QuantumType, origin: HandleBinding, expr_str: Optional[str] = None
703
+ qtype: QuantumType, origin: HandleBinding, expr_str: str | None = None
703
704
  ) -> QVar:
704
705
  # prevent addition to local handles, since this is used for ports
705
706
  with _no_current_expandable():
@@ -868,7 +869,7 @@ def _get_quantum_struct(type_hint: type[QStruct]) -> Struct:
868
869
 
869
870
  def _register_qstruct(
870
871
  type_hint: type[QStruct], *, qmodule: ModelStateContainer
871
- ) -> Optional[QStructDeclaration]:
872
+ ) -> QStructDeclaration | None:
872
873
  struct_name = type_hint.__name__
873
874
  if type_hint is QStruct:
874
875
  return None
@@ -1,13 +1,10 @@
1
1
  import sys
2
2
  from abc import ABC, abstractmethod
3
- from typing import ( # type: ignore[attr-defined]
3
+ from typing import (
4
4
  TYPE_CHECKING,
5
5
  Any,
6
6
  ClassVar,
7
7
  Generic,
8
- Optional,
9
- Union,
10
- _GenericAlias,
11
8
  )
12
9
 
13
10
  from typing_extensions import ParamSpec
@@ -39,13 +36,13 @@ class QExpandableInterface(ABC):
39
36
  self,
40
37
  name: str,
41
38
  qtype: QuantumType,
42
- source_ref: Optional[SourceReference] = None,
39
+ source_ref: SourceReference | None = None,
43
40
  ) -> None:
44
41
  raise NotImplementedError()
45
42
 
46
43
 
47
44
  class QCallable(Generic[P], ABC):
48
- CURRENT_EXPANDABLE: ClassVar[Optional[QExpandableInterface]] = None
45
+ CURRENT_EXPANDABLE: ClassVar[QExpandableInterface | None] = None
49
46
  FRAME_DEPTH = 1
50
47
 
51
48
  @suppress_return_value
@@ -62,12 +59,6 @@ class QCallable(Generic[P], ABC):
62
59
  def func_decl(self) -> AnonQuantumFunctionDeclaration:
63
60
  raise NotImplementedError
64
61
 
65
- # Support comma-separated generic args in older Python versions
66
- if sys.version_info[0:2] < (3, 10):
67
-
68
- def __class_getitem__(cls, args) -> _GenericAlias:
69
- return _GenericAlias(cls, args)
70
-
71
62
  @abstractmethod
72
63
  def create_quantum_function_call(
73
64
  self, source_ref_: SourceReference, *args: Any, **kwargs: Any
@@ -81,5 +72,19 @@ class QCallableList(QCallable, Generic[P], ABC):
81
72
  @property
82
73
  def len(self) -> int: ...
83
74
 
84
- def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
75
+ def __getitem__(self, key: slice | int | CInt) -> "QTerminalCallable":
76
+ raise NotImplementedError()
77
+
78
+
79
+ class QPerm(QCallable, Generic[P], ABC):
80
+ pass
81
+
82
+
83
+ class QPermList(QCallable, Generic[P], ABC):
84
+ if TYPE_CHECKING:
85
+
86
+ @property
87
+ def len(self) -> int: ...
88
+
89
+ def __getitem__(self, key: slice | int | CInt) -> "QTerminalCallable":
85
90
  raise NotImplementedError()
@@ -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 = [