Skip to content

Commit

Permalink
Migrate typing annotations to py39
Browse files Browse the repository at this point in the history
  • Loading branch information
snejus committed Nov 15, 2024
1 parent 59cd53b commit 39e5828
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 85 deletions.
11 changes: 6 additions & 5 deletions beetsplug/bandcamp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from functools import partial
from itertools import chain
from operator import itemgetter
from typing import TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Literal
from typing import TYPE_CHECKING, Any, Literal

from beets import IncludeLazyConfig, config, library, plugins

Expand All @@ -35,12 +35,13 @@
from .search import search_bandcamp

if TYPE_CHECKING:
from collections.abc import Iterable, Iterator
from beets.autotag.hooks import AlbumInfo, TrackInfo

JSONDict = Dict[str, Any]
JSONDict = dict[str, Any]
CandidateType = Literal["album", "track"]

DEFAULT_CONFIG: JSONDict = {
DEFAULT_CONFIG = {
"include_digital_only_tracks": True,
"search_max": 2,
"art": False,
Expand Down Expand Up @@ -224,7 +225,7 @@ def _find_url_in_item(
return ""

def candidates(
self, items: List[library.Item], artist: str, album: str, *_: Any, **__: Any
self, items: list[library.Item], artist: str, album: str, *_: Any, **__: Any
) -> Iterable[AlbumInfo]:
"""Return a sequence of album candidates matching given artist and album."""
item = items[0]
Expand Down Expand Up @@ -299,7 +300,7 @@ def track_for_id(self, track_id: str) -> TrackInfo | None:
self._info("Not a bandcamp URL, skipping")
return None

def get_album_info(self, url: str) -> List[AlbumInfo] | None:
def get_album_info(self, url: str) -> list[AlbumInfo] | None:
"""Return an AlbumInfo object for a bandcamp album page.
If track url is given by mistake, find and fetch the album url instead.
Expand Down
16 changes: 10 additions & 6 deletions beetsplug/bandcamp/album_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
import re
from dataclasses import dataclass
from functools import cached_property
from typing import Any, Dict, Iterable, List, Match, Optional
from re import Match
from typing import Any, Optional, TYPE_CHECKING

from .helpers import PATTERNS, Helpers

JSONDict = Dict[str, Any]
if TYPE_CHECKING:
from collections.abc import Iterable

JSONDict = dict[str, Any]


@dataclass
Expand Down Expand Up @@ -73,7 +77,7 @@ def from_title(self) -> Optional[str]:
return None

@cached_property
def album_names(self) -> List[str]:
def album_names(self) -> list[str]:
priority_list = [
self.from_track_titles,
self.from_description,
Expand Down Expand Up @@ -191,7 +195,7 @@ def remove_catalognum(cls, catalognum: str, *args) -> str:
def clean(
cls,
name: str,
artists: Optional[List[str]] = None,
artists: Optional[list[str]] = None,
catalognum: Optional[str] = None,
label: Optional[str] = None,
) -> str:
Expand Down Expand Up @@ -235,8 +239,8 @@ def check_eplp(self, album: str) -> str:
def get(
self,
catalognum: str,
original_artists: List[str],
artists: List[str],
original_artists: list[str],
artists: list[str],
label: str,
) -> str:
original_album = self.name
Expand Down
8 changes: 6 additions & 2 deletions beetsplug/bandcamp/catalognum.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
from dataclasses import dataclass
from functools import cached_property
from itertools import starmap
from typing import Callable, Generic, Iterable, Pattern, Tuple, TypeVar
from re import Pattern
from typing import Callable, Generic, TypeVar, TYPE_CHECKING

if TYPE_CHECKING:
from collections.abc import Iterable

T = TypeVar("T")

Expand Down Expand Up @@ -220,7 +224,7 @@ def search(self, pat: Pattern[str], string: str) -> str | None:
return None

def find(
self, patterns_and_texts: Iterable[Tuple[Pattern[str], str]]
self, patterns_and_texts: Iterable[tuple[Pattern[str], str]]
) -> str | None:
"""Try getting the catalog number using supplied pattern/string pairs."""

Expand Down
30 changes: 11 additions & 19 deletions beetsplug/bandcamp/helpers.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,27 @@
"""Module with a Helpers class that contains various static, independent functions."""

import re
from collections.abc import Iterable
from functools import lru_cache, partial
from itertools import chain
from operator import contains
from typing import (
Any,
Callable,
Dict,
Iterable,
List,
Match,
NamedTuple,
Pattern,
Tuple,
TypeVar,
Union,
)
from re import Match, Pattern
from typing import Any, Callable, NamedTuple, TypeVar, Union, TYPE_CHECKING

from beets import __version__ as beets_version
from beets.autotag.hooks import AlbumInfo
from ordered_set import OrderedSet as ordset # noqa: N813
from packaging.version import Version

from .genres_lookup import GENRES

if TYPE_CHECKING:
from beets.autotag.hooks import AlbumInfo

BEETS_VERSION = Version(beets_version)
ALBUMTYPES_LIST_SUPPORT = BEETS_VERSION >= Version("1.6.0")
ARTIST_LIST_FIELDS_SUPPORT = BEETS_VERSION >= Version("2.0.0")

JSONDict = Dict[str, Any]
JSONDict = dict[str, Any]
DIGI_MEDIA = "Digital Media"
USB_TYPE_ID = 5
FORMAT_TO_MEDIA = {
Expand Down Expand Up @@ -81,7 +73,7 @@ def medium_count(self) -> int:
return 1


PATTERNS: Dict[str, Pattern[str]] = {
PATTERNS: dict[str, Pattern[str]] = {
"split_artists": re.compile(r", - |, | (?:[x+/-]|//|vs|and)[.]? "),
"meta": re.compile(r'.*"@id".*'),
"ft": re.compile(
Expand Down Expand Up @@ -152,7 +144,7 @@ def split_artist_title(m: Match[str]) -> str:


# fmt: off
CLEAN_PATTERNS: List[Tuple[Pattern[str], Union[str, Callable[[Match[str]], str]]]] = [
CLEAN_PATTERNS: list[tuple[Pattern[str], Union[str, Callable[[Match[str]], str]]]] = [
(re.compile(rf"(([\[(])|(^| ))\*?({'|'.join(rm_strings)})(?(2)[])]|([- ]|$))", re.I), ""), # noqa
(re.compile(r" -(\S)"), r" - \1"), # hi -bye -> hi - bye # noqa
(re.compile(r"(\S)- "), r"\1 - "), # hi- bye -> hi - bye # noqa
Expand All @@ -173,7 +165,7 @@ def split_artist_title(m: Match[str]) -> str:

class Helpers:
@staticmethod
def split_artists(artists: Union[str, Iterable[str]]) -> List[str]:
def split_artists(artists: Union[str, Iterable[str]]) -> list[str]:
"""Split artists taking into account delimiters such as ',', '+', 'x', 'X'.
Note: featuring artists are removed since they are not main artists.
Expand Down Expand Up @@ -280,7 +272,7 @@ def unpack_props(obj: JSONDict) -> JSONDict:
return obj

@staticmethod
def get_media_formats(format_list: List[JSONDict]) -> List[MediaInfo]:
def get_media_formats(format_list: list[JSONDict]) -> list[MediaInfo]:
"""Return filtered Bandcamp media formats as a list of MediaInfo objects.
Formats are filtered using the following fields,
Expand Down
2 changes: 1 addition & 1 deletion beetsplug/bandcamp/http.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from functools import lru_cache
from html import unescape

from beets import __version__
import httpx
from beets import __version__

HTTPError = httpx.HTTPError

Expand Down
15 changes: 8 additions & 7 deletions beetsplug/bandcamp/metaguru.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import json
import operator as op
import re
from collections.abc import Iterable
from datetime import date, datetime
from functools import cached_property, partial
from typing import Any, Dict, Iterable, List, Optional, Set
from typing import Any, Optional
from unicodedata import normalize

from beets import config as beets_config
Expand All @@ -20,7 +21,7 @@
from .track import Track
from .tracks import Tracks

JSONDict = Dict[str, Any]
JSONDict = dict[str, Any]

COUNTRY_OVERRIDES = {
"Russia": "RU", # pycountry: Russian Federation
Expand All @@ -44,7 +45,7 @@ class Metaguru(Helpers):

meta: JSONDict
config: JSONDict
media_formats: List[MediaInfo]
media_formats: list[MediaInfo]
_tracks: Tracks
_album_name: AlbumName

Expand Down Expand Up @@ -83,7 +84,7 @@ def from_html(cls, html: str, config: Optional[JSONDict] = None) -> "Metaguru":
return cls(json.loads(meta), config)

@cached_property
def excluded_fields(self) -> Set[str]:
def excluded_fields(self) -> set[str]:
return set(self.config.get("exclude_extra_fields") or [])

@cached_property
Expand Down Expand Up @@ -238,7 +239,7 @@ def tracks(self) -> Tracks:
return self._tracks

@cached_property
def unique_artists(self) -> List[str]:
def unique_artists(self) -> list[str]:
return self.split_artists(self._tracks.artists)

@cached_property
Expand Down Expand Up @@ -358,7 +359,7 @@ def albumtype(self) -> str:
return "album"

@cached_property
def albumtypes(self) -> List[str]:
def albumtypes(self) -> list[str]:
albumtypes = {self.albumtype}
if self.is_comp:
if self.albumtype == "ep":
Expand Down Expand Up @@ -512,6 +513,6 @@ def get_media_album(self, media: MediaInfo) -> AlbumInfo:
return self.check_list_fields(album_info)

@cached_property
def albums(self) -> List[AlbumInfo]:
def albums(self) -> list[AlbumInfo]:
"""Return album for the appropriate release format."""
return list(map(self.get_media_album, self.media_formats))
30 changes: 15 additions & 15 deletions beetsplug/bandcamp/names.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from dataclasses import dataclass, field
from functools import cached_property, reduce
from os.path import commonprefix
from typing import List, Optional, Tuple
from typing import Optional

from ordered_set import OrderedSet

Expand All @@ -28,7 +28,7 @@ class Names:
album_artist: str
album_in_titles: Optional[str] = None
catalognum_in_titles: Optional[str] = None
titles: List[str] = field(default_factory=list)
titles: list[str] = field(default_factory=list)

@cached_property
def label(self) -> str:
Expand All @@ -44,7 +44,7 @@ def original_album(self) -> str:
return str(self.meta["name"])

@cached_property
def json_tracks(self) -> List[JSONDict]:
def json_tracks(self) -> list[JSONDict]:
try:
return [{**t, **t["item"]} for t in self.meta["track"]["itemListElement"]]
except KeyError as e:
Expand All @@ -56,7 +56,7 @@ def json_tracks(self) -> List[JSONDict]:
return []

@cached_property
def original_titles(self) -> List[str]:
def original_titles(self) -> list[str]:
return [i["name"] for i in self.json_tracks]

@cached_property
Expand All @@ -79,23 +79,23 @@ def common_prefix(self) -> str:
return commonprefix(self.titles)

@classmethod
def split_quoted_titles(cls, names: List[str]) -> List[str]:
def split_quoted_titles(cls, names: list[str]) -> list[str]:
if len(names) > 1:
matches = list(filter(None, map(cls.TITLE_IN_QUOTES.match, names)))
if len(matches) == len(names):
return [m.expand(r"\1 - \2") for m in matches]

return names

def remove_album_catalognum(self, names: List[str]) -> List[str]:
def remove_album_catalognum(self, names: list[str]) -> list[str]:
if catalognum := self.catalognum_in_album:
pat = re.compile(rf"(?i)[([]{re.escape(catalognum)}[])]")
return [pat.sub("", n) for n in names]

return names

@classmethod
def remove_number_prefix(cls, names: List[str]) -> List[str]:
def remove_number_prefix(cls, names: list[str]) -> list[str]:
"""Remove track number prefix from the track names.
If there is more than one track and at least half of the track names have
Expand All @@ -114,7 +114,7 @@ def remove_number_prefix(cls, names: List[str]) -> List[str]:
return names

@classmethod
def find_common_track_delimiter(cls, names: List[str]) -> str:
def find_common_track_delimiter(cls, names: list[str]) -> str:
"""Return the track parts delimiter that is in effect in the current release.
In some (rare) situations track parts are delimited by a pipe character
Expand All @@ -135,13 +135,13 @@ def find_common_track_delimiter(cls, names: List[str]) -> str:
return delim if (len(names) == 1 or count > len(names) / 2) else "-"

@classmethod
def normalize_delimiter(cls, names: List[str]) -> List[str]:
def normalize_delimiter(cls, names: list[str]) -> list[str]:
"""Ensure the same delimiter splits artist and title in all names."""
delim = cls.find_common_track_delimiter(names)
pat = re.compile(f" +{re.escape(delim)} +")
return [pat.sub(" - ", n) for n in names]

def remove_label(self, names: List[str]) -> List[str]:
def remove_label(self, names: list[str]) -> list[str]:
"""Remove label name from the end of track names.
See https://gutterfunkuk.bandcamp.com/album/gutterfunk-all-subject-to-vibes-various-artists-lp # noqa: E501
Expand All @@ -150,8 +150,8 @@ def remove_label(self, names: List[str]) -> List[str]:
return [remove_label.sub(" ", n).strip() for n in names]

def eject_common_catalognum(
self, names: List[str]
) -> Tuple[Optional[str], List[str]]:
self, names: list[str]
) -> tuple[Optional[str], list[str]]:
"""Return catalognum found in every track title.
1. Split each track name into words
Expand All @@ -173,7 +173,7 @@ def eject_common_catalognum(
return catalognum, names

@staticmethod
def parenthesize_remixes(names: List[str]) -> List[str]:
def parenthesize_remixes(names: list[str]) -> list[str]:
"""Reformat broken remix titles for an album with a single root title.
1. Check whether this release has a single root title
Expand All @@ -193,7 +193,7 @@ def parenthesize_remixes(names: List[str]) -> List[str]:
return names

@classmethod
def eject_album_name(cls, names: List[str]) -> Tuple[Optional[str], List[str]]:
def eject_album_name(cls, names: list[str]) -> tuple[Optional[str], list[str]]:
matches = list(map(cls.ALBUM_IN_TITLE.search, names))
albums = {m.group(1).replace('"', "") for m in matches if m}
if len(albums) != 1:
Expand All @@ -203,7 +203,7 @@ def eject_album_name(cls, names: List[str]) -> Tuple[Optional[str], List[str]]:
(n.replace(m.group(), "") if m else n) for m, n in zip(matches, names)
]

def ensure_artist_first(self, names: List[str]) -> List[str]:
def ensure_artist_first(self, names: list[str]) -> list[str]:
"""Ensure the artist is the first part of the track name."""
splits = [n.split(" - ", 1) for n in names]
if (
Expand Down
Loading

0 comments on commit 39e5828

Please sign in to comment.