Source code for qurry.tools.backend.import_fake

"""Import Fake (:mod:`qurry.tools.backend.import_fake`)

This file is used to unify the import point of `FakeProvider`, `FakeBackend`/`FakeBackendV2`
from :mod:`qiskit.providers.fake_provider` and :mod:`qiskit_ibm_runtime.fake_provider`.
Avoiding the import error occurs on different parts of Qurrium.

"""

from typing import Literal, Type, Union, Optional, overload
import warnings

from qiskit.providers import BackendV2, Backend

from .utils import backend_name_getter, shorten_name
from ...exceptions import QurryDependenciesNotWorking, QurryDependenciesFailureError

# pylint: disable=ungrouped-imports
ImportPointType = Literal[
    "qiskit_ibm_runtime.fake_provider",
    "qiskit.providers.fake_provider",
]
ImportPointOrder: list[ImportPointType] = [
    "qiskit_ibm_runtime.fake_provider",
    "qiskit.providers.fake_provider",
]
FAKE_BACKENDV2_SOURCES: dict[ImportPointType, Optional[Type[BackendV2]]] = {}
FAKE_PROVIDERFORV2_SOURCES: dict[
    ImportPointType,
    Optional[Union[Type["FakeProviderForBackendV2Dep"], Type["FakeProviderForBackendV2Indep"]]],
] = {}
FAKE_VERSION_INFOS: dict[ImportPointType, Optional[str]] = {}
FAKE_IMPORT_ERROR_INFOS: dict[ImportPointType, ImportError] = {}

QISKIT_IBM_RUNTIME_ISSUE_1318 = (
    "The version of 'qiskit-ibm-runtime' is 0.18.0, "
    "FackBackend is not working in this version for this issue: "
    "https://github.com/Qiskit/qiskit-ibm-runtime/issues/1318."
    "You need to change the version of 'qiskit-ibm-runtime' to access FakeBackend"
)
"""Qiskit IBM Runtime Issue 1318

This is a warning message for the issue 
that FakeBackend is not working in qiskit-ibm-runtime 0.18.0.
It is caused by the issue: https://github.com/Qiskit/qiskit-ibm-runtime/issues/1318.
"""

try:
    from qiskit_ibm_runtime import __version__ as qiskit_ibm_runtime_version  # type: ignore

    major, minor, _ = qiskit_ibm_runtime_version.split(".")
    IS_V1_REMOVE = int(major) >= 0 and int(minor) >= 31
    if major == "18" and minor == "0":
        warnings.warn(
            QISKIT_IBM_RUNTIME_ISSUE_1318,
            category=QurryDependenciesNotWorking,
        )

    from qiskit_ibm_runtime.fake_provider import (  # type: ignore
        FakeProviderForBackendV2 as FakeProviderForBackendV2Indep,  # type: ignore
    )
    from qiskit_ibm_runtime.fake_provider.fake_backend import (  # type: ignore
        FakeBackendV2 as FakeBackendV2Indep,  # type: ignore
    )

    FAKE_BACKENDV2_SOURCES["qiskit_ibm_runtime.fake_provider"] = FakeBackendV2Indep
    FAKE_PROVIDERFORV2_SOURCES["qiskit_ibm_runtime.fake_provider"] = FakeProviderForBackendV2Indep
    FAKE_VERSION_INFOS["qiskit_ibm_runtime.fake_provider"] = qiskit_ibm_runtime_version

except ImportError as err:
    FAKE_IMPORT_ERROR_INFOS["qiskit_ibm_runtime.fake_provider"] = err

if len(FAKE_BACKENDV2_SOURCES) == 0:
    try:
        from qiskit.providers.fake_provider import (
            FakeProviderForBackendV2 as FakeProviderForBackendV2Dep,  # type: ignore
            FakeBackendV2 as FakeBackendV2Dep,  # type: ignore
        )
        from qiskit import __version__ as qiskit_version

        FAKE_BACKENDV2_SOURCES["qiskit.providers.fake_provider"] = FakeBackendV2Dep
        FAKE_PROVIDERFORV2_SOURCES["qiskit.providers.fake_provider"] = FakeProviderForBackendV2Dep
        FAKE_VERSION_INFOS["qiskit.providers.fake_provider"] = qiskit_version

    except ImportError as err:
        FAKE_IMPORT_ERROR_INFOS["qiskit.providers.fake_provider"] = err


[docs] def get_default_fake_provider() -> Optional[ImportPointType]: """Get the default fake provider. Returns: ImportPointType: The default fake provider. """ for source in ImportPointOrder: if source in FAKE_PROVIDERFORV2_SOURCES: return source return None
FAKE_DEFAULT_SOURCE: Optional[ImportPointType] = get_default_fake_provider() LUCKY_MSG = """ No fake provider available. It may be caused by version conflict. For qiskit<1.0.0 please install qiskit-ibm-runtime<0.21.0 by 'pip install qiskit-ibm-runtime<0.21.0'. If you are still using qiskit 0.46.X and lower originally, then install newer qiskit-ibm-runtime at same time, please check whether the version of qiskit has been updated to 1.0 by the installation because since qiskit-ibm-runtime 0.21.0+ has been updated its dependency to qiskit 1.0. If you already have qiskit-ibm-runtimes installed and lower than 0.21.0, it is only available to use qiskit 0.46.X as dependency for the migration of fake_provider is not completed around this version. Many of the fake backends are not available in qiskit-ibm-runtime. (This made me a lot problem to handle the fake backends in Qurry.) (If you see this error raised, good luck to you to fix environment. :smile:.) """.replace( "\n", " " ).strip() """A warning message for the fake backend not available. """ @overload def fack_backend_loader() -> tuple[dict[str, str], dict[str, Backend]]: ... @overload def fack_backend_loader() -> tuple[dict[str, str], dict[str, Backend]]: ...
[docs] def fack_backend_loader(): """Load the fake backend. Args: version (str, optional): The version of fake backend. Defaults to None. "v1" for FakeProvider, "v2" for FakeProviderForBackendV2. Returns: tuple[dict[str, str], dict[str, Backend]]: The callsign of fake backend, the fake backend dict, the fake provider. """ if FAKE_DEFAULT_SOURCE is None: warnings.warn(LUCKY_MSG, category=QurryDependenciesNotWorking) return {}, {} _fake_provider_v2_becalled = FAKE_PROVIDERFORV2_SOURCES.get(FAKE_DEFAULT_SOURCE, None) if _fake_provider_v2_becalled is None: raise QurryDependenciesFailureError(LUCKY_MSG) try: _fake_provider = _fake_provider_v2_becalled() except FileNotFoundError as err1318: raise QurryDependenciesFailureError(QISKIT_IBM_RUNTIME_ISSUE_1318) from err1318 backend_fake: dict[str, Backend] = { backend_name_getter(b): b for b in _fake_provider.backends() } backend_fake_callsign = {shorten_name(bn, ["_v2"]): bn for bn in backend_fake} backend_fake_callsign["fake_qasm"] = "fake_qasm_simulator" return backend_fake_callsign, backend_fake