Chore(deps): Bump ruff from 0.9.6 to 0.11.2 (#2083)
authordependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Mon, 31 Mar 2025 22:15:08 +0000 (00:15 +0200)
committerGitHub <noreply@github.com>
Mon, 31 Mar 2025 22:15:08 +0000 (00:15 +0200)
* Chore(deps): Bump ruff from 0.9.6 to 0.11.2

Bumps [ruff](https://github.com/astral-sh/ruff) from 0.9.6 to 0.11.2.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.9.6...0.11.2)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
* lint

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
33 files changed:
music_assistant/constants.py
music_assistant/controllers/metadata.py
music_assistant/controllers/music.py
music_assistant/controllers/player_queues.py
music_assistant/controllers/players.py
music_assistant/helpers/audio.py
music_assistant/helpers/logging.py
music_assistant/mass.py
music_assistant/models/music_provider.py
music_assistant/providers/airplay/__init__.py
music_assistant/providers/airplay/provider.py
music_assistant/providers/audible/__init__.py
music_assistant/providers/builtin/__init__.py
music_assistant/providers/builtin_player/__init__.py
music_assistant/providers/fanarttv/__init__.py
music_assistant/providers/filesystem_local/__init__.py
music_assistant/providers/hass/__init__.py
music_assistant/providers/hass_players/__init__.py
music_assistant/providers/lastfm_scrobble/__init__.py
music_assistant/providers/musicbrainz/__init__.py
music_assistant/providers/player_group/__init__.py
music_assistant/providers/plex/__init__.py
music_assistant/providers/plex/helpers.py
music_assistant/providers/radiobrowser/__init__.py
music_assistant/providers/siriusxm/__init__.py
music_assistant/providers/snapcast/__init__.py
music_assistant/providers/sonos_s1/__init__.py
music_assistant/providers/spotify/__init__.py
music_assistant/providers/spotify_connect/__init__.py
music_assistant/providers/theaudiodb/__init__.py
music_assistant/providers/tidal/__init__.py
pyproject.toml
scripts/gen_requirements_all.py

index 51d27e6eafea5f8b4ae1e6a36b004f5b5af1b363..243164a7a50431efb7546eb29151264fdaeb8c00 100644 (file)
@@ -643,7 +643,7 @@ def create_sample_rates_config_entry(
     default_value: list[str] = []
 
     for option in CONF_ENTRY_SAMPLE_RATES.options:
-        option_value = cast(str, option.value)
+        option_value = cast("str", option.value)
         sample_rate_str, bit_depth_str = option_value.split(MULTI_VALUE_SPLITTER, 1)
         sample_rate = int(sample_rate_str)
         bit_depth = int(bit_depth_str)
index b993532e56389e23841ae41c2aab126b0ce7b7ec..58eb619a0801972a7fdd856d5e38b47fb9012539 100644 (file)
@@ -206,7 +206,7 @@ class MetaDataController(CoreController):
     def providers(self) -> list[MetadataProvider]:
         """Return all loaded/running MetadataProviders."""
         if TYPE_CHECKING:
-            return cast(list[MetadataProvider], self.mass.get_providers(ProviderType.METADATA))
+            return cast("list[MetadataProvider]", self.mass.get_providers(ProviderType.METADATA))
         return self.mass.get_providers(ProviderType.METADATA)
 
     @property
@@ -456,7 +456,7 @@ class MetaDataController(CoreController):
         # collect (local) metadata from all local providers
         local_provs = get_global_cache_value("non_streaming_providers")
         if TYPE_CHECKING:
-            local_provs = cast(set[str], local_provs)
+            local_provs = cast("set[str]", local_provs)
 
         # ensure the item is matched to all providers
         await self.mass.music.artists.match_providers(artist)
@@ -522,7 +522,7 @@ class MetaDataController(CoreController):
         unique_keys: set[str] = set()
         local_provs = get_global_cache_value("non_streaming_providers")
         if TYPE_CHECKING:
-            local_provs = cast(set[str], local_provs)
+            local_provs = cast("set[str]", local_provs)
         for prov_mapping in sorted(album.provider_mappings, key=lambda x: x.priority, reverse=True):
             if (prov := self.mass.get_provider(prov_mapping.provider_instance)) is None:
                 continue
@@ -577,7 +577,7 @@ class MetaDataController(CoreController):
         unique_keys: set[str] = set()
         local_provs = get_global_cache_value("non_streaming_providers")
         if TYPE_CHECKING:
-            local_provs = cast(set[str], local_provs)
+            local_provs = cast("set[str]", local_provs)
         for prov_mapping in sorted(track.provider_mappings, key=lambda x: x.priority, reverse=True):
             if (prov := self.mass.get_provider(prov_mapping.provider_instance)) is None:
                 continue
@@ -691,7 +691,7 @@ class MetaDataController(CoreController):
 
         musicbrainz: MusicbrainzProvider = self.mass.get_provider("musicbrainz")
         if TYPE_CHECKING:
-            musicbrainz = cast(MusicbrainzProvider, musicbrainz)
+            musicbrainz = cast("MusicbrainzProvider", musicbrainz)
         # first try with resource URL (e.g. streaming provider share URL)
         for prov_mapping in artist.provider_mappings:
             if prov_mapping.url and prov_mapping.url.startswith("http"):
index 3589510a2148aa2cf4a34031d93fcdce4005816a..7c7ec682843606083df0b81b4573383e9bae3622 100644 (file)
@@ -730,7 +730,7 @@ class MusicController(CoreController):
 
         available_providers = get_global_cache_value("available_providers")
         if TYPE_CHECKING:
-            available_providers = cast(set[str], available_providers)
+            available_providers = cast("set[str]", available_providers)
 
         # fetch the first (available) provider item
         for prov_mapping in sorted(
index b1266ec0e9fbab271f5bf916d2335f1ed4784443..c594dffbd3f9673b34092ba85119b7a7c589c752 100644 (file)
@@ -1344,7 +1344,7 @@ class PlayerQueuesController(CoreController):
                 "Fetching resume point to play for Podcast episode %s",
                 episode.name,
             )
-            episode = cast(PodcastEpisode, episode)
+            episode = cast("PodcastEpisode", episode)
             fully_played, resume_position_ms = await self.mass.music.get_resume_position(episode)
             episode.fully_played = fully_played
             episode.resume_position_ms = 0 if fully_played else resume_position_ms
index c8705d2160d39534f07d3235e122e7f8e57459ab..fd80dc5fba75983e42ad02e77c16538508524ceb 100644 (file)
@@ -1217,7 +1217,7 @@ class PlayerController(CoreController):
         """Return PlayerProvider for given player."""
         player = self._players[player_id]
         player_provider = self.mass.get_provider(player.provider)
-        return cast(PlayerProvider, player_provider)
+        return cast("PlayerProvider", player_provider)
 
     def get_announcement_volume(self, player_id: str, volume_override: int | None) -> int | None:
         """Get the (player specific) volume for a announcement."""
index e630cf2350ba66b623689ceb91d49544c75ca608..f40991fd30a1a5cb5ff803a9d9accf7cfe24fcb2 100644 (file)
@@ -625,7 +625,7 @@ async def get_stream_details(
         if streamdetails.cache is None:
             streamdetails.cache = StreamCache(mass, streamdetails)
         else:
-            streamdetails.cache = cast(StreamCache, streamdetails.cache)
+            streamdetails.cache = cast("StreamCache", streamdetails.cache)
         # create cache (if needed) and wait until the cache is available
         await streamdetails.cache.create()
         LOGGER.debug(
@@ -706,7 +706,7 @@ async def get_media_stream(
     # work out audio source for these streamdetails
     stream_type = streamdetails.stream_type
     if stream_type == StreamType.CACHE:
-        cache = cast(StreamCache, streamdetails.cache)
+        cache = cast("StreamCache", streamdetails.cache)
         audio_source = await cache.get_audio_stream()
     elif stream_type == StreamType.MULTI_FILE:
         audio_source = get_multi_file_stream(mass, streamdetails)
@@ -875,7 +875,7 @@ async def get_media_stream(
 
         # release cache if needed
         if cache := streamdetails.cache:
-            cache = cast(StreamCache, streamdetails.cache)
+            cache = cast("StreamCache", streamdetails.cache)
             cache.release()
 
         # parse loudnorm data if we have that collected (and enabled)
@@ -1505,7 +1505,7 @@ async def analyze_loudness(
         "600",
     ]
     if streamdetails.stream_type == StreamType.CACHE:
-        cache = cast(StreamCache, streamdetails.cache)
+        cache = cast("StreamCache", streamdetails.cache)
         audio_source = await cache.get_audio_stream()
     elif streamdetails.stream_type == StreamType.MULTI_FILE:
         audio_source = get_multi_file_stream(mass, streamdetails)
@@ -1563,7 +1563,7 @@ async def analyze_loudness(
         finally:
             # release cache if needed
             if cache := streamdetails.cache:
-                cache = cast(StreamCache, streamdetails.cache)
+                cache = cast("StreamCache", streamdetails.cache)
                 cache.release()
 
 
index 1dac5a3addecd449a8f90fd61d5e2b7afb364bee..ffecb3c8f15b87f4880ac5fe697f9423aaaa8c94 100644 (file)
@@ -133,7 +133,7 @@ def catch_log_exception(
 
     wrapper_func: Callable[..., None] | Callable[..., Coroutine[Any, Any, None]]
     if asyncio.iscoroutinefunction(check_func):
-        async_func = cast(Callable[..., Coroutine[Any, Any, None]], func)
+        async_func = cast("Callable[..., Coroutine[Any, Any, None]]", func)
 
         @wraps(async_func)
         async def async_wrapper(*args: Any) -> None:
index 120ecabb0fd07686468af667bbdeb34b83d9260e..0da50bd23b950bb2d1bda2e9074a5c8fff8642b9 100644 (file)
@@ -307,11 +307,11 @@ class MusicAssistant:
                 continue
             if asyncio.iscoroutinefunction(cb_func):
                 if TYPE_CHECKING:
-                    cb_func = cast(Callable[[MassEvent], Coroutine[Any, Any, None]], cb_func)
+                    cb_func = cast("Callable[[MassEvent], Coroutine[Any, Any, None]]", cb_func)
                 self.create_task(cb_func, event_obj)
             else:
                 if TYPE_CHECKING:
-                    cb_func = cast(Callable[[MassEvent], None], cb_func)
+                    cb_func = cast("Callable[[MassEvent], None]", cb_func)
                 self.loop.call_soon_threadsafe(cb_func, event_obj)
 
     def subscribe(
@@ -428,12 +428,12 @@ class MusicAssistant:
         if asyncio.iscoroutinefunction(target) or asyncio.iscoroutine(target):
             # coroutine function
             if TYPE_CHECKING:
-                target = cast(Coroutine[Any, Any, _R], target)
+                target = cast("Coroutine[Any, Any, _R]", target)
             handle = self.loop.call_later(delay, _create_task, target)
         else:
             # regular callable
             if TYPE_CHECKING:
-                target = cast(Callable[..., _R], target)
+                target = cast("Callable[..., _R]", target)
             handle = self.loop.call_later(delay, target, *args)
         self._tracked_timers[task_id] = handle
         return handle
@@ -700,7 +700,7 @@ class MusicAssistant:
         async def load_provider_manifest(provider_domain: str, provider_path: str) -> None:
             """Preload all available provider manifest files."""
             # get files in subdirectory
-            for file_str in os.listdir(provider_path):
+            for file_str in os.listdir(provider_path):  # noqa: PTH208, RUF100
                 file_path = os.path.join(provider_path, file_str)
                 if not await isfile(file_path):
                     continue
@@ -733,7 +733,7 @@ class MusicAssistant:
                     )
 
         async with TaskManager(self) as tg:
-            for dir_str in os.listdir(PROVIDERS_PATH):
+            for dir_str in os.listdir(PROVIDERS_PATH):  # noqa: PTH208, RUF100
                 if dir_str.startswith(("_", ".")):
                     continue
                 dir_path = os.path.join(PROVIDERS_PATH, dir_str)
index d521af50cbbfbd3bf10c30b05e5b88fe22c19659..13273d0da3751838f7ddb517f48e0e726f0bbd41 100644 (file)
@@ -431,7 +431,7 @@ class MusicProvider(Provider):
             )
             if not library_item_ids:
                 return [x async for x in self.get_library_artists()]
-            library_items = cast(list[int], library_item_ids)
+            library_items = cast("list[int]", library_item_ids)
             query = "artists.item_id in :ids"
             query_params = {"ids": library_items}
             return await self.mass.music.artists.library_items(
@@ -447,7 +447,7 @@ class MusicProvider(Provider):
             )
             if not library_item_ids:
                 return [x async for x in self.get_library_albums()]
-            library_item_ids = cast(list[int], library_item_ids)
+            library_item_ids = cast("list[int]", library_item_ids)
             query = "albums.item_id in :ids"
             query_params = {"ids": library_item_ids}
             return await self.mass.music.albums.library_items(
@@ -461,7 +461,7 @@ class MusicProvider(Provider):
             )
             if not library_item_ids:
                 return [x async for x in self.get_library_tracks()]
-            library_item_ids = cast(list[int], library_item_ids)
+            library_item_ids = cast("list[int]", library_item_ids)
             query = "tracks.item_id in :ids"
             query_params = {"ids": library_items}
             return await self.mass.music.tracks.library_items(
@@ -475,7 +475,7 @@ class MusicProvider(Provider):
             )
             if not library_item_ids:
                 return [x async for x in self.get_library_radios()]
-            library_item_ids = cast(list[int], library_item_ids)
+            library_item_ids = cast("list[int]", library_item_ids)
             query = "radios.item_id in :ids"
             query_params = {"ids": library_item_ids}
             return await self.mass.music.radio.library_items(
@@ -489,7 +489,7 @@ class MusicProvider(Provider):
             )
             if not library_item_ids:
                 return [x async for x in self.get_library_playlists()]
-            library_item_ids = cast(list[int], library_item_ids)
+            library_item_ids = cast("list[int]", library_item_ids)
             query = "playlists.item_id in :ids"
             query_params = {"ids": library_item_ids}
             return await self.mass.music.playlists.library_items(
@@ -503,7 +503,7 @@ class MusicProvider(Provider):
             )
             if not library_item_ids:
                 return [x async for x in self.get_library_audiobooks()]
-            library_item_ids = cast(list[int], library_item_ids)
+            library_item_ids = cast("list[int]", library_item_ids)
             query = "audiobooks.item_id in :ids"
             query_params = {"ids": library_item_ids}
             return await self.mass.music.audiobooks.library_items(
@@ -517,7 +517,7 @@ class MusicProvider(Provider):
             )
             if not library_item_ids:
                 return [x async for x in self.get_library_podcasts()]
-            library_item_ids = cast(list[int], library_item_ids)
+            library_item_ids = cast("list[int]", library_item_ids)
             query = "podcasts.item_id in :ids"
             query_params = {"ids": library_item_ids}
             return await self.mass.music.podcasts.library_items(
index 35463ecaa8269cdb13eef2aab938909de821b710..752d21465cdac5fe9a5444e819701e3fd038fd23 100644 (file)
@@ -38,7 +38,7 @@ async def get_config_entries(
         ConfigEntry(
             key=CONF_BIND_INTERFACE,
             type=ConfigEntryType.STRING,
-            default_value=cast(str, mass.streams.publish_ip),
+            default_value=cast("str", mass.streams.publish_ip),
             label="Bind interface",
             description="Interface to bind to for Airplay streaming.",
             category="advanced",
index 080e57c28bc0c648fd9d48adaa557fcb782f532a..e514398fa4bcb2339ee319667ff306a25dcef69b 100644 (file)
@@ -327,7 +327,7 @@ class AirplayProvider(PlayerProvider):
             )
         elif media.queue_id and media.queue_id.startswith("ugp_"):
             # special case: UGP stream
-            ugp_provider = cast(PlayerGroupProvider, self.mass.get_provider("player_group"))
+            ugp_provider = cast("PlayerGroupProvider", self.mass.get_provider("player_group"))
             ugp_stream = ugp_provider.ugp_streams[media.queue_id]
             input_format = ugp_stream.base_pcm_format
             audio_source = ugp_stream.subscribe_raw()
index 3f7bd329262c116b4b3ba983d28693e71d3b354e..2c9a74307ffc02d51916ff8017ca7d64da256048 100644 (file)
@@ -73,8 +73,8 @@ async def get_config_entries(
     if values is None:
         values = {}
 
-    locale = cast(str, values.get("locale", "") or "us")
-    auth_file = cast(str, values.get(CONF_AUTH_FILE))
+    locale = cast("str", values.get("locale", "") or "us")
+    auth_file = cast("str", values.get(CONF_AUTH_FILE))
 
     auth_required = True
     if auth_file and await check_file_exists(auth_file):
@@ -166,7 +166,7 @@ async def get_config_entries(
             type=ConfigEntryType.STRING,
             label="Post Login Url",
             required=False,
-            value=cast(str | None, values.get(CONF_POST_LOGIN_URL)),
+            value=cast("str | None", values.get(CONF_POST_LOGIN_URL)),
             hidden=not auth_required,
         ),
         ConfigEntry(
@@ -183,7 +183,7 @@ async def get_config_entries(
             label="Code Verifier",
             hidden=True,
             required=False,
-            value=cast(str | None, values.get(CONF_CODE_VERIFIER)),
+            value=cast("str | None", values.get(CONF_CODE_VERIFIER)),
         ),
         ConfigEntry(
             key=CONF_SERIAL,
@@ -191,7 +191,7 @@ async def get_config_entries(
             label="Serial",
             hidden=True,
             required=False,
-            value=cast(str | None, values.get(CONF_SERIAL)),
+            value=cast("str | None", values.get(CONF_SERIAL)),
         ),
         ConfigEntry(
             key=CONF_LOGIN_URL,
@@ -199,7 +199,7 @@ async def get_config_entries(
             label="Login Url",
             hidden=True,
             required=False,
-            value=cast(str | None, values.get(CONF_LOGIN_URL)),
+            value=cast("str | None", values.get(CONF_LOGIN_URL)),
         ),
         ConfigEntry(
             key=CONF_AUTH_FILE,
@@ -207,7 +207,7 @@ async def get_config_entries(
             label="Authentication File",
             hidden=True,
             required=True,
-            value=cast(str | None, values.get(CONF_AUTH_FILE)),
+            value=cast("str | None", values.get(CONF_AUTH_FILE)),
         ),
     )
 
@@ -220,8 +220,8 @@ class Audibleprovider(MusicProvider):
     ) -> None:
         """Initialize the Audible Audiobook Provider."""
         super().__init__(mass, manifest, config)
-        self.locale = cast(str, self.config.get_value(CONF_LOCALE) or "us")
-        self.auth_file = cast(str, self.config.get_value(CONF_AUTH_FILE))
+        self.locale = cast("str", self.config.get_value(CONF_LOCALE) or "us")
+        self.auth_file = cast("str", self.config.get_value(CONF_AUTH_FILE))
         self._client: audible.AsyncClient | None = None
         audible.log_helper.set_level(getLevelName(self.logger.level))
 
index b1fdfe65c755e0e750cc27cac0a0a23642c912c9..c6512299576ccadf43b31829240ebfee1443b45e 100644 (file)
@@ -179,7 +179,7 @@ class BuiltinProvider(MusicProvider):
 
     async def get_track(self, prov_track_id: str) -> Track:
         """Get full track details by id."""
-        parsed_item = cast(Track, await self.parse_item(prov_track_id))
+        parsed_item = cast("Track", await self.parse_item(prov_track_id))
         stored_items: list[StoredItem] = self.mass.config.get(CONF_KEY_TRACKS, [])
         if stored_item := next((x for x in stored_items if x["item_id"] == prov_track_id), None):
             # always prefer the stored info, such as the name
index e1d2c38bd5470b6903d1ea33b8b51719db7b48c8..3f106909a79f81362cfddb1065b55ab02ee88a2f 100644 (file)
@@ -216,7 +216,7 @@ class BuiltinPlayerProvider(PlayerProvider):
     ) -> None:
         """Handle PLAY MEDIA on given player."""
         url = f"builtin_player/flow/{player_id}.mp3"
-        player = cast(Player, self.mass.players.get(player_id, raise_unavailable=True))
+        player = cast("Player", self.mass.players.get(player_id, raise_unavailable=True))
         player.current_media = media
 
         self.mass.signal_event(
index 89a94c5bd413ffb5c42844c654e8d0163a454b1f..92e13e63d13137023abddfdc6b0a3e9c4b36c6be 100644 (file)
@@ -190,4 +190,4 @@ class FanartTvMetadataProvider(MetadataProvider):
             if "error" in result and "limit" in result["error"]:
                 self.logger.warning(result["error"])
                 return None
-            return cast(dict[str, Any], result)
+            return cast("dict[str, Any]", result)
index d4194b1c849037803d33a02810bf2232f1ba5fa5..3fe868deba8ed75557bdc1d16d227185ab298244 100644 (file)
@@ -113,7 +113,7 @@ async def setup(
     mass: MusicAssistant, manifest: ProviderManifest, config: ProviderConfig
 ) -> ProviderInstanceType:
     """Initialize provider(instance) with given configuration."""
-    base_path = cast(str, config.get_value(CONF_PATH))
+    base_path = cast("str", config.get_value(CONF_PATH))
     return LocalFileSystemProvider(mass, manifest, config, base_path)
 
 
@@ -167,7 +167,7 @@ class LocalFileSystemProvider(MusicProvider):
         self.base_path: str = base_path
         self.write_access: bool = False
         self.sync_running: bool = False
-        self.media_content_type = cast(str, config.get_value(CONF_ENTRY_CONTENT_TYPE.key))
+        self.media_content_type = cast("str", config.get_value(CONF_ENTRY_CONTENT_TYPE.key))
 
     @property
     def supported_features(self) -> set[ProviderFeature]:
@@ -1010,7 +1010,7 @@ class LocalFileSystemProvider(MusicProvider):
         # prefer (short lived) cache for a bit more speed
         cache_base_key = f"{self.instance_id}.artist"
         if artist_path and (cache := await self.cache.get(artist_path, base_key=cache_base_key)):
-            return cast(Artist, cache)
+            return cast("Artist", cache)
 
         prov_artist_id = artist_path or name
         artist = Artist(
@@ -1309,7 +1309,7 @@ class LocalFileSystemProvider(MusicProvider):
 
         cache_base_key = f"{self.instance_id}.album"
         if album_dir and (cache := await self.cache.get(album_dir, base_key=cache_base_key)):
-            return cast(Album, cache)
+            return cast("Album", cache)
 
         # album artist(s)
         album_artists: UniqueList[Artist | ItemMapping] = UniqueList()
@@ -1451,7 +1451,7 @@ class LocalFileSystemProvider(MusicProvider):
         """Return local images found in a given folderpath."""
         cache_base_key = f"{self.lookup_key}.folderimages"
         if (cache := await self.cache.get(folder, base_key=cache_base_key)) is not None:
-            return cast(UniqueList[MediaItemImage], cache)
+            return cast("UniqueList[MediaItemImage]", cache)
         if extra_thumb_names is None:
             extra_thumb_names = ()
         images: UniqueList[MediaItemImage] = UniqueList()
@@ -1729,7 +1729,7 @@ class LocalFileSystemProvider(MusicProvider):
         """Return metadata for a podcast."""
         cache_base_key = f"{self.lookup_key}.podcastmetadata"
         if (cache := await self.cache.get(podcast_folder, base_key=cache_base_key)) is not None:
-            return cast(dict[str, Any], cache)
+            return cast("dict[str, Any]", cache)
         data: dict[str, Any] = {}
         metadata_file = os.path.join(podcast_folder, "metadata.json")
         if await self.exists(metadata_file):
index f4494c5cbb2b9f3421349dc6708d9fbb7d485300..27167e0928c3d853143434c0dc9f1a42370a70ad 100644 (file)
@@ -143,7 +143,7 @@ async def get_config_entries(
                 label="URL",
                 required=True,
                 description="URL to your Home Assistant instance (e.g. http://192.168.1.1:8123)",
-                value=cast(str, values.get(CONF_URL)) if values else None,
+                value=cast("str", values.get(CONF_URL)) if values else None,
             ),
             ConfigEntry(
                 key=CONF_ACTION_AUTH,
@@ -162,7 +162,7 @@ async def get_config_entries(
                 description="You can either paste a Long Lived Token here manually or use the "
                 "'authenticate' button to generate a token for you with logging in.",
                 depends_on=CONF_URL,
-                value=cast(str, values.get(CONF_AUTH_TOKEN)) if values else None,
+                value=cast("str", values.get(CONF_AUTH_TOKEN)) if values else None,
                 category="advanced",
             ),
             ConfigEntry(
@@ -178,7 +178,7 @@ async def get_config_entries(
 
     # append player controls entries (if we have an active instance)
     if instance_id and (hass_prov := mass.get_provider(instance_id)) and hass_prov.available:
-        hass_prov = cast(HomeAssistantProvider, hass_prov)
+        hass_prov = cast("HomeAssistantProvider", hass_prov)
         return (*base_entries, *(await _get_player_control_config_entries(hass_prov.hass)))
 
     return (
@@ -355,9 +355,9 @@ class HomeAssistantProvider(PluginProvider):
 
     async def _register_player_controls(self) -> None:
         """Register all player controls."""
-        power_controls = cast(list[str], self.config.get_value(CONF_POWER_CONTROLS))
-        mute_controls = cast(list[str], self.config.get_value(CONF_MUTE_CONTROLS))
-        volume_controls = cast(list[str], self.config.get_value(CONF_VOLUME_CONTROLS))
+        power_controls = cast("list[str]", self.config.get_value(CONF_POWER_CONTROLS))
+        mute_controls = cast("list[str]", self.config.get_value(CONF_MUTE_CONTROLS))
+        volume_controls = cast("list[str]", self.config.get_value(CONF_VOLUME_CONTROLS))
         control_entity_ids: set[str] = {
             *power_controls,
             *mute_controls,
index 0c9e4c8d07953eaf58ca1fadf62904a7db3690da..60b307bba417926b3b427d054f191c361172c323 100644 (file)
@@ -640,7 +640,7 @@ class HomeAssistantPlayers(PlayerProvider):
                     if "supported_formats" not in media_player_obj:
                         continue
                     for supported_format_obj in media_player_obj["supported_formats"]:
-                        result.append(cast(ESPHomeSupportedAudioFormat, supported_format_obj))
+                        result.append(cast("ESPHomeSupportedAudioFormat", supported_format_obj))
         except Exception as exc:
             self.logger.warning(
                 "Failed to fetch diagnostics for ESPHome player: %s",
index a515136a307a2aaacda34014f949d79711eda96a..e871b57536f3d9277ae094c5b96dcb93b3d5541c 100644 (file)
@@ -292,10 +292,10 @@ def get_network(config: dict[str, ConfigValueType]) -> pylast._Network:
     provider: str = str(config.get(CONF_PROVIDER))
 
     if TYPE_CHECKING:
-        key = cast(str, key)
-        secret = cast(str, secret)
-        session_key = cast(str, session_key)
-        username = cast(str, username)
+        key = cast("str", key)
+        secret = cast("str", secret)
+        session_key = cast("str", session_key)
+        username = cast("str", username)
 
     match provider.lower():
         case "lastfm":
index a7522994c4cd2b99a59d9315ad83110ff7b526c7..215acfdcf9b2c9dacfe420fbda0dc1a7b4460020 100644 (file)
@@ -67,10 +67,10 @@ def replace_hyphens(data: _T) -> _T:
         for key, value in data.items():
             new_key = key.replace("-", "_")
             new_values[new_key] = replace_hyphens(value)
-        return cast(_T, new_values)
+        return cast("_T", new_values)
 
     if isinstance(data, list):
-        return cast(_T, [replace_hyphens(x) if isinstance(x, dict) else x for x in data])
+        return cast("_T", [replace_hyphens(x) if isinstance(x, dict) else x for x in data])
 
     return data
 
index d6c21e5d249d452049cd1836ef97a81b2334b338..637a20f586a1b4eda8dd81eb0a925a20e83f64bc 100644 (file)
@@ -261,7 +261,7 @@ class PlayerGroupProvider(PlayerProvider):
         if not (player_provider := self.mass.get_provider(group_type)):
             return base_entries  # guard
         if TYPE_CHECKING:
-            player_provider = cast(PlayerProvider, player_provider)
+            player_provider = cast("PlayerProvider", player_provider)
         assert player_provider.instance_id != self.instance_id
         if not (child_player := next((x for x in player_provider.players), None)):
             return base_entries  # guard
@@ -351,7 +351,7 @@ class PlayerGroupProvider(PlayerProvider):
         """Handle POWER command to group player."""
         group_player = self.mass.players.get(player_id, raise_unavailable=True)
         if TYPE_CHECKING:
-            group_player = cast(Player, group_player)
+            group_player = cast("Player", group_player)
 
         # always stop at power off
         if not powered and group_player.state in (PlayerState.PLAYING, PlayerState.PAUSED):
@@ -589,7 +589,7 @@ class PlayerGroupProvider(PlayerProvider):
         """
         group_player = self.mass.players.get(target_player, raise_unavailable=True)
         if TYPE_CHECKING:
-            group_player = cast(Player, group_player)
+            group_player = cast("Player", group_player)
         dynamic_members_enabled = self.mass.config.get_raw_player_config_value(
             group_player.player_id,
             CONFIG_ENTRY_DYNAMIC_MEMBERS.key,
@@ -604,7 +604,7 @@ class PlayerGroupProvider(PlayerProvider):
             )
         child_player = self.mass.players.get(player_id, raise_unavailable=True)
         if TYPE_CHECKING:
-            group_player = cast(Player, group_player)
+            group_player = cast("Player", group_player)
         if child_player.active_group and child_player.active_group != group_player.player_id:
             raise InvalidDataError(
                 f"Player {child_player.display_name} already has another group active"
@@ -642,8 +642,8 @@ class PlayerGroupProvider(PlayerProvider):
         group_player = self.mass.players.get(target_player, raise_unavailable=True)
         child_player = self.mass.players.get(player_id, raise_unavailable=True)
         if TYPE_CHECKING:
-            group_player = cast(Player, group_player)
-            child_player = cast(Player, child_player)
+            group_player = cast("Player", group_player)
+            child_player = cast("Player", child_player)
         dynamic_members_enabled = self.mass.config.get_raw_player_config_value(
             group_player.player_id,
             CONFIG_ENTRY_DYNAMIC_MEMBERS.key,
@@ -746,7 +746,7 @@ class PlayerGroupProvider(PlayerProvider):
         elif player_provider := self.mass.get_provider(group_type):
             # grab additional details from one of the provider's players
             if TYPE_CHECKING:
-                player_provider = cast(PlayerProvider, player_provider)
+                player_provider = cast("PlayerProvider", player_provider)
             model_name = "Sync Group"
             manufacturer = self.mass.get_provider(group_type).name
             can_group_with = {player_provider.instance_id}
index 81f5a22d9f54d4cb3c6b9eabb9cdd47ded5262d2..40d1244ea24de9e4cdbd50f72f2fccf16c13dd34 100644 (file)
@@ -182,7 +182,7 @@ async def get_config_entries(  # noqa: PLR0915
             label="Local server IP",
             description="The local server IP (e.g. 192.168.1.77)",
             required=True,
-            value=cast(str, values.get(CONF_LOCAL_SERVER_IP)) if values else None,
+            value=cast("str", values.get(CONF_LOCAL_SERVER_IP)) if values else None,
         ),
         ConfigEntry(
             key=CONF_LOCAL_SERVER_PORT,
@@ -191,7 +191,7 @@ async def get_config_entries(  # noqa: PLR0915
             description="The local server port (e.g. 32400)",
             required=True,
             default_value=32400,
-            value=cast(int, values.get(CONF_LOCAL_SERVER_PORT)) if values else None,
+            value=cast("int", values.get(CONF_LOCAL_SERVER_PORT)) if values else None,
         ),
         ConfigEntry(
             key=CONF_LOCAL_SERVER_SSL,
@@ -216,7 +216,7 @@ async def get_config_entries(  # noqa: PLR0915
             type=ConfigEntryType.SECURE_STRING,
             label=CONF_AUTH_TOKEN,
             action=CONF_AUTH_TOKEN,
-            value=cast(str | None, values.get(CONF_AUTH_TOKEN)) if values else None,
+            value=cast("str | None", values.get(CONF_AUTH_TOKEN)) if values else None,
             hidden=True,
         ),
     ]
@@ -422,7 +422,7 @@ class PlexProvider(MusicProvider):
 
     async def _get_data(self, key: str, cls: type[PlexObjectT]) -> PlexObjectT:
         results = await self._run_async(self._plex_library.fetchItem, key, cls)
-        return cast(PlexObjectT, results)
+        return cast("PlexObjectT", results)
 
     def _get_item_mapping(self, media_type: MediaType, key: str, name: str) -> ItemMapping:
         name, version = parse_title_and_version(name)
@@ -471,19 +471,19 @@ class PlexProvider(MusicProvider):
 
     async def _search_track(self, search_query: str | None, limit: int) -> list[PlexTrack]:
         return cast(
-            list[PlexTrack],
+            "list[PlexTrack]",
             await self._run_async(self._plex_library.searchTracks, title=search_query, limit=limit),
         )
 
     async def _search_album(self, search_query: str, limit: int) -> list[PlexAlbum]:
         return cast(
-            list[PlexAlbum],
+            "list[PlexAlbum]",
             await self._run_async(self._plex_library.searchAlbums, title=search_query, limit=limit),
         )
 
     async def _search_artist(self, search_query: str, limit: int) -> list[PlexArtist]:
         return cast(
-            list[PlexArtist],
+            "list[PlexArtist]",
             await self._run_async(
                 self._plex_library.searchArtists, title=search_query, limit=limit
             ),
@@ -491,31 +491,31 @@ class PlexProvider(MusicProvider):
 
     async def _search_playlist(self, search_query: str, limit: int) -> list[PlexPlaylist]:
         return cast(
-            list[PlexPlaylist],
+            "list[PlexPlaylist]",
             await self._run_async(self._plex_library.playlists, title=search_query, limit=limit),
         )
 
     async def _search_track_advanced(self, limit: int, **kwargs: Any) -> list[PlexTrack]:
         return cast(
-            list[PlexPlaylist],
+            "list[PlexPlaylist]",
             await self._run_async(self._plex_library.searchTracks, filters=kwargs, limit=limit),
         )
 
     async def _search_album_advanced(self, limit: int, **kwargs: Any) -> list[PlexAlbum]:
         return cast(
-            list[PlexPlaylist],
+            "list[PlexPlaylist]",
             await self._run_async(self._plex_library.searchAlbums, filters=kwargs, limit=limit),
         )
 
     async def _search_artist_advanced(self, limit: int, **kwargs: Any) -> list[PlexArtist]:
         return cast(
-            list[PlexPlaylist],
+            "list[PlexPlaylist]",
             await self._run_async(self._plex_library.searchArtists, filters=kwargs, limit=limit),
         )
 
     async def _search_playlist_advanced(self, limit: int, **kwargs: Any) -> list[PlexPlaylist]:
         return cast(
-            list[PlexPlaylist],
+            "list[PlexPlaylist]",
             await self._run_async(self._plex_library.playlists, filters=kwargs, limit=limit),
         )
 
@@ -882,7 +882,7 @@ class PlexProvider(MusicProvider):
         """Get a list of albums for the given artist."""
         if not prov_artist_id.startswith(FAKE_ARTIST_PREFIX):
             plex_artist = await self._get_data(prov_artist_id, PlexArtist)
-            plex_albums = cast(list[PlexAlbum], await self._run_async(plex_artist.albums))
+            plex_albums = cast("list[PlexAlbum]", await self._run_async(plex_artist.albums))
             if plex_albums:
                 albums = []
                 for album_obj in plex_albums:
index 98850835ba58666a1fdcc91018ae3a9a5eddae85..0bd1645a9239efd3451bcfad3419a85e920cb226 100644 (file)
@@ -47,7 +47,7 @@ async def get_libraries(
                 auth_token,
                 session=session,
             )
-        for media_section in cast(list[PlexLibrarySection], plex_server.library.sections()):
+        for media_section in cast("list[PlexLibrarySection]", plex_server.library.sections()):
             if media_section.type != PlexMusicSection.TYPE:
                 continue
             # TODO: figure out what plex uses as stable id and use that instead of names
@@ -55,7 +55,7 @@ async def get_libraries(
         return all_libraries
 
     if cache := await mass.cache.get(cache_key, checksum=auth_token):
-        return cast(list[str], cache)
+        return cast("list[str]", cache)
 
     result = await asyncio.to_thread(_get_libraries)
     # use short expiration for in-memory cache
index bd3bb5a34c3c762ee70646f328535671e9f1edf9..78e2e3eff2eb55f8caafa0920523ff012e802f72 100644 (file)
@@ -191,7 +191,7 @@ class RadioBrowserProvider(MusicProvider):
         """Retrieve library/subscribed radio stations from the provider."""
         stored_radios = self.config.get_value(CONF_STORED_RADIOS)
         if TYPE_CHECKING:
-            stored_radios = cast(list[str], stored_radios)
+            stored_radios = cast("list[str]", stored_radios)
         for item in stored_radios:
             try:
                 yield await self.get_radio(item)
@@ -202,7 +202,7 @@ class RadioBrowserProvider(MusicProvider):
         """Add item to provider's library. Return true on success."""
         stored_radios = self.config.get_value(CONF_STORED_RADIOS)
         if TYPE_CHECKING:
-            stored_radios = cast(list[str], stored_radios)
+            stored_radios = cast("list[str]", stored_radios)
         if item.item_id in stored_radios:
             return False
         self.logger.debug("Adding radio %s to stored radios", item.item_id)
@@ -214,7 +214,7 @@ class RadioBrowserProvider(MusicProvider):
         """Remove item from provider's library. Return true on success."""
         stored_radios = self.config.get_value(CONF_STORED_RADIOS)
         if TYPE_CHECKING:
-            stored_radios = cast(list[str], stored_radios)
+            stored_radios = cast("list[str]", stored_radios)
         if prov_item_id not in stored_radios:
             return False
         self.logger.debug("Removing radio %s from stored radios", prov_item_id)
index 7be2408816e5b50f5678fdc2411ca5789be02071..a2d98a16798b43217bab0be89715638af3d7d2a6 100644 (file)
@@ -168,7 +168,7 @@ class SiriusXMProvider(MusicProvider):
             bind_port=bind_port,
             base_url=self._base_url,
             static_routes=[
-                ("*", "/{tail:.*}", cast(Awaitable, http_handler)),
+                ("*", "/{tail:.*}", cast("Awaitable", http_handler)),
             ],
         )
 
index 16caf2f7cda726e1289128f428d328e02e1341b0..a880f0a0fdd5ee55ea30b0ae7b18793bbe1fe8f0 100644 (file)
@@ -28,7 +28,6 @@ from music_assistant_models.errors import SetupFailedError
 from music_assistant_models.media_items import AudioFormat
 from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
 from snapcast.control import create_server
-from snapcast.control.client import Snapclient
 from zeroconf import NonUniqueNameException
 from zeroconf.asyncio import AsyncServiceInfo
 
@@ -46,6 +45,7 @@ from music_assistant.models.player_provider import PlayerProvider
 if TYPE_CHECKING:
     from music_assistant_models.config_entries import ProviderConfig
     from music_assistant_models.provider import ProviderManifest
+    from snapcast.control.client import Snapclient
     from snapcast.control.group import Snapgroup
     from snapcast.control.server import Snapserver
     from snapcast.control.stream import Snapstream
@@ -384,7 +384,7 @@ class SnapCastProvider(PlayerProvider):
         player = self.mass.players.get(player_id, raise_unavailable=False)
         if not player:
             snap_client = cast(
-                Snapclient, self._snapserver.client(self._get_snapclient_id(player_id))
+                "Snapclient", self._snapserver.client(self._get_snapclient_id(player_id))
             )
             player = Player(
                 player_id=player_id,
index 28218ae0cf771c38b8373821f47d0a77b6a0bef4..462d1d10eaa66a9c2a431d0f1fffe80ccef8567e 100644 (file)
@@ -360,7 +360,7 @@ class SonosPlayerProvider(PlayerProvider):
 
         # Handle config option for manual IP's
         manual_ip_config = cast(
-            list[str], self.config.get_value(CONF_ENTRY_MANUAL_DISCOVERY_IPS.key)
+            "list[str]", self.config.get_value(CONF_ENTRY_MANUAL_DISCOVERY_IPS.key)
         )
         for ip_address in manual_ip_config:
             try:
@@ -473,7 +473,7 @@ class SonosPlayerProvider(PlayerProvider):
 async def discover_household_ids(mass: MusicAssistant, prefer_s1: bool = True) -> list[str]:
     """Discover the HouseHold ID of S1 speaker(s) the network."""
     if cache := await mass.cache.get("sonos_household_ids"):
-        return cast(list[str], cache)
+        return cast("list[str]", cache)
     household_ids: list[str] = []
 
     def get_all_sonos_ips() -> set[SoCo]:
index 3df36273f7ac40949b65b9e92612f507c3f72fa0..506d30764c03d36f8324edf4cfebd56e5beb640c 100644 (file)
@@ -140,7 +140,7 @@ async def get_config_entries(
         import pkce
 
         code_verifier, code_challenge = pkce.generate_pkce_pair()
-        async with AuthenticationHelper(mass, cast(str, values["session_id"])) as auth_helper:
+        async with AuthenticationHelper(mass, cast("str", values["session_id"])) as auth_helper:
             params = {
                 "response_type": "code",
                 "client_id": values.get(CONF_CLIENT_ID) or app_var(2),
index 1db5a5a6ead6e4e51b1616c88001628e56162f74..f6c806ec5a4d1afe979a4fcc6972c02553b11554 100644 (file)
@@ -114,7 +114,7 @@ class SpotifyConnectProvider(PluginProvider):
     ) -> None:
         """Initialize MusicProvider."""
         super().__init__(mass, manifest, config)
-        self.mass_player_id = cast(str, self.config.get_value(CONF_MASS_PLAYER_ID))
+        self.mass_player_id = cast("str", self.config.get_value(CONF_MASS_PLAYER_ID))
         self.cache_dir = os.path.join(self.mass.cache_path, self.instance_id)
         self._librespot_bin: str | None = None
         self._stop_called: bool = False
index 1485dc81bb2276a6aac0abcfe907dd11616b830b..6729d05e9e154f3f35479f7887a64f54a0e213fe 100644 (file)
@@ -319,7 +319,7 @@ class AudioDbMetadataProvider(MetadataProvider):
         if not album.year:
             album.year = int(adb_album.get("intYearReleased", "0"))
         if album.album_type == AlbumType.UNKNOWN and adb_album.get("strReleaseFormat"):
-            releaseformat = cast(str, adb_album.get("strReleaseFormat"))
+            releaseformat = cast("str", adb_album.get("strReleaseFormat"))
             album.album_type = ALBUMTYPE_MAPPING.get(releaseformat, AlbumType.UNKNOWN)
         # update the artist mbid while at it
         for album_artist in album.artists:
@@ -403,7 +403,7 @@ class AudioDbMetadataProvider(MetadataProvider):
             self.mass.http_session.get(url, params=kwargs, ssl=False) as response,
         ):
             try:
-                result = cast(dict[str, Any], await response.json())
+                result = cast("dict[str, Any]", await response.json())
             except (
                 aiohttp.client_exceptions.ContentTypeError,
                 JSONDecodeError,
index 3ca5299714b0722cd4f0f98cb03d3e475f6236f1..59ac7bdbabdcdfbedddd9928016cdb77654f9719 100644 (file)
@@ -139,7 +139,9 @@ async def get_config_entries(
     assert values is not None
 
     if action == CONF_ACTION_START_PKCE_LOGIN:
-        async with ManualAuthenticationHelper(mass, cast(str, values["session_id"])) as auth_helper:
+        async with ManualAuthenticationHelper(
+            mass, cast("str", values["session_id"])
+        ) as auth_helper:
             quality = str(values.get(CONF_QUALITY))
             base64_session = await TidalAuthManager.generate_auth_url(auth_helper, quality)
             values[CONF_TEMP_SESSION] = base64_session
@@ -189,8 +191,10 @@ async def get_config_entries(
                 label=CONF_QUALITY,
                 required=True,
                 hidden=True,
-                value=cast(str, values.get(CONF_QUALITY) or TidalQualityEnum.HI_RES.value),
-                default_value=cast(str, values.get(CONF_QUALITY) or TidalQualityEnum.HI_RES.value),
+                value=cast("str", values.get(CONF_QUALITY) or TidalQualityEnum.HI_RES.value),
+                default_value=cast(
+                    "str", values.get(CONF_QUALITY) or TidalQualityEnum.HI_RES.value
+                ),
             ),
         )
     else:
@@ -203,7 +207,7 @@ async def get_config_entries(
                 description="HIGH_LOSSLESS = 16bit 44.1kHz, HI_RES = Up to 24bit 192kHz",
                 options=[ConfigValueOption(x.value, x.name) for x in TidalQualityEnum],
                 default_value=TidalQualityEnum.HI_RES.value,
-                value=cast(str, values.get(CONF_QUALITY)) if values else None,
+                value=cast("str", values.get(CONF_QUALITY)) if values else None,
             ),
             ConfigEntry(
                 key=LABEL_START_PKCE_LOGIN,
@@ -224,7 +228,7 @@ async def get_config_entries(
                 action=CONF_ACTION_START_PKCE_LOGIN,
                 depends_on=CONF_QUALITY,
                 action_label="Starts the auth process via PKCE on Tidal.com",
-                value=cast(str, values.get(CONF_TEMP_SESSION)) if values else None,
+                value=cast("str", values.get(CONF_TEMP_SESSION)) if values else None,
                 hidden=action == CONF_ACTION_START_PKCE_LOGIN,
             ),
             ConfigEntry(
@@ -233,7 +237,7 @@ async def get_config_entries(
                 label="Temporary session for Tidal",
                 hidden=True,
                 required=False,
-                value=cast(str, values.get(CONF_TEMP_SESSION)) if values else None,
+                value=cast("str", values.get(CONF_TEMP_SESSION)) if values else None,
             ),
             ConfigEntry(
                 key=LABEL_OOPS_URL,
@@ -250,7 +254,7 @@ async def get_config_entries(
                 " Tidal.com and being redirected to a page that prominently displays"
                 " 'Oops' at the top.",
                 depends_on=CONF_ACTION_START_PKCE_LOGIN,
-                value=cast(str, values.get(CONF_OOPS_URL)) if values else None,
+                value=cast("str", values.get(CONF_OOPS_URL)) if values else None,
                 hidden=action != CONF_ACTION_START_PKCE_LOGIN,
             ),
             ConfigEntry(
@@ -283,7 +287,7 @@ async def get_config_entries(
             label="Authentication token for Tidal",
             description="You need to link Music Assistant to your Tidal account.",
             hidden=True,
-            value=cast(str, values.get(CONF_AUTH_TOKEN)) if values else None,
+            value=cast("str", values.get(CONF_AUTH_TOKEN)) if values else None,
         ),
         ConfigEntry(
             key=CONF_REFRESH_TOKEN,
@@ -291,14 +295,14 @@ async def get_config_entries(
             label="Refresh token for Tidal",
             description="You need to link Music Assistant to your Tidal account.",
             hidden=True,
-            value=cast(str, values.get(CONF_REFRESH_TOKEN)) if values else None,
+            value=cast("str", values.get(CONF_REFRESH_TOKEN)) if values else None,
         ),
         ConfigEntry(
             key=CONF_EXPIRY_TIME,
             type=ConfigEntryType.STRING,
             label="Expiry time of auth token for Tidal",
             hidden=True,
-            value=cast(str, values.get(CONF_EXPIRY_TIME)) if values else None,
+            value=cast("str", values.get(CONF_EXPIRY_TIME)) if values else None,
         ),
         ConfigEntry(
             key=CONF_USER_ID,
@@ -306,7 +310,7 @@ async def get_config_entries(
             label="Your Tidal User ID",
             description="This is your unique Tidal user ID.",
             hidden=True,
-            value=cast(str, values.get(CONF_USER_ID)) if values else None,
+            value=cast("str", values.get(CONF_USER_ID)) if values else None,
         ),
     )
 
@@ -489,14 +493,14 @@ class TidalProvider(MusicProvider):
             # Use data parameter for form-encoded data
             async with self.mass.http_session.post(url, data=data, **kwargs) as response:
                 return cast(
-                    dict[str, Any],
+                    "dict[str, Any]",
                     await self._handle_response(response, return_etag=False),
                 )
         else:
             # Use json parameter for JSON data (default)
             async with self.mass.http_session.post(url, json=data, **kwargs) as response:
                 return cast(
-                    dict[str, Any],
+                    "dict[str, Any]",
                     await self._handle_response(response, return_etag=False),
                 )
 
@@ -510,7 +514,7 @@ class TidalProvider(MusicProvider):
 
         # For DELETE requests with a body, we need to use json parameter
         async with self.mass.http_session.delete(url, json=data, **kwargs) as response:
-            return cast(dict[str, Any], await self._handle_response(response, return_etag=False))
+            return cast("dict[str, Any]", await self._handle_response(response, return_etag=False))
 
     async def _handle_response(
         self, response: ClientResponse, return_etag: bool = False
index 10fb59eb90eb5fe08b4f35a8a71d42521c9c9752..76e355996d9bf8e186de9285d4d441c39916ce79 100644 (file)
@@ -53,7 +53,7 @@ test = [
   "pytest-cov==5.0.0",
   "syrupy==4.8.2",
   "tomli==2.2.1",
-  "ruff==0.9.6",
+  "ruff==0.11.2",
 ]
 
 [project.scripts]
@@ -181,6 +181,7 @@ ignore = [
   "EM102", # Just annoying, not really useful
   "FIX002", # Just annoying, not really useful
   "PLR2004", # Just annoying, not really useful
+  "PGH004", # Just annoying, not really useful
   "PD011", # Just annoying, not really useful
   "S101", # assert is often used to satisfy type checking
   "TC001", # Just annoying, not really useful
index 89519a36f9dbfa50df85a12fc5c0f39909fe1f77..57c4491fb23943593f01391fcb6434be4c74bc4f 100644 (file)
@@ -26,12 +26,12 @@ def gather_requirements_from_manifests() -> list[str]:
     """Gather all of the requirements from provider manifests."""
     dependencies: list[str] = []
     providers_path = "music_assistant/providers"
-    for dir_str in os.listdir(providers_path):
+    for dir_str in os.listdir(providers_path):  # noqa: PTH208, RUF100
         dir_path = os.path.join(providers_path, dir_str)
         if not os.path.isdir(dir_path):
             continue
         # get files in subdirectory
-        for file_str in os.listdir(dir_path):
+        for file_str in os.listdir(dir_path):  # noqa: PTH208, RUF100
             file_path = os.path.join(dir_path, file_str)
             if not os.path.isfile(file_path):
                 continue