mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 00:24:25 +01:00
Replace percent formatting
This commit is contained in:
parent
4a361bd501
commit
9352a79e41
25 changed files with 70 additions and 93 deletions
|
|
@ -78,9 +78,9 @@ def string_dist(str1: str | None, str2: str | None) -> float:
|
|||
# example, "the something" should be considered equal to
|
||||
# "something, the".
|
||||
for word in SD_END_WORDS:
|
||||
if str1.endswith(", %s" % word):
|
||||
if str1.endswith(f", {word}"):
|
||||
str1 = f"{word} {str1[: -len(word) - 2]}"
|
||||
if str2.endswith(", %s" % word):
|
||||
if str2.endswith(f", {word}"):
|
||||
str2 = f"{word} {str2[: -len(word) - 2]}"
|
||||
|
||||
# Perform a couple of basic normalizing substitutions.
|
||||
|
|
@ -444,7 +444,7 @@ def distance(
|
|||
# Preferred media options.
|
||||
media_patterns: Sequence[str] = preferred_config["media"].as_str_seq()
|
||||
options = [
|
||||
re.compile(r"(\d+x)?(%s)" % pat, re.I) for pat in media_patterns
|
||||
re.compile(rf"(\d+x)?({pat})", re.I) for pat in media_patterns
|
||||
]
|
||||
if options:
|
||||
dist.add_priority("media", album_info.media, options)
|
||||
|
|
|
|||
|
|
@ -1158,7 +1158,7 @@ class Database:
|
|||
"""
|
||||
# Get current schema.
|
||||
with self.transaction() as tx:
|
||||
rows = tx.query("PRAGMA table_info(%s)" % table)
|
||||
rows = tx.query(f"PRAGMA table_info({table})")
|
||||
current_fields = {row[1] for row in rows}
|
||||
|
||||
field_names = set(fields.keys())
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ class Album(LibModel):
|
|||
"""
|
||||
item = self.items().get()
|
||||
if not item:
|
||||
raise ValueError("empty album for album id %d" % self.id)
|
||||
raise ValueError(f"empty album for album id {self.id}")
|
||||
return os.path.dirname(item.path)
|
||||
|
||||
def _albumtotal(self):
|
||||
|
|
|
|||
|
|
@ -831,8 +831,8 @@ class AutotagStub:
|
|||
|
||||
def _make_track_match(self, artist, album, number):
|
||||
return TrackInfo(
|
||||
title="Applied Track %d" % number,
|
||||
track_id="match %d" % number,
|
||||
title=f"Applied Track {number}",
|
||||
track_id=f"match {number}",
|
||||
artist=artist,
|
||||
length=1,
|
||||
index=0,
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ def input_options(
|
|||
)
|
||||
):
|
||||
# The first option is the default; mark it.
|
||||
show_letter = "[%s]" % found_letter.upper()
|
||||
show_letter = f"[{found_letter.upper()}]"
|
||||
is_default = True
|
||||
else:
|
||||
show_letter = found_letter.upper()
|
||||
|
|
@ -308,9 +308,9 @@ def input_options(
|
|||
if isinstance(default, int):
|
||||
default_name = str(default)
|
||||
default_name = colorize("action_default", default_name)
|
||||
tmpl = "# selection (default %s)"
|
||||
prompt_parts.append(tmpl % default_name)
|
||||
prompt_part_lengths.append(len(tmpl % str(default)))
|
||||
tmpl = "# selection (default {})"
|
||||
prompt_parts.append(tmpl.format(default_name))
|
||||
prompt_part_lengths.append(len(tmpl) - 2 + len(str(default)))
|
||||
else:
|
||||
prompt_parts.append("# selection")
|
||||
prompt_part_lengths.append(len(prompt_parts[-1]))
|
||||
|
|
@ -349,7 +349,7 @@ def input_options(
|
|||
if not fallback_prompt:
|
||||
fallback_prompt = "Enter one of "
|
||||
if numrange:
|
||||
fallback_prompt += "%i-%i, " % numrange
|
||||
fallback_prompt += "{}-{}, ".format(*numrange)
|
||||
fallback_prompt += ", ".join(display_letters) + ":"
|
||||
|
||||
resp = input_(prompt)
|
||||
|
|
@ -406,7 +406,7 @@ def input_select_objects(prompt, objs, rep, prompt_all=None):
|
|||
objects individually.
|
||||
"""
|
||||
choice = input_options(
|
||||
("y", "n", "s"), False, "%s? (Yes/no/select)" % (prompt_all or prompt)
|
||||
("y", "n", "s"), False, f"{prompt_all or prompt}? (Yes/no/select)"
|
||||
)
|
||||
print() # Blank line.
|
||||
|
||||
|
|
@ -420,7 +420,7 @@ def input_select_objects(prompt, objs, rep, prompt_all=None):
|
|||
answer = input_options(
|
||||
("y", "n", "q"),
|
||||
True,
|
||||
"%s? (yes/no/quit)" % prompt,
|
||||
f"{prompt}? (yes/no/quit)",
|
||||
"Enter Y or N:",
|
||||
)
|
||||
if answer == "y":
|
||||
|
|
@ -534,7 +534,7 @@ def _colorize(color, text):
|
|||
# over all "ANSI codes" in `color`.
|
||||
escape = ""
|
||||
for code in color:
|
||||
escape = escape + COLOR_ESCAPE + "%im" % ANSI_CODES[code]
|
||||
escape = escape + COLOR_ESCAPE + f"{ANSI_CODES[code]}m"
|
||||
return escape + text + RESET_COLOR
|
||||
|
||||
|
||||
|
|
@ -1475,7 +1475,7 @@ class SubcommandsOptionParser(CommonOptionsParser):
|
|||
for subcommand in subcommands:
|
||||
name = subcommand.name
|
||||
if subcommand.aliases:
|
||||
name += " (%s)" % ", ".join(subcommand.aliases)
|
||||
name += f" ({', '.join(subcommand.aliases)})"
|
||||
disp_names.append(name)
|
||||
|
||||
# Set the help position based on the max width.
|
||||
|
|
@ -1488,26 +1488,18 @@ class SubcommandsOptionParser(CommonOptionsParser):
|
|||
# Lifted directly from optparse.py.
|
||||
name_width = help_position - formatter.current_indent - 2
|
||||
if len(name) > name_width:
|
||||
name = "%*s%s\n" % (formatter.current_indent, "", name)
|
||||
name = f"{' ' * formatter.current_indent}{name}\n"
|
||||
indent_first = help_position
|
||||
else:
|
||||
name = "%*s%-*s " % (
|
||||
formatter.current_indent,
|
||||
"",
|
||||
name_width,
|
||||
name,
|
||||
)
|
||||
name = f"{' ' * formatter.current_indent}{name:<{name_width}}\n"
|
||||
indent_first = 0
|
||||
result.append(name)
|
||||
help_width = formatter.width - help_position
|
||||
help_lines = textwrap.wrap(subcommand.help, help_width)
|
||||
help_line = help_lines[0] if help_lines else ""
|
||||
result.append("%*s%s\n" % (indent_first, "", help_line))
|
||||
result.append(f"{' ' * indent_first}{help_line}\n")
|
||||
result.extend(
|
||||
[
|
||||
"%*s%s\n" % (help_position, "", line)
|
||||
for line in help_lines[1:]
|
||||
]
|
||||
[f"{' ' * help_position}{line}\n" for line in help_lines[1:]]
|
||||
)
|
||||
formatter.dedent()
|
||||
|
||||
|
|
|
|||
|
|
@ -144,13 +144,13 @@ def fields_func(lib, opts, args):
|
|||
|
||||
with lib.transaction() as tx:
|
||||
# The SQL uses the DISTINCT to get unique values from the query
|
||||
unique_fields = "SELECT DISTINCT key FROM (%s)"
|
||||
unique_fields = "SELECT DISTINCT key FROM ({})"
|
||||
|
||||
print_("Item flexible attributes:")
|
||||
_print_keys(tx.query(unique_fields % library.Item._flex_table))
|
||||
_print_keys(tx.query(unique_fields.format(library.Item._flex_table)))
|
||||
|
||||
print_("Album flexible attributes:")
|
||||
_print_keys(tx.query(unique_fields % library.Album._flex_table))
|
||||
_print_keys(tx.query(unique_fields.format(library.Album._flex_table)))
|
||||
|
||||
|
||||
fields_cmd = ui.Subcommand(
|
||||
|
|
@ -1926,7 +1926,7 @@ default_commands.append(stats_cmd)
|
|||
|
||||
|
||||
def show_version(lib, opts, args):
|
||||
print_("beets version %s" % beets.__version__)
|
||||
print_(f"beets version {beets.__version__}")
|
||||
print_(f"Python version {python_version()}")
|
||||
# Show plugins.
|
||||
names = sorted(p.name for p in plugins.find_plugins())
|
||||
|
|
@ -1990,7 +1990,7 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm, inherit):
|
|||
extra = ""
|
||||
|
||||
changed = ui.input_select_objects(
|
||||
"Really modify%s" % extra,
|
||||
f"Really modify{extra}",
|
||||
changed,
|
||||
lambda o: print_and_modify(o, mods, dels),
|
||||
)
|
||||
|
|
@ -2168,7 +2168,7 @@ def move_items(
|
|||
else:
|
||||
if confirm:
|
||||
objs = ui.input_select_objects(
|
||||
"Really %s" % act,
|
||||
f"Really {act}",
|
||||
objs,
|
||||
lambda o: show_path_changes(
|
||||
[(o.path, o.destination(basedir=dest))]
|
||||
|
|
@ -2461,22 +2461,18 @@ def completion_script(commands):
|
|||
yield "_beet() {\n"
|
||||
|
||||
# Command names
|
||||
yield " local commands='%s'\n" % " ".join(command_names)
|
||||
yield f" local commands={' '.join(command_names)!r}\n"
|
||||
yield "\n"
|
||||
|
||||
# Command aliases
|
||||
yield " local aliases='%s'\n" % " ".join(aliases.keys())
|
||||
yield f" local aliases={' '.join(aliases.keys())!r}\n"
|
||||
for alias, cmd in aliases.items():
|
||||
yield f" local alias__{alias.replace('-', '_')}={cmd}\n"
|
||||
yield "\n"
|
||||
|
||||
# Fields
|
||||
yield " fields='%s'\n" % " ".join(
|
||||
set(
|
||||
list(library.Item._fields.keys())
|
||||
+ list(library.Album._fields.keys())
|
||||
)
|
||||
)
|
||||
fields = library.Item._fields.keys() | library.Album._fields.keys()
|
||||
yield f" fields={' '.join(fields)!r}\n"
|
||||
|
||||
# Command options
|
||||
for cmd, opts in options.items():
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ def spawn(coro):
|
|||
and child coroutines run concurrently.
|
||||
"""
|
||||
if not isinstance(coro, types.GeneratorType):
|
||||
raise ValueError("%s is not a coroutine" % coro)
|
||||
raise ValueError(f"{coro} is not a coroutine")
|
||||
return SpawnEvent(coro)
|
||||
|
||||
|
||||
|
|
@ -569,7 +569,7 @@ def call(coro):
|
|||
returns a value using end(), then this event returns that value.
|
||||
"""
|
||||
if not isinstance(coro, types.GeneratorType):
|
||||
raise ValueError("%s is not a coroutine" % coro)
|
||||
raise ValueError(f"{coro} is not a coroutine")
|
||||
return DelegationEvent(coro)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class Symbol:
|
|||
self.original = original
|
||||
|
||||
def __repr__(self):
|
||||
return "Symbol(%s)" % repr(self.ident)
|
||||
return f"Symbol({self.ident!r})"
|
||||
|
||||
def evaluate(self, env):
|
||||
"""Evaluate the symbol in the environment, returning a Unicode
|
||||
|
|
@ -178,7 +178,7 @@ class Call:
|
|||
except Exception as exc:
|
||||
# Function raised exception! Maybe inlining the name of
|
||||
# the exception will help debug.
|
||||
return "<%s>" % str(exc)
|
||||
return f"<{exc}>"
|
||||
return str(out)
|
||||
else:
|
||||
return self.original
|
||||
|
|
@ -224,7 +224,7 @@ class Expression:
|
|||
self.parts = parts
|
||||
|
||||
def __repr__(self):
|
||||
return "Expression(%s)" % (repr(self.parts))
|
||||
return f"Expression({self.parts!r})"
|
||||
|
||||
def evaluate(self, env):
|
||||
"""Evaluate the entire expression in the environment, returning
|
||||
|
|
@ -296,9 +296,6 @@ class Parser:
|
|||
GROUP_CLOSE,
|
||||
ESCAPE_CHAR,
|
||||
)
|
||||
special_char_re = re.compile(
|
||||
r"[%s]|\Z" % "".join(re.escape(c) for c in special_chars)
|
||||
)
|
||||
escapable_chars = (SYMBOL_DELIM, FUNC_DELIM, GROUP_CLOSE, ARG_SEP)
|
||||
terminator_chars = (GROUP_CLOSE,)
|
||||
|
||||
|
|
@ -310,16 +307,10 @@ class Parser:
|
|||
"""
|
||||
# Append comma (ARG_SEP) to the list of special characters only when
|
||||
# parsing function arguments.
|
||||
extra_special_chars = ()
|
||||
special_char_re = self.special_char_re
|
||||
if self.in_argument:
|
||||
extra_special_chars = (ARG_SEP,)
|
||||
extra_special_chars = (ARG_SEP,) if self.in_argument else ()
|
||||
special_chars = (*self.special_chars, *extra_special_chars)
|
||||
special_char_re = re.compile(
|
||||
r"[%s]|\Z"
|
||||
% "".join(
|
||||
re.escape(c)
|
||||
for c in self.special_chars + extra_special_chars
|
||||
)
|
||||
rf"[{''.join(map(re.escape, special_chars))}]|\Z"
|
||||
)
|
||||
|
||||
text_parts = []
|
||||
|
|
@ -327,7 +318,7 @@ class Parser:
|
|||
while self.pos < len(self.string):
|
||||
char = self.string[self.pos]
|
||||
|
||||
if char not in self.special_chars + extra_special_chars:
|
||||
if char not in special_chars:
|
||||
# A non-special character. Skip to the next special
|
||||
# character, treating the interstice as literal text.
|
||||
next_pos = (
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ def human_seconds_short(interval):
|
|||
string.
|
||||
"""
|
||||
interval = int(interval)
|
||||
return "%i:%02i" % (interval // 60, interval % 60)
|
||||
return f"{interval // 60}:{interval % 60:02d}"
|
||||
|
||||
|
||||
def human_bytes(size):
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ except ImportError as e:
|
|||
PROTOCOL_VERSION = "0.16.0"
|
||||
BUFSIZE = 1024
|
||||
|
||||
HELLO = "OK MPD %s" % PROTOCOL_VERSION
|
||||
HELLO = f"OK MPD {PROTOCOL_VERSION}"
|
||||
CLIST_BEGIN = "command_list_begin"
|
||||
CLIST_VERBOSE_BEGIN = "command_list_ok_begin"
|
||||
CLIST_END = "command_list_end"
|
||||
|
|
@ -1219,7 +1219,7 @@ class Server(BaseServer):
|
|||
if dirpath.startswith("/"):
|
||||
# Strip leading slash (libmpc rejects this).
|
||||
dirpath = dirpath[1:]
|
||||
yield "directory: %s" % dirpath
|
||||
yield f"directory: {dirpath}"
|
||||
|
||||
def _listall(self, basepath, node, info=False):
|
||||
"""Helper function for recursive listing. If info, show
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def span_from_str(span_str):
|
|||
def normalize_year(d, yearfrom):
|
||||
"""Convert string to a 4 digits year"""
|
||||
if yearfrom < 100:
|
||||
raise BucketError("%d must be expressed on 4 digits" % yearfrom)
|
||||
raise BucketError(f"{yearfrom} must be expressed on 4 digits")
|
||||
|
||||
# if two digits only, pick closest year that ends by these two
|
||||
# digits starting from yearfrom
|
||||
|
|
@ -55,14 +55,13 @@ def span_from_str(span_str):
|
|||
years = [int(x) for x in re.findall(r"\d+", span_str)]
|
||||
if not years:
|
||||
raise ui.UserError(
|
||||
"invalid range defined for year bucket '%s': no year found"
|
||||
% span_str
|
||||
f"invalid range defined for year bucket {span_str!r}: no year found"
|
||||
)
|
||||
try:
|
||||
years = [normalize_year(x, years[0]) for x in years]
|
||||
except BucketError as exc:
|
||||
raise ui.UserError(
|
||||
"invalid range defined for year bucket '%s': %s" % (span_str, exc)
|
||||
f"invalid range defined for year bucket {span_str!r}: {exc}"
|
||||
)
|
||||
|
||||
res = {"from": years[0], "str": span_str}
|
||||
|
|
@ -126,18 +125,18 @@ def str2fmt(s):
|
|||
"tonchars": len(m.group("toyear")),
|
||||
}
|
||||
res["fmt"] = (
|
||||
f"{m['bef']}%s{m['sep']}{'%s' if res['tonchars'] else ''}{m['after']}"
|
||||
f"{m['bef']}{{}}{m['sep']}{'{}' if res['tonchars'] else ''}{m['after']}"
|
||||
)
|
||||
return res
|
||||
|
||||
|
||||
def format_span(fmt, yearfrom, yearto, fromnchars, tonchars):
|
||||
"""Return a span string representation."""
|
||||
args = str(yearfrom)[-fromnchars:]
|
||||
args = [str(yearfrom)[-fromnchars:]]
|
||||
if tonchars:
|
||||
args = (str(yearfrom)[-fromnchars:], str(yearto)[-tonchars:])
|
||||
args.append(str(yearto)[-tonchars:])
|
||||
|
||||
return fmt % args
|
||||
return fmt.format(*args)
|
||||
|
||||
|
||||
def extract_modes(spans):
|
||||
|
|
@ -166,7 +165,7 @@ def build_alpha_spans(alpha_spans_str, alpha_regexs):
|
|||
else:
|
||||
raise ui.UserError(
|
||||
"invalid range defined for alpha bucket "
|
||||
"'%s': no alphanumeric character found" % elem
|
||||
f"'{elem}': no alphanumeric character found"
|
||||
)
|
||||
spans.append(
|
||||
re.compile(
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ class CoverArtArchive(RemoteArtSource):
|
|||
class Amazon(RemoteArtSource):
|
||||
NAME = "Amazon"
|
||||
ID = "amazon"
|
||||
URL = "https://images.amazon.com/images/P/%s.%02i.LZZZZZZZ.jpg"
|
||||
URL = "https://images.amazon.com/images/P/{}.{:02d}.LZZZZZZZ.jpg"
|
||||
INDICES = (1, 2)
|
||||
|
||||
def get(
|
||||
|
|
@ -606,7 +606,7 @@ class Amazon(RemoteArtSource):
|
|||
if album.asin:
|
||||
for index in self.INDICES:
|
||||
yield self._candidate(
|
||||
url=self.URL % (album.asin, index),
|
||||
url=self.URL.format(album.asin, index),
|
||||
match=MetadataMatch.EXACT,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@ class InlineError(Exception):
|
|||
|
||||
def __init__(self, code, exc):
|
||||
super().__init__(
|
||||
("error in inline path field code:\n%s\n%s: %s")
|
||||
% (code, type(exc).__name__, str(exc))
|
||||
f"error in inline path field code:\n{code}\n{type(exc).__name__}: {exc}"
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class Amarok(MetaSource):
|
|||
|
||||
query_xml = '<query version="1.0"> \
|
||||
<filters> \
|
||||
<and><include field="filename" value=%s /></and> \
|
||||
<and><include field="filename" value={} /></and> \
|
||||
</filters> \
|
||||
</query>'
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ class Amarok(MetaSource):
|
|||
# of the result set. So query for the filename and then try to match
|
||||
# the correct item from the results we get back
|
||||
results = self.collection.Query(
|
||||
self.query_xml % quoteattr(basename(path))
|
||||
self.query_xml.format(quoteattr(basename(path)))
|
||||
)
|
||||
for result in results:
|
||||
if result["xesam:url"] != path:
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class MPDUpdatePlugin(BeetsPlugin):
|
|||
return
|
||||
|
||||
if password:
|
||||
s.send(b'password "%s"\n' % password.encode("utf8"))
|
||||
s.send(f'password "{password}"\n'.encode())
|
||||
resp = s.readline()
|
||||
if b"OK" not in resp:
|
||||
self._log.warning("Authentication failed: {0!r}", resp)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class RewritePlugin(BeetsPlugin):
|
|||
raise ui.UserError("invalid rewrite specification")
|
||||
if fieldname not in library.Item._fields:
|
||||
raise ui.UserError(
|
||||
"invalid field name (%s) in rewriter" % fieldname
|
||||
f"invalid field name ({fieldname}) in rewriter"
|
||||
)
|
||||
self._log.debug("adding template field {0}", key)
|
||||
pattern = re.compile(pattern.lower())
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ def json_generator(items, root, expand=False):
|
|||
representation
|
||||
:returns: generator that yields strings
|
||||
"""
|
||||
yield '{"%s":[' % root
|
||||
yield f'{{"{root}":['
|
||||
first = True
|
||||
for item in items:
|
||||
if first:
|
||||
|
|
|
|||
|
|
@ -384,9 +384,9 @@ Here's an example that adds a ``$disc_and_track`` field:
|
|||
number.
|
||||
"""
|
||||
if item.disctotal > 1:
|
||||
return u'%02i.%02i' % (item.disc, item.track)
|
||||
return f"{item.disc:02d}.{item.track:02d}"
|
||||
else:
|
||||
return u'%02i' % (item.track)
|
||||
return f"{item.track:02d}"
|
||||
|
||||
With this plugin enabled, templates can reference ``$disc_and_track`` as they
|
||||
can any standard metadata field.
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ Here are a couple of examples of expressions:
|
|||
|
||||
item_fields:
|
||||
initial: albumartist[0].upper() + u'.'
|
||||
disc_and_track: u'%02i.%02i' % (disc, track) if
|
||||
disctotal > 1 else u'%02i' % (track)
|
||||
disc_and_track: f"{disc:02d}.{track:02d}" if disctotal > 1 else f"{track:02d}"
|
||||
|
||||
Note that YAML syntax allows newlines in values if the subsequent lines are
|
||||
indented.
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ select = [
|
|||
"PT", # flake8-pytest-style
|
||||
# "RUF", # ruff
|
||||
# "UP", # pyupgrade
|
||||
"UP031", # do not use percent formatting
|
||||
"UP032", # use f-string instead of format call
|
||||
"TCH", # flake8-type-checking
|
||||
"W", # pycodestyle
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class DGAlbumInfoTest(BeetsTestCase):
|
|||
"""Return a Bag that mimics a discogs_client.Release with a
|
||||
tracklist where tracks have the specified `positions`."""
|
||||
tracks = [
|
||||
self._make_track("TITLE%s" % i, position)
|
||||
self._make_track(f"TITLE{i}", position)
|
||||
for (i, position) in enumerate(positions, start=1)
|
||||
]
|
||||
return self._make_release(tracks)
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase):
|
|||
for recording in tracks:
|
||||
i += 1
|
||||
track = {
|
||||
"id": "RELEASE TRACK ID %d" % i,
|
||||
"id": f"RELEASE TRACK ID {i}",
|
||||
"recording": recording,
|
||||
"position": i,
|
||||
"number": "A1",
|
||||
|
|
@ -140,7 +140,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase):
|
|||
for recording in data_tracks:
|
||||
i += 1
|
||||
data_track = {
|
||||
"id": "RELEASE TRACK ID %d" % i,
|
||||
"id": f"RELEASE TRACK ID {i}",
|
||||
"recording": recording,
|
||||
"position": i,
|
||||
"number": "A1",
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ class TransactionTest(unittest.TestCase):
|
|||
def test_query_no_increase_revision(self):
|
||||
old_rev = self.db.revision
|
||||
with self.db.transaction() as tx:
|
||||
tx.query("PRAGMA table_info(%s)" % ModelFixture1._table)
|
||||
tx.query(f"PRAGMA table_info({ModelFixture1._table})")
|
||||
assert self.db.revision == old_rev
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1033,7 +1033,7 @@ class ArtDestinationTest(BeetsTestCase):
|
|||
|
||||
def test_art_filename_respects_setting(self):
|
||||
art = self.ai.art_destination("something.jpg")
|
||||
new_art = bytestring_path("%sartimage.jpg" % os.path.sep)
|
||||
new_art = bytestring_path(f"{os.path.sep}artimage.jpg")
|
||||
assert new_art in art
|
||||
|
||||
def test_art_path_in_item_dir(self):
|
||||
|
|
|
|||
|
|
@ -1020,7 +1020,7 @@ class ConfigTest(TestPluginTestCase):
|
|||
|
||||
def test_cli_config_file_loads_plugin_commands(self):
|
||||
with open(self.cli_config_path, "w") as file:
|
||||
file.write("pluginpath: %s\n" % _common.PLUGINPATH)
|
||||
file.write(f"pluginpath: {_common.PLUGINPATH}\n")
|
||||
file.write("plugins: test")
|
||||
|
||||
self.run_command("--config", self.cli_config_path, "plugin", lib=None)
|
||||
|
|
|
|||
Loading…
Reference in a new issue