diff --git a/qiskit/primitives/containers/data_bin.py b/qiskit/primitives/containers/data_bin.py index 21252d2ef906..cb6efcc4f42c 100644 --- a/qiskit/primitives/containers/data_bin.py +++ b/qiskit/primitives/containers/data_bin.py @@ -103,9 +103,6 @@ def __init__(self, *, shape: ShapeInput = (), **data): def __len__(self): return len(self._data) - def __setattr__(self, *_): - raise NotImplementedError - def __repr__(self): vals = [f"{name}={_value_repr(val)}" for name, val in self.items()] if self.ndim: diff --git a/qiskit/primitives/primitive_job.py b/qiskit/primitives/primitive_job.py index 64ab8d016095..580ab5930df5 100644 --- a/qiskit/primitives/primitive_job.py +++ b/qiskit/primitives/primitive_job.py @@ -35,6 +35,8 @@ def __init__(self, function, *args, **kwargs): super().__init__(str(uuid.uuid4())) self._future = None self._function = function + self._result = None + self._status = None self._args = args self._kwargs = kwargs @@ -46,19 +48,31 @@ def _submit(self): self._future = executor.submit(self._function, *self._args, **self._kwargs) executor.shutdown(wait=False) + def _prepare_dump(self): + """This method allows PrimitiveJob to be serialized""" + _ = self.result() + _ = self.status() + self._future = None + def result(self) -> ResultT: - self._check_submitted() - return self._future.result() + if self._result is None: + self._check_submitted() + self._result = self._future.result() + return self._result def status(self) -> JobStatus: - self._check_submitted() - if self._future.running(): - return JobStatus.RUNNING - elif self._future.cancelled(): - return JobStatus.CANCELLED - elif self._future.done() and self._future.exception() is None: - return JobStatus.DONE - return JobStatus.ERROR + if self._status is None: + self._check_submitted() + if self._future.running(): + # we should not store status running because it is not completed + return JobStatus.RUNNING + elif self._future.cancelled(): + self._status = JobStatus.CANCELLED + elif self._future.done() and self._future.exception() is None: + self._status = JobStatus.DONE + else: + self._status = JobStatus.ERROR + return self._status def _check_submitted(self): if self._future is None: diff --git a/releasenotes/notes/serialize-primitive-job-aa97d0bf8221ea99.yaml b/releasenotes/notes/serialize-primitive-job-aa97d0bf8221ea99.yaml new file mode 100644 index 000000000000..071de1e35a9d --- /dev/null +++ b/releasenotes/notes/serialize-primitive-job-aa97d0bf8221ea99.yaml @@ -0,0 +1,5 @@ +--- +features_primitives: + - | + To make :class:`.PrimitiveJob` serializable, ``qiskit.primitives.containers.DataBin`` has been + updated to be pickleable. As a result, :class:`.PrimitiveResult` is now also pickleable.