conversion of remaining % format

This commit is contained in:
un-pogaz 2025-02-02 10:18:08 +01:00
parent 7cde6ce243
commit 75aff43417
34 changed files with 55 additions and 70 deletions

View File

@ -48,7 +48,6 @@ unfixable = ['PIE794', 'ISC001']
[tool.ruff.lint.per-file-ignores]
"recipes/*" = ['UP']
"setup/changelog.py" = ['ISC001']
"src/calibre/*" = ['UP031']
"src/calibre/ebooks/unihandecode/*codepoints.py" = ['E501']
"src/calibre/ebooks/metadata/sources/*" = ['UP']
"src/calibre/gui2/store/stores/*" = ['UP']

View File

@ -86,7 +86,7 @@ def _print_check_library_results(checker, check, as_csv=False, out=sys.stdout):
else:
print(check[1], file=out)
for i in list:
print(' %-40.40s - %-40.40s' % (i[0], i[1]), file=out)
print(f' {i[0]:<40.40} -{i[1]:<40.40}', file=out)
def main(opts, args, dbctx):

View File

@ -251,7 +251,7 @@ def do_list(
ft = text[i][l] if l < len(text[i]) else ''
stdout.write(ft.encode('utf-8'))
if i < len(text) - 1:
filler = ('%*s' % (widths[i] - str_width(ft) - 1, ''))
filler = ' '*(widths[i] - str_width(ft) - 1)
stdout.write((filler + separator).encode('utf-8'))
stdout.write(linesep)

View File

@ -115,7 +115,7 @@ def do_list(fields, data, opts):
for l in range(lines):
for i, field in enumerate(text):
ft = text[i][l] if l < len(text[i]) else ''
filler = '%*s' % (widths[i] - len(ft) - 1, '')
filler = ' '*(widths[i] - len(ft) - 1)
print(ft.encode('utf-8') + filler.encode('utf-8'), end=separator)
print()

View File

@ -118,9 +118,9 @@ def get_fields(dbctx):
def main(opts, args, dbctx):
if opts.list_fields:
ans = get_fields(dbctx)
prints('%-40s' % _('Title'), _('Field name'), '\n')
prints('{:<40}'.format(_('Title')), _('Field name'), '\n')
for key, m in ans:
prints('%-40s' % m['name'], key)
prints('{:<40}'.format(m['name']), key)
return 0
def verify_int(x):

View File

@ -244,7 +244,7 @@ def main():
where = ('Memory', 'Card A', 'Card B')
print('Filesystem\tSize \tUsed \tAvail \tUse%')
for i in range(3):
print('%-10s\t%s\t%s\t%s\t%s'%(where[i], human_readable(total[i]), human_readable(total[i]-free[i]), human_readable(free[i]),
print('{:<10}\t{}\t{}\t{}\t{}'.format(where[i], human_readable(total[i]), human_readable(total[i]-free[i]), human_readable(free[i]),
str(0 if total[i]==0 else int(100*(total[i]-free[i])/(total[i]*1.)))+'%'))
elif command == 'eject':
dev.eject()

View File

@ -168,7 +168,7 @@ class Bookmark: # {{{
ans = ['Kobo bookmark:']
def fmt(x, y):
ans.append('%-20s: %s'%(str(x), str(y)))
ans.append(f'{x:<20}: {y}')
if self.contentId:
fmt('ContentID', self.contentId)

View File

@ -101,7 +101,7 @@ class Book(Book_):
ans = ['Kobo metadata:']
def fmt(x, y):
ans.append('%-20s: %s'%(str(x), str(y)))
ans.append(f'{x:<20}: {y}')
if self.contentID:
fmt('Content ID', self.contentID)

View File

@ -484,7 +484,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
except:
today = time.localtime()
date = (today[0], today[1], today[2])
template = '{title}_%d-%d-%d' % date
template = f'{{title}}_{date[0]}-{date[1]}-{date[2]}'
use_subdirs = self.SUPPORTS_SUB_DIRS and settings.use_subdirs
from calibre.library.save_to_disk import config, get_components

View File

@ -91,7 +91,7 @@ def create_upload_path(mdata, fname, template, sanitize,
except:
today = time.localtime()
date = (today[0], today[1], today[2])
template = '{title}_%d-%d-%d' % date
template = f'{{title}}_{date[0]}-{date[1]}-{date[2]}'
fname = sanitize(fname)
ext = path_type.splitext(fname)[1]

View File

@ -192,10 +192,8 @@ class RTFInput(InputFormatPlugin):
return name
def write_inline_css(self, ic, border_styles):
font_size_classes = ['span.fs%d { font-size: %spt }'%(i, x) for i, x in
enumerate(ic.font_sizes)]
color_classes = ['span.col%d { color: %s }'%(i, x) for i, x in
enumerate(ic.colors) if x != 'false']
font_size_classes = [f'span.fs{i} {{ font-size: {x}pt }}' for i, x in enumerate(ic.font_sizes)]
color_classes = [f'span.col{i} {{ color: {x} }}' for i, x in enumerate(ic.colors) if x != 'false']
css = textwrap.dedent('''
span.none {
text-decoration: none; font-weight: normal;

View File

@ -209,7 +209,7 @@ class DOCX:
E = ElementMaker(namespace=self.namespace.namespaces['ep'], nsmap={None:self.namespace.namespaces['ep']})
props = E.Properties(
E.Application(__appname__),
E.AppVersion('%02d.%04d' % numeric_version[:2]),
E.AppVersion(f'{numeric_version[0]:02}.{numeric_version[1]:04}'),
E.DocSecurity('0'),
E.HyperlinksChanged('false'),
E.LinksUpToDate('true'),

View File

@ -769,8 +769,7 @@ class StylesManager:
text_style.seq = i
self.descendant_text_styles = sorted(descendant_style_map, key=attrgetter('seq'))
self.log.debug('%d Text Styles %d Combined styles' % tuple(map(len, (
self.descendant_text_styles, self.combined_styles))))
self.log.debug(f'{len(self.descendant_text_styles)} Text Styles {len(self.combined_styles)} Combined styles')
self.primary_heading_style = None
if heading_styles:

View File

@ -765,7 +765,7 @@ class Metadata:
ans = []
def fmt(x, y):
ans.append('%-20s: %s'%(str(x), str(y)))
ans.append(f'{x:<20}: {y}')
fmt('Title', self.title)
if self.title_sort:

View File

@ -308,7 +308,7 @@ class MetadataUpdater:
def dump_pdbrecords(self):
# Diagnostic
print('MetadataUpdater.dump_pdbrecords()')
print('%10s %10s %10s' % ('offset','flags','val'))
print(f"{'offset':>10} {'flags':>10} {'val':>10}")
for i in range(len(self.pdbrecords)):
pdbrecord = self.pdbrecords[i]
print(f'{pdbrecord[0]:10X} {pdbrecord[1]:10X} {pdbrecord[2]:10X}')

View File

@ -96,13 +96,13 @@ class Index:
a = ans.append
if self.header is not None:
for field in INDEX_HEADER_FIELDS:
a('%-12s: %r'%(FIELD_NAMES.get(field, field), self.header[field]))
a(f'{FIELD_NAMES.get(field, field):<12}: {self.header[field]!r}')
ans.extend(['', ''])
ans += ['*'*10 + f' Index Record Headers ({len(self.index_headers)} records) ' + '*'*10]
for i, header in enumerate(self.index_headers):
ans += ['*'*10 + f' Index Record {i} ' + '*'*10]
for field in INDEX_HEADER_FIELDS:
a('%-12s: %r'%(FIELD_NAMES.get(field, field), header[field]))
a(f'{FIELD_NAMES.get(field, field):<12}: {header[field]!r}')
if self.cncx:
a('*'*10 + ' CNCX ' + '*'*10)

View File

@ -98,8 +98,8 @@ class SecondaryIndexHeader: # {{{
a = ans.append
def u(w):
a('Unknown: %r (%d bytes) (All zeros: %r)'%(w,
len(w), not bool(w.replace(b'\0', b''))))
a('Unknown: {!r} ({} bytes) (All zeros: {!r})'.format(
w, len(w), not bool(w.replace(b'\0', b''))))
a(f'Header length: {self.header_length}')
u(self.unknown1)
@ -199,7 +199,7 @@ class IndexHeader: # {{{
a = ans.append
def u(w):
a('Unknown: %r (%d bytes) (All zeros: %r)'%(w,
a('Unknown: {!r} ({} bytes) (All zeros: {!r})'.format(w,
len(w), not bool(w.replace(b'\0', b''))))
a(f'Header length: {self.header_length}')
@ -411,7 +411,7 @@ class IndexRecord: # {{{
a = ans.append
def u(w):
a('Unknown: %r (%d bytes) (All zeros: %r)'%(w,
a('Unknown: {!r} ({} bytes) (All zeros: {!r})'.format(w,
len(w), not bool(w.replace(b'\0', b''))))
for entry in self.indices:
offset = entry.offset
@ -582,9 +582,7 @@ class TBSIndexing: # {{{
ans = []
ans.append(f"\nRecord #{r.idx}: Starts at: {dat['geom'][0]} Ends at: {dat['geom'][1]}")
s, e, c = dat['starts'], dat['ends'], dat['complete']
ans.append(('\tContains: %d index entries '
'(%d ends, %d complete, %d starts)')%tuple(map(len, (s+e+c, e,
c, s))))
ans.append(f'\tContains: {len(s+e+c)} index entries ({len(e)} ends, {len(c)} complete, {len(s)} starts)')
byts = bytearray(r.trailing_data.get('indexing', b''))
ans.append(f'TBS bytes: {format_bytes(byts)}')
for typ, entries in (('Ends', e), ('Complete', c), ('Starts', s)):

View File

@ -45,7 +45,7 @@ class FDST:
a('Number of section records', self.num_sections)
ans.append(f'**** {len(self.sections)} Sections ****')
for sec in self.sections:
ans.append('Start: %20d End: %d'%sec)
ans.append(f'Start: {sec[0]:>20} End: {sec[1]}')
return '\n'.join(ans)
@ -266,7 +266,7 @@ class MOBIFile:
for entries in itervalues(strand):
for e in entries:
desc.append(
' %s%d [%-9s] parent: %s (%d) Geometry: (%d, %d)'%(
' {}{} [{:<9}] parent: {} ({}) Geometry: ({}, {})'.format(
e.depth * (' ') + '- ', e.index, e.action, e.parent,
e.index-(e.parent or 0), e.start-i*RECORD_SIZE,
e.start+e.length-i*RECORD_SIZE))

View File

@ -662,7 +662,7 @@ class MobiReader:
elif mi.cover is not None:
opf.cover = mi.cover
else:
opf.cover = 'images/%05d.jpg' % 1
opf.cover = f'images/{1:05}.jpg'
if not os.path.exists(os.path.join(os.path.dirname(htmlfile),
* opf.cover.split('/'))):
opf.cover = None

View File

@ -68,7 +68,7 @@ class IndirectObjects:
stream.write(b'xref'+EOL)
stream.write(f'0 {1 + len(self._offsets)}')
stream.write(EOL)
stream.write('%010d 65535 f '%0)
stream.write(f'{0:010} 65535 f ')
stream.write(EOL)
for offset in self._offsets:

View File

@ -366,8 +366,7 @@ class Document:
tag = el.tag
if weight + content_score < 0:
self.debug('Cleaned %s with score %6.3f and weight %-3s' %
(describe(el), content_score, weight, ))
self.debug(f'Cleaned {describe(el)} with score {content_score:6.3f} and weight {weight:<3}')
el.drop_tree()
elif el.text_content().count(',') < 10:
counts = {}

View File

@ -322,10 +322,10 @@ class RtfTokenizer:
l = l + 1
i = i + 1
if l > 10:
raise Exception('Error (at:%d): Too many digits in control word numeric argument.'%[tokenStart])
raise Exception(f'Error (at:{tokenStart}): Too many digits in control word numeric argument.')
if not consumed:
raise Exception('Error (at:%d): Control Word without numeric argument end.'%[tokenStart])
raise Exception(f'Error (at:{tokenStart}): Control Word without numeric argument end.')
separator = ''
if isChar(self.rtfData[i], ' '):

View File

@ -98,7 +98,7 @@ def getimagesize(url):
break
p.feed(s)
if p.image:
return 'width="%i" height="%i"' % p.image.size
return f'width="{p.image.size[0]}" height="{p.image.size[1]}"'
except (OSError, ValueError):
return None

View File

@ -90,7 +90,7 @@ class RichTextDelegate(QStyledItemDelegate): # {{{
group = (QPalette.ColorGroup.Active if option.state & QStyle.StateFlag.State_Active else
QPalette.ColorGroup.Inactive)
c = p.color(group, QPalette.ColorRole.HighlightedText)
c = 'rgb(%d, %d, %d)'%c.getRgb()[:3]
c = 'rgb({}, {}, {})'.format(*c.getRgb()[:3])
doc.setDefaultStyleSheet(f' * {{ color: {c} }}')
doc.setHtml(index.data() or '')
return doc

View File

@ -202,8 +202,7 @@ class Check(QSplitter):
fix_tt = _('Try to fix all fixable errors automatically. Only works for some types of error.')
fix_msg = _('Try to correct all fixable errors automatically')
run_tt, run_msg = _('Re-run the check'), _('Re-run check')
header = '<style>a { text-decoration: none}</style><h2>%s [%d / %d]</h2>' % (
header, self.items.currentRow()+1, self.items.count())
header = f'<style>a {{text-decoration: none}}</style><h2>{header} [{self.items.currentRow()+1} / {self.items.count()}]</h2>'
msg = '<p>%s</p>'
footer = '<div>%s<a href="fix:errors" title="%s">%s</a><br><br> <a href="run:check" title="%s">%s</a></div>'
if err.has_multiple_locations:

View File

@ -143,7 +143,7 @@ class CheckExternalLinks(Dialog):
for i, (locations, err, url) in enumerate(self.errors):
if i in self.fixed_errors:
continue
text += '<li><b>%s</b> \xa0<a href="err:%d">[%s]</a><br>%s<br><ul>' % (url, i, _('Fix this link'), err)
text += '<li><b>{}</b> \xa0<a href="err:{}">[{}]</a><br>{}<br><ul>'.format(url, i, _('Fix this link'), err)
for name, href, lnum, col in locations:
text += '<li>{name} \xa0<a href="loc:{lnum},{name}">[{line}: {lnum}]</a></li>'.format(
name=name, lnum=lnum, line=_('line number'))

View File

@ -547,7 +547,7 @@ class NamesDelegate(QStyledItemDelegate):
positions = sorted(set(positions) - {-1}, reverse=True)
text = f'<body>{make_highlighted_text(emphasis_style(), text, positions)}</body>'
doc = QTextDocument()
c = 'rgb(%d, %d, %d)'%c.getRgb()[:3]
c = 'rgb({}, {}, {})'.format(*c.getRgb()[:3])
doc.setDefaultStyleSheet(f' body {{ color: {c} }}')
doc.setHtml(text)
doc.setDefaultFont(option.font)

View File

@ -653,9 +653,8 @@ class CatalogBuilder:
self.opts.log.info(' Custom fields:')
all_custom_fields = self.db.custom_field_keys()
for cf in all_custom_fields:
self.opts.log.info(' %-20s %-20s %s' %
(cf, "'{}'".format(self.db.metadata_for_field(cf)['name']),
self.db.metadata_for_field(cf)['datatype']))
self.opts.log.info(' {:<20} {!r:<20} {}'.format(
cf, self.db.metadata_for_field(cf)['name'], self.db.metadata_for_field(cf)['datatype']))
def establish_equivalencies(self, item_list, key=None):
''' Return icu equivalent sort letter.
@ -835,8 +834,7 @@ class CatalogBuilder:
if self.DEBUG and self.opts.verbose:
self.opts.log.info(f'\nfetch_books_by_author(): {len(unique_authors)} unique authors')
for author in unique_authors:
self.opts.log.info((' %-50s %-25s %2d' % (author[0][0:45], author[1][0:20],
author[2])).encode('utf-8'))
self.opts.log.info(f' {author[0][0:45]:<50} {author[1][0:20]:<25} {author[2]:>2}')
self.opts.log.info(f'\nfetch_books_by_author(): {len(individual_authors)} individual authors')
for author in sorted(individual_authors):
self.opts.log.info(f'{author}')
@ -865,10 +863,9 @@ class CatalogBuilder:
if self.DEBUG and self.opts.verbose:
self.opts.log.info(f'fetch_books_by_title(): {len(self.books_by_title)} books')
self.opts.log.info(' %-40s %-40s' % ('title', 'title_sort'))
self.opts.log.info(' {:<40} {:<40}'.format('title', 'title_sort'))
for title in self.books_by_title:
self.opts.log.info((' %-40s %-40s' % (title['title'][0:40],
title['title_sort'][0:40])).encode('utf-8'))
self.opts.log.info(' {:<40} {:<40}'.format(title['title'][0:40], title['title_sort'][0:40]))
else:
error_msg = _("No books to catalog.\nCheck 'Excluded books' rules in the E-book options.\n")
self.opts.log.error('*** ' + error_msg + ' ***')

View File

@ -59,8 +59,7 @@ class CustomHelpFormatter(optparse.IndentedHelpFormatter):
def format_heading(self, heading):
from calibre.utils.terminal import colored
return '%*s%s:\n' % (self.current_indent, '',
colored(heading, fg='blue', bold=True))
return ' '*self.current_indent + '{}:\n'.format(colored(heading, fg='blue', bold=True))
def format_option(self, option):
import textwrap
@ -71,12 +70,10 @@ class CustomHelpFormatter(optparse.IndentedHelpFormatter):
opts = self.option_strings[option]
opt_width = self.help_position - self.current_indent - 2
if len(opts) > opt_width:
opts = '%*s%s\n' % (self.current_indent, '',
colored(opts, fg='green'))
opts = ' '*self.current_indent + '{}\n'.format(colored(opts, fg='green'))
indent_first = self.help_position
else: # start help on same line as opts
opts = '%*s%-*s ' % (self.current_indent, '', opt_width +
len(colored('', fg='green')), colored(opts, fg='green'))
opts = ' '*self.current_indent + '%-*s ' % (opt_width+len(colored('', fg='green')), colored(opts, fg='green'))
indent_first = 0
result.append(opts)
if option.help:
@ -85,9 +82,8 @@ class CustomHelpFormatter(optparse.IndentedHelpFormatter):
for line in help_text:
help_lines.extend(textwrap.wrap(line, self.help_width))
result.append('%*s%s\n' % (indent_first, '', help_lines[0]))
result.extend(['%*s%s\n' % (self.help_position, '', line)
for line in help_lines[1:]])
result.append(' '*indent_first + f'{help_lines[0]}')
result.extend([' '*self.help_position + f'{line}' for line in help_lines[1:]])
elif opts[-1] != '\n':
result.append('\n')
return ''.join(result)+'\n'

View File

@ -220,8 +220,7 @@ def option_parser():
def print_stats(old_stats, new_stats):
from calibre import prints
prints('========= Table comparison (original vs. subset) =========')
prints('Table', ' ', '%10s'%'Size', ' ', 'Percent', ' ', '%10s'%'New Size',
' New Percent')
prints('Table', ' ', f"{'Size':>10}", ' ', 'Percent', ' ', f"{'New Size':>10}", ' New Percent')
prints('='*80)
old_total = sum(itervalues(old_stats))
new_total = sum(itervalues(new_stats))
@ -235,8 +234,8 @@ def print_stats(old_stats, new_stats):
suffix = ' | same size'
if nsz != osz:
suffix = f' | reduced to {nsz/osz*100:.1f} %'
prints(f'{table:4}', ' ', f'{osz:10}', ' ', f'{op:5.1f} %', ' ',
f'{nsz:10}', ' ', f'{np:5.1f} %', suffix)
prints(f'{table:>4}', ' ', f'{osz:>10}', ' ', f'{op:5.1f} %', ' ',
f'{nsz:>10}', ' ', f'{np:5.1f} %', suffix)
prints('='*80)

View File

@ -971,10 +971,11 @@ class ZipFile:
def printdir(self):
'''Print a table of contents for the zip file.'''
print('%-46s %19s %12s' % ('File Name', 'Modified ', 'Size'))
print(f"{'File Name':<46} {'Modified ':>19} {'Size':>12}")
for zinfo in self.filelist:
date = '%d-%02d-%02d %02d:%02d:%02d' % zinfo.date_time[:6]
print('%-46s %s %12d' % (zinfo.filename, date, zinfo.file_size))
date = (f'{zinfo.date_time[0]}-{zinfo.date_time[1]:02}-{zinfo.date_time[2]:02} '
f'{zinfo.date_time[3]:02}:{zinfo.date_time[4]:02}:{zinfo.date_time[5]:02}')
print(f'{zinfo.filename:<46} {date:>19} {zinfo.file_size:>12}')
def testzip(self):
'''Read all the files and check the CRC.'''

View File

@ -250,7 +250,7 @@ class Feed:
return len(self.articles)
def __repr__(self):
res = [('%20s\n'%'').replace(' ', '_')+repr(art) for art in self]
res = ['_'*20 + f'\n{art!r}' for art in self]
return '\n'+'\n'.join(res)+'\n'

View File

@ -1693,7 +1693,7 @@ class BasicNewsRecipe(Recipe):
f.title, play_order=po, description=desc, author=auth))
else:
entries.append('feed_%d/index.html'%0)
entries.append('feed_0/index.html')
feed_index(0, toc)
for i, p in enumerate(entries):

View File

@ -427,7 +427,7 @@ class SchedulerConfig:
schedule = 0.04
text = f'{schedule:f}'
elif typ == 'day/time':
text = '%d:%d:%d'%schedule
text = f'{int(schedule[0])}:{int(schedule[1])}:{int(schedule[2])}'
elif typ in ('days_of_week', 'days_of_month'):
dw = ','.join(map(str, map(int, schedule[0])))
text = f'{dw}:{int(schedule[1])}:{int(schedule[2])}'