Skip to content

Commit

Permalink
fix: Unpickling an AbstractInstruction will result in an `Abstract…
Browse files Browse the repository at this point in the history
…Instruction` instead of a `quil` `Instruction` (#1801)

* fix: The DefMeasureCalibration class returns `pyQuil` `AbstractInstrutcion`s instead of `quil` `Instruction`s

* fix: Unpickling an AbstractInstruction will result in an AbstractInstruction instead of a `quil` Instruction

* fix ruff checks

* mypy is wrong

* fix tests

* fix typo

* fix assertion
  • Loading branch information
MarquessV authored Aug 13, 2024
1 parent 75fb322 commit 23967ca
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 4 deletions.
53 changes: 53 additions & 0 deletions pyquil/quilbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
Callable,
ClassVar,
Optional,
TypeVar,
Union,
)

Expand Down Expand Up @@ -104,6 +105,22 @@ def __hash__(self) -> int:
return hash(str(self))


_T = TypeVar("_T", bound=type)


def _add_reduce_method(cls: _T) -> _T:
def __reduce__(self: Any) -> tuple[Callable[[Any], AbstractInstruction], tuple[Any]]:
init_fn, args = super(cls, self).__reduce__() # type: ignore
obj = init_fn(*args)
return (
_convert_to_py_instruction,
(obj,),
)

cls.__reduce__ = __reduce__ # type: ignore
return cls


def _convert_to_rs_instruction(instr: Union[AbstractInstruction, quil_rs.Instruction]) -> quil_rs.Instruction:
if isinstance(instr, quil_rs.Instruction):
return instr
Expand Down Expand Up @@ -319,6 +336,7 @@ def _convert_to_py_instructions(instrs: Iterable[quil_rs.Instruction]) -> list[A
]


@_add_reduce_method
class Gate(quil_rs.Gate, AbstractInstruction):
"""A quantum gate instruction."""

Expand Down Expand Up @@ -488,6 +506,7 @@ def _strip_modifiers(gate: Gate, limit: Optional[int] = None) -> Gate:
return stripped


@_add_reduce_method
class Measurement(quil_rs.Measurement, AbstractInstruction):
"""A Quil measurement instruction."""

Expand Down Expand Up @@ -565,6 +584,7 @@ def __deepcopy__(self, memo: dict) -> "Measurement":
return Measurement._from_rs_measurement(super().__deepcopy__(memo))


@_add_reduce_method
class Reset(quil_rs.Reset, AbstractInstruction):
"""The RESET instruction."""

Expand Down Expand Up @@ -644,6 +664,7 @@ def _from_rs_reset(cls, reset: quil_rs.Reset) -> "ResetQubit":
raise ValueError("reset.qubit should not be None")


@_add_reduce_method
class DefGate(quil_rs.GateDefinition, AbstractInstruction):
"""A DEFGATE directive."""

Expand Down Expand Up @@ -840,6 +861,7 @@ def __str__(self) -> str:
return super().to_quil_or_debug()


@_add_reduce_method
class JumpTarget(quil_rs.Label, AbstractInstruction):
"""Representation of a target that can be jumped to."""

Expand Down Expand Up @@ -872,6 +894,7 @@ def __deepcopy__(self, memo: dict) -> "JumpTarget":
return JumpTarget._from_rs_label(super().__deepcopy__(memo))


@_add_reduce_method
class JumpWhen(quil_rs.JumpWhen, AbstractInstruction):
"""The JUMP-WHEN instruction."""

Expand Down Expand Up @@ -923,6 +946,7 @@ def __deepcopy__(self, memo: dict) -> "JumpWhen":
return JumpWhen._from_rs_jump_when(super().__deepcopy__(memo))


@_add_reduce_method
class JumpUnless(quil_rs.JumpUnless, AbstractInstruction):
"""The JUMP-UNLESS instruction."""

Expand Down Expand Up @@ -1011,6 +1035,7 @@ class Nop(SimpleInstruction):
instruction = quil_rs.Instruction.new_nop()


@_add_reduce_method
class UnaryClassicalInstruction(quil_rs.UnaryLogic, AbstractInstruction):
"""Base class for unary classical instructions."""

Expand Down Expand Up @@ -1061,6 +1086,7 @@ class ClassicalNot(UnaryClassicalInstruction):
op = quil_rs.UnaryOperator.Not


@_add_reduce_method
class LogicalBinaryOp(quil_rs.BinaryLogic, AbstractInstruction):
"""Base class for binary logical classical instructions."""

Expand Down Expand Up @@ -1142,6 +1168,7 @@ class ClassicalExclusiveOr(LogicalBinaryOp):
op = quil_rs.BinaryOperator.Xor


@_add_reduce_method
class ArithmeticBinaryOp(quil_rs.Arithmetic, AbstractInstruction):
"""Base class for binary arithmetic classical instructions."""

Expand Down Expand Up @@ -1216,6 +1243,7 @@ class ClassicalDiv(ArithmeticBinaryOp):
op = quil_rs.ArithmeticOperator.Divide


@_add_reduce_method
class ClassicalMove(quil_rs.Move, AbstractInstruction):
"""The MOVE instruction."""

Expand Down Expand Up @@ -1259,6 +1287,7 @@ def __deepcopy__(self, memo: dict) -> "ClassicalMove":
return ClassicalMove._from_rs_move(super().__deepcopy__(memo))


@_add_reduce_method
class ClassicalExchange(quil_rs.Exchange, AbstractInstruction):
"""The EXCHANGE instruction."""

Expand Down Expand Up @@ -1306,6 +1335,7 @@ def __deepcopy__(self, memo: dict) -> "ClassicalExchange":
return ClassicalExchange._from_rs_exchange(super().__deepcopy__(memo))


@_add_reduce_method
class ClassicalConvert(quil_rs.Convert, AbstractInstruction):
"""The CONVERT instruction."""

Expand Down Expand Up @@ -1349,6 +1379,7 @@ def __deepcopy__(self, memo: dict) -> "ClassicalConvert":
return ClassicalConvert._from_rs_convert(super().__deepcopy__(memo))


@_add_reduce_method
class ClassicalLoad(quil_rs.Load, AbstractInstruction):
"""The LOAD instruction."""

Expand Down Expand Up @@ -1420,6 +1451,7 @@ def _to_py_arithmetic_operand(operand: quil_rs.ArithmeticOperand) -> Union[Memor
return inner


@_add_reduce_method
class ClassicalStore(quil_rs.Store, AbstractInstruction):
"""The STORE instruction."""

Expand Down Expand Up @@ -1473,6 +1505,7 @@ def __deepcopy__(self, memo: dict) -> "ClassicalStore":
return ClassicalStore._from_rs_store(super().__deepcopy__(memo))


@_add_reduce_method
class ClassicalComparison(quil_rs.Comparison, AbstractInstruction):
"""Base class for ternary comparison instructions."""

Expand Down Expand Up @@ -1588,6 +1621,7 @@ class ClassicalGreaterEqual(ClassicalComparison):
op = quil_rs.ComparisonOperator.GreaterThanOrEqual


@_add_reduce_method
class Jump(quil_rs.Jump, AbstractInstruction):
"""Representation of an unconditional jump instruction (JUMP)."""

Expand Down Expand Up @@ -1624,6 +1658,7 @@ def __deepcopy__(self, memo: dict) -> "Jump":
return Jump._from_rs_jump(super().__deepcopy__(memo))


@_add_reduce_method
class Pragma(quil_rs.Pragma, AbstractInstruction):
"""A PRAGMA instruction.
Expand Down Expand Up @@ -1712,6 +1747,7 @@ def __deepcopy__(self, memo: dict) -> "Pragma":
return Pragma._from_rs_pragma(super().__deepcopy__(memo))


@_add_reduce_method
class Declare(quil_rs.Declaration, AbstractInstruction):
"""A DECLARE directive.
Expand Down Expand Up @@ -1838,6 +1874,7 @@ def __deepcopy__(self, memo: dict) -> "Declare":
return Declare._from_rs_declaration(super().__deepcopy__(memo))


@_add_reduce_method
class Include(quil_rs.Include, AbstractInstruction):
"""An INCLUDE directive."""

Expand All @@ -1859,6 +1896,7 @@ def __deepcopy__(self, memo: dict) -> "Include":
return Include._from_rs_include(super().__deepcopy__(memo))


@_add_reduce_method
class Pulse(quil_rs.Pulse, AbstractInstruction):
"""A PULSE instruction."""

Expand Down Expand Up @@ -1926,6 +1964,7 @@ def __deepcopy__(self, memo: dict) -> "Pulse":
return Pulse._from_rs_pulse(super().__deepcopy__(memo))


@_add_reduce_method
class SetFrequency(quil_rs.SetFrequency, AbstractInstruction):
"""A SET-FREQUENCY instruction."""

Expand Down Expand Up @@ -1983,6 +2022,7 @@ def __deepcopy__(self, memo: dict) -> "SetFrequency":
return SetFrequency._from_rs_set_frequency(super().__deepcopy__(memo))


@_add_reduce_method
class ShiftFrequency(quil_rs.ShiftFrequency, AbstractInstruction):
"""The SHIFT-FREQUENCY instruction."""

Expand Down Expand Up @@ -2040,6 +2080,7 @@ def __deepcopy__(self, memo: dict) -> "ShiftFrequency":
return ShiftFrequency._from_rs_shift_frequency(super().__deepcopy__(memo))


@_add_reduce_method
class SetPhase(quil_rs.SetPhase, AbstractInstruction):
"""The SET-PHASE instruction."""

Expand Down Expand Up @@ -2097,6 +2138,7 @@ def __deepcopy__(self, memo: dict) -> "SetPhase":
return SetPhase._from_rs_set_phase(super().__deepcopy__(memo))


@_add_reduce_method
class ShiftPhase(quil_rs.ShiftPhase, AbstractInstruction):
"""The SHIFT-PHASE instruction."""

Expand Down Expand Up @@ -2154,6 +2196,7 @@ def __deepcopy__(self, memo: dict) -> "ShiftPhase":
return ShiftPhase._from_rs_shift_phase(super().__deepcopy__(memo))


@_add_reduce_method
class SwapPhases(quil_rs.SwapPhases, AbstractInstruction):
"""The SWAP-PHASES instruction."""

Expand Down Expand Up @@ -2211,6 +2254,7 @@ def __deepcopy__(self, memo: dict) -> "SwapPhases":
return SwapPhases._from_rs_swap_phases(super().__deepcopy__(memo))


@_add_reduce_method
class SetScale(quil_rs.SetScale, AbstractInstruction):
"""The SET-SCALE instruction."""

Expand Down Expand Up @@ -2268,6 +2312,7 @@ def __deepcopy__(self, memo: dict) -> "SetScale":
return SetScale._from_rs_set_scale(super().__deepcopy__(memo))


@_add_reduce_method
class Capture(quil_rs.Capture, AbstractInstruction):
"""The CAPTURE instruction."""

Expand Down Expand Up @@ -2352,6 +2397,7 @@ def __deepcopy__(self, memo: dict) -> "Capture":
return Capture._from_rs_capture(super().__deepcopy__(memo))


@_add_reduce_method
class RawCapture(quil_rs.RawCapture, AbstractInstruction):
"""The RAW-CAPTURE instruction."""

Expand Down Expand Up @@ -2440,6 +2486,7 @@ def __deepcopy__(self, memo: dict) -> "RawCapture":
return RawCapture._from_rs_raw_capture(super().__deepcopy__(memo))


@_add_reduce_method
class Delay(quil_rs.Delay, AbstractInstruction):
"""The DELAY instruction."""

Expand Down Expand Up @@ -2534,6 +2581,7 @@ def _from_rs_delay(cls, delay: quil_rs.Delay) -> "DelayQubits":
return Delay._from_rs_delay.__func__(cls, delay) # type: ignore


@_add_reduce_method
class Fence(quil_rs.Fence, AbstractInstruction):
"""The FENCE instruction."""

Expand Down Expand Up @@ -2579,6 +2627,7 @@ def __new__(cls) -> Self:
return super().__new__(cls, [])


@_add_reduce_method
class DefWaveform(quil_rs.WaveformDefinition, AbstractInstruction):
"""A waveform definition."""

Expand Down Expand Up @@ -2637,6 +2686,7 @@ def __deepcopy__(self, memo: dict) -> "DefWaveform":
return DefWaveform._from_rs_waveform_definition(super().__deepcopy__(memo))


@_add_reduce_method
class DefCircuit(quil_rs.CircuitDefinition, AbstractInstruction):
"""A circuit definition."""

Expand Down Expand Up @@ -2707,6 +2757,7 @@ def __deepcopy__(self, memo: dict) -> "DefCircuit":
return DefCircuit._from_rs_circuit_definition(super().__deepcopy__(memo))


@_add_reduce_method
class DefCalibration(quil_rs.Calibration, AbstractInstruction):
"""A calibration definition."""

Expand Down Expand Up @@ -2789,6 +2840,7 @@ def __deepcopy__(self, memo: dict) -> "DefCalibration":
return DefCalibration._from_rs_calibration(super().__deepcopy__(memo))


@_add_reduce_method
class DefMeasureCalibration(quil_rs.MeasureCalibrationDefinition, AbstractInstruction):
"""A measure calibration definition."""

Expand Down Expand Up @@ -2866,6 +2918,7 @@ def __deepcopy__(self, memo: dict) -> "DefMeasureCalibration":
return DefMeasureCalibration._from_rs_measure_calibration_definition(super().__deepcopy__(memo))


@_add_reduce_method
class DefFrame(quil_rs.FrameDefinition, AbstractInstruction):
"""A frame definition."""

Expand Down
Loading

0 comments on commit 23967ca

Please sign in to comment.