diff --git a/manual/custom.py b/manual/custom.py
index 4ed1f286ab..6d7599d688 100644
--- a/manual/custom.py
+++ b/manual/custom.py
@@ -198,7 +198,7 @@ details and examples.
lines += [f'.. _calibredb-{language}-{cmd}:', '']
lines += [cmd, '~'*20, '']
usage = parser.usage.strip()
- usage = [i for i in usage.replace('%prog', 'calibredb').splitlines()]
+ usage = list(usage.replace('%prog', 'calibredb').splitlines())
cmdline = ' '+usage[0]
usage = usage[1:]
usage = [re.sub(rf'({cmd})([^a-zA-Z0-9])', r':command:`\1`\2', i) for i in usage]
diff --git a/recipes/bloomberg-business-week.recipe b/recipes/bloomberg-business-week.recipe
index 58a5bb185d..2d68d60dcd 100644
--- a/recipes/bloomberg-business-week.recipe
+++ b/recipes/bloomberg-business-week.recipe
@@ -124,7 +124,7 @@ class Bloomberg(BasicNewsRecipe):
cat = '
' + data['primaryCategory'] + '
'
if 'abstract' in data and data['abstract'] and data['abstract'] is not None:
- subhead = '- ' + '
- '.join([x for x in data['abstract']]) + '
'
+ subhead = '- ' + '
- '.join(list(data['abstract'])) + '
'
elif 'summary' in data and data['summary']:
subhead = ''
diff --git a/recipes/bloomberg.recipe b/recipes/bloomberg.recipe
index e2bc3f3831..8b2cb982ae 100644
--- a/recipes/bloomberg.recipe
+++ b/recipes/bloomberg.recipe
@@ -134,7 +134,7 @@ class Bloomberg(BasicNewsRecipe):
cat = '' + data['primaryCategory'] + '
'
if 'abstract' in data and data['abstract'] and data['abstract'] is not None:
- subhead = '- ' + '
- '.join([x for x in data['abstract']]) + '
'
+ subhead = '- ' + '
- '.join(list(data['abstract'])) + '
'
elif 'summary' in data and data['summary']:
subhead = ''
diff --git a/recipes/factcheck.recipe b/recipes/factcheck.recipe
index 732344ebd0..f7fad0d34c 100644
--- a/recipes/factcheck.recipe
+++ b/recipes/factcheck.recipe
@@ -13,6 +13,6 @@ class FactCheckOrg(BasicNewsRecipe):
masthead_url = 'http://factcheck.org/wp-content/themes/Streamline/images/headernew.jpg'
cover_url = 'http://factcheck.org/wp-content/themes/Streamline/images/headernew.jpg'
- remove_tags = [dict({'id': ['footer', 'footerabout', 'sidebar']})]
+ remove_tags = [{'id': ['footer', 'footerabout', 'sidebar']}]
feeds = [(u'Factcheck', u'feed://www.factcheck.org/feed/')]
diff --git a/recipes/gry_online_pl.recipe b/recipes/gry_online_pl.recipe
index 3be11ba2a2..61fd76d1c0 100644
--- a/recipes/gry_online_pl.recipe
+++ b/recipes/gry_online_pl.recipe
@@ -21,7 +21,7 @@ class GryOnlinePl(BasicNewsRecipe):
keep_only_tags = [dict(name='div', attrs={'class': [
'gc660', 'gc660 S013', 'news_endpage_tit', 'news_container', 'news']})]
remove_tags = [
- dict({'class': ['nav-social', 'add-info', 'smlb', 'lista lista3 lista-gry', 'S013po', 'S013-npb', 'zm_gfx_cnt_bottom', 'ocen-txt', 'wiecej-txt', 'wiecej-txt2', 'social-for-old-news', 'social-for-old-rec']})] # noqa: E501
+ {'class': ['nav-social', 'add-info', 'smlb', 'lista lista3 lista-gry', 'S013po', 'S013-npb', 'zm_gfx_cnt_bottom', 'ocen-txt', 'wiecej-txt', 'wiecej-txt2', 'social-for-old-news', 'social-for-old-rec']}] # noqa: E501
feeds = [
(u'Newsy', 'http://www.gry-online.pl/rss/news.xml'),
('Teksty', u'http://www.gry-online.pl/rss/teksty.xml')]
diff --git a/recipes/reuters.recipe b/recipes/reuters.recipe
index b3ecf2e42c..282b39e869 100644
--- a/recipes/reuters.recipe
+++ b/recipes/reuters.recipe
@@ -140,7 +140,7 @@ class Reuters(BasicNewsRecipe):
for y in x['templates']:
if 'author' in y['cid']:
body += ''
- auths = [x for x in y.get('authors_names', [])]
+ auths = list(y.get('authors_names', []))
if auths:
body += (
'
' + 'By ' + ', '.join(auths) + '
'
diff --git a/ruff-strict-pep8.toml b/ruff-strict-pep8.toml
index ee0751078a..54eec4a104 100644
--- a/ruff-strict-pep8.toml
+++ b/ruff-strict-pep8.toml
@@ -17,8 +17,14 @@ exclude = [
quote-style = 'single'
[lint]
-ignore = ['E402', 'E722', 'E741', 'UP012', 'UP030', 'UP032', 'UP038']
-select = ['E', 'F', 'I', 'W', 'INT', 'Q', 'UP', 'YTT', 'TID']
+ignore = [
+ 'E402', 'E722', 'E741',
+ 'UP012', 'UP030', 'UP032', 'UP038', 'C408', 'C413', 'C417', 'C420',
+]
+select = [
+ 'E', 'F', 'I', 'W', 'INT',
+ 'Q', 'UP', 'YTT', 'TID', 'C4',
+]
[lint.per-file-ignores]
"recipes/*" = ['UP']
diff --git a/setup/translations.py b/setup/translations.py
index d6bbd7661b..1e46bfe156 100644
--- a/setup/translations.py
+++ b/setup/translations.py
@@ -357,7 +357,7 @@ class Translations(POT): # {{{
l = {}
lc_dataf = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lc_data.py')
exec(compile(open(lc_dataf, 'rb').read(), lc_dataf, 'exec'), l, l)
- lcdata = {k:{k1:v1 for k1, v1 in v} for k, v in l['data']}
+ lcdata = {k:dict(v) for k, v in l['data']}
self.info('Compiling main UI translation files...')
fmap = {f:self.mo_file(f) for f in self.po_files()}
files = [(f, fmap[f][1]) for f in self.po_files()]
diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py
index ff4f7852e7..afdf4cceaa 100644
--- a/src/calibre/customize/__init__.py
+++ b/src/calibre/customize/__init__.py
@@ -573,10 +573,10 @@ class CatalogPlugin(Plugin): # {{{
# Validate requested_fields
if requested_fields - all_fields:
from calibre.library import current_library_name
- invalid_fields = sorted(list(requested_fields - all_fields))
+ invalid_fields = sorted(requested_fields - all_fields)
print('invalid --fields specified: %s' % ', '.join(invalid_fields))
print("available fields in '%s': %s" %
- (current_library_name(), ', '.join(sorted(list(all_fields)))))
+ (current_library_name(), ', '.join(sorted(all_fields))))
raise ValueError('unable to generate catalog with specified fields')
fields = [x for x in of if x in all_fields]
diff --git a/src/calibre/db/cli/cmd_set_metadata.py b/src/calibre/db/cli/cmd_set_metadata.py
index 7724b152ee..aa18a6ce72 100644
--- a/src/calibre/db/cli/cmd_set_metadata.py
+++ b/src/calibre/db/cli/cmd_set_metadata.py
@@ -152,7 +152,7 @@ def main(opts, args, dbctx):
raise SystemExit(_('No book with id: %s in the database') % book_id)
if opts.field:
- fields = {k: v for k, v in get_fields(dbctx)}
+ fields = dict(get_fields(dbctx))
fields['title_sort'] = fields['sort']
vals = {}
for x in opts.field:
diff --git a/src/calibre/db/fields.py b/src/calibre/db/fields.py
index bfa62101bd..a3d1027588 100644
--- a/src/calibre/db/fields.py
+++ b/src/calibre/db/fields.py
@@ -366,7 +366,7 @@ class CompositeField(OneToOneField):
for book_id in candidates:
vals = self.get_value_with_cache(book_id, get_metadata)
if splitter:
- length = len(list(vv.strip() for vv in vals.split(splitter) if vv.strip()))
+ length = len([vv.strip() for vv in vals.split(splitter) if vv.strip()])
elif vals.strip():
length = 1
else:
diff --git a/src/calibre/db/legacy.py b/src/calibre/db/legacy.py
index b8a9ff5d11..3532032ef6 100644
--- a/src/calibre/db/legacy.py
+++ b/src/calibre/db/legacy.py
@@ -799,7 +799,7 @@ class LibraryDatabase:
with self.new_api.write_lock:
self.new_api._set_field(field, {book_id:val for book_id in ids}, allow_case_change=False)
if extras is not None:
- self.new_api._set_field(field + '_index', {book_id:val for book_id, val in zip(ids, extras)})
+ self.new_api._set_field(field + '_index', dict(zip(ids, extras)))
if notify:
self.notify('metadata', list(ids))
diff --git a/src/calibre/db/tables.py b/src/calibre/db/tables.py
index 269a8a189a..eba46dd614 100644
--- a/src/calibre/db/tables.py
+++ b/src/calibre/db/tables.py
@@ -234,7 +234,7 @@ class ManyToOneTable(Table):
bcm[book] = item_id
def fix_link_table(self, db):
- linked_item_ids = {item_id for item_id in itervalues(self.book_col_map)}
+ linked_item_ids = set(itervalues(self.book_col_map))
extra_item_ids = linked_item_ids - set(self.id_map)
if extra_item_ids:
for item_id in extra_item_ids:
diff --git a/src/calibre/db/tests/writing.py b/src/calibre/db/tests/writing.py
index 9cc25ffa3f..cdb33cbb39 100644
--- a/src/calibre/db/tests/writing.py
+++ b/src/calibre/db/tests/writing.py
@@ -1019,9 +1019,9 @@ class WritingTest(BaseTest):
cache.set_field('publisher', {1:'random'})
cache.set_link_map('publisher', {'random': 'url2'})
links = cache.get_all_link_maps_for_book(1)
- self.assertSetEqual({v for v in links.keys()}, {'tags', 'publisher'}, 'Wrong link keys')
- self.assertSetEqual({v for v in links['tags'].keys()}, {'foo', }, 'Should be "foo"')
- self.assertSetEqual({v for v in links['publisher'].keys()}, {'random', }, 'Should be "random"')
+ self.assertSetEqual(set(links.keys()), {'tags', 'publisher'}, 'Wrong link keys')
+ self.assertSetEqual(set(links['tags'].keys()), {'foo', }, 'Should be "foo"')
+ self.assertSetEqual(set(links['publisher'].keys()), {'random', }, 'Should be "random"')
self.assertEqual('url', links['tags']['foo'], 'link for tag foo is wrong')
self.assertEqual('url2', links['publisher']['random'], 'link for publisher random is wrong')
diff --git a/src/calibre/db/write.py b/src/calibre/db/write.py
index 61319fef4b..e8cdf88142 100644
--- a/src/calibre/db/write.py
+++ b/src/calibre/db/write.py
@@ -129,7 +129,7 @@ def clean_identifier(typ, val):
def adapt_identifiers(to_tuple, x):
if not isinstance(x, dict):
- x = {k:v for k, v in (y.partition(':')[0::2] for y in to_tuple(x))}
+ x = dict(y.partition(':')[0::2] for y in to_tuple(x))
ans = {}
for k, v in iteritems(x):
k, v = clean_identifier(k, v)
diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py
index 17116df386..0d5fe8a183 100644
--- a/src/calibre/devices/kobo/driver.py
+++ b/src/calibre/devices/kobo/driver.py
@@ -2260,7 +2260,7 @@ class KOBOTOUCH(KOBO):
return extra_sheet
def get_extra_css_rules(self, sheet, css_rule):
- return [r for r in sheet.cssRules.rulesOfType(css_rule)]
+ return list(sheet.cssRules.rulesOfType(css_rule))
def get_extra_css_rules_widow_orphan(self, sheet):
from css_parser.css import CSSRule
diff --git a/src/calibre/devices/mtp/driver.py b/src/calibre/devices/mtp/driver.py
index ec51c48694..d87239e6ee 100644
--- a/src/calibre/devices/mtp/driver.py
+++ b/src/calibre/devices/mtp/driver.py
@@ -487,7 +487,7 @@ class MTP_DEVICE(BASE):
self.report_progress(0, _('Transferring books to device...'))
i, total = 0, len(files)
- routing = {fmt:dest for fmt,dest in self.get_pref('rules')}
+ routing = dict(self.get_pref('rules'))
for infile, fname, mi in zip(files, names, metadata):
path = self.create_upload_path(prefix, mi, fname, routing)
diff --git a/src/calibre/ebooks/conversion/plugins/fb2_input.py b/src/calibre/ebooks/conversion/plugins/fb2_input.py
index c14d681735..fcd27aa093 100644
--- a/src/calibre/ebooks/conversion/plugins/fb2_input.py
+++ b/src/calibre/ebooks/conversion/plugins/fb2_input.py
@@ -105,7 +105,7 @@ class FB2Input(InputFormatPlugin):
# Handle links of type note and cite
notes = {a.get('href')[1:]: a for a in result.xpath('//a[@link_note and @href]') if a.get('href').startswith('#')}
cites = {a.get('link_cite'): a for a in result.xpath('//a[@link_cite]') if not a.get('href', '')}
- all_ids = {x for x in result.xpath('//*/@id')}
+ all_ids = set(result.xpath('//*/@id'))
for cite, a in iteritems(cites):
note = notes.get(cite, None)
if note:
diff --git a/src/calibre/ebooks/covers.py b/src/calibre/ebooks/covers.py
index 934a6140ee..b9ef909a83 100644
--- a/src/calibre/ebooks/covers.py
+++ b/src/calibre/ebooks/covers.py
@@ -318,7 +318,7 @@ ColorTheme = namedtuple('ColorTheme', 'color1 color2 contrast_color1 contrast_co
def to_theme(x):
- return {k:v for k, v in zip(ColorTheme._fields[:4], x.split())}
+ return dict(zip(ColorTheme._fields[:4], x.split()))
fallback_colors = to_theme('ffffff 000000 000000 ffffff')
diff --git a/src/calibre/ebooks/docx/block_styles.py b/src/calibre/ebooks/docx/block_styles.py
index 6e5f548cd8..747a7ad535 100644
--- a/src/calibre/ebooks/docx/block_styles.py
+++ b/src/calibre/ebooks/docx/block_styles.py
@@ -128,7 +128,7 @@ def read_single_border(parent, edge, XPath, get):
width = min(96, max(2, float(sz))) / 8
except (ValueError, TypeError):
pass
- return {p:v for p, v in zip(border_props, (padding, width, style, color))}
+ return dict(zip(border_props, (padding, width, style, color)))
def read_border(parent, dest, XPath, get, border_edges=border_edges, name='pBdr'):
diff --git a/src/calibre/ebooks/lrf/lrs/convert_from.py b/src/calibre/ebooks/lrf/lrs/convert_from.py
index 887e6771f7..049278b086 100644
--- a/src/calibre/ebooks/lrf/lrs/convert_from.py
+++ b/src/calibre/ebooks/lrf/lrs/convert_from.py
@@ -108,7 +108,7 @@ class LrsParser:
def process_paragraph(self, tag):
p = Paragraph()
- contents = [i for i in tag.contents]
+ contents = list(tag.contents)
if contents:
if isinstance(contents[0], NavigableString):
contents[0] = contents[0].string.lstrip()
diff --git a/src/calibre/ebooks/metadata/author_mapper.py b/src/calibre/ebooks/metadata/author_mapper.py
index 56643deecf..6c31c11baa 100644
--- a/src/calibre/ebooks/metadata/author_mapper.py
+++ b/src/calibre/ebooks/metadata/author_mapper.py
@@ -127,7 +127,7 @@ def uniq(vals, kmap=icu_lower):
lvals = (kmap(x) for x in vals)
seen = set()
seen_add = seen.add
- return list(x for x, k in zip(vals, lvals) if k not in seen and not seen_add(k))
+ return [x for x, k in zip(vals, lvals) if k not in seen and not seen_add(k)]
def compile_rules(rules):
diff --git a/src/calibre/ebooks/metadata/odt.py b/src/calibre/ebooks/metadata/odt.py
index 1245a5775e..00dc0237d8 100644
--- a/src/calibre/ebooks/metadata/odt.py
+++ b/src/calibre/ebooks/metadata/odt.py
@@ -63,7 +63,7 @@ def uniq(vals):
vals = vals or ()
seen = set()
seen_add = seen.add
- return list(x for x in vals if x not in seen and not seen_add(x))
+ return [x for x in vals if x not in seen and not seen_add(x)]
def get_metadata(stream, extract_cover=True):
diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py
index a5330a46ba..d095981b3e 100644
--- a/src/calibre/ebooks/metadata/opf3.py
+++ b/src/calibre/ebooks/metadata/opf3.py
@@ -34,7 +34,7 @@ def uniq(vals):
vals = vals or ()
seen = set()
seen_add = seen.add
- return list(x for x in vals if x not in seen and not seen_add(x))
+ return [x for x in vals if x not in seen and not seen_add(x)]
def dump_dict(cats):
diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py
index 1becef626e..33fab58364 100644
--- a/src/calibre/ebooks/metadata/sources/amazon.py
+++ b/src/calibre/ebooks/metadata/sources/amazon.py
@@ -564,9 +564,9 @@ class Worker(Thread): # Get details {{{
res = self.tostring(elem, encoding='unicode', method='text')
if only_printable:
try:
- filtered_characters = list(s for s in res if s.isprintable())
+ filtered_characters = [s for s in res if s.isprintable()]
except AttributeError:
- filtered_characters = list(s for s in res if s in string.printable)
+ filtered_characters = [s for s in res if s in string.printable]
res = ''.join(filtered_characters)
return res.strip()
@@ -1395,8 +1395,8 @@ class Amazon(Source):
q['field-keywords'] += ' ' + q.pop(f, '')
q['field-keywords'] = q['field-keywords'].strip()
- encoded_q = dict([(x.encode('utf-8', 'ignore'), y.encode(
- 'utf-8', 'ignore')) for x, y in q.items()])
+ encoded_q = {x.encode('utf-8', 'ignore'): y.encode(
+ 'utf-8', 'ignore') for x, y in q.items()}
url_query = urlencode(encoded_q)
# amazon's servers want IRIs with unicode characters not percent esaped
parts = []
diff --git a/src/calibre/ebooks/metadata/sources/base.py b/src/calibre/ebooks/metadata/sources/base.py
index 5bf5a19e98..eb0218ce0e 100644
--- a/src/calibre/ebooks/metadata/sources/base.py
+++ b/src/calibre/ebooks/metadata/sources/base.py
@@ -180,7 +180,7 @@ class Option:
self.name, self.type, self.default, self.label, self.desc = (name,
type_, default, label, desc)
if choices and not isinstance(choices, dict):
- choices = dict([(x, x) for x in choices])
+ choices = {x: x for x in choices}
self.choices = choices
diff --git a/src/calibre/ebooks/metadata/tag_mapper.py b/src/calibre/ebooks/metadata/tag_mapper.py
index 904dc0038f..84e3997e55 100644
--- a/src/calibre/ebooks/metadata/tag_mapper.py
+++ b/src/calibre/ebooks/metadata/tag_mapper.py
@@ -119,7 +119,7 @@ def uniq(vals, kmap=icu_lower):
lvals = (kmap(x) for x in vals)
seen = set()
seen_add = seen.add
- return list(x for x, k in zip(vals, lvals) if k not in seen and not seen_add(k))
+ return [x for x, k in zip(vals, lvals) if k not in seen and not seen_add(k)]
def map_tags(tags, rules=()):
diff --git a/src/calibre/ebooks/mobi/reader/headers.py b/src/calibre/ebooks/mobi/reader/headers.py
index 0f694eb9ff..1499dc8acb 100644
--- a/src/calibre/ebooks/mobi/reader/headers.py
+++ b/src/calibre/ebooks/mobi/reader/headers.py
@@ -26,7 +26,7 @@ def uniq(vals):
vals = vals or ()
seen = set()
seen_add = seen.add
- return list(x for x in vals if x not in seen and not seen_add(x))
+ return [x for x in vals if x not in seen and not seen_add(x)]
class EXTHHeader: # {{{
diff --git a/src/calibre/ebooks/oeb/polish/check/opf.py b/src/calibre/ebooks/oeb/polish/check/opf.py
index 0c977b75fa..eb4c2c1eb0 100644
--- a/src/calibre/ebooks/oeb/polish/check/opf.py
+++ b/src/calibre/ebooks/oeb/polish/check/opf.py
@@ -214,7 +214,7 @@ class MultipleCovers(BaseError):
self.all_locations = [(name, lnum, None) for lnum in sorted(locs)]
def __call__(self, container):
- items = [e for e in container.opf_xpath('/opf:package/opf:metadata/opf:meta[@name="cover"]')]
+ items = list(container.opf_xpath('/opf:package/opf:metadata/opf:meta[@name="cover"]'))
[container.remove_from_xml(e) for e in items[1:]]
container.dirty(self.name)
return True
diff --git a/src/calibre/ebooks/oeb/polish/fonts.py b/src/calibre/ebooks/oeb/polish/fonts.py
index 28bd209eb9..1c94c50483 100644
--- a/src/calibre/ebooks/oeb/polish/fonts.py
+++ b/src/calibre/ebooks/oeb/polish/fonts.py
@@ -112,7 +112,7 @@ def change_font_in_sheet(container, sheet, old_name, new_name, sheet_name):
elif rule.type == rule.FONT_FACE_RULE:
ff = rule.style.getProperty('font-family')
if ff is not None:
- families = {x for x in parse_font_family(css_text(ff.propertyValue))}
+ families = set(parse_font_family(css_text(ff.propertyValue)))
if old_name in families:
changed = True
removals.append(rule)
diff --git a/src/calibre/ebooks/oeb/polish/utils.py b/src/calibre/ebooks/oeb/polish/utils.py
index 122aa3cb09..5af4d42e17 100644
--- a/src/calibre/ebooks/oeb/polish/utils.py
+++ b/src/calibre/ebooks/oeb/polish/utils.py
@@ -117,7 +117,7 @@ def corrected_case_for_name(container, name):
correctx = x
else:
try:
- candidates = {q for q in os.listdir(os.path.dirname(container.name_to_abspath(base)))}
+ candidates = set(os.listdir(os.path.dirname(container.name_to_abspath(base))))
except OSError:
return None # one of the non-terminal components of name is a file instead of a directory
for q in candidates:
@@ -213,7 +213,7 @@ def lead_text(top_elem, num_words=10):
if attr == 'text':
if elem is not top_elem:
stack.append((elem, 'tail'))
- stack.extend(reversed(list((c, 'text') for c in elem.iterchildren('*'))))
+ stack.extend(reversed([(c, 'text') for c in elem.iterchildren('*')]))
return ' '.join(words[:num_words])
diff --git a/src/calibre/gui2/actions/convert.py b/src/calibre/gui2/actions/convert.py
index 8f5297c813..cfc623e94b 100644
--- a/src/calibre/gui2/actions/convert.py
+++ b/src/calibre/gui2/actions/convert.py
@@ -177,7 +177,7 @@ class ConvertAction(InterfaceActionWithLibraryDrop):
converted_func, extra_job_args=[], rows_are_ids=False):
for func, args, desc, fmt, id, temp_files in jobs:
func, _, parts = func.partition(':')
- parts = {x for x in parts.split(';')}
+ parts = set(parts.split(';'))
input_file = args[0]
input_fmt = os.path.splitext(input_file)[1]
core_usage = 1
diff --git a/src/calibre/gui2/actions/preferences.py b/src/calibre/gui2/actions/preferences.py
index d46311efca..fdb6ebe5b5 100644
--- a/src/calibre/gui2/actions/preferences.py
+++ b/src/calibre/gui2/actions/preferences.py
@@ -46,7 +46,7 @@ class PreferencesAction(InterfaceAction):
def initialization_complete(self):
# Add the individual preferences to the menu.
# First, sort them into the same order as shown in the preferences dialog
- plugins = sorted([p for p in preferences_plugins()],
+ plugins = sorted(preferences_plugins(),
key=lambda p: p.category_order * 100 + p.name_order)
pm = self.preferences_menu
diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py
index 0fb477ab6a..8155e5040a 100644
--- a/src/calibre/gui2/custom_column_widgets.py
+++ b/src/calibre/gui2/custom_column_widgets.py
@@ -891,8 +891,8 @@ def get_field_list(db, use_defaults=False, pref_data_override=None):
def get_custom_columns_to_display_in_editor(db):
- return list([k[0] for k in
- get_field_list(db, use_defaults=db.prefs['edit_metadata_ignore_display_order']) if k[1]])
+ return [k[0] for k in
+ get_field_list(db, use_defaults=db.prefs['edit_metadata_ignore_display_order']) if k[1]]
def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, parent=None):
diff --git a/src/calibre/gui2/dialogs/tag_categories.py b/src/calibre/gui2/dialogs/tag_categories.py
index 2137332943..70234c2206 100644
--- a/src/calibre/gui2/dialogs/tag_categories.py
+++ b/src/calibre/gui2/dialogs/tag_categories.py
@@ -230,7 +230,7 @@ class TagCategories(QDialog, Ui_TagCategories):
def fill_applied_items(self):
ccn = self.current_cat_name
if ccn:
- self.applied_items = [v for v in self.user_categories[ccn]]
+ self.applied_items = list(self.user_categories[ccn])
self.applied_items.sort(key=self.item_sort_key)
else:
self.applied_items = []
diff --git a/src/calibre/gui2/dialogs/tag_editor.py b/src/calibre/gui2/dialogs/tag_editor.py
index fdf90af097..780cb66820 100644
--- a/src/calibre/gui2/dialogs/tag_editor.py
+++ b/src/calibre/gui2/dialogs/tag_editor.py
@@ -75,9 +75,9 @@ class TagEditor(QDialog, Ui_TagEditor):
self.applied_tags.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
if key:
- all_tags = [tag for tag in self.db.all_custom(label=key)]
+ all_tags = list(self.db.all_custom(label=key))
else:
- all_tags = [tag for tag in self.db.all_tags()]
+ all_tags = list(self.db.all_tags())
all_tags = sorted(set(all_tags) - set(tags), key=sort_key)
self.all_tags_model = QStringListModel(all_tags)
p = QSortFilterProxyModel()
diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py
index 9eb389bdef..da84004ea2 100644
--- a/src/calibre/gui2/dialogs/template_dialog.py
+++ b/src/calibre/gui2/dialogs/template_dialog.py
@@ -958,7 +958,7 @@ def evaluate(book, context):
self.textbox.set_clicked_line_numbers(set())
def set_all_button_pressed(self):
- self.textbox.set_clicked_line_numbers({i for i in range(1, self.textbox.blockCount()+1)})
+ self.textbox.set_clicked_line_numbers(set(range(1, self.textbox.blockCount()+1)))
def toggle_button_pressed(self):
ln = self.breakpoint_line_box.value()
diff --git a/src/calibre/gui2/library/delegates.py b/src/calibre/gui2/library/delegates.py
index ad434bed8e..42431fb1bf 100644
--- a/src/calibre/gui2/library/delegates.py
+++ b/src/calibre/gui2/library/delegates.py
@@ -560,7 +560,7 @@ class CcTextDelegate(StyledItemDelegate, UpdateEditorGeometry, EditableTextDeleg
editor = EditWithComplete(parent)
editor.set_separator(None)
editor.set_clear_button_enabled(False)
- complete_items = sorted(list(m.db.all_custom(label=key)), key=sort_key)
+ complete_items = sorted(m.db.all_custom(label=key), key=sort_key)
editor.update_items_cache(complete_items)
else:
editor = QLineEdit(parent)
diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py
index c66c35b4ae..946681b188 100644
--- a/src/calibre/gui2/library/views.py
+++ b/src/calibre/gui2/library/views.py
@@ -1335,7 +1335,7 @@ class BooksView(QTableView): # {{{
def visible_columns(self):
h = self.horizontalHeader()
logical_indices = (x for x in range(h.count()) if not h.isSectionHidden(x))
- rmap = {i:x for i, x in enumerate(self.column_map)}
+ rmap = dict(enumerate(self.column_map))
return (rmap[h.visualIndex(x)] for x in logical_indices if h.visualIndex(x) > -1)
def refresh_book_details(self, force=False):
diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py
index d8ad6f9ab1..a97e3e8e76 100644
--- a/src/calibre/gui2/preferences/coloring.py
+++ b/src/calibre/gui2/preferences/coloring.py
@@ -1281,7 +1281,7 @@ class EditRules(QWidget): # {{{
def move_rows(self, moving_up=True):
sm = self.rules_view.selectionModel()
- rows = sorted(list(sm.selectedRows()), reverse=not moving_up)
+ rows = sorted(sm.selectedRows(), reverse=not moving_up)
if rows:
if rows[0].row() == (0 if moving_up else self.model.rowCount() - 1):
return
diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py
index b524f8fc16..5567ac4aba 100644
--- a/src/calibre/gui2/preferences/look_feel.py
+++ b/src/calibre/gui2/preferences/look_feel.py
@@ -353,7 +353,7 @@ class TBPartitionedFields(DisplayedFields): # {{{
ans = [[k, True] for k in cats.keys()]
self.changed = True
elif pref_data_override:
- po = {k:v for k,v in pref_data_override}
+ po = dict(pref_data_override)
ans = [[k, po.get(k, True)] for k in cats.keys()]
self.changed = True
else:
@@ -389,7 +389,7 @@ class BDVerticalCats(DisplayedFields): # {{{
ans = [[k, False] for k in cats]
self.changed = True
elif pref_data_override:
- ph = {k:v for k,v in pref_data_override}
+ ph = dict(pref_data_override)
ans = [[k, ph.get(k, False)] for k in cats]
self.changed = True
else:
diff --git a/src/calibre/gui2/preferences/look_feel_tabs/tb_hierarchy.py b/src/calibre/gui2/preferences/look_feel_tabs/tb_hierarchy.py
index eeb7c333c7..139123a95f 100644
--- a/src/calibre/gui2/preferences/look_feel_tabs/tb_hierarchy.py
+++ b/src/calibre/gui2/preferences/look_feel_tabs/tb_hierarchy.py
@@ -37,7 +37,7 @@ class TBHierarchicalFields(DisplayedFields): # {{{
ans = [[k, False] for k in cats]
self.changed = True
elif pref_data_override:
- ph = {k:v for k,v in pref_data_override}
+ ph = dict(pref_data_override)
ans = [[k, ph.get(k, False)] for k in cats]
self.changed = True
else:
diff --git a/src/calibre/gui2/store/config/chooser/results_view.py b/src/calibre/gui2/store/config/chooser/results_view.py
index 50604f5c1f..8a2bbb64f7 100644
--- a/src/calibre/gui2/store/config/chooser/results_view.py
+++ b/src/calibre/gui2/store/config/chooser/results_view.py
@@ -16,7 +16,7 @@ class ResultsView(QTreeView):
def __init__(self, parent=None):
QTreeView.__init__(self,parent)
- self._model = Matches([p for p in store_plugins()])
+ self._model = Matches(list(store_plugins()))
self.setModel(self._model)
self.setIconSize(QSize(24, 24))
diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py
index 1dffddce40..8af5c2942b 100644
--- a/src/calibre/gui2/tag_browser/model.py
+++ b/src/calibre/gui2/tag_browser/model.py
@@ -636,7 +636,7 @@ class TagsModel(QAbstractItemModel): # {{{
key, (category_icon_map['user:'] if key.startswith('@') else category_icon_map['custom:'])))
if key.startswith('@'):
- path_parts = [p for p in key.split('.')]
+ path_parts = list(key.split('.'))
path = ''
last_category_node = self.root_item
tree_root = self.user_category_node_tree
@@ -1547,7 +1547,7 @@ class TagsModel(QAbstractItemModel): # {{{
self.use_position_based_index_on_next_recount = True
return True
- for c in sorted(list(user_cats.keys()), key=sort_key):
+ for c in sorted(user_cats.keys(), key=sort_key):
if icu_lower(c).startswith(ckey_lower):
if len(c) == len(ckey):
if strcmp(ckey, nkey) != 0 and \
@@ -1652,13 +1652,13 @@ class TagsModel(QAbstractItemModel): # {{{
if ucat.get(new_name, None) == item_category:
if ucat.pop(item_name, None) is not None:
# Only update the user_cats when something changes
- user_cats[k] = list([(n, c, 0) for n, c in ucat.items()])
+ user_cats[k] = [(n, c, 0) for n, c in ucat.items()]
elif ucat.get(item_name, None) == item_category:
# If the old name/item_category exists, rename it to the new
# name using del/add
del ucat[item_name]
ucat[new_name] = item_category
- user_cats[k] = list([(n, c, 0) for n, c in ucat.items()])
+ user_cats[k] = [(n, c, 0) for n, c in ucat.items()]
self.db.new_api.set_pref('user_categories', user_cats)
def delete_item_from_all_user_categories(self, item_name, item_category):
diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py
index 56759537ed..e386e08807 100644
--- a/src/calibre/gui2/tag_browser/ui.py
+++ b/src/calibre/gui2/tag_browser/ui.py
@@ -105,7 +105,7 @@ class TagBrowserMixin: # {{{
proxy_md = db.new_api.get_proxy_metadata(db.id(idx.row()))
items = proxy_md.get(current_cat)
if isinstance(items, str):
- items = list((items,))
+ items = [items,]
if items:
items_title = _('{category} for current book').format(category=cdn)
if len(items) > 4:
diff --git a/src/calibre/library/catalogs/epub_mobi.py b/src/calibre/library/catalogs/epub_mobi.py
index 0b2e24acf2..75b9140059 100644
--- a/src/calibre/library/catalogs/epub_mobi.py
+++ b/src/calibre/library/catalogs/epub_mobi.py
@@ -201,7 +201,7 @@ class EPUB_MOBI(CatalogPlugin):
if opts.preset not in available_presets:
if available_presets:
print(_('Error: Preset "{}" not found.').format(opts.preset))
- print(_('Stored presets: {}').format(', '.join([p for p in sorted(available_presets.keys())])))
+ print(_('Stored presets: {}').format(', '.join(list(sorted(available_presets.keys())))))
else:
print(_('Error: No stored presets.'))
return 1
diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py
index 0e0d85a46c..b60304c447 100644
--- a/src/calibre/library/catalogs/epub_mobi_builder.py
+++ b/src/calibre/library/catalogs/epub_mobi_builder.py
@@ -547,7 +547,7 @@ class CatalogBuilder:
AuthorSortMismatchException: author_sort mismatch detected
'''
- books_by_author = sorted(list(books_to_test), key=self._kf_books_by_author_sorter_author)
+ books_by_author = sorted(books_to_test, key=self._kf_books_by_author_sorter_author)
authors = [(record['author'], record['author_sort']) for record in books_by_author]
current_author = authors[0]
diff --git a/src/calibre/utils/bibtex.py b/src/calibre/utils/bibtex.py
index e5fa805ead..ec50351418 100644
--- a/src/calibre/utils/bibtex.py
+++ b/src/calibre/utils/bibtex.py
@@ -2603,7 +2603,7 @@ class BibTeX:
'''
Format authors for Bibtex compliance (get a list as input)
'''
- return self.utf8ToBibtex(' and '.join([author for author in item]))
+ return self.utf8ToBibtex(' and '.join(list(item)))
def stripUnmatchedSyntax(self, text, open_character, close_character):
'''
diff --git a/src/calibre/utils/fonts/sfnt/subset.py b/src/calibre/utils/fonts/sfnt/subset.py
index e3fedfe20b..843155631d 100644
--- a/src/calibre/utils/fonts/sfnt/subset.py
+++ b/src/calibre/utils/fonts/sfnt/subset.py
@@ -254,7 +254,7 @@ def main(args):
with open(iff, 'rb') as f:
orig = f.read()
- chars = [x for x in chars.split(',')]
+ chars = list(chars.split(','))
individual, ranges = set(), set()
def not_single(c):
diff --git a/src/calibre/utils/formatter.py b/src/calibre/utils/formatter.py
index bce17a8d38..ba3d8b33a4 100644
--- a/src/calibre/utils/formatter.py
+++ b/src/calibre/utils/formatter.py
@@ -878,11 +878,11 @@ class PythonTemplateContext:
@property
def attributes(self):
# return a list of attributes in the context object
- return sorted(list(self.attrs_set))
+ return sorted(self.attrs_set)
def __str__(self):
# return a string of the attribute with values separated by newlines
- attrs = sorted(list(self.attrs_set))
+ attrs = sorted(self.attrs_set)
ans = OrderedDict()
for k in attrs:
ans[k] = getattr(self, k, None)
diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py
index 3e9988d989..8f5672ec01 100644
--- a/src/calibre/utils/formatter_functions.py
+++ b/src/calibre/utils/formatter_functions.py
@@ -3169,7 +3169,7 @@ This function works only in the GUI and the content server.
return '1' if note is not None else ''
try:
notes_for_book = db.items_with_notes_in_book(mi.id)
- values = [v for v in notes_for_book.get(field_name, {}).values()]
+ values = list(notes_for_book.get(field_name, {}).values())
return db.field_metadata[field_name]['is_multiple'].get('list_to_ui', ', ').join(values)
except Exception as e:
traceback.print_exc()
diff --git a/src/calibre/utils/winreg/dde.py b/src/calibre/utils/winreg/dde.py
index 70c44b83be..3c9f0a5bde 100644
--- a/src/calibre/utils/winreg/dde.py
+++ b/src/calibre/utils/winreg/dde.py
@@ -55,7 +55,7 @@ DML_ERRORS = {
'UNFOUND_QUEUE_ID': (0x4011, 'An invalid transaction identifier was passed to a DDEML function. Once the application has returned from an XTYP_XACT_COMPLETE callback, the transaction identifier for that callback function is no longer valid.'), # noqa: E501
}
-DML_ERROR_TEXT = {code:text for (code, text) in itervalues(DML_ERRORS)}
+DML_ERROR_TEXT = dict(itervalues(DML_ERRORS))
user32 = windll.user32