diff --git a/qiskit_ibm_runtime/base_primitive.py b/qiskit_ibm_runtime/base_primitive.py index 5e35a15ca..d07d028d3 100644 --- a/qiskit_ibm_runtime/base_primitive.py +++ b/qiskit_ibm_runtime/base_primitive.py @@ -17,7 +17,6 @@ from typing import Dict, Optional, Union, TypeVar, Generic, Type import logging from dataclasses import asdict, replace -import warnings from qiskit.primitives.containers.estimator_pub import EstimatorPub from qiskit.primitives.containers.sampler_pub import SamplerPub @@ -48,7 +47,7 @@ def _get_mode_service_backend( - mode: Optional[Union[BackendV1, BackendV2, Session, Batch, str]] = None + mode: Optional[Union[BackendV1, BackendV2, Session, Batch]] = None ) -> tuple[ Union[Session, Batch, None], Union[QiskitRuntimeService, QiskitRuntimeLocalService, None], @@ -69,43 +68,21 @@ def _get_mode_service_backend( return mode, mode.service, mode._backend elif isinstance(mode, IBMBackend): # type: ignore[unreachable] if get_cm_session(): - warnings.warn( - ( - "Passing a backend as the mode currently runs the job in job mode even " - "if inside of a session/batch context manager. As of qiskit-ibm-runtime " - "version 0.26.0, this behavior is deprecated and in a future " - "release no sooner than than 3 months " - "after the release date, the session/batch will take precendence and " - "the job will not run in job mode. To ensure that jobs are run in session/batch " - "mode, pass in the session/batch or leave the mode parameter emtpy." - ), - DeprecationWarning, - stacklevel=4, + logger.warning( + "A backend was passed in as the mode but a session context manager " + "is open so this job will run inside this session/batch " + "instead of in job mode." ) + if get_cm_session()._backend != mode: + raise ValueError( + "The backend passed in to the primitive is different from the session backend. " + "Please check which backend you intend to use or leave the mode parameter " + "empty to use the session backend." + ) + return get_cm_session(), mode.service, mode return None, mode.service, mode elif isinstance(mode, (BackendV1, BackendV2)): return None, QiskitRuntimeLocalService(), mode - elif isinstance(mode, str): - if get_cm_session(): - warnings.warn( - ( - "Passing a backend as the mode currently runs the job in job mode even " - "if inside of a session/batch context manager. As of qiskit-ibm-runtime " - "version 0.26.0, this behavior is deprecated and in a future " - "release no sooner than than 3 months " - "after the release date, the session/batch will take precendence and " - "the job will not run in job mode. To ensure that jobs are run in session/batch " - "mode, pass in the session/batch or leave the mode parameter emtpy." - ), - DeprecationWarning, - stacklevel=4, - ) - service = ( - QiskitRuntimeService() - if QiskitRuntimeService.global_service is None - else QiskitRuntimeService.global_service - ) - return None, service, service.backend(mode) elif mode is not None: # type: ignore[unreachable] raise ValueError("mode must be of type Backend, Session, Batch or None") elif get_cm_session(): diff --git a/qiskit_ibm_runtime/batch.py b/qiskit_ibm_runtime/batch.py index ee49e774a..12119ae1b 100644 --- a/qiskit_ibm_runtime/batch.py +++ b/qiskit_ibm_runtime/batch.py @@ -18,7 +18,6 @@ from qiskit_ibm_runtime import QiskitRuntimeService from .session import Session -from .utils.deprecation import issue_deprecation_msg class Batch(Session): @@ -87,19 +86,13 @@ class Batch(Session): def __init__( self, - service: Optional[QiskitRuntimeService] = None, - backend: Optional[Union[str, BackendV1, BackendV2]] = None, + backend: Optional[Union[BackendV1, BackendV2]] = None, max_time: Optional[Union[int, str]] = None, ): """Batch constructor. Args: - service: (DEPRECATED) Optional instance of the ``QiskitRuntimeService`` class. - If ``None``, the service associated with the backend, if known, is used. - Otherwise ``QiskitRuntimeService()`` is used to initialize - your default saved account. - backend: Instance of ``Backend`` class or backend string name. Note that passing a - backend name is deprecated. + backend: Instance of ``Backend`` class. max_time: Maximum amount of time a runtime session can be open before being @@ -111,25 +104,8 @@ def __init__( Raises: ValueError: If an input value is invalid. """ - if service: - issue_deprecation_msg( - msg="The service parameter is deprecated", - version="0.26.0", - remedy=( - "The service can be extracted from the backend object so " - "it is no longer necessary." - ), - period="3 months", - ) - if isinstance(backend, str): - issue_deprecation_msg( - msg="Passing a backend as a string is deprecated", - version="0.26.0", - remedy="Use the actual backend object instead.", - period="3 months", - ) - super().__init__(service=service, backend=backend, max_time=max_time) + super().__init__(backend=backend, max_time=max_time) def _create_session(self) -> Optional[str]: """Create a session.""" diff --git a/qiskit_ibm_runtime/estimator.py b/qiskit_ibm_runtime/estimator.py index aabe7c089..d98a9c02b 100644 --- a/qiskit_ibm_runtime/estimator.py +++ b/qiskit_ibm_runtime/estimator.py @@ -26,7 +26,6 @@ from .runtime_job_v2 import RuntimeJobV2 from .options.estimator_options import EstimatorOptions from .base_primitive import BasePrimitiveV2 -from .utils.deprecation import issue_deprecation_msg from .utils import validate_estimator_pubs # pylint: disable=unused-import,cyclic-import @@ -121,13 +120,6 @@ def __init__( """ BaseEstimatorV2.__init__(self) Estimator.__init__(self) - if isinstance(mode, str): - issue_deprecation_msg( - msg="Passing a backend as a string is deprecated", - version="0.26.0", - remedy="Use the actual backend object instead.", - period="3 months", - ) BasePrimitiveV2.__init__(self, mode=mode, options=options) diff --git a/qiskit_ibm_runtime/qiskit_runtime_service.py b/qiskit_ibm_runtime/qiskit_runtime_service.py index 0391cc268..ba2039cbd 100644 --- a/qiskit_ibm_runtime/qiskit_runtime_service.py +++ b/qiskit_ibm_runtime/qiskit_runtime_service.py @@ -53,8 +53,6 @@ class QiskitRuntimeService: """Class for interacting with the Qiskit Runtime service.""" - global_service = None - def __new__(cls, *args, **kwargs): # type: ignore[no-untyped-def] channel = kwargs.get("channel", None) if channel == "local": @@ -178,7 +176,6 @@ def __init__( if not self._current_instance: self._current_instance = self._get_hgp().name logger.info("Default instance: %s", self._current_instance) - QiskitRuntimeService.global_service = self def _discover_account( self, diff --git a/qiskit_ibm_runtime/sampler.py b/qiskit_ibm_runtime/sampler.py index 34650896a..d7e9d0fbe 100644 --- a/qiskit_ibm_runtime/sampler.py +++ b/qiskit_ibm_runtime/sampler.py @@ -29,7 +29,6 @@ # pylint: disable=unused-import,cyclic-import from .session import Session from .batch import Batch -from .utils.deprecation import issue_deprecation_msg from .utils import validate_classical_registers from .options import SamplerOptions @@ -61,7 +60,7 @@ class SamplerV2(BasePrimitiveV2[SamplerOptions], Sampler, BaseSamplerV2): def __init__( self, - mode: Optional[Union[BackendV1, BackendV2, Session, Batch, str]] = None, + mode: Optional[Union[BackendV1, BackendV2, Session, Batch]] = None, options: Optional[Union[Dict, SamplerOptions]] = None, ): """Initializes the Sampler primitive. @@ -84,15 +83,6 @@ def __init__( BaseSamplerV2.__init__(self) Sampler.__init__(self) - if isinstance(mode, str): - issue_deprecation_msg( - msg="Passing a backend as a string is deprecated", - version="0.26.0", - remedy="Use the actual backend object instead.", - period="3 months", - stacklevel=2, - ) - BasePrimitiveV2.__init__(self, mode=mode, options=options) def run(self, pubs: Iterable[SamplerPubLike], *, shots: int | None = None) -> RuntimeJobV2: diff --git a/qiskit_ibm_runtime/session.py b/qiskit_ibm_runtime/session.py index 76fce752a..f67b2ba7f 100644 --- a/qiskit_ibm_runtime/session.py +++ b/qiskit_ibm_runtime/session.py @@ -27,7 +27,6 @@ from .utils.result_decoder import ResultDecoder from .ibm_backend import IBMBackend from .utils.default_session import set_cm_session -from .utils.deprecation import issue_deprecation_msg from .utils.converters import hms_to_seconds from .fake_provider.local_service import QiskitRuntimeLocalService @@ -86,19 +85,13 @@ class Session: def __init__( self, - service: Optional[QiskitRuntimeService] = None, - backend: Optional[Union[str, BackendV1, BackendV2]] = None, + backend: Optional[Union[BackendV1, BackendV2]] = None, max_time: Optional[Union[int, str]] = None, ): # pylint: disable=line-too-long """Session constructor. Args: - service: (DEPRECATED) Optional instance of the ``QiskitRuntimeService`` class. - If ``None``, the service associated with the backend, if known, is used. - Otherwise ``QiskitRuntimeService()`` is used to initialize - your default saved account. - backend: Instance of ``Backend`` class or string name of backend. Note that passing a - backend name is deprecated. + backend: Instance of ``Backend`` class. max_time: Maximum amount of time, a runtime session can be open before being @@ -115,43 +108,14 @@ def __init__( self._active = True self._session_id = None - if service: - issue_deprecation_msg( - msg="The service parameter is deprecated", - version="0.26.0", - remedy=( - "The service can be extracted from the backend object so " - "it is no longer necessary." - ), - period="3 months", - ) - - self._service = service if isinstance(backend, IBMBackend): - self._service = self._service or backend.service + self._service = backend.service self._backend = backend elif isinstance(backend, (BackendV1, BackendV2)): self._service = QiskitRuntimeLocalService() self._backend = backend else: - if not self._service: - self._service = ( - QiskitRuntimeService() - if QiskitRuntimeService.global_service is None - else QiskitRuntimeService.global_service - ) - if isinstance(backend, str): - issue_deprecation_msg( - msg="Passing a backend as a string is deprecated", - version="0.26.0", - remedy="Use the actual backend object instead.", - period="3 months", - ) - self._backend = self._service.backend(backend) - elif backend is None: - raise ValueError('"backend" is required') - else: - raise ValueError(f"Invalid backend type {type(backend)}") + raise ValueError(f"Invalid backend type {type(backend)}") self._max_time = ( max_time @@ -378,7 +342,7 @@ def from_id(cls, session_id: str, service: QiskitRuntimeService) -> "Session": ) cls._create_new_session = False - session = cls(service, backend) + session = cls(backend) cls._create_new_session = True if state == "closed": session._active = False diff --git a/release-notes/unreleased/2027.other.rst b/release-notes/unreleased/2027.other.rst new file mode 100644 index 000000000..62673274a --- /dev/null +++ b/release-notes/unreleased/2027.other.rst @@ -0,0 +1,11 @@ +The deprecations from the ``0.26.0`` release have been removed. + + - Passing a backend as a string into ``Session``, ``Batch``, + ``Sampler``, and ``Estimator`` is no longer valid. Use the actual backend + object instead. + - Passing a backend as the mode into ``SamplerV2`` or ``EstimatorV2`` used + to run jobs in job mode, even if a session context manager was open. These jobs will now + run inside of the open session. Additionally, if a backend that is different + from the session backend is passed in as the mode, an error will be raised. + - ``Service`` is no longer a valid parameter in ``Session`` and ``Batch``. + diff --git a/test/integration/test_estimator_v2.py b/test/integration/test_estimator_v2.py index 5544bd98a..ac2bfd532 100644 --- a/test/integration/test_estimator_v2.py +++ b/test/integration/test_estimator_v2.py @@ -22,7 +22,6 @@ from qiskit_ibm_runtime import EstimatorV2, Session from qiskit_ibm_runtime.fake_provider import FakeAuckland -from ..decorators import run_integration_test from ..ibm_test_case import IBMIntegrationTestCase @@ -33,8 +32,7 @@ def setUp(self) -> None: super().setUp() self._backend = self.service.backend(self.dependencies.qpu) - @run_integration_test - def test_estimator_v2_session(self, service): + def test_estimator_v2_session(self): """Verify correct results are returned""" pass_mgr = generate_preset_pass_manager(backend=self._backend, optimization_level=1) @@ -50,7 +48,7 @@ def test_estimator_v2_session(self, service): theta2 = [0, 1, 1, 2, 3, 5, 8, 13] theta3 = [1, 2, 3, 4, 5, 6] - with Session(service, self._backend) as session: + with Session(self._backend) as session: estimator = EstimatorV2(mode=session) job = estimator.run([(psi1, H1, [theta1])]) diff --git a/test/integration/test_noise_learner.py b/test/integration/test_noise_learner.py index 22bd2f4b5..ebd96ff8d 100644 --- a/test/integration/test_noise_learner.py +++ b/test/integration/test_noise_learner.py @@ -120,7 +120,7 @@ def test_learner_plus_estimator(self, service): # pylint: disable=unused-argume pubs = [(circuit, "Z" * circuit.num_qubits)] - with Session(service, self._backend) as session: + with Session(self._backend) as session: learner = NoiseLearner(mode=session, options=options) learner_job = learner.run(self.circuits) noise_model = learner_job.result() diff --git a/test/integration/test_sampler_v2.py b/test/integration/test_sampler_v2.py index f896033e6..e2b055f08 100644 --- a/test/integration/test_sampler_v2.py +++ b/test/integration/test_sampler_v2.py @@ -77,11 +77,10 @@ def setUp(self): (pqc2, [0, 1, 2, 3, 4, 5, 6, 7], {0: 1898, 1: 6864, 2: 928, 3: 311}) ) # case 6 - @run_integration_test - def test_sampler_run(self, service): + def test_sampler_run(self): """Test Sampler.run().""" - with Session(service, self._backend) as session: + with Session(self._backend) as session: _, _, target = self._cases[1] with self.subTest("single"): sampler = Sampler(mode=session, options=self._options) @@ -158,11 +157,10 @@ def test_run_2qubit(self): result = sampler.run([qc0, qc1, qc2, qc3]).result() self._verify_result_type(result, num_pubs=4) - @run_integration_test - def test_run_single_circuit(self, service): + def test_run_single_circuit(self): """Test for single circuit case.""" pm = generate_preset_pass_manager(optimization_level=1, target=self._backend.target) - with Session(service, self._backend) as session: + with Session(self._backend) as session: sampler = Sampler(mode=session, options=self._options) with self.subTest("No parameter"): @@ -234,10 +232,9 @@ def test_run_reverse_meas_order(self): result = sampler.run([(pm.run(qc), [0, 0]), (pm.run(qc), [np.pi / 2, 0])]).result() self._verify_result_type(result, num_pubs=2) - @run_integration_test - def test_run_empty_parameter(self, service): + def test_run_empty_parameter(self): """Test for empty parameter""" - with Session(service, self._backend) as session: + with Session(self._backend) as session: n = 5 qc = QuantumCircuit(n, n - 1) qc.measure(range(n - 1), range(n - 1)) @@ -250,10 +247,9 @@ def test_run_empty_parameter(self, service): result = sampler.run([qc, qc]).result() self._verify_result_type(result, num_pubs=2) - @run_integration_test - def test_run_numpy_params(self, service): + def test_run_numpy_params(self): """Test for numpy array as parameter values""" - with Session(service, self._backend) as session: + with Session(self._backend) as session: qc = RealAmplitudes(num_qubits=2, reps=2) qc.measure_all() qc = transpile(circuits=qc, backend=self._backend) @@ -273,10 +269,9 @@ def test_run_numpy_params(self, service): result, num_pubs=len(params_list), targets=[np.array(target)] ) - @run_integration_test - def test_run_with_shots_option(self, service): + def test_run_with_shots_option(self): """test with shots option.""" - with Session(service, self._backend) as session: + with Session(self._backend) as session: _, _, _ = self._cases[1] shots = 100 with self.subTest("init option"): @@ -358,12 +353,11 @@ def test_primitive_job_status_done(self): _ = job.result() self.assertEqual(job.status(), "DONE") - @run_integration_test - def test_circuit_with_unitary(self, service): + def test_circuit_with_unitary(self): """Test for circuit with unitary gate.""" pm = generate_preset_pass_manager(optimization_level=1, target=self._backend.target) - with Session(service, self._backend) as session: + with Session(self._backend) as session: with self.subTest("identity"): gate = UnitaryGate(np.eye(2)) @@ -395,10 +389,9 @@ def test_metadata(self): self.assertEqual(result[0].data.meas.num_shots, self._shots) self._verify_result_type(result, num_pubs=1) - @run_integration_test - def test_circuit_with_multiple_cregs(self, service): + def test_circuit_with_multiple_cregs(self): """Test for circuit with multiple classical registers.""" - with Session(service, self._backend) as session: + with Session(self._backend) as session: cases = [] pm = generate_preset_pass_manager(optimization_level=1, target=self._backend.target) diff --git a/test/integration/test_session.py b/test/integration/test_session.py index a60607897..95453ac68 100644 --- a/test/integration/test_session.py +++ b/test/integration/test_session.py @@ -43,7 +43,7 @@ def test_estimator_sampler(self, service): H1 = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)]).apply_layout(psi1.layout) theta1 = [0, 1, 1, 2, 3, 5] - with Session(service, backend=backend) as session: + with Session(backend=backend) as session: estimator = EstimatorV2(mode=session) result = estimator.run([(psi1, H1, [theta1])]).result() self.assertIsInstance(result, PrimitiveResult) @@ -67,7 +67,7 @@ def test_using_correct_instance(self, service): instance = self.dependencies.instance backend = service.backend(self.dependencies.qpu, self.dependencies.instance) pm = generate_preset_pass_manager(optimization_level=1, target=backend.target) - with Session(service, backend=backend) as session: + with Session(backend=backend) as session: sampler = SamplerV2(mode=session) job = sampler.run([pm.run(bell())]) self.assertEqual(instance, backend._instance) @@ -82,7 +82,7 @@ def test_session_from_id(self, service): raise SkipTest("No proper backends available") pm = generate_preset_pass_manager(backend=backend, optimization_level=1) isa_circuit = pm.run([bell()]) - with Session(service, backend=backend) as session: + with Session(backend=backend) as session: sampler = SamplerV2(mode=session) sampler.run(isa_circuit) @@ -94,11 +94,3 @@ def test_session_from_id(self, service): with self.assertRaises(IBMInputValueError): Batch.from_id(session_id=session._session_id, service=service) - - @run_integration_test - def test_job_mode_warning(self, service): - """Test deprecation warning is raised when using job mode inside a session.""" - backend = service.backend(self.dependencies.qpu) - with Session(service, backend=backend): - with self.assertWarns(DeprecationWarning): - _ = SamplerV2(mode=backend) diff --git a/test/unit/test_batch.py b/test/unit/test_batch.py index 77785207e..5e0fb2c2e 100644 --- a/test/unit/test_batch.py +++ b/test/unit/test_batch.py @@ -12,8 +12,6 @@ """Tests for Batch class.""" -from unittest.mock import MagicMock - from qiskit_ibm_runtime import Batch from qiskit_ibm_runtime.utils.default_session import _DEFAULT_SESSION from qiskit_ibm_runtime.exceptions import IBMRuntimeError @@ -33,7 +31,7 @@ def test_passing_ibm_backend(self): """Test passing in IBMBackend instance.""" name = "ibm_gotham" backend = get_mocked_backend(name=name) - session = Batch(service=MagicMock(), backend=backend) + session = Batch(backend=backend) self.assertEqual(session.backend(), name) def test_using_ibm_backend_service(self): @@ -45,14 +43,16 @@ def test_using_ibm_backend_service(self): def test_run_after_close(self): """Test running after session is closed.""" - session = Batch(service=MagicMock(), backend="ibm_gotham") + backend = get_mocked_backend(name="ibm_gotham") + session = Batch(backend=backend) session.cancel() with self.assertRaises(IBMRuntimeError): session._run(program_id="program_id", inputs={}) def test_context_manager(self): """Test session as a context manager.""" - with Batch(service=MagicMock(), backend="ibm_gotham") as session: + backend = get_mocked_backend(name="ibm_gotham") + with Batch(backend=backend) as session: session._run(program_id="foo", inputs={}) session.cancel() self.assertFalse(session._active) diff --git a/test/unit/test_estimator.py b/test/unit/test_estimator.py index 32050ec7f..58a07d728 100644 --- a/test/unit/test_estimator.py +++ b/test/unit/test_estimator.py @@ -23,7 +23,6 @@ from qiskit_ibm_runtime import Session, EstimatorV2, EstimatorOptions, IBMInputValueError from qiskit_ibm_runtime.fake_provider import FakeSherbrooke -from .mock.fake_runtime_service import FakeRuntimeService from ..ibm_test_case import IBMTestCase from ..utils import ( get_mocked_backend, @@ -77,9 +76,9 @@ def test_unsupported_values_for_estimator_options(self): }, ] + backend = get_mocked_backend() with Session( - service=FakeRuntimeService(channel="ibm_quantum", token="abc"), - backend="common_backend", + backend=backend, ) as session: for bad_opt in options_bad: inst = EstimatorV2(mode=session) diff --git a/test/unit/test_ibm_primitives_v2.py b/test/unit/test_ibm_primitives_v2.py index 31b6b83ec..94467e49b 100644 --- a/test/unit/test_ibm_primitives_v2.py +++ b/test/unit/test_ibm_primitives_v2.py @@ -134,13 +134,11 @@ def test_init_with_backend_str(self, primitive): class MockQRTService: """Mock class used to create a new QiskitRuntimeService.""" - global_service = None - def __new__(cls, *args, **kwargs): # pylint: disable=unused-argument return mock_service_inst with patch("qiskit_ibm_runtime.base_primitive.QiskitRuntimeService", new=MockQRTService): - inst = primitive(mode=backend_name) + inst = primitive(mode=mock_backend) self.assertIsNone(inst.mode) inst.run(**get_primitive_inputs(inst)) mock_service_inst._run.assert_called_once() @@ -148,7 +146,7 @@ def __new__(cls, *args, **kwargs): # pylint: disable=unused-argument self.assertEqual(runtime_options["backend"], mock_backend) mock_service_inst.reset_mock() - str_mode_inst = primitive(mode=backend_name) + str_mode_inst = primitive(mode=mock_backend) self.assertIsNone(str_mode_inst.mode) inst.run(**get_primitive_inputs(str_mode_inst)) mock_service_inst._run.assert_called_once() @@ -187,7 +185,7 @@ def test_default_session_context_manager(self, primitive): backend_name = "ibm_gotham" backend = get_mocked_backend(name=backend_name) - with Session(service=backend.service, backend=backend_name) as session: + with Session(backend=backend) as session: inst = primitive() self.assertEqual(inst.mode, session) self.assertEqual(inst.mode.backend(), backend_name) @@ -195,17 +193,12 @@ def test_default_session_context_manager(self, primitive): @data(EstimatorV2, SamplerV2) def test_default_session_cm_new_backend(self, primitive): """Test using a different backend within context manager.""" - cm_backend = "ibm_metropolis" + session_backend = get_mocked_backend("ibm_metropolis") backend = get_mocked_backend() - service = backend.service - with Session(service=service, backend=cm_backend): - inst = primitive(mode=backend) - self.assertIsNone(inst.mode) - inst.run(**get_primitive_inputs(inst)) - service._run.assert_called_once() - runtime_options = service._run.call_args.kwargs["options"] - self.assertEqual(runtime_options["backend"], backend) + with Session(backend=session_backend): + with self.assertRaises(ValueError): + _ = primitive(mode=backend) @data(EstimatorV2, SamplerV2) def test_no_session(self, primitive): @@ -600,7 +593,7 @@ def test_faulty_edge_not_used(self, primitive): service = MagicMock() service.backend.return_value = ibm_backend - session = Session(service=service, backend=fake_backend) + session = Session(backend=fake_backend) inst = primitive(mode=session) if isinstance(inst, IBMBaseEstimator): diff --git a/test/unit/test_sampler.py b/test/unit/test_sampler.py index 31318ca2e..ba452f5fc 100644 --- a/test/unit/test_sampler.py +++ b/test/unit/test_sampler.py @@ -75,9 +75,9 @@ def test_run_program_inputs(self, in_pubs): ) def test_unsupported_values_for_sampler_options(self, opt): """Test exception when options levels are not supported.""" + backend = get_mocked_backend() with Session( - service=FakeRuntimeService(channel="ibm_quantum", token="abc"), - backend="common_backend", + backend=backend, ) as session: inst = SamplerV2(mode=session) with self.assertRaises(ValueError) as exc: @@ -138,9 +138,9 @@ def test_run_default_options(self): def test_sampler_validations(self): """Test exceptions when failing client-side validations.""" + backend = get_mocked_backend() with Session( - service=FakeRuntimeService(channel="ibm_quantum", token="abc"), - backend="common_backend", + backend=backend, ) as session: inst = SamplerV2(mode=session) circ = QuantumCircuit(QuantumRegister(2), ClassicalRegister(0)) diff --git a/test/unit/test_session.py b/test/unit/test_session.py index 10c3f1516..a1d24ff05 100644 --- a/test/unit/test_session.py +++ b/test/unit/test_session.py @@ -12,7 +12,7 @@ """Tests for Session classession.""" -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock from qiskit_ibm_runtime.fake_provider import FakeManilaV2 from qiskit_ibm_runtime import Session, SamplerV2 @@ -33,39 +33,12 @@ def tearDown(self) -> None: super().tearDown() _DEFAULT_SESSION.set(None) - @patch("qiskit_ibm_runtime.session.QiskitRuntimeService") - def test_default_service(self, mock_service): - """Test using default service.""" - mock_service.global_service = None - session = Session(backend="ibm_gotham") - self.assertIsNotNone(session.service) - mock_service.assert_called_once() - - def test_missing_backend(self): - """Test missing backend.""" - service = MagicMock() - service.channel = "ibm_quantum" - with self.assertRaises(ValueError): - Session(service=service) - - service.channel = "ibm_cloud" - with self.assertRaises(ValueError): - Session(service=service) - def test_passing_ibm_backend(self): """Test passing in IBMBackend instance.""" backend_name = "ibm_gotham" backend = get_mocked_backend(name=backend_name) - session = Session(service=backend.service, backend=backend) - self.assertEqual(session.backend(), backend_name) - - def test_using_ibm_backend_service(self): - """Test using service from an IBMBackend instance.""" - backend = MagicMock(spec=IBMBackend) - backend._instance = None - backend.name = "ibm_gotham" session = Session(backend=backend) - self.assertEqual(session.service, backend.service) + self.assertEqual(session.backend(), backend_name) def test_max_time(self): """Test max time.""" @@ -83,7 +56,8 @@ def test_max_time(self): ] for max_t, expected in max_times: with self.subTest(max_time=max_t): - session = Session(service=MagicMock(), backend="ibm_gotham", max_time=max_t) + backend = get_mocked_backend("ibm_gotham") + session = Session(backend=backend, max_time=max_t) self.assertEqual(session._max_time, expected) for max_t, expected in max_times: with self.subTest(max_time=max_t): @@ -92,7 +66,8 @@ def test_max_time(self): def test_run_after_close(self): """Test running after session is closed.""" - session = Session(service=MagicMock(), backend="ibm_gotham") + backend = get_mocked_backend("ibm_gotham") + session = Session(backend=backend) session.cancel() with self.assertRaises(IBMRuntimeError): session._run(program_id="program_id", inputs={}) @@ -110,7 +85,7 @@ def test_run(self): program_id = "batman_begins" decoder = MagicMock() max_time = 42 - session = Session(service=service, backend=backend, max_time=max_time) + session = Session(backend=backend, max_time=max_time) session._run( program_id=program_id, @@ -127,25 +102,12 @@ def test_run(self): def test_context_manager(self): """Test session as a context manager.""" - with Session(service=MagicMock(), backend="ibm_gotham") as session: + backend = get_mocked_backend("ibm_gotham") + with Session(backend=backend) as session: session._run(program_id="foo", inputs={}) session.cancel() self.assertFalse(session._active) - def test_global_service(self): - """Test that global service is used in Session""" - _ = FakeRuntimeService(channel="ibm_quantum", token="abc") - session = Session(backend="common_backend") - self.assertTrue(isinstance(session._service, FakeRuntimeService)) - self.assertEqual(session._service._account.token, "abc") - _ = FakeRuntimeService(channel="ibm_quantum", token="xyz") - session = Session(backend="common_backend") - self.assertEqual(session._service._account.token, "xyz") - with Session( - service=FakeRuntimeService(channel="ibm_quantum", token="uvw"), backend="common_backend" - ) as session: - self.assertEqual(session._service._account.token, "uvw") - def test_session_from_id(self): """Create session with given session_id""" service = FakeRuntimeService(channel="ibm_quantum", token="abc") @@ -159,7 +121,8 @@ def test_session_from_id(self): def test_correct_execution_mode(self): """Test that the execution mode is correctly set.""" _ = FakeRuntimeService(channel="ibm_quantum", token="abc") - session = Session(backend="common_backend") + backend = get_mocked_backend("ibm_gotham") + session = Session(backend=backend) self.assertEqual(session.details()["mode"], "dedicated") def test_cm_session_fractional(self): diff --git a/test/utils.py b/test/utils.py index 735a66a10..0abf9d7bb 100644 --- a/test/utils.py +++ b/test/utils.py @@ -325,6 +325,7 @@ def get_mocked_backend( mock_api_client.backend_properties = lambda *args, **kwargs: properties mock_api_client.backend_pulse_defaults = lambda *args, **kwargs: defaults + mock_api_client.session_details = lambda *args, **kwargs: {"mode": "dedicated"} mock_backend = IBMBackend( configuration=configuration, service=mock_service, api_client=mock_api_client )