Skip to content

Commit

Permalink
Remove deprecate IBMQ dependent functionality
Browse files Browse the repository at this point in the history
This commit removes all the functionality in Qiskit that depended on the
legacy qiskit-ibmq-provider package. This process was started in Qiskit#10525
which removed the qiskit.IBMQ alias object but as was discovered in that
PR there were many other places in qiskit that were relying on the
qiskit-ibmq-provider package. This commit removes all of these places,
which primarily include qiskit.test.decorators's online_test decorator,
qiskit.tools.jupyter, qiskit.tools.monitor, qiskit.test.ibmq_mock, and
qiskit.test.mock (which just referenced IBMQ and didn't actually use
it). With these removals we're also no longer optionally dependent on
ipywidgets, jupyter, or ipython and those are removed from the optional
and development requirements lists.
  • Loading branch information
mtreinish committed Jan 8, 2024
1 parent 3263355 commit 6fbde9d
Show file tree
Hide file tree
Showing 80 changed files with 38 additions and 4,876 deletions.
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ qasm3-import = [
]
visualization = [
"matplotlib >= 3.3",
"ipywidgets >= 7.3.0",
"pydot",
"Pillow >= 4.2.1",
"pylatexenc >= 1.4",
Expand Down
54 changes: 1 addition & 53 deletions qiskit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@

_config = _user_config.get_config()

# Moved to after IBMQ and Aer imports due to import issues
# with other modules that check for IBMQ (tools)
# Moved to after Aer imports due to import issues
from qiskit.execute_function import execute
from qiskit.compiler import transpile, assemble, schedule, sequence

Expand Down Expand Up @@ -125,64 +124,13 @@ def __getattr__(self, attr):
return getattr(self.aer, attr)


class IBMQWrapper:
"""Lazy loading wrapper for IBMQ provider."""

def __init__(self):
self.ibmq = None

def __bool__(self):
if self.ibmq is None:
try:
from qiskit.providers import ibmq

self.ibmq = ibmq.IBMQ
warnings.warn(
"The qiskit.IBMQ entrypoint and the qiskit-ibmq-provider package ("
"accessible from 'qiskit.providers.ibmq`) are deprecated and will be removed "
"in a future release. Instead you should use the qiskit-ibm-provider package "
"which is accessible from 'qiskit_ibm_provider'. You can install it with "
"'pip install qiskit_ibm_provider'",
DeprecationWarning,
stacklevel=2,
)

except ImportError:
return False
return True

def __getattr__(self, attr):
if not self.ibmq:
try:
from qiskit.providers import ibmq

self.ibmq = ibmq.IBMQ
warnings.warn(
"The qiskit.IBMQ entrypoint and the qiskit-ibmq-provider package ("
"accessible from 'qiskit.providers.ibmq`) are deprecated and will be removed "
"in a future release. Instead you should use the qiskit-ibm-provider package "
"which is accessible from 'qiskit_ibm_provider'. You can install it with "
"'pip install qiskit_ibm_provider'. Just replace 'qiskit.IBMQ' with "
"'qiskit_ibm_provider.IBMProvider'",
DeprecationWarning,
stacklevel=2,
)
except ImportError as ex:
raise MissingOptionalLibraryError(
"qiskit-ibmq-provider", "IBMQ provider", "pip install qiskit-ibmq-provider"
) from ex
return getattr(self.ibmq, attr)


Aer = AerWrapper()
IBMQ = IBMQWrapper()

__all__ = [
"Aer",
"AncillaRegister",
"BasicAer",
"ClassicalRegister",
"IBMQ",
"MissingOptionalLibraryError",
"QiskitError",
"QuantumCircuit",
Expand Down
2 changes: 1 addition & 1 deletion qiskit/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ def get_translation_stage_plugin(self):
handles submitting the circuits to the backend to be executed and returning a
:class:`~qiskit.providers.Job` object. Depending on the type of backend this
typically involves serializing the circuit object into the API format used by a
backend. For example, on IBMQ backends from the ``qiskit-ibmq-provider``
backend. For example, on IBM backends from the ``qiskit-ibm-provider``
package this involves converting from a quantum circuit and options into a
`qobj <https://arxiv.org/abs/1809.03452>`__ JSON payload and submitting
that to the IBM Quantum API. Since every backend interface is different (and
Expand Down
13 changes: 0 additions & 13 deletions qiskit/providers/fake_provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,6 @@
run noisy simulations to compare with the real quantum system, please follow steps below to
generate a simulator mimics a real quantum system with the latest calibration results.
.. code-block:: python
from qiskit.providers.ibmq import IBMQ
from qiskit.providers.aer import AerSimulator
# get a real backend from a real provider
provider = IBMQ.load_account()
backend = provider.get_backend('ibmq_manila')
# generate a simulator that mimics the real quantum system with the latest calibration results
backend_sim = AerSimulator.from_backend(backend)
Fake Providers
==============
Expand Down
2 changes: 1 addition & 1 deletion qiskit/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"""Functionality and helpers for testing Qiskit."""

from .base import QiskitTestCase
from .decorators import requires_aer_provider, online_test, slow_test
from .decorators import requires_aer_provider, slow_test
from .reference_circuits import ReferenceCircuits
from .utils import Path
2 changes: 0 additions & 2 deletions qiskit/test/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ def tearDown(self):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Determines if the TestCase is using IBMQ credentials.
cls.using_ibmq_credentials = False
# Set logging to file and stdout if the LOG_LEVEL envar is set.
cls.log = logging.getLogger(cls.__name__)
if os.getenv("LOG_LEVEL"):
Expand Down
86 changes: 0 additions & 86 deletions qiskit/test/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

import collections.abc
import functools
import os
import socket
import sys
from typing import Union, Callable, Type, Iterable
Expand Down Expand Up @@ -99,91 +98,6 @@ def _wrapper(*args, **kwargs):
return _wrapper


def _get_credentials():
"""Finds the credentials for a specific test and options.
Returns:
Credentials: set of credentials
Raises:
SkipTest: when credentials can't be found
"""
try:
from qiskit.providers.ibmq.credentials import Credentials, discover_credentials
except ImportError as ex:
raise unittest.SkipTest(
"qiskit-ibmq-provider could not be found, "
"and is required for executing online tests. "
'To install, run "pip install qiskit-ibmq-provider" '
"or check your installation."
) from ex

if os.getenv("IBMQ_TOKEN") and os.getenv("IBMQ_URL"):
return Credentials(os.getenv("IBMQ_TOKEN"), os.getenv("IBMQ_URL"))
elif os.getenv("QISKIT_TESTS_USE_CREDENTIALS_FILE"):
# Attempt to read the standard credentials.
discovered_credentials = discover_credentials()

if discovered_credentials:
# Decide which credentials to use for testing.
if len(discovered_credentials) > 1:
raise unittest.SkipTest(
"More than 1 credential set found, use: "
"IBMQ_TOKEN and IBMQ_URL env variables to "
"set credentials explicitly"
)

# Use the first available credentials.
return list(discovered_credentials.values())[0]
raise unittest.SkipTest(
"No IBMQ credentials found for running the test. This is required for running online tests."
)


def online_test(func):
"""Decorator that signals that the test uses the network (and the online API):
It involves:
* determines if the test should be skipped by checking environment
variables.
* if the `USE_ALTERNATE_ENV_CREDENTIALS` environment variable is
set, it reads the credentials from an alternative set of environment
variables.
* if the test is not skipped, it reads `qe_token` and `qe_url` from
`Qconfig.py`, environment variables or qiskitrc.
* if the test is not skipped, it appends `qe_token` and `qe_url` as
arguments to the test function.
Args:
func (callable): test function to be decorated.
Returns:
callable: the decorated function.
"""

@functools.wraps(func)
def _wrapper(self, *args, **kwargs):
# To avoid checking the connection in each test
global HAS_NET_CONNECTION # pylint: disable=global-statement

if TEST_OPTIONS["skip_online"]:
raise unittest.SkipTest("Skipping online tests")

if HAS_NET_CONNECTION is None:
HAS_NET_CONNECTION = _has_connection("qiskit.org", 443)

if not HAS_NET_CONNECTION:
raise unittest.SkipTest("Test requires internet connection.")

credentials = _get_credentials()
self.using_ibmq_credentials = credentials.is_ibmq()
kwargs.update({"qe_token": credentials.token, "qe_url": credentials.url})

return func(self, *args, **kwargs)

return _wrapper


def enforce_subclasses_call(
methods: Union[str, Iterable[str]], attr: str = "_enforce_subclasses_call_cache"
) -> Callable[[Type], Type]:
Expand Down
45 changes: 0 additions & 45 deletions qiskit/test/ibmq_mock.py

This file was deleted.

40 changes: 0 additions & 40 deletions qiskit/test/mock/__init__.py

This file was deleted.

32 changes: 0 additions & 32 deletions qiskit/test/mock/backends/__init__.py

This file was deleted.

32 changes: 0 additions & 32 deletions qiskit/test/mock/backends/almaden/__init__.py

This file was deleted.

Loading

0 comments on commit 6fbde9d

Please sign in to comment.