Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions qiskit/algorithms/amplitude_amplifiers/grover.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from qiskit import ClassicalRegister, QuantumCircuit
from qiskit.algorithms.exceptions import AlgorithmError
from qiskit.primitives import BaseSampler
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.quantum_info import partial_trace, Statevector
from qiskit.utils import QuantumInstance, algorithm_globals
from qiskit.utils.deprecation import deprecate_arg, deprecate_func
Expand Down Expand Up @@ -221,7 +221,7 @@ def quantum_instance(self, quantum_instance: QuantumInstance | Backend) -> None:
Args:
quantum_instance: The quantum instance used to run this algorithm.
"""
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance

Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/amplitude_estimators/ae.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from scipy.optimize import bisect

from qiskit import QuantumCircuit, ClassicalRegister
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.primitives import BaseSampler
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_arg, deprecate_func
Expand Down Expand Up @@ -157,7 +157,7 @@ def quantum_instance(self, quantum_instance: QuantumInstance | Backend) -> None:
Args:
quantum_instance: The quantum instance used to run this algorithm.
"""
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance

Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/amplitude_estimators/fae.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import numpy as np

from qiskit.circuit import QuantumCircuit, ClassicalRegister
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.primitives import BaseSampler
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_arg, deprecate_func
Expand Down Expand Up @@ -135,7 +135,7 @@ def quantum_instance(self, quantum_instance: QuantumInstance | Backend) -> None:
Args:
quantum_instance: The quantum instance used to run this algorithm.
"""
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance

Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/amplitude_estimators/iae.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from scipy.stats import beta

from qiskit import ClassicalRegister, QuantumCircuit
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.primitives import BaseSampler
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_arg, deprecate_func
Expand Down Expand Up @@ -158,7 +158,7 @@ def quantum_instance(self, quantum_instance: QuantumInstance | Backend) -> None:
Args:
quantum_instance: The quantum instance used to run this algorithm.
"""
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance

Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/amplitude_estimators/mlae.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from scipy.optimize import brute
from scipy.stats import norm, chi2

from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit
from qiskit.utils import QuantumInstance
from qiskit.primitives import BaseSampler
Expand Down Expand Up @@ -162,7 +162,7 @@ def quantum_instance(self, quantum_instance: QuantumInstance | Backend) -> None:
Args:
quantum_instance: The quantum instance used to run this algorithm.
"""
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance

Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/evolvers/trotterization/trotter_qrte.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
OperatorBase,
)
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.synthesis import ProductFormula, LieTrotter
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_func
Expand Down Expand Up @@ -125,7 +125,7 @@ def quantum_instance(self, quantum_instance: QuantumInstance | Backend | None) -
Args:
quantum_instance: The quantum instance used to run this algorithm.
"""
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)

self._circuit_sampler = None
Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/phase_estimators/ipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import qiskit
from qiskit.circuit import QuantumCircuit, QuantumRegister
from qiskit.circuit.classicalregister import ClassicalRegister
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_arg
from qiskit.algorithms.exceptions import AlgorithmError
Expand Down Expand Up @@ -68,7 +68,7 @@ def __init__(
raise AlgorithmError(
"Neither a sampler nor a quantum instance was provided. Please provide one of them."
)
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance
if num_iterations <= 0:
Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/phase_estimators/phase_estimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import qiskit
from qiskit import circuit
from qiskit.circuit.classicalregister import ClassicalRegister
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_arg
from qiskit.result import Result
Expand Down Expand Up @@ -114,7 +114,7 @@ def __init__(
if num_evaluation_qubits is not None:
self._num_evaluation_qubits = num_evaluation_qubits

if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance
self._sampler = sampler
Expand Down
4 changes: 2 additions & 2 deletions qiskit/execute_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from time import time

from qiskit.compiler import transpile, schedule
from qiskit.providers.backend import Backend
from qiskit.providers.backend import is_backend
from qiskit.pulse import Schedule, ScheduleBlock
from qiskit.exceptions import QiskitError
from qiskit.utils.deprecation import deprecate_arg
Expand Down Expand Up @@ -319,7 +319,7 @@ def execute(
method=scheduling_method,
)

if isinstance(backend, Backend):
if is_backend(backend):
start_time = time()
run_kwargs = {
"shots": shots,
Expand Down
4 changes: 2 additions & 2 deletions qiskit/opflow/converters/circuit_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from qiskit.opflow.state_fns.circuit_state_fn import CircuitStateFn
from qiskit.opflow.state_fns.dict_state_fn import DictStateFn
from qiskit.opflow.state_fns.state_fn import StateFn
from qiskit.providers import Backend
from qiskit.providers import Backend, is_backend
from qiskit.utils.backend_utils import is_aer_provider, is_statevector_backend
from qiskit.utils.quantum_instance import QuantumInstance
from qiskit.utils.deprecation import deprecate_func
Expand Down Expand Up @@ -140,7 +140,7 @@ def quantum_instance(self, quantum_instance: Union[QuantumInstance, Backend]) ->
Raises:
ValueError: statevector or param_qobj are True when not supported by backend.
"""
if isinstance(quantum_instance, Backend):
if is_backend(quantum_instance):
quantum_instance = QuantumInstance(quantum_instance)
self._quantum_instance = quantum_instance
self._check_quantum_instance_and_modes_consistent()
Expand Down
1 change: 1 addition & 0 deletions qiskit/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ def status(self):
from qiskit.providers.backend import Backend
from qiskit.providers.backend import BackendV1
from qiskit.providers.backend import BackendV2
from qiskit.providers.backend import is_backend_v1, is_backend_v2, is_backend
from qiskit.providers.backend import QubitProperties
from qiskit.providers.backend_compat import BackendV2Converter
from qiskit.providers.backend_compat import convert_to_target
Expand Down
52 changes: 33 additions & 19 deletions qiskit/providers/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,19 @@
"""Backend abstract interface for providers."""


from abc import ABC
from abc import abstractmethod
import datetime
from typing import List, Union, Iterable, Tuple
import typing
from abc import ABC, abstractmethod
from typing import Any, Iterable, List, Tuple, Union

from qiskit.providers.provider import Provider
from qiskit.providers.models.backendstatus import BackendStatus
from qiskit.circuit.gate import Instruction


class Backend:
"""Base common type for all versioned Backend abstract classes.
from typing_extensions import TypeAlias, TypeGuard

Note this class should not be inherited from directly, it is intended
to be used for type checking. When implementing a provider you should use
the versioned abstract classes as the parent class and not this class
directly.
"""

version = 0
from qiskit.circuit.gate import Instruction
from qiskit.providers.models.backendstatus import BackendStatus
from qiskit.providers.provider import Provider


class BackendV1(Backend, ABC):
class BackendV1(ABC):
"""Abstract class for Backends

This abstract class is to be used for all Backend objects created by a
Expand Down Expand Up @@ -265,7 +255,7 @@ def __repr__(self):
return f"QubitProperties(t1={self.t1}, t2={self.t2}, " f"frequency={self.frequency})"


class BackendV2(Backend, ABC):
class BackendV2(ABC):
"""Abstract class for Backends

This abstract class is to be used for all Backend objects created by a
Expand Down Expand Up @@ -635,3 +625,27 @@ class can handle either situation.
Job: The job object for the run
"""
pass


Backend: TypeAlias = Union[BackendV1, BackendV2]
"""Type that represents any backend type version.

Use this type for functions that take a backend in any version.
The :func:`is_backend_v1` and :func:`is_backend_v2` functions can
be used to narrow the type appropriately.
"""


def is_backend(obj: Any) -> TypeGuard[Backend]:
"""Type guard that narrows an object to the Backend union type."""
return isinstance(obj, typing.get_args(Backend))


def is_backend_v1(obj: Backend) -> TypeGuard[BackendV1]:
"""Type guard that narrows a backend instance to the BackendV1 type."""
return isinstance(obj, BackendV1)


def is_backend_v2(obj: Backend) -> TypeGuard[BackendV2]:
"""Type guard that narrows a backend instance to the BackendV2 type."""
return isinstance(obj, BackendV2)
4 changes: 2 additions & 2 deletions qiskit/utils/quantum_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ def __init__(

# if the shots are none, try to get them from the backend
if shots is None:
from qiskit.providers.backend import Backend # pylint: disable=cyclic-import
from qiskit.providers.backend import is_backend # pylint: disable=cyclic-import

if isinstance(backend, Backend):
if is_backend(backend):
if hasattr(backend, "options"): # should always be true for V1
backend_shots = backend.options.get("shots", 1024)
if shots != backend_shots:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
features:
- |
Define the :class:`qiskit.providers.Backend` type as a union of all
existing backend versions types instead of an empty base class.
Functions that take a backend can handle the corresponding argument in a
uniform and typed manner as:

```python
from qiskit.providers import Backend, BackendV2, BackendV2Converter, is_backend_v2
from typing_extensions import backend_v2

def func(backend: Backend) -> None:
if is_backend_v1(backend):
backend_v2 = BackendV2Converter(backend)
else:
backend_v2 = backend

assert_type(backend_v2, BackendV2)
print(backend_v2.name)
```