From 41edbfdf7a0933fca7a648417e03f75c21b31ba8 Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Mon, 31 Mar 2025 16:41:05 +0200 Subject: [PATCH] Update code to Python 3.11 --- lib/matplotlib/_api/__init__.pyi | 3 +-- lib/matplotlib/_api/deprecation.pyi | 5 +---- lib/matplotlib/_mathtext.py | 4 ++-- lib/matplotlib/axes/_base.py | 2 +- lib/matplotlib/axis.pyi | 3 +-- lib/matplotlib/backends/backend_pgf.py | 11 ++++++----- lib/matplotlib/backends/backend_ps.py | 14 +++++++------- lib/matplotlib/backends/backend_svg.py | 2 +- lib/matplotlib/cbook.pyi | 2 +- lib/matplotlib/colors.py | 3 +-- lib/matplotlib/dates.py | 6 +++--- lib/matplotlib/dviread.pyi | 3 +-- lib/matplotlib/sankey.pyi | 3 +-- lib/matplotlib/tests/test_api.py | 2 +- lib/matplotlib/tests/test_dates.py | 10 +++++----- lib/matplotlib/tests/test_figure.py | 2 +- lib/matplotlib/ticker.py | 4 ++-- lib/matplotlib/typing.py | 4 ++-- lib/mpl_toolkits/mplot3d/axes3d.py | 2 +- 19 files changed, 39 insertions(+), 46 deletions(-) diff --git a/lib/matplotlib/_api/__init__.pyi b/lib/matplotlib/_api/__init__.pyi index ea7076feac3c..ddd51ed6deda 100644 --- a/lib/matplotlib/_api/__init__.pyi +++ b/lib/matplotlib/_api/__init__.pyi @@ -1,6 +1,5 @@ from collections.abc import Callable, Generator, Iterable, Mapping, Sequence -from typing import Any, TypeVar, overload -from typing_extensions import Self # < Py 3.11 +from typing import Any, Self, TypeVar, overload from numpy.typing import NDArray diff --git a/lib/matplotlib/_api/deprecation.pyi b/lib/matplotlib/_api/deprecation.pyi index e050290662d9..30034c0f7f31 100644 --- a/lib/matplotlib/_api/deprecation.pyi +++ b/lib/matplotlib/_api/deprecation.pyi @@ -1,9 +1,6 @@ from collections.abc import Callable import contextlib -from typing import Any, Literal, ParamSpec, TypedDict, TypeVar, overload -from typing_extensions import ( - Unpack, # < Py 3.11 -) +from typing import Any, Literal, ParamSpec, TypedDict, TypeVar, Unpack, overload _P = ParamSpec("_P") _R = TypeVar("_R") diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index 6a1d9add9e8a..0794678a3a03 100644 --- a/lib/matplotlib/_mathtext.py +++ b/lib/matplotlib/_mathtext.py @@ -1966,9 +1966,9 @@ class _MathStyle(enum.Enum): """.split()) _delims = _left_delims | _right_delims | _ambi_delims - _small_greek = set([unicodedata.name(chr(i)).split()[-1].lower() for i in + _small_greek = {unicodedata.name(chr(i)).split()[-1].lower() for i in range(ord('\N{GREEK SMALL LETTER ALPHA}'), - ord('\N{GREEK SMALL LETTER OMEGA}') + 1)]) + ord('\N{GREEK SMALL LETTER OMEGA}') + 1)} _latin_alphabets = set(string.ascii_letters) def __init__(self) -> None: diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index c5c525b29a06..bee87c6a0f60 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -4114,7 +4114,7 @@ def format_coord(self, x, y): for ax in sorted(twins, key=attrgetter("zorder")): data_x, data_y = ax.transData.inverted().transform(screen_xy) xy_strs.append( - "({}, {})".format(ax.format_xdata(data_x), ax.format_ydata(data_y))) + f"({ax.format_xdata(data_x)}, {ax.format_ydata(data_y)})") return "(x, y) = {}".format(" | ".join(xy_strs)) def minorticks_on(self): diff --git a/lib/matplotlib/axis.pyi b/lib/matplotlib/axis.pyi index 6119b946fd7b..cd3d18ef9c4f 100644 --- a/lib/matplotlib/axis.pyi +++ b/lib/matplotlib/axis.pyi @@ -1,7 +1,6 @@ from collections.abc import Callable, Iterable, Sequence import datetime -from typing import Any, Literal, overload -from typing_extensions import Self # < Py 3.11 +from typing import Any, Literal, Self, overload import numpy as np from numpy.typing import ArrayLike diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index 48b6e8ac152c..b985831fc1c0 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -121,7 +121,7 @@ def _escape_and_apply_props(s, prop): _log.warning("Ignoring unknown font: %s", family) size = prop.get_size_in_points() - commands.append(r"\fontsize{%f}{%f}" % (size, size * 1.2)) + commands.append(r"\fontsize{{{:f}}}{{{:f}}}".format(size, size * 1.2)) styles = {"normal": r"", "italic": r"\itshape", "oblique": r"\slshape"} commands.append(styles[prop.get_style()]) @@ -416,7 +416,8 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, clip=clip): x, y = point[0] * f, point[1] * f _writeln(self.fh, r"\begin{pgfscope}") - _writeln(self.fh, r"\pgfsys@transformshift{%fin}{%fin}" % (x, y)) + _writeln(self.fh, + r"\pgfsys@transformshift{{{:f}in}}{{{:f}in}}".format(x, y)) _writeln(self.fh, r"\pgfsys@useobject{currentmarker}{}") _writeln(self.fh, r"\end{pgfscope}") @@ -465,7 +466,7 @@ def draw_path(self, gc, path, transform, rgbFace=None): ymin, ymax = f * ymin, f * ymax repx, repy = math.ceil(xmax - xmin), math.ceil(ymax - ymin) _writeln(self.fh, - r"\pgfsys@transformshift{%fin}{%fin}" % (xmin, ymin)) + r"\pgfsys@transformshift{{{:f}in}}{{{:f}in}}".format(xmin, ymin)) for iy in range(repy): for ix in range(repx): _writeln(self.fh, r"\pgfsys@useobject{currentpattern}{}") @@ -652,7 +653,7 @@ def draw_image(self, gc, x, y, im, transform=None): f = 1. / self.dpi # from display coords to inch if transform is None: _writeln(self.fh, - r"\pgfsys@transformshift{%fin}{%fin}" % (x * f, y * f)) + r"\pgfsys@transformshift{{{:f}in}}{{{:f}in}}".format(x * f, y * f)) w, h = w * f, h * f else: tr1, tr2, tr3, tr4, tr5, tr6 = transform.frozen().to_values() @@ -718,7 +719,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): if angle != 0: text_args.append("rotate=%f" % angle) - _writeln(self.fh, r"\pgftext[%s]{%s}" % (",".join(text_args), s)) + _writeln(self.fh, r"\pgftext[{}]{{{}}}".format(",".join(text_args), s)) _writeln(self.fh, r"\end{pgfscope}") def get_text_width_height_descent(self, s, prop, ismath): diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 62952caa32e1..728362cef76f 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -151,10 +151,10 @@ def _font_to_ps_type3(font_path, chars): g = font.load_glyph(glyph_id, LoadFlags.NO_SCALE) v, c = font.get_path() entries.append( - "/%(name)s{%(bbox)s sc\n" % { - "name": font.get_glyph_name(glyph_id), - "bbox": " ".join(map(str, [g.horiAdvance, 0, *g.bbox])), - } + "/{name}{{{bbox} sc\n".format( + name=font.get_glyph_name(glyph_id), + bbox=" ".join(map(str, [g.horiAdvance, 0, *g.bbox])), + ) + _path.convert_to_string( # Convert back to TrueType's internal units (1/64's). # (Other dimensions are already in these units.) @@ -740,14 +740,14 @@ def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None): 'monospace': r'{\ttfamily %s}'}.get( mpl.rcParams['font.family'][0], r'{\rmfamily %s}') s = fontcmd % s - tex = r'\color[rgb]{%s} %s' % (color, s) + tex = r'\color[rgb]{{{}}} {}'.format(color, s) # Stick to bottom-left alignment, so subtract descent from the text-normal # direction since text is normally positioned by its baseline. rangle = np.radians(angle + 90) pos = _nums_to_str(x - bl * np.cos(rangle), y - bl * np.sin(rangle)) self.psfrag.append( - r'\psfrag{%s}[bl][bl][1][%f]{\fontsize{%f}{%f}%s}' % ( + r'\psfrag{{{}}}[bl][bl][1][{:f}]{{\fontsize{{{:f}}}{{{:f}}}{}}}'.format( thetext, angle, fontsize, fontsize*1.25, tex)) self._pswriter.write(f"""\ @@ -981,7 +981,7 @@ def _print_ps( dsc_comments["CreationDate"] = ( datetime.datetime.fromtimestamp( int(source_date_epoch), - datetime.timezone.utc).strftime("%a %b %d %H:%M:%S %Y") + datetime.UTC).strftime("%a %b %d %H:%M:%S %Y") if source_date_epoch else time.ctime()) dsc_comments = "\n".join( diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 0cb6430ec823..ab345a059ba9 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -397,7 +397,7 @@ def _write_metadata(self, metadata): # See https://reproducible-builds.org/specs/source-date-epoch/ date = os.getenv("SOURCE_DATE_EPOCH") if date: - date = datetime.datetime.fromtimestamp(int(date), datetime.timezone.utc) + date = datetime.datetime.fromtimestamp(int(date), datetime.UTC) metadata['Date'] = date.replace(tzinfo=UTC).isoformat() else: metadata['Date'] = datetime.datetime.today().isoformat() diff --git a/lib/matplotlib/cbook.pyi b/lib/matplotlib/cbook.pyi index 6c2d9c303eb2..ad14841463e8 100644 --- a/lib/matplotlib/cbook.pyi +++ b/lib/matplotlib/cbook.pyi @@ -14,10 +14,10 @@ from typing import ( Generic, IO, Literal, - Sequence, TypeVar, overload, ) +from collections.abc import Sequence _T = TypeVar("_T") diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index e3c3b39e8bb2..e51f4c307dfa 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -1547,8 +1547,7 @@ def __getitem__(self, item): return self._colormaps[item] def __iter__(self): - for c in self._colormaps: - yield c + yield from self._colormaps def __len__(self): return len(self._colormaps) diff --git a/lib/matplotlib/dates.py b/lib/matplotlib/dates.py index 511e1c6df6cc..5200f040ceb3 100644 --- a/lib/matplotlib/dates.py +++ b/lib/matplotlib/dates.py @@ -202,7 +202,7 @@ _log = logging.getLogger(__name__) -UTC = datetime.timezone.utc +UTC = datetime.UTC def _get_tzinfo(tz=None): @@ -1169,14 +1169,14 @@ def _create_rrule(self, vmin, vmax): except (ValueError, OverflowError): # cap start = datetime.datetime(1, 1, 1, 0, 0, 0, - tzinfo=datetime.timezone.utc) + tzinfo=datetime.UTC) try: stop = vmax + delta except (ValueError, OverflowError): # cap stop = datetime.datetime(9999, 12, 31, 23, 59, 59, - tzinfo=datetime.timezone.utc) + tzinfo=datetime.UTC) self.rule.set(dtstart=start, until=stop) diff --git a/lib/matplotlib/dviread.pyi b/lib/matplotlib/dviread.pyi index 29d9288c047f..d4214f57419d 100644 --- a/lib/matplotlib/dviread.pyi +++ b/lib/matplotlib/dviread.pyi @@ -4,8 +4,7 @@ import os from enum import Enum from collections.abc import Generator -from typing import NamedTuple -from typing_extensions import Self # < Py 3.11 +from typing import NamedTuple, Self class _dvistate(Enum): pre = ... diff --git a/lib/matplotlib/sankey.pyi b/lib/matplotlib/sankey.pyi index 33565b998a9c..75a1bd5aed57 100644 --- a/lib/matplotlib/sankey.pyi +++ b/lib/matplotlib/sankey.pyi @@ -1,8 +1,7 @@ from matplotlib.axes import Axes from collections.abc import Callable, Iterable -from typing import Any -from typing_extensions import Self # < Py 3.11 +from typing import Any, Self import numpy as np diff --git a/lib/matplotlib/tests/test_api.py b/lib/matplotlib/tests/test_api.py index f04604c14cce..58e7986bfce6 100644 --- a/lib/matplotlib/tests/test_api.py +++ b/lib/matplotlib/tests/test_api.py @@ -13,7 +13,7 @@ if typing.TYPE_CHECKING: - from typing_extensions import Self + from typing import Self T = TypeVar('T') diff --git a/lib/matplotlib/tests/test_dates.py b/lib/matplotlib/tests/test_dates.py index 73f10cec52aa..6e3784e647df 100644 --- a/lib/matplotlib/tests/test_dates.py +++ b/lib/matplotlib/tests/test_dates.py @@ -855,7 +855,7 @@ def _create_auto_date_locator(date1, date2, tz): sts = [st.get_text() for st in ax.get_yticklabels()] return sts, ax.yaxis.get_offset_text().get_text() - d1 = datetime.datetime(1997, 1, 1).replace(tzinfo=datetime.timezone.utc) + d1 = datetime.datetime(1997, 1, 1).replace(tzinfo=datetime.UTC) results = ([datetime.timedelta(hours=40), ['03:00', '07:00', '11:00', '15:00', '19:00', '23:00', '03:00', '07:00', '11:00', '15:00', '19:00'], @@ -1310,8 +1310,8 @@ def test_DateLocator(): locator.create_dummy_axis() # default values assert locator.datalim_to_dt() == ( - datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - datetime.datetime(1970, 1, 2, 0, 0, tzinfo=datetime.timezone.utc)) + datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.UTC), + datetime.datetime(1970, 1, 2, 0, 0, tzinfo=datetime.UTC)) # Check default is UTC assert locator.tz == mdates.UTC @@ -1395,10 +1395,10 @@ def test_num2date_error(val): def test_num2date_roundoff(): assert mdates.num2date(100000.0000578702) == datetime.datetime( - 2243, 10, 17, 0, 0, 4, 999980, tzinfo=datetime.timezone.utc) + 2243, 10, 17, 0, 0, 4, 999980, tzinfo=datetime.UTC) # Slightly larger, steps of 20 microseconds assert mdates.num2date(100000.0000578703) == datetime.datetime( - 2243, 10, 17, 0, 0, 5, tzinfo=datetime.timezone.utc) + 2243, 10, 17, 0, 0, 5, tzinfo=datetime.UTC) def test_DateFormatter_settz(): diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index c80f53413181..6ef900888b89 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -1349,7 +1349,7 @@ def test_subfigure(): fig.suptitle('Figure suptitle', fontsize='xx-large') # below tests for the draw zorder of subfigures. - leg = fig.legend(handles=[plt.Line2D([0], [0], label='Line{}'.format(i)) + leg = fig.legend(handles=[plt.Line2D([0], [0], label=f'Line{i}') for i in range(5)], loc='center') sub[0].set_zorder(leg.get_zorder() - 1) sub[1].set_zorder(leg.get_zorder() + 1) diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index b5c12e7f4905..58864a59585a 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -1086,7 +1086,7 @@ class LogFormatterMathtext(LogFormatter): def _non_decade_format(self, sign_string, base, fx, usetex): """Return string for non-decade locations.""" - return r'$\mathdefault{%s%s^{%.2f}}$' % (sign_string, base, fx) + return r'$\mathdefault{{{}{}^{{{:.2f}}}}}$'.format(sign_string, base, fx) def __call__(self, x, pos=None): # docstring inherited @@ -1118,7 +1118,7 @@ def __call__(self, x, pos=None): base = '%s' % b if abs(fx) < mpl.rcParams['axes.formatter.min_exponent']: - return r'$\mathdefault{%s%g}$' % (sign_string, x) + return r'$\mathdefault{{{}{:g}}}$'.format(sign_string, x) elif not is_x_decade: usetex = mpl.rcParams['text.usetex'] return self._non_decade_format(sign_string, base, fx, usetex) diff --git a/lib/matplotlib/typing.py b/lib/matplotlib/typing.py index e29b08b437d6..d2b462b4dac4 100644 --- a/lib/matplotlib/typing.py +++ b/lib/matplotlib/typing.py @@ -9,9 +9,9 @@ The ``typing`` module and type stub files are considered provisional and may change at any time without a deprecation period. """ -from collections.abc import Hashable, Sequence +from collections.abc import Callable, Hashable, Sequence import pathlib -from typing import Any, Callable, Literal, TypeAlias, TypeVar, Union +from typing import Any, Literal, TypeAlias, TypeVar, Union from . import path from ._enums import JoinStyle, CapStyle diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 55b204022fb9..c3fd6e53c436 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -4140,7 +4140,7 @@ def __eq__(self, other): return (self.scalar == other.scalar) and (self.vector == other.vector).all def __repr__(self): - return "_Quaternion({}, {})".format(repr(self.scalar), repr(self.vector)) + return f"_Quaternion({repr(self.scalar)}, {repr(self.vector)})" @classmethod def rotate_from_to(cls, r1, r2):