diff --git a/pyquil/quilbase.py b/pyquil/quilbase.py index 287a9e900..2e36909d5 100644 --- a/pyquil/quilbase.py +++ b/pyquil/quilbase.py @@ -430,6 +430,12 @@ def _update_super(self, gate: quil_rs.Gate) -> None: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Gate": + return Gate._from_rs_gate(super().__deepcopy__(memo)) + def _strip_modifiers(gate: Gate, limit: Optional[int] = None) -> Gate: """ @@ -536,6 +542,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Measurement": + return Measurement._from_rs_measurement(super().__deepcopy__(memo)) + class Reset(quil_rs.Reset, AbstractInstruction): """ @@ -587,6 +599,14 @@ def qubit(self, qubit: Optional[QubitDesignator]) -> None: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Reset": + copy = Reset._from_rs_reset(super().__deepcopy__(memo)) + copy.__class__ = self.__class__ + return copy + class ResetQubit(Reset): """ @@ -699,6 +719,12 @@ def __hash__(self) -> int: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "DefGate": + return DefGate._from_rs_gate_definition(super().__deepcopy__(memo)) + class DefPermutationGate(DefGate): def __new__(cls, name: str, permutation: Union[List[int], np.ndarray]) -> Self: @@ -808,6 +834,12 @@ def __repr__(self) -> str: def out(self) -> str: return super().to_quil() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "JumpTarget": + return JumpTarget._from_rs_label(super().__deepcopy__(memo)) + class JumpWhen(quil_rs.JumpWhen, AbstractInstruction): """ @@ -845,6 +877,12 @@ def target(self, target: Union[Label, LabelPlaceholder]) -> None: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "JumpWhen": + return JumpWhen._from_rs_jump_when(super().__deepcopy__(memo)) + class JumpUnless(quil_rs.JumpUnless, AbstractInstruction): """ @@ -882,6 +920,12 @@ def target(self, target: Union[Label, LabelPlaceholder]) -> None: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "JumpUnless": + return JumpUnless._from_rs_jump_unless(super().__deepcopy__(memo)) + class SimpleInstruction(AbstractInstruction): """ @@ -896,6 +940,12 @@ def out(self) -> str: def __str__(self) -> str: return self.out() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "SimpleInstruction": + return self + class Halt(SimpleInstruction): """ @@ -931,6 +981,10 @@ class UnaryClassicalInstruction(quil_rs.UnaryLogic, AbstractInstruction): def __new__(cls, target: MemoryReference) -> "UnaryClassicalInstruction": return super().__new__(cls, cls.op, target._to_rs_memory_reference()) + @classmethod + def _from_rs_unary_logic(cls, unary_logic: quil_rs.UnaryLogic) -> Self: + return super().__new__(cls, unary_logic.operator, unary_logic.operand) + @property def target(self) -> MemoryReference: return MemoryReference._from_rs_memory_reference(super().operand) @@ -945,6 +999,14 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "UnaryClassicalInstruction": + copy = UnaryClassicalInstruction._from_rs_unary_logic(super().__deepcopy__(memo)) + copy.__class__ = self.__class__ + return copy + class ClassicalNeg(UnaryClassicalInstruction): """ @@ -973,6 +1035,10 @@ def __new__(cls, left: MemoryReference, right: Union[MemoryReference, int]) -> S operands = cls._to_rs_binary_operands(left, right) return super().__new__(cls, cls.op, operands) + @classmethod + def _from_rs_binary_logic(cls, binary_logic: quil_rs.BinaryLogic) -> "LogicalBinaryOp": + return super().__new__(cls, binary_logic.operator, binary_logic.operands) + @staticmethod def _to_rs_binary_operand(operand: Union[MemoryReference, int]) -> quil_rs.BinaryOperand: if isinstance(operand, MemoryReference): @@ -1017,6 +1083,14 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "LogicalBinaryOp": + copy = LogicalBinaryOp._from_rs_binary_logic(super().__deepcopy__(memo)) + copy.__class__ = self.__class__ + return copy + class ClassicalAnd(LogicalBinaryOp): """ @@ -1054,6 +1128,10 @@ def __new__(cls, left: MemoryReference, right: Union[MemoryReference, int, float right_operand = _to_rs_arithmetic_operand(right) return super().__new__(cls, cls.op, left_operand, right_operand) + @classmethod + def _from_rs_arithmetic(cls, arithmetic: quil_rs.Arithmetic) -> "ArithmeticBinaryOp": + return super().__new__(cls, arithmetic.operator, arithmetic.destination, arithmetic.source) + @property def left(self) -> MemoryReference: return MemoryReference._from_rs_memory_reference(super().destination.to_memory_reference()) @@ -1078,6 +1156,14 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ArithmeticBinaryOp": + copy = ArithmeticBinaryOp._from_rs_arithmetic(super().__deepcopy__(memo)) + copy.__class__ = self.__class__ + return copy + class ClassicalAdd(ArithmeticBinaryOp): """ @@ -1145,6 +1231,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ClassicalMove": + return ClassicalMove._from_rs_move(super().__deepcopy__(memo)) + class ClassicalExchange(quil_rs.Exchange, AbstractInstruction): """ @@ -1158,6 +1250,10 @@ def __new__( ) -> "ClassicalExchange": return super().__new__(cls, left._to_rs_memory_reference(), right._to_rs_memory_reference()) + @classmethod + def _from_rs_exchange(cls, exchange: quil_rs.Exchange) -> Self: + return super().__new__(cls, exchange.left, exchange.right) + @property # type: ignore[override] def left(self) -> MemoryReference: return MemoryReference._from_rs_memory_reference(super().left) @@ -1180,6 +1276,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ClassicalExchange": + return ClassicalExchange._from_rs_exchange(super().__deepcopy__(memo)) + class ClassicalConvert(quil_rs.Convert, AbstractInstruction): """ @@ -1189,6 +1291,10 @@ class ClassicalConvert(quil_rs.Convert, AbstractInstruction): def __new__(cls, left: MemoryReference, right: MemoryReference) -> "ClassicalConvert": return super().__new__(cls, left._to_rs_memory_reference(), right._to_rs_memory_reference()) + @classmethod + def _from_rs_convert(cls, convert: quil_rs.Convert) -> Self: + return super().__new__(cls, convert.destination, convert.source) + @property def left(self) -> MemoryReference: return MemoryReference._from_rs_memory_reference(super().destination) @@ -1211,6 +1317,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ClassicalConvert": + return ClassicalConvert._from_rs_convert(super().__deepcopy__(memo)) + class ClassicalLoad(quil_rs.Load, AbstractInstruction): """ @@ -1220,6 +1332,10 @@ class ClassicalLoad(quil_rs.Load, AbstractInstruction): def __new__(cls, target: MemoryReference, left: str, right: MemoryReference) -> "ClassicalLoad": return super().__new__(cls, target._to_rs_memory_reference(), left, right._to_rs_memory_reference()) + @classmethod + def _from_rs_load(cls, load: quil_rs.Load) -> Self: + return super().__new__(cls, load.destination, load.source, load.offset) + @property def target(self) -> MemoryReference: return MemoryReference._from_rs_memory_reference(super().destination) @@ -1250,6 +1366,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ClassicalLoad": + return ClassicalLoad._from_rs_load(super().__deepcopy__(memo)) + def _to_rs_arithmetic_operand(operand: Union[MemoryReference, int, float]) -> quil_rs.ArithmeticOperand: if isinstance(operand, MemoryReference): @@ -1279,6 +1401,10 @@ def __new__(cls, target: str, left: MemoryReference, right: Union[MemoryReferenc rs_right = _to_rs_arithmetic_operand(right) return super().__new__(cls, target, left._to_rs_memory_reference(), rs_right) + @classmethod + def _from_rs_store(cls, store: quil_rs.Store) -> Self: + return super().__new__(cls, store.destination, store.offset, store.source) + @property def target(self) -> str: return super().destination @@ -1309,6 +1435,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ClassicalStore": + return ClassicalStore._from_rs_store(super().__deepcopy__(memo)) + class ClassicalComparison(quil_rs.Comparison, AbstractInstruction): """ @@ -1326,6 +1458,10 @@ def __new__( operands = (target._to_rs_memory_reference(), left._to_rs_memory_reference(), cls._to_comparison_operand(right)) return super().__new__(cls, cls.op, operands) + @classmethod + def _from_rs_comparison(cls, comparison: quil_rs.Comparison) -> Self: + return super().__new__(cls, comparison.operator, comparison.operands) + @staticmethod def _to_comparison_operand(operand: Union[MemoryReference, int, float]) -> quil_rs.ComparisonOperand: if isinstance(operand, MemoryReference): @@ -1381,6 +1517,14 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ClassicalComparison": + copy = ClassicalComparison._from_rs_comparison(super().__deepcopy__(memo)) + copy.__class__ = self.__class__ + return copy + class ClassicalEqual(ClassicalComparison): """ @@ -1450,6 +1594,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Jump": + return Jump._from_rs_jump(super().__deepcopy__(memo)) + class Pragma(quil_rs.Pragma, AbstractInstruction): """ @@ -1528,6 +1678,12 @@ def freeform_string(self) -> str: def freeform_string(self, freeform_string: str) -> None: quil_rs.Pragma.data.__set__(self, freeform_string) # type: ignore[attr-defined] + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Pragma": + return Pragma._from_rs_pragma(super().__deepcopy__(memo)) + class Declare(quil_rs.Declaration, AbstractInstruction): """ @@ -1643,14 +1799,30 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Declare": + return Declare._from_rs_declaration(super().__deepcopy__(memo)) + class Include(quil_rs.Include, AbstractInstruction): def out(self) -> str: return super().to_quil() + @classmethod + def _from_rs_include(cls, include: quil_rs.Include) -> "Include": + return super().__new__(cls, include.filename) + def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Include": + return Include._from_rs_include(super().__deepcopy__(memo)) + class Pulse(quil_rs.Pulse, AbstractInstruction): def __new__(cls, frame: Frame, waveform: Waveform, nonblocking: bool = False) -> Self: @@ -1703,6 +1875,12 @@ def nonblocking(self) -> bool: def nonblocking(self, nonblocking: bool) -> None: quil_rs.Pulse.blocking.__set__(self, not nonblocking) # type: ignore[attr-defined] + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Pulse": + return Pulse._from_rs_pulse(super().__deepcopy__(memo)) + class SetFrequency(quil_rs.SetFrequency, AbstractInstruction): def __new__(cls, frame: Frame, freq: ParameterDesignator) -> Self: @@ -1746,6 +1924,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "SetFrequency": + return SetFrequency._from_rs_set_frequency(super().__deepcopy__(memo)) + class ShiftFrequency(quil_rs.ShiftFrequency, AbstractInstruction): def __new__(cls, frame: Frame, freq: ParameterDesignator) -> Self: @@ -1789,6 +1973,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ShiftFrequency": + return ShiftFrequency._from_rs_shift_frequency(super().__deepcopy__(memo)) + class SetPhase(quil_rs.SetPhase, AbstractInstruction): def __new__(cls, frame: Frame, phase: ParameterDesignator) -> Self: @@ -1832,6 +2022,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "SetPhase": + return SetPhase._from_rs_set_phase(super().__deepcopy__(memo)) + class ShiftPhase(quil_rs.ShiftPhase, AbstractInstruction): def __new__(cls, frame: Frame, phase: ParameterDesignator) -> Self: @@ -1875,6 +2071,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "ShiftPhase": + return ShiftPhase._from_rs_shift_phase(super().__deepcopy__(memo)) + class SwapPhases(quil_rs.SwapPhases, AbstractInstruction): def __new__(cls, frameA: Frame, frameB: Frame) -> Self: @@ -1918,6 +2120,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame_1.qubits + super().frame_2.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "SwapPhases": + return SwapPhases._from_rs_swap_phases(super().__deepcopy__(memo)) + class SetScale(quil_rs.SetScale, AbstractInstruction): def __new__(cls, frame: Frame, scale: ParameterDesignator) -> Self: @@ -1961,6 +2169,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "SetScale": + return SetScale._from_rs_set_scale(super().__deepcopy__(memo)) + class Capture(quil_rs.Capture, AbstractInstruction): def __new__( @@ -2029,6 +2243,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Capture": + return Capture._from_rs_capture(super().__deepcopy__(memo)) + class RawCapture(quil_rs.RawCapture, AbstractInstruction): def __new__( @@ -2101,6 +2321,12 @@ def get_qubits(self, indices: bool = True) -> Union[Set[QubitDesignator], Set[in def get_qubit_indices(self) -> Set[int]: return {qubit.to_fixed() for qubit in super().frame.qubits} + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "RawCapture": + return RawCapture._from_rs_raw_capture(super().__deepcopy__(memo)) + class Delay(quil_rs.Delay, AbstractInstruction): def __new__(cls, frames: List[Frame], qubits: Sequence[Union[int, Qubit, FormalArgument]], duration: float) -> Self: @@ -2156,6 +2382,14 @@ def duration(self, duration: float) -> None: expression = quil_rs_expr.Expression.from_number(complex(duration)) quil_rs.Delay.duration.__set__(self, expression) # type: ignore[attr-defined] + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Delay": + copy = Delay._from_rs_delay(super().__deepcopy__(memo)) + copy.__class__ = self.__class__ + return copy + class DelayFrames(Delay): def __new__(cls, frames: List[Frame], duration: float) -> Self: @@ -2189,6 +2423,12 @@ def qubits(self) -> List[QubitDesignator]: def qubits(self, qubits: List[Union[Qubit, FormalArgument]]) -> None: quil_rs.Fence.qubits.__set__(self, _convert_to_rs_qubits(qubits)) # type: ignore[attr-defined] + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "Fence": + return Fence._from_rs_fence(super().__deepcopy__(memo)) + class FenceAll(Fence): """ @@ -2244,6 +2484,12 @@ def entries(self, entries: List[Union[complex, Expression]]) -> None: waveform.matrix = _convert_to_rs_expressions(entries) quil_rs.WaveformDefinition.definition.__set__(self, waveform) # type: ignore[attr-defined] + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "DefWaveform": + return DefWaveform._from_rs_waveform_definition(super().__deepcopy__(memo)) + class DefCircuit(quil_rs.CircuitDefinition, AbstractInstruction): def __new__( @@ -2301,6 +2547,12 @@ def instructions(self, instructions: List[AbstractInstruction]) -> None: rs_instructions = _convert_to_rs_instructions(instructions) quil_rs.CircuitDefinition.instructions.__set__(self, rs_instructions) # type: ignore[attr-defined] + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "DefCircuit": + return DefCircuit._from_rs_circuit_definition(super().__deepcopy__(memo)) + class DefCalibration(quil_rs.Calibration, AbstractInstruction): def __new__( @@ -2361,6 +2613,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "DefCalibration": + return DefCalibration._from_rs_calibration(super().__deepcopy__(memo)) + class DefMeasureCalibration(quil_rs.MeasureCalibrationDefinition, AbstractInstruction): def __new__( @@ -2416,6 +2674,12 @@ def out(self) -> str: def __str__(self) -> str: return super().to_quil_or_debug() + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "DefMeasureCalibration": + return DefMeasureCalibration._from_rs_measure_calibration_definition(super().__deepcopy__(memo)) + class DefFrame(quil_rs.FrameDefinition, AbstractInstruction): def __new__( @@ -2548,3 +2812,9 @@ def center_frequency(self) -> Frame: def center_frequency(self, center_frequency: float) -> None: self._set_attribute("CENTER-FREQUENCY", center_frequency) self._set_attribute("CENTER-FREQUENCY", center_frequency) + + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Dict) -> "DefFrame": + return DefFrame._from_rs_frame_definition(super().__deepcopy__(memo)) diff --git a/test/unit/test_quilbase.py b/test/unit/test_quilbase.py index 14f2f1e65..6528334d1 100644 --- a/test/unit/test_quilbase.py +++ b/test/unit/test_quilbase.py @@ -1,3 +1,4 @@ +import copy from math import pi from typing import Any, List, Optional, Iterable, Tuple, Union from numbers import Complex, Number @@ -159,6 +160,10 @@ def test_eq(self, gate: Gate, name: str, params: List[ParameterDesignator], qubi assert not (gate == not_eq_gate) assert gate != not_eq_gate + def test_copy(self, gate: Gate): + assert isinstance(copy.copy(gate), Gate) + assert isinstance(copy.deepcopy(gate), Gate) + def test_compile(self, program: Program, compiler: QPUCompiler): try: compiler.quil_to_native_quil(program) @@ -225,6 +230,10 @@ def test_parameters(self, def_gate: DefGate, parameters: Optional[List[Parameter def_gate.parameters = [Parameter("brand_new_param")] assert def_gate.parameters == [Parameter("brand_new_param")] + def test_copy(self, def_gate: DefGate): + assert isinstance(copy.copy(def_gate), DefGate) + assert isinstance(copy.deepcopy(def_gate), DefGate) + @pytest.mark.parametrize( ("name", "permutation"), @@ -386,6 +395,10 @@ def test_instrs(self, calibration: DefCalibration, instrs: List[AbstractInstruct calibration.instrs = [Gate("SomeGate", [], [Qubit(0)], [])] assert calibration.instrs == [Gate("SomeGate", [], [Qubit(0)], [])] + def test_copy(self, calibration: DefCalibration): + assert isinstance(copy.copy(calibration), DefCalibration) + assert isinstance(copy.deepcopy(calibration), DefCalibration) + @pytest.mark.parametrize( ("qubit", "memory_reference", "instrs"), @@ -416,6 +429,10 @@ def test_instrs(self, measure_calibration: DefMeasureCalibration, instrs: List[A measure_calibration.instrs = [Gate("SomeGate", [], [Qubit(0)], [])] assert measure_calibration.instrs == [Gate("SomeGate", [], [Qubit(0)], [])] + def test_copy(self, measure_calibration: DefMeasureCalibration): + assert isinstance(copy.copy(measure_calibration), DefMeasureCalibration) + assert isinstance(copy.deepcopy(measure_calibration), DefMeasureCalibration) + @pytest.mark.parametrize( ("qubit", "classical_reg"), @@ -451,6 +468,10 @@ def test_classical_reg(self, measurement: Measurement, classical_reg: MemoryRefe measurement.classical_reg = MemoryReference("new_mem_ref") assert measurement.classical_reg == MemoryReference("new_mem_ref") + def test_copy(self, measurement: Measurement): + assert isinstance(copy.copy(measurement), Measurement) + assert isinstance(copy.deepcopy(measurement), Measurement) + @pytest.mark.parametrize( ("frame", "direction", "initial_frequency", "hardware_object", "sample_rate", "center_frequency"), @@ -521,6 +542,10 @@ def test_center_frequency(self, def_frame: DefFrame, center_frequency: Optional[ def_frame.center_frequency = 432.0 assert def_frame.center_frequency == 432.0 + def test_copy(self, def_frame: DefFrame): + assert isinstance(copy.copy(def_frame), DefFrame) + assert isinstance(copy.deepcopy(def_frame), DefFrame) + @pytest.mark.parametrize( ("name", "memory_type", "memory_size", "shared_region", "offsets"), @@ -583,6 +608,10 @@ def test_offsets(self, declare: Declare, offsets: Optional[Iterable[Tuple[int, s declare.offsets = [(1, "BIT"), (2, "INTEGER")] assert declare.offsets == [(1, "BIT"), (2, "INTEGER")] + def test_copy(self, declare: Declare): + assert isinstance(copy.copy(declare), Declare) + assert isinstance(copy.deepcopy(declare), Declare) + @pytest.mark.parametrize( ("command", "args", "freeform_string"), @@ -620,6 +649,10 @@ def test_freeform_string(self, pragma: Pragma, freeform_string: str): pragma.freeform_string = "new string" assert pragma.freeform_string == "new string" + def test_copy(self, pragma: Pragma): + assert isinstance(copy.copy(pragma), Pragma) + assert isinstance(copy.deepcopy(pragma), Pragma) + @pytest.mark.parametrize( ("qubit"), @@ -659,6 +692,10 @@ def test_get_qubits(self, reset_qubit: ResetQubit, qubit: Qubit): if isinstance(qubit, Qubit): assert reset_qubit.get_qubit_indices() == {qubit.index} + def test_copy(self, reset_qubit: Union[Reset, ResetQubit]): + assert isinstance(copy.copy(reset_qubit), type(reset_qubit)) + assert isinstance(copy.deepcopy(reset_qubit), type(reset_qubit)) + @pytest.mark.parametrize( ("frames", "duration"), @@ -684,6 +721,10 @@ def test_duration(self, delay_frames: DelayFrames, duration: float): delay_frames.duration = 3.14 assert delay_frames.duration == 3.14 + def test_copy(self, delay_frames: DelayFrames): + assert isinstance(copy.copy(delay_frames), DelayFrames) + assert isinstance(copy.deepcopy(delay_frames), DelayFrames) + @pytest.mark.parametrize( ("qubits", "duration"), @@ -711,6 +752,10 @@ def test_duration(self, delay_qubits: DelayQubits, duration: float): delay_qubits.duration = 3.14 assert delay_qubits.duration == 3.14 + def test_copy(self, delay_qubits: DelayQubits): + assert isinstance(copy.copy(delay_qubits), DelayQubits) + assert isinstance(copy.deepcopy(delay_qubits), DelayQubits) + @pytest.mark.parametrize( ("qubits"), @@ -733,6 +778,10 @@ def test_qubits(self, fence: Fence, qubits: List[Union[Qubit, FormalArgument]]): fence.qubits = [Qubit(123)] # type: ignore assert fence.qubits == [Qubit(123)] + def test_copy(self, fence: Fence): + assert isinstance(copy.copy(fence), Fence) + assert isinstance(copy.deepcopy(fence), Fence) + def test_fence_all(): fa = FenceAll() @@ -776,6 +825,10 @@ def test_entries(self, def_waveform: DefWaveform, entries: List[Union[Complex, E def_waveform.entries = [Parameter("z")] # type: ignore assert def_waveform.entries == [Parameter("z")] + def test_copy(self, def_waveform: DefWaveform): + assert isinstance(copy.copy(def_waveform), DefWaveform) + assert isinstance(copy.deepcopy(def_waveform), DefWaveform) + @pytest.mark.parametrize( ("name", "parameters", "qubit_variables", "instructions"), @@ -828,6 +881,10 @@ def test_instructions(self, def_circuit: DefCircuit, instructions: List[Abstract def_circuit.instructions = [Gate("new_gate", [], [Qubit(0)], [])] assert def_circuit.instructions == [Gate("new_gate", [], [Qubit(0)], [])] + def test_copy(self, def_circuit: DefCircuit): + assert isinstance(copy.copy(def_circuit), DefCircuit) + assert isinstance(copy.deepcopy(def_circuit), DefCircuit) + @pytest.mark.parametrize( ("frame", "kernel", "memory_region", "nonblocking"), @@ -881,6 +938,10 @@ def test_nonblocking(self, capture: Capture, nonblocking: bool): capture.nonblocking = not nonblocking assert capture.nonblocking == (not nonblocking) + def test_copy(self, capture: Capture): + assert isinstance(copy.copy(capture), Capture) + assert isinstance(copy.deepcopy(capture), Capture) + @pytest.mark.parametrize( ("frame", "waveform", "nonblocking"), @@ -963,6 +1024,10 @@ def test_nonblocking(self, pulse: Pulse, nonblocking: bool): pulse.nonblocking = not nonblocking assert pulse.nonblocking == (not nonblocking) + def test_copy(self, pulse: Pulse): + assert isinstance(copy.copy(pulse), Pulse) + assert isinstance(copy.deepcopy(pulse), Pulse) + @pytest.mark.parametrize( ("frame", "duration", "memory_region", "nonblocking"), @@ -1016,6 +1081,10 @@ def test_nonblocking(self, raw_capture: RawCapture, nonblocking: bool): raw_capture.nonblocking = not nonblocking assert raw_capture.nonblocking == (not nonblocking) + def test_copy(self, raw_capture: RawCapture): + assert isinstance(copy.copy(raw_capture), RawCapture) + assert isinstance(copy.deepcopy(raw_capture), RawCapture) + @pytest.mark.parametrize( ("frame", "expression"), @@ -1073,6 +1142,11 @@ def test_expression(self, frame_mutation_instructions, expression: ParameterDesi setattr(instr, expression_name, 3.14) assert getattr(instr, expression_name) == 3.14 + def test_copy(self, frame_mutation_instructions): + for instr in frame_mutation_instructions: + assert isinstance(copy.copy(instr), type(instr)) + assert isinstance(copy.deepcopy(instr), type(instr)) + @pytest.mark.parametrize( ("frame_a", "frame_b"), @@ -1099,6 +1173,10 @@ def test_get_qubits(self, swap_phase: SwapPhases, frame_a: Frame, frame_b: Frame assert swap_phase.get_qubits() == set([q.index for q in expected_qubits if isinstance(q, Qubit)]) assert swap_phase.get_qubits(False) == expected_qubits + def test_copy(self, swap_phase: SwapPhases): + assert isinstance(copy.copy(swap_phase), SwapPhases) + assert isinstance(copy.deepcopy(swap_phase), SwapPhases) + @pytest.mark.parametrize( ("left", "right"), @@ -1126,6 +1204,10 @@ def test_right(self, move: ClassicalMove, right: Union[MemoryReference, int, flo move.right = MemoryReference("new-memory-reference") assert move.right == MemoryReference("new-memory-reference") + def test_copy(self, move: ClassicalMove): + assert isinstance(copy.copy(move), ClassicalMove) + assert isinstance(copy.deepcopy(move), ClassicalMove) + @pytest.mark.parametrize( ("left", "right"), @@ -1149,6 +1231,10 @@ def test_right(self, exchange: ClassicalExchange, right: MemoryReference): exchange.right = MemoryReference("new-memory-reference") assert exchange.right == MemoryReference("new-memory-reference") + def test_copy(self, exchange: ClassicalExchange): + assert isinstance(copy.copy(exchange), ClassicalExchange) + assert isinstance(copy.deepcopy(exchange), ClassicalExchange) + @pytest.mark.parametrize( ("left", "right"), @@ -1172,6 +1258,10 @@ def test_right(self, convert: ClassicalConvert, right: MemoryReference): convert.right = MemoryReference("new-memory-reference") assert convert.right == MemoryReference("new-memory-reference") + def test_copy(self, convert: ClassicalConvert): + assert isinstance(copy.copy(convert), ClassicalConvert) + assert isinstance(copy.deepcopy(convert), ClassicalConvert) + @pytest.mark.parametrize( ("target", "left", "right"), @@ -1200,6 +1290,10 @@ def test_right(self, load: ClassicalLoad, right: MemoryReference): load.right = MemoryReference("new-memory-reference") assert load.right == MemoryReference("new-memory-reference") + def test_copy(self, load: ClassicalLoad): + assert isinstance(copy.copy(load), ClassicalLoad) + assert isinstance(copy.deepcopy(load), ClassicalLoad) + @pytest.mark.parametrize( ("target", "left", "right"), @@ -1232,6 +1326,10 @@ def test_right(self, load: ClassicalStore, right: Union[MemoryReference, int, fl load.right = MemoryReference("new-memory-reference") assert load.right == MemoryReference("new-memory-reference") + def test_copy(self, load: ClassicalStore): + assert isinstance(copy.copy(load), ClassicalStore) + assert isinstance(copy.deepcopy(load), ClassicalStore) + @pytest.mark.parametrize( ("op", "target", "left", "right"), @@ -1276,6 +1374,10 @@ def test_right(self, comparison: ClassicalComparison, right: Union[MemoryReferen comparison.right = MemoryReference("new-memory-reference") assert comparison.right == MemoryReference("new-memory-reference") + def test_copy(self, comparison: ClassicalComparison): + assert isinstance(copy.copy(comparison), type(comparison)) + assert isinstance(copy.deepcopy(comparison), type(comparison)) + @pytest.mark.parametrize( ("op", "target"), @@ -1300,6 +1402,10 @@ def test_target(self, unary: UnaryClassicalInstruction, target: MemoryReference) unary.target = MemoryReference("new-memory-reference") assert unary.target == MemoryReference("new-memory-reference") + def test_copy(self, unary: UnaryClassicalInstruction): + assert isinstance(copy.copy(unary), type(unary)) + assert isinstance(copy.deepcopy(unary), type(unary)) + @pytest.mark.parametrize( ("op", "left", "right"), @@ -1336,6 +1442,10 @@ def test_right(self, arithmetic: ArithmeticBinaryOp, right: Union[MemoryReferenc arithmetic.right = 3.14 assert arithmetic.right == 3.14 + def test_copy(self, arithmetic: ArithmeticBinaryOp): + assert isinstance(copy.copy(arithmetic), type(arithmetic)) + assert isinstance(copy.deepcopy(arithmetic), type(arithmetic)) + @pytest.mark.parametrize( ("op", "left", "right"), @@ -1367,6 +1477,10 @@ def test_right(self, logical: LogicalBinaryOp, right: Union[MemoryReference, flo logical.right = 3 assert logical.right == 3 + def test_copy(self, logical: LogicalBinaryOp): + assert isinstance(copy.copy(logical), type(logical)) + assert isinstance(copy.deepcopy(logical), type(logical)) + def test_include(): include = Include("my-cool-file.quil")