diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f89498912..43341047e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,10 +26,10 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip @@ -48,10 +48,10 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip @@ -80,11 +80,11 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.9, '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.10', '3.11', '3.12', '3.13'] os: [ "macos-latest", "ubuntu-latest", "windows-latest" ] exclude: - os: "macos-latest" - python-version: 3.9 + python-version: '3.10' env: LOG_LEVEL: DEBUG STREAM_LOG: True @@ -120,7 +120,7 @@ jobs: # avoid cancellation of in-progress jobs if any matrix job fails fail-fast: false matrix: - python-version: [ 3.9 ] + python-version: [ '3.10' ] os: [ "ubuntu-latest" ] environment: ["ibm-cloud-production" ] environment: ${{ matrix.environment }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 48ddca4bb..a4d898072 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -25,7 +25,7 @@ jobs: id-token: write strategy: matrix: - python-version: [3.9] + python-version: ['3.10'] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3e506d765..d6a2896d1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.9.12' + python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 11d73c191..caaf3a926 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -25,7 +25,7 @@ jobs: # avoid cancellation of in-progress jobs if any matrix job fails fail-fast: false matrix: - python-version: [ 3.9 ] + python-version: [ '3.10' ] os: [ "ubuntu-latest" ] environment: ["ibm-cloud-production", "ibm-cloud-staging" ] environment: ${{ matrix.environment }} diff --git a/.github/workflows/smoke-tests.yml b/.github/workflows/smoke-tests.yml index 7a1dc2227..70a8e5002 100644 --- a/.github/workflows/smoke-tests.yml +++ b/.github/workflows/smoke-tests.yml @@ -22,7 +22,7 @@ jobs: # avoid cancellation of in-progress jobs if any matrix job fails fail-fast: false matrix: - python-version: [ 3.9 ] + python-version: [ '3.10' ] os: [ "ubuntu-latest" ] environment: [ "ibm-cloud-production", "ibm-cloud-staging" ] environment: ${{ matrix.environment }} diff --git a/.github/workflows/unit-tests-terra-main.yml b/.github/workflows/unit-tests-terra-main.yml index 56daf32d3..118d6644e 100644 --- a/.github/workflows/unit-tests-terra-main.yml +++ b/.github/workflows/unit-tests-terra-main.yml @@ -28,10 +28,10 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Set up Python 3.9 + - name: Set up Python 3.10 uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/pyproject.toml b/pyproject.toml index b31f6dd49..5af200017 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,7 +70,6 @@ classifiers=[ "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -80,7 +79,7 @@ classifiers=[ keywords = ["qiskit", "sdk", "quantum", "api", "runtime", "ibm"] -requires-python=">=3.9" +requires-python=">=3.10" dependencies = [ "requests>=2.19,!=2.32.2", diff --git a/qiskit_ibm_runtime/__init__.py b/qiskit_ibm_runtime/__init__.py index c80b4f8e3..ef70971d7 100644 --- a/qiskit_ibm_runtime/__init__.py +++ b/qiskit_ibm_runtime/__init__.py @@ -236,12 +236,3 @@ """The environment variable name that is used to set the level for the IBM Quantum logger.""" QISKIT_IBM_RUNTIME_LOG_FILE = "QISKIT_IBM_RUNTIME_LOG_FILE" """The environment variable name that is used to set the file for the IBM Quantum logger.""" - -if sys.version_info < (3, 10): - warnings.warn( - "Using qiskit-ibm-runtime with Python 3.9 is deprecated as of the 0.41.0 release. " - "Support for running qiskit-ibm-runtime with Python 3.9 will be removed in a future " - "release.", - DeprecationWarning, - stacklevel=2, - ) diff --git a/qiskit_ibm_runtime/qiskit_runtime_service.py b/qiskit_ibm_runtime/qiskit_runtime_service.py index 7777ef45f..7ec913e1c 100644 --- a/qiskit_ibm_runtime/qiskit_runtime_service.py +++ b/qiskit_ibm_runtime/qiskit_runtime_service.py @@ -1155,33 +1155,6 @@ def jobs( return [self._decode_job(job) for job in job_responses] - def delete_job(self, job_id: str) -> None: - """(DEPRECATED) Delete a runtime job. - - Note that this operation cannot be reversed. - - Args: - job_id: ID of the job to delete. - - Raises: - RuntimeJobNotFound: The job doesn't exist. - IBMRuntimeError: Method is not supported. - """ - - warnings.warn( - "The delete_job() method is deprecated and will be removed in a future release. " - "The new IBM Quantum Platform does not support deleting jobs.", - DeprecationWarning, - stacklevel=2, - ) - - try: - self._active_api_client.job_delete(job_id) - except RequestsApiError as ex: - if ex.status_code == 404: - raise RuntimeJobNotFound(f"Job not found: {ex.message}") from None - raise IBMRuntimeError(f"Failed to delete job: {ex}") from None - def usage(self) -> Dict[str, Any]: """Return usage information for the current active instance. @@ -1235,43 +1208,6 @@ def _decode_job(self, raw_data: Dict) -> RuntimeJobV2: private=raw_data.get("private", False), ) - def check_pending_jobs(self) -> None: - """(DEPRECATED) Check the number of pending jobs and wait for the oldest pending job if - the maximum number of pending jobs has been reached. - """ - - warnings.warn( - "The check_pending_jobs() method is deprecated and will be removed in a future release. " - "The new IBM Quantum Platform does not support this functionality.", - DeprecationWarning, - stacklevel=2, - ) - - try: - usage = self.usage().get("byInstance")[0] - pending_jobs = usage.get("pendingJobs") - max_pending_jobs = usage.get("maxPendingJobs") - if pending_jobs >= max_pending_jobs: - oldest_running = self.jobs(limit=1, descending=False, pending=True) - if oldest_running: - logger.warning( - "The pending jobs limit has been reached. " - "Waiting for job %s to finish before submitting the next one.", - oldest_running[0], - ) - try: - oldest_running[0].wait_for_final_state(timeout=300) - - except Exception as ex: # pylint: disable=broad-except - logger.debug( - "An error occurred while waiting for job %s to finish: %s", - oldest_running[0].job_id(), - ex, - ) - - except Exception as ex: # pylint: disable=broad-except - logger.warning("Unable to retrieve open plan pending jobs details. %s", ex) - def least_busy( self, min_num_qubits: Optional[int] = None, diff --git a/release-notes/unreleased/2439.other.rst b/release-notes/unreleased/2439.other.rst new file mode 100644 index 000000000..6a2b0ab8f --- /dev/null +++ b/release-notes/unreleased/2439.other.rst @@ -0,0 +1,2 @@ +The deprecated methods ``check_pending_jobs()`` and ``delete_job()`` methods along with +support for python 3.9 have been removed. \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 932aa32f8..3152e1a06 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,7 +2,7 @@ source = qiskit_ibm_runtime [mypy] -python_version = 3.8 +python_version = 3.10 namespace_packages = True ignore_missing_imports = True warn_redundant_casts = True diff --git a/test/ibm_test_case.py b/test/ibm_test_case.py index 34765fce1..b6c7ba8e0 100644 --- a/test/ibm_test_case.py +++ b/test/ibm_test_case.py @@ -218,8 +218,6 @@ def tearDown(self) -> None: for job in self.to_cancel[service.channel]: with suppress(Exception): job.cancel() - with suppress(Exception): - service.delete_job(job.job_id()) class IBMIntegrationJobTestCase(IBMIntegrationTestCase): diff --git a/test/integration/test_job.py b/test/integration/test_job.py index d5d634447..96b04b47e 100644 --- a/test/integration/test_job.py +++ b/test/integration/test_job.py @@ -15,11 +15,8 @@ import random import time -from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager - from qiskit_ibm_runtime.exceptions import ( RuntimeInvalidStateError, - RuntimeJobNotFound, ) from ..ibm_test_case import IBMIntegrationJobTestCase @@ -27,7 +24,7 @@ from ..serialization import ( SerializableClass, ) -from ..utils import cancel_job_safe, wait_for_status, get_real_device, bell +from ..utils import cancel_job_safe, wait_for_status class TestIntegrationJob(IBMIntegrationJobTestCase): @@ -87,35 +84,6 @@ def test_cancel_job_done(self, service): with self.assertRaises(RuntimeInvalidStateError): job.cancel() - @run_integration_test - def test_delete_job(self, service): - """Test deleting a job.""" - self.skipTest("Deleting jobs not supported on IBM Quantum Platform.") - sub_tests = ["DONE"] - for status in sub_tests: - with self.subTest(status=status): - job = self._run_program(service) - wait_for_status(job, status) - service.delete_job(job.job_id()) - with self.assertRaises(RuntimeJobNotFound): - service.job(job.job_id()) - - @run_integration_test - @production_only - def test_delete_job_queued(self, service): - """Test deleting a queued job.""" - self.skipTest("Deleting jobs not supported on IBM Quantum Platform.") - real_device_name = get_real_device(service) - real_device = service.backend(real_device_name) - pm = generate_preset_pass_manager(optimization_level=1, target=real_device.target) - isa_circuit = pm.run([bell()]) - _ = self._run_program(service, circuits=isa_circuit, backend=real_device_name) - job = self._run_program(service, circuits=isa_circuit, backend=real_device_name) - wait_for_status(job, "QUEUED") - service.delete_job(job.job_id()) - with self.assertRaises(RuntimeJobNotFound): - service.job(job.job_id()) - @run_integration_test def test_job_status(self, service): """Test job status.""" diff --git a/test/unit/test_jobs.py b/test/unit/test_jobs.py index b3fe36dea..1f37e1131 100644 --- a/test/unit/test_jobs.py +++ b/test/unit/test_jobs.py @@ -21,7 +21,6 @@ from qiskit_ibm_runtime.constants import API_TO_JOB_ERROR_MESSAGE from qiskit_ibm_runtime.exceptions import ( RuntimeJobFailureError, - RuntimeJobNotFound, RuntimeJobMaxTimeoutError, RuntimeInvalidStateError, ) @@ -145,13 +144,3 @@ def test_wait_for_final_state(self, service): with mock_wait_for_final_state(service, job): job.wait_for_final_state() self.assertEqual("DONE", job.status()) - - @run_cloud_fake - def test_delete_job(self, service): - """Test deleting a job.""" - params = {"param1": "foo"} - job = run_program(service=service, inputs=params) - self.assertTrue(job.job_id()) - service.delete_job(job.job_id()) - with self.assertRaises(RuntimeJobNotFound): - service.job(job.job_id())