classiq 0.51.0__py3-none-any.whl → 0.52.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 (150) hide show
  1. classiq/_internals/api_wrapper.py +41 -15
  2. classiq/_internals/authentication/auth0.py +20 -4
  3. classiq/_internals/authentication/password_manager.py +16 -4
  4. classiq/_internals/client.py +2 -2
  5. classiq/_internals/host_checker.py +5 -3
  6. classiq/_internals/jobs.py +3 -3
  7. classiq/analyzer/analyzer_utilities.py +1 -1
  8. classiq/applications/chemistry/ground_state_problem.py +1 -1
  9. classiq/applications/combinatorial_helpers/pyomo_utils.py +3 -1
  10. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  11. classiq/applications/qnn/qlayer.py +2 -2
  12. classiq/execution/__init__.py +3 -0
  13. classiq/execution/execution_session.py +2 -2
  14. classiq/execution/iqcc.py +63 -0
  15. classiq/execution/jobs.py +2 -2
  16. classiq/executor.py +2 -2
  17. classiq/interface/_version.py +1 -1
  18. classiq/interface/analyzer/analysis_params.py +19 -9
  19. classiq/interface/analyzer/cytoscape_graph.py +10 -3
  20. classiq/interface/analyzer/result.py +6 -5
  21. classiq/interface/applications/qsvm.py +13 -12
  22. classiq/interface/backend/backend_preferences.py +78 -105
  23. classiq/interface/backend/ionq/ionq_quantum_program.py +12 -19
  24. classiq/interface/backend/pydantic_backend.py +24 -12
  25. classiq/interface/backend/quantum_backend_providers.py +2 -0
  26. classiq/interface/chemistry/fermionic_operator.py +7 -7
  27. classiq/interface/chemistry/ground_state_problem.py +23 -18
  28. classiq/interface/chemistry/molecule.py +10 -5
  29. classiq/interface/chemistry/operator.py +71 -44
  30. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +2 -1
  31. classiq/interface/debug_info/debug_info.py +3 -4
  32. classiq/interface/execution/iqcc.py +21 -0
  33. classiq/interface/execution/jobs.py +10 -10
  34. classiq/interface/executor/aws_execution_cost.py +37 -20
  35. classiq/interface/executor/execution_preferences.py +1 -2
  36. classiq/interface/executor/execution_request.py +2 -2
  37. classiq/interface/executor/execution_result.py +4 -2
  38. classiq/interface/executor/iqae_result.py +1 -1
  39. classiq/interface/executor/optimizer_preferences.py +14 -10
  40. classiq/interface/executor/quantum_code.py +21 -16
  41. classiq/interface/executor/register_initialization.py +10 -10
  42. classiq/interface/executor/result.py +19 -16
  43. classiq/interface/executor/vqe_result.py +1 -1
  44. classiq/interface/finance/function_input.py +27 -18
  45. classiq/interface/finance/log_normal_model_input.py +2 -2
  46. classiq/interface/finance/model_input.py +3 -2
  47. classiq/interface/generator/amplitude_loading.py +8 -6
  48. classiq/interface/generator/arith/argument_utils.py +24 -0
  49. classiq/interface/generator/arith/arithmetic.py +5 -3
  50. classiq/interface/generator/arith/arithmetic_expression_abc.py +36 -14
  51. classiq/interface/generator/arith/arithmetic_operations.py +6 -3
  52. classiq/interface/generator/arith/binary_ops.py +88 -63
  53. classiq/interface/generator/arith/extremum_operations.py +22 -13
  54. classiq/interface/generator/arith/logical_ops.py +6 -4
  55. classiq/interface/generator/arith/number_utils.py +3 -3
  56. classiq/interface/generator/arith/register_user_input.py +32 -17
  57. classiq/interface/generator/arith/unary_ops.py +5 -4
  58. classiq/interface/generator/chemistry_function_params.py +2 -1
  59. classiq/interface/generator/circuit_code/circuit_code.py +2 -1
  60. classiq/interface/generator/commuting_pauli_exponentiation.py +6 -5
  61. classiq/interface/generator/complex_type.py +14 -18
  62. classiq/interface/generator/control_state.py +32 -26
  63. classiq/interface/generator/expressions/expression.py +6 -5
  64. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +3 -3
  65. classiq/interface/generator/function_params.py +22 -39
  66. classiq/interface/generator/functions/classical_function_declaration.py +1 -1
  67. classiq/interface/generator/functions/classical_type.py +32 -23
  68. classiq/interface/generator/functions/concrete_types.py +8 -7
  69. classiq/interface/generator/functions/function_declaration.py +4 -5
  70. classiq/interface/generator/functions/type_name.py +5 -4
  71. classiq/interface/generator/generated_circuit_data.py +9 -6
  72. classiq/interface/generator/grover_diffuser.py +26 -18
  73. classiq/interface/generator/grover_operator.py +32 -22
  74. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +3 -4
  75. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  76. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +8 -7
  77. classiq/interface/generator/hardware/hardware_data.py +27 -26
  78. classiq/interface/generator/hardware_efficient_ansatz.py +11 -6
  79. classiq/interface/generator/hartree_fock.py +2 -1
  80. classiq/interface/generator/identity.py +7 -2
  81. classiq/interface/generator/linear_pauli_rotations.py +27 -14
  82. classiq/interface/generator/mcu.py +15 -12
  83. classiq/interface/generator/mcx.py +18 -10
  84. classiq/interface/generator/model/constraints.py +4 -2
  85. classiq/interface/generator/model/model.py +2 -1
  86. classiq/interface/generator/model/preferences/preferences.py +30 -32
  87. classiq/interface/generator/oracles/custom_oracle.py +13 -10
  88. classiq/interface/generator/piecewise_linear_amplitude_loading.py +37 -21
  89. classiq/interface/generator/qpe.py +38 -26
  90. classiq/interface/generator/qsvm.py +4 -4
  91. classiq/interface/generator/quantum_function_call.py +57 -44
  92. classiq/interface/generator/quantum_program.py +8 -6
  93. classiq/interface/generator/range_types.py +10 -11
  94. classiq/interface/generator/standard_gates/controlled_standard_gates.py +9 -5
  95. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  96. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  97. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  98. classiq/interface/generator/state_preparation/distributions.py +12 -12
  99. classiq/interface/generator/state_preparation/state_preparation.py +22 -16
  100. classiq/interface/generator/types/enum_declaration.py +2 -1
  101. classiq/interface/generator/ucc.py +2 -1
  102. classiq/interface/generator/unitary_gate.py +2 -1
  103. classiq/interface/generator/user_defined_function_params.py +3 -0
  104. classiq/interface/generator/visitor.py +1 -1
  105. classiq/interface/hardware.py +18 -3
  106. classiq/interface/helpers/custom_pydantic_types.py +38 -47
  107. classiq/interface/helpers/pydantic_model_helpers.py +3 -2
  108. classiq/interface/helpers/versioned_model.py +1 -4
  109. classiq/interface/ide/ide_data.py +5 -5
  110. classiq/interface/ide/visual_model.py +5 -5
  111. classiq/interface/interface_version.py +1 -1
  112. classiq/interface/jobs.py +12 -22
  113. classiq/interface/model/bind_operation.py +2 -1
  114. classiq/interface/model/classical_parameter_declaration.py +10 -4
  115. classiq/interface/model/handle_binding.py +20 -24
  116. classiq/interface/model/inplace_binary_operation.py +16 -9
  117. classiq/interface/model/model.py +21 -11
  118. classiq/interface/model/port_declaration.py +10 -7
  119. classiq/interface/model/quantum_expressions/arithmetic_operation.py +6 -4
  120. classiq/interface/model/quantum_function_declaration.py +22 -11
  121. classiq/interface/model/quantum_statement.py +6 -7
  122. classiq/interface/model/quantum_type.py +22 -19
  123. classiq/interface/model/statement_block.py +9 -9
  124. classiq/interface/server/global_versions.py +4 -5
  125. classiq/interface/server/routes.py +8 -0
  126. classiq/model_expansions/evaluators/parameter_types.py +3 -3
  127. classiq/model_expansions/expression_renamer.py +1 -1
  128. classiq/model_expansions/quantum_operations/control.py +11 -12
  129. classiq/model_expansions/quantum_operations/emitter.py +22 -0
  130. classiq/model_expansions/quantum_operations/expression_operation.py +2 -20
  131. classiq/model_expansions/quantum_operations/inplace_binary_operation.py +65 -14
  132. classiq/model_expansions/quantum_operations/invert.py +1 -1
  133. classiq/model_expansions/quantum_operations/phase.py +4 -5
  134. classiq/model_expansions/quantum_operations/power.py +1 -1
  135. classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +50 -9
  136. classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
  137. classiq/model_expansions/quantum_operations/within_apply.py +1 -1
  138. classiq/qmod/builtins/__init__.py +1 -3
  139. classiq/qmod/builtins/functions/__init__.py +4 -0
  140. classiq/qmod/builtins/functions/arithmetic.py +10 -0
  141. classiq/qmod/create_model_function.py +14 -8
  142. classiq/qmod/quantum_expandable.py +22 -9
  143. classiq/qmod/quantum_function.py +1 -1
  144. classiq/qmod/semantics/static_semantics_visitor.py +3 -1
  145. classiq/qmod/type_attribute_remover.py +1 -1
  146. classiq/qmod/write_qmod.py +2 -4
  147. classiq/synthesis.py +11 -13
  148. {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/METADATA +3 -2
  149. {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/RECORD +150 -148
  150. {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/WHEEL +0 -0
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from typing import Any, Dict
4
4
 
5
5
  import pydantic
6
- from pydantic import BaseModel
6
+ from pydantic import BaseModel, ConfigDict
7
7
 
8
8
  from classiq.interface.exceptions import ClassiqValueError
9
9
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
@@ -18,45 +18,52 @@ class ControlState(BaseModel):
18
18
  default=_DEFAULT_NUM_CONTROL_QUBITS, description="Number of control qubits"
19
19
  )
20
20
  ctrl_state: str = pydantic.Field(
21
- default=_INVALID_CONTROL_STATE, description="Control state string"
21
+ default=_INVALID_CONTROL_STATE,
22
+ description="Control state string",
23
+ validate_default=True,
24
+ )
25
+ name: str = pydantic.Field(
26
+ default=_DEFAULT_CONTROL_NAME, description="Control name"
22
27
  )
23
- name: str = pydantic.Field(default=None, description="Control name")
24
28
 
25
- @pydantic.root_validator()
26
- def _validate_control(cls, values: Dict[str, Any]) -> Dict[str, Any]:
27
- num_ctrl_qubits: int = values.get(
28
- "num_ctrl_qubits", _DEFAULT_NUM_CONTROL_QUBITS
29
- )
30
- ctrl_state: str = values.get("ctrl_state", _INVALID_CONTROL_STATE)
29
+ @pydantic.model_validator(mode="before")
30
+ @classmethod
31
+ def _validate_control(cls, values: Any) -> Dict[str, Any]:
32
+ if isinstance(values, dict):
33
+ num_ctrl_qubits: int = (
34
+ values.get("num_ctrl_qubits", _DEFAULT_NUM_CONTROL_QUBITS) or 0
35
+ )
31
36
 
32
- if ctrl_state == _INVALID_CONTROL_STATE:
33
- ctrl_state = "1" * num_ctrl_qubits
34
- values["ctrl_state"] = ctrl_state
37
+ ctrl_state: str = values.get("ctrl_state") or _INVALID_CONTROL_STATE
35
38
 
36
- cls.validate_control_string(ctrl_state)
39
+ if ctrl_state == _INVALID_CONTROL_STATE:
40
+ ctrl_state = "1" * num_ctrl_qubits
41
+ values["ctrl_state"] = ctrl_state
37
42
 
38
- if num_ctrl_qubits == _DEFAULT_NUM_CONTROL_QUBITS:
39
- num_ctrl_qubits = len(ctrl_state)
40
- values["num_ctrl_qubits"] = num_ctrl_qubits
43
+ cls.validate_control_string(ctrl_state)
41
44
 
42
- if len(ctrl_state) != num_ctrl_qubits:
43
- raise ClassiqValueError(
44
- "Control state length should be equal to the number of control qubits"
45
- )
45
+ if num_ctrl_qubits == _DEFAULT_NUM_CONTROL_QUBITS:
46
+ num_ctrl_qubits = len(ctrl_state)
47
+ values["num_ctrl_qubits"] = num_ctrl_qubits
48
+
49
+ if len(ctrl_state) != num_ctrl_qubits:
50
+ raise ClassiqValueError(
51
+ "Control state length should be equal to the number of control qubits"
52
+ )
46
53
 
47
- if values.get("name") is None:
48
- values["name"] = f"{_DEFAULT_CONTROL_NAME}_{ctrl_state}"
54
+ if "name" not in values or values["name"] is None:
55
+ values["name"] = f"{_DEFAULT_CONTROL_NAME}_{ctrl_state}"
49
56
 
50
57
  return values
51
58
 
52
59
  @staticmethod
53
60
  def validate_control_string(ctrl_state: str) -> None:
61
+ if not ctrl_state:
62
+ raise ClassiqValueError("Control state cannot be empty")
54
63
  if not set(ctrl_state) <= {"1", "0"}:
55
64
  raise ClassiqValueError(
56
65
  f"Control state can only be constructed from 0 and 1, received: {ctrl_state}"
57
66
  )
58
- if not ctrl_state:
59
- raise ClassiqValueError("Control state cannot be empty")
60
67
 
61
68
  def __str__(self) -> str:
62
69
  return self.ctrl_state
@@ -71,5 +78,4 @@ class ControlState(BaseModel):
71
78
  def rename(self, name: str) -> ControlState:
72
79
  return ControlState(ctrl_state=self.ctrl_state, name=name)
73
80
 
74
- class Config:
75
- frozen = True
81
+ model_config = ConfigDict(frozen=True)
@@ -3,7 +3,7 @@ import sys
3
3
  from typing import Any, Mapping, Optional, Type
4
4
 
5
5
  import pydantic
6
- from pydantic import PrivateAttr
6
+ from pydantic import ConfigDict, PrivateAttr
7
7
 
8
8
  from classiq.interface.ast_node import HashableASTNode
9
9
  from classiq.interface.exceptions import ClassiqError
@@ -31,7 +31,8 @@ class Expression(HashableASTNode):
31
31
 
32
32
  self._try_to_immediate_evaluate()
33
33
 
34
- @pydantic.validator("expr")
34
+ @pydantic.field_validator("expr")
35
+ @classmethod
35
36
  def validate_expression(cls, expr: str) -> str:
36
37
  supported_functions = (
37
38
  SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS_QMOD
@@ -41,7 +42,8 @@ class Expression(HashableASTNode):
41
42
  validate_expression_str(expr, supported_functions=supported_functions)
42
43
  return expr
43
44
 
44
- @pydantic.validator("expr")
45
+ @pydantic.field_validator("expr")
46
+ @classmethod
45
47
  def format_expression(cls, expr: str) -> str:
46
48
  if sys.version_info >= (3, 9):
47
49
  expr = ast.unparse(ast.parse(expr))
@@ -97,8 +99,7 @@ class Expression(HashableASTNode):
97
99
  def is_constant(self) -> bool:
98
100
  return self.value.is_constant()
99
101
 
100
- class Config:
101
- frozen = True
102
+ model_config = ConfigDict(frozen=True)
102
103
 
103
104
  def __str__(self) -> str:
104
105
  return self.expr
@@ -29,10 +29,10 @@ class QmodQNumProxy(QmodQScalarProxy):
29
29
  self, handle: HandleBinding, size: int, fraction_digits: int, is_signed: bool
30
30
  ) -> None:
31
31
  super().__init__(handle, size)
32
- if fraction_digits + is_signed > size:
32
+ if fraction_digits > size:
33
33
  raise ClassiqValueError(
34
- f"{'Signed' if is_signed else 'Unsigned'} quantum numeric of size "
35
- f"{size} cannot have {fraction_digits} fraction digits"
34
+ f"Quantum numeric of size {size} cannot have {fraction_digits} "
35
+ f"fraction digits"
36
36
  )
37
37
  self._fraction_digits = fraction_digits
38
38
  self._is_signed = is_signed
@@ -17,7 +17,8 @@ from typing import (
17
17
 
18
18
  import pydantic
19
19
  import sympy
20
- from pydantic.fields import ModelField
20
+ from pydantic import BeforeValidator, ConfigDict
21
+ from typing_extensions import Annotated
21
22
 
22
23
  from classiq.interface.enum_utils import StrEnum
23
24
  from classiq.interface.exceptions import ClassiqValueError
@@ -25,6 +26,7 @@ from classiq.interface.generator.arith.arithmetic_expression_validator import (
25
26
  validate_expression,
26
27
  )
27
28
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
29
+ from classiq.interface.generator.parameters import ParameterFloatType
28
30
  from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
29
31
  from classiq.interface.helpers.hashable_pydantic_base_model import (
30
32
  HashablePydanticBaseModel,
@@ -126,6 +128,22 @@ def validate_expression_str(
126
128
  )
127
129
 
128
130
 
131
+ def validate_parameters(value: Any) -> Any:
132
+ if isinstance(value, str):
133
+ validate_expression_str(value)
134
+ elif isinstance(value, sympy.Expr):
135
+ return str(value)
136
+ try:
137
+ return float(value)
138
+ except ValueError:
139
+ return value
140
+
141
+
142
+ FunctionParamsNumericParameter = Annotated[
143
+ ParameterFloatType, BeforeValidator(validate_parameters)
144
+ ]
145
+
146
+
129
147
  class PortDirection(StrEnum):
130
148
  Input = "input"
131
149
  Output = "output"
@@ -197,20 +215,6 @@ class FunctionParams(HashablePydanticBaseModel):
197
215
  if self.discriminator() not in _UNVALIDATED_FUNCTIONS:
198
216
  self._validate_total_io_sizes()
199
217
 
200
- def is_field_param_type(self, name: str, param_type_signature: str) -> bool:
201
- f = type(self).__fields__[name]
202
- return isinstance(f, ModelField) and (
203
- param_type_signature in f.field_info.extra
204
- )
205
-
206
- def is_field_gen_param(self, name: str) -> bool:
207
- return self.is_field_param_type(
208
- name, "is_gen_param"
209
- ) or self.is_field_exec_param(name)
210
-
211
- def is_field_exec_param(self, name: str) -> bool:
212
- return self.is_field_param_type(name, "is_exec_param")
213
-
214
218
  def is_powerable(self, strict_zero_ios: bool = True) -> bool:
215
219
  input_names = set(self.inputs_full(strict_zero_ios))
216
220
  output_names = set(self._output_names)
@@ -261,28 +265,7 @@ class FunctionParams(HashablePydanticBaseModel):
261
265
  def discriminator(cls) -> FunctionParamsDiscriminator:
262
266
  return cls.__name__
263
267
 
264
- @property
265
- def _params(self) -> List[str]:
266
- return [
267
- name
268
- for name, field in self.__fields__.items()
269
- if field.field_info.extra.get("is_exec_param", False)
270
- ]
271
-
272
- @pydantic.validator("*", pre=True)
273
- def validate_parameters(cls, value: Any, field: pydantic.fields.ModelField) -> Any:
274
- if (
275
- "is_exec_param" in field.field_info.extra
276
- or "is_gen_param" in field.field_info.extra
277
- ):
278
- if isinstance(value, str):
279
- validate_expression_str(value)
280
- elif isinstance(value, sympy.Expr):
281
- return str(value)
282
- return value
283
-
284
- class Config:
285
- frozen = True
268
+ model_config = ConfigDict(frozen=True, extra="forbid")
286
269
 
287
270
 
288
271
  def parse_function_params(
@@ -306,12 +289,12 @@ def parse_function_params(
306
289
  if len(matching_classes) != 1:
307
290
  if default_parser_class is not None:
308
291
  try:
309
- return default_parser_class.parse_obj(params)
292
+ return default_parser_class.model_validate(params)
310
293
  except Exception:
311
294
  raise bad_function_error from None
312
295
  raise bad_function_error
313
296
 
314
- return matching_classes[0].parse_obj(params)
297
+ return matching_classes[0].model_validate(params)
315
298
 
316
299
 
317
300
  def parse_function_params_values(
@@ -40,4 +40,4 @@ class ClassicalFunctionDeclaration(FunctionDeclaration):
40
40
  return self.positional_parameters
41
41
 
42
42
 
43
- ClassicalFunctionDeclaration.update_forward_refs()
43
+ ClassicalFunctionDeclaration.model_rebuild()
@@ -1,7 +1,7 @@
1
1
  from typing import TYPE_CHECKING, Any, Dict, List, Literal, Union
2
2
 
3
3
  import pydantic
4
- from pydantic import Extra
4
+ from pydantic import ConfigDict
5
5
  from sympy import IndexedBase, Symbol
6
6
 
7
7
  from classiq.interface.ast_node import HashableASTNode
@@ -22,8 +22,7 @@ class ClassicalType(HashableASTNode):
22
22
  def as_symbolic(self, name: str) -> Union[NamedSymbol, List[NamedSymbol]]:
23
23
  return Symbol(name)
24
24
 
25
- class Config:
26
- extra = Extra.forbid
25
+ model_config = ConfigDict(extra="forbid")
27
26
 
28
27
  def __str__(self) -> str:
29
28
  return str(type(self).__name__)
@@ -35,8 +34,9 @@ class Integer(ClassicalType):
35
34
  def as_symbolic(self, name: str) -> Symbol:
36
35
  return Symbol(name, integer=True)
37
36
 
38
- @pydantic.root_validator(pre=True)
39
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
37
+ @pydantic.model_validator(mode="before")
38
+ @classmethod
39
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
40
40
  return values_with_discriminator(values, "kind", "int")
41
41
 
42
42
 
@@ -46,16 +46,18 @@ class Real(ClassicalType):
46
46
  def as_symbolic(self, name: str) -> Symbol:
47
47
  return Symbol(name, real=True)
48
48
 
49
- @pydantic.root_validator(pre=True)
50
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
49
+ @pydantic.model_validator(mode="before")
50
+ @classmethod
51
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
51
52
  return values_with_discriminator(values, "kind", "real")
52
53
 
53
54
 
54
55
  class Bool(ClassicalType):
55
56
  kind: Literal["bool"]
56
57
 
57
- @pydantic.root_validator(pre=True)
58
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
58
+ @pydantic.model_validator(mode="before")
59
+ @classmethod
60
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
59
61
  return values_with_discriminator(values, "kind", "bool")
60
62
 
61
63
 
@@ -66,16 +68,18 @@ class ClassicalList(ClassicalType):
66
68
  def as_symbolic(self, name: str) -> Symbol:
67
69
  return IndexedBase(name)
68
70
 
69
- @pydantic.root_validator(pre=True)
70
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
71
+ @pydantic.model_validator(mode="before")
72
+ @classmethod
73
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
71
74
  return values_with_discriminator(values, "kind", "list")
72
75
 
73
76
 
74
77
  class StructMetaType(ClassicalType):
75
78
  kind: Literal["type_proxy"]
76
79
 
77
- @pydantic.root_validator(pre=True)
78
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
80
+ @pydantic.model_validator(mode="before")
81
+ @classmethod
82
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
79
83
  return values_with_discriminator(values, "kind", "type_proxy")
80
84
 
81
85
 
@@ -87,8 +91,9 @@ class ClassicalArray(ClassicalType):
87
91
  def as_symbolic(self, name: str) -> list:
88
92
  return [self.element_type.as_symbolic(f"{name}_{i}") for i in range(self.size)]
89
93
 
90
- @pydantic.root_validator(pre=True)
91
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
94
+ @pydantic.model_validator(mode="before")
95
+ @classmethod
96
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
92
97
  return values_with_discriminator(values, "kind", "array")
93
98
 
94
99
 
@@ -99,32 +104,36 @@ class OpaqueHandle(ClassicalType):
99
104
  class VQEResult(OpaqueHandle):
100
105
  kind: Literal["vqe_result"]
101
106
 
102
- @pydantic.root_validator(pre=True)
103
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
107
+ @pydantic.model_validator(mode="before")
108
+ @classmethod
109
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
104
110
  return values_with_discriminator(values, "kind", "vqe_result")
105
111
 
106
112
 
107
113
  class Histogram(OpaqueHandle):
108
114
  kind: Literal["histogram"]
109
115
 
110
- @pydantic.root_validator(pre=True)
111
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
116
+ @pydantic.model_validator(mode="before")
117
+ @classmethod
118
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
112
119
  return values_with_discriminator(values, "kind", "histogram")
113
120
 
114
121
 
115
122
  class Estimation(OpaqueHandle):
116
123
  kind: Literal["estimation_result"]
117
124
 
118
- @pydantic.root_validator(pre=True)
119
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
125
+ @pydantic.model_validator(mode="before")
126
+ @classmethod
127
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
120
128
  return values_with_discriminator(values, "kind", "estimation_result")
121
129
 
122
130
 
123
131
  class IQAERes(OpaqueHandle):
124
132
  kind: Literal["iqae_result"]
125
133
 
126
- @pydantic.root_validator(pre=True)
127
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
134
+ @pydantic.model_validator(mode="before")
135
+ @classmethod
136
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
128
137
  return values_with_discriminator(values, "kind", "iqae_result")
129
138
 
130
139
 
@@ -40,16 +40,17 @@ ConcreteClassicalType = Annotated[
40
40
  ],
41
41
  Field(discriminator="kind"),
42
42
  ]
43
- ClassicalList.update_forward_refs(ConcreteClassicalType=ConcreteClassicalType)
44
- ClassicalArray.update_forward_refs(ConcreteClassicalType=ConcreteClassicalType)
43
+ ClassicalList.model_rebuild()
44
+ ClassicalArray.model_rebuild()
45
45
 
46
- PythonClassicalTypes = (int, float, bool, list, Enum)
46
+ NativePythonClassicalTypes = (int, float, bool, list)
47
+ PythonClassicalPydanticTypes = (Enum,)
47
48
 
48
49
  ConcreteQuantumType = Annotated[
49
50
  Union[QuantumBit, QuantumBitvector, QuantumNumeric, TypeName],
50
51
  Field(discriminator="kind", default_factory=QuantumBitvector),
51
52
  ]
52
- QuantumBitvector.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
53
- TypeName.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
54
- QStructDeclaration.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
55
- RegisterQuantumType.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
53
+ QuantumBitvector.model_rebuild()
54
+ TypeName.model_rebuild()
55
+ QStructDeclaration.model_rebuild()
56
+ RegisterQuantumType.model_rebuild()
@@ -1,7 +1,7 @@
1
1
  import abc
2
2
  from typing import Sequence
3
3
 
4
- import pydantic
4
+ from pydantic import ConfigDict
5
5
 
6
6
  from classiq.interface.model.classical_parameter_declaration import (
7
7
  AnonClassicalParameterDeclaration,
@@ -16,11 +16,10 @@ class FunctionDeclaration(Parameter, abc.ABC):
16
16
 
17
17
  @property
18
18
  @abc.abstractmethod
19
- def param_decls(self) -> Sequence[AnonClassicalParameterDeclaration]:
19
+ def param_decls(self) -> Sequence["AnonClassicalParameterDeclaration"]:
20
20
  pass
21
21
 
22
- class Config:
23
- extra = pydantic.Extra.forbid
22
+ model_config = ConfigDict(extra="forbid")
24
23
 
25
24
 
26
- FunctionDeclaration.update_forward_refs()
25
+ FunctionDeclaration.model_rebuild()
@@ -16,15 +16,16 @@ if TYPE_CHECKING:
16
16
  from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
17
17
 
18
18
 
19
- class TypeName(ClassicalType, QuantumType): # type:ignore[misc]
19
+ class TypeName(ClassicalType, QuantumType):
20
20
  kind: Literal["struct_instance"]
21
21
  name: str = pydantic.Field(description="The type name of the instance")
22
22
  _assigned_fields: Optional[Mapping[str, "ConcreteQuantumType"]] = (
23
23
  pydantic.PrivateAttr(default=None)
24
24
  )
25
25
 
26
- @pydantic.root_validator(pre=True)
27
- def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
26
+ @pydantic.model_validator(mode="before")
27
+ @classmethod
28
+ def _set_kind(cls, values: Any) -> Dict[str, Any]:
28
29
  return values_with_discriminator(values, "kind", "struct_instance")
29
30
 
30
31
  def _update_size_in_bits_from_declaration(self) -> None:
@@ -60,7 +61,7 @@ class TypeName(ClassicalType, QuantumType): # type:ignore[misc]
60
61
  if self._assigned_fields is None:
61
62
  qstruct_fields = QMODULE.qstruct_decls[self.name].fields
62
63
  self._assigned_fields = {
63
- field_name: field_type.copy()
64
+ field_name: field_type.model_copy()
64
65
  for field_name, field_type in qstruct_fields.items()
65
66
  }
66
67
 
@@ -2,6 +2,7 @@ import logging
2
2
  from typing import Any, Dict, List, Literal, Optional, Tuple, Union
3
3
 
4
4
  import pydantic
5
+ from pydantic import ConfigDict
5
6
  from typing_extensions import TypeAlias
6
7
 
7
8
  from classiq.interface.generator.control_state import ControlState
@@ -56,8 +57,8 @@ class GeneratedFunction(pydantic.BaseModel):
56
57
  name: str
57
58
  control_states: List[ControlState]
58
59
  registers: List[GeneratedRegister] = list()
59
- depth: Optional[int]
60
- width: Optional[int]
60
+ depth: Optional[int] = pydantic.Field(default=None)
61
+ width: Optional[int] = pydantic.Field(default=None)
61
62
  released_auxiliary_qubits: List[int] = list()
62
63
  dangling_inputs: Dict[str, GeneratedRegister] = dict()
63
64
  dangling_outputs: Dict[str, GeneratedRegister] = dict()
@@ -97,16 +98,18 @@ class GeneratedCircuitData(pydantic.BaseModel):
97
98
 
98
99
 
99
100
  class FunctionDebugInfoInterface(pydantic.BaseModel):
100
- generated_function: Optional[GeneratedFunction]
101
+ generated_function: Optional[GeneratedFunction] = pydantic.Field(default=None)
101
102
  children: List["FunctionDebugInfoInterface"]
102
103
  relative_qubits: Tuple[int, ...]
103
- absolute_qubits: Optional[Tuple[int, ...]]
104
- is_basis_gate: Optional[bool]
104
+ absolute_qubits: Optional[Tuple[int, ...]] = pydantic.Field(default=None)
105
+ is_basis_gate: Optional[bool] = pydantic.Field(default=None)
105
106
  is_inverse: bool = pydantic.Field(default=False)
106
107
  is_allocate_or_free: bool = pydantic.Field(default=False)
107
108
  level: OperationLevel = pydantic.Field(default=OperationLevel.UNKNOWN)
108
109
  parameters: List[OperationParameter] = list()
109
- port_to_passed_variable_map: Dict[str, str] = pydantic.Field(default_factory=dict)
110
+ port_to_passed_variable_map: Dict[str, str] = pydantic.Field(default={})
111
+
112
+ model_config = ConfigDict(extra="allow")
110
113
  # Temporary field to store the override debug info for parallel old/new visualization
111
114
  override_debug_info: Optional["FunctionDebugInfoInterface"] = None
112
115
 
@@ -1,6 +1,7 @@
1
1
  from typing import Any, Dict, List, Set, Tuple, Union
2
2
 
3
3
  import pydantic
4
+ from pydantic_core.core_schema import ValidationInfo
4
5
 
5
6
  from classiq.interface.exceptions import ClassiqValueError
6
7
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
@@ -29,28 +30,34 @@ class GroverDiffuser(FunctionParams):
29
30
  self._inputs = {reg.name: reg for reg in self.variables}
30
31
  self._outputs = {reg.name: reg for reg in self.variables}
31
32
 
32
- @pydantic.root_validator(pre=True)
33
- def _validate_state_preparation_name(cls, values: Dict[str, Any]) -> Dict[str, Any]:
34
- if isinstance(
35
- values.get("state_preparation_params"), CustomFunction
36
- ) and not values.get("state_preparation"):
33
+ @pydantic.model_validator(mode="before")
34
+ @classmethod
35
+ def _validate_state_preparation_name(cls, values: Any) -> Dict[str, Any]:
36
+ if (
37
+ isinstance(values, dict)
38
+ and isinstance(values.get("state_preparation_params"), CustomFunction)
39
+ and not values.get("state_preparation")
40
+ ):
37
41
  raise ClassiqValueError(
38
42
  "Must receive the function name from the `state_preparation` field for user defined functions"
39
43
  )
40
44
  return values
41
45
 
42
- @pydantic.root_validator(pre=True)
43
- def _parse_state_preparation(cls, values: Dict[str, Any]) -> Dict[str, Any]:
44
- parse_function_params_values(
45
- values=values,
46
- params_key="state_preparation_params",
47
- discriminator_key="state_preparation",
48
- param_classes={StatePreparation, CustomFunction},
49
- default_parser_class=CustomFunction,
50
- )
46
+ @pydantic.model_validator(mode="before")
47
+ @classmethod
48
+ def _parse_state_preparation(cls, values: Any) -> Dict[str, Any]:
49
+ if isinstance(values, dict):
50
+ parse_function_params_values(
51
+ values=values,
52
+ params_key="state_preparation_params",
53
+ discriminator_key="state_preparation",
54
+ param_classes={StatePreparation, CustomFunction},
55
+ default_parser_class=CustomFunction,
56
+ )
51
57
  return values
52
58
 
53
- @pydantic.validator("variables")
59
+ @pydantic.field_validator("variables")
60
+ @classmethod
54
61
  def _validate_variables(
55
62
  cls, variables: List[RegisterUserInput]
56
63
  ) -> List[RegisterUserInput]:
@@ -58,11 +65,12 @@ class GroverDiffuser(FunctionParams):
58
65
  assert len(variables) == len(names), "Repeating names not allowed"
59
66
  return variables
60
67
 
61
- @pydantic.validator("state_preparation_params")
68
+ @pydantic.field_validator("state_preparation_params")
69
+ @classmethod
62
70
  def _validate_state_preparation(
63
- cls, state_preparation_params: GroverStatePreparation, values: Dict[str, Any]
71
+ cls, state_preparation_params: GroverStatePreparation, info: ValidationInfo
64
72
  ) -> GroverStatePreparation:
65
- variables = values.get("variables", list())
73
+ variables = info.data.get("variables", list())
66
74
  sp_inputs = state_preparation_params.inputs_full(strict_zero_ios=False)
67
75
  sp_outputs = state_preparation_params.outputs
68
76
  if len(sp_inputs) == 1 and len(sp_outputs) == 1: