From 5ab115c145cb7c6f66d3a3c93b3792546507c56f Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 11 Feb 2021 09:51:09 +1000 Subject: [PATCH] convert some pylib strings to f-strings with flynt excluded some changes where readability got noticeably worse --- pylib/anki/cards.py | 2 +- pylib/anki/collection.py | 10 +++++----- pylib/anki/decks.py | 10 +++++----- pylib/anki/errors.py | 2 +- pylib/anki/importing/anki2.py | 4 ++-- pylib/anki/importing/apkg.py | 2 +- pylib/anki/importing/csvfile.py | 2 +- pylib/anki/importing/noteimp.py | 2 +- pylib/anki/latex.py | 12 ++++++------ pylib/anki/media.py | 2 +- pylib/anki/models.py | 4 ++-- pylib/anki/sched.py | 4 ++-- pylib/anki/schedv2.py | 4 ++-- pylib/anki/tags.py | 8 ++++---- pylib/anki/template.py | 2 +- pylib/anki/utils.py | 12 ++++++------ 16 files changed, 41 insertions(+), 41 deletions(-) diff --git a/pylib/anki/cards.py b/pylib/anki/cards.py index 9b5068b45..bfb4a937b 100644 --- a/pylib/anki/cards.py +++ b/pylib/anki/cards.py @@ -123,7 +123,7 @@ class Card: # legacy def css(self) -> str: - return "" % self.render_output().css + return f"" def render_output( self, reload: bool = False, browser: bool = False diff --git a/pylib/anki/collection.py b/pylib/anki/collection.py index d909832a7..b493835aa 100644 --- a/pylib/anki/collection.py +++ b/pylib/anki/collection.py @@ -329,7 +329,7 @@ class Collection: ########################################################################## def nextID(self, type: str, inc: bool = True) -> Any: - type = "next" + type.capitalize() + type = f"next{type.capitalize()}" id = self.conf.get(type, 1) if inc: self.conf[type] = id + 1 @@ -368,7 +368,7 @@ class Collection: def remove_notes_by_card(self, card_ids: List[int]) -> None: if hooks.notes_will_be_deleted.count(): nids = self.db.list( - "select nid from cards where id in " + ids2str(card_ids) + f"select nid from cards where id in {ids2str(card_ids)}" ) hooks.notes_will_be_deleted(self, nids) self._backend.remove_notes(note_ids=[], card_ids=card_ids) @@ -503,7 +503,7 @@ class Collection: return fields[mid] for nid, mid, flds in self.db.all( - "select id, mid, flds from notes where id in " + ids2str(nids) + f"select id, mid, flds from notes where id in {ids2str(nids)}" ): flds = splitFields(flds) ord = ordForMid(mid) @@ -794,7 +794,7 @@ table.review-log {{ {revlog_style} }} fn, ", ".join([customRepr(x) for x in args]), ) - self._logHnd.write(buf + "\n") + self._logHnd.write(f"{buf}\n") if devMode: print(buf) @@ -803,7 +803,7 @@ table.review-log {{ {revlog_style} }} return lpath = re.sub(r"\.anki2$", ".log", self.path) if os.path.exists(lpath) and os.path.getsize(lpath) > 10 * 1024 * 1024: - lpath2 = lpath + ".old" + lpath2 = f"{lpath}.old" if os.path.exists(lpath2): os.unlink(lpath2) os.rename(lpath, lpath2) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index fdbe4d892..17efb366e 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -385,7 +385,7 @@ class DeckManager: def setDeck(self, cids: List[int], did: int) -> None: self.col.db.execute( - "update cards set did=?,usn=?,mod=? where id in " + ids2str(cids), + f"update cards set did=?,usn=?,mod=? where id in {ids2str(cids)}", did, self.col.usn(), intTime(), @@ -397,7 +397,7 @@ class DeckManager: dids = [did] for name, id in self.children(did): dids.append(id) - return self.col.db.list("select id from cards where did in " + ids2str(dids)) + return self.col.db.list(f"select id from cards where did in {ids2str(dids)}") def for_card_ids(self, cids: List[int]) -> List[int]: return self.col.db.list(f"select did from cards where id in {ids2str(cids)}") @@ -465,12 +465,12 @@ class DeckManager: name = self.get(did)["name"] actv = [] for g in self.all_names_and_ids(): - if g.name.startswith(name + "::"): + if g.name.startswith(f"{name}::"): actv.append((g.name, g.id)) return actv def child_ids(self, parent_name: str) -> Iterable[int]: - prefix = parent_name + "::" + prefix = f"{parent_name}::" return (d.id for d in self.all_names_and_ids() if d.name.startswith(prefix)) def deck_and_child_ids(self, deck_id: int) -> List[int]: @@ -519,7 +519,7 @@ class DeckManager: if not parents_names: parents_names.append(part) else: - parents_names.append(parents_names[-1] + "::" + part) + parents_names.append(f"{parents_names[-1]}::{part}") parents: List[Deck] = [] # convert to objects for parent_name in parents_names: diff --git a/pylib/anki/errors.py b/pylib/anki/errors.py index 955d6009f..0fd0a5abb 100644 --- a/pylib/anki/errors.py +++ b/pylib/anki/errors.py @@ -103,4 +103,4 @@ class DeckRenameError(Exception): self.description = description def __str__(self) -> str: - return "Couldn't rename deck: " + self.description + return f"Couldn't rename deck: {self.description}" diff --git a/pylib/anki/importing/anki2.py b/pylib/anki/importing/anki2.py index c0de3e3a0..df4e9bb39 100644 --- a/pylib/anki/importing/anki2.py +++ b/pylib/anki/importing/anki2.py @@ -265,7 +265,7 @@ class Anki2Importer(Importer): tmpname = "::".join(DeckManager.path(name)[1:]) name = self.deckPrefix if tmpname: - name += "::" + tmpname + name += f"::{tmpname}" # manually create any parents so we can pull in descriptions head = "" for parent in DeckManager.immediate_parent_path(name): @@ -441,7 +441,7 @@ insert or ignore into revlog values (?,?,?,?,?,?,?,?,?)""", return match.group(0) # if model-local file exists from a previous import, use that name, ext = os.path.splitext(fname) - lname = "%s_%s%s" % (name, mid, ext) + lname = f"{name}_{mid}{ext}" if self.dst.media.have(lname): return match.group(0).replace(fname, lname) # if missing or the same, pass unmodified diff --git a/pylib/anki/importing/apkg.py b/pylib/anki/importing/apkg.py index 36801aa4c..4c574c44d 100644 --- a/pylib/anki/importing/apkg.py +++ b/pylib/anki/importing/apkg.py @@ -25,7 +25,7 @@ class AnkiPackageImporter(Anki2Importer): except KeyError: suffix = ".anki2" - col = z.read("collection" + suffix) + col = z.read(f"collection{suffix}") colpath = tmpfile(suffix=".anki2") with open(colpath, "wb") as f: f.write(col) diff --git a/pylib/anki/importing/csvfile.py b/pylib/anki/importing/csvfile.py index bcf3b5fe9..e4595a377 100644 --- a/pylib/anki/importing/csvfile.py +++ b/pylib/anki/importing/csvfile.py @@ -78,7 +78,7 @@ class TextImporter(NoteImporter): return re.sub(r"^\#.*$", "__comment", s) self.data = [ - sub(x) + "\n" for x in self.data.split("\n") if sub(x) != "__comment" + f"{sub(x)}\n" for x in self.data.split("\n") if sub(x) != "__comment" ] if self.data: if self.data[0].startswith("tags:"): diff --git a/pylib/anki/importing/noteimp.py b/pylib/anki/importing/noteimp.py index e3617330b..7095a6408 100644 --- a/pylib/anki/importing/noteimp.py +++ b/pylib/anki/importing/noteimp.py @@ -229,7 +229,7 @@ class NoteImporter(Importer): else: unchanged = 0 part3 = self.col.tr(TR.IMPORTING_NOTE_UNCHANGED, count=unchanged) - self.log.append("%s, %s, %s." % (part1, part2, part3)) + self.log.append(f"{part1}, {part2}, {part3}.") self.log.extend(updateLog) self.total = len(self._ids) diff --git a/pylib/anki/latex.py b/pylib/anki/latex.py index 486331406..cfbf6734b 100644 --- a/pylib/anki/latex.py +++ b/pylib/anki/latex.py @@ -111,7 +111,7 @@ def _save_latex_image( svg: bool, ) -> Optional[str]: # add header/footer - latex = header + "\n" + extracted.latex_body + "\n" + footer + latex = f"{header}\n{extracted.latex_body}\n{footer}" # it's only really secure if run in a jail, but these are the most common tmplatex = latex.replace("\\includegraphics", "") for bad in ( @@ -127,7 +127,7 @@ def _save_latex_image( "\\shipout", ): # don't mind if the sequence is only part of a command - bad_re = "\\" + bad + "[^a-zA-Z]" + bad_re = f"\\{bad}[^a-zA-Z]" if re.search(bad_re, tmplatex): return col.tr(TR.MEDIA_FOR_SECURITY_REASONS_IS_NOT, val=bad) @@ -146,7 +146,7 @@ def _save_latex_image( texfile.write(latex) texfile.close() oldcwd = os.getcwd() - png_or_svg = namedtmp("tmp.%s" % ext) + png_or_svg = namedtmp(f"tmp.{ext}") try: # generate png/svg os.chdir(tmpdir()) @@ -165,14 +165,14 @@ def _save_latex_image( def _errMsg(col: anki.collection.Collection, type: str, texpath: str) -> Any: - msg = col.tr(TR.MEDIA_ERROR_EXECUTING, val=type) + "
" - msg += col.tr(TR.MEDIA_GENERATED_FILE, val=texpath) + "
" + msg = f"{col.tr(TR.MEDIA_ERROR_EXECUTING, val=type)}
" + msg += f"{col.tr(TR.MEDIA_GENERATED_FILE, val=texpath)}
" try: with open(namedtmp("latex_log.txt", rm=False)) as f: log = f.read() if not log: raise Exception() - msg += "
" + html.escape(log) + "
" + msg += f"
{html.escape(log)}
" except: msg += col.tr(TR.MEDIA_HAVE_YOU_INSTALLED_LATEX_AND_DVIPNGDVISVGM) return msg diff --git a/pylib/anki/media.py b/pylib/anki/media.py index c9b3b293e..3becaf196 100644 --- a/pylib/anki/media.py +++ b/pylib/anki/media.py @@ -24,7 +24,7 @@ from anki.utils import intTime def media_paths_from_col_path(col_path: str) -> Tuple[str, str]: media_folder = re.sub(r"(?i)\.(anki2)$", ".media", col_path) - media_db = media_folder + ".db2" + media_db = f"{media_folder}.db2" return (media_folder, media_db) diff --git a/pylib/anki/models.py b/pylib/anki/models.py index e85641032..3b6a25222 100644 --- a/pylib/anki/models.py +++ b/pylib/anki/models.py @@ -440,7 +440,7 @@ and notes.mid = ? and cards.ord = ?""", d = [] nfields = len(newModel["flds"]) for (nid, flds) in self.col.db.execute( - "select id, flds from notes where id in " + ids2str(nids) + f"select id, flds from notes where id in {ids2str(nids)}" ): newflds = {} flds = splitFields(flds) @@ -473,7 +473,7 @@ and notes.mid = ? and cards.ord = ?""", d = [] deleted = [] for (cid, ord) in self.col.db.execute( - "select id, ord from cards where nid in " + ids2str(nids) + f"select id, ord from cards where nid in {ids2str(nids)}" ): # if the src model is a cloze, we ignore the map, as the gui # doesn't currently support mapping them diff --git a/pylib/anki/sched.py b/pylib/anki/sched.py index ad4967a64..7e98e9c6e 100644 --- a/pylib/anki/sched.py +++ b/pylib/anki/sched.py @@ -77,7 +77,7 @@ class Scheduler(V2): self._answerRevCard(card, ease) review_delta = +1 else: - raise Exception("Invalid queue '%s'" % card) + raise Exception(f"Invalid queue '{card}'") self.update_stats( card.did, @@ -374,7 +374,7 @@ limit %d""" def removeLrn(self, ids: Optional[List[int]] = None) -> None: "Remove cards from the learning queues." if ids: - extra = " and id in " + ids2str(ids) + extra = f" and id in {ids2str(ids)}" else: # benchmarks indicate it's about 10x faster to search all decks # with the index than scan the table diff --git a/pylib/anki/schedv2.py b/pylib/anki/schedv2.py index c2f5cdd72..8aa18459c 100644 --- a/pylib/anki/schedv2.py +++ b/pylib/anki/schedv2.py @@ -118,7 +118,7 @@ class Scheduler: self._answerRevCard(card, ease) review_delta = +1 else: - raise Exception("Invalid queue '%s'" % card) + raise Exception(f"Invalid queue '{card}'") self.update_stats( card.did, @@ -1120,7 +1120,7 @@ due = (case when odue>0 then odue else due end), odue = 0, odid = 0, usn = ? whe ) def remFromDyn(self, cids: List[int]) -> None: - self.emptyDyn(None, "id in %s and odid" % ids2str(cids)) + self.emptyDyn(None, f"id in {ids2str(cids)} and odid") # Leeches ########################################################################## diff --git a/pylib/anki/tags.py b/pylib/anki/tags.py index ec12cbf37..686cd6ad7 100644 --- a/pylib/anki/tags.py +++ b/pylib/anki/tags.py @@ -58,13 +58,13 @@ class TagManager: def byDeck(self, did: int, children: bool = False) -> List[str]: basequery = "select n.tags from cards c, notes n WHERE c.nid = n.id" if not children: - query = basequery + " AND c.did=?" + query = f"{basequery} AND c.did=?" res = self.col.db.list(query, did) return list(set(self.split(" ".join(res)))) dids = [did] for name, id in self.col.decks.children(did): dids.append(id) - query = basequery + " AND c.did IN " + ids2str(dids) + query = f"{basequery} AND c.did IN {ids2str(dids)}" res = self.col.db.list(query) return list(set(self.split(" ".join(res)))) @@ -127,7 +127,7 @@ class TagManager: "Join tags into a single string, with leading and trailing spaces." if not tags: return "" - return " %s " % " ".join(tags) + return f" {' '.join(tags)} " def addToStr(self, addtags: str, tags: str) -> str: "Add tags if they don't exist, and canonify." @@ -142,7 +142,7 @@ class TagManager: def wildcard(pat: str, repl: str) -> Match: pat = re.escape(pat).replace("\\*", ".*") - return re.match("^" + pat + "$", repl, re.IGNORECASE) + return re.match(f"^{pat}$", repl, re.IGNORECASE) currentTags = self.split(tags) for tag in self.split(deltags): diff --git a/pylib/anki/template.py b/pylib/anki/template.py index 253e4a50b..94fd00a21 100644 --- a/pylib/anki/template.py +++ b/pylib/anki/template.py @@ -306,7 +306,7 @@ def apply_custom_filters( ) # legacy hook - the second and fifth argument are no longer used. field_text = anki.hooks.runFilter( - "fmod_" + filter_name, + f"fmod_{filter_name}", field_text, "", ctx.note().items(), diff --git a/pylib/anki/utils.py b/pylib/anki/utils.py index 69853de7b..330797c0f 100644 --- a/pylib/anki/utils.py +++ b/pylib/anki/utils.py @@ -141,7 +141,7 @@ def timestampID(db: DBProxy, table: str) -> int: # be careful not to create multiple objects without flushing them, or they # may share an ID. t = intTime(1000) - while db.scalar("select id from %s where id = ?" % table, t): + while db.scalar(f"select id from {table} where id = ?", t): t += 1 return t @@ -150,7 +150,7 @@ def maxID(db: DBProxy) -> int: "Return the first safe ID to use." now = intTime(1000) for tbl in "cards", "notes": - now = max(now, db.scalar("select max(id) from %s" % tbl) or 0) + now = max(now, db.scalar(f"select max(id) from {tbl}") or 0) return now + 1 @@ -326,14 +326,14 @@ def platDesc() -> str: try: system = platform.system() if isMac: - theos = "mac:%s" % (platform.mac_ver()[0]) + theos = f"mac:{platform.mac_ver()[0]}" elif isWin: - theos = "win:%s" % (platform.win32_ver()[0]) + theos = f"win:{platform.win32_ver()[0]}" elif system == "Linux": import distro # pytype: disable=import-error # pylint: disable=import-error r = distro.linux_distribution(full_distribution_name=False) - theos = "lin:%s:%s" % (r[0], r[1]) + theos = f"lin:{r[0]}:{r[1]}" else: theos = system break @@ -365,7 +365,7 @@ class TimedLog: def versionWithBuild() -> str: from anki.buildinfo import buildhash, version - return "%s (%s)" % (version, buildhash) + return f"{version} ({buildhash})" def pointVersion() -> int: