classiq 0.53.0__py3-none-any.whl → 0.55.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 (301) hide show
  1. classiq/__init__.py +1 -3
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/__init__.py +0 -20
  4. classiq/_internals/api_wrapper.py +8 -8
  5. classiq/_internals/async_utils.py +1 -3
  6. classiq/_internals/authentication/auth0.py +5 -5
  7. classiq/_internals/authentication/device.py +5 -4
  8. classiq/_internals/authentication/password_manager.py +3 -3
  9. classiq/_internals/authentication/token_manager.py +3 -2
  10. classiq/_internals/client.py +10 -12
  11. classiq/_internals/config.py +2 -2
  12. classiq/_internals/jobs.py +7 -6
  13. classiq/_internals/type_validation.py +9 -9
  14. classiq/analyzer/__init__.py +1 -3
  15. classiq/analyzer/analyzer.py +8 -7
  16. classiq/analyzer/analyzer_utilities.py +8 -8
  17. classiq/analyzer/rb.py +11 -11
  18. classiq/applications/__init__.py +1 -3
  19. classiq/applications/chemistry/__init__.py +1 -3
  20. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  21. classiq/applications/chemistry/chemistry_model_constructor.py +10 -9
  22. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +26 -9
  23. classiq/applications/combinatorial_helpers/encoding_mapping.py +10 -10
  24. classiq/applications/combinatorial_helpers/encoding_utils.py +4 -4
  25. classiq/applications/combinatorial_helpers/memory.py +5 -7
  26. classiq/applications/combinatorial_helpers/optimization_model.py +43 -24
  27. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +4 -6
  28. classiq/applications/combinatorial_helpers/pyomo_utils.py +95 -24
  29. classiq/applications/combinatorial_helpers/sympy_utils.py +2 -2
  30. classiq/applications/combinatorial_helpers/transformations/encoding.py +8 -8
  31. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -5
  32. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +7 -9
  33. classiq/applications/combinatorial_helpers/transformations/penalty.py +1 -2
  34. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -2
  35. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +1 -2
  36. classiq/applications/combinatorial_optimization/__init__.py +1 -3
  37. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  38. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  39. classiq/applications/finance/__init__.py +1 -3
  40. classiq/applications/grover/__init__.py +1 -3
  41. classiq/applications/grover/grover_model_constructor.py +7 -9
  42. classiq/applications/hamiltonian/pauli_decomposition.py +6 -6
  43. classiq/applications/qnn/__init__.py +1 -3
  44. classiq/applications/qnn/circuit_utils.py +5 -5
  45. classiq/applications/qnn/datasets/__init__.py +1 -3
  46. classiq/applications/qnn/datasets/dataset_base_classes.py +5 -4
  47. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  48. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  49. classiq/applications/qnn/qlayer.py +3 -3
  50. classiq/applications/qnn/torch_utils.py +2 -2
  51. classiq/applications/qnn/types.py +5 -5
  52. classiq/applications/qsvm/qsvm.py +1 -3
  53. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  54. classiq/applications/qsvm/qsvm_model_constructor.py +5 -5
  55. classiq/execution/__init__.py +1 -3
  56. classiq/execution/all_hardware_devices.py +1 -3
  57. classiq/execution/execution_session.py +16 -16
  58. classiq/execution/jobs.py +4 -4
  59. classiq/execution/qaoa.py +3 -3
  60. classiq/execution/qnn.py +3 -3
  61. classiq/executor.py +3 -3
  62. classiq/interface/_version.py +1 -1
  63. classiq/interface/analyzer/analysis_params.py +9 -10
  64. classiq/interface/analyzer/cytoscape_graph.py +5 -5
  65. classiq/interface/analyzer/result.py +17 -17
  66. classiq/interface/applications/qsvm.py +6 -10
  67. classiq/interface/backend/backend_preferences.py +4 -3
  68. classiq/interface/backend/ionq/ionq_quantum_program.py +4 -5
  69. classiq/interface/backend/pydantic_backend.py +1 -2
  70. classiq/interface/chemistry/fermionic_operator.py +5 -5
  71. classiq/interface/chemistry/ground_state_problem.py +7 -8
  72. classiq/interface/chemistry/molecule.py +4 -4
  73. classiq/interface/chemistry/operator.py +11 -13
  74. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  75. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  76. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  77. classiq/interface/combinatorial_optimization/examples/mht.py +2 -3
  78. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  79. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  80. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +5 -7
  81. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  82. classiq/interface/combinatorial_optimization/result.py +1 -3
  83. classiq/interface/debug_info/debug_info.py +8 -7
  84. classiq/interface/exceptions.py +8 -6
  85. classiq/interface/execution/jobs.py +2 -2
  86. classiq/interface/execution/primitives.py +3 -3
  87. classiq/interface/executor/aws_execution_cost.py +4 -4
  88. classiq/interface/executor/execution_request.py +2 -3
  89. classiq/interface/executor/execution_result.py +3 -3
  90. classiq/interface/executor/iqae_result.py +3 -5
  91. classiq/interface/executor/optimizer_preferences.py +2 -2
  92. classiq/interface/executor/quantum_code.py +6 -6
  93. classiq/interface/executor/register_initialization.py +2 -4
  94. classiq/interface/executor/result.py +23 -27
  95. classiq/interface/executor/vqe_result.py +8 -8
  96. classiq/interface/finance/function_input.py +2 -2
  97. classiq/interface/finance/gaussian_model_input.py +5 -5
  98. classiq/interface/finance/log_normal_model_input.py +2 -2
  99. classiq/interface/finance/model_input.py +1 -2
  100. classiq/interface/generator/adjacency.py +1 -3
  101. classiq/interface/generator/ansatz_library.py +4 -4
  102. classiq/interface/generator/application_apis/finance_declarations.py +1 -1
  103. classiq/interface/generator/arith/argument_utils.py +3 -3
  104. classiq/interface/generator/arith/arithmetic.py +7 -7
  105. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +5 -5
  106. classiq/interface/generator/arith/arithmetic_expression_abc.py +11 -11
  107. classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -7
  108. classiq/interface/generator/arith/arithmetic_expression_validator.py +8 -8
  109. classiq/interface/generator/arith/arithmetic_operations.py +4 -3
  110. classiq/interface/generator/arith/arithmetic_param_getters.py +6 -6
  111. classiq/interface/generator/arith/arithmetic_result_builder.py +9 -9
  112. classiq/interface/generator/arith/ast_node_rewrite.py +2 -1
  113. classiq/interface/generator/arith/binary_ops.py +10 -13
  114. classiq/interface/generator/arith/extremum_operations.py +3 -2
  115. classiq/interface/generator/arith/logical_ops.py +7 -6
  116. classiq/interface/generator/arith/number_utils.py +4 -4
  117. classiq/interface/generator/arith/register_user_input.py +4 -4
  118. classiq/interface/generator/arith/unary_ops.py +2 -1
  119. classiq/interface/generator/builtin_api_builder.py +2 -1
  120. classiq/interface/generator/circuit_code/circuit_code.py +4 -4
  121. classiq/interface/generator/circuit_code/types_and_constants.py +3 -5
  122. classiq/interface/generator/complex_type.py +1 -2
  123. classiq/interface/generator/control_state.py +2 -2
  124. classiq/interface/generator/custom_ansatz.py +1 -3
  125. classiq/interface/generator/distance.py +3 -5
  126. classiq/interface/generator/excitations.py +3 -2
  127. classiq/interface/generator/expressions/enums/finance_functions.py +1 -3
  128. classiq/interface/generator/expressions/evaluated_expression.py +4 -3
  129. classiq/interface/generator/expressions/expression.py +4 -5
  130. classiq/interface/generator/expressions/expression_constants.py +4 -4
  131. classiq/interface/generator/expressions/qmod_qarray_proxy.py +2 -1
  132. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -1
  133. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +2 -1
  134. classiq/interface/generator/expressions/qmod_sized_proxy.py +2 -1
  135. classiq/interface/generator/expressions/qmod_struct_instance.py +2 -1
  136. classiq/interface/generator/expressions/sympy_supported_expressions.py +11 -13
  137. classiq/interface/generator/finance.py +2 -2
  138. classiq/interface/generator/function_param_library.py +6 -6
  139. classiq/interface/generator/function_params.py +13 -19
  140. classiq/interface/generator/functions/builtins/internal_operators.py +9 -1
  141. classiq/interface/generator/functions/classical_function_declaration.py +4 -3
  142. classiq/interface/generator/functions/classical_type.py +13 -13
  143. classiq/interface/generator/functions/concrete_types.py +1 -2
  144. classiq/interface/generator/functions/function_declaration.py +1 -1
  145. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  146. classiq/interface/generator/functions/type_name.py +3 -2
  147. classiq/interface/generator/generated_circuit_data.py +33 -22
  148. classiq/interface/generator/grover_diffuser.py +7 -7
  149. classiq/interface/generator/grover_operator.py +2 -2
  150. classiq/interface/generator/hardware/hardware_data.py +7 -6
  151. classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
  152. classiq/interface/generator/identity.py +5 -6
  153. classiq/interface/generator/linear_pauli_rotations.py +6 -6
  154. classiq/interface/generator/mcu.py +2 -2
  155. classiq/interface/generator/mcx.py +6 -6
  156. classiq/interface/generator/model/__init__.py +1 -3
  157. classiq/interface/generator/model/constraints.py +2 -2
  158. classiq/interface/generator/model/model.py +5 -6
  159. classiq/interface/generator/model/preferences/preferences.py +11 -6
  160. classiq/interface/generator/model/quantum_register.py +6 -11
  161. classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
  162. classiq/interface/generator/oracles/custom_oracle.py +2 -2
  163. classiq/interface/generator/oracles/oracle_abc.py +6 -5
  164. classiq/interface/generator/partitioned_register.py +6 -5
  165. classiq/interface/generator/piecewise_linear_amplitude_loading.py +8 -7
  166. classiq/interface/generator/qpe.py +4 -4
  167. classiq/interface/generator/qsvm.py +3 -3
  168. classiq/interface/generator/quantum_function_call.py +24 -29
  169. classiq/interface/generator/quantum_program.py +9 -9
  170. classiq/interface/generator/register_role.py +2 -4
  171. classiq/interface/generator/slice_parsing_utils.py +4 -3
  172. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  173. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  174. classiq/interface/generator/state_preparation/distributions.py +6 -5
  175. classiq/interface/generator/state_preparation/metrics.py +2 -4
  176. classiq/interface/generator/state_preparation/state_preparation.py +4 -4
  177. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -3
  178. classiq/interface/generator/transpiler_basis_gates.py +2 -2
  179. classiq/interface/generator/types/compilation_metadata.py +5 -0
  180. classiq/interface/generator/types/enum_declaration.py +2 -3
  181. classiq/interface/generator/types/qstruct_declaration.py +2 -1
  182. classiq/interface/generator/types/struct_declaration.py +3 -2
  183. classiq/interface/generator/ucc.py +2 -1
  184. classiq/interface/generator/unitary_gate.py +2 -2
  185. classiq/interface/generator/user_defined_function_params.py +1 -1
  186. classiq/interface/generator/validations/flow_graph.py +6 -5
  187. classiq/interface/generator/validations/validator_functions.py +3 -2
  188. classiq/interface/generator/visitor.py +9 -14
  189. classiq/interface/hardware.py +5 -6
  190. classiq/interface/helpers/custom_encoders.py +2 -2
  191. classiq/interface/helpers/custom_pydantic_types.py +8 -9
  192. classiq/interface/helpers/hashable_mixin.py +3 -2
  193. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  194. classiq/interface/helpers/pydantic_model_helpers.py +4 -3
  195. classiq/interface/helpers/validation_helpers.py +2 -2
  196. classiq/interface/ide/ide_data.py +11 -15
  197. classiq/interface/ide/visual_model.py +22 -22
  198. classiq/interface/jobs.py +2 -2
  199. classiq/interface/model/bind_operation.py +5 -4
  200. classiq/interface/model/classical_parameter_declaration.py +2 -2
  201. classiq/interface/model/control.py +22 -1
  202. classiq/interface/model/handle_binding.py +3 -2
  203. classiq/interface/model/inplace_binary_operation.py +2 -1
  204. classiq/interface/model/model.py +16 -11
  205. classiq/interface/model/native_function_definition.py +1 -1
  206. classiq/interface/model/port_declaration.py +2 -2
  207. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +3 -2
  208. classiq/interface/model/quantum_expressions/arithmetic_operation.py +4 -27
  209. classiq/interface/model/quantum_expressions/quantum_expression.py +8 -7
  210. classiq/interface/model/quantum_function_call.py +9 -14
  211. classiq/interface/model/quantum_function_declaration.py +10 -12
  212. classiq/interface/model/quantum_lambda_function.py +3 -16
  213. classiq/interface/model/quantum_statement.py +7 -3
  214. classiq/interface/model/quantum_type.py +5 -5
  215. classiq/interface/model/statement_block.py +2 -3
  216. classiq/interface/model/validation_handle.py +5 -4
  217. classiq/interface/server/global_versions.py +3 -3
  218. classiq/model_expansions/atomic_expression_functions_defs.py +3 -2
  219. classiq/model_expansions/capturing/captured_var_manager.py +4 -6
  220. classiq/model_expansions/capturing/propagated_var_stack.py +7 -7
  221. classiq/model_expansions/closure.py +83 -12
  222. classiq/model_expansions/evaluators/arg_type_match.py +3 -2
  223. classiq/model_expansions/evaluators/argument_types.py +3 -3
  224. classiq/model_expansions/evaluators/control.py +3 -3
  225. classiq/model_expansions/evaluators/parameter_types.py +7 -7
  226. classiq/model_expansions/evaluators/quantum_type_utils.py +2 -1
  227. classiq/model_expansions/evaluators/type_type_match.py +1 -1
  228. classiq/model_expansions/expression_evaluator.py +10 -9
  229. classiq/model_expansions/expression_renamer.py +6 -6
  230. classiq/model_expansions/function_builder.py +13 -12
  231. classiq/model_expansions/generative_functions.py +5 -4
  232. classiq/model_expansions/interpreter.py +20 -11
  233. classiq/model_expansions/model_tables.py +14 -14
  234. classiq/model_expansions/quantum_operations/bind.py +2 -4
  235. classiq/model_expansions/quantum_operations/classicalif.py +1 -1
  236. classiq/model_expansions/quantum_operations/control.py +81 -24
  237. classiq/model_expansions/quantum_operations/emitter.py +33 -20
  238. classiq/model_expansions/quantum_operations/expression_operation.py +47 -16
  239. classiq/model_expansions/quantum_operations/inplace_binary_operation.py +160 -35
  240. classiq/model_expansions/quantum_operations/phase.py +6 -6
  241. classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +28 -31
  242. classiq/model_expansions/quantum_operations/quantum_function_call.py +9 -0
  243. classiq/model_expansions/quantum_operations/repeat.py +1 -3
  244. classiq/model_expansions/quantum_operations/within_apply.py +0 -16
  245. classiq/model_expansions/scope.py +11 -10
  246. classiq/model_expansions/scope_initialization.py +5 -5
  247. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +6 -6
  248. classiq/model_expansions/sympy_conversion/sympy_to_python.py +2 -2
  249. classiq/model_expansions/visitors/variable_references.py +5 -4
  250. classiq/qmod/builtins/classical_execution_primitives.py +9 -9
  251. classiq/qmod/builtins/functions/__init__.py +72 -55
  252. classiq/qmod/builtins/functions/amplitude_estimation.py +4 -1
  253. classiq/qmod/builtins/functions/arithmetic.py +14 -1
  254. classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +86 -6
  255. classiq/qmod/builtins/functions/grover.py +41 -45
  256. classiq/qmod/builtins/functions/hea.py +60 -4
  257. classiq/qmod/builtins/functions/linear_pauli_rotation.py +26 -4
  258. classiq/qmod/builtins/functions/modular_exponentiation.py +90 -29
  259. classiq/qmod/builtins/functions/operators.py +1 -1
  260. classiq/qmod/builtins/functions/qaoa_penalty.py +14 -5
  261. classiq/qmod/builtins/functions/qft_functions.py +57 -0
  262. classiq/qmod/builtins/functions/qpe.py +20 -4
  263. classiq/qmod/builtins/functions/qsvt.py +49 -4
  264. classiq/qmod/builtins/functions/standard_gates.py +4 -4
  265. classiq/qmod/builtins/functions/state_preparation.py +92 -10
  266. classiq/qmod/builtins/functions/swap_test.py +7 -1
  267. classiq/qmod/builtins/functions/utility_functions.py +43 -0
  268. classiq/qmod/builtins/functions/variational.py +18 -2
  269. classiq/qmod/builtins/operations.py +117 -22
  270. classiq/qmod/cfunc.py +2 -2
  271. classiq/qmod/classical_function.py +3 -7
  272. classiq/qmod/create_model_function.py +16 -17
  273. classiq/qmod/declaration_inferrer.py +7 -10
  274. classiq/qmod/expression_query.py +3 -3
  275. classiq/qmod/generative.py +2 -1
  276. classiq/qmod/model_state_container.py +10 -8
  277. classiq/qmod/native/__init__.py +1 -3
  278. classiq/qmod/native/expression_to_qmod.py +9 -8
  279. classiq/qmod/native/pretty_printer.py +12 -6
  280. classiq/qmod/pretty_print/__init__.py +1 -3
  281. classiq/qmod/pretty_print/expression_to_python.py +13 -12
  282. classiq/qmod/pretty_print/pretty_printer.py +38 -23
  283. classiq/qmod/python_classical_type.py +8 -4
  284. classiq/qmod/qfunc.py +4 -4
  285. classiq/qmod/qmod_variable.py +11 -10
  286. classiq/qmod/quantum_expandable.py +12 -15
  287. classiq/qmod/quantum_function.py +35 -22
  288. classiq/qmod/semantics/annotation.py +1 -1
  289. classiq/qmod/semantics/error_manager.py +8 -7
  290. classiq/qmod/semantics/static_semantics_visitor.py +19 -24
  291. classiq/qmod/semantics/validation/constants_validation.py +1 -1
  292. classiq/qmod/semantics/validation/func_call_validation.py +2 -2
  293. classiq/qmod/semantics/validation/main_validation.py +33 -0
  294. classiq/qmod/semantics/validation/types_validation.py +2 -1
  295. classiq/qmod/symbolic.py +5 -8
  296. classiq/qmod/symbolic_type.py +2 -2
  297. classiq/qmod/synthesize_separately.py +1 -2
  298. {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/METADATA +1 -1
  299. {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/RECORD +300 -297
  300. classiq/qmod/builtins/functions/qft.py +0 -23
  301. {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/WHEEL +0 -0
@@ -1,8 +1,7 @@
1
1
  import ast
2
2
  import inspect
3
- import sys
4
3
  from textwrap import dedent
5
- from typing import Any, Callable, Dict
4
+ from typing import Any, Callable
6
5
 
7
6
  from classiq.interface.exceptions import ClassiqValueError
8
7
 
@@ -17,16 +16,13 @@ def _unparse_function_body(code: str, func: ast.FunctionDef) -> str:
17
16
 
18
17
 
19
18
  class CFunc:
20
- def __init__(self, py_callable: Callable[[], None], caller_locals: Dict[str, Any]):
19
+ def __init__(self, py_callable: Callable[[], None], caller_locals: dict[str, Any]):
21
20
  code = dedent(inspect.getsource(py_callable))
22
21
  func = ast.parse(code).body[0]
23
22
  if not isinstance(func, ast.FunctionDef):
24
23
  raise ClassiqValueError("Use @cfunc to decorate a function")
25
24
  if len(func.args.args) > 0:
26
25
  raise ClassiqValueError("A @cfunc must receive no arguments")
27
- if sys.version_info >= (3, 9):
28
- self.code = "\n".join([ast.unparse(statement) for statement in func.body])
29
- else:
30
- self.code = _unparse_function_body(code, func)
26
+ self.code = "\n".join([ast.unparse(statement) for statement in func.body])
31
27
 
32
28
  self._caller_constants = caller_locals
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, Dict, List, Optional, Union, cast
1
+ from typing import TYPE_CHECKING, Optional, Union, cast
2
2
 
3
3
  from classiq.interface.exceptions import ClassiqError
4
4
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
@@ -60,6 +60,7 @@ def create_model(
60
60
  user_gen_functions = {
61
61
  gen_func._py_callable.__name__ for gen_func in GEN_QFUNCS
62
62
  } - set(BUILTIN_FUNCTION_DECLARATIONS.keys())
63
+
63
64
  if len(user_gen_functions) > 0 and is_generative_expansion_enabled():
64
65
  model = _expand_generative_model(
65
66
  (
@@ -100,11 +101,17 @@ def _expand_generative_model(
100
101
  def _dummy() -> None:
101
102
  pass
102
103
 
104
+ functions_compilation_metadata = {
105
+ dec_func._py_callable.__name__: dec_func.compilation_metadata
106
+ for dec_func in DEC_QFUNCS
107
+ if dec_func.compilation_metadata is not None
108
+ }
103
109
  model = _dummy.create_model(
104
110
  constraints,
105
111
  execution_preferences,
106
112
  preferences,
107
113
  classical_execution_function,
114
+ functions_compilation_metadata,
108
115
  )
109
116
  generative_functions = _get_generative_functions(gen_main, preferences)
110
117
  model.functions = generative_functions
@@ -116,7 +123,7 @@ def _expand_generative_model(
116
123
 
117
124
  def _get_generative_functions(
118
125
  gen_main: QFunc, preferences: Optional[Preferences]
119
- ) -> List[NativeFunctionDefinition]:
126
+ ) -> list[NativeFunctionDefinition]:
120
127
  # The Interpreter accepts a model and a list of generative functions.
121
128
  # Since the main function is generative, it can only be expanded using the
122
129
  # Interpreter.
@@ -154,10 +161,11 @@ def _get_wrapper_main(gen_main: QFunc, preferences: Optional[Preferences]) -> Mo
154
161
  )
155
162
 
156
163
 
157
- def _get_all_model_functions_as_generative_functions() -> List[GenerativeQFunc]:
164
+ def _get_all_model_functions_as_generative_functions() -> list[GenerativeQFunc]:
158
165
 
159
166
  gen_functions = list(GEN_QFUNCS) + [
160
- _get_gen_from_dec(dec_func) for dec_func in DEC_QFUNCS
167
+ GenerativeQFunc(dec_func._py_callable, dec_func.func_decl)
168
+ for dec_func in DEC_QFUNCS
161
169
  ]
162
170
  return [
163
171
  (
@@ -173,26 +181,17 @@ def _get_all_model_functions_as_generative_functions() -> List[GenerativeQFunc]:
173
181
  ]
174
182
 
175
183
 
176
- def _get_gen_from_dec(dec_func: QFunc) -> GenerativeQFunc:
177
- synthesis_data = dec_func.synthesis_data
178
- if synthesis_data is not None and synthesis_data.should_synthesize_separately:
179
- raise ClassiqError(
180
- """The model contains generative functions,
181
- which cannot coexist with functions marked for separate synthesis"""
182
- )
183
- return GenerativeQFunc(dec_func._py_callable, dec_func.func_decl)
184
-
185
-
186
184
  def _interpret_generative_model(
187
- gen_model: Model, gen_functions: List[GenerativeQFunc]
188
- ) -> Dict[str, NativeFunctionDefinition]:
185
+ gen_model: Model, gen_functions: list[GenerativeQFunc]
186
+ ) -> dict[str, NativeFunctionDefinition]:
189
187
  resolve_function_calls(
190
188
  gen_model,
191
189
  {gen_func.func_decl.name: gen_func.func_decl for gen_func in gen_functions},
192
190
  )
193
191
  interpreter = Interpreter(gen_model, gen_functions, is_frontend=True)
194
192
  set_frontend_interpreter(interpreter)
195
- functions_dict = nameables_to_dict(interpreter.expand().functions)
193
+ expand_model = interpreter.expand()
194
+ functions_dict = nameables_to_dict(expand_model.functions)
196
195
 
197
196
  # Inline _gen_main call in main
198
197
  expanded_gen_main_name = cast(
@@ -1,15 +1,12 @@
1
1
  import dataclasses
2
2
  import sys
3
+ from collections.abc import Sequence
3
4
  from enum import EnumMeta
4
5
  from typing import (
5
6
  Any,
6
7
  Callable,
7
- List,
8
8
  Literal,
9
9
  Optional,
10
- Sequence,
11
- Tuple,
12
- Type,
13
10
  get_args,
14
11
  get_origin,
15
12
  overload,
@@ -91,7 +88,7 @@ def python_type_to_qmod(
91
88
 
92
89
  def _extract_port_decl(name: Optional[str], py_type: Any) -> AnonPortDeclaration:
93
90
  # FIXME: CAD-13409
94
- qtype: Type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
91
+ qtype: type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
95
92
  direction = qtype.port_direction(py_type)
96
93
  if isinstance(py_type, _AnnotatedAlias):
97
94
  py_type = py_type.__args__[0]
@@ -128,7 +125,7 @@ def _extract_operand_decl(
128
125
  return param
129
126
 
130
127
 
131
- def _extract_operand_param(py_type: Any) -> Tuple[Optional[str], Any]:
128
+ def _extract_operand_param(py_type: Any) -> tuple[Optional[str], Any]:
132
129
  if sys.version_info[0:2] < (3, 9) or get_origin(py_type) is not Annotated:
133
130
  return None, py_type
134
131
  args = get_args(py_type)
@@ -152,22 +149,22 @@ def _extract_operand_param(py_type: Any) -> Tuple[Optional[str], Any]:
152
149
 
153
150
  @overload
154
151
  def _extract_positional_args(
155
- args: Sequence[Tuple[str, Any]], qmodule: Optional[ModelStateContainer]
152
+ args: Sequence[tuple[str, Any]], qmodule: Optional[ModelStateContainer]
156
153
  ) -> Sequence[PositionalArg]:
157
154
  pass
158
155
 
159
156
 
160
157
  @overload
161
158
  def _extract_positional_args(
162
- args: Sequence[Tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
159
+ args: Sequence[tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
163
160
  ) -> Sequence[AnonPositionalArg]:
164
161
  pass
165
162
 
166
163
 
167
164
  def _extract_positional_args(
168
- args: Sequence[Tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
165
+ args: Sequence[tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
169
166
  ) -> Sequence[AnonPositionalArg]:
170
- result: List[AnonPositionalArg] = []
167
+ result: list[AnonPositionalArg] = []
171
168
  for name, py_type in args:
172
169
  if name == "return":
173
170
  continue
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, List, Tuple
1
+ from typing import TYPE_CHECKING
2
2
 
3
3
  from classiq.interface.generator.arith.arithmetic import compute_arithmetic_result_type
4
4
  from classiq.interface.generator.arith.number_utils import MAXIMAL_MACHINE_PRECISION
@@ -9,10 +9,10 @@ from classiq.qmod.symbolic_type import SymbolicTypes
9
9
 
10
10
 
11
11
  def get_expression_numeric_attributes(
12
- vars: List[QNum],
12
+ vars: list[QNum],
13
13
  expr: SymbolicTypes,
14
14
  machine_precision: int = MAXIMAL_MACHINE_PRECISION,
15
- ) -> Tuple[int, bool, int]:
15
+ ) -> tuple[int, bool, int]:
16
16
  """
17
17
  Computes and returns the numeric attributes of a given symbolic expression.
18
18
 
@@ -1,5 +1,6 @@
1
+ from collections.abc import Iterator
1
2
  from contextlib import contextmanager
2
- from typing import TYPE_CHECKING, Any, Iterator, Optional
3
+ from typing import TYPE_CHECKING, Any, Optional
3
4
 
4
5
  from classiq.interface.exceptions import ClassiqError
5
6
  from classiq.interface.generator.expressions.expression import Expression
@@ -1,18 +1,20 @@
1
- from typing import Dict
2
-
3
1
  from classiq.interface.generator.constant import Constant
2
+ from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
4
3
  from classiq.interface.generator.types.enum_declaration import EnumDeclaration
5
4
  from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
6
5
  from classiq.interface.generator.types.struct_declaration import StructDeclaration
7
- from classiq.interface.model.native_function_definition import NativeFunctionDefinition
6
+ from classiq.interface.model.native_function_definition import (
7
+ NativeFunctionDefinition,
8
+ )
8
9
 
9
10
 
10
11
  class ModelStateContainer:
11
- enum_decls: Dict[str, EnumDeclaration]
12
- type_decls: Dict[str, StructDeclaration]
13
- qstruct_decls: Dict[str, QStructDeclaration]
14
- native_defs: Dict[str, NativeFunctionDefinition]
15
- constants: Dict[str, Constant]
12
+ enum_decls: dict[str, EnumDeclaration]
13
+ type_decls: dict[str, StructDeclaration]
14
+ qstruct_decls: dict[str, QStructDeclaration]
15
+ native_defs: dict[str, NativeFunctionDefinition]
16
+ constants: dict[str, Constant]
17
+ functions_compilation_metadata: dict[str, CompilationMetadata]
16
18
 
17
19
 
18
20
  QMODULE = ModelStateContainer()
@@ -1,9 +1,7 @@
1
- from typing import List
2
-
3
1
  from .pretty_printer import DSLPrettyPrinter
4
2
 
5
3
  __all__ = ["DSLPrettyPrinter"]
6
4
 
7
5
 
8
- def __dir__() -> List[str]:
6
+ def __dir__() -> list[str]:
9
7
  return __all__
@@ -1,14 +1,15 @@
1
1
  import ast
2
2
  import re
3
+ from collections.abc import Mapping
3
4
  from dataclasses import dataclass
4
- from typing import Callable, Dict, List, Mapping, Optional, Type
5
+ from typing import Callable, Optional
5
6
 
6
7
  import numpy as np
7
8
 
8
9
  from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
9
10
 
10
11
  IDENTIFIER = re.compile(r"[a-zA-Z_]\w*")
11
- BINARY_OPS: Mapping[Type[ast.operator], str] = {
12
+ BINARY_OPS: Mapping[type[ast.operator], str] = {
12
13
  ast.Add: "+",
13
14
  ast.Sub: "-",
14
15
  ast.Mult: "*",
@@ -21,14 +22,14 @@ BINARY_OPS: Mapping[Type[ast.operator], str] = {
21
22
  ast.LShift: "<<",
22
23
  ast.RShift: ">>",
23
24
  }
24
- BOOL_OPS: Mapping[Type[ast.boolop], str] = {ast.And: "and", ast.Or: "or"}
25
- UNARY_OPS: Mapping[Type[ast.unaryop], str] = {
25
+ BOOL_OPS: Mapping[type[ast.boolop], str] = {ast.And: "and", ast.Or: "or"}
26
+ UNARY_OPS: Mapping[type[ast.unaryop], str] = {
26
27
  ast.UAdd: "+",
27
28
  ast.USub: "-",
28
29
  ast.Invert: "~",
29
30
  ast.Not: "not",
30
31
  }
31
- COMPARE_OPS: Mapping[Type[ast.cmpop], str] = {
32
+ COMPARE_OPS: Mapping[type[ast.cmpop], str] = {
32
33
  ast.Eq: "==",
33
34
  ast.NotEq: "!=",
34
35
  ast.Lt: "<",
@@ -139,7 +140,7 @@ class ASTToQMODCode:
139
140
  else:
140
141
  raise AssertionError("Error parsing expression: unsupported AST node.")
141
142
 
142
- def indent_items(self, items: Callable[[], List[str]]) -> str:
143
+ def indent_items(self, items: Callable[[], list[str]]) -> str:
143
144
  should_indent = (
144
145
  len("".join([i.strip() for i in items()])) >= LIST_FORMAT_CHAR_LIMIT
145
146
  )
@@ -165,8 +166,8 @@ class ASTToQMODCode:
165
166
  def _remove_redundant_parentheses(expr: str) -> str:
166
167
  if not (expr.startswith("(") and expr.endswith(")")):
167
168
  return expr
168
- parentheses_map: Dict[int, int] = dict()
169
- stack: List[int] = []
169
+ parentheses_map: dict[int, int] = dict()
170
+ stack: list[int] = []
170
171
  for index, char in enumerate(expr):
171
172
  if char == "(":
172
173
  stack.append(index)
@@ -1,4 +1,5 @@
1
- from typing import Dict, List, Mapping, Optional, Union
1
+ from collections.abc import Mapping
2
+ from typing import Optional, Union
2
3
 
3
4
  from classiq.interface.generator.constant import Constant
4
5
  from classiq.interface.generator.expressions.expression import Expression
@@ -135,7 +136,7 @@ class DSLPrettyPrinter(Visitor):
135
136
  def visit_EnumDeclaration(self, enum_decl: EnumDeclaration) -> str:
136
137
  return f"enum {enum_decl.name} {{\n{self._visit_members(enum_decl.members)}}}\n"
137
138
 
138
- def _visit_members(self, members: Dict[str, int]) -> str:
139
+ def _visit_members(self, members: dict[str, int]) -> str:
139
140
  self._level += 1
140
141
  members_str = "".join(
141
142
  f"{self._indent}{self.visit(member_name)} = {member_value};\n"
@@ -252,7 +253,12 @@ class DSLPrettyPrinter(Visitor):
252
253
  def visit_Control(self, op: Control) -> str:
253
254
  control = f"{self._indent}control ({self.visit(op.expression)}) {{\n"
254
255
  control += self._visit_body(op.body)
255
- control += f"{self._indent}}}\n"
256
+ control += f"{self._indent}}}"
257
+ if op.else_block is not None:
258
+ control += " else {\n"
259
+ control += self._visit_body(op.else_block)
260
+ control += f"{self._indent}}}"
261
+ control += "\n"
256
262
  return control
257
263
 
258
264
  def visit_PhaseOperation(self, op: PhaseOperation) -> str:
@@ -310,7 +316,7 @@ class DSLPrettyPrinter(Visitor):
310
316
  def visit_InplaceBinaryOperation(self, op: InplaceBinaryOperation) -> str:
311
317
  return f"{self._indent}{op.operation.value}({self.visit(op.value)}, {self.visit(op.target)});\n"
312
318
 
313
- def _visit_pack_expr(self, vars: List[HandleBinding]) -> str:
319
+ def _visit_pack_expr(self, vars: list[HandleBinding]) -> str:
314
320
  if len(vars) == 1:
315
321
  return self.visit(vars[0])
316
322
 
@@ -324,7 +330,7 @@ class DSLPrettyPrinter(Visitor):
324
330
 
325
331
  def visit_QuantumLambdaFunction(self, qlambda: QuantumLambdaFunction) -> str:
326
332
  positional_args = ", ".join(
327
- qlambda.get_rename_params()[idx]
333
+ qlambda.pos_rename_params[idx]
328
334
  for idx, arg_decl in enumerate(
329
335
  qlambda.func_decl.positional_arg_declarations
330
336
  )
@@ -358,7 +364,7 @@ class DSLPrettyPrinter(Visitor):
358
364
  ) -> str:
359
365
  return f"{self._indent}{self.visit(amplitude_loading_op.result_var)} *= {self.visit(amplitude_loading_op.expression)};\n"
360
366
 
361
- def _print_bind_handles(self, handles: List[HandleBinding]) -> str:
367
+ def _print_bind_handles(self, handles: list[HandleBinding]) -> str:
362
368
  if len(handles) == 1:
363
369
  return self.visit(handles[0])
364
370
 
@@ -1,9 +1,7 @@
1
- from typing import List
2
-
3
1
  from .pretty_printer import PythonPrettyPrinter
4
2
 
5
3
  __all__ = ["PythonPrettyPrinter"]
6
4
 
7
5
 
8
- def __dir__() -> List[str]:
6
+ def __dir__() -> list[str]:
9
7
  return __all__
@@ -1,7 +1,8 @@
1
1
  import ast
2
2
  import re
3
+ from collections.abc import Mapping
3
4
  from dataclasses import dataclass
4
- from typing import Callable, Dict, List, Mapping, Type
5
+ from typing import Callable
5
6
 
6
7
  import numpy as np
7
8
 
@@ -9,7 +10,7 @@ import classiq
9
10
  from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
10
11
 
11
12
  IDENTIFIER = re.compile(r"[a-zA-Z_]\w*")
12
- BINARY_OPS: Mapping[Type[ast.operator], str] = {
13
+ BINARY_OPS: Mapping[type[ast.operator], str] = {
13
14
  ast.Add: "+",
14
15
  ast.Sub: "-",
15
16
  ast.Mult: "*",
@@ -22,14 +23,14 @@ BINARY_OPS: Mapping[Type[ast.operator], str] = {
22
23
  ast.LShift: "<<",
23
24
  ast.RShift: ">>",
24
25
  }
25
- BOOL_OPS: Mapping[Type[ast.boolop], str] = {ast.And: "and", ast.Or: "or"}
26
- UNARY_OPS: Mapping[Type[ast.unaryop], str] = {
26
+ BOOL_OPS: Mapping[type[ast.boolop], str] = {ast.And: "and", ast.Or: "or"}
27
+ UNARY_OPS: Mapping[type[ast.unaryop], str] = {
27
28
  ast.UAdd: "+",
28
29
  ast.USub: "-",
29
30
  ast.Invert: "~",
30
31
  ast.Not: "not",
31
32
  }
32
- COMPARE_OPS: Mapping[Type[ast.cmpop], str] = {
33
+ COMPARE_OPS: Mapping[type[ast.cmpop], str] = {
33
34
  ast.Eq: "==",
34
35
  ast.NotEq: "!=",
35
36
  ast.Lt: "<",
@@ -43,8 +44,8 @@ LIST_FORMAT_CHAR_LIMIT = 20
43
44
  @dataclass
44
45
  class ASTToQMODCode(ast.NodeVisitor):
45
46
  level: int
46
- imports: Dict[str, int]
47
- symbolic_imports: Dict[str, int]
47
+ imports: dict[str, int]
48
+ symbolic_imports: dict[str, int]
48
49
  decimal_precision: int
49
50
  indent_seq: str = " "
50
51
 
@@ -162,7 +163,7 @@ class ASTToQMODCode(ast.NodeVisitor):
162
163
  def generic_visit(self, node: ast.AST) -> None:
163
164
  raise AssertionError("Cannot parse node of type: " + type(node).__name__)
164
165
 
165
- def indent_items(self, items: Callable[[], List[str]]) -> str:
166
+ def indent_items(self, items: Callable[[], list[str]]) -> str:
166
167
  should_indent = (
167
168
  len("".join([i.strip() for i in items()])) >= LIST_FORMAT_CHAR_LIMIT
168
169
  )
@@ -188,8 +189,8 @@ class ASTToQMODCode(ast.NodeVisitor):
188
189
  def _remove_redundant_parentheses(expr: str) -> str:
189
190
  if not (expr.startswith("(") and expr.endswith(")")):
190
191
  return expr
191
- parentheses_map: Dict[int, int] = dict()
192
- stack: List[int] = []
192
+ parentheses_map: dict[int, int] = dict()
193
+ stack: list[int] = []
193
194
  for index, char in enumerate(expr):
194
195
  if char == "(":
195
196
  stack.append(index)
@@ -208,8 +209,8 @@ def _remove_redundant_parentheses(expr: str) -> str:
208
209
 
209
210
  def transform_expression(
210
211
  expr: str,
211
- imports: Dict[str, int],
212
- symbolic_imports: Dict[str, int],
212
+ imports: dict[str, int],
213
+ symbolic_imports: dict[str, int],
213
214
  level: int = 0,
214
215
  decimal_precision: int = DEFAULT_DECIMAL_PRECISION,
215
216
  ) -> str:
@@ -1,4 +1,5 @@
1
- from typing import Dict, List, Mapping, Optional, Tuple, Union, cast
1
+ from collections.abc import Mapping
2
+ from typing import Optional, Union, cast
2
3
 
3
4
  import black
4
5
 
@@ -49,9 +50,6 @@ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
49
50
  ArithmeticOperation,
50
51
  ArithmeticOperationKind,
51
52
  )
52
- from classiq.interface.model.quantum_expressions.quantum_expression import (
53
- QuantumAssignmentOperation,
54
- )
55
53
  from classiq.interface.model.quantum_function_call import (
56
54
  OperandIdentifier,
57
55
  QuantumFunctionCall,
@@ -88,20 +86,20 @@ class VariableDeclarationAssignment(Visitor):
88
86
  def __init__(self, pretty_printer: "PythonPrettyPrinter") -> None:
89
87
  self.pretty_printer = pretty_printer
90
88
 
91
- def visit(self, node: NodeType) -> Tuple[str, Optional[List[str]]]:
89
+ def visit(self, node: NodeType) -> tuple[str, Optional[list[str]]]:
92
90
  res = super().visit(node)
93
91
  if not isinstance(res, tuple):
94
92
  raise AssertionError(f"Pretty printing for {type(node)} is not supported ")
95
93
  return res # type: ignore[return-value]
96
94
 
97
- def visit_QuantumBit(self, qtype: QuantumBit) -> Tuple[str, Optional[List[str]]]:
95
+ def visit_QuantumBit(self, qtype: QuantumBit) -> tuple[str, Optional[list[str]]]:
98
96
  self.pretty_printer._imports["QBit"] = 1
99
97
 
100
98
  return "QBit", None
101
99
 
102
100
  def visit_QuantumBitvector(
103
101
  self, qtype: QuantumBitvector
104
- ) -> Tuple[str, Optional[List[str]]]:
102
+ ) -> tuple[str, Optional[list[str]]]:
105
103
  self.pretty_printer._imports["QArray"] = 1
106
104
 
107
105
  element_type = self.pretty_printer.visit(qtype.element_type)
@@ -111,7 +109,7 @@ class VariableDeclarationAssignment(Visitor):
111
109
 
112
110
  def visit_QuantumNumeric(
113
111
  self, qtype: QuantumNumeric
114
- ) -> Tuple[str, Optional[List[str]]]:
112
+ ) -> tuple[str, Optional[list[str]]]:
115
113
  self.pretty_printer._imports["QNum"] = 1
116
114
 
117
115
  params = []
@@ -124,7 +122,7 @@ class VariableDeclarationAssignment(Visitor):
124
122
 
125
123
  return "QNum", params
126
124
 
127
- def visit_TypeName(self, qtype: TypeName) -> Tuple[str, None]:
125
+ def visit_TypeName(self, qtype: TypeName) -> tuple[str, None]:
128
126
  return qtype.name, None
129
127
 
130
128
 
@@ -136,7 +134,7 @@ class PythonPrettyPrinter(Visitor):
136
134
  self._import_enum = False
137
135
  self._import_dataclass = False
138
136
  self._import_annotated = False
139
- self._symbolic_imports: Dict[str, int] = dict()
137
+ self._symbolic_imports: dict[str, int] = dict()
140
138
  self._functions: Optional[Mapping[str, QuantumFunctionDeclaration]] = None
141
139
 
142
140
  def visit(self, node: NodeType) -> str:
@@ -183,7 +181,7 @@ class PythonPrettyPrinter(Visitor):
183
181
  def special_imports(self) -> str:
184
182
  imports = ""
185
183
  if self._import_annotated:
186
- imports += "from typing_extensions import Annotated\n"
184
+ imports += "from typing import Annotated\n"
187
185
  if self._import_dataclass:
188
186
  imports += "from dataclasses import dataclass\n"
189
187
  if self._import_enum:
@@ -214,7 +212,7 @@ class PythonPrettyPrinter(Visitor):
214
212
  self._import_enum = True
215
213
  return f"class {enum_decl.name}(IntEnum):\n{self._visit_members(enum_decl.members)}\n"
216
214
 
217
- def _visit_members(self, members: Dict[str, int]) -> str:
215
+ def _visit_members(self, members: dict[str, int]) -> str:
218
216
  self._level += 1
219
217
  members_str = "".join(
220
218
  f"{self._indent}{self.visit(member_name)} = {member_value}\n"
@@ -390,7 +388,10 @@ class PythonPrettyPrinter(Visitor):
390
388
 
391
389
  def visit_Control(self, op: Control) -> str:
392
390
  self._imports["control"] = 1
393
- return f"{self._indent}control({self.visit(op.expression)}, {self._visit_body(op.body)})\n"
391
+ control_else = (
392
+ f", {self._visit_body(op.else_block)}" if op.else_block is not None else ""
393
+ )
394
+ return f"{self._indent}control({self.visit(op.expression)}, {self._visit_body(op.body)}{control_else})\n"
394
395
 
395
396
  def visit_PhaseOperation(self, op: PhaseOperation) -> str:
396
397
  self._imports["phase"] = 1
@@ -418,7 +419,7 @@ class PythonPrettyPrinter(Visitor):
418
419
  return f"{self._indent}invert({self._visit_body(invert.body)})\n"
419
420
 
420
421
  def _visit_body(
421
- self, body: StatementBlock, operand_arguments: Optional[List[str]] = None
422
+ self, body: StatementBlock, operand_arguments: Optional[list[str]] = None
422
423
  ) -> str:
423
424
  if len(body) == 0:
424
425
  return "lambda: []"
@@ -428,13 +429,16 @@ class PythonPrettyPrinter(Visitor):
428
429
  code = f"lambda{argument_string}: {'[' if len(body) > 1 else ''}\n"
429
430
  self._level += 1
430
431
  for i, statement in enumerate(body):
431
- if isinstance(
432
- statement, (QuantumAssignmentOperation, VariableDeclarationStatement)
433
- ):
432
+ if isinstance(statement, VariableDeclarationStatement):
434
433
  raise AssertionError(
435
- "pretty printing quantum assignment operations or variable declaration statements in quantum lambda function is unsupported."
434
+ "pretty printing variable declaration statements in quantum lambda function is unsupported."
436
435
  )
437
- code += self.visit(statement)
436
+ if isinstance(statement, AmplitudeLoadingOperation):
437
+ code += self.visit_AmplitudeLoadingOperation(statement, in_lambda=True)
438
+ elif isinstance(statement, ArithmeticOperation):
439
+ code += self.visit_ArithmeticOperation(statement, in_lambda=True)
440
+ else:
441
+ code += self.visit(statement)
438
442
  if i < len(body) - 1:
439
443
  code += ","
440
444
  self._level -= 1
@@ -454,7 +458,7 @@ class PythonPrettyPrinter(Visitor):
454
458
  )
455
459
 
456
460
  def visit_QuantumLambdaFunction(self, qlambda: QuantumLambdaFunction) -> str:
457
- return self._visit_body(qlambda.body, qlambda.get_rename_params())
461
+ return self._visit_body(qlambda.body, qlambda.pos_rename_params)
458
462
 
459
463
  def visit_HandleBinding(self, var_ref: HandleBinding) -> str:
460
464
  return var_ref.name
@@ -468,21 +472,32 @@ class PythonPrettyPrinter(Visitor):
468
472
  def visit_FieldHandleBinding(self, var_ref: FieldHandleBinding) -> str:
469
473
  return f"{self.visit(var_ref.base_handle)}.{self.visit(var_ref.field)}"
470
474
 
471
- def visit_ArithmeticOperation(self, arith_op: ArithmeticOperation) -> str:
475
+ def visit_ArithmeticOperation(
476
+ self, arith_op: ArithmeticOperation, in_lambda: bool = False
477
+ ) -> str:
472
478
  if arith_op.operation_kind == ArithmeticOperationKind.Assignment:
473
479
  op = "|="
480
+ func = "assign"
474
481
  elif arith_op.operation_kind == ArithmeticOperationKind.InplaceXor:
475
482
  op = "^="
483
+ func = "inplace_xor"
476
484
  else:
477
485
  op = "+="
486
+ func = "inplace_add"
487
+ if in_lambda:
488
+ self._imports[func] = 1
489
+ return f"{func}({self.visit(arith_op.expression)}, {self._indent}{self.visit(arith_op.result_var)})\n"
478
490
  return f"{self._indent}{self.visit(arith_op.result_var)} {op} {self.visit(arith_op.expression)}\n"
479
491
 
480
492
  def visit_AmplitudeLoadingOperation(
481
- self, amplitude_loading_op: AmplitudeLoadingOperation
493
+ self, amplitude_loading_op: AmplitudeLoadingOperation, in_lambda: bool = False
482
494
  ) -> str:
495
+ if in_lambda:
496
+ self._imports["assign_amplitude"] = 1
497
+ return f"assign_amplitude({self.visit(amplitude_loading_op.expression)}, {self._indent}{self.visit(amplitude_loading_op.result_var)})\n"
483
498
  return f"{self._indent}{self.visit(amplitude_loading_op.result_var)} *= {self.visit(amplitude_loading_op.expression)}\n"
484
499
 
485
- def _print_bind_handles(self, handles: List[HandleBinding]) -> str:
500
+ def _print_bind_handles(self, handles: list[HandleBinding]) -> str:
486
501
  if len(handles) == 1:
487
502
  return self.visit(handles[0])
488
503
 
@@ -26,6 +26,11 @@ if sys.version_info[0:2] >= (3, 9):
26
26
  pass
27
27
  from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
28
28
 
29
+ CARRAY_ERROR_MESSAGE = (
30
+ "CArray accepts one or two generic parameters in the form "
31
+ "`CArray[<element-type>]` or `CArray[<element-type>, <size>]`"
32
+ )
33
+
29
34
 
30
35
  class PythonClassicalType:
31
36
  def convert(self, py_type: type) -> Optional[ConcreteClassicalType]:
@@ -48,16 +53,15 @@ class PythonClassicalType:
48
53
  element_type=self.convert(array_args[0]),
49
54
  size=get_type_hint_expr(array_args[1]),
50
55
  )
51
- raise ClassiqValueError(
52
- "CArray accepts one or two generic parameters in the form "
53
- "`CArray[<element-type>]` or `CArray[<element-type>, <size>]`"
54
- )
56
+ raise ClassiqValueError(CARRAY_ERROR_MESSAGE)
55
57
  elif inspect.isclass(py_type) and dataclasses.is_dataclass(py_type):
56
58
  self.register_struct(py_type)
57
59
  return Struct(name=py_type.__name__)
58
60
  elif inspect.isclass(py_type) and isinstance(py_type, EnumMeta):
59
61
  self.register_enum(py_type)
60
62
  return Enum(name=py_type.__name__)
63
+ elif py_type in (CArray, list):
64
+ raise ClassiqValueError(CARRAY_ERROR_MESSAGE)
61
65
  return None
62
66
 
63
67
  def register_struct(self, py_type: type) -> None:
classiq/qmod/qfunc.py CHANGED
@@ -1,14 +1,14 @@
1
- from typing import Callable, List, Literal, Optional, Union, overload
1
+ from typing import Callable, Literal, Optional, Union, overload
2
2
 
3
3
  from classiq.qmod.quantum_callable import QCallable
4
4
  from classiq.qmod.quantum_function import ExternalQFunc, GenerativeQFunc, QFunc
5
5
 
6
- GEN_QFUNCS: List[GenerativeQFunc] = []
7
- DEC_QFUNCS: List[QFunc] = []
6
+ GEN_QFUNCS: list[GenerativeQFunc] = []
7
+ DEC_QFUNCS: list[QFunc] = []
8
8
 
9
9
 
10
10
  def set_discovered_functions(
11
- dec_funcs: List[QFunc], gen_funcs: List[GenerativeQFunc]
11
+ dec_funcs: list[QFunc], gen_funcs: list[GenerativeQFunc]
12
12
  ) -> None:
13
13
  DEC_QFUNCS.clear()
14
14
  DEC_QFUNCS.extend(dec_funcs)