Skip to content

Commit

Permalink
Fix deprecation warnings emitted by import qiskit.primitives (#10287)
Browse files Browse the repository at this point in the history
The primitives still need to support the legacy
`qiskit.opflow.PauliSumOp` while that object is deprecated but not
removed.  However, we do not want the import of `qiskit.primitives` to
need to import `opflow` to do that, since that will cause the
deprecation warnings emitted by the import of `opflow` to be hidden
(they'll be blamed on Qiskit library code, so hidden by default).

All type-hint usage we can hide behind the `TYPE_CHECKING` static
analysis gate.  For cases where we were actively runtime type-checking
an object, we can gate the `isinstance` check behind a check that
`qiskit.opflow` is already imported; the object cannot be a `PauliSumOp`
if the module isn't initialised.

(cherry picked from commit 81964e6)
  • Loading branch information
jakelishman authored and mergify[bot] committed Jun 15, 2023
1 parent 9f18b91 commit 64d8d2c
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 5 deletions.
5 changes: 4 additions & 1 deletion qiskit/primitives/backend_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
from __future__ import annotations

import copy
import typing
from collections.abc import Sequence
from itertools import accumulate

import numpy as np

from qiskit.circuit import QuantumCircuit
from qiskit.compiler import transpile
from qiskit.opflow import PauliSumOp
from qiskit.providers import BackendV1, BackendV2, Options
from qiskit.quantum_info import Pauli, PauliList
from qiskit.quantum_info.operators.base_operator import BaseOperator
Expand All @@ -34,6 +34,9 @@
from .primitive_job import PrimitiveJob
from .utils import _circuit_key, _observable_key, init_observable

if typing.TYPE_CHECKING:
from qiskit.opflow import PauliSumOp


def _run_circuits(
circuits: QuantumCircuit | list[QuantumCircuit],
Expand Down
5 changes: 4 additions & 1 deletion qiskit/primitives/base/base_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,20 @@
from collections.abc import Sequence
from copy import copy
from typing import Generic, TypeVar
import typing

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.parametertable import ParameterView
from qiskit.opflow import PauliSumOp
from qiskit.providers import JobV1 as Job
from qiskit.quantum_info.operators import SparsePauliOp
from qiskit.quantum_info.operators.base_operator import BaseOperator

from ..utils import init_observable
from .base_primitive import BasePrimitive

if typing.TYPE_CHECKING:
from qiskit.opflow import PauliSumOp

T = TypeVar("T", bound=Job)


Expand Down
5 changes: 4 additions & 1 deletion qiskit/primitives/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@

from collections.abc import Sequence
from typing import Any
import typing

import numpy as np

from qiskit.circuit import QuantumCircuit
from qiskit.exceptions import QiskitError
from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import Statevector
from qiskit.quantum_info.operators.base_operator import BaseOperator

Expand All @@ -35,6 +35,9 @@
init_observable,
)

if typing.TYPE_CHECKING:
from qiskit.opflow import PauliSumOp


class Estimator(BaseEstimator[PrimitiveJob[EstimatorResult]]):
"""
Expand Down
17 changes: 15 additions & 2 deletions qiskit/primitives/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@
"""
from __future__ import annotations

import sys
import typing
from collections.abc import Iterable

import numpy as np

from qiskit.circuit import Instruction, ParameterExpression, QuantumCircuit
from qiskit.circuit.bit import Bit
from qiskit.extensions.quantum_initializer.initializer import Initialize
from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp, Statevector
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.quantum_info.operators.symplectic.base_pauli import BasePauli

if typing.TYPE_CHECKING:
from qiskit.opflow import PauliSumOp


def init_circuit(state: QuantumCircuit | Statevector) -> QuantumCircuit:
"""Initialize state by converting the input to a quantum circuit.
Expand Down Expand Up @@ -58,9 +62,18 @@ def init_observable(observable: BaseOperator | PauliSumOp | str) -> SparsePauliO
TypeError: If the observable is a :class:`~qiskit.opflow.PauliSumOp` and has a parameterized
coefficient.
"""
# This dance is to avoid importing the deprecated `qiskit.opflow` if the user hasn't already
# done so. They can't hold a `qiskit.opflow.PauliSumOp` if `qiskit.opflow` hasn't been
# imported, and we don't want unrelated Qiskit library code to be responsible for the first
# import, so the deprecation warnings will show.
if "qiskit.opflow" in sys.modules:
pauli_sum_check = sys.modules["qiskit.opflow"].PauliSumOp
else:
pauli_sum_check = ()

if isinstance(observable, SparsePauliOp):
return observable
elif isinstance(observable, PauliSumOp):
elif isinstance(observable, pauli_sum_check):
if isinstance(observable.coeff, ParameterExpression):
raise TypeError(
f"Observable must have numerical coefficient, not {type(observable.coeff)}."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
fixes:
- |
Importing :mod:`qiskit.primitives` will no longer cause deprecation warnings stemming from the
deprecated :mod:`qiskit.opflow` module. These warnings would have been hidden to users by the
default Python filters, but triggered the eager import of :mod:`.opflow`, which meant that a
subsequent import by a user would not trigger the warnings.

0 comments on commit 64d8d2c

Please sign in to comment.