classiq 0.63.0__py3-none-any.whl → 0.64.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 (42) hide show
  1. classiq/analyzer/url_utils.py +2 -3
  2. classiq/interface/_version.py +1 -1
  3. classiq/interface/analyzer/result.py +1 -2
  4. classiq/interface/executor/result.py +6 -3
  5. classiq/interface/helpers/datastructures.py +26 -0
  6. classiq/interface/interface_version.py +1 -1
  7. classiq/interface/model/handle_binding.py +11 -3
  8. classiq/interface/server/routes.py +4 -0
  9. classiq/model_expansions/atomic_expression_functions_defs.py +6 -6
  10. classiq/model_expansions/capturing/captured_vars.py +27 -10
  11. classiq/model_expansions/evaluators/arg_type_match.py +4 -7
  12. classiq/model_expansions/evaluators/quantum_type_utils.py +15 -8
  13. classiq/model_expansions/expression_evaluator.py +8 -2
  14. classiq/model_expansions/generative_functions.py +3 -3
  15. classiq/model_expansions/interpreters/__init__.py +0 -0
  16. classiq/model_expansions/{interpreter.py → interpreters/base_interpreter.py} +26 -137
  17. classiq/model_expansions/interpreters/generative_interpreter.py +108 -0
  18. classiq/model_expansions/model_tables.py +1 -92
  19. classiq/model_expansions/quantum_operations/__init__.py +0 -10
  20. classiq/model_expansions/quantum_operations/call_emitter.py +3 -3
  21. classiq/model_expansions/quantum_operations/emitter.py +2 -2
  22. classiq/model_expansions/quantum_operations/quantum_function_call.py +2 -2
  23. classiq/model_expansions/quantum_operations/shallow_emitter.py +2 -2
  24. classiq/model_expansions/scope_initialization.py +8 -0
  25. classiq/qmod/declaration_inferrer.py +0 -3
  26. classiq/qmod/generative.py +4 -4
  27. classiq/qmod/qfunc.py +4 -2
  28. classiq/qmod/qmod_variable.py +17 -10
  29. classiq/qmod/quantum_function.py +6 -4
  30. classiq/qmod/utilities.py +7 -1
  31. {classiq-0.63.0.dist-info → classiq-0.64.0.dist-info}/METADATA +1 -1
  32. {classiq-0.63.0.dist-info → classiq-0.64.0.dist-info}/RECORD +33 -39
  33. classiq/interface/helpers/dotdict.py +0 -18
  34. classiq/model_expansions/quantum_operations/control.py +0 -290
  35. classiq/model_expansions/quantum_operations/expression_operation.py +0 -103
  36. classiq/model_expansions/quantum_operations/inplace_binary_operation.py +0 -535
  37. classiq/model_expansions/quantum_operations/invert.py +0 -36
  38. classiq/model_expansions/quantum_operations/phase.py +0 -187
  39. classiq/model_expansions/quantum_operations/power.py +0 -71
  40. classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +0 -230
  41. classiq/model_expansions/quantum_operations/within_apply.py +0 -25
  42. {classiq-0.63.0.dist-info → classiq-0.64.0.dist-info}/WHEEL +0 -0
@@ -1,535 +0,0 @@
1
- from typing import TYPE_CHECKING, Optional, Union
2
-
3
- from classiq.interface.exceptions import ClassiqInternalExpansionError
4
- from classiq.interface.generator.expressions.expression import Expression
5
- from classiq.interface.generator.functions.port_declaration import (
6
- PortDeclarationDirection,
7
- )
8
- from classiq.interface.model.bind_operation import BindOperation
9
- from classiq.interface.model.control import Control
10
- from classiq.interface.model.handle_binding import HandleBinding, SubscriptHandleBinding
11
- from classiq.interface.model.inplace_binary_operation import (
12
- BinaryOperation,
13
- InplaceBinaryOperation,
14
- )
15
- from classiq.interface.model.port_declaration import PortDeclaration
16
- from classiq.interface.model.quantum_function_call import QuantumFunctionCall
17
- from classiq.interface.model.quantum_function_declaration import (
18
- NamedParamsQuantumFunctionDeclaration,
19
- )
20
- from classiq.interface.model.quantum_statement import QuantumStatement
21
- from classiq.interface.model.quantum_type import QuantumBitvector, QuantumNumeric
22
- from classiq.interface.model.repeat import Repeat
23
- from classiq.interface.model.variable_declaration_statement import (
24
- VariableDeclarationStatement,
25
- )
26
- from classiq.interface.model.within_apply_operation import WithinApply
27
-
28
- from classiq.model_expansions.closure import FunctionClosure
29
- from classiq.model_expansions.evaluators.parameter_types import (
30
- evaluate_types_in_quantum_symbols,
31
- )
32
- from classiq.model_expansions.evaluators.quantum_type_utils import (
33
- validate_inplace_binary_op_vars,
34
- )
35
- from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
36
- from classiq.model_expansions.scope import QuantumSymbol, Scope
37
- from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
38
- from classiq.qmod.builtins.functions import (
39
- CX,
40
- X,
41
- allocate,
42
- integer_xor,
43
- modular_add,
44
- modular_add_constant,
45
- real_xor_constant,
46
- )
47
-
48
-
49
- def _binary_function_declaration(
50
- op: BinaryOperation, constant: bool
51
- ) -> NamedParamsQuantumFunctionDeclaration:
52
- return {
53
- False: {
54
- BinaryOperation.Addition: modular_add.func_decl,
55
- BinaryOperation.Xor: integer_xor.func_decl,
56
- },
57
- True: {
58
- BinaryOperation.Addition: modular_add_constant.func_decl,
59
- BinaryOperation.Xor: real_xor_constant.func_decl,
60
- },
61
- }[constant][op]
62
-
63
-
64
- class InplaceBinaryOperationEmitter(CallEmitter[InplaceBinaryOperation]):
65
- def emit(self, op: InplaceBinaryOperation, /) -> None:
66
- if isinstance(op.value, Expression):
67
- self._emit_constant_operation(op)
68
- return
69
-
70
- value_var = self._interpreter.evaluate(op.value).as_type(QuantumSymbol)
71
- target_var = self._interpreter.evaluate(op.target).as_type(QuantumSymbol)
72
- value_var, target_var = evaluate_types_in_quantum_symbols(
73
- [value_var, target_var], self._current_scope
74
- )
75
- validate_inplace_binary_op_vars(value_var, target_var, op.operation.value)
76
- if TYPE_CHECKING:
77
- assert isinstance(value_var.quantum_type, QuantumNumeric)
78
- assert isinstance(target_var.quantum_type, QuantumNumeric)
79
-
80
- frac_digits_diff = (
81
- value_var.quantum_type.fraction_digits_value
82
- - target_var.quantum_type.fraction_digits_value
83
- )
84
- if (
85
- frac_digits_diff == value_var.quantum_type.size_in_bits
86
- or -frac_digits_diff == target_var.quantum_type.size_in_bits
87
- ):
88
- return
89
-
90
- value_var = QuantumSymbol(
91
- handle=HandleBinding(name="value"), quantum_type=value_var.quantum_type
92
- )
93
- target_var = QuantumSymbol(
94
- handle=HandleBinding(name="target"),
95
- quantum_type=target_var.quantum_type,
96
- )
97
- internal_func_decl = _binary_function_declaration(op.operation, constant=False)
98
- if op.operation == BinaryOperation.Xor:
99
- body = _build_inplace_xor_operation(
100
- value_var=value_var,
101
- target_var=target_var,
102
- name_allocator=self._interpreter._counted_name_allocator,
103
- )
104
- else:
105
- body = _build_inplace_binary_operation(
106
- value_var=value_var,
107
- target_var=target_var,
108
- internal_function_declaration=internal_func_decl,
109
- )
110
- inplace_binary_op_function = FunctionClosure.create(
111
- name=op.operation.value,
112
- positional_arg_declarations=[
113
- PortDeclaration(
114
- name=value_var.handle.name,
115
- quantum_type=value_var.quantum_type,
116
- direction=PortDeclarationDirection.Inout,
117
- ),
118
- PortDeclaration(
119
- name=target_var.handle.name,
120
- quantum_type=target_var.quantum_type,
121
- direction=PortDeclarationDirection.Inout,
122
- ),
123
- ],
124
- body=body,
125
- scope=Scope(parent=self._current_scope),
126
- )
127
- self._emit_quantum_function_call(
128
- inplace_binary_op_function, [op.value, op.target]
129
- )
130
-
131
- def _emit_constant_operation(self, op: InplaceBinaryOperation) -> None:
132
- if TYPE_CHECKING:
133
- assert isinstance(op.value, Expression)
134
- self._interpreter.emit(
135
- _internal_inplace_binary_operation_function_call(
136
- _binary_function_declaration(op.operation, constant=True),
137
- op.value,
138
- op.target,
139
- )
140
- )
141
-
142
-
143
- def _build_inplace_binary_operation(
144
- value_var: QuantumSymbol,
145
- target_var: QuantumSymbol,
146
- internal_function_declaration: NamedParamsQuantumFunctionDeclaration,
147
- ) -> list[QuantumStatement]:
148
- if TYPE_CHECKING:
149
- assert isinstance(value_var.quantum_type, QuantumNumeric)
150
- assert isinstance(target_var.quantum_type, QuantumNumeric)
151
-
152
- frac_digits_diff = (
153
- value_var.quantum_type.fraction_digits_value
154
- - target_var.quantum_type.fraction_digits_value
155
- )
156
-
157
- target_overlap_var, target_var_decls, target_bind_ops = (
158
- _trim_superfluous_fraction_digits("target", target_var, -frac_digits_diff)
159
- )
160
- value_overlap_var, value_trim_var_decls, value_bind_ops = (
161
- _trim_superfluous_fraction_digits("value", value_var, frac_digits_diff)
162
- )
163
- size_diff = (
164
- value_overlap_var.quantum_type.size_in_bits
165
- - target_overlap_var.quantum_type.size_in_bits
166
- )
167
- (
168
- value_padded_var,
169
- value_pad_var_decls,
170
- value_pad_pre_bind_ops,
171
- value_pad_init_ops,
172
- value_post_bind_ops,
173
- ) = _pad_with_sign_bit("value", value_overlap_var, size_diff)
174
-
175
- op_call = _internal_inplace_binary_operation_function_call(
176
- internal_function_declaration,
177
- value_padded_var.handle,
178
- target_overlap_var.handle,
179
- )
180
-
181
- return [
182
- *target_var_decls,
183
- *value_trim_var_decls,
184
- *value_pad_var_decls,
185
- WithinApply(
186
- compute=[
187
- *target_bind_ops,
188
- *value_bind_ops,
189
- *value_pad_pre_bind_ops,
190
- *value_pad_init_ops,
191
- *value_post_bind_ops,
192
- ],
193
- action=[
194
- op_call,
195
- ],
196
- ),
197
- ]
198
-
199
-
200
- def _build_inplace_xor_operation(
201
- value_var: QuantumSymbol,
202
- target_var: QuantumSymbol,
203
- name_allocator: CountedNameAllocator,
204
- ) -> list[QuantumStatement]:
205
- if TYPE_CHECKING:
206
- assert isinstance(value_var.quantum_type, QuantumNumeric)
207
- assert isinstance(target_var.quantum_type, QuantumNumeric)
208
-
209
- frac_digits_diff = (
210
- value_var.quantum_type.fraction_digits_value
211
- - target_var.quantum_type.fraction_digits_value
212
- )
213
-
214
- target_overlap_var, target_var_decls, target_bind_ops = (
215
- _trim_superfluous_fraction_digits("target", target_var, -frac_digits_diff)
216
- )
217
- value_overlap_var, value_trim_var_decls, value_bind_ops = (
218
- _trim_superfluous_fraction_digits("value", value_var, frac_digits_diff)
219
- )
220
- target_left_var, value_left_var, sign_var_decls, sign_bind_ops, sign_xor = (
221
- _split_and_xor_sign(target_overlap_var, value_overlap_var, name_allocator)
222
- )
223
-
224
- action: list[QuantumStatement] = []
225
- if target_left_var is not None and value_left_var is not None:
226
- action.append(
227
- _internal_inplace_binary_operation_function_call(
228
- integer_xor.func_decl,
229
- value_left_var.handle,
230
- target_left_var.handle,
231
- )
232
- )
233
- action.extend(sign_xor)
234
-
235
- return [
236
- *target_var_decls,
237
- *value_trim_var_decls,
238
- *sign_var_decls,
239
- WithinApply(
240
- compute=[
241
- *target_bind_ops,
242
- *value_bind_ops,
243
- *sign_bind_ops,
244
- ],
245
- action=action,
246
- ),
247
- ]
248
-
249
-
250
- def _internal_inplace_binary_operation_function_call(
251
- internal_function_declaration: NamedParamsQuantumFunctionDeclaration,
252
- value: Union[HandleBinding, Expression],
253
- target_var: HandleBinding,
254
- ) -> QuantumFunctionCall:
255
- internal_function_call = QuantumFunctionCall(
256
- function=internal_function_declaration.name,
257
- positional_args=[value, target_var],
258
- )
259
- internal_function_call.set_func_decl(internal_function_declaration)
260
- return internal_function_call
261
-
262
-
263
- def _trim_superfluous_fraction_digits(
264
- kind: str, var: QuantumSymbol, frac_digits_diff: int
265
- ) -> tuple[QuantumSymbol, list[VariableDeclarationStatement], list[BindOperation]]:
266
- if frac_digits_diff <= 0:
267
- return var, [], []
268
-
269
- quantum_type = var.quantum_type
270
- if TYPE_CHECKING:
271
- assert isinstance(quantum_type, QuantumNumeric)
272
-
273
- trimmed_fraction_digits_var = QuantumSymbol(
274
- handle=HandleBinding(name=f"trimmed_{kind}_fraction_digits"),
275
- quantum_type=QuantumBitvector(
276
- length=Expression(expr=str(frac_digits_diff)),
277
- ),
278
- )
279
- overlap_var = QuantumSymbol(
280
- handle=HandleBinding(name=f"{kind}_overlap"),
281
- quantum_type=QuantumNumeric(
282
- size=Expression(expr=str(quantum_type.size_in_bits - frac_digits_diff)),
283
- is_signed=quantum_type.is_signed,
284
- fraction_digits=Expression(expr="0"),
285
- ),
286
- )
287
- bind_targets = trimmed_fraction_digits_var, overlap_var
288
-
289
- split_var_declarations = [
290
- VariableDeclarationStatement(
291
- name=var.handle.name,
292
- quantum_type=var.quantum_type,
293
- )
294
- for var in bind_targets
295
- ]
296
- bind_op = BindOperation(
297
- in_handles=[var.handle],
298
- out_handles=[var.handle for var in bind_targets],
299
- )
300
-
301
- return overlap_var, split_var_declarations, [bind_op]
302
-
303
-
304
- def _pad_with_sign_bit(kind: str, var: QuantumSymbol, size_diff: int) -> tuple[
305
- QuantumSymbol,
306
- list[VariableDeclarationStatement],
307
- list[QuantumStatement],
308
- list[QuantumFunctionCall],
309
- list[BindOperation],
310
- ]:
311
- quantum_type = var.quantum_type
312
- if TYPE_CHECKING:
313
- assert isinstance(quantum_type, QuantumNumeric)
314
-
315
- if not quantum_type.sign_value or size_diff >= 0:
316
- return var, [], [], [], []
317
-
318
- padding_var, padding_allocation = _allocate_padding(kind, size_diff)
319
- padded_var = QuantumSymbol(
320
- handle=HandleBinding(name=f"padded_{kind}"),
321
- quantum_type=QuantumNumeric(
322
- size=Expression(expr=str(quantum_type.size_in_bits - size_diff)),
323
- is_signed=Expression(expr="False"),
324
- fraction_digits=Expression(expr="0"),
325
- ),
326
- )
327
- var_decls = [
328
- VariableDeclarationStatement(
329
- name=var.handle.name,
330
- quantum_type=var.quantum_type,
331
- )
332
- for var in (padding_var, padded_var)
333
- ]
334
-
335
- if quantum_type.size_in_bits == 1: # qnum<1, SIGNED, ?>
336
- padding_init_ops = _init_padding(var, padding_var, size_diff)
337
- padding_rebind = BindOperation(
338
- in_handles=[var.handle, padding_var.handle],
339
- out_handles=[padded_var.handle],
340
- )
341
- return (
342
- padded_var,
343
- var_decls,
344
- [padding_allocation],
345
- padding_init_ops,
346
- [padding_rebind],
347
- )
348
-
349
- significand_var, sign_var, sign_split_bind = _split_var(kind, var, 1)
350
- padding_init_ops = _init_padding(sign_var, padding_var, size_diff)
351
-
352
- padding_rebind = BindOperation(
353
- in_handles=[significand_var.handle, sign_var.handle, padding_var.handle],
354
- out_handles=[padded_var.handle],
355
- )
356
-
357
- var_decls += [
358
- VariableDeclarationStatement(
359
- name=var.handle.name,
360
- quantum_type=var.quantum_type,
361
- )
362
- for var in (significand_var, sign_var)
363
- ]
364
-
365
- return (
366
- padded_var,
367
- var_decls,
368
- [sign_split_bind, padding_allocation],
369
- padding_init_ops,
370
- [padding_rebind],
371
- )
372
-
373
-
374
- def _init_padding(
375
- sign_var: QuantumSymbol, padding_var: QuantumSymbol, size_diff: int
376
- ) -> list[QuantumFunctionCall]:
377
- padding_init_ops = [
378
- QuantumFunctionCall(
379
- function=CX.func_decl.name,
380
- positional_args=[sign_var.handle, padding_var[idx].handle],
381
- )
382
- for idx in range(-size_diff)
383
- ]
384
- for cx_call in padding_init_ops:
385
- cx_call.set_func_decl(CX.func_decl)
386
- return padding_init_ops
387
-
388
-
389
- def _allocate_padding(
390
- kind: str, size_diff: int
391
- ) -> tuple[QuantumSymbol, QuantumFunctionCall]:
392
- padding_var = QuantumSymbol(
393
- handle=HandleBinding(name=f"{kind}_sign_padding"),
394
- quantum_type=QuantumBitvector(
395
- length=Expression(expr=str(-size_diff)),
396
- ),
397
- )
398
- padding_allocation = QuantumFunctionCall(
399
- function=allocate.func_decl.name,
400
- positional_args=[Expression(expr=str(-size_diff)), padding_var.handle],
401
- )
402
- padding_allocation.set_func_decl(allocate.func_decl)
403
- return padding_var, padding_allocation
404
-
405
-
406
- def _split_var(
407
- kind: str, var: QuantumSymbol, right_size: int
408
- ) -> tuple[QuantumSymbol, QuantumSymbol, BindOperation]:
409
- left_var = QuantumSymbol(
410
- handle=HandleBinding(name=f"{kind}_left"),
411
- quantum_type=QuantumNumeric(
412
- size=Expression(expr=str(var.quantum_type.size_in_bits - right_size)),
413
- is_signed=Expression(expr="False"),
414
- fraction_digits=Expression(expr="0"),
415
- ),
416
- )
417
- right_var = QuantumSymbol(
418
- handle=HandleBinding(name=f"{kind}_right"),
419
- quantum_type=QuantumNumeric(
420
- size=Expression(expr=str(right_size)),
421
- is_signed=Expression(expr="False"),
422
- fraction_digits=Expression(expr="0"),
423
- ),
424
- )
425
- split_bind = BindOperation(
426
- in_handles=[var.handle],
427
- out_handles=[left_var.handle, right_var.handle],
428
- )
429
- return left_var, right_var, split_bind
430
-
431
-
432
- def _split_and_xor_sign(
433
- target_var: QuantumSymbol,
434
- value_var: QuantumSymbol,
435
- name_allocator: CountedNameAllocator,
436
- ) -> tuple[
437
- Optional[QuantumSymbol],
438
- Optional[QuantumSymbol],
439
- list[VariableDeclarationStatement],
440
- list[BindOperation],
441
- list[Control],
442
- ]:
443
- if TYPE_CHECKING:
444
- assert isinstance(value_var.quantum_type, QuantumNumeric)
445
- assert isinstance(target_var.quantum_type, QuantumNumeric)
446
- size_diff = (
447
- value_var.quantum_type.size_in_bits - target_var.quantum_type.size_in_bits
448
- )
449
- if not value_var.quantum_type.sign_value or size_diff >= 0:
450
- return target_var, value_var, [], [], []
451
-
452
- if value_var.quantum_type.size_in_bits == 1:
453
- return None, None, [], [], [_xor_sign(target_var, value_var, name_allocator)]
454
-
455
- value_rest_var, value_sign_var, value_split_bind = _split_var("value", value_var, 1)
456
- target_left_var, target_right_var, target_split_bind = _split_var(
457
- "target", target_var, -size_diff + 1
458
- )
459
- var_decls = [
460
- VariableDeclarationStatement(
461
- name=var.handle.name,
462
- quantum_type=var.quantum_type,
463
- )
464
- for var in (value_rest_var, value_sign_var, target_left_var, target_right_var)
465
- ]
466
- bind_ops = [value_split_bind, target_split_bind]
467
- sign_xor = _xor_sign(target_right_var, value_sign_var, name_allocator)
468
- return target_left_var, value_rest_var, var_decls, bind_ops, [sign_xor]
469
-
470
-
471
- def _xor_sign(
472
- target_var: QuantumSymbol,
473
- value_var: QuantumSymbol,
474
- name_allocator: CountedNameAllocator,
475
- ) -> Control:
476
- quantum_type = value_var.quantum_type
477
- if TYPE_CHECKING:
478
- assert isinstance(quantum_type, QuantumNumeric)
479
- if quantum_type.size_in_bits != 1 or quantum_type.fraction_digits_value not in (
480
- 0,
481
- 1,
482
- ):
483
- raise ClassiqInternalExpansionError
484
-
485
- aux_var = name_allocator.allocate("inplace_xor_aux")
486
- iteration_var = name_allocator.allocate("i")
487
- inner_x_call = QuantumFunctionCall(
488
- function=X.func_decl.name,
489
- positional_args=[
490
- SubscriptHandleBinding(
491
- base_handle=HandleBinding(name=aux_var),
492
- index=Expression(expr=iteration_var),
493
- )
494
- ],
495
- )
496
- inner_x_call.set_func_decl(X.func_decl)
497
- inner_xor = WithinApply(
498
- compute=[
499
- BindOperation(
500
- in_handles=[target_var.handle],
501
- out_handles=[HandleBinding(name=aux_var)],
502
- ),
503
- ],
504
- action=[
505
- Repeat(
506
- iter_var=iteration_var,
507
- count=Expression(expr=f"{target_var.quantum_type.size_in_bits}"),
508
- body=[inner_x_call],
509
- )
510
- ],
511
- )
512
-
513
- if quantum_type.sign_value:
514
- if quantum_type.fraction_digits_value == 1:
515
- ctrl_value = -0.5
516
- else:
517
- ctrl_value = -1
518
- else:
519
- if quantum_type.fraction_digits_value == 1:
520
- ctrl_value = 0.5
521
- else:
522
- ctrl_value = 1
523
-
524
- return Control(
525
- expression=Expression(expr=f"{value_var.handle} == {ctrl_value}"),
526
- body=[
527
- VariableDeclarationStatement(
528
- name=aux_var,
529
- quantum_type=QuantumBitvector(
530
- length=Expression(expr=f"{target_var.quantum_type.size_in_bits}")
531
- ),
532
- ),
533
- inner_xor,
534
- ],
535
- )
@@ -1,36 +0,0 @@
1
- from classiq.interface.generator.functions.builtins.internal_operators import (
2
- INVERT_OPERATOR_NAME,
3
- )
4
- from classiq.interface.model.invert import Invert
5
-
6
- from classiq.model_expansions.closure import Closure
7
- from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
8
- from classiq.model_expansions.scope import Scope
9
-
10
-
11
- class InvertEmitter(CallEmitter[Invert]):
12
- def emit(self, invert: Invert, /) -> None:
13
- if self._should_wrap(invert.body):
14
- self._emit_wrapped(invert)
15
- return
16
-
17
- self._emit_as_operation(invert)
18
-
19
- def _emit_as_operation(self, invert: Invert) -> None:
20
- invert_operation = Closure(
21
- name=INVERT_OPERATOR_NAME,
22
- blocks={"body": invert.body},
23
- scope=Scope(parent=self._current_scope),
24
- )
25
- context = self._expand_operation(invert_operation)
26
- self.emit_statement(
27
- Invert(body=context.statements("body"), source_ref=invert.source_ref)
28
- )
29
-
30
- def _emit_wrapped(self, invert: Invert) -> None:
31
- wrapping_function = self._create_expanded_wrapping_function(
32
- INVERT_OPERATOR_NAME, invert.body
33
- )
34
- self.emit_statement(
35
- Invert(body=[wrapping_function], source_ref=invert.source_ref)
36
- )