Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/selective_cache_persist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.9-minver', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
python-version: ['3.10-minver', '3.10', '3.11', '3.12', '3.13', '3.14']
name: Persist cache for ${{ matrix.python-version }}
steps:
- name: Create cache directory
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ jobs:
matrix:
include:
- name-suffix: "(Minimum Versions)"
python-version: "3.9"
python-version: "3.10"
cache-suffix: "-minver"
extra-requirements: "-c requirements/minver.txt"
- python-version: "3.9"
- python-version: "3.10"
- python-version: "3.11"
- python-version: "3.12"
Expand Down
8 changes: 2 additions & 6 deletions fastf1/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
import datetime
import json
import zlib
from typing import (
Optional,
Union
)

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -105,7 +101,7 @@ def make_path(wname, wdate, sname, sdate):


def timing_data(path: str,
response: Optional[str] = None,
response: str | None = None,
livedata=None
) -> (pd.DataFrame, pd.DataFrame):
"""
Expand Down Expand Up @@ -1784,7 +1780,7 @@ def fetch_page(path, name):
return None


def parse(text: str, zipped: bool = False) -> Union[str, dict]:
def parse(text: str, zipped: bool = False) -> str | dict:
"""
.. warning::
:mod:`fastf1.api` will be considered private in future releases and
Expand Down
60 changes: 31 additions & 29 deletions fastf1/core.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import collections
import re
import warnings
from collections.abc import Iterable
from collections.abc import (
Callable,
Iterable
)
from functools import cached_property
from typing import (
Any,
Callable,
Literal,
Optional,
Union
Expand Down Expand Up @@ -181,7 +183,7 @@ def __init__(self,
drop_unknown_channels: bool = False,
**kwargs):
super().__init__(*args, **kwargs)
self.session: Optional[Session] = session
self.session: Session | None = session
self.driver = driver

if drop_unknown_channels:
Expand Down Expand Up @@ -234,7 +236,7 @@ def merge(self, *args, **kwargs):

def slice_by_mask(
self,
mask: Union[list, pd.Series, np.ndarray],
mask: list | pd.Series | np.ndarray,
pad: int = 0,
pad_side: str = 'both'
) -> "Telemetry":
Expand Down Expand Up @@ -297,7 +299,7 @@ def slice_by_lap(
end_time = ref_laps['Time'].max()
start_time = ref_laps['LapStartTime'].min()

elif isinstance(ref_laps, (Lap, Laps)):
elif isinstance(ref_laps, Lap | Laps):
if isinstance(ref_laps, Laps): # one lap in Laps
ref_laps = ref_laps.iloc[0] # handle as a single lap
if 'DriverNumber' not in ref_laps.index:
Expand Down Expand Up @@ -365,7 +367,7 @@ def slice_by_time(
def merge_channels(
self,
other: Union["Telemetry", pd.DataFrame],
frequency: Union[int, Literal['original'], None] = None
frequency: int | Literal['original'] | None = None
):
"""Merge telemetry objects containing different telemetry channels.

Expand Down Expand Up @@ -544,9 +546,9 @@ def merge_channels(

def resample_channels(
self,
rule: Optional[str] = None,
new_date_ref: Optional[pd.Series] = None,
**kwargs: Optional[Any]
rule: str | None = None,
new_date_ref: pd.Series | None = None,
**kwargs: Any | None
):
"""Resample telemetry data.

Expand Down Expand Up @@ -671,7 +673,7 @@ def register_new_channel(
cls,
name: str,
signal_type: str,
interpolation_method: Optional[str] = None
interpolation_method: str | None = None
):
"""Register a custom telemetry channel.

Expand Down Expand Up @@ -1186,19 +1188,19 @@ def __init__(self, event, session_name, f1_api_support=False):

self._track_status: pd.DataFrame

self._total_laps: Optional[int]
self._total_laps: int | None
self._laps: Laps

self._t0_date: Optional[pd.Timestamp]
self._session_start_time: Optional[pd.Timedelta]
self._t0_date: pd.Timestamp | None
self._session_start_time: pd.Timedelta | None

self._car_data: dict
self._pos_data: dict

self._weather_data: pd.DataFrame
self._results: SessionResults

self._session_split_times: Optional[list] = None
self._session_split_times: list | None = None

def __repr__(self):
return (f"{self.event.year} Season Round {self.event.RoundNumber}: "
Expand Down Expand Up @@ -2405,7 +2407,7 @@ def _drivers_from_f1_api(self, *, livedata=None):

def _drivers_results_from_ergast(
self, *, load_drivers=False, load_results=False
) -> Optional[pd.DataFrame]:
) -> pd.DataFrame | None:
if self.name in self._RACE_LIKE_SESSIONS + self._QUALI_LIKE_SESSIONS:
session_name = self.name
else:
Expand Down Expand Up @@ -2620,7 +2622,7 @@ def get_driver(self, identifier) -> "DriverResult":
raise ValueError(f"Invalid driver identifier '{identifier}'")
return self.results[mask].iloc[0]

def get_circuit_info(self) -> Optional[CircuitInfo]:
def get_circuit_info(self) -> CircuitInfo | None:
"""Returns additional information about the circuit that hosts this
event.

Expand Down Expand Up @@ -2740,7 +2742,7 @@ class Laps(BaseDataFrame):
'LapStartDate': 'datetime64[ns]',
'TrackStatus': str,
'Position': 'float64', # need to support NaN
'Deleted': Optional[bool],
'Deleted': bool | None,
'DeletedReason': str,
'FastF1Generated': bool,
'IsAccurate': bool
Expand All @@ -2755,7 +2757,7 @@ class Laps(BaseDataFrame):

def __init__(self,
*args,
session: Optional[Session] = None,
session: Session | None = None,
**kwargs):

super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -2815,7 +2817,7 @@ def merge(self, *args, **kwargs):

def get_telemetry(self,
*,
frequency: Union[int, Literal['original'], None] = None
frequency: int | Literal['original'] | None = None
) -> Telemetry:
"""Telemetry data for all laps in `self`

Expand Down Expand Up @@ -3037,7 +3039,7 @@ def pick_lap(self, lap_number: int) -> "Laps":
FutureWarning)
return self[self['LapNumber'] == lap_number]

def pick_laps(self, lap_numbers: Union[int, Iterable[int]]) -> "Laps":
def pick_laps(self, lap_numbers: int | Iterable[int]) -> "Laps":
"""Return all laps of a specific LapNumber or a list of LapNumbers
in self. ::

Expand All @@ -3051,7 +3053,7 @@ def pick_laps(self, lap_numbers: Union[int, Iterable[int]]) -> "Laps":
Returns:
instance of :class:`Laps`
"""
if isinstance(lap_numbers, (int, float)):
if isinstance(lap_numbers, int | float):
lap_numbers = [lap_numbers, ]

for i in lap_numbers:
Expand All @@ -3060,7 +3062,7 @@ def pick_laps(self, lap_numbers: Union[int, Iterable[int]]) -> "Laps":

return self[self["LapNumber"].isin(lap_numbers)]

def pick_driver(self, identifier: Union[int, str]) -> "Laps":
def pick_driver(self, identifier: int | str) -> "Laps":
"""Return all laps of a specific driver in self based on the driver's
three letters identifier or based on the driver number.

Expand Down Expand Up @@ -3088,7 +3090,7 @@ def pick_driver(self, identifier: Union[int, str]) -> "Laps":
return self[self['Driver'] == identifier]

def pick_drivers(self,
identifiers: Union[int, str, Iterable[Union[int, str]]]
identifiers: int | str | Iterable[int | str]
) -> "Laps":
"""Return all laps of the specified driver or drivers in self based
on the drivers' three letters identifier or the driver number. ::
Expand All @@ -3103,7 +3105,7 @@ def pick_drivers(self,
Returns:
instance of :class:`Laps`
"""
if isinstance(identifiers, (int, str)):
if isinstance(identifiers, int | str):
identifiers = [identifiers, ]

names = [n.upper() for n in identifiers if not str(n).isdigit()]
Expand Down Expand Up @@ -3134,7 +3136,7 @@ def pick_team(self, name: str) -> "Laps":
FutureWarning)
return self[self['Team'] == name]

def pick_teams(self, names: Union[str, Iterable[str]]) -> "Laps":
def pick_teams(self, names: str | Iterable[str]) -> "Laps":
"""Return all laps of the specified team or teams in self based
on the team names. ::

Expand Down Expand Up @@ -3192,7 +3194,7 @@ def pick_fastest(self, only_by_time: bool = False) -> Optional["Lap"]:

return lap

def pick_quicklaps(self, threshold: Optional[float] = None) -> "Laps":
def pick_quicklaps(self, threshold: float | None = None) -> "Laps":
"""Return all laps with `LapTime` faster than a certain limit. By
default, the threshold is 107% of the best `LapTime` of all laps
in self.
Expand Down Expand Up @@ -3229,7 +3231,7 @@ def pick_tyre(self, compound: str) -> "Laps":
FutureWarning)
return self[self['Compound'] == compound.upper()]

def pick_compounds(self, compounds: Union[str, Iterable[str]]) -> "Laps":
def pick_compounds(self, compounds: str | Iterable[str]) -> "Laps":
"""Return all laps in self which were done on some specific compounds.
::

Expand Down Expand Up @@ -3416,7 +3418,7 @@ def split_qualifying_sessions(self) -> list[Optional["Laps"]]:
laps[i] = None
return laps

def iterlaps(self, require: Optional[Iterable] = None) \
def iterlaps(self, require: Iterable | None = None) \
-> Iterable[tuple[int, "Lap"]]:
"""Iterator for iterating over all laps in self.

Expand Down Expand Up @@ -3481,7 +3483,7 @@ def telemetry(self) -> Telemetry:

def get_telemetry(self,
*,
frequency: Union[int, Literal['original'], None] = None
frequency: int | Literal['original'] | None = None
) -> Telemetry:
"""Telemetry data for this lap

Expand Down
Loading
Loading