Skip to content

Commit f04682b

Browse files
authored
Drop support for Python 3.8 (#743)
* Drop support for python 3.8 * Relax matplotlib requirement * Incorporate matplotlib type hints
1 parent 96ab5c4 commit f04682b

File tree

16 files changed

+114
-61
lines changed

16 files changed

+114
-61
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
strategy:
5959
fail-fast: false
6060
matrix:
61-
python-version: ["3.8", "3.12"]
61+
python-version: ["3.9", "3.12"]
6262
with-torch: ["with-torch", "no-torch"]
6363
steps:
6464
- name: Check out Pulser

.github/workflows/publish.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
fail-fast: false
6767
matrix:
6868
os: [ubuntu-latest, macos-latest, windows-latest]
69-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
69+
python-version: ["3.9", "3.10", "3.11", "3.12"]
7070
steps:
7171
- name: Check out Pulser
7272
uses: actions/checkout@v4

.github/workflows/test.yml

+3-5
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,12 @@ jobs:
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
# Python 3.8 and 3.9 does not run on macos-latest (14)
19-
# Uses macos-13 for 3.8 and 3.9 and macos-latest for >=3.10
18+
# Python 3.9 does not run on macos-latest (14)
19+
# Uses macos-13 for 3.9 and macos-latest for >=3.10
2020
os: [ubuntu-latest, macos-13, macos-latest, windows-latest]
2121
with-torch: ["with-torch", "no-torch"]
22-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
22+
python-version: ["3.9", "3.10", "3.11", "3.12"]
2323
exclude:
24-
- os: macos-latest
25-
python-version: "3.8"
2624
- os: macos-latest
2725
python-version: "3.9"
2826
- os: macos-13

.mypy.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ warn_unused_ignores = True
1111
disallow_untyped_defs = True
1212

1313
# 3rd-party libs without type hints nor stubs
14-
[mypy-matplotlib.*,scipy.*,qutip.*,jsonschema.*,py.*]
14+
[mypy-scipy.*,qutip.*,jsonschema.*,py.*]
1515
follow_imports = silent
1616
ignore_missing_imports = True
1717

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ For a comprehensive overview of Pulser, check out [Pulser's white paper](https:/
2323

2424
**Note**: *Pulser v0.6 introduced a split of the ``pulser`` package that prevents it from being correctly upgraded. If you have an older version of ``pulser`` installed and wish to upgrade, make sure to uninstall it first by running ``pip uninstall pulser``.*
2525

26-
To install the latest release of ``pulser``, have Python 3.8 or higher installed, then use ``pip``:
26+
To install the latest release of ``pulser``, have Python 3.9 or higher installed, then use ``pip``:
2727

2828
```bash
2929
pip install pulser

docs/source/installation.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Installation
1010

1111
before proceeding to any of the steps below.
1212

13-
To install the latest release of ``pulser``, have Python 3.8 or higher
13+
To install the latest release of ``pulser``, have Python 3.9 or higher
1414
installed, then use ``pip``: ::
1515

1616
pip install pulser

pulser-core/pulser/register/_reg_drawer.py

+40-16
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from collections.abc import Mapping
1919
from collections.abc import Sequence as abcSequence
2020
from itertools import combinations
21-
from typing import TYPE_CHECKING, Optional
21+
from typing import TYPE_CHECKING, Any, Optional, Tuple, cast
2222

2323
import matplotlib.pyplot as plt
2424
import numpy as np
@@ -48,15 +48,15 @@ def default_qubit_color() -> str:
4848

4949
@staticmethod
5050
def _draw_2D(
51-
ax: plt.axes._subplots.AxesSubplot,
51+
ax: plt.Axes,
5252
pos: np.ndarray,
5353
ids: abcSequence[QubitId],
5454
plane: tuple = (0, 1),
5555
with_labels: bool = True,
5656
blockade_radius: Optional[float] = None,
5757
draw_graph: bool = True,
5858
draw_half_radius: bool = False,
59-
qubit_colors: Mapping[QubitId, str] = dict(),
59+
qubit_colors: Mapping[QubitId, Any] = dict(),
6060
masked_qubits: set[QubitId] = set(),
6161
are_traps: bool = False,
6262
dmm_qubits: Mapping[QubitId, float] = {},
@@ -68,6 +68,7 @@ def _draw_2D(
6868

6969
ix, iy = plane
7070

71+
params: dict[str, Any]
7172
if are_traps:
7273
params = dict(
7374
s=50,
@@ -107,7 +108,7 @@ def _draw_2D(
107108
dmm_arr[:, iy],
108109
marker="s",
109110
s=1200,
110-
alpha=alpha,
111+
alpha=alpha, # type: ignore[arg-type]
111112
c="black" if not qubit_colors else ordered_qubit_colors,
112113
)
113114
axes = "xyz"
@@ -194,12 +195,12 @@ def _draw_2D(
194195
fontsize=12 if i not in final_plot_det_map else 8.3,
195196
multialignment="right",
196197
)
197-
txt._get_wrap_line_width = lambda: 50.0
198+
txt._get_wrap_line_width = lambda: 50.0 # type: ignore
198199

199200
if draw_half_radius and blockade_radius is not None:
200201
for p, color in zip(pos, ordered_qubit_colors):
201202
circle = plt.Circle(
202-
tuple(p[[ix, iy]]),
203+
(p[ix], p[iy]),
203204
blockade_radius / 2,
204205
alpha=0.1,
205206
color=color,
@@ -214,7 +215,11 @@ def _draw_2D(
214215
lines = bonds[:, :, (ix, iy)]
215216
else:
216217
lines = np.array([])
217-
lc = mc.LineCollection(lines, linewidths=0.6, colors="grey")
218+
lc = mc.LineCollection(
219+
cast(abcSequence[np.ndarray], lines),
220+
linewidths=0.6,
221+
colors="grey",
222+
)
218223
ax.add_collection(lc)
219224

220225
else:
@@ -258,9 +263,14 @@ def _draw_3D(
258263
blockade_radius=blockade_radius,
259264
draw_half_radius=draw_half_radius,
260265
)
261-
fig.get_layout_engine().set(w_pad=6.5)
262-
263-
for ax, (ix, iy) in zip(axes, combinations(np.arange(3), 2)):
266+
_layout_engine = fig.get_layout_engine()
267+
assert _layout_engine is not None
268+
_layout_engine.set(w_pad=6.5) # type: ignore[call-arg]
269+
270+
for ax, (ix, iy) in zip(
271+
cast(abcSequence[plt.Axes], axes),
272+
combinations(np.arange(3), 2),
273+
):
264274
RegDrawer._draw_2D(
265275
ax,
266276
pos,
@@ -284,7 +294,12 @@ def _draw_3D(
284294
)
285295

286296
else:
287-
fig = plt.figure(figsize=2 * plt.figaspect(0.5))
297+
fig = plt.figure(
298+
figsize=cast(
299+
Tuple[float, float],
300+
tuple(2 * np.array(plt.figaspect(0.5))),
301+
)
302+
)
288303

289304
if draw_graph and blockade_radius is not None:
290305
bonds = {}
@@ -293,6 +308,7 @@ def _draw_3D(
293308
xj, yj, zj = pos[j]
294309
bonds[(i, j)] = [[xi, xj], [yi, yj], [zi, zj]]
295310

311+
params: dict[str, Any]
296312
if are_traps:
297313
params = dict(s=50, c="white", edgecolors="black")
298314
else:
@@ -313,7 +329,7 @@ def _draw_3D(
313329
coords[0],
314330
coords[1],
315331
coords[2],
316-
q,
332+
q, # type: ignore[arg-type]
317333
fontsize=12,
318334
ha="left",
319335
va="bottom",
@@ -336,15 +352,21 @@ def _draw_3D(
336352
y = radius * np.sin(u) * np.sin(v) + y0
337353
z = radius * np.cos(v) + z0
338354
# alpha controls opacity
339-
ax.plot_surface(x, y, z, color=color, alpha=0.1)
355+
ax.plot_surface( # type: ignore[attr-defined]
356+
x,
357+
y,
358+
z,
359+
color=color,
360+
alpha=0.1,
361+
)
340362

341363
if draw_graph and blockade_radius is not None:
342364
for x, y, z in bonds.values():
343365
ax.plot(x, y, z, linewidth=1.5, color="grey")
344366

345367
ax.set_xlabel("x (µm)")
346368
ax.set_ylabel("y (µm)")
347-
ax.set_zlabel("z (µm)")
369+
ax.set_zlabel("z (µm)") # type: ignore[attr-defined]
348370

349371
@staticmethod
350372
def _register_dims(
@@ -367,7 +389,7 @@ def _initialize_fig_axes(
367389
blockade_radius: Optional[float] = None,
368390
draw_half_radius: bool = False,
369391
nregisters: int = 1,
370-
) -> tuple[plt.figure.Figure, plt.axes.Axes]:
392+
) -> tuple[plt.Figure, plt.Axes | abcSequence[plt.Axes]]:
371393
"""Creates the Figure and Axes for drawing the register."""
372394
diffs = RegDrawer._register_dims(
373395
pos,
@@ -394,7 +416,9 @@ def _initialize_fig_axes_projection(
394416
blockade_radius: Optional[float] = None,
395417
draw_half_radius: bool = False,
396418
nregisters: int = 1,
397-
) -> tuple[plt.figure.Figure, plt.axes.Axes]:
419+
) -> tuple[
420+
plt.Figure, abcSequence[plt.Axes] | abcSequence[abcSequence[plt.Axes]]
421+
]:
398422
"""Creates the Figure and Axes for drawing the register projections."""
399423
diffs = RegDrawer._register_dims(
400424
pos,

pulser-core/pulser/register/register.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import warnings
1919
from collections.abc import Mapping
20-
from typing import Any, Optional, Union
20+
from typing import Any, Optional, Union, cast
2121

2222
import matplotlib.pyplot as plt
2323
import numpy as np
@@ -408,10 +408,13 @@ def draw(
408408

409409
pos = self._coords_arr.as_array(detach=True)
410410
if custom_ax is None:
411-
_, custom_ax = self._initialize_fig_axes(
412-
pos,
413-
blockade_radius=blockade_radius,
414-
draw_half_radius=draw_half_radius,
411+
custom_ax = cast(
412+
plt.Axes,
413+
self._initialize_fig_axes(
414+
pos,
415+
blockade_radius=blockade_radius,
416+
draw_half_radius=draw_half_radius,
417+
)[1],
415418
)
416419
super()._draw_2D(
417420
custom_ax,

pulser-core/pulser/register/register_layout.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from collections.abc import Sequence as abcSequence
2222
from dataclasses import dataclass
2323
from operator import itemgetter
24-
from typing import Any, Optional
24+
from typing import Any, Optional, cast
2525

2626
import matplotlib.pyplot as plt
2727
import numpy as np
@@ -180,7 +180,7 @@ def draw(
180180
draw_half_radius=draw_half_radius,
181181
)
182182
self._draw_2D(
183-
ax,
183+
cast(plt.Axes, ax),
184184
coords,
185185
ids,
186186
blockade_radius=blockade_radius,

pulser-core/pulser/register/weight_maps.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ def draw(
121121
need to set this flag to False.
122122
"""
123123
pos = self.trap_coordinates
124-
if custom_ax is None:
125-
_, custom_ax = self._initialize_fig_axes(pos)
124+
custom_ax = custom_ax or cast(Axes, self._initialize_fig_axes(pos)[1])
126125

127126
labels_ = labels if labels is not None else list(range(len(pos)))
128127

0 commit comments

Comments
 (0)