diff --git a/.github/workflows/selective_cache_persist.yml b/.github/workflows/selective_cache_persist.yml index b44e232bd..59e4e690b 100644 --- a/.github/workflows/selective_cache_persist.yml +++ b/.github/workflows/selective_cache_persist.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '3.8-minver', '3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: [ '3.9-minver', '3.9', '3.10', '3.11', '3.12'] # name: Persist cache for ${{ matrix.python-version }} steps: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 10dbe0105..883cbd0dc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,10 +16,9 @@ jobs: matrix: include: - name-suffix: "(Minimum Versions)" - python-version: "3.8" + python-version: "3.9" cache-suffix: "-minver" extra-requirements: "-c requirements/minver.txt" - - python-version: "3.8" - python-version: "3.9" - python-version: "3.10" - python-version: "3.11" diff --git a/fastf1/_api.py b/fastf1/_api.py index e5e3aa5ba..1f7266462 100644 --- a/fastf1/_api.py +++ b/fastf1/_api.py @@ -4,7 +4,6 @@ import json import zlib from typing import ( - Dict, Optional, Union ) @@ -29,7 +28,7 @@ base_url = 'https://livetiming.formula1.com' -headers: Dict[str, str] = { +headers: dict[str, str] = { 'Host': 'livetiming.formula1.com', 'Connection': 'close', 'TE': 'identity', @@ -37,7 +36,7 @@ 'Accept-Encoding': 'gzip, identity', } -pages: Dict[str, str] = { +pages: dict[str, str] = { 'session_data': 'SessionData.json', # track + session status + lap count 'session_info': 'SessionInfo.jsonStream', # more rnd 'archive_status': 'ArchiveStatus.json', # rnd=1880327548 @@ -83,7 +82,7 @@ def make_path(wname, wdate, sname, sdate): # define all empty columns for timing data -EMPTY_LAPS = {'Time': pd.NaT, 'Driver': str(), 'LapTime': pd.NaT, +EMPTY_LAPS = {'Time': pd.NaT, 'Driver': '', 'LapTime': pd.NaT, 'NumberOfLaps': np.nan, 'NumberOfPitStops': np.nan, 'PitOutTime': pd.NaT, 'PitInTime': pd.NaT, 'Sector1Time': pd.NaT, 'Sector2Time': pd.NaT, @@ -92,7 +91,7 @@ def make_path(wname, wdate, sname, sdate): 'SpeedI1': np.nan, 'SpeedI2': np.nan, 'SpeedFL': np.nan, 'SpeedST': np.nan, 'IsPersonalBest': False} -EMPTY_STREAM = {'Time': pd.NaT, 'Driver': str(), 'Position': np.nan, +EMPTY_STREAM = {'Time': pd.NaT, 'Driver': '', 'Position': np.nan, 'GapToLeader': np.nan, 'IntervalToPositionAhead': np.nan} diff --git a/fastf1/core.py b/fastf1/core.py index e25ad54fc..eacd28dab 100644 --- a/fastf1/core.py +++ b/fastf1/core.py @@ -43,15 +43,13 @@ import re import typing import warnings +from collections.abc import Iterable from functools import cached_property from typing import ( Any, Callable, - Iterable, - List, Literal, Optional, - Tuple, Union ) @@ -925,8 +923,8 @@ def add_driver_ahead(self, drop_existing: bool = True) -> "Telemetry": ) if ((d['Date'].shape != dtd['Date'].shape) - or np.any((d['Date'].values - != dtd['Date'].values))): + or np.any(d['Date'].values + != dtd['Date'].values)): dtd = dtd.resample_channels(new_date_ref=d["Date"]) # indices need to match as .join works index-on-index @@ -1510,7 +1508,7 @@ def _load_laps_data(self, livedata=None): elif not len(d2): result = d1.copy() result.reset_index(drop=True, inplace=True) - result['Compound'] = str() + result['Compound'] = '' result['TyreLife'] = np.nan result['Stint'] = 0 result['New'] = False @@ -3295,7 +3293,7 @@ def pick_accurate(self) -> "Laps": """ return self[self['IsAccurate']] - def split_qualifying_sessions(self) -> List[Optional["Laps"]]: + def split_qualifying_sessions(self) -> list[Optional["Laps"]]: """Splits a lap object into individual laps objects for each qualifying session. @@ -3354,7 +3352,7 @@ def split_qualifying_sessions(self) -> List[Optional["Laps"]]: return laps def iterlaps(self, require: Optional[Iterable] = None) \ - -> Iterable[Tuple[int, "Lap"]]: + -> Iterable[tuple[int, "Lap"]]: """Iterator for iterating over all laps in self. This method wraps :meth:`pandas.DataFrame.iterrows`. @@ -3762,9 +3760,8 @@ class NoLapDataError(Exception): after processing the result. """ def __init__(self, *args): - super(NoLapDataError, self).__init__("Failed to load session because " - "the API did not provide any " - "usable data.") + super().__init__("Failed to load session because the API did not " + "provide any usable data.") class InvalidSessionError(Exception): @@ -3772,6 +3769,4 @@ class InvalidSessionError(Exception): can be found.""" def __init__(self, *args): - super(InvalidSessionError, self).__init__( - "No matching session can be found." - ) + super().__init__("No matching session can be found.") diff --git a/fastf1/ergast/interface.py b/fastf1/ergast/interface.py index ff3f00cbc..a157a8f43 100644 --- a/fastf1/ergast/interface.py +++ b/fastf1/ergast/interface.py @@ -1,10 +1,8 @@ import copy import json from typing import ( - List, Literal, Optional, - Type, Union ) @@ -252,7 +250,7 @@ class ErgastSimpleResponse(ErgastResponseMixin, ErgastResultFrame): _internal_names_set = set(_internal_names) @property - def _constructor(self) -> Type["ErgastResultFrame"]: + def _constructor(self) -> type["ErgastResultFrame"]: # drop from ErgastSimpleResponse to ErgastResultFrame, removing the # ErgastResponseMixin because a slice of the data is no longer a full # response and pagination, ... is therefore not supported anymore @@ -363,7 +361,7 @@ def description(self) -> ErgastResultFrame: return self._description @property - def content(self) -> List[ErgastResultFrame]: + def content(self) -> list[ErgastResultFrame]: """A ``list`` of :class:`ErgastResultFrame` that contain the main response data. diff --git a/fastf1/events.py b/fastf1/events.py index a935141c8..0af2aab00 100644 --- a/fastf1/events.py +++ b/fastf1/events.py @@ -194,7 +194,6 @@ from typing import ( Literal, Optional, - Type, Union ) @@ -624,7 +623,7 @@ def _get_schedule_ff1(year): data[f'session{j+1}_date'][i] = pd.Timestamp(date) data[f'session{j+1}_date_Utc'][i] = pd.Timestamp(date_utc) - str().capitalize() + ''.capitalize() df = pd.DataFrame(data) # change column names from snake_case to UpperCamelCase @@ -885,7 +884,7 @@ def __init__(self, *args, year: int = 0, self[col] = self[col].astype(_type) @property - def _constructor_sliced_horizontal(self) -> Type["Event"]: + def _constructor_sliced_horizontal(self) -> type["Event"]: return Event def is_testing(self): diff --git a/fastf1/internals/fuzzy.py b/fastf1/internals/fuzzy.py index 4a5406464..24fd77a72 100644 --- a/fastf1/internals/fuzzy.py +++ b/fastf1/internals/fuzzy.py @@ -1,5 +1,4 @@ import warnings -from typing import List import numpy as np @@ -15,7 +14,7 @@ def fuzzy_matcher( query: str, - reference: List[List[str]], + reference: list[list[str]], abs_confidence: float = 0.0, rel_confidence: float = 0.0 ) -> (int, bool): diff --git a/fastf1/internals/pandas_extensions.py b/fastf1/internals/pandas_extensions.py index 9a5823c81..3188a5f03 100644 --- a/fastf1/internals/pandas_extensions.py +++ b/fastf1/internals/pandas_extensions.py @@ -1,5 +1,3 @@ -from typing import List - import numpy as np from pandas import ( DataFrame, @@ -35,7 +33,7 @@ def create_df_fast( *, - arrays: List[np.ndarray], + arrays: list[np.ndarray], columns: list, fallback: bool = True ) -> DataFrame: @@ -71,7 +69,7 @@ def create_df_fast( def _fallback_create_df( - arrays: List[np.ndarray], + arrays: list[np.ndarray], columns: list ) -> DataFrame: data = {col: arr for col, arr in zip(columns, arrays)} @@ -87,7 +85,7 @@ def _fallback_if_unsupported(func): @_fallback_if_unsupported def _unsafe_create_df_fast( - arrays: List[np.ndarray], + arrays: list[np.ndarray], columns: list ) -> DataFrame: # Implements parts of pandas' internal DataFrame creation mechanics diff --git a/fastf1/livetiming/__main__.py b/fastf1/livetiming/__main__.py index db2741c2d..bfd5e15a5 100644 --- a/fastf1/livetiming/__main__.py +++ b/fastf1/livetiming/__main__.py @@ -15,7 +15,7 @@ def save(args): def convert(args): - with open(args.input, 'r') as infile: + with open(args.input) as infile: messages = infile.readlines() data, ec = messages_from_raw(messages) with open(args.output, 'w') as outfile: diff --git a/fastf1/livetiming/client.py b/fastf1/livetiming/client.py index 4a845f682..6e006f9cd 100644 --- a/fastf1/livetiming/client.py +++ b/fastf1/livetiming/client.py @@ -3,10 +3,8 @@ import json import logging import time -from typing import ( - Iterable, - Optional -) +from collections.abc import Iterable +from typing import Optional import requests diff --git a/fastf1/livetiming/data.py b/fastf1/livetiming/data.py index 220b3e48e..f287674b1 100644 --- a/fastf1/livetiming/data.py +++ b/fastf1/livetiming/data.py @@ -95,7 +95,7 @@ def load(self): next_data = None else: # read a new file as next file - with open(next_file, 'r') as fobj: + with open(next_file) as fobj: next_data = fobj.readlines() if current_data is None: diff --git a/fastf1/plotting/__init__.py b/fastf1/plotting/__init__.py index 691d8ce99..1e6b6c568 100644 --- a/fastf1/plotting/__init__.py +++ b/fastf1/plotting/__init__.py @@ -1,8 +1,4 @@ import warnings -from typing import ( - Dict, - List -) from fastf1.plotting._constants import \ LEGACY_DRIVER_COLORS as _LEGACY_DRIVER_COLORS @@ -91,11 +87,11 @@ def __getattr__(name): raise AttributeError(f"module {__name__!r} has no attribute {name!r}") -_DEPR_COMPOUND_COLORS: Dict[str, str] = { +_DEPR_COMPOUND_COLORS: dict[str, str] = { key: val for key, val in _Constants['2024'].CompoundColors.items() } -COMPOUND_COLORS: Dict[str, str] +COMPOUND_COLORS: dict[str, str] """ Mapping of tyre compound names to compound colors (hex color codes). (current season only) @@ -107,8 +103,8 @@ def __getattr__(name): """ -_DEPR_DRIVER_COLORS: Dict[str, str] = _LEGACY_DRIVER_COLORS.copy() -DRIVER_COLORS: Dict[str, str] +_DEPR_DRIVER_COLORS: dict[str, str] = _LEGACY_DRIVER_COLORS.copy() +DRIVER_COLORS: dict[str, str] """ Mapping of driver names to driver colors (hex color codes). @@ -123,8 +119,8 @@ def __getattr__(name): """ -_DEPR_DRIVER_TRANSLATE: Dict[str, str] = _LEGACY_DRIVER_TRANSLATE.copy() -DRIVER_TRANSLATE: Dict[str, str] +_DEPR_DRIVER_TRANSLATE: dict[str, str] = _LEGACY_DRIVER_TRANSLATE.copy() +DRIVER_TRANSLATE: dict[str, str] """ Mapping of driver names to theirs respective abbreviations. @@ -138,13 +134,13 @@ def __getattr__(name): future version. Use :func:`~fastf1.plotting.get_driver_name` instead. """ -_DEPR_TEAM_COLORS: Dict[str, str] = { +_DEPR_TEAM_COLORS: dict[str, str] = { # str(key.value): val for key, val # in _Constants['2024'].Colormaps[_Colormaps.Default].items() name.replace("kick ", ""): team.TeamColor.FastF1 for name, team in _Constants['2024'].Teams.items() } -TEAM_COLORS: Dict[str, str] +TEAM_COLORS: dict[str, str] """ Mapping of team names to team colors (hex color codes). (current season only) @@ -154,8 +150,8 @@ def __getattr__(name): future version. Use :func:`~fastf1.plotting.get_team_color` instead. """ -_DEPR_TEAM_TRANSLATE: Dict[str, str] = _LEGACY_TEAM_TRANSLATE.copy() -TEAM_TRANSLATE: Dict[str, str] +_DEPR_TEAM_TRANSLATE: dict[str, str] = _LEGACY_TEAM_TRANSLATE.copy() +TEAM_TRANSLATE: dict[str, str] """ Mapping of team names to theirs respective abbreviations. @@ -164,8 +160,8 @@ def __getattr__(name): future version. Use :func:`~fastf1.plotting.get_team_name` instead. """ -_DEPR_COLOR_PALETTE: List[str] = _COLOR_PALETTE.copy() -COLOR_PALETTE: List[str] +_DEPR_COLOR_PALETTE: list[str] = _COLOR_PALETTE.copy() +COLOR_PALETTE: list[str] """ The default color palette for matplotlib plot lines in fastf1's color scheme. diff --git a/fastf1/plotting/_backend.py b/fastf1/plotting/_backend.py index 02c3ac2ea..ab23e635e 100644 --- a/fastf1/plotting/_backend.py +++ b/fastf1/plotting/_backend.py @@ -1,8 +1,4 @@ import dataclasses -from typing import ( - Dict, - List -) import fastf1._api from fastf1.plotting._base import ( @@ -16,12 +12,12 @@ def _load_drivers_from_f1_livetiming( *, api_path: str, year: str -) -> List[_Team]: +) -> list[_Team]: # load the driver information for the determined session driver_info = fastf1._api.driver_info(api_path) # parse the data into the required format - teams: Dict[str, _Team] = dict() + teams: dict[str, _Team] = dict() # Sorting by driver number here will directly guarantee that drivers # are sorted by driver number within each team. This has two advantages: diff --git a/fastf1/plotting/_base.py b/fastf1/plotting/_base.py index e1a4cdfc2..0f7a71703 100644 --- a/fastf1/plotting/_base.py +++ b/fastf1/plotting/_base.py @@ -1,8 +1,4 @@ import unicodedata -from typing import ( - Dict, - List -) from fastf1.logger import get_logger from fastf1.plotting._constants.base import TeamConst @@ -25,21 +21,21 @@ class _Team: def __init__(self): super().__init__() - self.drivers: List["_Driver"] = list() + self.drivers: list[_Driver] = list() class _DriverTeamMapping: def __init__( self, year: str, - teams: List[_Team], + teams: list[_Team], ): self.year = year self.teams = teams - self.drivers_by_normalized: Dict[str, _Driver] = dict() - self.drivers_by_abbreviation: Dict[str, _Driver] = dict() - self.teams_by_normalized: Dict[str, _Team] = dict() + self.drivers_by_normalized: dict[str, _Driver] = dict() + self.drivers_by_abbreviation: dict[str, _Driver] = dict() + self.teams_by_normalized: dict[str, _Team] = dict() for team in teams: for driver in team.drivers: diff --git a/fastf1/plotting/_constants/__init__.py b/fastf1/plotting/_constants/__init__.py index 34fe5fbc4..f79bf1aa2 100644 --- a/fastf1/plotting/_constants/__init__.py +++ b/fastf1/plotting/_constants/__init__.py @@ -1,5 +1,3 @@ -from typing import Dict - from fastf1.plotting._constants import ( # noqa: F401, unused import used through globals() season2018, season2019, @@ -12,7 +10,7 @@ from fastf1.plotting._constants.base import BaseSeasonConst -Constants: Dict[str, BaseSeasonConst] = dict() +Constants: dict[str, BaseSeasonConst] = dict() for year in range(2018, 2025): season = globals()[f"season{year}"] @@ -32,7 +30,7 @@ } -LEGACY_TEAM_TRANSLATE: Dict[str, str] = { +LEGACY_TEAM_TRANSLATE: dict[str, str] = { 'MER': 'mercedes', 'FER': 'ferrari', 'RBR': 'red bull', @@ -46,7 +44,7 @@ } -LEGACY_DRIVER_COLORS: Dict[str, str] = { +LEGACY_DRIVER_COLORS: dict[str, str] = { "valtteri bottas": "#00e701", "zhou guanyu": "#008d01", "theo pourchaire": "#004601", @@ -93,7 +91,7 @@ } -LEGACY_DRIVER_TRANSLATE: Dict[str, str] = { +LEGACY_DRIVER_TRANSLATE: dict[str, str] = { 'LEC': 'charles leclerc', 'SAI': 'carlos sainz', 'SHW': 'robert shwartzman', 'VER': 'max verstappen', 'PER': 'sergio perez', diff --git a/fastf1/plotting/_constants/base.py b/fastf1/plotting/_constants/base.py index b492fbaee..fe74202a0 100644 --- a/fastf1/plotting/_constants/base.py +++ b/fastf1/plotting/_constants/base.py @@ -1,5 +1,4 @@ from dataclasses import dataclass -from typing import Dict class CompoundsConst: @@ -30,5 +29,5 @@ class TeamConst: @dataclass(frozen=True) class BaseSeasonConst: - CompoundColors: Dict[str, str] - Teams: Dict[str, TeamConst] + CompoundColors: dict[str, str] + Teams: dict[str, TeamConst] diff --git a/fastf1/plotting/_constants/season2018.py b/fastf1/plotting/_constants/season2018.py index c8bb81280..782ec33ba 100644 --- a/fastf1/plotting/_constants/season2018.py +++ b/fastf1/plotting/_constants/season2018.py @@ -1,4 +1,3 @@ -from typing import Dict from fastf1.plotting._constants.base import ( CompoundsConst, @@ -11,7 +10,7 @@ # and values may be modified there, it the used API provides different values -Teams: Dict[str, TeamConst] = { +Teams: dict[str, TeamConst] = { 'ferrari': TeamConst( ShortName='Ferrari', TeamColor=TeamColorsConst( @@ -91,7 +90,7 @@ ) } -CompoundColors: Dict[CompoundsConst, str] = { +CompoundColors: dict[CompoundsConst, str] = { CompoundsConst.HyperSoft: "#feb1c1", CompoundsConst.UltraSoft: "#b24ba7", CompoundsConst.SuperSoft: "#fc2b2a", diff --git a/fastf1/plotting/_constants/season2019.py b/fastf1/plotting/_constants/season2019.py index 7c786d602..4b7038cc4 100644 --- a/fastf1/plotting/_constants/season2019.py +++ b/fastf1/plotting/_constants/season2019.py @@ -1,4 +1,3 @@ -from typing import Dict from fastf1.plotting._constants.base import ( CompoundsConst, @@ -11,7 +10,7 @@ # and values may be modified there, it the used API provides different values -Teams: Dict[str, TeamConst] = { +Teams: dict[str, TeamConst] = { 'alfa romeo': TeamConst( ShortName='Alfa Romeo', TeamColor=TeamColorsConst( @@ -84,7 +83,7 @@ ) } -CompoundColors: Dict[CompoundsConst, str] = { +CompoundColors: dict[CompoundsConst, str] = { CompoundsConst.Soft: "#da291c", CompoundsConst.Medium: "#ffd12e", CompoundsConst.Hard: "#f0f0ec", diff --git a/fastf1/plotting/_constants/season2020.py b/fastf1/plotting/_constants/season2020.py index c4f13ddfe..5c87b33f4 100644 --- a/fastf1/plotting/_constants/season2020.py +++ b/fastf1/plotting/_constants/season2020.py @@ -1,4 +1,3 @@ -from typing import Dict from fastf1.plotting._constants.base import ( CompoundsConst, @@ -11,7 +10,7 @@ # and values may be modified there, it the used API provides different values -Teams: Dict[str, TeamConst] = { +Teams: dict[str, TeamConst] = { 'alfa romeo': TeamConst( ShortName='Alfa Romeo', TeamColor=TeamColorsConst( @@ -84,7 +83,7 @@ ) } -CompoundColors: Dict[CompoundsConst, str] = { +CompoundColors: dict[CompoundsConst, str] = { CompoundsConst.Soft: "#da291c", CompoundsConst.Medium: "#ffd12e", CompoundsConst.Hard: "#f0f0ec", diff --git a/fastf1/plotting/_constants/season2021.py b/fastf1/plotting/_constants/season2021.py index 3a03b274e..9273a39ae 100644 --- a/fastf1/plotting/_constants/season2021.py +++ b/fastf1/plotting/_constants/season2021.py @@ -1,4 +1,3 @@ -from typing import Dict from fastf1.plotting._constants.base import ( CompoundsConst, @@ -11,7 +10,7 @@ # and values may be modified there, it the used API provides different values -Teams: Dict[str, TeamConst] = { +Teams: dict[str, TeamConst] = { 'alfa romeo': TeamConst( ShortName='Alfa Romeo', TeamColor=TeamColorsConst( @@ -84,7 +83,7 @@ ) } -CompoundColors: Dict[CompoundsConst, str] = { +CompoundColors: dict[CompoundsConst, str] = { CompoundsConst.Soft: "#da291c", CompoundsConst.Medium: "#ffd12e", CompoundsConst.Hard: "#f0f0ec", diff --git a/fastf1/plotting/_constants/season2022.py b/fastf1/plotting/_constants/season2022.py index 4f09b282c..6983a01df 100644 --- a/fastf1/plotting/_constants/season2022.py +++ b/fastf1/plotting/_constants/season2022.py @@ -1,4 +1,3 @@ -from typing import Dict from fastf1.plotting._constants.base import ( CompoundsConst, @@ -11,7 +10,7 @@ # and values may be modified there, it the used API provides different values -Teams: Dict[str, TeamConst] = { +Teams: dict[str, TeamConst] = { 'alfa romeo': TeamConst( ShortName='Alfa Romeo', TeamColor=TeamColorsConst( @@ -84,7 +83,7 @@ ) } -CompoundColors: Dict[CompoundsConst, str] = { +CompoundColors: dict[CompoundsConst, str] = { CompoundsConst.Soft: "#da291c", CompoundsConst.Medium: "#ffd12e", CompoundsConst.Hard: "#f0f0ec", diff --git a/fastf1/plotting/_constants/season2023.py b/fastf1/plotting/_constants/season2023.py index be88f828e..e58cdfbc0 100644 --- a/fastf1/plotting/_constants/season2023.py +++ b/fastf1/plotting/_constants/season2023.py @@ -1,4 +1,3 @@ -from typing import Dict from fastf1.plotting._constants.base import ( CompoundsConst, @@ -11,7 +10,7 @@ # and values may be modified there, it the used API provides different values -Teams: Dict[str, TeamConst] = { +Teams: dict[str, TeamConst] = { 'alfa romeo': TeamConst( ShortName='Alfa Romeo', TeamColor=TeamColorsConst( @@ -84,7 +83,7 @@ ) } -CompoundColors: Dict[CompoundsConst, str] = { +CompoundColors: dict[CompoundsConst, str] = { CompoundsConst.Soft: "#da291c", CompoundsConst.Medium: "#ffd12e", CompoundsConst.Hard: "#f0f0ec", diff --git a/fastf1/plotting/_constants/season2024.py b/fastf1/plotting/_constants/season2024.py index b067d74b1..4d1b23ed2 100644 --- a/fastf1/plotting/_constants/season2024.py +++ b/fastf1/plotting/_constants/season2024.py @@ -1,4 +1,3 @@ -from typing import Dict from fastf1.plotting._constants.base import ( CompoundsConst, @@ -11,7 +10,7 @@ # and values may be modified there, if the used API provides different values -Teams: Dict[str, TeamConst] = { +Teams: dict[str, TeamConst] = { 'alpine': TeamConst( ShortName='Alpine', TeamColor=TeamColorsConst( @@ -84,7 +83,7 @@ ) } -CompoundColors: Dict[CompoundsConst, str] = { +CompoundColors: dict[CompoundsConst, str] = { CompoundsConst.Soft: "#da291c", CompoundsConst.Medium: "#ffd12e", CompoundsConst.Hard: "#f0f0ec", diff --git a/fastf1/plotting/_interface.py b/fastf1/plotting/_interface.py index d0d085836..ae6ae6236 100644 --- a/fastf1/plotting/_interface.py +++ b/fastf1/plotting/_interface.py @@ -1,11 +1,9 @@ import dataclasses +from collections.abc import Sequence from typing import ( Any, - Dict, - List, Literal, Optional, - Sequence, Union ) @@ -334,7 +332,7 @@ def get_driver_abbreviation( def get_driver_names_by_team( identifier: str, session: Session, *, exact_match: bool = False -) -> List[str]: +) -> list[str]: """ Get a list of full names of all drivers that drove for a team in a given session based on a recognizable and identifiable part of the team name. @@ -351,7 +349,7 @@ def get_driver_names_by_team( def get_driver_abbreviations_by_team( identifier: str, session: Session, *, exact_match: bool = False -) -> List[str]: +) -> list[str]: """ Get a list of abbreviations of all drivers that drove for a team in a given session based on a recognizable and identifiable part of the team name. @@ -411,7 +409,7 @@ def get_driver_style( colormap: str = 'default', additional_color_kws: Union[list, tuple] = (), exact_match: bool = False -) -> Dict[str, Any]: +) -> dict[str, Any]: """ Get a plotting style that is unique for a driver based on the driver's abbreviation or based on a recognizable and identifiable part of the @@ -626,7 +624,7 @@ def get_compound_color(compound: str, session: Session) -> str: return _Constants[year].CompoundColors[compound.upper()] -def get_compound_mapping(session: Session) -> Dict[str, str]: +def get_compound_mapping(session: Session) -> dict[str, str]: """ Returns a dictionary that maps compound names to their associated colors. The colors are given as hexadecimal RGB color codes. @@ -643,7 +641,7 @@ def get_compound_mapping(session: Session) -> Dict[str, str]: def get_driver_color_mapping( session: Session, *, colormap: str = 'default', -) -> Dict[str, str]: +) -> dict[str, str]: """ Returns a dictionary that maps driver abbreviations to their associated colors. The colors are given as hexadecimal RGB color codes. @@ -677,7 +675,7 @@ def get_driver_color_mapping( return colors -def list_team_names(session: Session, *, short: bool = False) -> List[str]: +def list_team_names(session: Session, *, short: bool = False) -> list[str]: """Returns a list of team names of all teams in the ``session``. By default, the full team names are returned. Use the ``short`` argument @@ -699,19 +697,19 @@ def list_team_names(session: Session, *, short: bool = False) -> List[str]: return list(team.value for team in dtm.teams_by_normalized.values()) -def list_driver_abbreviations(session: Session) -> List[str]: +def list_driver_abbreviations(session: Session) -> list[str]: """Returns a list of abbreviations of all drivers in the ``session``.""" dtm = _get_driver_team_mapping(session) return list(dtm.drivers_by_abbreviation.keys()) -def list_driver_names(session: Session) -> List[str]: +def list_driver_names(session: Session) -> list[str]: """Returns a list of full names of all drivers in the ``session``.""" dtm = _get_driver_team_mapping(session) return list(driver.value for driver in dtm.drivers_by_normalized.values()) -def list_compounds(session: Session) -> List[str]: +def list_compounds(session: Session) -> list[str]: """Returns a list of all compound names for this season (not session).""" year = str(session.event['EventDate'].year) return list(_Constants[year].CompoundColors.keys()) diff --git a/fastf1/plotting/_plotting.py b/fastf1/plotting/_plotting.py index a75d4560a..2256a15b5 100644 --- a/fastf1/plotting/_plotting.py +++ b/fastf1/plotting/_plotting.py @@ -1,8 +1,5 @@ import warnings -from typing import ( - List, - Optional -) +from typing import Optional import numpy as np import pandas as pd @@ -37,7 +34,7 @@ _logger = get_logger(__package__) -_COLOR_PALETTE: List[str] = ['#FF79C6', '#50FA7B', '#8BE9FD', '#BD93F9', +_COLOR_PALETTE: list[str] = ['#FF79C6', '#50FA7B', '#8BE9FD', '#BD93F9', '#FFB86C', '#FF5555', '#F1FA8C'] # The default color palette for matplotlib plot lines in fastf1's color scheme @@ -181,9 +178,9 @@ def driver_color(identifier: str) -> str: key_ratios.sort(reverse=True) if key_ratios[0][0] != 100: _logger.warning( - ("Correcting invalid user input " + "Correcting invalid user input " f"'{identifier}' to '{key_ratios[0][1]}'." - ) + ) if ((key_ratios[0][0] < 35) or (key_ratios[0][0] / key_ratios[1][0] < 1.2)): @@ -268,9 +265,9 @@ def team_color(identifier: str) -> str: key_ratios.sort(reverse=True) if key_ratios[0][0] != 100: _logger.warning( - ("Correcting invalid user input " + "Correcting invalid user input " f"'{identifier}' to '{key_ratios[0][1]}'." - ) + ) if ((key_ratios[0][0] < 35) or (key_ratios[0][0] / key_ratios[1][0] < 1.2)): diff --git a/fastf1/req.py b/fastf1/req.py index d23a01f31..f16e0d6ec 100644 --- a/fastf1/req.py +++ b/fastf1/req.py @@ -29,10 +29,7 @@ import re import sys import time -from typing import ( - Optional, - Tuple -) +from typing import Optional import requests from requests_cache import CacheMixin @@ -524,8 +521,8 @@ def _enable_default_cache(cls): try: os.mkdir(cache_dir, mode=0o0700) except Exception as err: - _logger.error("Failed to create cache directory {0}. " - "Error {1}".format(cache_dir, err)) + _logger.error(f"Failed to create cache directory " + f"{cache_dir}. Error {err}") raise # Enable cache with default @@ -632,7 +629,7 @@ def ci_mode(cls, enabled: bool): cls._ci_mode = enabled @classmethod - def get_cache_info(cls) -> Tuple[Optional[str], Optional[int]]: + def get_cache_info(cls) -> tuple[Optional[str], Optional[int]]: """Returns information about the cache directory and its size. If the cache is not configured, None will be returned for both the @@ -658,7 +655,7 @@ def _convert_size(cls, size_bytes): # https://stackoverflow.com/questions/51940 i = int(math.floor(math.log(size_bytes, 1024))) p = math.pow(1024, i) s = round(size_bytes / p, 2) - return "%s %s" % (s, size_name[i]) + return f"{s} {size_name[i]}" @classmethod def _get_size(cls, start_path='.'): # https://stackoverflow.com/questions/1392413/calculating-a-directorys-size-using-python # noqa: E501 diff --git a/fastf1/utils.py b/fastf1/utils.py index 4e35f0314..b3fb36074 100644 --- a/fastf1/utils.py +++ b/fastf1/utils.py @@ -3,9 +3,7 @@ import warnings from functools import reduce from typing import ( - Dict, Optional, - Tuple, Union ) @@ -22,7 +20,7 @@ def delta_time( reference_lap: "fastf1.core.Lap", compare_lap: "fastf1.core.Lap" -) -> Tuple[pd.Series, "fastf1.core.Telemetry", "fastf1.core.Telemetry"]: +) -> tuple[pd.Series, "fastf1.core.Telemetry", "fastf1.core.Telemetry"]: """Calculates the delta time of a given lap, along the 'Distance' axis of the reference lap. @@ -114,7 +112,7 @@ def mini_pro(stream): return delta, ref, comp -def recursive_dict_get(d: Dict, *keys: str, default_none: bool = False): +def recursive_dict_get(d: dict, *keys: str, default_none: bool = False): """Recursive dict get. Can take an arbitrary number of keys and returns an empty dict if any key does not exist. https://stackoverflow.com/a/28225747""" diff --git a/pyproject.toml b/pyproject.toml index 13b9d4c24..c4e5a75af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,16 +12,16 @@ readme = "README.md" license = { file = "LICENSE" } # minimum python version additionally needs to be changed in the test matrix -requires-python = ">=3.8" +requires-python = ">=3.9" # minimum package versions additionally need to be changed in requirements/minver.txt dependencies = [ "matplotlib>=3.5.1,<4.0.0", - "numpy>=1.21.5,<3.0.0", + "numpy>=1.23.1,<3.0.0", "pandas>=1.4.1,<3.0.0", "python-dateutil", "requests>=2.28.1", "requests-cache>=1.0.0", - "scipy>=1.7.3,<2.0.0", + "scipy>=1.8.1,<2.0.0", "rapidfuzz", "timple>=0.1.6", "websockets>=10.3", @@ -85,6 +85,7 @@ select = [ "E", "F", "W", + "UP", "NPY201" ] diff --git a/requirements/minver.txt b/requirements/minver.txt index 1f0f33cc4..cd2f83f8f 100644 --- a/requirements/minver.txt +++ b/requirements/minver.txt @@ -1,8 +1,8 @@ matplotlib==3.5.1 -numpy==1.21.5 +numpy==1.23.1 pandas==1.4.1 requests==2.28.1 requests-cache==1.0.0 -scipy==1.7.3 +scipy==1.8.1 timple==0.1.6 websockets==10.3 \ No newline at end of file