diff --git a/crates/accelerate/src/quantum_circuit/circuit_data.rs b/crates/accelerate/src/quantum_circuit/circuit_data.rs index c162e5237efc..fceb689c0751 100644 --- a/crates/accelerate/src/quantum_circuit/circuit_data.rs +++ b/crates/accelerate/src/quantum_circuit/circuit_data.rs @@ -40,6 +40,10 @@ pub struct CircuitData { #[derive(FromPyObject)] pub struct ElementType { + // Note that _operation_wrapper is used only to support c_if, + // which on the Python-side swaps out the operation that the + // wrapper points to. + #[pyo3(attribute("_operation_wrapper"))] operation: PyObject, qubits: Py, clbits: Py, diff --git a/qiskit/circuit/quantumcircuitdata.py b/qiskit/circuit/quantumcircuitdata.py index 7783c5e41815..2042262e630a 100644 --- a/qiskit/circuit/quantumcircuitdata.py +++ b/qiskit/circuit/quantumcircuitdata.py @@ -23,6 +23,13 @@ from .classicalregister import Clbit +class _OperationWrapper: + operation: Operation + + def __init__(self, op: Operation): + self.operation = op + + class CircuitInstruction: """A single instruction in a :class:`.QuantumCircuit`, comprised of the :attr:`operation` and various operands. @@ -58,10 +65,20 @@ class CircuitInstruction: of distinct items, with no duplicates. """ - __slots__ = ("operation", "qubits", "clbits") + __slots__ = ("_operation_wrapper", "qubits", "clbits") + + _operation_wrapper: _OperationWrapper + + @property + def operation(self) -> Operation: + """The logical operation that this instruction represents an execution of.""" + return self._operation_wrapper.operation + + @operation.setter + def operation(self, op: Operation): + """Updates in place the logical operation that this instruction represents an execution of.""" + self._operation_wrapper.operation = op - operation: Operation - """The logical operation that this instruction represents an execution of.""" qubits: Tuple[Qubit, ...] """A sequence of the qubits that the operation is applied to.""" clbits: Tuple[Clbit, ...] @@ -73,14 +90,14 @@ def __init__( qubits: Iterable[Qubit] = (), clbits: Iterable[Clbit] = (), ): - self.operation = operation + self._operation_wrapper = operation if isinstance(operation, _OperationWrapper) else _OperationWrapper(operation) self.qubits = tuple(qubits) self.clbits = tuple(clbits) def copy(self) -> "CircuitInstruction": """Return a shallow copy of the :class:`CircuitInstruction`.""" return self.__class__( - operation=self.operation, + operation=self._operation_wrapper, qubits=self.qubits, clbits=self.clbits, )