write better list/set/dict comprehensions (auto-fix)

ruff 'C4'
This commit is contained in:
un-pogaz 2025-01-24 11:14:17 +01:00
parent a833a130fc
commit 6c54a656ba
52 changed files with 73 additions and 67 deletions

View File

@ -198,7 +198,7 @@ details and examples.
lines += [f'.. _calibredb-{language}-{cmd}:', ''] lines += [f'.. _calibredb-{language}-{cmd}:', '']
lines += [cmd, '~'*20, ''] lines += [cmd, '~'*20, '']
usage = parser.usage.strip() usage = parser.usage.strip()
usage = [i for i in usage.replace('%prog', 'calibredb').splitlines()] usage = list(usage.replace('%prog', 'calibredb').splitlines())
cmdline = ' '+usage[0] cmdline = ' '+usage[0]
usage = usage[1:] usage = usage[1:]
usage = [re.sub(rf'({cmd})([^a-zA-Z0-9])', r':command:`\1`\2', i) for i in usage] usage = [re.sub(rf'({cmd})([^a-zA-Z0-9])', r':command:`\1`\2', i) for i in usage]

View File

@ -124,7 +124,7 @@ class Bloomberg(BasicNewsRecipe):
cat = '<div class="cat">' + data['primaryCategory'] + '</div>' cat = '<div class="cat">' + data['primaryCategory'] + '</div>'
if 'abstract' in data and data['abstract'] and data['abstract'] is not None: if 'abstract' in data and data['abstract'] and data['abstract'] is not None:
subhead = '<div class="subhead"><ul><li>' + '</li><li>'.join([x for x in data['abstract']]) + '</li></ul></div>' subhead = '<div class="subhead"><ul><li>' + '</li><li>'.join(list(data['abstract'])) + '</li></ul></div>'
elif 'summary' in data and data['summary']: elif 'summary' in data and data['summary']:
subhead = '<div class="subhead"><p>' + data['summary'] + '</p></div>' subhead = '<div class="subhead"><p>' + data['summary'] + '</p></div>'

View File

@ -134,7 +134,7 @@ class Bloomberg(BasicNewsRecipe):
cat = '<div class="cat">' + data['primaryCategory'] + '</div>' cat = '<div class="cat">' + data['primaryCategory'] + '</div>'
if 'abstract' in data and data['abstract'] and data['abstract'] is not None: if 'abstract' in data and data['abstract'] and data['abstract'] is not None:
subhead = '<div class="subhead"><ul><li>' + '</li><li>'.join([x for x in data['abstract']]) + '</li></ul></div>' subhead = '<div class="subhead"><ul><li>' + '</li><li>'.join(list(data['abstract'])) + '</li></ul></div>'
elif 'summary' in data and data['summary']: elif 'summary' in data and data['summary']:
subhead = '<div class="subhead"><p>' + data['summary'] + '</p></div>' subhead = '<div class="subhead"><p>' + data['summary'] + '</p></div>'

View File

@ -13,6 +13,6 @@ class FactCheckOrg(BasicNewsRecipe):
masthead_url = 'http://factcheck.org/wp-content/themes/Streamline/images/headernew.jpg' masthead_url = 'http://factcheck.org/wp-content/themes/Streamline/images/headernew.jpg'
cover_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/')] feeds = [(u'Factcheck', u'feed://www.factcheck.org/feed/')]

View File

@ -21,7 +21,7 @@ class GryOnlinePl(BasicNewsRecipe):
keep_only_tags = [dict(name='div', attrs={'class': [ keep_only_tags = [dict(name='div', attrs={'class': [
'gc660', 'gc660 S013', 'news_endpage_tit', 'news_container', 'news']})] 'gc660', 'gc660 S013', 'news_endpage_tit', 'news_container', 'news']})]
remove_tags = [ 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 = [ feeds = [
(u'Newsy', 'http://www.gry-online.pl/rss/news.xml'), (u'Newsy', 'http://www.gry-online.pl/rss/news.xml'),
('Teksty', u'http://www.gry-online.pl/rss/teksty.xml')] ('Teksty', u'http://www.gry-online.pl/rss/teksty.xml')]

View File

@ -140,7 +140,7 @@ class Reuters(BasicNewsRecipe):
for y in x['templates']: for y in x['templates']:
if 'author' in y['cid']: if 'author' in y['cid']:
body += '<p>' body += '<p>'
auths = [x for x in y.get('authors_names', [])] auths = list(y.get('authors_names', []))
if auths: if auths:
body += ( body += (
'<div class="auth">' + 'By ' + ', '.join(auths) + '</div>' '<div class="auth">' + 'By ' + ', '.join(auths) + '</div>'

View File

@ -17,8 +17,14 @@ exclude = [
quote-style = 'single' quote-style = 'single'
[lint] [lint]
ignore = ['E402', 'E722', 'E741', 'UP012', 'UP030', 'UP032', 'UP038'] ignore = [
select = ['E', 'F', 'I', 'W', 'INT', 'Q', 'UP', 'YTT', 'TID'] '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] [lint.per-file-ignores]
"recipes/*" = ['UP'] "recipes/*" = ['UP']

View File

@ -357,7 +357,7 @@ class Translations(POT): # {{{
l = {} l = {}
lc_dataf = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lc_data.py') 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) 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...') self.info('Compiling main UI translation files...')
fmap = {f:self.mo_file(f) for f in self.po_files()} fmap = {f:self.mo_file(f) for f in self.po_files()}
files = [(f, fmap[f][1]) for f in self.po_files()] files = [(f, fmap[f][1]) for f in self.po_files()]

View File

@ -573,10 +573,10 @@ class CatalogPlugin(Plugin): # {{{
# Validate requested_fields # Validate requested_fields
if requested_fields - all_fields: if requested_fields - all_fields:
from calibre.library import current_library_name 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('invalid --fields specified: %s' % ', '.join(invalid_fields))
print("available fields in '%s': %s" % 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') raise ValueError('unable to generate catalog with specified fields')
fields = [x for x in of if x in all_fields] fields = [x for x in of if x in all_fields]

View File

@ -152,7 +152,7 @@ def main(opts, args, dbctx):
raise SystemExit(_('No book with id: %s in the database') % book_id) raise SystemExit(_('No book with id: %s in the database') % book_id)
if opts.field: if opts.field:
fields = {k: v for k, v in get_fields(dbctx)} fields = dict(get_fields(dbctx))
fields['title_sort'] = fields['sort'] fields['title_sort'] = fields['sort']
vals = {} vals = {}
for x in opts.field: for x in opts.field:

View File

@ -366,7 +366,7 @@ class CompositeField(OneToOneField):
for book_id in candidates: for book_id in candidates:
vals = self.get_value_with_cache(book_id, get_metadata) vals = self.get_value_with_cache(book_id, get_metadata)
if splitter: 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(): elif vals.strip():
length = 1 length = 1
else: else:

View File

@ -799,7 +799,7 @@ class LibraryDatabase:
with self.new_api.write_lock: with self.new_api.write_lock:
self.new_api._set_field(field, {book_id:val for book_id in ids}, allow_case_change=False) self.new_api._set_field(field, {book_id:val for book_id in ids}, allow_case_change=False)
if extras is not None: 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: if notify:
self.notify('metadata', list(ids)) self.notify('metadata', list(ids))

View File

@ -234,7 +234,7 @@ class ManyToOneTable(Table):
bcm[book] = item_id bcm[book] = item_id
def fix_link_table(self, db): 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) extra_item_ids = linked_item_ids - set(self.id_map)
if extra_item_ids: if extra_item_ids:
for item_id in extra_item_ids: for item_id in extra_item_ids:

View File

@ -1019,9 +1019,9 @@ class WritingTest(BaseTest):
cache.set_field('publisher', {1:'random'}) cache.set_field('publisher', {1:'random'})
cache.set_link_map('publisher', {'random': 'url2'}) cache.set_link_map('publisher', {'random': 'url2'})
links = cache.get_all_link_maps_for_book(1) links = cache.get_all_link_maps_for_book(1)
self.assertSetEqual({v for v in links.keys()}, {'tags', 'publisher'}, 'Wrong link keys') self.assertSetEqual(set(links.keys()), {'tags', 'publisher'}, 'Wrong link keys')
self.assertSetEqual({v for v in links['tags'].keys()}, {'foo', }, 'Should be "foo"') self.assertSetEqual(set(links['tags'].keys()), {'foo', }, 'Should be "foo"')
self.assertSetEqual({v for v in links['publisher'].keys()}, {'random', }, 'Should be "random"') self.assertSetEqual(set(links['publisher'].keys()), {'random', }, 'Should be "random"')
self.assertEqual('url', links['tags']['foo'], 'link for tag foo is wrong') self.assertEqual('url', links['tags']['foo'], 'link for tag foo is wrong')
self.assertEqual('url2', links['publisher']['random'], 'link for publisher random is wrong') self.assertEqual('url2', links['publisher']['random'], 'link for publisher random is wrong')

View File

@ -129,7 +129,7 @@ def clean_identifier(typ, val):
def adapt_identifiers(to_tuple, x): def adapt_identifiers(to_tuple, x):
if not isinstance(x, dict): 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 = {} ans = {}
for k, v in iteritems(x): for k, v in iteritems(x):
k, v = clean_identifier(k, v) k, v = clean_identifier(k, v)

View File

@ -2260,7 +2260,7 @@ class KOBOTOUCH(KOBO):
return extra_sheet return extra_sheet
def get_extra_css_rules(self, sheet, css_rule): 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): def get_extra_css_rules_widow_orphan(self, sheet):
from css_parser.css import CSSRule from css_parser.css import CSSRule

View File

@ -487,7 +487,7 @@ class MTP_DEVICE(BASE):
self.report_progress(0, _('Transferring books to device...')) self.report_progress(0, _('Transferring books to device...'))
i, total = 0, len(files) 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): for infile, fname, mi in zip(files, names, metadata):
path = self.create_upload_path(prefix, mi, fname, routing) path = self.create_upload_path(prefix, mi, fname, routing)

View File

@ -105,7 +105,7 @@ class FB2Input(InputFormatPlugin):
# Handle links of type note and cite # 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('#')} 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', '')} 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): for cite, a in iteritems(cites):
note = notes.get(cite, None) note = notes.get(cite, None)
if note: if note:

View File

@ -318,7 +318,7 @@ ColorTheme = namedtuple('ColorTheme', 'color1 color2 contrast_color1 contrast_co
def to_theme(x): 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') fallback_colors = to_theme('ffffff 000000 000000 ffffff')

View File

@ -128,7 +128,7 @@ def read_single_border(parent, edge, XPath, get):
width = min(96, max(2, float(sz))) / 8 width = min(96, max(2, float(sz))) / 8
except (ValueError, TypeError): except (ValueError, TypeError):
pass 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'): def read_border(parent, dest, XPath, get, border_edges=border_edges, name='pBdr'):

View File

@ -108,7 +108,7 @@ class LrsParser:
def process_paragraph(self, tag): def process_paragraph(self, tag):
p = Paragraph() p = Paragraph()
contents = [i for i in tag.contents] contents = list(tag.contents)
if contents: if contents:
if isinstance(contents[0], NavigableString): if isinstance(contents[0], NavigableString):
contents[0] = contents[0].string.lstrip() contents[0] = contents[0].string.lstrip()

View File

@ -127,7 +127,7 @@ def uniq(vals, kmap=icu_lower):
lvals = (kmap(x) for x in vals) lvals = (kmap(x) for x in vals)
seen = set() seen = set()
seen_add = seen.add 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): def compile_rules(rules):

View File

@ -63,7 +63,7 @@ def uniq(vals):
vals = vals or () vals = vals or ()
seen = set() seen = set()
seen_add = seen.add 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): def get_metadata(stream, extract_cover=True):

View File

@ -34,7 +34,7 @@ def uniq(vals):
vals = vals or () vals = vals or ()
seen = set() seen = set()
seen_add = seen.add 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): def dump_dict(cats):

View File

@ -564,9 +564,9 @@ class Worker(Thread): # Get details {{{
res = self.tostring(elem, encoding='unicode', method='text') res = self.tostring(elem, encoding='unicode', method='text')
if only_printable: if only_printable:
try: try:
filtered_characters = list(s for s in res if s.isprintable()) filtered_characters = [s for s in res if s.isprintable()]
except AttributeError: 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) res = ''.join(filtered_characters)
return res.strip() return res.strip()
@ -1395,8 +1395,8 @@ class Amazon(Source):
q['field-keywords'] += ' ' + q.pop(f, '') q['field-keywords'] += ' ' + q.pop(f, '')
q['field-keywords'] = q['field-keywords'].strip() q['field-keywords'] = q['field-keywords'].strip()
encoded_q = dict([(x.encode('utf-8', 'ignore'), y.encode( encoded_q = {x.encode('utf-8', 'ignore'): y.encode(
'utf-8', 'ignore')) for x, y in q.items()]) 'utf-8', 'ignore') for x, y in q.items()}
url_query = urlencode(encoded_q) url_query = urlencode(encoded_q)
# amazon's servers want IRIs with unicode characters not percent esaped # amazon's servers want IRIs with unicode characters not percent esaped
parts = [] parts = []

View File

@ -180,7 +180,7 @@ class Option:
self.name, self.type, self.default, self.label, self.desc = (name, self.name, self.type, self.default, self.label, self.desc = (name,
type_, default, label, desc) type_, default, label, desc)
if choices and not isinstance(choices, dict): 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 self.choices = choices

View File

@ -119,7 +119,7 @@ def uniq(vals, kmap=icu_lower):
lvals = (kmap(x) for x in vals) lvals = (kmap(x) for x in vals)
seen = set() seen = set()
seen_add = seen.add 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=()): def map_tags(tags, rules=()):

View File

@ -26,7 +26,7 @@ def uniq(vals):
vals = vals or () vals = vals or ()
seen = set() seen = set()
seen_add = seen.add 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: # {{{ class EXTHHeader: # {{{

View File

@ -214,7 +214,7 @@ class MultipleCovers(BaseError):
self.all_locations = [(name, lnum, None) for lnum in sorted(locs)] self.all_locations = [(name, lnum, None) for lnum in sorted(locs)]
def __call__(self, container): 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.remove_from_xml(e) for e in items[1:]]
container.dirty(self.name) container.dirty(self.name)
return True return True

View File

@ -112,7 +112,7 @@ def change_font_in_sheet(container, sheet, old_name, new_name, sheet_name):
elif rule.type == rule.FONT_FACE_RULE: elif rule.type == rule.FONT_FACE_RULE:
ff = rule.style.getProperty('font-family') ff = rule.style.getProperty('font-family')
if ff is not None: 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: if old_name in families:
changed = True changed = True
removals.append(rule) removals.append(rule)

View File

@ -117,7 +117,7 @@ def corrected_case_for_name(container, name):
correctx = x correctx = x
else: else:
try: 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: except OSError:
return None # one of the non-terminal components of name is a file instead of a directory return None # one of the non-terminal components of name is a file instead of a directory
for q in candidates: for q in candidates:
@ -213,7 +213,7 @@ def lead_text(top_elem, num_words=10):
if attr == 'text': if attr == 'text':
if elem is not top_elem: if elem is not top_elem:
stack.append((elem, 'tail')) 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]) return ' '.join(words[:num_words])

View File

@ -177,7 +177,7 @@ class ConvertAction(InterfaceActionWithLibraryDrop):
converted_func, extra_job_args=[], rows_are_ids=False): converted_func, extra_job_args=[], rows_are_ids=False):
for func, args, desc, fmt, id, temp_files in jobs: for func, args, desc, fmt, id, temp_files in jobs:
func, _, parts = func.partition(':') func, _, parts = func.partition(':')
parts = {x for x in parts.split(';')} parts = set(parts.split(';'))
input_file = args[0] input_file = args[0]
input_fmt = os.path.splitext(input_file)[1] input_fmt = os.path.splitext(input_file)[1]
core_usage = 1 core_usage = 1

View File

@ -46,7 +46,7 @@ class PreferencesAction(InterfaceAction):
def initialization_complete(self): def initialization_complete(self):
# Add the individual preferences to the menu. # Add the individual preferences to the menu.
# First, sort them into the same order as shown in the preferences dialog # 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) key=lambda p: p.category_order * 100 + p.name_order)
pm = self.preferences_menu pm = self.preferences_menu

View File

@ -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): def get_custom_columns_to_display_in_editor(db):
return list([k[0] for k in return [k[0] for k in
get_field_list(db, use_defaults=db.prefs['edit_metadata_ignore_display_order']) if k[1]]) 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): def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, parent=None):

View File

@ -230,7 +230,7 @@ class TagCategories(QDialog, Ui_TagCategories):
def fill_applied_items(self): def fill_applied_items(self):
ccn = self.current_cat_name ccn = self.current_cat_name
if ccn: 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) self.applied_items.sort(key=self.item_sort_key)
else: else:
self.applied_items = [] self.applied_items = []

View File

@ -75,9 +75,9 @@ class TagEditor(QDialog, Ui_TagEditor):
self.applied_tags.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.applied_tags.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
if key: if key:
all_tags = [tag for tag in self.db.all_custom(label=key)] all_tags = list(self.db.all_custom(label=key))
else: 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) all_tags = sorted(set(all_tags) - set(tags), key=sort_key)
self.all_tags_model = QStringListModel(all_tags) self.all_tags_model = QStringListModel(all_tags)
p = QSortFilterProxyModel() p = QSortFilterProxyModel()

View File

@ -958,7 +958,7 @@ def evaluate(book, context):
self.textbox.set_clicked_line_numbers(set()) self.textbox.set_clicked_line_numbers(set())
def set_all_button_pressed(self): 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): def toggle_button_pressed(self):
ln = self.breakpoint_line_box.value() ln = self.breakpoint_line_box.value()

View File

@ -560,7 +560,7 @@ class CcTextDelegate(StyledItemDelegate, UpdateEditorGeometry, EditableTextDeleg
editor = EditWithComplete(parent) editor = EditWithComplete(parent)
editor.set_separator(None) editor.set_separator(None)
editor.set_clear_button_enabled(False) 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) editor.update_items_cache(complete_items)
else: else:
editor = QLineEdit(parent) editor = QLineEdit(parent)

View File

@ -1335,7 +1335,7 @@ class BooksView(QTableView): # {{{
def visible_columns(self): def visible_columns(self):
h = self.horizontalHeader() h = self.horizontalHeader()
logical_indices = (x for x in range(h.count()) if not h.isSectionHidden(x)) 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) return (rmap[h.visualIndex(x)] for x in logical_indices if h.visualIndex(x) > -1)
def refresh_book_details(self, force=False): def refresh_book_details(self, force=False):

View File

@ -1281,7 +1281,7 @@ class EditRules(QWidget): # {{{
def move_rows(self, moving_up=True): def move_rows(self, moving_up=True):
sm = self.rules_view.selectionModel() 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:
if rows[0].row() == (0 if moving_up else self.model.rowCount() - 1): if rows[0].row() == (0 if moving_up else self.model.rowCount() - 1):
return return

View File

@ -353,7 +353,7 @@ class TBPartitionedFields(DisplayedFields): # {{{
ans = [[k, True] for k in cats.keys()] ans = [[k, True] for k in cats.keys()]
self.changed = True self.changed = True
elif pref_data_override: 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()] ans = [[k, po.get(k, True)] for k in cats.keys()]
self.changed = True self.changed = True
else: else:
@ -389,7 +389,7 @@ class BDVerticalCats(DisplayedFields): # {{{
ans = [[k, False] for k in cats] ans = [[k, False] for k in cats]
self.changed = True self.changed = True
elif pref_data_override: 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] ans = [[k, ph.get(k, False)] for k in cats]
self.changed = True self.changed = True
else: else:

View File

@ -37,7 +37,7 @@ class TBHierarchicalFields(DisplayedFields): # {{{
ans = [[k, False] for k in cats] ans = [[k, False] for k in cats]
self.changed = True self.changed = True
elif pref_data_override: 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] ans = [[k, ph.get(k, False)] for k in cats]
self.changed = True self.changed = True
else: else:

View File

@ -16,7 +16,7 @@ class ResultsView(QTreeView):
def __init__(self, parent=None): def __init__(self, parent=None):
QTreeView.__init__(self,parent) QTreeView.__init__(self,parent)
self._model = Matches([p for p in store_plugins()]) self._model = Matches(list(store_plugins()))
self.setModel(self._model) self.setModel(self._model)
self.setIconSize(QSize(24, 24)) self.setIconSize(QSize(24, 24))

View File

@ -636,7 +636,7 @@ class TagsModel(QAbstractItemModel): # {{{
key, (category_icon_map['user:'] if key.startswith('@') else category_icon_map['custom:']))) key, (category_icon_map['user:'] if key.startswith('@') else category_icon_map['custom:'])))
if key.startswith('@'): if key.startswith('@'):
path_parts = [p for p in key.split('.')] path_parts = list(key.split('.'))
path = '' path = ''
last_category_node = self.root_item last_category_node = self.root_item
tree_root = self.user_category_node_tree tree_root = self.user_category_node_tree
@ -1547,7 +1547,7 @@ class TagsModel(QAbstractItemModel): # {{{
self.use_position_based_index_on_next_recount = True self.use_position_based_index_on_next_recount = True
return 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 icu_lower(c).startswith(ckey_lower):
if len(c) == len(ckey): if len(c) == len(ckey):
if strcmp(ckey, nkey) != 0 and \ if strcmp(ckey, nkey) != 0 and \
@ -1652,13 +1652,13 @@ class TagsModel(QAbstractItemModel): # {{{
if ucat.get(new_name, None) == item_category: if ucat.get(new_name, None) == item_category:
if ucat.pop(item_name, None) is not None: if ucat.pop(item_name, None) is not None:
# Only update the user_cats when something changes # 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: elif ucat.get(item_name, None) == item_category:
# If the old name/item_category exists, rename it to the new # If the old name/item_category exists, rename it to the new
# name using del/add # name using del/add
del ucat[item_name] del ucat[item_name]
ucat[new_name] = item_category 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) self.db.new_api.set_pref('user_categories', user_cats)
def delete_item_from_all_user_categories(self, item_name, item_category): def delete_item_from_all_user_categories(self, item_name, item_category):

View File

@ -105,7 +105,7 @@ class TagBrowserMixin: # {{{
proxy_md = db.new_api.get_proxy_metadata(db.id(idx.row())) proxy_md = db.new_api.get_proxy_metadata(db.id(idx.row()))
items = proxy_md.get(current_cat) items = proxy_md.get(current_cat)
if isinstance(items, str): if isinstance(items, str):
items = list((items,)) items = [items,]
if items: if items:
items_title = _('{category} for current book').format(category=cdn) items_title = _('{category} for current book').format(category=cdn)
if len(items) > 4: if len(items) > 4:

View File

@ -201,7 +201,7 @@ class EPUB_MOBI(CatalogPlugin):
if opts.preset not in available_presets: if opts.preset not in available_presets:
if available_presets: if available_presets:
print(_('Error: Preset "{}" not found.').format(opts.preset)) 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: else:
print(_('Error: No stored presets.')) print(_('Error: No stored presets.'))
return 1 return 1

View File

@ -547,7 +547,7 @@ class CatalogBuilder:
AuthorSortMismatchException: author_sort mismatch detected 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] authors = [(record['author'], record['author_sort']) for record in books_by_author]
current_author = authors[0] current_author = authors[0]

View File

@ -2603,7 +2603,7 @@ class BibTeX:
''' '''
Format authors for Bibtex compliance (get a list as input) 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): def stripUnmatchedSyntax(self, text, open_character, close_character):
''' '''

View File

@ -254,7 +254,7 @@ def main(args):
with open(iff, 'rb') as f: with open(iff, 'rb') as f:
orig = f.read() orig = f.read()
chars = [x for x in chars.split(',')] chars = list(chars.split(','))
individual, ranges = set(), set() individual, ranges = set(), set()
def not_single(c): def not_single(c):

View File

@ -878,11 +878,11 @@ class PythonTemplateContext:
@property @property
def attributes(self): def attributes(self):
# return a list of attributes in the context object # return a list of attributes in the context object
return sorted(list(self.attrs_set)) return sorted(self.attrs_set)
def __str__(self): def __str__(self):
# return a string of the attribute with values separated by newlines # return a string of the attribute with values separated by newlines
attrs = sorted(list(self.attrs_set)) attrs = sorted(self.attrs_set)
ans = OrderedDict() ans = OrderedDict()
for k in attrs: for k in attrs:
ans[k] = getattr(self, k, None) ans[k] = getattr(self, k, None)

View File

@ -3169,7 +3169,7 @@ This function works only in the GUI and the content server.
return '1' if note is not None else '' return '1' if note is not None else ''
try: try:
notes_for_book = db.items_with_notes_in_book(mi.id) 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) return db.field_metadata[field_name]['is_multiple'].get('list_to_ui', ', ').join(values)
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()

View File

@ -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 '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 user32 = windll.user32