diff --git a/docs/changelog/v3.1.x.rst b/docs/changelog/v3.1.x.rst index 02382d405..6c4bc5c67 100644 --- a/docs/changelog/v3.1.x.rst +++ b/docs/changelog/v3.1.x.rst @@ -1,3 +1,16 @@ +What's new in v3.1.3 +-------------------- + +(released 07/10/2023) + +Bug Fixes +^^^^^^^^^ + +- fixed a bug in the driver list parser that caused Piastri to be missing from + the results in the 2023 Qatar Sprint Shootout (#460) + + + What's new in v3.1.2 -------------------- diff --git a/fastf1/_api.py b/fastf1/_api.py index ce878a41d..d0c03b40e 100644 --- a/fastf1/_api.py +++ b/fastf1/_api.py @@ -1,4 +1,5 @@ import base64 +import collections import datetime import json import zlib @@ -1487,51 +1488,30 @@ def driver_info(path, response=None, livedata=None): "recently, please try again in a few minutes." ) - # search for the correct entries that contain driver/team/headshot info - # for some sessions headshots are one entry for each team (Miami 22 FPs, Q) - drv_idx = None - team_idx = None - headshots = [] - - for i, entry in enumerate(response): - if 'RacingNumber' in str(entry): - drv_idx = i - if 'TeamName' in str(entry): - team_idx = i - if 'HeadshotUrl' in str(entry): - headshots.append(i) - if drv_idx and team_idx: - break - - # parse data - try: - drv_info = response[drv_idx][1] - except (IndexError, TypeError): - return dict() - - try: - team_info = response[team_idx][1] - except (IndexError, TypeError): - return dict() - - # loop through headshots - try: - head_info = dict() - for head in headshots: - head_info.update(response[head][1]) - except (IndexError, TypeError): - return dict() + drivers = collections.defaultdict(dict) - else: - for drv in drv_info: - drv_info[drv].update(team_info.get(drv, {})) - drv_info[drv].update(head_info.get(drv, {})) - - if not len(drv_info) or not isinstance(drv_info, dict): - return dict() - if 'RacingNumber' not in list(drv_info.values())[0]: - return dict() - return drv_info + default_keys = [ + 'RacingNumber', 'BroadcastName', 'FullName', 'Tla', 'Line', 'TeamName', + 'TeamColour', 'FirstName', 'LastName', 'Reference', 'HeadshotUrl' + ] + + for line in response: + try: + ts, content = line + except ValueError: + # unexpected data format, incorrect number of values to unpack + continue + if not isinstance(content, dict): + continue # unexpected data format + for drv_num, patch in content.items(): + if not isinstance(patch, dict): + continue # unexpected data format + for key, val in patch.items(): + if key not in default_keys: + continue + drivers[drv_num][key] = val + + return drivers @Cache.api_request_wrapper diff --git a/fastf1/req.py b/fastf1/req.py index 70db60547..c87151277 100644 --- a/fastf1/req.py +++ b/fastf1/req.py @@ -198,7 +198,7 @@ class Cache: """ _CACHE_DIR = None # version of the api parser code (unrelated to release version number) - _API_CORE_VERSION = 11 + _API_CORE_VERSION = 12 _IGNORE_VERSION = False _FORCE_RENEW = False diff --git a/fastf1/tests/test_api.py b/fastf1/tests/test_api.py index 9a3f5d7a9..51e560a7f 100644 --- a/fastf1/tests/test_api.py +++ b/fastf1/tests/test_api.py @@ -240,12 +240,13 @@ def test_driver_list(): # ########## verify driver data assert isinstance(data, dict) assert len(data.keys()) == 20 - dtypes = [str, str, str, str, int, str, str, str, str, str, str, - datetime.timedelta, datetime.timedelta, datetime.timedelta, - datetime.timedelta, str, float] + dtypes = {'RacingNumber': str, 'BroadcastName': str, 'FullName': str, + 'Tla': str, 'Line': int, 'TeamName': str, 'TeamColour': str, + 'FirstName': str, 'LastName': str, 'Reference': str, + 'HeadshotUrl': str} for driver in data.values(): - for col, dtype in zip(driver.values(), dtypes): - assert isinstance(col, dtype) + for key, val in driver.items(): + assert isinstance(val, dtypes[key]) # ########## special test cases ##########