From fd16a620f2853b2bbb5e943c4ebd356945d352b9 Mon Sep 17 00:00:00 2001 From: Robert Honz Date: Wed, 2 Jul 2025 08:47:59 +0200 Subject: [PATCH] =?UTF-8?q?refactor(gui):=20=E2=9C=A8=20Enhance=20type=20a?= =?UTF-8?q?nnotations=20and=20improve=20method=20signatures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated type hints for various methods in and classes. * Changed list types from to for better clarity and consistency. * Improved function signatures to include return types for better type safety. --- tidal_dl_ng/download.py | 64 ++++++++++++++++++++--------------------- tidal_dl_ng/gui.py | 34 +++++++++++----------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/tidal_dl_ng/download.py b/tidal_dl_ng/download.py index 9b13053..34d3ef5 100644 --- a/tidal_dl_ng/download.py +++ b/tidal_dl_ng/download.py @@ -57,7 +57,7 @@ from tidal_dl_ng.model.gui_data import ProgressBars class RequestsClient: def download( self, uri: str, timeout: int = REQUESTS_TIMEOUT_SEC, headers: dict | None = None, verify_ssl: bool = True - ): + ) -> tuple[str, str]: if not headers: headers = {} @@ -84,12 +84,12 @@ class Download: path_base: str, fn_logger: Callable, skip_existing: bool = False, - progress_gui: ProgressBars = None, - progress: Progress = None, - progress_overall: Progress = None, - event_abort: Event = None, - event_run: Event = None, - ): + progress_gui: ProgressBars | None = None, + progress: Progress | None = None, + progress_overall: Progress | None = None, + event_abort: Event | None = None, + event_run: Event | None = None, + ) -> None: self.settings = Settings() self.session = session self.skip_existing = skip_existing @@ -118,12 +118,12 @@ class Download: media: Track | Video, path_file: pathlib.Path, stream_manifest: StreamManifest | None = None, - ) -> (bool, pathlib.Path): + ) -> tuple[bool, pathlib.Path]: media_name: str = name_builder_item(media) - urls: [str] + urls: list[str] path_base: pathlib.Path = path_file.parent result_segments: bool = True - dl_segment_results: [DownloadSegmentResult] = [] + dl_segment_results: list[DownloadSegmentResult] = [] result_merge: bool = False # Get urls for media. @@ -179,7 +179,7 @@ class Download: max_workers=self.settings.data.downloads_simultaneous_per_track_max ) as executor: # Dispatch all download tasks to worker threads - l_futures: [futures.Future] = [ + l_futures: list[futures.Future] = [ executor.submit(self._download_segment, url, path_base, block_size, p_task, progress_to_stdout) for url in urls ] @@ -225,7 +225,7 @@ class Download: return result_merge, tmp_path_file_decrypted - def _segments_merge(self, path_file, dl_segment_results) -> bool: + def _segments_merge(self, path_file: pathlib.Path, dl_segment_results: list[DownloadSegmentResult]) -> bool: result: bool = True # Copy the content of all segments into one file. @@ -298,7 +298,7 @@ class Download: ) def extension_guess( - self, quality_audio: Quality, metadata_tags: [str], is_video: bool + self, quality_audio: Quality, metadata_tags: list[str], is_video: bool ) -> AudioExtensions | VideoExtensions: result: AudioExtensions | VideoExtensions @@ -321,9 +321,9 @@ class Download: def item( self, file_template: str, - media: Track | Video = None, - media_id: str = None, - media_type: MediaType = None, + media: Track | Video | None = None, + media_id: str | None = None, + media_type: MediaType | None = None, video_download: bool = True, download_delay: bool = False, quality_audio: Quality | None = None, @@ -331,7 +331,7 @@ class Download: is_parent_album: bool = False, list_position: int = 0, list_total: int = 0, - ) -> (bool, pathlib.Path): + ) -> tuple[bool, pathlib.Path | str]: try: if media_id and media_type: # If no media instance is provided, we need to create the media instance. @@ -557,14 +557,14 @@ class Download: return path_media_dst - def adjust_quality_audio(self, quality) -> Quality: + def adjust_quality_audio(self, quality: Quality) -> Quality: # Save original quality settings quality_old: Quality = self.session.audio_quality self.session.audio_quality = quality return quality_old - def adjust_quality_video(self, quality) -> QualityVideo: + def adjust_quality_video(self, quality: QualityVideo) -> QualityVideo: quality_old: QualityVideo = self.settings.data.quality_video self.settings.data.quality_video = quality @@ -618,7 +618,7 @@ class Download: return result @staticmethod - def cover_data(url: str = None, path_file: str = None) -> str | bytes: + def cover_data(url: str | None = None, path_file: str | None = None) -> str | bytes: result: str | bytes = "" if url: @@ -642,7 +642,7 @@ class Download: def metadata_write( self, track: Track, path_media: pathlib.Path, is_parent_album: bool, media_stream: Stream - ) -> (bool, pathlib.Path | None, pathlib.Path | None): + ) -> tuple[bool, pathlib.Path | None, pathlib.Path | None]: result: bool = False path_lyrics: pathlib.Path | None = None path_cover: pathlib.Path | None = None @@ -713,14 +713,14 @@ class Download: def items( self, file_template: str, - media: Album | Playlist | UserPlaylist | Mix = None, - media_id: str = None, - media_type: MediaType = None, + media: Album | Playlist | UserPlaylist | Mix | None = None, + media_id: str | None = None, + media_type: MediaType | None = None, video_download: bool = False, download_delay: bool = True, quality_audio: Quality | None = None, quality_video: QualityVideo | None = None, - ): + ) -> None: try: if media_id and media_type: # If no media instance is provided, we need to create the media instance. @@ -765,14 +765,14 @@ class Download: is_album: bool = isinstance(media, Album) # TODO: Refactor strings to constants (also in cfg.py) sort_by_track_num: bool = bool("album_track_num" in file_name_relative or "list_pos" in file_name_relative) - result_dirs: [pathlib.Path] = [] + result_dirs: list[pathlib.Path] = [] list_total: int = len(items) # Iterate through list items while not progress.finished: with futures.ThreadPoolExecutor(max_workers=self.settings.data.downloads_concurrent_max) as executor: # Dispatch all download tasks to worker threads - l_futures: [futures.Future] = [ + l_futures: list[futures.Future] = [ executor.submit( self.item, media=item_media, @@ -817,9 +817,9 @@ class Download: self.fn_logger.info(f"Finished list '{list_media_name}'.") def playlist_populate( - self, dirs_scoped: [pathlib.Path], name_list: str, is_album: bool, sort_alphabetically - ) -> [pathlib.Path]: - result: [pathlib.Path] = [] + self, dirs_scoped: set[pathlib.Path], name_list: str, is_album: bool, sort_alphabetically: bool + ) -> list[pathlib.Path]: + result: list[pathlib.Path] = [] # For each dir, which contains tracks for dir_scoped in dirs_scoped: @@ -830,7 +830,7 @@ class Download: self.fn_logger.debug(f"Playlist: Creating {path_playlist}") # Get all tracks in the directory - path_tracks: [pathlib.Path] = [] + path_tracks: list[pathlib.Path] = [] for extension_audio in AudioExtensions: path_tracks = path_tracks + list(dir_scoped.glob(f"*{extension_audio!s}")) @@ -889,7 +889,7 @@ class Download: return path_media_out - def _extract_video_stream(self, m3u8_variant: m3u8.M3U8, quality: int) -> (m3u8.M3U8 | bool, str): + def _extract_video_stream(self, m3u8_variant: m3u8.M3U8, quality: int) -> tuple[m3u8.M3U8 | bool, str]: m3u8_playlist: m3u8.M3U8 | bool = False resolution_best: int = 0 mime_type: str = "" diff --git a/tidal_dl_ng/gui.py b/tidal_dl_ng/gui.py index 57613f5..80dc07e 100644 --- a/tidal_dl_ng/gui.py +++ b/tidal_dl_ng/gui.py @@ -326,7 +326,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def handle_filter_activated(self) -> None: """Handle activation of filter headers in the results tree.""" header = self.tr_results.header() - filters: list[str] = [] + filters: list[tuple[int, str]] = [] for i in range(header.count()): text: str = header.filter_text(i) @@ -369,7 +369,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): Args: model (QStandardItemModel): The model to initialize. """ - labels_column: [str] = ["#", "obj", "Artist", "Title", "Album", "Duration", "Quality", "Date"] + labels_column: list[str] = ["#", "obj", "Artist", "Title", "Album", "Duration", "Quality", "Date"] model.setColumnCount(len(labels_column)) model.setRowCount(0) @@ -404,7 +404,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): """Populate the user lists tree with playlists, mixes, and favorites. Args: - user_lists (list): List of user playlists, mixes, and favorites. + user_lists (list[Playlist | UserPlaylist | Mix]): List of user playlists, mixes, and favorites. """ twi_playlists: QtWidgets.QTreeWidgetItem = self.tr_lists_user.findItems( TidalLists.Playlists, QtCore.Qt.MatchExactly, 0 @@ -612,7 +612,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): """Download all media items in a selected list. Args: - point (QPoint, optional): The point in the tree. Defaults to None. + point (QPoint | None, optional): The point in the tree. Defaults to None. """ items: list[QtWidgets.QTreeWidgetItem] = [] @@ -733,12 +733,12 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self.apply_settings(self.settings) self._init_dl() - def search(self, query: str, types_media: Any) -> list[ResultItem]: + def search(self, query: str, types_media: list[Any]) -> list[ResultItem]: """Perform a search and return a list of ResultItems. Args: query (str): The search query. - types_media (SearchTypes): The types of media to search for. + types_media (list[Any]): The types of media to search for. Returns: list[ResultItem]: The search results. @@ -759,7 +759,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): result_search = {"direct": [media]} else: - result_search: dict[str, [SearchTypes]] = search_results_all( + result_search: dict[str, list[SearchTypes]] = search_results_all( session=self.tidal.session, needle=query, types_media=types_media ) @@ -780,7 +780,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): Returns: list[ResultItem]: List of ResultItem models. """ - result = [] + result: list[ResultItem] = [] for idx, item in enumerate(items): result_item = self._to_result_item(idx, item) @@ -1288,16 +1288,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): self, media_list: Album | Playlist | Mix | Artist | None = None, point: QtCore.QPoint | None = None, - parent: QtGui.QStandardItem = None, - favorite_function: Callable = None, + parent: QtGui.QStandardItem | None = None, + favorite_function: Callable | None = None, ) -> None: """Populate the results tree with the items of a media list. Args: media_list (Album | Playlist | Mix | Artist | None, optional): The media list to show. Defaults to None. point (QPoint | None, optional): The point in the tree. Defaults to None. - parent (QStandardItem, optional): Parent item for nested results. Defaults to None. - favorite_function (Callable, optional): Function to fetch favorite items. Defaults to None. + parent (QStandardItem | None, optional): Parent item for nested results. Defaults to None. + favorite_function (Callable | None, optional): Function to fetch favorite items. Defaults to None. """ if point: item = self.tr_lists_user.itemAt(point) @@ -1308,9 +1308,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): if isinstance(media_list, str): favorite_function = favorite_function_factory(self.tidal, media_list) - media_items: [Track | Video | Album] = favorite_function() + media_items: list[Track | Video | Album] = favorite_function() else: - media_items: [Track | Video | Album] = items_results_all(media_list) + media_items: list[Track | Video | Album] = items_results_all(media_list) result: list[ResultItem] = self.search_result_to_model(media_items) @@ -1346,7 +1346,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): Args: regex (str): Regular expression to match items. """ - items: [QtWidgets.QTreeWidgetItem | None] = self.tr_queue_download.findItems( + items: list[QtWidgets.QTreeWidgetItem | None] = self.tr_queue_download.findItems( regex, QtCore.Qt.MatchFlag.MatchRegularExpression, column=0 ) @@ -1355,7 +1355,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def on_queue_download_remove(self) -> None: """Remove selected items from the download queue.""" - items: [QtWidgets.QTreeWidgetItem | None] = self.tr_queue_download.selectedItems() + items: list[QtWidgets.QTreeWidgetItem | None] = self.tr_queue_download.selectedItems() if len(items) == 0: logger_gui.error("Please select an item from the queue first.") @@ -1439,7 +1439,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): handling_app: HandlingApp = HandlingApp() while not handling_app.event_abort.is_set(): - items: [QtWidgets.QTreeWidgetItem | None] = self.tr_queue_download.findItems( + items: list[QtWidgets.QTreeWidgetItem | None] = self.tr_queue_download.findItems( QueueDownloadStatus.Waiting, QtCore.Qt.MatchFlag.MatchExactly, column=0 )