From 5a5c9e33f55d2de3adb7f7377ce835cc65e2204d Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 23 Nov 2023 13:17:14 -0500 Subject: [PATCH] Add support for Python 3.12 (#11262) * Add support for Python 3.12 Python 3.12.0 was released on 10-02-2023, this commit marks the start of support for Python 3.12 in Qiskit. It adds the supported Pythonv ersion in the package metadata and updates the CI configuration to run test jobs on Python 3.12 and build Python 3.12 wheels on release. Fixes: #10887 * Add release note * Avoid deprecated `datetime.datetime.utcnow()` usage In Python 3.12 `datetime.datetime.utcnow()` has been deprecated, being replaced by: `datetime.datetime.now(datetime.UTC)`. This commit updates the usage of `utcnow()` to follow the new convention. * Adjust UTC usage to support Python 3.8 The recommended alternative for using utcnow() in the deprecation warnings emitted by Python 3.12 are not compatible with Python 3.8. The datetime.UTC alias was not added to Python until Python 3.11. To ensure that the code is compatible with Python < 3.11 this commit updates all the usage of datetime.UTC to use datetime.timezone.utc instead, which is what datetime.UTC aliases to in Python >=3.11. --- .github/workflows/wheels.yml | 10 +++++----- azure-pipelines.yml | 4 ++-- constraints.txt | 4 ++-- qiskit/providers/fake_provider/fake_backend_v2.py | 6 +++--- qiskit/providers/fake_provider/fake_mumbai_v2.py | 2 +- qiskit/transpiler/target.py | 8 ++++---- qiskit_pkg/setup.py | 1 + .../notes/add-py312-support-7077426af34ac5da.yaml | 4 ++++ requirements.txt | 2 +- setup.py | 1 + test/python/providers/test_fake_backends.py | 12 ++++++------ tox.ini | 2 +- 12 files changed, 31 insertions(+), 25 deletions(-) create mode 100644 releasenotes/notes/add-py312-support-7077426af34ac5da.yaml diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 336b86c8db52..41b15d89653b 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -21,7 +21,7 @@ jobs: python-version: '3.10' - uses: dtolnay/rust-toolchain@stable - name: Build wheels - uses: pypa/cibuildwheel@v2.13.0 + uses: pypa/cibuildwheel@v2.16.2 - uses: actions/upload-artifact@v3 with: path: ./wheelhouse/*.whl @@ -42,7 +42,7 @@ jobs: python-version: '3.10' - uses: dtolnay/rust-toolchain@stable - name: Build wheels - uses: pypa/cibuildwheel@v2.13.0 + uses: pypa/cibuildwheel@v2.16.2 env: CIBW_BEFORE_ALL: rustup target add aarch64-apple-darwin CIBW_ARCHS_MACOS: arm64 universal2 @@ -91,7 +91,7 @@ jobs: with: platforms: all - name: Build wheels - uses: pypa/cibuildwheel@v2.13.0 + uses: pypa/cibuildwheel@v2.16.2 env: CIBW_ARCHS_LINUX: s390x CIBW_TEST_SKIP: "cp*" @@ -124,7 +124,7 @@ jobs: with: platforms: all - name: Build wheels - uses: pypa/cibuildwheel@v2.13.0 + uses: pypa/cibuildwheel@v2.16.2 env: CIBW_ARCHS_LINUX: ppc64le CIBW_TEST_SKIP: "cp*" @@ -157,7 +157,7 @@ jobs: with: platforms: all - name: Build wheels - uses: pypa/cibuildwheel@v2.13.0 + uses: pypa/cibuildwheel@v2.16.2 env: CIBW_ARCHS_LINUX: aarch64 - uses: actions/upload-artifact@v3 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1c85874e9f10..8fc21b7d8db1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -31,7 +31,7 @@ parameters: - name: "supportedPythonVersions" displayName: "All supported versions of Python" type: object - default: ["3.8", "3.9", "3.10", "3.11"] + default: ["3.8", "3.9", "3.10", "3.11", "3.12"] - name: "minimumPythonVersion" displayName: "Minimum supported version of Python" @@ -41,7 +41,7 @@ parameters: - name: "maximumPythonVersion" displayName: "Maximum supported version of Python" type: string - default: "3.11" + default: "3.12" # These two versions of Python can be chosen somewhat arbitrarily, but we get # slightly better coverage per PR if they're neither the maximum nor minimum diff --git a/constraints.txt b/constraints.txt index 07b9862e426c..ef4197223893 100644 --- a/constraints.txt +++ b/constraints.txt @@ -5,12 +5,12 @@ jsonschema==3.2.0 # Numpy 1.25 deprecated some behaviours that we used, and caused the isometry # tests to flake. See https://github.com/Qiskit/qiskit-terra/issues/10305, # remove pin when resolving that. -numpy<1.25 +numpy<1.25; python_version<'3.12' # Scipy 1.11 seems to have caused an instability in the Weyl coordinates # eigensystem code for one of the test cases. See # https://github.com/Qiskit/qiskit-terra/issues/10345 for current details. -scipy<1.11 +scipy<1.11; python_version<'3.12' # Aer 0.13 causes several randomised tests to begin failing, and some # `QuantumInstance` use of noise models to raise exceptions. These need fixes diff --git a/qiskit/providers/fake_provider/fake_backend_v2.py b/qiskit/providers/fake_provider/fake_backend_v2.py index 23b0c58dadce..96cd6dff9d37 100644 --- a/qiskit/providers/fake_provider/fake_backend_v2.py +++ b/qiskit/providers/fake_provider/fake_backend_v2.py @@ -42,7 +42,7 @@ def __init__(self): None, name="FakeV2", description="A fake BackendV2 example", - online_date=datetime.datetime.utcnow(), + online_date=datetime.datetime.now(datetime.timezone.utc), backend_version="0.0.1", ) self._qubit_properties = [ @@ -116,7 +116,7 @@ def __init__(self, bidirectional=True): None, name="Fake5QV2", description="A fake BackendV2 example", - online_date=datetime.datetime.utcnow(), + online_date=datetime.datetime.now(datetime.timezone.utc), backend_version="0.0.1", ) qubit_properties = [ @@ -188,7 +188,7 @@ def __init__(self): None, name="FakeSimpleV2", description="A fake simple BackendV2 example", - online_date=datetime.datetime.utcnow(), + online_date=datetime.datetime.now(datetime.timezone.utc), backend_version="0.0.1", ) self._lam = Parameter("lambda") diff --git a/qiskit/providers/fake_provider/fake_mumbai_v2.py b/qiskit/providers/fake_provider/fake_mumbai_v2.py index 1a5f1c24d4a3..8474319dfa62 100644 --- a/qiskit/providers/fake_provider/fake_mumbai_v2.py +++ b/qiskit/providers/fake_provider/fake_mumbai_v2.py @@ -39,7 +39,7 @@ def __init__(self): super().__init__( name="FakeMumbaiFractionalCX", description="A fake BackendV2 example based on IBM Mumbai", - online_date=datetime.datetime.utcnow(), + online_date=datetime.datetime.now(datetime.timezone.utc), backend_version="0.0.1", ) dt = 0.2222222222222222e-9 diff --git a/qiskit/transpiler/target.py b/qiskit/transpiler/target.py index 5171951119d9..bc42a9c11e99 100644 --- a/qiskit/transpiler/target.py +++ b/qiskit/transpiler/target.py @@ -1477,7 +1477,7 @@ def target_to_backend_properties(target: Target): if getattr(props, "duration", None) is not None: property_list.append( { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "gate_length", "unit": "s", "value": props.duration, @@ -1486,7 +1486,7 @@ def target_to_backend_properties(target: Target): if getattr(props, "error", None) is not None: property_list.append( { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "gate_error", "unit": "", "value": props.error, @@ -1511,7 +1511,7 @@ def target_to_backend_properties(target: Target): if getattr(props, "error", None) is not None: props_list.append( { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "readout_error", "unit": "", "value": props.error, @@ -1520,7 +1520,7 @@ def target_to_backend_properties(target: Target): if getattr(props, "duration", None) is not None: props_list.append( { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "readout_length", "unit": "s", "value": props.duration, diff --git a/qiskit_pkg/setup.py b/qiskit_pkg/setup.py index 4846b2d0b9f6..ecff044d2ac5 100644 --- a/qiskit_pkg/setup.py +++ b/qiskit_pkg/setup.py @@ -52,6 +52,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering", ], keywords="qiskit sdk quantum", diff --git a/releasenotes/notes/add-py312-support-7077426af34ac5da.yaml b/releasenotes/notes/add-py312-support-7077426af34ac5da.yaml new file mode 100644 index 000000000000..4e2be1e92983 --- /dev/null +++ b/releasenotes/notes/add-py312-support-7077426af34ac5da.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Added support for using Qiskit with Python 3.12. diff --git a/requirements.txt b/requirements.txt index 7620b00ee3ec..31206e951128 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,4 @@ dill>=0.3 python-dateutil>=2.8.0 stevedore>=3.0.0 typing-extensions; python_version<'3.11' -symengine>=0.9, <0.10 +symengine>=0.9,!=0.10.0 diff --git a/setup.py b/setup.py index 97ca604fd757..751a151f21fc 100644 --- a/setup.py +++ b/setup.py @@ -78,6 +78,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering", ], keywords="qiskit sdk quantum", diff --git a/test/python/providers/test_fake_backends.py b/test/python/providers/test_fake_backends.py index 1b7668a5b9f4..078a5110f818 100644 --- a/test/python/providers/test_fake_backends.py +++ b/test/python/providers/test_fake_backends.py @@ -497,7 +497,7 @@ def test_filter_faulty_qubits_backend_v2_converter(self): props_dict = backend.properties().to_dict() for i in range(62, 67): non_operational = { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "operational", "unit": "", "value": 0, @@ -518,7 +518,7 @@ def test_filter_faulty_qubits_backend_v2_converter_with_delay(self): props_dict = backend.properties().to_dict() for i in range(62, 67): non_operational = { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "operational", "unit": "", "value": 0, @@ -539,7 +539,7 @@ def test_filter_faulty_qubits_and_gates_backend_v2_converter(self): props_dict = backend.properties().to_dict() for i in range(62, 67): non_operational = { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "operational", "unit": "", "value": 0, @@ -556,7 +556,7 @@ def test_filter_faulty_qubits_and_gates_backend_v2_converter(self): (34, 24), } non_operational_gate = { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "operational", "unit": "", "value": 0, @@ -591,7 +591,7 @@ def test_filter_faulty_gates_v2_converter(self): (34, 24), } non_operational_gate = { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "operational", "unit": "", "value": 0, @@ -618,7 +618,7 @@ def test_filter_faulty_no_faults_v2_converter(self): def test_faulty_full_path_transpile_connected_cmap(self, opt_level): backend = FakeYorktown() non_operational_gate = { - "date": datetime.datetime.utcnow(), + "date": datetime.datetime.now(datetime.timezone.utc), "name": "operational", "unit": "", "value": 0, diff --git a/tox.ini b/tox.ini index 0c799d28ba9a..5c517b1d2cc9 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 3.3.0 -envlist = py38, py39, py310, py311, lint-incr +envlist = py38, py39, py310, py311, py312, lint-incr isolated_build = true [testenv]