Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Support python 3.11 #614

Merged
merged 14 commits into from
May 11, 2023
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [ 3.8, 3.9, '3.10' ]
python-version: [ 3.8, 3.9, '3.10', '3.11']
os: [ "macOS-latest", "ubuntu-latest", "windows-latest" ]
env:
LOG_LEVEL: DEBUG
Expand Down
2 changes: 0 additions & 2 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ confidence=
# no Warning level messages displayed, use "--disable=all --enable=classes
# --disable=W".
disable=arguments-renamed, # more readable and clear
bad-continuation, bad-whitespace, # differences of opinion with black
consider-using-f-string, # unnecesary to convert all str.format() to f strings
consider-using-with, # too verbose, not all resource-allocating operations should have `with`
docstring-first-line-empty, # docstrings are more readable
Expand All @@ -76,7 +75,6 @@ disable=arguments-renamed, # more readable and clear
missing-param-doc, # false positives when docs contain ":"
no-else-return, # relax "elif" after a clause with a return
no-member, # false positives when variable from external function
no-self-use, # too verbose
protected-access, # we don't strictly follow the public vs. private convention
raise-missing-from, # not every exception needs `from`, adding `from None` is too verbose
too-few-public-methods, # too verbose
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def least_busy(backends: List[Backend]) -> Backend:
"""
if not backends:
raise IBMError(
"Unable to find the least_busy " "backend from an empty list."
"Unable to find the least_busy backend from an empty list."
) from None
try:
candidates = []
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_provider/ibm_qubit_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class IBMQubitProperties(QubitProperties):
"""A representation of the properties of a qubit on an IBM backend."""

__slots__ = (
__slots__ = ( # pylint: disable=redefined-slots-in-subclass
"t1",
"t2",
"frequency",
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_provider/job/ibm_circuit_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ def _download_external_result(self, response: Any) -> Any:
result_url_json = json.loads(response)
if "url" in result_url_json:
url = result_url_json["url"]
result_response = requests.get(url)
result_response = requests.get(url, timeout=10)
return result_response.content
return response
except json.JSONDecodeError:
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_provider/job/ibm_composite_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ def creation_date(self) -> Optional[datetime]:
circuit_jobs = self._get_circuit_jobs()
if not circuit_jobs:
return None
self._creation_date = min([job.creation_date() for job in circuit_jobs])
self._creation_date = min(job.creation_date() for job in circuit_jobs)
return self._creation_date

def time_per_step(self) -> Optional[Dict]:
Expand Down
4 changes: 2 additions & 2 deletions qiskit_ibm_provider/jupyter/dashboard/backend_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ def make_backend_widget(backend_item: BackendWithProviders) -> wid.HBox:

# Get basic device stats
t1_units = props["qubits"][0][0]["unit"]
avg_t1 = round(sum([q[0]["value"] for q in props["qubits"]]) / n_qubits, 1)
avg_t2 = round(sum([q[1]["value"] for q in props["qubits"]]) / n_qubits, 1)
avg_t1 = round(sum(q[0]["value"] for q in props["qubits"]) / n_qubits, 1)
avg_t2 = round(sum(q[1]["value"] for q in props["qubits"]) / n_qubits, 1)

if n_qubits != 1:
sum_cx_err = 0
Expand Down
1 change: 1 addition & 0 deletions qiskit_ibm_provider/jupyter/dashboard/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ def cancel_job(self, job_id: str) -> None:
ind = idx
break
if not do_pop:
# pylint: disable=broad-exception-raised
raise Exception("Job is not found.")
if self.jobs[ind].children[3].value not in ["CANCELLED", "DONE", "ERROR"]:
try:
Expand Down
8 changes: 4 additions & 4 deletions qiskit_ibm_provider/jupyter/jobs_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,15 @@ def _job_summary(
parents=parents,
values=values,
branchvalues="total",
textfont=dict(size=18),
outsidetextfont=dict(size=20),
textfont={"size": 18},
outsidetextfont={"size": 20},
maxdepth=2,
hoverinfo="text",
hovertext=hover_text,
marker=dict(colors=wedge_colors),
marker={"colors": wedge_colors},
)
)
fig.update_layout(margin=dict(t=10, l=10, r=10, b=10))
fig.update_layout(margin={"t": 10, "l": 10, "r": 10, "b": 10})
sun_wid = PlotlyWidget(fig)
sun_wid._active = 0
sun_wid._job_index = index_jobs
Expand Down
4 changes: 0 additions & 4 deletions qiskit_ibm_provider/qpy/binary_io/schedules.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import numpy as np

from qiskit.exceptions import QiskitError
from qiskit.pulse import library, channels, instructions
from qiskit.pulse.schedule import ScheduleBlock
from qiskit.utils import optionals as _optional
Expand Down Expand Up @@ -436,9 +435,6 @@ def read_schedule_block(file_obj, version, metadata_deserializer=None): # type:
QiskitError: QPY version is earlier than block support.
"""

if version < 5:
QiskitError(f"QPY version {version} does not support ScheduleBlock.")

data = formats.SCHEDULE_BLOCK_HEADER._make(
struct.unpack(
formats.SCHEDULE_BLOCK_HEADER_PACK,
Expand Down
7 changes: 4 additions & 3 deletions qiskit_ibm_provider/qpy/binary_io/value.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"""Binary IO for any value objects, such as numbers, string, parameters."""

import struct
from typing import Any
import uuid

import numpy as np
Expand Down Expand Up @@ -93,7 +92,7 @@ def _read_parameter(file_obj): # type: ignore[no-untyped-def]
param_uuid = uuid.UUID(bytes=data.uuid)
name = file_obj.read(data.name_size).decode(common.ENCODE)
param = Parameter.__new__(Parameter, name, uuid=param_uuid)
param.__init__(name)
param.__init__(name) # pylint: disable=unnecessary-dunder-call
return param


Expand All @@ -114,7 +113,9 @@ def _read_parameter_vec(file_obj, vectors): # type: ignore[no-untyped-def]
vector._params[data.index] = ParameterVectorElement.__new__(
ParameterVectorElement, vector, data.index, uuid=param_uuid
)
vector._params[data.index].__init__(vector, data.index)
vector._params[data.index].__init__( # pylint: disable=unnecessary-dunder-call
vector, data.index
)
return vector[data.index]


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

"""Padding pass to fill timeslots for IBM (dynamic circuit) backends."""

from typing import Any, Dict, Iterable, List, Optional, Union, Set
from typing import Dict, Iterable, List, Optional, Union, Set

from qiskit.circuit import (
Qubit,
Expand Down
30 changes: 15 additions & 15 deletions qiskit_ibm_provider/visualization/interactive/error_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def iplot_error_map(
paper_bgcolor=background_color,
width=figsize[0],
height=figsize[1],
margin=dict(t=60, l=0, r=0, b=0),
margin={"t": 60, "l": 0, "r": 0, "b": 0},
)
out = PlotlyWidget(fig)
return out
Expand Down Expand Up @@ -193,8 +193,8 @@ def iplot_error_map(
num_left = math.ceil(n_qubits / 2)
num_right = n_qubits - num_left

x_max = max([d[1] for d in grid_data])
y_max = max([d[0] for d in grid_data])
x_max = max(d[1] for d in grid_data)
y_max = max(d[0] for d in grid_data)
max_dim = max(x_max, y_max)

qubit_size = 32
Expand Down Expand Up @@ -302,7 +302,7 @@ def iplot_error_map(
x=[x_start, x_mid, x_end],
y=[-y_start, -y_mid, -y_end],
mode="lines",
line=dict(width=6, color=line_colors[ind]),
line={"width": 6, "color": line_colors[ind]},
hoverinfo="text",
hovertext="CX<sub>err</sub>{B}_{A} = {err} %".format(
A=edge[0], B=edge[1], err=np.round(cx_errors[ind], 3)
Expand Down Expand Up @@ -352,7 +352,7 @@ def iplot_error_map(
marker=go.scatter.Marker(size=qubit_size, color=q_colors, opacity=1),
text=[str(ii) for ii in range(n_qubits)],
textposition="middle center",
textfont=dict(size=font_size, color=qtext_color),
textfont={"size": font_size, "color": qtext_color},
hoverinfo="text",
hovertext=qubit_text,
),
Expand Down Expand Up @@ -441,9 +441,9 @@ def iplot_error_map(
x=[read_err[kk]],
y=[kk],
orientation="h",
marker=dict(color="#eedccb"),
marker={"color": "#eedccb"},
hoverinfo="text",
hoverlabel=dict(font=dict(color=meas_text_color)),
hoverlabel={"font": {"color": meas_text_color}},
hovertext=[hover_text.format(kk, np.round(read_err[kk], 3))],
),
row=1,
Expand All @@ -456,7 +456,7 @@ def iplot_error_map(
y=[-0.25, num_left - 1 + 0.25],
mode="lines",
hoverinfo="none",
line=dict(color=text_color, width=2, dash="dot"),
line={"color": text_color, "width": 2, "dash": "dot"},
),
row=1,
col=1,
Expand Down Expand Up @@ -486,9 +486,9 @@ def iplot_error_map(
x=[-read_err[kk]],
y=[kk],
orientation="h",
marker=dict(color="#eedccb"),
marker={"color": "#eedccb"},
hoverinfo="text",
hoverlabel=dict(font=dict(color=meas_text_color)),
hoverlabel={"font": {"color": meas_text_color}},
hovertext=[hover_text.format(kk, np.round(read_err[kk], 3))],
),
row=1,
Expand All @@ -501,7 +501,7 @@ def iplot_error_map(
y=[num_left - 0.25, n_qubits - 1 + 0.25],
mode="lines",
hoverinfo="none",
line=dict(color=text_color, width=2, dash="dot"),
line={"color": text_color, "width": 2, "dash": "dot"},
),
row=1,
col=9,
Expand Down Expand Up @@ -532,7 +532,7 @@ def iplot_error_map(

# Makes the subplot titles smaller than the 16pt default
for ann in fig["layout"]["annotations"]:
ann["font"] = dict(size=13)
ann["font"] = {"size": 13}

title_text = "{} Error Map".format(backend.name) if show_title else ""
fig.update_layout(
Expand All @@ -541,10 +541,10 @@ def iplot_error_map(
paper_bgcolor=background_color,
width=figsize[0],
height=figsize[1],
title=dict(text=title_text, x=0.452),
title={"text": title_text, "x": 0.452},
title_font_size=20,
font=dict(color=text_color),
margin=dict(t=60, l=0, r=40, b=0),
font={"color": text_color},
margin={"t": 60, "l": 0, "r": 40, "b": 0},
)
if as_widget:
return PlotlyWidget(fig)
Expand Down
8 changes: 4 additions & 4 deletions qiskit_ibm_provider/visualization/interactive/gate_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def iplot_gate_map(
paper_bgcolor=background_color,
width=figsize[0],
height=figsize[1],
margin=dict(t=30, l=0, r=0, b=0),
margin={"t": 30, "l": 0, "r": 0, "b": 0},
)

if as_widget:
Expand Down Expand Up @@ -188,7 +188,7 @@ def iplot_gate_map(
y=[-y_start, -y_mid, -y_end],
mode="lines",
hoverinfo="none",
line=dict(width=line_width, color=line_color[ind]),
line={"width": line_width, "color": line_color[ind]},
)
)

Expand All @@ -213,7 +213,7 @@ def iplot_gate_map(
marker=go.scatter.Marker(size=qubit_size, color=qubit_color, opacity=1),
text=[str(ii) for ii in range(n_qubits)] if label_qubits else None,
textposition="middle center",
textfont=dict(size=font_size, color=font_color),
textfont={"size": font_size, "color": font_color},
hoverinfo="text" if label_qubits else "none",
hovertext=qubit_text,
)
Expand All @@ -231,7 +231,7 @@ def iplot_gate_map(
paper_bgcolor=background_color,
width=figsize[0],
height=figsize[1],
margin=dict(t=30, l=0, r=0, b=0),
margin={"t": 30, "l": 0, "r": 0, "b": 0},
)

if as_widget:
Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/python-3.11-support-68160484eff57263.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
features:
- |
Python 3.11 is now supported.
3 changes: 1 addition & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mypy==0.931
pylint==2.12.2
vcrpy
pylint==2.16.2
pproxy==2.7.8
matplotlib>=3.3
jupyter
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Scientific/Engineering",
],
keywords="qiskit sdk quantum api ibmq",
Expand Down
2 changes: 2 additions & 0 deletions test/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def _wrapper(self, *args, **kwargs):
)
)
if not _backend:
# pylint: disable=broad-exception-raised
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps instead change to IBMBackendError instead of disabling?
May also be applicable to other exceptions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think IBMBackendError would make it more clear since it's a configuration issue so i'll leave it as is for now

raise Exception("Unable to find a suitable backend.")

kwargs["backend"] = _backend
Expand Down Expand Up @@ -111,6 +112,7 @@ def _decorator(func):
def _wrapper(self, *args, **kwargs):
token, url, instance, instance_private = _get_integration_test_config()
if not all([token, url]):
# pylint: disable=broad-exception-raised
raise Exception("Configuration Issue. Token and URL must be set.")

provider = None
Expand Down
10 changes: 5 additions & 5 deletions test/e2e/test_real_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ def test_run_multiple_device(self):
]
time.sleep(3) # give time for jobs to start (better way?)
job_status = [job.status() for job in job_array]
num_init = sum([status is JobStatus.INITIALIZING for status in job_status])
num_queued = sum([status is JobStatus.QUEUED for status in job_status])
num_running = sum([status is JobStatus.RUNNING for status in job_status])
num_done = sum([status is JobStatus.DONE for status in job_status])
num_error = sum([status is JobStatus.ERROR for status in job_status])
num_init = sum(status is JobStatus.INITIALIZING for status in job_status)
num_queued = sum(status is JobStatus.QUEUED for status in job_status)
num_running = sum(status is JobStatus.RUNNING for status in job_status)
num_done = sum(status is JobStatus.DONE for status in job_status)
num_error = sum(status is JobStatus.ERROR for status in job_status)
self.log.info(
"number of currently initializing jobs: %d/%d", num_init, num_jobs
)
Expand Down
2 changes: 1 addition & 1 deletion test/ibm_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def tearDown(self) -> None:
failed = False
# It's surprisingly difficult to find out whether the test failed.
# Using a private attribute is not ideal but it'll have to do.
if self._outcome and self._outcome.errors:
if self._outcome and hasattr(self._outcome, "errors"):
for _, exc_info in self._outcome.errors:
if exc_info is not None:
failed = True
Expand Down
4 changes: 2 additions & 2 deletions test/integration/test_ibm_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ def test_run_multiple_simulator(self):
timeout = 30
start_time = time.time()
while True:
check = sum([job.status() is JobStatus.RUNNING for job in job_array])
check = sum(job.status() is JobStatus.RUNNING for job in job_array)
if check >= 2:
self.log.info("found %d simultaneous jobs", check)
break
if all((job.status() is JobStatus.DONE for job in job_array)):
# done too soon? don't generate error
self.log.warning(
"all jobs completed before simultaneous jobs " "could be detected"
"all jobs completed before simultaneous jobs could be detected"
)
break
for job in job_array:
Expand Down
2 changes: 1 addition & 1 deletion test/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def most_busy_backend(
"""
backends = provider.backends(simulator=False, operational=True, instance=instance)
return max(
[b for b in backends if b.configuration().n_qubits >= 5],
(b for b in backends if b.configuration().n_qubits >= 5),
key=lambda b: b.status().pending_jobs,
)

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tox]
minversion = 3.15
envlist = py38, py39, py310, lint, docs
envlist = py38, py39, py310, py311, lint, docs
isolated_build = True

[testenv]
Expand Down