From 21968923b38f6d28a83bf1a995c7e6605e23aa11 Mon Sep 17 00:00:00 2001 From: rlaphoenix Date: Thu, 9 May 2024 14:19:14 +0100 Subject: [PATCH] refactor(Track): Use defaultdict with a dict factory for data property This is so both internal code and service code can save data to sub-keys without the parent keys needing to exist. This also fixes a bug introduced in v3.3.3 where it will fail to download tracks without the "hls" key in the data property. This can happen when manually making Audio tracks using the HLS descriptor, and not putting any of the hls data the HLS class sets in to_tracks(). --- devine/core/tracks/track.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/devine/core/tracks/track.py b/devine/core/tracks/track.py index 740b98d..615d4d9 100644 --- a/devine/core/tracks/track.py +++ b/devine/core/tracks/track.py @@ -4,6 +4,7 @@ import re import shutil import subprocess +from collections import defaultdict from copy import copy from enum import Enum from functools import partial @@ -42,7 +43,7 @@ def __init__( drm: Optional[Iterable[DRM_T]] = None, edition: Optional[str] = None, downloader: Optional[Callable] = None, - data: Optional[dict] = None, + data: Optional[Union[dict, defaultdict]] = None, id_: Optional[str] = None, ) -> None: if not isinstance(url, (str, list)): @@ -63,8 +64,8 @@ def __init__( raise TypeError(f"Expected edition to be a {str}, not {type(edition)}") if not isinstance(downloader, (Callable, type(None))): raise TypeError(f"Expected downloader to be a {Callable}, not {type(downloader)}") - if not isinstance(data, (dict, type(None))): - raise TypeError(f"Expected data to be a {dict}, not {type(data)}") + if not isinstance(data, (dict, defaultdict, type(None))): + raise TypeError(f"Expected data to be a {dict} or {defaultdict}, not {type(data)}") invalid_urls = ", ".join(set(type(x) for x in url if not isinstance(x, str))) if invalid_urls: @@ -93,7 +94,7 @@ def __init__( self.drm = drm self.edition: str = edition self.downloader = downloader - self.data = data or {} + self.data = defaultdict(dict, **(data or {})) if self.name is None: lang = Language.get(self.language)