diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index c1fc63d208..3dc777a64a 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -1,4 +1,3 @@ - ''' E-book management software''' __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -13,7 +12,7 @@ if not hasenv('CALIBRE_SHOW_DEPRECATION_WARNINGS'): warnings.simplefilter('ignore', DeprecationWarning) try: os.getcwd() -except EnvironmentError: +except OSError: os.chdir(os.path.expanduser('~')) from calibre.constants import (iswindows, ismacos, islinux, isfrozen, @@ -372,7 +371,7 @@ class CurrentDir: def __exit__(self, *args): try: os.chdir(self.cwd) - except EnvironmentError: + except OSError: # The previous CWD no longer exists pass diff --git a/src/calibre/constants.py b/src/calibre/constants.py index d305f7d69f..bded43cacf 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -118,7 +118,7 @@ def _get_cache_dir(): confcache = os.path.join(config_dir, 'caches') try: os.makedirs(confcache) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise if isportable: @@ -129,7 +129,7 @@ def _get_cache_dir(): try: os.makedirs(ans) return ans - except EnvironmentError as err: + except OSError as err: if err.errno == errno.EEXIST: return ans @@ -151,7 +151,7 @@ def _get_cache_dir(): candidate = confcache try: os.makedirs(candidate) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: candidate = confcache return candidate diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index 964e61dbdb..1587d20391 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 6b67987799..12690e3a35 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1814,7 +1814,7 @@ class StoreWeightlessBooksStore(StoreBase): class StoreWHSmithUKStore(StoreBase): name = 'WH Smith UK' author = 'Charles Haley' - description = u"Shop for savings on Books, discounted Magazine subscriptions and great prices on Stationery, Toys & Games" + description = "Shop for savings on Books, discounted Magazine subscriptions and great prices on Stationery, Toys & Games" actual_plugin = 'calibre.gui2.store.stores.whsmith_uk_plugin:WHSmithUKStore' headquarters = 'UK' diff --git a/src/calibre/customize/profiles.py b/src/calibre/customize/profiles.py index 8683d20e5b..08452b2062 100644 --- a/src/calibre/customize/profiles.py +++ b/src/calibre/customize/profiles.py @@ -31,8 +31,8 @@ class Plugin(_Plugin): self.fsizes = [] for (name, num), size in zip(FONT_SIZES, fsizes): self.fsizes.append((name, num, float(size))) - self.fnames = dict((name, sz) for name, _, sz in self.fsizes if name) - self.fnums = dict((num, sz) for _, num, sz in self.fsizes if num) + self.fnames = {name: sz for name, _, sz in self.fsizes if name} + self.fnums = {num: sz for _, num, sz in self.fsizes if num} self.width_pts = self.width * 72./self.dpi self.height_pts = self.height * 72./self.dpi @@ -486,7 +486,7 @@ class SonyReaderOutput(OutputProfile): dpi = 168.451 fbase = 12 fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24] - unsupported_unicode_chars = [u'\u201f', u'\u201b'] + unsupported_unicode_chars = ['\u201f', '\u201b'] epub_periodical_format = 'sony' # periodical_date_in_title = False diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index 25b8348293..cd1183af9b 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -769,8 +768,7 @@ initialize_plugins() def initialized_plugins(): - for plugin in _initialized_plugins: - yield plugin + yield from _initialized_plugins # }}} @@ -786,7 +784,7 @@ def build_plugin(path): if '__init__.py' not in names: prints(path, ' is not a valid plugin') raise SystemExit(1) - t = PersistentTemporaryFile(u'.zip') + t = PersistentTemporaryFile('.zip') with ZipFile(t, 'w', ZIP_STORED) as zf: zf.add_dir(path, simple_filter=lambda x:x in {'.git', '.bzr', '.svn', '.hg'}) t.close() @@ -852,7 +850,7 @@ def main(args=sys.argv): for plugin in initialized_plugins(): type_len, name_len = max(type_len, len(plugin.type)), max(name_len, len(plugin.name)) fmt = '%-{}s%-{}s%-15s%-15s%s'.format(type_len+1, name_len+1) - print(fmt%tuple(('Type|Name|Version|Disabled|Site Customization'.split('|')))) + print(fmt%tuple('Type|Name|Version|Disabled|Site Customization'.split('|'))) print() for plugin in initialized_plugins(): print(fmt%( diff --git a/src/calibre/customize/zipplugin.py b/src/calibre/customize/zipplugin.py index b7d212da05..3fb6c7de34 100644 --- a/src/calibre/customize/zipplugin.py +++ b/src/calibre/customize/zipplugin.py @@ -340,9 +340,9 @@ class CalibrePluginFinder: break else: if self._identifier_pat.match(plugin_name) is None: - raise InvalidPlugin(( + raise InvalidPlugin( 'The plugin at %r uses an invalid import name: %r' % - (path_to_zip_file, plugin_name))) + (path_to_zip_file, plugin_name)) pynames = [x for x in names if x.endswith('.py')] diff --git a/src/calibre/db/__init__.py b/src/calibre/db/__init__.py index 31cc5f0e96..75d9fccc4b 100644 --- a/src/calibre/db/__init__.py +++ b/src/calibre/db/__init__.py @@ -77,10 +77,10 @@ def get_data_as_dict(self, prefix=None, authors_as_string=False, ids=None, conve prefix = backend.library_path fdata = backend.custom_column_num_map - FIELDS = set(['title', 'sort', 'authors', 'author_sort', 'publisher', + FIELDS = {'title', 'sort', 'authors', 'author_sort', 'publisher', 'rating', 'timestamp', 'size', 'tags', 'comments', 'series', 'series_index', 'uuid', 'pubdate', 'last_modified', 'identifiers', - 'languages']).union(set(fdata)) + 'languages'}.union(set(fdata)) for x, data in iteritems(fdata): if data['datatype'] == 'series': FIELDS.add('%d_index'%x) diff --git a/src/calibre/db/adding.py b/src/calibre/db/adding.py index 299780ec45..c2ffd5901a 100644 --- a/src/calibre/db/adding.py +++ b/src/calibre/db/adding.py @@ -93,7 +93,7 @@ def listdir(root, sort_by_mtime=False): def safe_mtime(x): try: return os.path.getmtime(x) - except EnvironmentError: + except OSError: return time.time() items = sorted(items, key=safe_mtime) @@ -230,8 +230,7 @@ def cdb_find_in_dir(dirpath, single_book_per_directory, compiled_rules): def cdb_recursive_find(root, single_book_per_directory=True, compiled_rules=()): root = os.path.abspath(root) for dirpath in os.walk(root): - for formats in cdb_find_in_dir(dirpath[0], single_book_per_directory, compiled_rules): - yield formats + yield from cdb_find_in_dir(dirpath[0], single_book_per_directory, compiled_rules) def add_catalog(cache, path, title, dbapi=None): diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index 66adc38089..43817e8dcb 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -151,18 +151,18 @@ class DBPrefs(dict): # {{{ self.__setitem__(key, val) def get_namespaced(self, namespace, key, default=None): - key = u'namespaced:%s:%s'%(namespace, key) + key = 'namespaced:%s:%s'%(namespace, key) try: return dict.__getitem__(self, key) except KeyError: return default def set_namespaced(self, namespace, key, val): - if u':' in key: + if ':' in key: raise KeyError('Colons are not allowed in keys') - if u':' in namespace: + if ':' in namespace: raise KeyError('Colons are not allowed in the namespace') - key = u'namespaced:%s:%s'%(namespace, key) + key = 'namespaced:%s:%s'%(namespace, key) self[key] = val def write_serialized(self, library_path): @@ -261,7 +261,7 @@ def IdentifiersConcat(): '''String concatenation aggregator for the identifiers map''' def step(ctxt, key, val): - ctxt.append(u'%s:%s'%(key, val)) + ctxt.append('%s:%s'%(key, val)) def finalize(ctxt): try: @@ -402,7 +402,7 @@ def set_global_state(backend): def rmtree_with_retry(path, sleep_time=1): try: shutil.rmtree(path) - except EnvironmentError as e: + except OSError as e: if e.errno == errno.ENOENT and not os.path.exists(path): return time.sleep(sleep_time) # In case something has temporarily locked a file @@ -645,7 +645,7 @@ class DB: prints('found user category case overlap', catmap[uc]) cat = catmap[uc][0] suffix = 1 - while icu_lower((cat + str(suffix))) in catmap: + while icu_lower(cat + str(suffix)) in catmap: suffix += 1 prints('Renaming user category %s to %s'%(cat, cat+str(suffix))) user_cats[cat + str(suffix)] = user_cats[cat] @@ -759,7 +759,7 @@ class DB: x = [y.strip() for y in x if y.strip()] x = [y.decode(preferred_encoding, 'replace') if not isinstance(y, str) else y for y in x] - return [u' '.join(y.split()) for y in x] + return [' '.join(y.split()) for y in x] else: return x if x is None or isinstance(x, str) else \ x.decode(preferred_encoding, 'replace') @@ -824,7 +824,7 @@ class DB: else: is_category = False is_m = v['multiple_seps'] - tn = 'custom_column_{0}'.format(v['num']) + tn = 'custom_column_{}'.format(v['num']) self.field_metadata.add_custom_field(label=v['label'], table=tn, column='value', datatype=v['datatype'], colnum=v['num'], name=v['name'], display=v['display'], @@ -1428,7 +1428,7 @@ class DB: path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg')) try: return utcfromtimestamp(os.stat(path).st_mtime) - except EnvironmentError: + except OSError: pass # Cover doesn't exist def copy_cover_to(self, path, dest, windows_atomic_move=None, use_hardlink=False, report_file_size=None): @@ -1444,11 +1444,11 @@ class DB: if os.access(path, os.R_OK): try: f = lopen(path, 'rb') - except (IOError, OSError): + except OSError: time.sleep(0.2) try: f = lopen(path, 'rb') - except (IOError, OSError) as e: + except OSError as e: # Ensure the path that caused this error is reported raise Exception('Failed to open %r with error: %s' % (path, e)) @@ -1478,13 +1478,13 @@ class DB: path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg')) try: stat = os.stat(path) - except EnvironmentError: + except OSError: return False, None, None if abs(timestamp - stat.st_mtime) < 0.1: return True, None, None try: f = lopen(path, 'rb') - except (IOError, OSError): + except OSError: time.sleep(0.2) f = lopen(path, 'rb') with f: @@ -1519,7 +1519,7 @@ class DB: if os.path.exists(path): try: os.remove(path) - except (IOError, OSError): + except OSError: time.sleep(0.2) os.remove(path) else: @@ -1529,7 +1529,7 @@ class DB: else: try: save_cover_data_to(data, path) - except (IOError, OSError): + except OSError: time.sleep(0.2) save_cover_data_to(data, path) @@ -1615,7 +1615,7 @@ class DB: # wrong in the rest of this function, at least the file is # not deleted os.rename(old_path, dest) - except EnvironmentError as e: + except OSError as e: if getattr(e, 'errno', None) != errno.ENOENT: # Failing to rename the old format will at worst leave a # harmless orphan, so log and ignore the error @@ -1727,11 +1727,11 @@ class DB: try: with lopen(path, 'wb') as f: f.write(raw) - except EnvironmentError: + except OSError: exc_info = sys.exc_info() try: os.makedirs(os.path.dirname(path)) - except EnvironmentError as err: + except OSError as err: if err.errno == errno.EEXIST: # Parent directory already exists, re-raise original exception reraise(*exc_info) @@ -1810,8 +1810,7 @@ class DB: return frozenset(r[0] for r in self.execute('SELECT book FROM books_plugin_data WHERE name=?', (name,))) def annotations_for_book(self, book_id, fmt, user_type, user): - for x in annotations_for_book(self.conn, book_id, fmt, user_type, user): - yield x + yield from annotations_for_book(self.conn, book_id, fmt, user_type, user) def search_annotations(self, fts_engine_query, use_stemming, highlight_start, highlight_end, snippet_size, annotation_type, @@ -2080,18 +2079,18 @@ class DB: for loc in old_dirs: try: rmtree_with_retry(loc) - except EnvironmentError as e: + except OSError as e: if os.path.exists(loc): prints('Failed to delete:', loc, 'with error:', as_unicode(e)) for loc in old_files: try: os.remove(loc) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: prints('Failed to delete:', loc, 'with error:', as_unicode(e)) try: os.rmdir(odir) - except EnvironmentError: + except OSError: pass self.conn # Connect to the moved metadata.db progress(_('Completed'), total, total) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 09afc7a4a5..a50792e9e3 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -1327,7 +1327,7 @@ class Cache: try: return self.backend.read_backup(path) - except EnvironmentError: + except OSError: return None @write_api diff --git a/src/calibre/db/categories.py b/src/calibre/db/categories.py index 512feff4d0..685f303832 100644 --- a/src/calibre/db/categories.py +++ b/src/calibre/db/categories.py @@ -44,7 +44,7 @@ class Tag: @property def string_representation(self): - return u'%s:%s:%s:%s:%s'%(self.name, self.count, self.id, self.state, self.category) + return '%s:%s:%s:%s:%s'%(self.name, self.count, self.id, self.state, self.category) def __str__(self): return self.string_representation diff --git a/src/calibre/db/cli/cmd_add.py b/src/calibre/db/cli/cmd_add.py index 298d4453b7..5684cfc6a4 100644 --- a/src/calibre/db/cli/cmd_add.py +++ b/src/calibre/db/cli/cmd_add.py @@ -263,7 +263,7 @@ def do_add( try: with lopen(mi.cover, 'rb') as f: cover_data = f.read() - except EnvironmentError: + except OSError: pass book_title, ids, mids, dups = dbctx.run( @@ -462,8 +462,8 @@ def main(opts, args, dbctx): lcodes = [canonicalize_lang(x) for x in (opts.languages or '').split(',')] lcodes = [x for x in lcodes if x] identifiers = (x.partition(':')[::2] for x in opts.identifier) - identifiers = dict((k.strip(), v.strip()) for k, v in identifiers - if k.strip() and v.strip()) + identifiers = {k.strip(): v.strip() for k, v in identifiers + if k.strip() and v.strip()} if opts.empty: do_add_empty( dbctx, opts.title, aut, opts.isbn, tags, opts.series, opts.series_index, diff --git a/src/calibre/db/cli/cmd_backup_metadata.py b/src/calibre/db/cli/cmd_backup_metadata.py index 57edc62c05..edcd8b268f 100644 --- a/src/calibre/db/cli/cmd_backup_metadata.py +++ b/src/calibre/db/cli/cmd_backup_metadata.py @@ -54,7 +54,7 @@ class BackupProgress: else: self.count += 1 prints( - u'%.1f%% %s - %s' % ((self.count * 100) / float(self.total), book_id, + '%.1f%% %s - %s' % ((self.count * 100) / float(self.total), book_id, getattr(mi, 'title', 'Unknown')) ) diff --git a/src/calibre/db/delete_service.py b/src/calibre/db/delete_service.py index f5fd837d21..c79808d195 100644 --- a/src/calibre/db/delete_service.py +++ b/src/calibre/db/delete_service.py @@ -88,7 +88,7 @@ class DeleteService(Thread): basename = '%d - %s' % (c, os.path.basename(path)) try: shutil.move(path, dest) - except EnvironmentError: + except OSError: if os.path.isdir(path): # shutil.move may have partially copied the directory, # so the subsequent call to move() will fail as the diff --git a/src/calibre/db/fields.py b/src/calibre/db/fields.py index 5f27cae4f7..efbac26aa1 100644 --- a/src/calibre/db/fields.py +++ b/src/calibre/db/fields.py @@ -328,8 +328,7 @@ class CompositeField(OneToOneField): for v in vals: if v: val_map[v].add(book_id) - for val, book_ids in iteritems(val_map): - yield val, book_ids + yield from iteritems(val_map) def iter_counts(self, candidates, get_metadata=None): val_map = defaultdict(set) @@ -343,8 +342,7 @@ class CompositeField(OneToOneField): else: length = 0 val_map[length].add(book_id) - for val, book_ids in iteritems(val_map): - yield val, book_ids + yield from iteritems(val_map) def get_composite_categories(self, tag_class, book_rating_map, book_ids, is_multiple, get_metadata): @@ -437,8 +435,7 @@ class OnDeviceField(OneToOneField): val_map = defaultdict(set) for book_id in candidates: val_map[self.for_book(book_id, default_value=default_value)].add(book_id) - for val, book_ids in iteritems(val_map): - yield val, book_ids + yield from iteritems(val_map) class LazySortMap: @@ -562,8 +559,7 @@ class ManyToManyField(Field): cbm = self.table.book_col_map for book_id in candidates: val_map[len(cbm.get(book_id, ()))].add(book_id) - for count, book_ids in iteritems(val_map): - yield count, book_ids + yield from iteritems(val_map) @property def book_value_map(self): diff --git a/src/calibre/db/legacy.py b/src/calibre/db/legacy.py index 414e0d3209..3b90bad0e6 100644 --- a/src/calibre/db/legacy.py +++ b/src/calibre/db/legacy.py @@ -29,7 +29,7 @@ def cleanup_tags(tags): tags = [x.strip().replace(',', ';') for x in tags if x.strip()] tags = [x.decode(preferred_encoding, 'replace') if isbytestring(x) else x for x in tags] - tags = [u' '.join(x.split()) for x in tags] + tags = [' '.join(x.split()) for x in tags] ans, seen = [], set() for tag in tags: if tag.lower() not in seen: @@ -684,8 +684,7 @@ class LibraryDatabase: self.new_api.refresh_ondevice() def tags_older_than(self, tag, delta, must_have_tag=None, must_have_authors=None): - for book_id in sorted(self.new_api.tags_older_than(tag, delta=delta, must_have_tag=must_have_tag, must_have_authors=must_have_authors)): - yield book_id + yield from sorted(self.new_api.tags_older_than(tag, delta=delta, must_have_tag=must_have_tag, must_have_authors=must_have_authors)) def sizeof_format(self, index, fmt, index_is_id=False): book_id = index if index_is_id else self.id(index) @@ -848,8 +847,7 @@ class LibraryDatabase: # Private interface {{{ def __iter__(self): - for row in self.data.iterall(): - yield row + yield from self.data.iterall() def _get_next_series_num_for_list(self, series_indices): return _get_next_series_num_for_list(series_indices) diff --git a/src/calibre/db/restore.py b/src/calibre/db/restore.py index 77ada98152..c31c110270 100644 --- a/src/calibre/db/restore.py +++ b/src/calibre/db/restore.py @@ -42,7 +42,7 @@ class Restorer(Cache): class Restore(Thread): def __init__(self, library_path, progress_callback=None): - super(Restore, self).__init__() + super().__init__() if isbytestring(library_path): library_path = library_path.decode(filesystem_encoding) self.src_library_path = os.path.abspath(library_path) @@ -107,7 +107,7 @@ class Restore(Thread): try: tdir = TemporaryDirectory('_rlib', dir=basedir) tdir.__enter__() - except EnvironmentError: + except OSError: # In case we dont have permissions to create directories in the # parent folder of the src library tdir = TemporaryDirectory('_rlib') @@ -279,7 +279,7 @@ class Restore(Thread): if os.path.exists(dbpath): try: os.rename(dbpath, save_path) - except EnvironmentError: + except OSError: time.sleep(30) # Wait a little for dropbox or the antivirus or whatever to release the file shutil.copyfile(dbpath, save_path) os.remove(dbpath) diff --git a/src/calibre/db/tables.py b/src/calibre/db/tables.py index 028d8341fd..91fba0a106 100644 --- a/src/calibre/db/tables.py +++ b/src/calibre/db/tables.py @@ -103,7 +103,7 @@ class OneToOneTable(Table): def read(self, db): idcol = 'id' if self.metadata['table'] == 'books' else 'book' - query = db.execute('SELECT {0}, {1} FROM {2}'.format(idcol, + query = db.execute('SELECT {}, {} FROM {}'.format(idcol, self.metadata['column'], self.metadata['table'])) if self.unserialize is None: try: @@ -111,7 +111,7 @@ class OneToOneTable(Table): except UnicodeDecodeError: # The db is damaged, try to work around it by ignoring # failures to decode utf-8 - query = db.execute('SELECT {0}, cast({1} as blob) FROM {2}'.format(idcol, + query = db.execute('SELECT {}, cast({} as blob) FROM {}'.format(idcol, self.metadata['column'], self.metadata['table'])) self.book_col_map = {k:bytes(val).decode('utf-8', 'replace') for k, val in query} else: @@ -205,7 +205,7 @@ class ManyToOneTable(Table): self.read_maps(db) def read_id_maps(self, db): - query = db.execute('SELECT id, {0} FROM {1}'.format( + query = db.execute('SELECT id, {} FROM {}'.format( self.metadata['column'], self.metadata['table'])) if self.unserialize is None: self.id_map = dict(query) @@ -217,7 +217,7 @@ class ManyToOneTable(Table): cbm = self.col_book_map bcm = self.book_col_map for book, item_id in db.execute( - 'SELECT book, {0} FROM {1}'.format( + 'SELECT book, {} FROM {}'.format( self.metadata['link_column'], self.link_table)): cbm[item_id].add(book) bcm[book] = item_id @@ -230,7 +230,7 @@ class ManyToOneTable(Table): book_ids = self.col_book_map.pop(item_id, ()) for book_id in book_ids: self.book_col_map.pop(book_id, None) - db.executemany('DELETE FROM {0} WHERE {1}=?'.format( + db.executemany('DELETE FROM {} WHERE {}=?'.format( self.link_table, self.metadata['link_column']), tuple((x,) for x in extra_item_ids)) def fix_case_duplicates(self, db): @@ -250,7 +250,7 @@ class ManyToOneTable(Table): db.executemany('UPDATE {0} SET {1}=? WHERE {1}=?'.format( self.link_table, self.metadata['link_column']), tuple((main_id, x) for x in v)) - db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), + db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']), tuple((x,) for x in v)) def remove_books(self, book_ids, db): @@ -270,7 +270,7 @@ class ManyToOneTable(Table): clean.add(item_id) if clean: db.executemany( - 'DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), + 'DELETE FROM {} WHERE id=?'.format(self.metadata['table']), [(x,) for x in clean]) return clean @@ -296,7 +296,7 @@ class ManyToOneTable(Table): # this is a many-to-one mapping we know that we can delete # links without checking the item ID db.executemany( - 'DELETE FROM {0} WHERE book=?'.format(self.link_table), tuple((x,) for x in books_to_delete)) + 'DELETE FROM {} WHERE book=?'.format(self.link_table), tuple((x,) for x in books_to_delete)) affected_books |= books_to_delete else: # Process normally any items where the VL was not significant @@ -314,8 +314,8 @@ class ManyToOneTable(Table): self.book_col_map.pop(book_id, None) affected_books.update(book_ids) item_ids = tuple((x,) for x in item_ids) - db.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']), item_ids) - db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), item_ids) + db.executemany('DELETE FROM {} WHERE {}=?'.format(self.link_table, self.metadata['link_column']), item_ids) + db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']), item_ids) return affected_books def rename_item(self, item_id, new_name, db): @@ -327,7 +327,7 @@ class ManyToOneTable(Table): if existing_item is None or existing_item == item_id: # A simple rename will do the trick self.id_map[item_id] = new_name - db.execute('UPDATE {0} SET {1}=? WHERE id=?'.format(table, col), (new_name, item_id)) + db.execute('UPDATE {} SET {}=? WHERE id=?'.format(table, col), (new_name, item_id)) else: # We have to replace new_id = existing_item @@ -353,9 +353,9 @@ class RatingTable(ManyToOneTable): bad_ids = {item_id for item_id, rating in iteritems(self.id_map) if rating == 0} if bad_ids: self.id_map = {item_id:rating for item_id, rating in iteritems(self.id_map) if rating != 0} - db.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']), + db.executemany('DELETE FROM {} WHERE {}=?'.format(self.link_table, self.metadata['link_column']), tuple((x,) for x in bad_ids)) - db.execute('DELETE FROM {0} WHERE {1}=0'.format( + db.execute('DELETE FROM {} WHERE {}=0'.format( self.metadata['table'], self.metadata['column'])) @@ -389,7 +389,7 @@ class ManyToManyTable(ManyToOneTable): book_ids = self.col_book_map.pop(item_id, ()) for book_id in book_ids: self.book_col_map[book_id] = tuple(iid for iid in self.book_col_map.pop(book_id, ()) if iid not in extra_item_ids) - db.executemany('DELETE FROM {0} WHERE {1}=?'.format( + db.executemany('DELETE FROM {} WHERE {}=?'.format( self.link_table, self.metadata['link_column']), tuple((x,) for x in extra_item_ids)) def remove_books(self, book_ids, db): @@ -409,7 +409,7 @@ class ManyToManyTable(ManyToOneTable): clean.add(item_id) if clean and self.do_clean_on_remove: db.executemany( - 'DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), + 'DELETE FROM {} WHERE id=?'.format(self.metadata['table']), [(x,) for x in clean]) return clean @@ -436,7 +436,7 @@ class ManyToManyTable(ManyToOneTable): # Delete book/item pairs from the link table. We don't need to do # anything with the main table because books with the old ID are # still in the library. - db.executemany('DELETE FROM {0} WHERE {1}=? and {2}=?'.format( + db.executemany('DELETE FROM {} WHERE {}=? and {}=?'.format( self.link_table, 'book', self.metadata['link_column']), [(b, i) for b in affected_books for i in item_ids]) # Take care of any items where the VL was not significant @@ -453,8 +453,8 @@ class ManyToManyTable(ManyToOneTable): self.book_col_map[book_id] = tuple(x for x in self.book_col_map.get(book_id, ()) if x != item_id) affected_books.update(book_ids) item_ids = tuple((x,) for x in item_ids) - db.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']), item_ids) - db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), item_ids) + db.executemany('DELETE FROM {} WHERE {}=?'.format(self.link_table, self.metadata['link_column']), item_ids) + db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']), item_ids) return affected_books def rename_item(self, item_id, new_name, db): @@ -466,7 +466,7 @@ class ManyToManyTable(ManyToOneTable): if existing_item is None or existing_item == item_id: # A simple rename will do the trick self.id_map[item_id] = new_name - db.execute('UPDATE {0} SET {1}=? WHERE id=?'.format(table, col), (new_name, item_id)) + db.execute('UPDATE {} SET {}=? WHERE id=?'.format(table, col), (new_name, item_id)) else: # We have to replace new_id = existing_item @@ -478,7 +478,7 @@ class ManyToManyTable(ManyToOneTable): for book_id in books: self.book_col_map[book_id] = tuple((existing_item if x == item_id else x) for x in self.book_col_map.get(book_id, ()) if x != existing_item) self.col_book_map[existing_item].update(books) - db.executemany('DELETE FROM {0} WHERE book=? AND {1}=?'.format(self.link_table, lcol), [ + db.executemany('DELETE FROM {} WHERE book=? AND {}=?'.format(self.link_table, lcol), [ (book_id, existing_item) for book_id in books]) db.execute('UPDATE {0} SET {1}=? WHERE {1}=?; DELETE FROM {2} WHERE id=?'.format( self.link_table, lcol, table), (existing_item, item_id, item_id)) @@ -515,11 +515,11 @@ class ManyToManyTable(ManyToOneTable): tuple((main_id, x, book_id) for x in v)) else: # duplicates - db.execute('DELETE FROM {0} WHERE book=?'.format(self.link_table), (book_id,)) + db.execute('DELETE FROM {} WHERE book=?'.format(self.link_table), (book_id,)) db.executemany( - 'INSERT INTO {0} (book,{1}) VALUES (?,?)'.format(self.link_table, self.metadata['link_column']), + 'INSERT INTO {} (book,{}) VALUES (?,?)'.format(self.link_table, self.metadata['link_column']), tuple((book_id, x) for x in vals)) - db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), + db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']), tuple((x,) for x in v)) diff --git a/src/calibre/db/tests/base.py b/src/calibre/db/tests/base.py index 77ddc8b8c0..edd190baf7 100644 --- a/src/calibre/db/tests/base.py +++ b/src/calibre/db/tests/base.py @@ -32,7 +32,7 @@ class BaseTest(unittest.TestCase): gc.collect(), gc.collect() try: shutil.rmtree(self.library_path) - except EnvironmentError: + except OSError: # Try again in case something transient has a file lock on windows gc.collect(), gc.collect() time.sleep(2) diff --git a/src/calibre/db/tests/legacy.py b/src/calibre/db/tests/legacy.py index 24597c6a0f..efbe7944be 100644 --- a/src/calibre/db/tests/legacy.py +++ b/src/calibre/db/tests/legacy.py @@ -62,7 +62,7 @@ def run_funcs(self, db, ndb, funcs): if meth[0] in {'!', '@', '#', '+', '$', '-', '%'}: if meth[0] != '+': fmt = {'!':dict, '@':lambda x:frozenset(x or ()), '#':lambda x:set((x or '').split(',')), - '$':lambda x:set(tuple(y) for y in x), '-':lambda x:None, + '$':lambda x:{tuple(y) for y in x}, '-':lambda x:None, '%':lambda x: set((x or '').split(','))}[meth[0]] else: fmt = args[-1] @@ -516,7 +516,7 @@ class LegacyTest(BaseTest): T = partial(ET, 'get_all_custom_book_data', old=old, legacy=legacy) T((name, object())) T = partial(ET, 'delete_all_custom_book_data', old=old, legacy=legacy) - T((name)) + T(name) T = partial(ET, 'get_all_custom_book_data', old=old, legacy=legacy) T((name, object())) diff --git a/src/calibre/db/utils.py b/src/calibre/db/utils.py index 89b26bfa59..81737f350f 100644 --- a/src/calibre/db/utils.py +++ b/src/calibre/db/utils.py @@ -136,7 +136,7 @@ class ThumbnailCache: def _do_delete(self, path): try: os.remove(path) - except EnvironmentError as err: + except OSError as err: self.log('Failed to delete cached thumbnail file:', as_unicode(err)) def _load_index(self): @@ -153,7 +153,7 @@ class ThumbnailCache: def listdir(*args): try: return os.listdir(os.path.join(*args)) - except EnvironmentError: + except OSError: return () # not a directory or no permission or whatever entries = ('/'.join((parent, subdir, entry)) for parent in listdir(self.location) @@ -164,13 +164,13 @@ class ThumbnailCache: try: with open(os.path.join(self.location, 'invalidate'), 'rb') as f: raw = f.read().decode('utf-8') - except EnvironmentError as err: + except OSError as err: if getattr(err, 'errno', None) != errno.ENOENT: self.log('Failed to read thumbnail invalidate data:', as_unicode(err)) else: try: os.remove(os.path.join(self.location, 'invalidate')) - except EnvironmentError as err: + except OSError as err: self.log('Failed to remove thumbnail invalidate data:', as_unicode(err)) else: def record(line): @@ -198,7 +198,7 @@ class ThumbnailCache: self.total_size += size else: self._do_delete(path) - except EnvironmentError as err: + except OSError as err: self.log('Failed to read thumbnail cache dir:', as_unicode(err)) self.items = OrderedDict(sorted(items, key=lambda x:order.get(x[0], 0))) @@ -230,7 +230,7 @@ class ThumbnailCache: data = '\n'.join(group_id + ' ' + str(book_id) for (group_id, book_id) in self.items) with lopen(os.path.join(self.location, 'order'), 'wb') as f: f.write(data.encode('utf-8')) - except EnvironmentError as err: + except OSError as err: self.log('Failed to save thumbnail cache order:', as_unicode(err)) def _read_order(self): @@ -281,14 +281,14 @@ class ThumbnailCache: try: with open(path, 'wb') as f: f.write(data) - except EnvironmentError as err: + except OSError as err: d = os.path.dirname(path) if not os.path.exists(d): try: os.makedirs(d) with open(path, 'wb') as f: f.write(data) - except EnvironmentError as err: + except OSError as err: self.log('Failed to write cached thumbnail:', path, as_unicode(err)) return self._apply_size() else: @@ -326,7 +326,7 @@ class ThumbnailCache: if entry.thumbnail_size != self.thumbnail_size: try: os.remove(entry.path) - except EnvironmentError as err: + except OSError as err: if getattr(err, 'errno', None) != errno.ENOENT: self.log('Failed to remove cached thumbnail:', entry.path, as_unicode(err)) self.total_size -= entry.size @@ -335,7 +335,7 @@ class ThumbnailCache: try: with open(entry.path, 'rb') as f: data = f.read() - except EnvironmentError as err: + except OSError as err: self.log('Failed to read cached thumbnail:', entry.path, as_unicode(err)) return None, None return data, entry.timestamp @@ -350,7 +350,7 @@ class ThumbnailCache: raw = '\n'.join('%s %d' % (self.group_id, book_id) for book_id in book_ids) with open(os.path.join(self.location, 'invalidate'), 'ab') as f: f.write(raw.encode('ascii')) - except EnvironmentError as err: + except OSError as err: self.log('Failed to write invalidate thumbnail record:', as_unicode(err)) @property @@ -364,7 +364,7 @@ class ThumbnailCache: with self.lock: try: os.remove(os.path.join(self.location, 'order')) - except EnvironmentError: + except OSError: pass if not hasattr(self, 'total_size'): self._load_index() diff --git a/src/calibre/db/view.py b/src/calibre/db/view.py index 8b00c10aa8..751046b891 100644 --- a/src/calibre/db/view.py +++ b/src/calibre/db/view.py @@ -174,8 +174,7 @@ class View: yield TableRow(book_id, self) def iterallids(self): - for book_id in sorted(self._map): - yield book_id + yield from sorted(self._map) def tablerow_for_id(self, book_id): return TableRow(book_id, self) @@ -280,7 +279,7 @@ class View: def _build_restriction_string(self, restriction): if self.base_restriction: if restriction: - return u'(%s) and (%s)' % (self.base_restriction, restriction) + return '(%s) and (%s)' % (self.base_restriction, restriction) else: return self.base_restriction else: @@ -296,7 +295,7 @@ class View: else: q = query if search_restriction: - q = u'(%s) and (%s)' % (search_restriction, query) + q = '(%s) and (%s)' % (search_restriction, query) if not q: if set_restriction_count: self.search_restriction_book_count = len(self._map) @@ -373,7 +372,7 @@ class View: old_marked_ids = set(self.marked_ids) if not hasattr(id_dict, 'items'): # Simple list. Make it a dict of string 'true' - self.marked_ids = dict.fromkeys(id_dict, u'true') + self.marked_ids = dict.fromkeys(id_dict, 'true') else: # Ensure that all the items in the dict are text self.marked_ids = {k: str(v) for k, v in iteritems(id_dict)} diff --git a/src/calibre/db/write.py b/src/calibre/db/write.py index daaeb49c46..6be1d29374 100644 --- a/src/calibre/db/write.py +++ b/src/calibre/db/write.py @@ -471,7 +471,7 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args): ) db.executemany('DELETE FROM %s WHERE book=?'%table.link_table, ((k,) for k in updated)) - db.executemany('INSERT INTO {0}(book,{1}) VALUES(?, ?)'.format( + db.executemany('INSERT INTO {}(book,{}) VALUES(?, ?)'.format( table.link_table, m['link_column']), vals) if is_authors: aus_map = {book_id:field.author_sort_for_book(book_id) for book_id diff --git a/src/calibre/debug.py b/src/calibre/debug.py index e85f11174f..c0168e56e3 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -208,7 +208,7 @@ def print_basic_debug_info(out=None): from calibre.customize.ui import has_external_plugins, initialized_plugins if has_external_plugins(): from calibre.customize import PluginInstallationType - names = ('{0} {1}'.format(p.name, p.version) for p in initialized_plugins() + names = ('{} {}'.format(p.name, p.version) for p in initialized_plugins() if getattr(p, 'installation_type', None) is not PluginInstallationType.BUILTIN) out('Successfully initialized third party plugins:', ' && '.join(names)) diff --git a/src/calibre/devices/__init__.py b/src/calibre/devices/__init__.py index 8d95c2f475..95db5d65cd 100644 --- a/src/calibre/devices/__init__.py +++ b/src/calibre/devices/__init__.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/devices/blackberry/__init__.py b/src/calibre/devices/blackberry/__init__.py index f0a799e860..9ddaad67a1 100644 --- a/src/calibre/devices/blackberry/__init__.py +++ b/src/calibre/devices/blackberry/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/devices/boeye/driver.py b/src/calibre/devices/boeye/driver.py index d261670dbd..99ccedad31 100644 --- a/src/calibre/devices/boeye/driver.py +++ b/src/calibre/devices/boeye/driver.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2011, Ken ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/devices/cli.py b/src/calibre/devices/cli.py index 46e771e4d4..1497f81ae4 100755 --- a/src/calibre/devices/cli.py +++ b/src/calibre/devices/cli.py @@ -301,7 +301,7 @@ def main(): outfile = os.path.join(outfile, path[path.rfind("/")+1:]) try: outfile = lopen(outfile, "wb") - except IOError as e: + except OSError as e: print(e, file=sys.stderr) parser.print_help() return 1 @@ -311,7 +311,7 @@ def main(): elif args[1].startswith("dev:"): try: infile = lopen(args[0], "rb") - except IOError as e: + except OSError as e: print(e, file=sys.stderr) parser.print_help() return 1 diff --git a/src/calibre/devices/cybook/t2b.py b/src/calibre/devices/cybook/t2b.py index 0eecc180ef..d43380c087 100644 --- a/src/calibre/devices/cybook/t2b.py +++ b/src/calibre/devices/cybook/t2b.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2009, John Schember ' ''' diff --git a/src/calibre/devices/eb600/__init__.py b/src/calibre/devices/eb600/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/devices/eb600/__init__.py +++ b/src/calibre/devices/eb600/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/devices/errors.py b/src/calibre/devices/errors.py index 56af2a091d..4e35786b59 100644 --- a/src/calibre/devices/errors.py +++ b/src/calibre/devices/errors.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' """ diff --git a/src/calibre/devices/folder_device/driver.py b/src/calibre/devices/folder_device/driver.py index 94366d5e1a..202cb582c7 100644 --- a/src/calibre/devices/folder_device/driver.py +++ b/src/calibre/devices/folder_device/driver.py @@ -1,5 +1,3 @@ - - ''' Created on 15 May 2010 @@ -63,7 +61,7 @@ class FOLDER_DEVICE(USBMS): def __init__(self, path): if not os.path.isdir(path): - raise IOError('Path is not a folder') + raise OSError('Path is not a folder') path = USBMS.normalize_path(path) if path.endswith(os.sep): self._main_prefix = path diff --git a/src/calibre/devices/hanlin/__init__.py b/src/calibre/devices/hanlin/__init__.py index accbf2eede..a4e8fdad76 100644 --- a/src/calibre/devices/hanlin/__init__.py +++ b/src/calibre/devices/hanlin/__init__.py @@ -1,4 +1,2 @@ - - __license__ = 'GPL v3' __copyright__ = '2009, Tijmen Ruizendaal ' diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index e219220b6b..cbb8c2aee9 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' import os diff --git a/src/calibre/devices/kindle/__init__.py b/src/calibre/devices/kindle/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/devices/kindle/__init__.py +++ b/src/calibre/devices/kindle/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/devices/kindle/bookmark.py b/src/calibre/devices/kindle/bookmark.py index fb135a688f..df4f5b2d6d 100644 --- a/src/calibre/devices/kindle/bookmark.py +++ b/src/calibre/devices/kindle/bookmark.py @@ -154,7 +154,7 @@ class Bookmark(): # {{{ split = my_clippings.find('documents') + len('documents/') my_clippings = my_clippings[:split] + "My Clippings.txt" try: - with io.open(my_clippings, encoding='utf-8', errors='replace') as f2: + with open(my_clippings, encoding='utf-8', errors='replace') as f2: marker_found = 0 text = '' search_str1 = '%s' % (mi.title) diff --git a/src/calibre/devices/kindle/driver.py b/src/calibre/devices/kindle/driver.py index afbfc7c6d7..826bbe98af 100644 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -232,7 +232,7 @@ class KINDLE(USBMS): pr=percent_read) else: markup = _("%(time)s
Last page read: Location %(loc)d (%(pr)d%%)") % dict( - time=strftime(u'%x', timestamp.timetuple()), + time=strftime('%x', timestamp.timetuple()), loc=last_read_location, pr=percent_read) spanTag = BeautifulSoup('' + markup + '').find('span') @@ -313,7 +313,7 @@ class KINDLE(USBMS): bm.value.path, index_is_id=True) elif bm.type == 'kindle_clippings': # Find 'My Clippings' author=Kindle in database, or add - last_update = 'Last modified %s' % strftime(u'%x %X',bm.value['timestamp'].timetuple()) + last_update = 'Last modified %s' % strftime('%x %X',bm.value['timestamp'].timetuple()) mc_id = list(db.data.search_getting_ids('title:"My Clippings"', '', sort_results=False)) if mc_id: db.add_format_with_hooks(mc_id[0], 'TXT', bm.value['path'], @@ -524,7 +524,7 @@ class KINDLE2(KINDLE): cache_dir = self.amazon_cover_bug_cache_dir() try: os.mkdir(cache_dir) - except EnvironmentError: + except OSError: pass with lopen(os.path.join(cache_dir, os.path.basename(tp)), 'wb') as f: f.write(coverdata[2]) @@ -545,7 +545,7 @@ class KINDLE2(KINDLE): dest_path = os.path.join(dest_dir, name) try: dest_stat_result = os.lstat(dest_path) - except EnvironmentError: + except OSError: needs_sync = True else: needs_sync = src_stat_result.st_size != dest_stat_result.st_size @@ -567,7 +567,7 @@ class KINDLE2(KINDLE): for tp in (tp1, tp2): try: os.remove(tp) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: prints('Failed to delete thumbnail for {!r} at {!r} with error: {}'.format(path, tp, err)) except Exception: diff --git a/src/calibre/devices/kobo/bookmark.py b/src/calibre/devices/kobo/bookmark.py index 4a0f8c7ef5..a370bcd08b 100644 --- a/src/calibre/devices/kobo/bookmark.py +++ b/src/calibre/devices/kobo/bookmark.py @@ -57,7 +57,7 @@ class Bookmark(): # {{{ 'ORDER BY bm.ContentID, bm.chapterprogress' ) - debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapters: contentId={0}".format(self.contentId)) + debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapters: contentId={}".format(self.contentId)) cursor.execute(kepub_chapter_query, book_query_values) kepub_chapters = {} if self.kepub: @@ -69,7 +69,7 @@ class Bookmark(): # {{{ 'chapter_title': chapter_row['Title'], 'chapter_index': chapter_row['VolumeIndex'] } - debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter: kepub chapters={0}".format(kepub_chapters)) + debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter: kepub chapters={}".format(kepub_chapters)) except: debug_print("Kobo::Bookmark::get_bookmark_data - No chapters found") @@ -83,20 +83,20 @@ class Bookmark(): # {{{ # For kepubs on newer firmware, the title needs to come from an 899 row. if self.kepub: chapter_contentID = row['ContentID'] - debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter chapter_contentID='{0}'".format(chapter_contentID)) + debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter chapter_contentID='{}'".format(chapter_contentID)) filename_index = chapter_contentID.find('!') book_contentID_part = chapter_contentID[:filename_index] - debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter book_contentID_part='{0}'".format(book_contentID_part)) + debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter book_contentID_part='{}'".format(book_contentID_part)) file_contentID_part = chapter_contentID[filename_index + 1:] filename_index = file_contentID_part.find('!') opf_reference = file_contentID_part[:filename_index] - debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter opf_reference='{0}'".format(opf_reference)) + debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter opf_reference='{}'".format(opf_reference)) file_contentID_part = file_contentID_part[filename_index + 1:] - debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter file_contentID_part='{0}'".format(file_contentID_part)) + debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter file_contentID_part='{}'".format(file_contentID_part)) # from urllib import quote # file_contentID_part = quote(file_contentID_part) chapter_contentID = book_contentID_part + "!" + opf_reference + "!" + file_contentID_part - debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter chapter_contentID='{0}'".format(chapter_contentID)) + debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter chapter_contentID='{}'".format(chapter_contentID)) kepub_chapter = kepub_chapters.get(chapter_contentID, None) if kepub_chapter is not None: chapter_title = kepub_chapter['chapter_title'] diff --git a/src/calibre/devices/kobo/books.py b/src/calibre/devices/kobo/books.py index 0964ca7c14..9a564d173f 100644 --- a/src/calibre/devices/kobo/books.py +++ b/src/calibre/devices/kobo/books.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2010-2012, , Timothy Legge and David Forrester ' __docformat__ = 'restructuredtext en' @@ -29,7 +28,7 @@ class Book(Book_): if show_debug: debug_print("Book::__init__ - title=", title, 'authors=', authors) debug_print("Book::__init__ - other=", other) - super(Book, self).__init__(prefix, lpath, size, other) + super().__init__(prefix, lpath, size, other) if title is not None and len(title) > 0: self.title = title @@ -117,7 +116,7 @@ class Book(Book_): ans = '\n'.join(ans) - return super(Book,self).__str__() + "\n" + ans + return super().__str__() + "\n" + ans class ImageWrapper: @@ -129,7 +128,7 @@ class ImageWrapper: class KTCollectionsBookList(CollectionsBookList): def __init__(self, oncard, prefix, settings): - super(KTCollectionsBookList, self).__init__(oncard, prefix, settings) + super().__init__(oncard, prefix, settings) self.set_device_managed_collections([]) def get_collections(self, collection_attributes): diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 7f815751db..cfbcfe69c7 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -203,7 +203,7 @@ class KOBO(USBMS): try: with lopen(self.normalize_path(self._main_prefix + '.kobo/version'), 'rb') as f: fwversion = f.readline().split(b',')[2] - fwversion = tuple((int(x) for x in fwversion.split(b'.'))) + fwversion = tuple(int(x) for x in fwversion.split(b'.')) except Exception: debug_print("Kobo::get_firmware_version - didn't get firmware version from file'") fwversion = (0,0,0) @@ -1138,7 +1138,7 @@ class KOBO(USBMS): def get_annotations(self, path_map): from calibre.devices.kobo.bookmark import Bookmark - EPUB_FORMATS = [u'epub'] + EPUB_FORMATS = ['epub'] epub_formats = set(EPUB_FORMATS) def get_storage(): @@ -1519,21 +1519,21 @@ class KOBOTOUCH(KOBO): self.plugboards = self.plugboard_func = None def initialize(self): - super(KOBOTOUCH, self).initialize() + super().initialize() self.bookshelvelist = [] def get_device_information(self, end_session=True): self.set_device_name() - return super(KOBOTOUCH, self).get_device_information(end_session) + return super().get_device_information(end_session) def open_linux(self): - super(KOBOTOUCH, self).open_linux() + super().open_linux() self.swap_drives_if_needed() def open_osx(self): # Just dump some info to the logs. - super(KOBOTOUCH, self).open_osx() + super().open_osx() # Wrap some debugging output in a try/except so that it is unlikely to break things completely. try: @@ -2049,7 +2049,7 @@ class KOBOTOUCH(KOBO): path = ContentID if not externalId: - return super(KOBOTOUCH, self).path_from_contentid(ContentID, ContentType, MimeType, oncard) + return super().path_from_contentid(ContentID, ContentType, MimeType, oncard) if oncard == 'cardb': print('path from_contentid cardb') @@ -2099,13 +2099,13 @@ class KOBOTOUCH(KOBO): from css_parser import parseFile as cssparseFile try: extra_sheet = cssparseFile(extra_css_path) - debug_print("KoboTouch:get_extra_css: Using extra CSS in {0} ({1} rules)".format(extra_css_path, len(extra_sheet.cssRules))) + debug_print("KoboTouch:get_extra_css: Using extra CSS in {} ({} rules)".format(extra_css_path, len(extra_sheet.cssRules))) if len(extra_sheet.cssRules) ==0: debug_print("KoboTouch:get_extra_css: Extra CSS file has no valid rules. CSS will not be modified.") extra_sheet = None except Exception as e: - debug_print("KoboTouch:get_extra_css: Problem parsing extra CSS file {0}".format(extra_css_path)) - debug_print("KoboTouch:get_extra_css: Exception {0}".format(e)) + debug_print("KoboTouch:get_extra_css: Problem parsing extra CSS file {}".format(extra_css_path)) + debug_print("KoboTouch:get_extra_css: Exception {}".format(e)) # create dictionary of features enabled in kobo extra css self.extra_css_options = {} @@ -2136,16 +2136,16 @@ class KOBOTOUCH(KOBO): self.extra_sheet = self.get_extra_css() i = 0 for file, n, mi in zip(files, names, metadata): - debug_print("KoboTouch:upload_books: Processing book: {0} by {1}".format(mi.title, " and ".join(mi.authors))) + debug_print("KoboTouch:upload_books: Processing book: {} by {}".format(mi.title, " and ".join(mi.authors))) debug_print("KoboTouch:upload_books: file=%s, name=%s" % (file, n)) - self.report_progress(i / float(len(files)), "Processing book: {0} by {1}".format(mi.title, " and ".join(mi.authors))) + self.report_progress(i / float(len(files)), "Processing book: {} by {}".format(mi.title, " and ".join(mi.authors))) mi.kte_calibre_name = n self._modify_epub(file, mi) i += 1 self.report_progress(0, 'Working...') - result = super(KOBOTOUCH, self).upload_books(files, names, on_card, end_session, metadata) + result = super().upload_books(files, names, on_card, end_session, metadata) # debug_print('KoboTouch:upload_books - result=', result) if self.dbversion >= 53: @@ -2179,7 +2179,7 @@ class KOBOTOUCH(KOBO): return result def _modify_epub(self, book_file, metadata, container=None): - debug_print("KoboTouch:_modify_epub:Processing {0} - {1}".format(metadata.author_sort, metadata.title)) + debug_print("KoboTouch:_modify_epub:Processing {} - {}".format(metadata.author_sort, metadata.title)) # Currently only modifying CSS, so if no stylesheet, don't do anything if not self.extra_sheet: @@ -2200,9 +2200,9 @@ class KOBOTOUCH(KOBO): # future css mods may be epub/kepub specific, so pass file extension arg fileext = os.path.splitext(book_file)[-1].lower() - debug_print("KoboTouch:_modify_epub: Modifying {0}".format(cssname)) + debug_print("KoboTouch:_modify_epub: Modifying {}".format(cssname)) if self._modify_stylesheet(newsheet, fileext): - debug_print("KoboTouch:_modify_epub:CSS rules {0} -> {1} ({2})".format(oldrules, len(newsheet.cssRules), cssname)) + debug_print("KoboTouch:_modify_epub:CSS rules {} -> {} ({})".format(oldrules, len(newsheet.cssRules), cssname)) container.dirty(cssname) is_dirty = True @@ -2256,8 +2256,8 @@ class KOBOTOUCH(KOBO): container = get_container(book_file) container.css_preprocessor = DummyCSSPreProcessor() except Exception as e: - debug_print("KoboTouch:create_container: exception from get_container {0} - {1}".format(metadata.author_sort, metadata.title)) - debug_print("KoboTouch:create_container: exception is: {0}".format(e)) + debug_print("KoboTouch:create_container: exception from get_container {} - {}".format(metadata.author_sort, metadata.title)) + debug_print("KoboTouch:create_container: exception is: {}".format(e)) else: commit_container = False debug_print("KoboTouch:create_container: received container") @@ -2277,7 +2277,7 @@ class KOBOTOUCH(KOBO): pass def delete_via_sql(self, ContentID, ContentType): - imageId = super(KOBOTOUCH, self).delete_via_sql(ContentID, ContentType) + imageId = super().delete_via_sql(ContentID, ContentType) if self.dbversion >= 53: debug_print('KoboTouch:delete_via_sql: ContentID="%s"'%ContentID, 'ContentType="%s"'%ContentType) @@ -2383,7 +2383,7 @@ class KOBOTOUCH(KOBO): def get_content_type_from_path(self, path): ContentType = 6 if self.fwversion < (1, 9, 17): - ContentType = super(KOBOTOUCH, self).get_content_type_from_path(path) + ContentType = super().get_content_type_from_path(path) return ContentType def get_content_type_from_extension(self, extension): @@ -2391,7 +2391,7 @@ class KOBOTOUCH(KOBO): # With new firmware, ContentType appears to be 6 for all types of sideloaded books. ContentType = 6 if self.fwversion < (1,9,17): - ContentType = super(KOBOTOUCH, self).get_content_type_from_extension(extension) + ContentType = super().get_content_type_from_extension(extension) return ContentType def set_plugboards(self, plugboards, pb_func): @@ -3329,7 +3329,7 @@ class KOBOTOUCH(KOBO): @classmethod def _config(cls): - c = super(KOBOTOUCH, cls)._config() + c = super()._config() c.add_opt('manage_collections', default=True) c.add_opt('collections_columns', default='') @@ -3819,7 +3819,7 @@ class KOBOTOUCH(KOBO): try: is_debugging = len(self.debugging_title) > 0 and title.lower().find(self.debugging_title.lower()) >= 0 or len(title) == 0 except: - debug_print(("KoboTouch::is_debugging_title - Exception checking debugging title for title '{0}'.").format(title)) + debug_print(("KoboTouch::is_debugging_title - Exception checking debugging title for title '{}'.").format(title)) is_debugging = False return is_debugging @@ -3864,7 +3864,7 @@ class KOBOTOUCH(KOBO): def __str__(self, *args, **kwargs): options = ', '.join(['%s: %s' % (x.name, self.get_pref(x.name)) for x in self._config().preferences]) - return u"Driver:%s, Options - %s" % (self.name, options) + return "Driver:%s, Options - %s" % (self.name, options) if __name__ == '__main__': diff --git a/src/calibre/devices/kobo/kobotouch_config.py b/src/calibre/devices/kobo/kobotouch_config.py index f08d1ecbb6..e45384f0de 100644 --- a/src/calibre/devices/kobo/kobotouch_config.py +++ b/src/calibre/devices/kobo/kobotouch_config.py @@ -39,7 +39,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig): must_read_metadata, supports_use_author_sort, extra_customization_message, device, extra_customization_choices=None, parent=None): - super(KOBOTOUCHConfig, self).__init__(device_settings, all_formats, supports_subdirs, + super().__init__(device_settings, all_formats, supports_subdirs, must_read_metadata, supports_use_author_sort, extra_customization_message, device, extra_customization_choices, parent) @@ -65,7 +65,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig): return self._device() def validate(self): - validated = super(KOBOTOUCHConfig, self).validate() + validated = super().validate() validated &= self.tab2.validate() return validated @@ -95,7 +95,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig): def commit(self): debug_print("KOBOTOUCHConfig::commit: start") - p = super(KOBOTOUCHConfig, self).commit() + p = super().commit() p['manage_collections'] = self.manage_collections p['create_collections'] = self.create_collections @@ -135,7 +135,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig): class Tab1Config(DeviceConfigTab): # {{{ def __init__(self, parent, device): - super(Tab1Config, self).__init__(parent) + super().__init__(parent) self.l = QVBoxLayout(self) self.setLayout(self.l) @@ -159,7 +159,7 @@ class Tab1Config(DeviceConfigTab): # {{{ class Tab2Config(DeviceConfigTab): # {{{ def __init__(self, parent, device): - super(Tab2Config, self).__init__(parent) + super().__init__(parent) self.l = QVBoxLayout(self) self.setLayout(self.l) @@ -187,7 +187,7 @@ class Tab2Config(DeviceConfigTab): # {{{ class BookUploadsGroupBox(DeviceOptionsGroupBox): def __init__(self, parent, device): - super(BookUploadsGroupBox, self).__init__(parent, device) + super().__init__(parent, device) self.setTitle(_("Uploading of books")) self.options_layout = QGridLayout() @@ -229,7 +229,7 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox): class CollectionsGroupBox(DeviceOptionsGroupBox): def __init__(self, parent, device): - super(CollectionsGroupBox, self).__init__(parent, device) + super().__init__(parent, device) self.setTitle(_("Collections")) self.options_layout = QGridLayout() @@ -296,7 +296,7 @@ class CollectionsGroupBox(DeviceOptionsGroupBox): class CoversGroupBox(DeviceOptionsGroupBox): def __init__(self, parent, device): - super(CoversGroupBox, self).__init__(parent, device) + super().__init__(parent, device) self.setTitle(_("Upload covers")) self.options_layout = QGridLayout() @@ -415,7 +415,7 @@ class CoversGroupBox(DeviceOptionsGroupBox): class DeviceListGroupBox(DeviceOptionsGroupBox): def __init__(self, parent, device): - super(DeviceListGroupBox, self).__init__(parent, device) + super().__init__(parent, device) self.setTitle(_("Show as on device")) self.options_layout = QGridLayout() @@ -465,7 +465,7 @@ class DeviceListGroupBox(DeviceOptionsGroupBox): class AdvancedGroupBox(DeviceOptionsGroupBox): def __init__(self, parent, device): - super(AdvancedGroupBox, self).__init__(parent, device, _("Advanced options")) + super().__init__(parent, device, _("Advanced options")) # self.setTitle(_("Advanced Options")) self.options_layout = QGridLayout() @@ -514,7 +514,7 @@ class AdvancedGroupBox(DeviceOptionsGroupBox): class MetadataGroupBox(DeviceOptionsGroupBox): def __init__(self, parent, device): - super(MetadataGroupBox, self).__init__(parent, device) + super().__init__(parent, device) self.setTitle(_("Update metadata on the device")) self.options_layout = QGridLayout() diff --git a/src/calibre/devices/mime.py b/src/calibre/devices/mime.py index 1853d40c2f..ee23549177 100644 --- a/src/calibre/devices/mime.py +++ b/src/calibre/devices/mime.py @@ -1,4 +1,3 @@ - __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/devices/mtp/books.py b/src/calibre/devices/mtp/books.py index e58fab1af9..06478a6aa8 100644 --- a/src/calibre/devices/mtp/books.py +++ b/src/calibre/devices/mtp/books.py @@ -46,7 +46,7 @@ class Book(Metadata): Metadata.__init__(self, _('Unknown'), other=other) self.storage_id, self.lpath = storage_id, lpath self.lpath = self.path = self.lpath.replace(os.sep, '/') - self.mtp_relpath = tuple([icu_lower(x) for x in self.lpath.split('/')]) + self.mtp_relpath = tuple(icu_lower(x) for x in self.lpath.split('/')) self.datetime = utcnow().timetuple() self.thumbail = None diff --git a/src/calibre/devices/mtp/filesystem_cache.py b/src/calibre/devices/mtp/filesystem_cache.py index 62ef4fe98e..632f5a3fb4 100644 --- a/src/calibre/devices/mtp/filesystem_cache.py +++ b/src/calibre/devices/mtp/filesystem_cache.py @@ -108,10 +108,8 @@ class FileOrFolder: return tuple(parts) def __iter__(self): - for e in self.folders: - yield e - for e in self.files: - yield e + yield from self.folders + yield from self.files def add_child(self, entry): ans = FileOrFolder(entry, self.fs_cache()) diff --git a/src/calibre/devices/mtp/unix/driver.py b/src/calibre/devices/mtp/unix/driver.py index 3038a2c727..8130f088b3 100644 --- a/src/calibre/devices/mtp/unix/driver.py +++ b/src/calibre/devices/mtp/unix/driver.py @@ -75,7 +75,7 @@ class MTP_DEVICE(MTPDeviceBase): traceback.print_stack() return False if debug is not None and ans: - debug('Device {0} claims to be an MTP device in the IOKit registry'.format(d)) + debug('Device {} claims to be an MTP device in the IOKit registry'.format(d)) return bool(ans) def set_debug_level(self, lvl): diff --git a/src/calibre/devices/mtp/unix/sysfs.py b/src/calibre/devices/mtp/unix/sysfs.py index a99b385575..a79745e80b 100644 --- a/src/calibre/devices/mtp/unix/sysfs.py +++ b/src/calibre/devices/mtp/unix/sysfs.py @@ -31,7 +31,7 @@ class MTPDetect: try: with lopen(x, 'rb') as f: return f.read() - except EnvironmentError: + except OSError: pass ipath = os.path.join(self.base, '{0}-*/{0}-*/interface'.format(dev.busnum)) @@ -44,7 +44,7 @@ class MTPDetect: try: if raw and int(raw) == dev.devnum: if debug is not None: - debug('Unknown device {0} claims to be an MTP device' + debug('Unknown device {} claims to be an MTP device' .format(dev)) return True except (ValueError, TypeError): diff --git a/src/calibre/devices/nook/driver.py b/src/calibre/devices/nook/driver.py index 23a5e81b83..9a4fc37eb5 100644 --- a/src/calibre/devices/nook/driver.py +++ b/src/calibre/devices/nook/driver.py @@ -111,7 +111,7 @@ class NOOK_COLOR(NOOK): self.EBOOK_DIR_MAIN = 'NOOK/My Files' try: os.makedirs(os.path.join(self._main_prefix, *self.EBOOK_DIR_MAIN.split('/'))) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: self.EBOOK_DIR_MAIN = 'NOOK' diff --git a/src/calibre/devices/nuut2/__init__.py b/src/calibre/devices/nuut2/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/devices/nuut2/__init__.py +++ b/src/calibre/devices/nuut2/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/devices/paladin/driver.py b/src/calibre/devices/paladin/driver.py index 11985e7ab5..bd6aea84ef 100644 --- a/src/calibre/devices/paladin/driver.py +++ b/src/calibre/devices/paladin/driver.py @@ -110,7 +110,7 @@ class PALADIN(USBMS): for i, row in enumerate(cursor): try: comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000) - except (OSError, IOError, TypeError): + except (OSError, TypeError): # In case the db has incorrect path info continue device_date = int(row[1]) diff --git a/src/calibre/devices/prs505/__init__.py b/src/calibre/devices/prs505/__init__.py index 7b237f281b..4fed9c32ed 100644 --- a/src/calibre/devices/prs505/__init__.py +++ b/src/calibre/devices/prs505/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index fd3e5d2176..0bd4d7b015 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/devices/prs505/sony_cache.py b/src/calibre/devices/prs505/sony_cache.py index 00a05d8197..d77273ae9c 100644 --- a/src/calibre/devices/prs505/sony_cache.py +++ b/src/calibre/devices/prs505/sony_cache.py @@ -758,7 +758,7 @@ class XMLCache: return m def book_by_lpath(self, lpath, root): - matches = root.xpath(u'//*[local-name()="text" and @path="%s"]'%lpath) + matches = root.xpath('//*[local-name()="text" and @path="%s"]'%lpath) if matches: return matches[0] diff --git a/src/calibre/devices/prst1/driver.py b/src/calibre/devices/prst1/driver.py index 97adc71bde..8ef883af64 100644 --- a/src/calibre/devices/prst1/driver.py +++ b/src/calibre/devices/prst1/driver.py @@ -199,7 +199,7 @@ class PRST1(USBMS): for i, row in enumerate(cursor): try: comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000) - except (OSError, IOError, TypeError): + except (OSError, TypeError): # In case the db has incorrect path info continue device_date = int(row[1]) diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py index 12b2119b41..073448b818 100644 --- a/src/calibre/devices/scanner.py +++ b/src/calibre/devices/scanner.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' ''' @@ -40,12 +39,12 @@ _USBDevice = namedtuple('USBDevice', class USBDevice(_USBDevice): def __new__(cls, *args, **kwargs): - self = super(USBDevice, cls).__new__(cls, *args) + self = super().__new__(cls, *args) self.busnum = self.devnum = -1 return self def __repr__(self): - return (u'USBDevice(busnum=%s, devnum=%s, ' + return ('USBDevice(busnum=%s, devnum=%s, ' 'vendor_id=0x%04x, product_id=0x%04x, bcd=0x%04x, ' 'manufacturer=%s, product=%s, serial=%s)')%( self.busnum, self.devnum, self.vendor_id, self.product_id, @@ -141,15 +140,15 @@ class LinuxScanner: try: dev.append(read(man).decode('utf-8')) except Exception: - dev.append(u'') + dev.append('') try: dev.append(read(prod_string).decode('utf-8')) except Exception: - dev.append(u'') + dev.append('') try: dev.append(read(serial).decode('utf-8')) except Exception: - dev.append(u'') + dev.append('') dev = USBDevice(*dev) try: diff --git a/src/calibre/devices/smart_device_app/driver.py b/src/calibre/devices/smart_device_app/driver.py index db4fe5cb45..7e9292bb66 100644 --- a/src/calibre/devices/smart_device_app/driver.py +++ b/src/calibre/devices/smart_device_app/driver.py @@ -164,7 +164,7 @@ class ConnectionListener(Thread): except socket.timeout: pass - except socket.error: + except OSError: x = sys.exc_info()[1] self.driver._debug('unexpected socket exception', x.args[0]) self._close_socket(device_socket) @@ -623,9 +623,9 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): amt_sent = sock.send(s[sent_len:]) sock.settimeout(None) if amt_sent <= 0: - raise IOError('Bad write on socket') + raise OSError('Bad write on socket') sent_len += amt_sent - except socket.error as e: + except OSError as e: self._debug('socket error', e, e.errno) if e.args[0] != EAGAIN and e.args[0] != EINTR: self._close_device_socket() @@ -661,7 +661,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): self._debug('timeout communicating with device') self._close_device_socket() raise TimeoutError('Device did not respond in reasonable time') - except socket.error: + except OSError: self._debug('device went away') self._close_device_socket() raise ControlError(desc='Device closed the network connection') @@ -689,7 +689,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): self._debug('timeout communicating with device') self._close_device_socket() raise TimeoutError('Device did not respond in reasonable time') - except socket.error: + except OSError: self._debug('device went away') self._close_device_socket() raise ControlError(desc='Device closed the network connection') @@ -936,7 +936,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): sock.bind((ip_addr, port)) else: sock.bind(('', port)) - except socket.error: + except OSError: self._debug('socket error on port', port) port = 0 except: @@ -1213,7 +1213,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): return True except socket.timeout: self._close_device_socket() - except socket.error: + except OSError: x = sys.exc_info()[1] self._debug('unexpected socket exception', x.args[0]) self._close_device_socket() diff --git a/src/calibre/devices/teclast/driver.py b/src/calibre/devices/teclast/driver.py index 81c65e7d6d..a2a20be3ec 100644 --- a/src/calibre/devices/teclast/driver.py +++ b/src/calibre/devices/teclast/driver.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/devices/usbms/cli.py b/src/calibre/devices/usbms/cli.py index 1def891586..148607da03 100644 --- a/src/calibre/devices/usbms/cli.py +++ b/src/calibre/devices/usbms/cli.py @@ -54,7 +54,7 @@ class CLI: with dest: try: shutil.copyfileobj(infile, dest) - except IOError: + except OSError: print('WARNING: First attempt to send file to device failed') time.sleep(0.2) infile.seek(0) diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index 4be336ed1f..6c3cf2532e 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -296,7 +296,7 @@ class Device(DeviceConfig, DevicePlugin): try: return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0] - except IOError: # Probably an interrupted system call + except OSError: # Probably an interrupted system call if i == 2: raise time.sleep(2) @@ -310,7 +310,7 @@ class Device(DeviceConfig, DevicePlugin): try: return subprocess.Popen('mount', stdout=subprocess.PIPE).communicate()[0] - except IOError: # Probably an interrupted system call + except OSError: # Probably an interrupted system call if i == 2: raise time.sleep(2) @@ -440,8 +440,7 @@ class Device(DeviceConfig, DevicePlugin): isfile = os.path.isfile(p) yield p, isfile if not isfile: - for y, q in walk(p): - yield y, q + yield from walk(p) def raw2num(raw): raw = raw.lower() diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index afa2a212e0..dde84a97c9 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -68,8 +68,7 @@ def safe_walk(top, topdown=True, onerror=None, followlinks=False, maxdepth=128): for name in dirs: new_path = join(top, name) if followlinks or not islink(new_path): - for x in safe_walk(new_path, topdown, onerror, followlinks, maxdepth-1): - yield x + yield from safe_walk(new_path, topdown, onerror, followlinks, maxdepth-1) if not topdown: yield top, dirs, nondirs @@ -151,8 +150,8 @@ class USBMS(CLI, Device): if self._main_prefix is not None: try: self.driveinfo['main'] = self._update_driveinfo_file(self._main_prefix, 'main') - except (IOError, OSError) as e: - raise IOError(_('Failed to access files in the main memory of' + except OSError as e: + raise OSError(_('Failed to access files in the main memory of' ' your device. You should contact the device' ' manufacturer for support. Common fixes are:' ' try a different USB cable/USB port on your computer.' @@ -164,8 +163,8 @@ class USBMS(CLI, Device): self.driveinfo['A'] = self._update_driveinfo_file(self._card_a_prefix, 'A') if self._card_b_prefix is not None: self.driveinfo['B'] = self._update_driveinfo_file(self._card_b_prefix, 'B') - except (IOError, OSError) as e: - raise IOError(_('Failed to access files on the SD card in your' + except OSError as e: + raise OSError(_('Failed to access files on the SD card in your' ' device. This can happen for many reasons. The SD card may be' ' corrupted, it may be too large for your device, it may be' ' write-protected, etc. Try a different SD card, or reformat' diff --git a/src/calibre/devices/utils.py b/src/calibre/devices/utils.py index 16b740e2c8..d0543174cd 100644 --- a/src/calibre/devices/utils.py +++ b/src/calibre/devices/utils.py @@ -59,8 +59,8 @@ def build_template_regexp(template): template = template.rpartition('/')[2] return re.compile(re.sub('{([^}]*)}', f, template) + r'([_\d]*$)') except: - prints(u'Failed to parse template: %r'%template) - template = u'{title} - {authors}' + prints('Failed to parse template: %r'%template) + template = '{title} - {authors}' return re.compile(re.sub('{([^}]*)}', f, template) + r'([_\d]*$)') @@ -90,7 +90,7 @@ def create_upload_path(mdata, fname, template, sanitize, except: today = time.localtime() date = (today[0], today[1], today[2]) - template = u"{title}_%d-%d-%d" % date + template = "{title}_%d-%d-%d" % date fname = sanitize(fname) ext = path_type.splitext(fname)[1] diff --git a/src/calibre/devices/winusb.py b/src/calibre/devices/winusb.py index f69cda94d5..e00531f1d2 100644 --- a/src/calibre/devices/winusb.py +++ b/src/calibre/devices/winusb.py @@ -507,8 +507,7 @@ def iterchildren(parent_devinst): def iterdescendants(parent_devinst): for child in iterchildren(parent_devinst): yield child - for gc in iterdescendants(child): - yield gc + yield from iterdescendants(child) def iterancestors(devinst): diff --git a/src/calibre/ebooks/__init__.py b/src/calibre/ebooks/__init__.py index f30f6e9daa..2605e47980 100644 --- a/src/calibre/ebooks/__init__.py +++ b/src/calibre/ebooks/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -81,7 +79,7 @@ def extract_calibre_cover(raw, base, log): if matches is None: body = soup.find('body') if body is not None: - text = u''.join(map(str, body.findAll(text=True))) + text = ''.join(map(str, body.findAll(text=True))) if text.strip(): # Body has text, abort return diff --git a/src/calibre/ebooks/chardet.py b/src/calibre/ebooks/chardet.py index 47fb91a8e0..ced93f410b 100644 --- a/src/calibre/ebooks/chardet.py +++ b/src/calibre/ebooks/chardet.py @@ -33,8 +33,7 @@ class LazyEncodingPats: if pats is None: pats = tuple(compile_pats(binary)) setattr(self, attr, pats) - for pat in pats: - yield pat + yield from pats lazy_encoding_pats = LazyEncodingPats() @@ -51,7 +50,7 @@ def strip_encoding_declarations(raw, limit=50*1024, preserve_newlines=False): else: sub = lambda m: '\n' * m.group().count('\n') else: - sub = b'' if is_binary else u'' + sub = b'' if is_binary else '' for pat in lazy_encoding_pats(is_binary): prefix = pat.sub(sub, prefix) raw = prefix + suffix diff --git a/src/calibre/ebooks/comic/input.py b/src/calibre/ebooks/comic/input.py index 62aea41a1e..1881916c89 100644 --- a/src/calibre/ebooks/comic/input.py +++ b/src/calibre/ebooks/comic/input.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/conversion/cli.py b/src/calibre/ebooks/conversion/cli.py index 49a3cff57d..f05067bafb 100644 --- a/src/calibre/ebooks/conversion/cli.py +++ b/src/calibre/ebooks/conversion/cli.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' @@ -372,7 +370,7 @@ def main(args=sys.argv): parser, plumber = create_option_parser(args, log) opts, leftover_args = parser.parse_args(args) if len(leftover_args) > 3: - log.error('Extra arguments not understood:', u', '.join(leftover_args[3:])) + log.error('Extra arguments not understood:', ', '.join(leftover_args[3:])) return 1 for x in ('read_metadata_from_opf', 'cover'): if getattr(opts, x, None) is not None: diff --git a/src/calibre/ebooks/conversion/config.py b/src/calibre/ebooks/conversion/config.py index b96c71ef3a..3d0828da1e 100644 --- a/src/calibre/ebooks/conversion/config.py +++ b/src/calibre/ebooks/conversion/config.py @@ -70,7 +70,7 @@ class GuiRecommendations(dict): def __new__(cls, *args): dict.__new__(cls) - obj = super(GuiRecommendations, cls).__new__(cls, *args) + obj = super().__new__(cls, *args) obj.disabled_options = set() return obj diff --git a/src/calibre/ebooks/conversion/plugins/chm_input.py b/src/calibre/ebooks/conversion/plugins/chm_input.py index 6653120cf5..058f4b96aa 100644 --- a/src/calibre/ebooks/conversion/plugins/chm_input.py +++ b/src/calibre/ebooks/conversion/plugins/chm_input.py @@ -1,5 +1,3 @@ - - ''' CHM File decoding support ''' __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ,' \ diff --git a/src/calibre/ebooks/conversion/plugins/comic_input.py b/src/calibre/ebooks/conversion/plugins/comic_input.py index a1970624c0..075f39ff79 100644 --- a/src/calibre/ebooks/conversion/plugins/comic_input.py +++ b/src/calibre/ebooks/conversion/plugins/comic_input.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/conversion/plugins/epub_input.py b/src/calibre/ebooks/conversion/plugins/epub_input.py index 98f3d3d62e..b5470ccbc4 100644 --- a/src/calibre/ebooks/conversion/plugins/epub_input.py +++ b/src/calibre/ebooks/conversion/plugins/epub_input.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/conversion/plugins/epub_output.py b/src/calibre/ebooks/conversion/plugins/epub_output.py index e6cf2fdf04..aef9448b72 100644 --- a/src/calibre/ebooks/conversion/plugins/epub_output.py +++ b/src/calibre/ebooks/conversion/plugins/epub_output.py @@ -291,7 +291,7 @@ class EPUBOutput(OutputFormatPlugin): from calibre.ebooks.oeb.polish.cover import fix_conversion_titlepage_links_in_nav try: os.mkdir(os.path.join(tdir, 'META-INF')) - except EnvironmentError: + except OSError: pass with open(os.path.join(tdir, 'META-INF', 'container.xml'), 'wb') as f: f.write(simple_container_xml(os.path.basename(opf)).encode('utf-8')) @@ -307,7 +307,7 @@ class EPUBOutput(OutputFormatPlugin): os.remove(f.name) try: os.rmdir(os.path.join(tdir, 'META-INF')) - except EnvironmentError: + except OSError: pass def encrypt_fonts(self, uris, tdir, uuid): # {{{ diff --git a/src/calibre/ebooks/conversion/plugins/fb2_input.py b/src/calibre/ebooks/conversion/plugins/fb2_input.py index 818d29e62a..69398c8bee 100644 --- a/src/calibre/ebooks/conversion/plugins/fb2_input.py +++ b/src/calibre/ebooks/conversion/plugins/fb2_input.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Anatoly Shipitsin ' """ @@ -146,7 +144,7 @@ class FB2Input(InputFormatPlugin): break opf = OPFCreator(os.getcwd(), mi) - entries = [(f2, guess_type(f2)[0]) for f2 in os.listdir(u'.')] + entries = [(f2, guess_type(f2)[0]) for f2 in os.listdir('.')] opf.create_manifest(entries) opf.create_spine(['index.xhtml']) if cpath: diff --git a/src/calibre/ebooks/conversion/plugins/html_input.py b/src/calibre/ebooks/conversion/plugins/html_input.py index 3e74de67bb..a75809e120 100644 --- a/src/calibre/ebooks/conversion/plugins/html_input.py +++ b/src/calibre/ebooks/conversion/plugins/html_input.py @@ -284,7 +284,7 @@ class HTMLInput(InputFormatPlugin): # Check for the common case, images try: img = what(link) - except EnvironmentError: + except OSError: pass else: if img: diff --git a/src/calibre/ebooks/conversion/plugins/html_output.py b/src/calibre/ebooks/conversion/plugins/html_output.py index d35fabb5f8..19fc47bd9c 100644 --- a/src/calibre/ebooks/conversion/plugins/html_output.py +++ b/src/calibre/ebooks/conversion/plugins/html_output.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2010, Fabian Grassl ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/conversion/plugins/htmlz_input.py b/src/calibre/ebooks/conversion/plugins/htmlz_input.py index ab22eb93d7..c67fcbb153 100644 --- a/src/calibre/ebooks/conversion/plugins/htmlz_input.py +++ b/src/calibre/ebooks/conversion/plugins/htmlz_input.py @@ -26,7 +26,7 @@ class HTMLZInput(InputFormatPlugin): from calibre.utils.zipfile import ZipFile self.log = log - html = u'' + html = '' top_levels = [] # Extract content from zip archive. @@ -35,21 +35,21 @@ class HTMLZInput(InputFormatPlugin): # Find the HTML file in the archive. It needs to be # top level. - index = u'' + index = '' multiple_html = False # Get a list of all top level files in the archive. - for x in os.listdir(u'.'): + for x in os.listdir('.'): if os.path.isfile(x): top_levels.append(x) # Try to find an index. file. for x in top_levels: - if x.lower() in (u'index.html', u'index.xhtml', u'index.htm'): + if x.lower() in ('index.html', 'index.xhtml', 'index.htm'): index = x break # Look for multiple HTML files in the archive. We look at the # top level files only as only they matter in HTMLZ. for x in top_levels: - if os.path.splitext(x)[1].lower() in (u'.html', u'.xhtml', u'.htm'): + if os.path.splitext(x)[1].lower() in ('.html', '.xhtml', '.htm'): # Set index to the first HTML file found if it's not # called index. if not index: @@ -86,11 +86,11 @@ class HTMLZInput(InputFormatPlugin): setattr(options, opt.option.name, opt.recommended_value) options.input_encoding = 'utf-8' base = os.getcwd() - htmlfile = os.path.join(base, u'index.html') + htmlfile = os.path.join(base, 'index.html') c = 0 while os.path.exists(htmlfile): c += 1 - htmlfile = u'index%d.html'%c + htmlfile = 'index%d.html'%c with open(htmlfile, 'wb') as f: f.write(html.encode('utf-8')) odi = options.debug_pipeline @@ -112,7 +112,7 @@ class HTMLZInput(InputFormatPlugin): cover_path = None opf = None for x in top_levels: - if os.path.splitext(x)[1].lower() == u'.opf': + if os.path.splitext(x)[1].lower() == '.opf': opf = x break if opf: diff --git a/src/calibre/ebooks/conversion/plugins/htmlz_output.py b/src/calibre/ebooks/conversion/plugins/htmlz_output.py index 2c07375ef1..c206062ec4 100644 --- a/src/calibre/ebooks/conversion/plugins/htmlz_output.py +++ b/src/calibre/ebooks/conversion/plugins/htmlz_output.py @@ -72,36 +72,36 @@ class HTMLZOutput(OutputFormatPlugin): else: from calibre.ebooks.htmlz.oeb2html import OEB2HTMLClassCSSizer as OEB2HTMLizer - with TemporaryDirectory(u'_htmlz_output') as tdir: + with TemporaryDirectory('_htmlz_output') as tdir: htmlizer = OEB2HTMLizer(log) html = htmlizer.oeb2html(oeb_book, opts) - fname = u'index' + fname = 'index' if opts.htmlz_title_filename: from calibre.utils.filenames import shorten_components_to fname = shorten_components_to(100, (ascii_filename(str(oeb_book.metadata.title[0])),))[0] - with open(os.path.join(tdir, fname+u'.html'), 'wb') as tf: + with open(os.path.join(tdir, fname+'.html'), 'wb') as tf: if isinstance(html, str): html = html.encode('utf-8') tf.write(html) # CSS if opts.htmlz_css_type == 'class' and opts.htmlz_class_style == 'external': - with open(os.path.join(tdir, u'style.css'), 'wb') as tf: + with open(os.path.join(tdir, 'style.css'), 'wb') as tf: tf.write(htmlizer.get_css(oeb_book).encode('utf-8')) # Images images = htmlizer.images if images: - if not os.path.exists(os.path.join(tdir, u'images')): - os.makedirs(os.path.join(tdir, u'images')) + if not os.path.exists(os.path.join(tdir, 'images')): + os.makedirs(os.path.join(tdir, 'images')) for item in oeb_book.manifest: if item.media_type in OEB_IMAGES and item.href in images: if item.media_type == SVG_MIME: data = etree.tostring(item.data, encoding='unicode').encode('utf-8') else: data = item.data - fname = os.path.join(tdir, u'images', images[item.href]) + fname = os.path.join(tdir, 'images', images[item.href]) with open(fname, 'wb') as img: img.write(data) @@ -114,7 +114,7 @@ class HTMLZOutput(OutputFormatPlugin): cover_data = oeb_book.guide[term].item.data if cover_data: from calibre.utils.img import save_cover_data_to - cover_path = os.path.join(tdir, u'cover.jpg') + cover_path = os.path.join(tdir, 'cover.jpg') with lopen(cover_path, 'w') as cf: cf.write('') save_cover_data_to(cover_data, cover_path) @@ -123,11 +123,11 @@ class HTMLZOutput(OutputFormatPlugin): traceback.print_exc() # Metadata - with open(os.path.join(tdir, u'metadata.opf'), 'wb') as mdataf: + with open(os.path.join(tdir, 'metadata.opf'), 'wb') as mdataf: opf = OPF(io.BytesIO(etree.tostring(oeb_book.metadata.to_opf1(), encoding='UTF-8'))) mi = opf.to_book_metadata() if cover_path: - mi.cover = u'cover.jpg' + mi.cover = 'cover.jpg' mdataf.write(metadata_to_opf(mi)) htmlz = ZipFile(output_path, 'w') diff --git a/src/calibre/ebooks/conversion/plugins/lrf_input.py b/src/calibre/ebooks/conversion/plugins/lrf_input.py index 9bc61946bc..ed2f80ff25 100644 --- a/src/calibre/ebooks/conversion/plugins/lrf_input.py +++ b/src/calibre/ebooks/conversion/plugins/lrf_input.py @@ -31,7 +31,7 @@ class LRFInput(InputFormatPlugin): d.parse() xml = d.to_xml(write_files=True) if options.verbose > 2: - open(u'lrs.xml', 'wb').write(xml.encode('utf-8')) + open('lrs.xml', 'wb').write(xml.encode('utf-8')) doc = safe_xml_fromstring(xml) char_button_map = {} diff --git a/src/calibre/ebooks/conversion/plugins/mobi_input.py b/src/calibre/ebooks/conversion/plugins/mobi_input.py index 7888f03e2d..7d515bd015 100644 --- a/src/calibre/ebooks/conversion/plugins/mobi_input.py +++ b/src/calibre/ebooks/conversion/plugins/mobi_input.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/conversion/plugins/odt_input.py b/src/calibre/ebooks/conversion/plugins/odt_input.py index a05f8e2faa..baa5634e0f 100644 --- a/src/calibre/ebooks/conversion/plugins/odt_input.py +++ b/src/calibre/ebooks/conversion/plugins/odt_input.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/conversion/plugins/oeb_output.py b/src/calibre/ebooks/conversion/plugins/oeb_output.py index 8d2ae95bdb..774537481f 100644 --- a/src/calibre/ebooks/conversion/plugins/oeb_output.py +++ b/src/calibre/ebooks/conversion/plugins/oeb_output.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/conversion/plugins/rtf_input.py b/src/calibre/ebooks/conversion/plugins/rtf_input.py index 547074fdeb..e4e15b2a80 100644 --- a/src/calibre/ebooks/conversion/plugins/rtf_input.py +++ b/src/calibre/ebooks/conversion/plugins/rtf_input.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -54,12 +53,12 @@ class RTFInput(InputFormatPlugin): def generate_xml(self, stream): from calibre.ebooks.rtf2xml.ParseRtf import ParseRtf - ofile = u'dataxml.xml' + ofile = 'dataxml.xml' run_lev, debug_dir, indent_out = 1, None, 0 if getattr(self.opts, 'debug_pipeline', None) is not None: try: - os.mkdir(u'rtfdebug') - debug_dir = u'rtfdebug' + os.mkdir('rtfdebug') + debug_dir = 'rtfdebug' run_lev = 4 indent_out = 1 self.log('Running RTFParser in debug mode') @@ -137,7 +136,7 @@ class RTFInput(InputFormatPlugin): if fmt is None: fmt = 'wmf' count += 1 - name = u'%04d.%s' % (count, fmt) + name = '%04d.%s' % (count, fmt) with open(name, 'wb') as f: f.write(data) imap[count] = name @@ -215,7 +214,7 @@ class RTFInput(InputFormatPlugin): for cls, val in iteritems(border_styles): css += '\n\n.%s {\n%s\n}'%(cls, val) - with open(u'styles.css', 'ab') as f: + with open('styles.css', 'ab') as f: f.write(css.encode('utf-8')) def convert_borders(self, doc): @@ -286,7 +285,7 @@ class RTFInput(InputFormatPlugin): extensions = {('calibre', 'inline-class') : inline_class} transform = etree.XSLT(styledoc, extensions=extensions) result = transform(doc) - html = u'index.xhtml' + html = 'index.xhtml' with open(html, 'wb') as f: res = as_bytes(transform.tostring(result)) # res = res[:100].replace('xmlns:html', 'xmlns') + res[100:] @@ -305,10 +304,10 @@ class RTFInput(InputFormatPlugin): if not mi.authors: mi.authors = [_('Unknown')] opf = OPFCreator(os.getcwd(), mi) - opf.create_manifest([(u'index.xhtml', None)]) - opf.create_spine([u'index.xhtml']) - opf.render(open(u'metadata.opf', 'wb')) - return os.path.abspath(u'metadata.opf') + opf.create_manifest([('index.xhtml', None)]) + opf.create_spine(['index.xhtml']) + opf.render(open('metadata.opf', 'wb')) + return os.path.abspath('metadata.opf') def postprocess_book(self, oeb, opts, log): for item in oeb.spine: diff --git a/src/calibre/ebooks/covers.py b/src/calibre/ebooks/covers.py index ff3dbe1801..52c4dbbd9b 100644 --- a/src/calibre/ebooks/covers.py +++ b/src/calibre/ebooks/covers.py @@ -561,10 +561,10 @@ class Blocks(Style): def all_styles(): - return set( + return { x.NAME for x in itervalues(globals()) if isinstance(x, type) and issubclass(x, Style) and x is not Style - ) + } def load_styles(prefs, respect_disabled=True): diff --git a/src/calibre/ebooks/docx/container.py b/src/calibre/ebooks/docx/container.py index 032e2a4b2f..d2d40453f0 100644 --- a/src/calibre/ebooks/docx/container.py +++ b/src/calibre/ebooks/docx/container.py @@ -259,7 +259,7 @@ class DOCX: else: try: shutil.rmtree(self.tdir) - except EnvironmentError: + except OSError: pass diff --git a/src/calibre/ebooks/docx/fields.py b/src/calibre/ebooks/docx/fields.py index a056c76606..d33ff8e951 100644 --- a/src/calibre/ebooks/docx/fields.py +++ b/src/calibre/ebooks/docx/fields.py @@ -54,7 +54,7 @@ null = object() def parser(name, field_map, default_field_name=None): - field_map = dict((x.split(':') for x in field_map.split())) + field_map = dict(x.split(':') for x in field_map.split()) def parse(raw, log=None): ans = {} diff --git a/src/calibre/ebooks/docx/footnotes.py b/src/calibre/ebooks/docx/footnotes.py index 36c1fea5f9..f0652e471f 100644 --- a/src/calibre/ebooks/docx/footnotes.py +++ b/src/calibre/ebooks/docx/footnotes.py @@ -18,8 +18,7 @@ class Note: self.namespace = namespace def __iter__(self): - for p in self.namespace.descendants(self.parent, 'w:p', 'w:tbl'): - yield p + yield from self.namespace.descendants(self.parent, 'w:p', 'w:tbl') class Footnotes: diff --git a/src/calibre/ebooks/docx/images.py b/src/calibre/ebooks/docx/images.py index 91d67c9a25..873e8781eb 100644 --- a/src/calibre/ebooks/docx/images.py +++ b/src/calibre/ebooks/docx/images.py @@ -359,8 +359,6 @@ class Images: os.mkdir(dest) self.dest_dir, self.docx = dest, docx if elem.tag.endswith('}drawing'): - for tag in self.drawing_to_html(elem, page): - yield tag + yield from self.drawing_to_html(elem, page) else: - for tag in self.pict_to_html(elem, page): - yield tag + yield from self.pict_to_html(elem, page) diff --git a/src/calibre/ebooks/docx/styles.py b/src/calibre/ebooks/docx/styles.py index f7346391e4..d20b13eeb0 100644 --- a/src/calibre/ebooks/docx/styles.py +++ b/src/calibre/ebooks/docx/styles.py @@ -124,8 +124,7 @@ class Styles: self.default_paragraph_style = self.default_character_style = None def __iter__(self): - for s in itervalues(self.id_map): - yield s + yield from itervalues(self.id_map) def __getitem__(self, key): return self.id_map[key] diff --git a/src/calibre/ebooks/docx/tables.py b/src/calibre/ebooks/docx/tables.py index bb1d8ebbdb..45c43151b9 100644 --- a/src/calibre/ebooks/docx/tables.py +++ b/src/calibre/ebooks/docx/tables.py @@ -615,11 +615,9 @@ class Table: tc.getparent().remove(tc) def __iter__(self): - for p in self.paragraphs: - yield p + yield from self.paragraphs for t in itervalues(self.sub_tables): - for p in t: - yield p + yield from t def apply_markup(self, rmap, page, parent=None): table = TABLE('\n\t\t') diff --git a/src/calibre/ebooks/docx/to_html.py b/src/calibre/ebooks/docx/to_html.py index 72b4fd54fc..a10a6ce181 100644 --- a/src/calibre/ebooks/docx/to_html.py +++ b/src/calibre/ebooks/docx/to_html.py @@ -311,7 +311,7 @@ class Convert: seraw = self.docx.read(sename) except KeyError: self.log.warn('Settings %s do not exist' % sename) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise self.log.warn('Settings %s file missing' % sename) diff --git a/src/calibre/ebooks/epub/__init__.py b/src/calibre/ebooks/epub/__init__.py index 02cad97ff5..71c1a5f210 100644 --- a/src/calibre/ebooks/epub/__init__.py +++ b/src/calibre/ebooks/epub/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' @@ -37,7 +35,7 @@ def initialize_container(path_to_container, opf_name='metadata.opf', ''' rootfiles = '' for path, mimetype, _ in extra_entries: - rootfiles += ''.format( + rootfiles += ''.format( path, mimetype) CONTAINER = simple_container_xml(opf_name, rootfiles).encode('utf-8') zf = ZipFile(path_to_container, 'w') diff --git a/src/calibre/ebooks/fb2/fb2ml.py b/src/calibre/ebooks/fb2/fb2ml.py index d7771afe87..f310f68991 100644 --- a/src/calibre/ebooks/fb2/fb2ml.py +++ b/src/calibre/ebooks/fb2/fb2ml.py @@ -124,7 +124,7 @@ class FB2MLizer: lc = self.oeb_book.metadata.language[0].value metadata['lang'] = lc or 'en' else: - metadata['lang'] = u'en' + metadata['lang'] = 'en' metadata['id'] = None metadata['cover'] = self.get_cover() metadata['genre'] = self.opts.fb2_genre @@ -483,7 +483,7 @@ class FB2MLizer: tags += p_tag fb2_out.append('' % self.image_hrefs[ihref]) else: - self.log.warn(u'Ignoring image not in manifest: %s' % ihref) + self.log.warn('Ignoring image not in manifest: %s' % ihref) if tag in ('br', 'hr') or ems >= 1: if ems < 1: multiplier = 1 diff --git a/src/calibre/ebooks/html/input.py b/src/calibre/ebooks/html/input.py index 2622ab6104..1527883dfc 100644 --- a/src/calibre/ebooks/html/input.py +++ b/src/calibre/ebooks/html/input.py @@ -121,10 +121,10 @@ class HTMLFile: self.is_binary = not bool(pat.search(header)) if not self.is_binary: src += f.read() - except IOError as err: + except OSError as err: msg = 'Could not read from file: %s with error: %s'%(self.path, as_unicode(err)) if level == 0: - raise IOError(msg) + raise OSError(msg) raise IgnoreFile(msg, err.errno) if not src: diff --git a/src/calibre/ebooks/html/meta.py b/src/calibre/ebooks/html/meta.py index 5dc5f45dc0..cad6cc6c5a 100644 --- a/src/calibre/ebooks/html/meta.py +++ b/src/calibre/ebooks/html/meta.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2010, Fabian Grassl ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/htmlz/oeb2html.py b/src/calibre/ebooks/htmlz/oeb2html.py index 027d42bd84..5d4166d8cf 100644 --- a/src/calibre/ebooks/htmlz/oeb2html.py +++ b/src/calibre/ebooks/htmlz/oeb2html.py @@ -58,7 +58,7 @@ class OEB2HTML: def mlize_spine(self, oeb_book): output = [ - u'%s' % ( + '%s' % ( prepare_string_for_xml(self.book_title)) ] for item in oeb_book.spine: @@ -139,10 +139,10 @@ class OEB2HTML: def prepare_string_for_html(self, raw): raw = prepare_string_for_xml(raw) - raw = raw.replace(u'\u00ad', '­') - raw = raw.replace(u'\u2014', '—') - raw = raw.replace(u'\u2013', '–') - raw = raw.replace(u'\u00a0', ' ') + raw = raw.replace('\u00ad', '­') + raw = raw.replace('\u2014', '—') + raw = raw.replace('\u2013', '–') + raw = raw.replace('\u00a0', ' ') return raw @@ -340,9 +340,9 @@ class OEB2HTMLClassCSSizer(OEB2HTML): css = '' else: css = '' - title = u'%s' % prepare_string_for_xml(self.book_title) - output = [u''] + \ - [css] + [title, u''] + output + [u''] + title = '%s' % prepare_string_for_xml(self.book_title) + output = [''] + \ + [css] + [title, ''] + output + [''] return ''.join(output) def dump_text(self, elem, stylizer, page): diff --git a/src/calibre/ebooks/hyphenate.py b/src/calibre/ebooks/hyphenate.py index 5311fbdda3..78480cdf57 100644 --- a/src/calibre/ebooks/hyphenate.py +++ b/src/calibre/ebooks/hyphenate.py @@ -1,5 +1,3 @@ - - """ Hyphenation, using Frank Liang's algorithm. This module provides a single function to hyphenate words. hyphenate_word takes diff --git a/src/calibre/ebooks/lit/__init__.py b/src/calibre/ebooks/lit/__init__.py index 98e16efde0..5be3cb9b6a 100644 --- a/src/calibre/ebooks/lit/__init__.py +++ b/src/calibre/ebooks/lit/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' diff --git a/src/calibre/ebooks/lit/lzx.py b/src/calibre/ebooks/lit/lzx.py index 2603859c21..1ce8d28db8 100644 --- a/src/calibre/ebooks/lit/lzx.py +++ b/src/calibre/ebooks/lit/lzx.py @@ -1,5 +1,3 @@ - - ''' LZX compression/decompression wrapper. ''' diff --git a/src/calibre/ebooks/lit/maps/__init__.py b/src/calibre/ebooks/lit/maps/__init__.py index 47b1ac0be1..b30974ba6b 100644 --- a/src/calibre/ebooks/lit/maps/__init__.py +++ b/src/calibre/ebooks/lit/maps/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' diff --git a/src/calibre/ebooks/lit/maps/html.py b/src/calibre/ebooks/lit/maps/html.py index 2b294242eb..c144d55ea8 100644 --- a/src/calibre/ebooks/lit/maps/html.py +++ b/src/calibre/ebooks/lit/maps/html.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' diff --git a/src/calibre/ebooks/lit/maps/opf.py b/src/calibre/ebooks/lit/maps/opf.py index 3ecf4d4587..af1355612b 100644 --- a/src/calibre/ebooks/lit/maps/opf.py +++ b/src/calibre/ebooks/lit/maps/opf.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' diff --git a/src/calibre/ebooks/lit/mssha1.py b/src/calibre/ebooks/lit/mssha1.py index 6ab6ccaccc..5ac50ddccf 100644 --- a/src/calibre/ebooks/lit/mssha1.py +++ b/src/calibre/ebooks/lit/mssha1.py @@ -1,4 +1,3 @@ - """ Modified version of SHA-1 used in Microsoft LIT files. diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 585f504e2b..9a4cc4604c 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -1,4 +1,3 @@ - ''' Support for reading LIT files. ''' @@ -117,7 +116,7 @@ def consume_sized_utf8_string(bytes, zpad=False): result.append(char) if zpad and bytes[pos:pos+1] == b'\0': pos += 1 - return u''.join(result), bytes[pos:] + return ''.join(result), bytes[pos:] def encode(string): @@ -197,7 +196,7 @@ class UnBinary: if state == 'close tag': if not tag_name: raise LitError('Tag ends before it begins.') - buf.write(encode(u''.join(('')))) + buf.write(encode(''.join(('')))) dynamic_tag = 0 tag_name = None state = 'text' @@ -380,7 +379,7 @@ class UnBinary: if frag: path = '#'.join((path, frag)) path = urlnormalize(path) - buf.write(encode(u'"%s"' % path)) + buf.write(encode('"%s"' % path)) state = 'get attr' @@ -955,4 +954,4 @@ class LitReader(OEBReader): hasattr(item.data, 'xpath') and item.data.xpath('/html')): item.media_type = 'application/xhtml+xml' item.data = item._parse_xhtml(etree.tostring(item.data)) - super(LitReader, self)._spine_from_opf(opf) + super()._spine_from_opf(opf) diff --git a/src/calibre/ebooks/lit/writer.py b/src/calibre/ebooks/lit/writer.py index 689f04a0eb..21af07a400 100644 --- a/src/calibre/ebooks/lit/writer.py +++ b/src/calibre/ebooks/lit/writer.py @@ -1,4 +1,3 @@ - ''' Basic support for writing LIT files. ''' @@ -48,9 +47,9 @@ ALL_MS_COVER_TYPES = [ def invert_tag_map(tag_map): tags, dattrs, tattrs = tag_map - tags = dict((tags[i], i) for i in range(len(tags))) - dattrs = dict((v, k) for k, v in dattrs.items()) - tattrs = [dict((v, k) for k, v in (map or {}).items()) for map in tattrs] + tags = {tags[i]: i for i in range(len(tags))} + dattrs = {v: k for k, v in dattrs.items()} + tattrs = [{v: k for k, v in (map or {}).items()} for map in tattrs] for map in tattrs: if map: map.update(dattrs) @@ -165,7 +164,7 @@ class ReBinary: value = codepoint_to_chr(value) except OverflowError: self.logger.warn('Unicode overflow for integer:', value) - value = u'?' + value = '?' self.buf.write(value.encode('utf-8')) def is_block(self, style): @@ -495,7 +494,7 @@ class LitWriter: def _build_manifest(self): states = ['linear', 'nonlinear', 'css', 'images'] - manifest = dict((state, []) for state in states) + manifest = {state: [] for state in states} for item in self._oeb.manifest.values(): if item.spine_position is not None: key = 'linear' if item.linear else 'nonlinear' @@ -577,7 +576,7 @@ class LitWriter: self._add_file('/meta', meta) def _build_drm_storage(self): - drmsource = u'Free as in freedom\0'.encode('utf-16-le') + drmsource = 'Free as in freedom\0'.encode('utf-16-le') self._add_file('/DRMStorage/DRMSource', drmsource) tempkey = self._calculate_deskey([self._meta, drmsource]) msdes.deskey(tempkey, msdes.EN0) diff --git a/src/calibre/ebooks/lrf/__init__.py b/src/calibre/ebooks/lrf/__init__.py index 45b6fb9b26..4f90be7d97 100644 --- a/src/calibre/ebooks/lrf/__init__.py +++ b/src/calibre/ebooks/lrf/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' """ diff --git a/src/calibre/ebooks/lrf/fonts.py b/src/calibre/ebooks/lrf/fonts.py index 6c4bee40ce..7da59cae0b 100644 --- a/src/calibre/ebooks/lrf/fonts.py +++ b/src/calibre/ebooks/lrf/fonts.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/ebooks/lrf/html/__init__.py b/src/calibre/ebooks/lrf/html/__init__.py index 108bfed51c..9e110971bf 100644 --- a/src/calibre/ebooks/lrf/html/__init__.py +++ b/src/calibre/ebooks/lrf/html/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' """ diff --git a/src/calibre/ebooks/lrf/html/color_map.py b/src/calibre/ebooks/lrf/html/color_map.py index 2443b914c2..0260fd4ab4 100644 --- a/src/calibre/ebooks/lrf/html/color_map.py +++ b/src/calibre/ebooks/lrf/html/color_map.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/ebooks/lrf/html/convert_from.py b/src/calibre/ebooks/lrf/html/convert_from.py index 8e862ae95e..6c087252f0 100644 --- a/src/calibre/ebooks/lrf/html/convert_from.py +++ b/src/calibre/ebooks/lrf/html/convert_from.py @@ -926,7 +926,7 @@ class HTMLConverter: try: im = PILImage.open(path) - except IOError as err: + except OSError as err: self.log.warning('Unable to process image: %s\n%s'%(original_path, err)) return encoding = detect_encoding(im) @@ -943,7 +943,7 @@ class HTMLConverter: pt.close() self.scaled_images[path] = pt return pt.name - except (IOError, SystemError) as err: # PIL chokes on interlaced PNG images as well a some GIF images + except (OSError, SystemError) as err: # PIL chokes on interlaced PNG images as well a some GIF images self.log.warning( _('Unable to process image %(path)s. Error: %(err)s')%dict( path=path, err=err)) @@ -990,7 +990,7 @@ class HTMLConverter: path = pt.name self.rotated_images[path] = pt width, height = im.size - except IOError: # PIL chokes on interlaced PNG files and since auto-rotation is not critical we ignore the error + except OSError: # PIL chokes on interlaced PNG files and since auto-rotation is not critical we ignore the error self.log.debug(_('Unable to process interlaced PNG %s')% original_path) finally: pt.close() @@ -1062,10 +1062,10 @@ class HTMLConverter: self.end_page() self.page_break_found = True if not self.page_break_found and self.page_break.match(tagname): - number_of_paragraphs = sum([ + number_of_paragraphs = sum( len([1 for i in block.contents if isinstance(i, Paragraph)]) for block in self.current_page.contents if isinstance(block, TextBlock) - ]) + ) if number_of_paragraphs > 2: self.end_page() @@ -1536,7 +1536,7 @@ class HTMLConverter: if match and not re.match('avoid', match.group(1), re.IGNORECASE): self.page_break_found = True ncss, npcss = self.parse_css(src) - except IOError: + except OSError: self.log.warn('Could not read stylesheet: '+tag['href']) if ncss: update_css(ncss, self.css) @@ -1814,7 +1814,7 @@ def process_file(path, options, logger): tf.close() tim.save(tf.name) tpath = tf.name - except IOError as err: # PIL sometimes fails, for example on interlaced PNG files + except OSError as err: # PIL sometimes fails, for example on interlaced PNG files logger.warn(_('Could not read cover image: %s'), err) options.cover = None else: diff --git a/src/calibre/ebooks/lrf/html/table.py b/src/calibre/ebooks/lrf/html/table.py index 46c05fb3ab..956eabe14b 100644 --- a/src/calibre/ebooks/lrf/html/table.py +++ b/src/calibre/ebooks/lrf/html/table.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' import math, sys, re, numbers @@ -47,15 +45,13 @@ def tokens(tb): if hasattr(x.contents[0], 'text'): yield x.contents[0].text, cattrs(attrs, {}) elif hasattr(x.contents[0], 'attrs'): - for z in process_element(x.contents[0], x.contents[0].attrs): - yield z + yield from process_element(x.contents[0], x.contents[0].attrs) elif isinstance(x, Plot): yield x, None elif isinstance(x, Span): attrs = cattrs(attrs, x.attrs) for y in x.contents: - for z in process_element(y, attrs): - yield z + yield from process_element(y, attrs) for i in tb.contents: if isinstance(i, CR): @@ -65,8 +61,7 @@ def tokens(tb): attrs = {} if hasattr(j, 'attrs'): attrs = j.attrs - for k in process_element(j, attrs): - yield k + yield from process_element(j, attrs) class Cell: @@ -129,7 +124,7 @@ class Cell: return ceil((float(self.conv.profile.dpi)/72)*(pts/10)) def minimum_width(self): - return max([self.minimum_tb_width(tb) for tb in self.text_blocks]) + return max(self.minimum_tb_width(tb) for tb in self.text_blocks) def minimum_tb_width(self, tb): ts = tb.textStyle.attrs @@ -204,10 +199,10 @@ class Cell: return self.text_block_size(tb, sys.maxsize, debug=debug)[0] def preferred_width(self, debug=False): - return ceil(max([self.text_block_preferred_width(i, debug=debug) for i in self.text_blocks])) + return ceil(max(self.text_block_preferred_width(i, debug=debug) for i in self.text_blocks)) def height(self, width): - return sum([self.text_block_size(i, width)[1] for i in self.text_blocks]) + return sum(self.text_block_size(i, width)[1] for i in self.text_blocks) class Row: @@ -273,8 +268,7 @@ class Row: return -1 if cell.colspan > 1 else cell.pwidth def cell_iterator(self): - for c in self.cells: - yield c + yield from self.cells class Table: @@ -303,13 +297,13 @@ class Table: def height(self, maxwidth): ''' Return row heights + self.rowpad''' widths = self.get_widths(maxwidth) - return sum([row.height(widths) + self.rowpad for row in self.rows]) - self.rowpad + return sum(row.height(widths) + self.rowpad for row in self.rows) - self.rowpad def minimum_width(self, col): - return max([row.minimum_width(col) for row in self.rows]) + return max(row.minimum_width(col) for row in self.rows) def width_percent(self, col): - return max([row.width_percent(col) for row in self.rows]) + return max(row.width_percent(col) for row in self.rows) def get_widths(self, maxwidth): ''' diff --git a/src/calibre/ebooks/lrf/lrfparser.py b/src/calibre/ebooks/lrf/lrfparser.py index e750a08027..29675cc08a 100644 --- a/src/calibre/ebooks/lrf/lrfparser.py +++ b/src/calibre/ebooks/lrf/lrfparser.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' '''''' @@ -76,8 +74,7 @@ class LRFDocument(LRFMetaFile): self.ruby_tags[attr] = getattr(obj, attr) def __iter__(self): - for pt in self.page_trees: - yield pt + yield from self.page_trees def write_files(self): for obj in chain(itervalues(self.image_map), itervalues(self.font_map)): diff --git a/src/calibre/ebooks/lrf/lrs/__init__.py b/src/calibre/ebooks/lrf/lrs/__init__.py index eca3b37146..c983eb7892 100644 --- a/src/calibre/ebooks/lrf/lrs/__init__.py +++ b/src/calibre/ebooks/lrf/lrs/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' '''''' diff --git a/src/calibre/ebooks/lrf/lrs/convert_from.py b/src/calibre/ebooks/lrf/lrs/convert_from.py index 026643c1fd..94d8e215a9 100644 --- a/src/calibre/ebooks/lrf/lrs/convert_from.py +++ b/src/calibre/ebooks/lrf/lrs/convert_from.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' ''' diff --git a/src/calibre/ebooks/lrf/meta.py b/src/calibre/ebooks/lrf/meta.py index 14aeae303e..b85a9dc78b 100644 --- a/src/calibre/ebooks/lrf/meta.py +++ b/src/calibre/ebooks/lrf/meta.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/ebooks/lrf/objects.py b/src/calibre/ebooks/lrf/objects.py index 06faf6e9a0..ae14c33db6 100644 --- a/src/calibre/ebooks/lrf/objects.py +++ b/src/calibre/ebooks/lrf/objects.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' import struct, array, zlib, io, collections, re @@ -85,8 +83,7 @@ class LRFObject: raise LRFParseError("Unknown tag in %s: %s" % (self.__class__.__name__, str(tag))) def __iter__(self): - for i in range(0): - yield i + yield from range(0) def __str__(self): return self.__class__.__name__ @@ -129,8 +126,7 @@ class LRFContentObject(LRFObject): raise LRFParseError("Unknown tag in %s: %s" % (self.__class__.__name__, str(tag))) def __iter__(self): - for i in self._contents: - yield i + yield from self._contents class LRFStream(LRFObject): @@ -265,8 +261,7 @@ class Color: class EmptyPageElement: def __iter__(self): - for i in range(0): - yield i + yield from range(0) def __str__(self): return str(self) @@ -418,8 +413,7 @@ class Page(LRFStream): self.content = Page.Content(self.stream, self._document.objects) def __iter__(self): - for i in self.content: - yield i + yield from self.content def __str__(self): s = '\n\n'%(self.style_id, self.id) @@ -996,8 +990,7 @@ class Canvas(LRFStream): return s def __iter__(self): - for i in self._contents: - yield i + yield from self._contents class Header(Canvas): @@ -1223,8 +1216,7 @@ class TOCObject(LRFStream): c -= 1 def __iter__(self): - for i in self._contents: - yield i + yield from self._contents def __str__(self): s = '\n' diff --git a/src/calibre/ebooks/lrf/pylrs/__init__.py b/src/calibre/ebooks/lrf/pylrs/__init__.py index c7354ae57b..f4d0439228 100644 --- a/src/calibre/ebooks/lrf/pylrs/__init__.py +++ b/src/calibre/ebooks/lrf/pylrs/__init__.py @@ -1,5 +1,3 @@ - - """ This package contains code to generate ebooks in the SONY LRS/F format. It was originally developed by Mike Higgins and has been extended and modified by Kovid diff --git a/src/calibre/ebooks/lrf/pylrs/elements.py b/src/calibre/ebooks/lrf/pylrs/elements.py index 5a6a786767..79ee5ba864 100644 --- a/src/calibre/ebooks/lrf/pylrs/elements.py +++ b/src/calibre/ebooks/lrf/pylrs/elements.py @@ -1,5 +1,3 @@ - - """ elements.py -- replacements and helpers for ElementTree """ from polyglot.builtins import string_or_bytes diff --git a/src/calibre/ebooks/lrf/pylrs/pylrfopt.py b/src/calibre/ebooks/lrf/pylrs/pylrfopt.py index 00167e8c2d..64648c565e 100644 --- a/src/calibre/ebooks/lrf/pylrs/pylrfopt.py +++ b/src/calibre/ebooks/lrf/pylrs/pylrfopt.py @@ -1,5 +1,3 @@ - - def _optimize(tagList, tagName, conversion): # copy the tag of interest plus any text newTagList = [] diff --git a/src/calibre/ebooks/lrf/pylrs/pylrs.py b/src/calibre/ebooks/lrf/pylrs/pylrs.py index a5e63c82d7..5fa247dd4a 100644 --- a/src/calibre/ebooks/lrf/pylrs/pylrs.py +++ b/src/calibre/ebooks/lrf/pylrs/pylrs.py @@ -1,5 +1,3 @@ - - # Copyright (c) 2007 Mike Higgins (Falstaff) # Modifications from the original: # Copyright (C) 2007 Kovid Goyal @@ -305,8 +303,7 @@ class LrsContainer: if predicate(child): yield child if hasattr(child, 'get_all'): - for grandchild in child.get_all(predicate): - yield grandchild + yield from child.get_all(predicate) class LrsObject: diff --git a/src/calibre/ebooks/lrf/tags.py b/src/calibre/ebooks/lrf/tags.py index aa977f8720..0893468c66 100644 --- a/src/calibre/ebooks/lrf/tags.py +++ b/src/calibre/ebooks/lrf/tags.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' '''''' diff --git a/src/calibre/ebooks/metadata/__init__.py b/src/calibre/ebooks/metadata/__init__.py index 870b90a028..60af28eaea 100644 --- a/src/calibre/ebooks/metadata/__init__.py +++ b/src/calibre/ebooks/metadata/__init__.py @@ -315,8 +315,7 @@ class ResourceCollection: self._resources = [] def __iter__(self): - for r in self._resources: - yield r + yield from self._resources def __len__(self): return len(self._resources) diff --git a/src/calibre/ebooks/metadata/archive.py b/src/calibre/ebooks/metadata/archive.py index 5c75ab11f1..25831ad9b2 100644 --- a/src/calibre/ebooks/metadata/archive.py +++ b/src/calibre/ebooks/metadata/archive.py @@ -156,7 +156,7 @@ def get_comic_book_info(d, mi, series_index='volume'): 'Creator'): x = credit.get('person', '') if x: - x = ' '.join((reversed(x.split(', ')))) + x = ' '.join(reversed(x.split(', '))) authors.append(x) if authors: mi.authors = authors diff --git a/src/calibre/ebooks/metadata/book/json_codec.py b/src/calibre/ebooks/metadata/book/json_codec.py index 789829da5f..cc48aeb2c6 100644 --- a/src/calibre/ebooks/metadata/book/json_codec.py +++ b/src/calibre/ebooks/metadata/book/json_codec.py @@ -1,5 +1,3 @@ - - ''' Created on 4 Jun 2010 diff --git a/src/calibre/ebooks/metadata/book/render.py b/src/calibre/ebooks/metadata/book/render.py index 41b3d847f6..c4912894f2 100644 --- a/src/calibre/ebooks/metadata/book/render.py +++ b/src/calibre/ebooks/metadata/book/render.py @@ -97,7 +97,7 @@ def mi_to_html( ans = [] comment_fields = [] isdevice = not hasattr(mi, 'id') - row = u'%s%s' + row = '%s%s' p = prepare_string_for_xml a = partial(prepare_string_for_xml, attribute=True) book_id = getattr(mi, 'id', 0) @@ -147,7 +147,7 @@ def mi_to_html( if val: star_string = rating_to_stars(val, disp.get('allow_half_stars', False)) ans.append((field, - u'%s%s%s'%( name, rating_font, star_string))) elif metadata['datatype'] == 'composite': @@ -172,7 +172,7 @@ def mi_to_html( elif field == 'path': if mi.path: path = force_unicode(mi.path, filesystem_encoding) - scheme = u'devpath' if isdevice else u'path' + scheme = 'devpath' if isdevice else 'path' loc = path if isdevice else book_id pathstr = _('Click to open') extra = '' @@ -208,7 +208,7 @@ def mi_to_html( action('identifier', url=url, name=namel, id_type=id_typ, value=id_val, field='identifiers', book_id=book_id), a(id_typ), a(id_val), p(namel)) for namel, id_typ, id_val, url in urls] - links = u', '.join(links) + links = ', '.join(links) if links: ans.append((field, row % (_('Ids')+':', links))) elif field == 'authors': @@ -241,7 +241,7 @@ def mi_to_html( names = filter(None, map(calibre_langcode_to_name, mi.languages)) names = ['%s' % (search_action_with_data('languages', n, book_id), _( 'Search calibre for books with the language: {}').format(n), n) for n in names] - ans.append((field, row % (name, u', '.join(names)))) + ans.append((field, row % (name, ', '.join(names)))) elif field == 'publisher': if not mi.publisher: continue @@ -308,7 +308,7 @@ def mi_to_html( dc = getattr(mi, 'device_collections', []) if dc: - dc = u', '.join(sorted(dc, key=sort_key)) + dc = ', '.join(sorted(dc, key=sort_key)) ans.append(('device_collections', row % (_('Collections')+':', dc))) @@ -319,11 +319,11 @@ def mi_to_html( dt = 'text' return 'datatype_%s'%dt - ans = [u'%s'%(fieldl.replace('#', '_'), + ans = ['%s'%(fieldl.replace('#', '_'), classname(fieldl), html) for fieldl, html in ans] # print '\n'.join(ans) direction = 'rtl' if rtl else 'ltr' - rans = u''%(self.id, self.href(), self.media_type) + return ''%(self.id, self.href(), self.media_type) __str__ = __unicode__representation__ @@ -1121,8 +1120,7 @@ class OPF: # {{{ self.set_text(matches[0], str(val)) def identifier_iter(self): - for item in self.identifier_path(self.metadata): - yield item + yield from self.identifier_path(self.metadata) @property def raw_unique_identifier(self): @@ -1785,8 +1783,8 @@ def suite(): def testReading(self, opf=None): if opf is None: opf = self.opf - self.assertEqual(opf.title, u'A Cool & \xa9 \xdf Title') - self.assertEqual(opf.authors, u'Monkey Kitchen,Next'.split(',')) + self.assertEqual(opf.title, 'A Cool & \xa9 \xdf Title') + self.assertEqual(opf.authors, 'Monkey Kitchen,Next'.split(',')) self.assertEqual(opf.author_sort, 'Monkey') self.assertEqual(opf.title_sort, 'Wow') self.assertEqual(opf.tags, ['One', 'Two']) @@ -1832,12 +1830,12 @@ def test(): def test_user_metadata(): mi = Metadata('Test title', ['test author1', 'test author2']) um = { - '#myseries': {'#value#': u'test series\xe4', 'datatype':'text', - 'is_multiple': None, 'name': u'My Series'}, + '#myseries': {'#value#': 'test series\xe4', 'datatype':'text', + 'is_multiple': None, 'name': 'My Series'}, '#myseries_index': {'#value#': 2.45, 'datatype': 'float', 'is_multiple': None}, '#mytags': {'#value#':['t1','t2','t3'], 'datatype':'text', - 'is_multiple': '|', 'name': u'My Tags'} + 'is_multiple': '|', 'name': 'My Tags'} } mi.set_all_user_metadata(um) raw = metadata_to_opf(mi) diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py index 60b6e951f7..46f947fa6a 100644 --- a/src/calibre/ebooks/metadata/opf3.py +++ b/src/calibre/ebooks/metadata/opf3.py @@ -1007,7 +1007,7 @@ def read_metadata(root, ver=None, return_extra_data=False): ans.series, ans.series_index = s, si ans.author_link_map = read_author_link_map(root, prefixes, refines) or ans.author_link_map ans.user_categories = read_user_categories(root, prefixes, refines) or ans.user_categories - for name, fm in iteritems((read_user_metadata(root, prefixes, refines) or {})): + for name, fm in iteritems(read_user_metadata(root, prefixes, refines) or {}): ans.set_user_metadata(name, fm) if return_extra_data: ans = ans, ver, read_raster_cover(root, prefixes, refines), first_spine_item(root, prefixes, refines) diff --git a/src/calibre/ebooks/metadata/pdf.py b/src/calibre/ebooks/metadata/pdf.py index 929a36beb7..93ff67ad8b 100644 --- a/src/calibre/ebooks/metadata/pdf.py +++ b/src/calibre/ebooks/metadata/pdf.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' '''Read meta information from PDF files''' diff --git a/src/calibre/ebooks/metadata/rb.py b/src/calibre/ebooks/metadata/rb.py index 420d186bc6..bdca8a7c0f 100644 --- a/src/calibre/ebooks/metadata/rb.py +++ b/src/calibre/ebooks/metadata/rb.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Ashish Kulkarni ' '''Read meta information from RB files''' diff --git a/src/calibre/ebooks/metadata/rtf.py b/src/calibre/ebooks/metadata/rtf.py index 7c24f2d070..799a166e19 100644 --- a/src/calibre/ebooks/metadata/rtf.py +++ b/src/calibre/ebooks/metadata/rtf.py @@ -173,7 +173,7 @@ def create_metadata(stream, options): publisher = encode(options.publisher) md.append(r'{\manager %s}'%(publisher,)) if options.tags: - tags = u', '.join(options.tags) + tags = ', '.join(options.tags) tags = encode(tags) md.append(r'{\category %s}'%(tags,)) if len(md) > 1: diff --git a/src/calibre/ebooks/metadata/sources/cli.py b/src/calibre/ebooks/metadata/sources/cli.py index 9078b87588..bd37f57a2e 100644 --- a/src/calibre/ebooks/metadata/sources/cli.py +++ b/src/calibre/ebooks/metadata/sources/cli.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai -from __future__ import absolute_import, division, print_function, unicode_literals __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py index a252ebb3af..418f56225a 100644 --- a/src/calibre/ebooks/metadata/sources/identify.py +++ b/src/calibre/ebooks/metadata/sources/identify.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai -from __future__ import absolute_import, division, print_function, unicode_literals __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' @@ -400,7 +399,7 @@ def identify(log, abort, # {{{ results = {} for p in plugins: results[p] = [] - logs = dict([(w.plugin, w.buf) for w in workers]) + logs = {w.plugin: w.buf for w in workers} def get_results(): found = False diff --git a/src/calibre/ebooks/metadata/toc.py b/src/calibre/ebooks/metadata/toc.py index 5d0f7aad39..b6558a560e 100644 --- a/src/calibre/ebooks/metadata/toc.py +++ b/src/calibre/ebooks/metadata/toc.py @@ -114,8 +114,7 @@ class TOC(list): 'Depth first iteration over the tree rooted at self' yield self for obj in self: - for i in obj.flat(): - yield i + yield from obj.flat() @property def abspath(self): diff --git a/src/calibre/ebooks/metadata/topaz.py b/src/calibre/ebooks/metadata/topaz.py index 1642a31f83..abf09c18ed 100644 --- a/src/calibre/ebooks/metadata/topaz.py +++ b/src/calibre/ebooks/metadata/topaz.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2010, Greg Riker ' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/metadata/xisbn.py b/src/calibre/ebooks/metadata/xisbn.py index 4f61d14388..53d8829847 100644 --- a/src/calibre/ebooks/metadata/xisbn.py +++ b/src/calibre/ebooks/metadata/xisbn.py @@ -52,8 +52,7 @@ class xISBN: def isbns_in_data(self, data): for rec in data: - for i in rec.get('isbn', []): - yield i + yield from rec.get('isbn', []) def get_data(self, isbn): isbn = self.purify(isbn) diff --git a/src/calibre/ebooks/metadata/zip.py b/src/calibre/ebooks/metadata/zip.py index 62dfa783db..e900c32616 100644 --- a/src/calibre/ebooks/metadata/zip.py +++ b/src/calibre/ebooks/metadata/zip.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/ebooks/mobi/debug/index.py b/src/calibre/ebooks/mobi/debug/index.py index e934f83fd4..d8ab38f3ac 100644 --- a/src/calibre/ebooks/mobi/debug/index.py +++ b/src/calibre/ebooks/mobi/debug/index.py @@ -135,7 +135,7 @@ class Index: class SKELIndex(Index): def __init__(self, skelidx, records, codec): - super(SKELIndex, self).__init__(skelidx, records, codec) + super().__init__(skelidx, records, codec) self.records = [] if self.table is not None: @@ -156,7 +156,7 @@ class SKELIndex(Index): class SECTIndex(Index): def __init__(self, sectidx, records, codec): - super(SECTIndex, self).__init__(sectidx, records, codec) + super().__init__(sectidx, records, codec) self.records = [] if self.table is not None: @@ -181,7 +181,7 @@ class SECTIndex(Index): class GuideIndex(Index): def __init__(self, guideidx, records, codec): - super(GuideIndex, self).__init__(guideidx, records, codec) + super().__init__(guideidx, records, codec) self.records = [] if self.table is not None: @@ -203,7 +203,7 @@ class GuideIndex(Index): class NCXIndex(Index): def __init__(self, ncxidx, records, codec): - super(NCXIndex, self).__init__(ncxidx, records, codec) + super().__init__(ncxidx, records, codec) self.records = [] if self.table is not None: diff --git a/src/calibre/ebooks/mobi/mobiml.py b/src/calibre/ebooks/mobi/mobiml.py index a79db95ba6..284b2c220e 100644 --- a/src/calibre/ebooks/mobi/mobiml.py +++ b/src/calibre/ebooks/mobi/mobiml.py @@ -1,5 +1,3 @@ - - ''' Transform XHTML/OPS-ish content into Mobipocket HTML 3.2. ''' @@ -134,7 +132,7 @@ class MobiMLizer: self.log = self.oeb.logger self.opts = context self.profile = profile = context.dest - self.fnums = fnums = dict((v, k) for k, v in profile.fnums.items()) + self.fnums = fnums = {v: k for k, v in profile.fnums.items()} self.fmap = KeyMapper(profile.fbase, profile.fbase, fnums.keys()) self.mobimlize_spine() diff --git a/src/calibre/ebooks/mobi/reader/index.py b/src/calibre/ebooks/mobi/reader/index.py index 713cb74ae6..7913542c99 100644 --- a/src/calibre/ebooks/mobi/reader/index.py +++ b/src/calibre/ebooks/mobi/reader/index.py @@ -241,12 +241,12 @@ def parse_index_record(table, data, control_byte_count, tags, codec, ident, consumed = decode_string(rec, codec=codec, ordt_map=ordt_map) except UnicodeDecodeError: ident, consumed = decode_string(rec, codec='utf-16', ordt_map=ordt_map) - if u'\x00' in ident: + if '\x00' in ident: try: ident, consumed = decode_string(rec, codec='utf-16', ordt_map=ordt_map) except UnicodeDecodeError: - ident = ident.replace('u\x00', u'') + ident = ident.replace('u\x00', '') rec = rec[consumed:] tag_map = get_tag_map(control_byte_count, tags, rec, strict=strict) table[ident] = tag_map diff --git a/src/calibre/ebooks/mobi/reader/mobi8.py b/src/calibre/ebooks/mobi/reader/mobi8.py index e480aadd43..73318be22e 100644 --- a/src/calibre/ebooks/mobi/reader/mobi8.py +++ b/src/calibre/ebooks/mobi/reader/mobi8.py @@ -567,7 +567,7 @@ class Mobi8Reader: elif elem is start: reached = True - depths = sorted(set(x[-1] for x in links)) + depths = sorted({x[-1] for x in links}) depth_map = {x:i for i, x in enumerate(depths)} for text, href, frag, depth in links: depth = depth_map[depth] diff --git a/src/calibre/ebooks/mobi/writer2/indexer.py b/src/calibre/ebooks/mobi/writer2/indexer.py index 8e7dcf0a58..0fc15b1161 100644 --- a/src/calibre/ebooks/mobi/writer2/indexer.py +++ b/src/calibre/ebooks/mobi/writer2/indexer.py @@ -144,8 +144,7 @@ class IndexEntry: @property def tag_nums(self): - for i in range(1, 5): - yield i + yield from range(1, 5) for attr in ('class_offset', 'parent_index', 'first_child_index', 'last_child_index'): if getattr(self, attr) is not None: diff --git a/src/calibre/ebooks/mobi/writer2/serializer.py b/src/calibre/ebooks/mobi/writer2/serializer.py index 36ecdf1e9b..e8aaa11341 100644 --- a/src/calibre/ebooks/mobi/writer2/serializer.py +++ b/src/calibre/ebooks/mobi/writer2/serializer.py @@ -365,7 +365,7 @@ class Serializer: text = text.replace('&', '&') text = text.replace('<', '<') text = text.replace('>', '>') - text = text.replace(u'\u00AD', '') # Soft-hyphen + text = text.replace('\u00AD', '') # Soft-hyphen if quot: text = text.replace('"', '"') if isinstance(text, str): diff --git a/src/calibre/ebooks/mobi/writer8/header.py b/src/calibre/ebooks/mobi/writer8/header.py index a07fe7f6a1..19cc54bd01 100644 --- a/src/calibre/ebooks/mobi/writer8/header.py +++ b/src/calibre/ebooks/mobi/writer8/header.py @@ -39,7 +39,7 @@ class Header(OrderedDict): line = line.strip() if not line or line.startswith('#'): continue - name, val = [x.strip() for x in line.partition('=')[0::2]] + name, val = (x.strip() for x in line.partition('=')[0::2]) if val: val = eval(val, {'zeroes':zeroes, 'NULL':NULL, 'DYN':None, 'nulls':nulls, 'short':short, 'random':random}) diff --git a/src/calibre/ebooks/mobi/writer8/index.py b/src/calibre/ebooks/mobi/writer8/index.py index 258c50b066..20028f1d83 100644 --- a/src/calibre/ebooks/mobi/writer8/index.py +++ b/src/calibre/ebooks/mobi/writer8/index.py @@ -338,7 +338,7 @@ class NCXIndex(Index): largest = max(x['index'] for x in toc_table) except ValueError: largest = 0 - fmt = '%0{0}X'.format(max(2, len('%X' % largest))) + fmt = '%0{}X'.format(max(2, len('%X' % largest))) def to_entry(x): ans = {} diff --git a/src/calibre/ebooks/mobi/writer8/mobi.py b/src/calibre/ebooks/mobi/writer8/mobi.py index 3e98841d17..d22dd33d96 100644 --- a/src/calibre/ebooks/mobi/writer8/mobi.py +++ b/src/calibre/ebooks/mobi/writer8/mobi.py @@ -199,12 +199,12 @@ class MOBIHeader(Header): # {{{ def __init__(self, file_version=8): self.DEFINITION = self.DEFINITION.format(file_version=file_version, record_size=RECORD_SIZE) - super(MOBIHeader, self).__init__() + super().__init__() def format_value(self, name, val): if name == 'compression': val = PALMDOC if val else UNCOMPRESSED - return super(MOBIHeader, self).format_value(name, val) + return super().format_value(name, val) # }}} diff --git a/src/calibre/ebooks/mobi/writer8/skeleton.py b/src/calibre/ebooks/mobi/writer8/skeleton.py index 691485c49c..4a4b5c95df 100644 --- a/src/calibre/ebooks/mobi/writer8/skeleton.py +++ b/src/calibre/ebooks/mobi/writer8/skeleton.py @@ -148,7 +148,7 @@ class Skeleton: return ans def __len__(self): - return len(self.skeleton) + sum([len(x.raw) for x in self.chunks]) + return len(self.skeleton) + sum(len(x.raw) for x in self.chunks) @property def raw_text(self): diff --git a/src/calibre/ebooks/odt/input.py b/src/calibre/ebooks/odt/input.py index c31b2a985b..b90045e8ca 100644 --- a/src/calibre/ebooks/odt/input.py +++ b/src/calibre/ebooks/odt/input.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' @@ -70,7 +69,7 @@ class Extract(ODF2XHTML): etree.SubElement(head, ns+'link', {'type':'text/css', 'rel':'stylesheet', 'href':'odfpy.css'}) - css = u'\n\n'.join(ans) + css = '\n\n'.join(ans) parser = CSSParser(loglevel=logging.WARNING, log=_css_logger) self.css = parser.parseString(css, validate=False) @@ -92,7 +91,7 @@ class Extract(ODF2XHTML): # Fix empty title tags for t in XPath('//h:title')(root): if not t.text: - t.text = u' ' + t.text = ' ' # Fix

constructs as the asinine epubchecker complains # about them pdiv = XPath('//h:p/h:div') @@ -134,24 +133,24 @@ class Extract(ODF2XHTML): cls.split()])) has_align = False for r in first_rules: - if r.style.getProperty(u'text-align') is not None: + if r.style.getProperty('text-align') is not None: has_align = True ml = mr = None if not has_align: aval = None - cls = div2.get(u'class', u'') + cls = div2.get('class', '') rules = list(filter(None, [self.get_css_for_class(x) for x in cls.split()])) for r in rules: - ml = r.style.getPropertyCSSValue(u'margin-left') or ml - mr = r.style.getPropertyCSSValue(u'margin-right') or mr + ml = r.style.getPropertyCSSValue('margin-left') or ml + mr = r.style.getPropertyCSSValue('margin-right') or mr ml = getattr(ml, 'value', None) mr = getattr(mr, 'value', None) - if ml == mr == u'auto': - aval = u'center' - elif ml == u'auto' and mr != u'auto': + if ml == mr == 'auto': + aval = 'center' + elif ml == 'auto' and mr != 'auto': aval = 'right' - elif ml != u'auto' and mr == u'auto': + elif ml != 'auto' and mr == 'auto': aval = 'left' if aval is not None: style = div1.attrib.get('style', '').strip() @@ -213,7 +212,7 @@ class Extract(ODF2XHTML): def search_page_img(self, mi, log): for frm in self.document.topnode.getElementsByType(odFrame): try: - if frm.getAttrNS(odTEXTNS,u'anchor-type') == 'page': + if frm.getAttrNS(odTEXTNS,'anchor-type') == 'page': log.warn('Document has Pictures anchored to Page, will all end up before first page!') break except ValueError: diff --git a/src/calibre/ebooks/oeb/__init__.py b/src/calibre/ebooks/oeb/__init__.py index 62cfe31800..4f8588535f 100644 --- a/src/calibre/ebooks/oeb/__init__.py +++ b/src/calibre/ebooks/oeb/__init__.py @@ -1,4 +1,2 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' diff --git a/src/calibre/ebooks/oeb/base.py b/src/calibre/ebooks/oeb/base.py index 2f7fbb7954..f57727c483 100644 --- a/src/calibre/ebooks/oeb/base.py +++ b/src/calibre/ebooks/oeb/base.py @@ -804,8 +804,7 @@ class Metadata: return item def iterkeys(self): - for key in self.items: - yield key + yield from self.items __iter__ = iterkeys def clear(self, key): @@ -1216,8 +1215,7 @@ class Manifest: return id, str(href) def __iter__(self): - for item in self.items: - yield item + yield from self.items def __len__(self): return len(self.items) @@ -1327,8 +1325,7 @@ class Spine: return -1 def __iter__(self): - for item in self.items: - yield item + yield from self.items def __getitem__(self, index): return self.items[index] @@ -1441,16 +1438,14 @@ class Guide: self.remove(r) def iterkeys(self): - for type in self.refs: - yield type + yield from self.refs __iter__ = iterkeys def values(self): return sorted(itervalues(self.refs), key=lambda ref: ref.ORDER.get(ref.type, 10000)) def items(self): - for type, ref in self.refs.items(): - yield type, ref + yield from self.refs.items() def __getitem__(self, key): return self.refs[key] @@ -1539,8 +1534,7 @@ class TOC: """Iterate over this node and all descendants in depth-first order.""" yield self for child in self.nodes: - for node in child.iter(): - yield node + yield from child.iter() def count(self): return len(list(self.iter())) - 1 @@ -1568,17 +1562,14 @@ class TOC: for child in self.nodes: yield child for child in self.nodes: - for node in child.iterdescendants(breadth_first=True): - yield node + yield from child.iterdescendants(breadth_first=True) else: for child in self.nodes: - for node in child.iter(): - yield node + yield from child.iter() def __iter__(self): """Iterate over all immediate child nodes.""" - for node in self.nodes: - yield node + yield from self.nodes def __getitem__(self, index): return self.nodes[index] @@ -1716,8 +1707,7 @@ class PageList: return len(self.pages) def __iter__(self): - for page in self.pages: - yield page + yield from self.pages def __getitem__(self, index): return self.pages[index] diff --git a/src/calibre/ebooks/oeb/iterator/bookmarks.py b/src/calibre/ebooks/oeb/iterator/bookmarks.py index 654c607071..3146b5cc36 100644 --- a/src/calibre/ebooks/oeb/iterator/bookmarks.py +++ b/src/calibre/ebooks/oeb/iterator/bookmarks.py @@ -12,8 +12,8 @@ from io import BytesIO from calibre.utils.zipfile import safe_replace from polyglot.builtins import as_unicode -BM_FIELD_SEP = u'*|!|?|*' -BM_LEGACY_ESC = u'esc-text-%&*#%(){}ads19-end-esc' +BM_FIELD_SEP = '*|!|?|*' +BM_LEGACY_ESC = 'esc-text-%&*#%(){}ads19-end-esc' def parse_bookmarks(raw): @@ -35,7 +35,7 @@ def parse_bookmarks(raw): except Exception: continue # Unescape from serialization - pos = pos.replace(BM_LEGACY_ESC, u'^') + pos = pos.replace(BM_LEGACY_ESC, '^') # Check for pos being a scroll fraction try: pos = float(pos) @@ -57,16 +57,16 @@ class BookmarksMixin: dat = [] for bm in bookmarks: if bm['type'] == 'legacy': - rec = u'%s^%d#%s'%(bm['title'], bm['spine'], bm['pos']) + rec = '%s^%d#%s'%(bm['title'], bm['spine'], bm['pos']) else: pos = bm['pos'] if isinstance(pos, numbers.Number): pos = str(pos) else: - pos = pos.replace(u'^', BM_LEGACY_ESC) + pos = pos.replace('^', BM_LEGACY_ESC) rec = BM_FIELD_SEP.join([bm['title'], str(bm['spine']), pos]) dat.append(rec) - return (u'\n'.join(dat) +u'\n') + return ('\n'.join(dat) +'\n') def read_bookmarks(self): self.bookmarks = [] @@ -93,7 +93,7 @@ class BookmarksMixin: safe_replace(zf, 'META-INF/calibre_bookmarks.txt', BytesIO(dat.encode('utf-8')), add_missing=True) - except IOError: + except OSError: return def add_bookmark(self, bm, no_copy_to_file=False): diff --git a/src/calibre/ebooks/oeb/iterator/spine.py b/src/calibre/ebooks/oeb/iterator/spine.py index d04cfe7358..5ae81275ae 100644 --- a/src/calibre/ebooks/oeb/iterator/spine.py +++ b/src/calibre/ebooks/oeb/iterator/spine.py @@ -50,7 +50,7 @@ class SpineItem(str): ppath = path.partition('#')[0] if not os.path.exists(path) and os.path.exists(ppath): path = ppath - obj = super(SpineItem, cls).__new__(cls, path) + obj = super().__new__(cls, path) with lopen(path, 'rb') as f: raw = f.read() if from_epub: diff --git a/src/calibre/ebooks/oeb/normalize_css.py b/src/calibre/ebooks/oeb/normalize_css.py index 524bf5d623..19db58fd0f 100644 --- a/src/calibre/ebooks/oeb/normalize_css.py +++ b/src/calibre/ebooks/oeb/normalize_css.py @@ -43,7 +43,7 @@ DEFAULTS = {'azimuth': 'center', 'background-attachment': 'scroll', # {{{ 'page-break-after': 'auto', 'page-break-before': 'auto', 'page-break-inside': 'auto', 'pause-after': 0, 'pause-before': 0, 'pitch': 'medium', 'pitch-range': '50', 'play-during': 'auto', - 'position': 'static', 'quotes': u"'“' '”' '‘' '’'", 'richness': + 'position': 'static', 'quotes': "'“' '”' '‘' '’'", 'richness': '50', 'right': 'auto', 'speak': 'normal', 'speak-header': 'once', 'speak-numeral': 'continuous', 'speak-punctuation': 'none', 'speech-rate': 'medium', 'stress': '50', 'table-layout': 'auto', diff --git a/src/calibre/ebooks/oeb/polish/cascade.py b/src/calibre/ebooks/oeb/polish/cascade.py index 7f670eccdb..d6c42e86a6 100644 --- a/src/calibre/ebooks/oeb/polish/cascade.py +++ b/src/calibre/ebooks/oeb/polish/cascade.py @@ -70,12 +70,10 @@ def iterrules(container, sheet_name, rules=None, media_rule_ok=media_allowed, ru else: csheet = container.parsed(name) if isinstance(csheet, CSSStyleSheet): - for cr in riter(name, rules=csheet): - yield cr + yield from riter(name, rules=csheet) elif rule.type == CSSRule.MEDIA_RULE: if media_rule_ok(rule.media): - for cr in riter(sheet_name, rules=rule.cssRules): - yield cr + yield from riter(sheet_name, rules=rule.cssRules) elif rule_type is None or rule.type == rule_type: num = next(rule_index_counter) diff --git a/src/calibre/ebooks/oeb/polish/check/parsing.py b/src/calibre/ebooks/oeb/polish/check/parsing.py index 2dbf924a06..f626aa29c5 100644 --- a/src/calibre/ebooks/oeb/polish/check/parsing.py +++ b/src/calibre/ebooks/oeb/polish/check/parsing.py @@ -23,7 +23,7 @@ HTML_ENTITTIES = frozenset(html5_entities) XML_ENTITIES = {'lt', 'gt', 'amp', 'apos', 'quot'} ALL_ENTITIES = HTML_ENTITTIES | XML_ENTITIES -replace_pat = re.compile('&(%s);' % '|'.join(re.escape(x) for x in sorted((HTML_ENTITTIES - XML_ENTITIES)))) +replace_pat = re.compile('&(%s);' % '|'.join(re.escape(x) for x in sorted(HTML_ENTITTIES - XML_ENTITIES))) mismatch_pat = re.compile(r'tag mismatch:.+?line (\d+).+?line \d+') diff --git a/src/calibre/ebooks/oeb/polish/container.py b/src/calibre/ebooks/oeb/polish/container.py index ebe3663243..13b00d0be6 100644 --- a/src/calibre/ebooks/oeb/polish/container.py +++ b/src/calibre/ebooks/oeb/polish/container.py @@ -425,7 +425,7 @@ class Container(ContainerBase): # {{{ parent_dir = os.path.dirname(parent_dir) try: os.rmdir(parent_dir) - except EnvironmentError: + except OSError: break for x in ('mime_map', 'encoding_map'): @@ -703,8 +703,7 @@ class Container(ContainerBase): # {{{ predicate = predicate.__contains__ for mt, names in iteritems(self.manifest_type_map): if predicate(mt): - for name in names: - yield name + yield from names def apply_unique_properties(self, name, *properties): ''' Ensure that the specified properties are set on only the manifest item @@ -1157,7 +1156,7 @@ class EpubContainer(Container): def __init__(self, pathtoepub, log, clone_data=None, tdir=None): if clone_data is not None: - super(EpubContainer, self).__init__(None, None, log, clone_data=clone_data) + super().__init__(None, None, log, clone_data=clone_data) for x in ('pathtoepub', 'obfuscated_fonts', 'is_dir'): setattr(self, x, clone_data[x]) return @@ -1191,7 +1190,7 @@ class EpubContainer(Container): extractall(stream, path=tdir) try: os.remove(join(tdir, 'mimetype')) - except EnvironmentError: + except OSError: pass # Ensure all filenames are in NFC normalized form # has no effect on HFS+ filesystems as they always store filenames @@ -1220,7 +1219,7 @@ class EpubContainer(Container): raise InvalidEpub('OPF file does not exist at location pointed to' ' by META-INF/container.xml') - super(EpubContainer, self).__init__(tdir, opf_path, log) + super().__init__(tdir, opf_path, log) self.obfuscated_fonts = {} if 'META-INF/encryption.xml' in self.name_path_map: @@ -1228,7 +1227,7 @@ class EpubContainer(Container): self.parsed_cache['META-INF/container.xml'] = container def clone_data(self, dest_dir): - ans = super(EpubContainer, self).clone_data(dest_dir) + ans = super().clone_data(dest_dir) ans['pathtoepub'] = self.pathtoepub ans['obfuscated_fonts'] = self.obfuscated_fonts.copy() ans['is_dir'] = self.is_dir @@ -1236,7 +1235,7 @@ class EpubContainer(Container): def rename(self, old_name, new_name): is_opf = old_name == self.opf_name - super(EpubContainer, self).rename(old_name, new_name) + super().rename(old_name, new_name) if is_opf: for elem in self.parsed('META-INF/container.xml').xpath(( r'child::ocf:rootfiles/ocf:rootfile' @@ -1257,18 +1256,18 @@ class EpubContainer(Container): @property def names_that_need_not_be_manifested(self): - return super(EpubContainer, self).names_that_need_not_be_manifested | {'META-INF/' + x for x in self.META_INF} + return super().names_that_need_not_be_manifested | {'META-INF/' + x for x in self.META_INF} def ok_to_be_unmanifested(self, name): return name in self.names_that_need_not_be_manifested or name.startswith('META-INF/') @property def names_that_must_not_be_removed(self): - return super(EpubContainer, self).names_that_must_not_be_removed | {'META-INF/container.xml'} + return super().names_that_must_not_be_removed | {'META-INF/container.xml'} @property def names_that_must_not_be_changed(self): - return super(EpubContainer, self).names_that_must_not_be_changed | {'META-INF/' + x for x in self.META_INF} + return super().names_that_must_not_be_changed | {'META-INF/' + x for x in self.META_INF} def remove_item(self, name, remove_from_guide=True): # Handle removal of obfuscated fonts @@ -1288,7 +1287,7 @@ class EpubContainer(Container): if name == self.href_to_name(cr.get('URI')): self.remove_from_xml(em.getparent()) self.dirty('META-INF/encryption.xml') - super(EpubContainer, self).remove_item(name, remove_from_guide=remove_from_guide) + super().remove_item(name, remove_from_guide=remove_from_guide) def process_encryption(self): fonts = {} @@ -1356,7 +1355,7 @@ class EpubContainer(Container): def commit(self, outpath=None, keep_parsed=False): if self.opf_version_parsed.major == 3: self.update_modified_timestamp() - super(EpubContainer, self).commit(keep_parsed=keep_parsed) + super().commit(keep_parsed=keep_parsed) container_path = join(self.root, 'META-INF', 'container.xml') if not exists(container_path): raise InvalidEpub('No META-INF/container.xml in EPUB, this typically happens if the temporary files calibre' @@ -1384,7 +1383,7 @@ class EpubContainer(Container): os.remove(os.path.join(dirpath, fname)) try: os.rmdir(dirpath) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOTEMPTY: raise # Now copy over everything from root to source dir @@ -1393,7 +1392,7 @@ class EpubContainer(Container): base = self.pathtoepub if is_root else os.path.join(self.pathtoepub, os.path.relpath(dirpath, self.root)) try: os.mkdir(base) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise for fname in filenames: @@ -1480,7 +1479,7 @@ class AZW3Container(Container): def __init__(self, pathtoazw3, log, clone_data=None, tdir=None): if clone_data is not None: - super(AZW3Container, self).__init__(None, None, log, clone_data=clone_data) + super().__init__(None, None, log, clone_data=clone_data) for x in ('pathtoazw3', 'obfuscated_fonts'): setattr(self, x, clone_data[x]) return @@ -1523,17 +1522,17 @@ class AZW3Container(Container): except WorkerError as e: log(e.orig_tb) raise InvalidMobi('Failed to explode MOBI') - super(AZW3Container, self).__init__(tdir, opf_path, log) + super().__init__(tdir, opf_path, log) self.obfuscated_fonts = {x.replace(os.sep, '/') for x in obfuscated_fonts} def clone_data(self, dest_dir): - ans = super(AZW3Container, self).clone_data(dest_dir) + ans = super().clone_data(dest_dir) ans['pathtoazw3'] = self.pathtoazw3 ans['obfuscated_fonts'] = self.obfuscated_fonts.copy() return ans def commit(self, outpath=None, keep_parsed=False): - super(AZW3Container, self).commit(keep_parsed=keep_parsed) + super().commit(keep_parsed=keep_parsed) if outpath is None: outpath = self.pathtoazw3 opf_to_azw3(self.name_path_map[self.opf_name], outpath, self) diff --git a/src/calibre/ebooks/oeb/polish/create.py b/src/calibre/ebooks/oeb/polish/create.py index d5e75f2b9d..1add13275b 100644 --- a/src/calibre/ebooks/oeb/polish/create.py +++ b/src/calibre/ebooks/oeb/polish/create.py @@ -87,7 +87,7 @@ def create_book(mi, path, fmt='epub', opf_name='metadata.opf', html_name='start. - + '''.format(prepare_string_for_xml(opf_name, True)).encode('utf-8') diff --git a/src/calibre/ebooks/oeb/polish/css.py b/src/calibre/ebooks/oeb/polish/css.py index 891fd7b1ba..9d0f83c450 100644 --- a/src/calibre/ebooks/oeb/polish/css.py +++ b/src/calibre/ebooks/oeb/polish/css.py @@ -425,8 +425,7 @@ def classes_in_rule_list(css_rules): def iter_declarations(sheet_or_rule): if hasattr(sheet_or_rule, 'cssRules'): for rule in sheet_or_rule.cssRules: - for x in iter_declarations(rule): - yield x + yield from iter_declarations(rule) elif hasattr(sheet_or_rule, 'style'): yield sheet_or_rule.style elif isinstance(sheet_or_rule, CSSStyleDeclaration): diff --git a/src/calibre/ebooks/oeb/polish/errors.py b/src/calibre/ebooks/oeb/polish/errors.py index c2c27747e9..8ffd913ca1 100644 --- a/src/calibre/ebooks/oeb/polish/errors.py +++ b/src/calibre/ebooks/oeb/polish/errors.py @@ -16,7 +16,7 @@ class InvalidBook(ValueError): class DRMError(_DRMError): def __init__(self): - super(DRMError, self).__init__(_('This file is locked with DRM. It cannot be edited.')) + super().__init__(_('This file is locked with DRM. It cannot be edited.')) class MalformedMarkup(ValueError): diff --git a/src/calibre/ebooks/oeb/polish/replace.py b/src/calibre/ebooks/oeb/polish/replace.py index 627c5ec3b5..b16876597a 100644 --- a/src/calibre/ebooks/oeb/polish/replace.py +++ b/src/calibre/ebooks/oeb/polish/replace.py @@ -273,7 +273,7 @@ def normalize_case(container, val): def safe_listdir(x): try: return os.listdir(x) - except EnvironmentError: + except OSError: return () parts = val.split('/') diff --git a/src/calibre/ebooks/oeb/polish/report.py b/src/calibre/ebooks/oeb/polish/report.py index 0c65c98acb..5db008f940 100644 --- a/src/calibre/ebooks/oeb/polish/report.py +++ b/src/calibre/ebooks/oeb/polish/report.py @@ -271,8 +271,7 @@ def css_data(container, book_locale, result_data, *args): else: # @import rule isheet = importable_sheets.get(rule) if isheet is not None: - for irule in rules_in_sheet(isheet): - yield irule + yield from rules_in_sheet(isheet) def sheets_for_html(name, root): for href in link_path(root): diff --git a/src/calibre/ebooks/oeb/polish/spell.py b/src/calibre/ebooks/oeb/polish/spell.py index 19a436fa79..1c25cb898e 100644 --- a/src/calibre/ebooks/oeb/polish/spell.py +++ b/src/calibre/ebooks/oeb/polish/spell.py @@ -37,7 +37,7 @@ class Patterns: # French words with prefixes are reduced to the stem word, so that the # words appear only once in the word list self.fr_elision_pat = regex.compile( - u"^(?:l|d|m|t|s|j|c|ç|lorsqu|puisqu|quoiqu|qu)['’]", flags=regex.UNICODE | regex.VERSION1 | regex.IGNORECASE) + "^(?:l|d|m|t|s|j|c|ç|lorsqu|puisqu|quoiqu|qu)['’]", flags=regex.UNICODE | regex.VERSION1 | regex.IGNORECASE) def patterns(): diff --git a/src/calibre/ebooks/oeb/polish/toc.py b/src/calibre/ebooks/oeb/polish/toc.py index ad26b86a74..41e9fb5fcf 100644 --- a/src/calibre/ebooks/oeb/polish/toc.py +++ b/src/calibre/ebooks/oeb/polish/toc.py @@ -65,8 +65,7 @@ class TOC: self.parent = None def __iter__(self): - for c in self.children: - yield c + yield from self.children def __len__(self): return len(self.children) @@ -78,8 +77,7 @@ class TOC: yield child else: yield level, child - for gc in child.iterdescendants(level=gc_level): - yield gc + yield from child.iterdescendants(level=gc_level) def remove_duplicates(self, only_text=True): seen = set() diff --git a/src/calibre/ebooks/oeb/polish/utils.py b/src/calibre/ebooks/oeb/polish/utils.py index 39191ebcfa..added0bb97 100644 --- a/src/calibre/ebooks/oeb/polish/utils.py +++ b/src/calibre/ebooks/oeb/polish/utils.py @@ -59,7 +59,7 @@ def corrected_case_for_name(container, name): else: try: candidates = {q for q in os.listdir(os.path.dirname(container.name_to_abspath(base)))} - except EnvironmentError: + except OSError: return None # one of the non-terminal components of name is a file instead of a directory for q in candidates: if q.lower() == x.lower(): diff --git a/src/calibre/ebooks/oeb/transforms/embed_fonts.py b/src/calibre/ebooks/oeb/transforms/embed_fonts.py index ecd12341e1..6e7780e409 100644 --- a/src/calibre/ebooks/oeb/transforms/embed_fonts.py +++ b/src/calibre/ebooks/oeb/transforms/embed_fonts.py @@ -230,7 +230,7 @@ class EmbedFonts: name = f['full_name'] ext = 'otf' if f['is_otf'] else 'ttf' name = ascii_filename(name).replace(' ', '-').replace('(', '').replace(')', '') - fid, href = self.oeb.manifest.generate(id=u'font', href=u'fonts/%s.%s'%(name, ext)) + fid, href = self.oeb.manifest.generate(id='font', href='fonts/%s.%s'%(name, ext)) item = self.oeb.manifest.add(fid, href, guess_type('dummy.'+ext)[0], data=data) item.unload_data_from_memory() page_sheet = self.get_page_sheet() diff --git a/src/calibre/ebooks/oeb/transforms/flatcss.py b/src/calibre/ebooks/oeb/transforms/flatcss.py index ca74dc4a66..e9ee981765 100644 --- a/src/calibre/ebooks/oeb/transforms/flatcss.py +++ b/src/calibre/ebooks/oeb/transforms/flatcss.py @@ -242,7 +242,7 @@ class CSSFlattener: for i, font in enumerate(faces): ext = 'otf' if font['is_otf'] else 'ttf' - fid, href = self.oeb.manifest.generate(id=u'font', + fid, href = self.oeb.manifest.generate(id='font', href='fonts/%s.%s'%(ascii_filename(font['full_name']).replace(' ', '-'), ext)) item = self.oeb.manifest.add(fid, href, guess_type('dummy.'+ext)[0], @@ -529,7 +529,7 @@ class CSSFlattener: if cssdict: items = sorted(iteritems(cssdict)) - css = ';\n'.join(u'%s: %s' % (key, val) for key, val in items) + css = ';\n'.join('%s: %s' % (key, val) for key, val in items) classes = node.get('class', '').strip() or 'calibre' classes_list = classes.split() # lower() because otherwise if the document uses the same class diff --git a/src/calibre/ebooks/oeb/transforms/htmltoc.py b/src/calibre/ebooks/oeb/transforms/htmltoc.py index a4a4ad7b1a..3fef82a001 100644 --- a/src/calibre/ebooks/oeb/transforms/htmltoc.py +++ b/src/calibre/ebooks/oeb/transforms/htmltoc.py @@ -1,4 +1,3 @@ - ''' HTML-TOC-adding transform. ''' diff --git a/src/calibre/ebooks/oeb/transforms/jacket.py b/src/calibre/ebooks/oeb/transforms/jacket.py index 0b286e7509..fc621a032f 100644 --- a/src/calibre/ebooks/oeb/transforms/jacket.py +++ b/src/calibre/ebooks/oeb/transforms/jacket.py @@ -188,7 +188,7 @@ class Series(str): combined = _('{1} of {0}').format( escape(series), escape(fmt_sidx(series_index, use_roman=False))) else: - combined = roman = escape(series or u'') + combined = roman = escape(series or '') s = str.__new__(self, combined) s.roman = roman s.name = escape(series or '') diff --git a/src/calibre/ebooks/oeb/transforms/manglecase.py b/src/calibre/ebooks/oeb/transforms/manglecase.py index 81239527f1..4b955663c5 100644 --- a/src/calibre/ebooks/oeb/transforms/manglecase.py +++ b/src/calibre/ebooks/oeb/transforms/manglecase.py @@ -1,4 +1,3 @@ - ''' CSS case-mangling transform. ''' diff --git a/src/calibre/ebooks/oeb/transforms/rasterize.py b/src/calibre/ebooks/oeb/transforms/rasterize.py index 67a61a40d2..ad73500258 100644 --- a/src/calibre/ebooks/oeb/transforms/rasterize.py +++ b/src/calibre/ebooks/oeb/transforms/rasterize.py @@ -1,4 +1,3 @@ - ''' SVG rasterization transform. ''' diff --git a/src/calibre/ebooks/oeb/transforms/split.py b/src/calibre/ebooks/oeb/transforms/split.py index ff423da6c4..ff42b8666a 100644 --- a/src/calibre/ebooks/oeb/transforms/split.py +++ b/src/calibre/ebooks/oeb/transforms/split.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/ebooks/pdb/haodoo/reader.py b/src/calibre/ebooks/pdb/haodoo/reader.py index 7c3ea18e65..cdf3400dd3 100644 --- a/src/calibre/ebooks/pdb/haodoo/reader.py +++ b/src/calibre/ebooks/pdb/haodoo/reader.py @@ -22,32 +22,32 @@ BPDB_IDENT = 'BOOKMTIT' UPDB_IDENT = 'BOOKMTIU' punct_table = { - u"︵": u"(", - u"︶": u")", - u"︷": u"{", - u"︸": u"}", - u"︹": u"〔", - u"︺": u"〕", - u"︻": u"【", - u"︼": u"】", - u"︗": u"〖", - u"︘": u"〗", - u"﹇": u"[]", - u"﹈": u"[]", - u"︽": u"《", - u"︾": u"》", - u"︿": u"〈", - u"﹀": u"〉", - u"﹁": u"「", - u"﹂": u"」", - u"﹃": u"『", - u"﹄": u"』", - u"|": u"—", - u"︙": u"…", - u"ⸯ": u"~", - u"│": u"…", - u"¦": u"…", - u" ": u" ", + "︵": "(", + "︶": ")", + "︷": "{", + "︸": "}", + "︹": "〔", + "︺": "〕", + "︻": "【", + "︼": "】", + "︗": "〖", + "︘": "〗", + "﹇": "[]", + "﹈": "[]", + "︽": "《", + "︾": "》", + "︿": "〈", + "﹀": "〉", + "﹁": "「", + "﹂": "」", + "﹃": "『", + "﹄": "』", + "|": "—", + "︙": "…", + "ⸯ": "~", + "│": "…", + "¦": "…", + " ": " ", } @@ -124,9 +124,9 @@ class Reader(FormatReader): def extract_content(self, output_dir): txt = '' - self.log.info(u'Decompressing text...') + self.log.info('Decompressing text...') for i in range(1, self.header_record.num_records + 1): - self.log.debug(u'\tDecompressing text section %i' % i) + self.log.debug('\tDecompressing text section %i' % i) title = self.header_record.chapter_titles[i-1] lines = [] title_added = False @@ -143,7 +143,7 @@ class Reader(FormatReader): lines.insert(0, '

' + title + '

\n') txt += '\n'.join(lines) - self.log.info(u'Converting text to OEB...') + self.log.info('Converting text to OEB...') html = HTML_TEMPLATE % (self.header_record.title, txt) with open(os.path.join(output_dir, 'index.html'), 'wb') as index: index.write(html.encode('utf-8')) diff --git a/src/calibre/ebooks/pdb/plucker/reader.py b/src/calibre/ebooks/pdb/plucker/reader.py index d8716913b6..fa7af3cb44 100644 --- a/src/calibre/ebooks/pdb/plucker/reader.py +++ b/src/calibre/ebooks/pdb/plucker/reader.py @@ -365,7 +365,7 @@ class Reader(FormatReader): for uid, num in self.uid_text_secion_number.items(): self.log.debug('Writing record with uid: %s as %s.html' % (uid, uid)) with open('%s.html' % uid, 'wb') as htmlf: - html = u'' + html = '' section_header, section_data = self.sections[num] if section_header.type == DATATYPE_PHTML: html += self.process_phtml(section_data.data, section_data.header.paragraph_offsets) @@ -477,7 +477,7 @@ class Reader(FormatReader): return decompress_doc(data) def process_phtml(self, d, paragraph_offsets=()): - html = u'

' + html = '

' offset = 0 paragraph_open = True link_open = False @@ -488,11 +488,11 @@ class Reader(FormatReader): while offset < len(d): if not paragraph_open: if need_set_p_id: - html += u'

' % p_num + html += '

' % p_num p_num += 1 need_set_p_id = False else: - html += u'

' + html += '

' paragraph_open = True c = ord(d[offset:offset+1]) @@ -616,23 +616,23 @@ class Reader(FormatReader): elif c == 0x33: offset += 3 if paragraph_open: - html += u'

' + html += '

' paragraph_open = False - html += u'
' + html += '
' # New line # 0 Bytes elif c == 0x38: if paragraph_open: - html += u'

\n' + html += '

\n' paragraph_open = False # Italic text begins # 0 Bytes elif c == 0x40: - html += u'' + html += '' # Italic text ends # 0 Bytes elif c == 0x48: - html += u'' + html += '' # Set text color # 3 Bytes # 8-bit red, 8-bit green, 8-bit blue @@ -649,19 +649,19 @@ class Reader(FormatReader): # Underline text begins # 0 Bytes elif c == 0x60: - html += u'' + html += '' # Underline text ends # 0 Bytes elif c == 0x68: - html += u'' + html += '' # Strike-through text begins # 0 Bytes elif c == 0x70: - html += u'' + html += '' # Strike-through text ends # 0 Bytes elif c == 0x78: - html += u'' + html += '' # 16-bit Unicode character # 3 Bytes # alternate text length, 16-bit unicode character @@ -721,10 +721,10 @@ class Reader(FormatReader): if offset in paragraph_offsets: need_set_p_id = True if paragraph_open: - html += u'

\n' + html += '

\n' paragraph_open = False if paragraph_open: - html += u'

' + html += '

' return html diff --git a/src/calibre/ebooks/pdf/html_writer.py b/src/calibre/ebooks/pdf/html_writer.py index b614de420b..2f82f75199 100644 --- a/src/calibre/ebooks/pdf/html_writer.py +++ b/src/calibre/ebooks/pdf/html_writer.py @@ -294,7 +294,7 @@ class RenderManager(QObject): def signal_received(self, read_fd): try: os.read(read_fd, 1024) - except EnvironmentError: + except OSError: return QApplication.instance().exit(KILL_SIGNAL) diff --git a/src/calibre/ebooks/pdf/reflow.py b/src/calibre/ebooks/pdf/reflow.py index 37ffee3f55..7aec7f8458 100644 --- a/src/calibre/ebooks/pdf/reflow.py +++ b/src/calibre/ebooks/pdf/reflow.py @@ -77,7 +77,7 @@ class Text(Element): text.tail = '' self.text_as_string = etree.tostring(text, method='text', encoding='unicode') - self.raw = text.text if text.text else u'' + self.raw = text.text if text.text else '' for x in text.iterchildren(): self.raw += etree.tostring(x, method='xml', encoding='unicode') self.average_character_width = self.width/len(self.text_as_string) @@ -179,8 +179,7 @@ class Column: self.width, self.height = self.right-self.left, self.bottom-self.top def __iter__(self): - for x in self.elements: - yield x + yield from self.elements def __len__(self): return len(self.elements) @@ -319,19 +318,18 @@ class Region: col = most_suitable_column(elem) if self.opts.verbose > 3: idx = self.columns.index(col) - self.log.debug(u'Absorbing singleton %s into column'%elem.to_html(), + self.log.debug('Absorbing singleton %s into column'%elem.to_html(), idx) col.add(elem) def collect_stats(self): for column in self.columns: column.collect_stats() - self.average_line_separation = sum([x.average_line_separation for x in - self.columns])/float(len(self.columns)) + self.average_line_separation = sum(x.average_line_separation for x in + self.columns)/float(len(self.columns)) def __iter__(self): - for x in self.columns: - yield x + yield from self.columns def absorb_regions(self, regions, at): for region in regions: @@ -562,8 +560,8 @@ class Page: absorb_into = prev_region if self.regions[next_region].line_count >= \ self.regions[prev_region].line_count: - avg_column_count = sum([len(r.columns) for r in - regions])/float(len(regions)) + avg_column_count = sum(len(r.columns) for r in + regions)/float(len(regions)) if self.regions[next_region].line_count > \ self.regions[prev_region].line_count \ or abs(avg_column_count - @@ -694,6 +692,6 @@ class PDFDocument: for elem in self.elements: html.extend(elem.to_html()) html += ['', ''] - raw = (u'\n'.join(html)).replace('', '') + raw = ('\n'.join(html)).replace('', '') with open('index.html', 'wb') as f: f.write(raw.encode('utf-8')) diff --git a/src/calibre/ebooks/pdf/render/common.py b/src/calibre/ebooks/pdf/render/common.py index e41343824e..71205f19d9 100644 --- a/src/calibre/ebooks/pdf/render/common.py +++ b/src/calibre/ebooks/pdf/render/common.py @@ -212,7 +212,7 @@ class Stream(BytesIO): self.write(EOL) def write(self, raw): - super(Stream, self).write(raw if isinstance(raw, bytes) else + super().write(raw if isinstance(raw, bytes) else raw.encode('ascii')) def write_raw(self, raw): diff --git a/src/calibre/ebooks/pdf/render/graphics.py b/src/calibre/ebooks/pdf/render/graphics.py index 1659cfb40a..0278cf7512 100644 --- a/src/calibre/ebooks/pdf/render/graphics.py +++ b/src/calibre/ebooks/pdf/render/graphics.py @@ -224,7 +224,7 @@ class QtPattern(TilingPattern): ) # }}} def __init__(self, pattern_num, matrix): - super(QtPattern, self).__init__(pattern_num, matrix) + super().__init__(pattern_num, matrix) self.write(self.qt_patterns[pattern_num-2]) @@ -237,14 +237,14 @@ class TexturePattern(TilingPattern): imgref = pdf.add_image(image, cache_key) paint_type = (2 if image.format() in {QImage.Format.Format_MonoLSB, QImage.Format.Format_Mono} else 1) - super(TexturePattern, self).__init__( + super().__init__( cache_key, matrix, w=image.width(), h=image.height(), paint_type=paint_type) m = (self.w, 0, 0, -self.h, 0, self.h) self.resources['XObject'] = Dictionary({'Texture':imgref}) self.write_line('%s cm /Texture Do'%(' '.join(map(fmtnum, m)))) else: - super(TexturePattern, self).__init__( + super().__init__( clone.cache_key[1], matrix, w=clone.w, h=clone.h, paint_type=clone.paint_type) self.resources['XObject'] = Dictionary(clone.resources['XObject']) diff --git a/src/calibre/ebooks/pdf/render/links.py b/src/calibre/ebooks/pdf/render/links.py index 4ead9be159..60c59f826a 100644 --- a/src/calibre/ebooks/pdf/render/links.py +++ b/src/calibre/ebooks/pdf/render/links.py @@ -27,7 +27,7 @@ class Destination(Array): q -= 1 if q != pnum: current_log().warn('Could not find page {} for link destination, using page {} instead'.format(pnum, q)) - super(Destination, self).__init__([ + super().__init__([ pref, Name('XYZ'), pos['left'], pos['top'], None ]) diff --git a/src/calibre/ebooks/pdf/render/serialize.py b/src/calibre/ebooks/pdf/render/serialize.py index dc73fe8cca..c922da96a5 100644 --- a/src/calibre/ebooks/pdf/render/serialize.py +++ b/src/calibre/ebooks/pdf/render/serialize.py @@ -83,7 +83,7 @@ class IndirectObjects: class Page(Stream): def __init__(self, parentref, *args, **kwargs): - super(Page, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.page_dict = Dictionary({ 'Type': Name('Page'), 'Parent': parentref, @@ -173,14 +173,14 @@ class Path: class Catalog(Dictionary): def __init__(self, pagetree): - super(Catalog, self).__init__({'Type':Name('Catalog'), + super().__init__({'Type':Name('Catalog'), 'Pages': pagetree}) class PageTree(Dictionary): def __init__(self, page_size): - super(PageTree, self).__init__({'Type':Name('Pages'), + super().__init__({'Type':Name('Pages'), 'MediaBox':Array([0, 0, page_size[0], page_size[1]]), 'Kids':Array(), 'Count':0, }) @@ -278,7 +278,7 @@ class PDFStream: self.stream = HashingStream(stream) self.compress = compress self.write_line(PDFVER) - self.write_line(u'%íì¦"'.encode('utf-8')) + self.write_line('%íì¦"'.encode()) creator = ('%s %s [https://calibre-ebook.com]'%(__appname__, __version__)) self.write_line('%% Created by %s'%creator) diff --git a/src/calibre/ebooks/rb/rbml.py b/src/calibre/ebooks/rb/rbml.py index 94a412ac3b..a023094b8e 100644 --- a/src/calibre/ebooks/rb/rbml.py +++ b/src/calibre/ebooks/rb/rbml.py @@ -225,7 +225,7 @@ class RBMLizer: return text def close_tags(self, tags): - text = [u''] + text = [''] for i in range(0, len(tags)): tag = tags.pop() text.append('' % tag) diff --git a/src/calibre/ebooks/readability/__init__.py b/src/calibre/ebooks/readability/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/ebooks/readability/__init__.py +++ b/src/calibre/ebooks/readability/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/ebooks/readability/cleaners.py b/src/calibre/ebooks/readability/cleaners.py index aa6a25a5b0..d30216c4d8 100644 --- a/src/calibre/ebooks/readability/cleaners.py +++ b/src/calibre/ebooks/readability/cleaners.py @@ -1,5 +1,3 @@ - - # strip out a set of nuisance html attributes that can mess up rendering in RSS feeds import re from lxml.html.clean import Cleaner diff --git a/src/calibre/ebooks/readability/debug.py b/src/calibre/ebooks/readability/debug.py index bc51815909..07b3f67dd1 100644 --- a/src/calibre/ebooks/readability/debug.py +++ b/src/calibre/ebooks/readability/debug.py @@ -1,5 +1,3 @@ - - def save_to_file(text, filename): with open(filename, 'wb') as f: f.write(b'') diff --git a/src/calibre/ebooks/readability/htmls.py b/src/calibre/ebooks/readability/htmls.py index 834b5d45ce..9c9289face 100644 --- a/src/calibre/ebooks/readability/htmls.py +++ b/src/calibre/ebooks/readability/htmls.py @@ -1,5 +1,3 @@ - - import re from lxml.html import tostring diff --git a/src/calibre/ebooks/readability/readability.py b/src/calibre/ebooks/readability/readability.py index cdd77cb542..52c8e8dc5c 100644 --- a/src/calibre/ebooks/readability/readability.py +++ b/src/calibre/ebooks/readability/readability.py @@ -339,13 +339,11 @@ class Document: def tags(self, node, *tag_names): for tag_name in tag_names: - for e in node.findall('.//%s' % tag_name): - yield e + yield from node.findall('.//%s' % tag_name) def reverse_tags(self, node, *tag_names): for tag_name in tag_names: - for e in reversed(node.findall('.//%s' % tag_name)): - yield e + yield from reversed(node.findall('.//%s' % tag_name)) def sanitize(self, node, candidates): MIN_LEN = self.options.get('min_text_length', self.TEXT_LENGTH_THRESHOLD) diff --git a/src/calibre/ebooks/rtf/__init__.py b/src/calibre/ebooks/rtf/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/ebooks/rtf/__init__.py +++ b/src/calibre/ebooks/rtf/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/ebooks/rtf/input.py b/src/calibre/ebooks/rtf/input.py index fd0fcad91e..a8a0802398 100644 --- a/src/calibre/ebooks/rtf/input.py +++ b/src/calibre/ebooks/rtf/input.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/ebooks/rtf/rtfml.py b/src/calibre/ebooks/rtf/rtfml.py index e91b4d33e6..f28844c0c9 100644 --- a/src/calibre/ebooks/rtf/rtfml.py +++ b/src/calibre/ebooks/rtf/rtfml.py @@ -90,7 +90,7 @@ def txt2rtf(text): buf.write(x) else: # python2 and ur'\u' does not work - c = '\\u{0:d}?'.format(val) + c = '\\u{:d}?'.format(val) buf.write(c) return buf.getvalue() diff --git a/src/calibre/ebooks/rtf2xml/ParseRtf.py b/src/calibre/ebooks/rtf2xml/ParseRtf.py index 3347f1d4f0..2e9d024baa 100644 --- a/src/calibre/ebooks/rtf2xml/ParseRtf.py +++ b/src/calibre/ebooks/rtf2xml/ParseRtf.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/__init__.py b/src/calibre/ebooks/rtf2xml/__init__.py index c02bcf8676..4decfc328b 100644 --- a/src/calibre/ebooks/rtf2xml/__init__.py +++ b/src/calibre/ebooks/rtf2xml/__init__.py @@ -1,12 +1,10 @@ - - import io def open_for_read(path): - return io.open(path, encoding='utf-8', errors='replace') + return open(path, encoding='utf-8', errors='replace') def open_for_write(path, append=False): mode = 'a' if append else 'w' - return io.open(path, mode, encoding='utf-8', errors='replace', newline='') + return open(path, mode, encoding='utf-8', errors='replace', newline='') diff --git a/src/calibre/ebooks/rtf2xml/add_brackets.py b/src/calibre/ebooks/rtf2xml/add_brackets.py index 81f8112305..43cc9cb061 100644 --- a/src/calibre/ebooks/rtf2xml/add_brackets.py +++ b/src/calibre/ebooks/rtf2xml/add_brackets.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/body_styles.py b/src/calibre/ebooks/rtf2xml/body_styles.py index 27ace8fd58..1876264971 100644 --- a/src/calibre/ebooks/rtf2xml/body_styles.py +++ b/src/calibre/ebooks/rtf2xml/body_styles.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/border_parse.py b/src/calibre/ebooks/rtf2xml/border_parse.py index 8c0e9beb36..29852eeba1 100644 --- a/src/calibre/ebooks/rtf2xml/border_parse.py +++ b/src/calibre/ebooks/rtf2xml/border_parse.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/char_set.py b/src/calibre/ebooks/rtf2xml/char_set.py index a680ba365a..304a0a271f 100644 --- a/src/calibre/ebooks/rtf2xml/char_set.py +++ b/src/calibre/ebooks/rtf2xml/char_set.py @@ -1,4 +1,3 @@ - char_set = """ NON-BREAKING HYPEHN:_:8290:‑ diff --git a/src/calibre/ebooks/rtf2xml/check_brackets.py b/src/calibre/ebooks/rtf2xml/check_brackets.py index e82ca1c471..355af163b4 100644 --- a/src/calibre/ebooks/rtf2xml/check_brackets.py +++ b/src/calibre/ebooks/rtf2xml/check_brackets.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/colors.py b/src/calibre/ebooks/rtf2xml/colors.py index 6a99669339..a8aab50230 100644 --- a/src/calibre/ebooks/rtf2xml/colors.py +++ b/src/calibre/ebooks/rtf2xml/colors.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/combine_borders.py b/src/calibre/ebooks/rtf2xml/combine_borders.py index 81576c07d7..eb5c83890c 100644 --- a/src/calibre/ebooks/rtf2xml/combine_borders.py +++ b/src/calibre/ebooks/rtf2xml/combine_borders.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/configure_txt.py b/src/calibre/ebooks/rtf2xml/configure_txt.py index 1d36d66184..c66a1c961e 100644 --- a/src/calibre/ebooks/rtf2xml/configure_txt.py +++ b/src/calibre/ebooks/rtf2xml/configure_txt.py @@ -1,4 +1,3 @@ - import os, sys from . import open_for_read diff --git a/src/calibre/ebooks/rtf2xml/convert_to_tags.py b/src/calibre/ebooks/rtf2xml/convert_to_tags.py index 40d8c983c5..640d11816e 100644 --- a/src/calibre/ebooks/rtf2xml/convert_to_tags.py +++ b/src/calibre/ebooks/rtf2xml/convert_to_tags.py @@ -1,4 +1,3 @@ - import os, sys from calibre.ebooks.rtf2xml import copy, check_encoding diff --git a/src/calibre/ebooks/rtf2xml/copy.py b/src/calibre/ebooks/rtf2xml/copy.py index 5f378367c6..e89d24c002 100644 --- a/src/calibre/ebooks/rtf2xml/copy.py +++ b/src/calibre/ebooks/rtf2xml/copy.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/default_encoding.py b/src/calibre/ebooks/rtf2xml/default_encoding.py index c3745dc822..5d1461c57c 100644 --- a/src/calibre/ebooks/rtf2xml/default_encoding.py +++ b/src/calibre/ebooks/rtf2xml/default_encoding.py @@ -1,4 +1,3 @@ - ######################################################################### # # # copyright 2002 Paul Henry Tremblay # diff --git a/src/calibre/ebooks/rtf2xml/delete_info.py b/src/calibre/ebooks/rtf2xml/delete_info.py index 4555fa94f2..b45e3d122d 100644 --- a/src/calibre/ebooks/rtf2xml/delete_info.py +++ b/src/calibre/ebooks/rtf2xml/delete_info.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/field_strings.py b/src/calibre/ebooks/rtf2xml/field_strings.py index def908cfee..31316c7404 100644 --- a/src/calibre/ebooks/rtf2xml/field_strings.py +++ b/src/calibre/ebooks/rtf2xml/field_strings.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/fields_large.py b/src/calibre/ebooks/rtf2xml/fields_large.py index 9b46a43bdd..2d4af119a9 100644 --- a/src/calibre/ebooks/rtf2xml/fields_large.py +++ b/src/calibre/ebooks/rtf2xml/fields_large.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/fields_small.py b/src/calibre/ebooks/rtf2xml/fields_small.py index 4a484ef135..3feef24eb8 100644 --- a/src/calibre/ebooks/rtf2xml/fields_small.py +++ b/src/calibre/ebooks/rtf2xml/fields_small.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/fonts.py b/src/calibre/ebooks/rtf2xml/fonts.py index 6312bd3442..54ab352efa 100644 --- a/src/calibre/ebooks/rtf2xml/fonts.py +++ b/src/calibre/ebooks/rtf2xml/fonts.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/footnote.py b/src/calibre/ebooks/rtf2xml/footnote.py index e48d15be20..7303f95011 100644 --- a/src/calibre/ebooks/rtf2xml/footnote.py +++ b/src/calibre/ebooks/rtf2xml/footnote.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/get_char_map.py b/src/calibre/ebooks/rtf2xml/get_char_map.py index 7fe1384580..4ce42e37c8 100644 --- a/src/calibre/ebooks/rtf2xml/get_char_map.py +++ b/src/calibre/ebooks/rtf2xml/get_char_map.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/get_options.py b/src/calibre/ebooks/rtf2xml/get_options.py index ec7fdac2a9..47aa3faf6a 100644 --- a/src/calibre/ebooks/rtf2xml/get_options.py +++ b/src/calibre/ebooks/rtf2xml/get_options.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/group_borders.py b/src/calibre/ebooks/rtf2xml/group_borders.py index 5f84b668af..6fde25d7b2 100644 --- a/src/calibre/ebooks/rtf2xml/group_borders.py +++ b/src/calibre/ebooks/rtf2xml/group_borders.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/group_styles.py b/src/calibre/ebooks/rtf2xml/group_styles.py index 4480c1dd0d..f873650823 100644 --- a/src/calibre/ebooks/rtf2xml/group_styles.py +++ b/src/calibre/ebooks/rtf2xml/group_styles.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/header.py b/src/calibre/ebooks/rtf2xml/header.py index c88bb7b597..1d6e3261dd 100644 --- a/src/calibre/ebooks/rtf2xml/header.py +++ b/src/calibre/ebooks/rtf2xml/header.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/headings_to_sections.py b/src/calibre/ebooks/rtf2xml/headings_to_sections.py index a0c8c6b4b9..b40f4cd9a5 100644 --- a/src/calibre/ebooks/rtf2xml/headings_to_sections.py +++ b/src/calibre/ebooks/rtf2xml/headings_to_sections.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/hex_2_utf8.py b/src/calibre/ebooks/rtf2xml/hex_2_utf8.py index 20ec20e11c..48a45ce007 100644 --- a/src/calibre/ebooks/rtf2xml/hex_2_utf8.py +++ b/src/calibre/ebooks/rtf2xml/hex_2_utf8.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/info.py b/src/calibre/ebooks/rtf2xml/info.py index 8a4e063af8..2a841e9a0e 100644 --- a/src/calibre/ebooks/rtf2xml/info.py +++ b/src/calibre/ebooks/rtf2xml/info.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/inline.py b/src/calibre/ebooks/rtf2xml/inline.py index 5eca1e35cc..e3e2c89683 100644 --- a/src/calibre/ebooks/rtf2xml/inline.py +++ b/src/calibre/ebooks/rtf2xml/inline.py @@ -1,4 +1,3 @@ - import sys, os from calibre.ebooks.rtf2xml import copy diff --git a/src/calibre/ebooks/rtf2xml/line_endings.py b/src/calibre/ebooks/rtf2xml/line_endings.py index 11840279fd..5dbc59a995 100644 --- a/src/calibre/ebooks/rtf2xml/line_endings.py +++ b/src/calibre/ebooks/rtf2xml/line_endings.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/list_numbers.py b/src/calibre/ebooks/rtf2xml/list_numbers.py index 2ce48babe9..6da6a34b8d 100644 --- a/src/calibre/ebooks/rtf2xml/list_numbers.py +++ b/src/calibre/ebooks/rtf2xml/list_numbers.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/list_table.py b/src/calibre/ebooks/rtf2xml/list_table.py index 44a985e58f..18c03145dd 100644 --- a/src/calibre/ebooks/rtf2xml/list_table.py +++ b/src/calibre/ebooks/rtf2xml/list_table.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/make_lists.py b/src/calibre/ebooks/rtf2xml/make_lists.py index 199b4cb956..84c37b15b4 100644 --- a/src/calibre/ebooks/rtf2xml/make_lists.py +++ b/src/calibre/ebooks/rtf2xml/make_lists.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/old_rtf.py b/src/calibre/ebooks/rtf2xml/old_rtf.py index e86d2fa5ca..f8ca3ec8f5 100644 --- a/src/calibre/ebooks/rtf2xml/old_rtf.py +++ b/src/calibre/ebooks/rtf2xml/old_rtf.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/options_trem.py b/src/calibre/ebooks/rtf2xml/options_trem.py index 1861fae8a7..c62e18910a 100644 --- a/src/calibre/ebooks/rtf2xml/options_trem.py +++ b/src/calibre/ebooks/rtf2xml/options_trem.py @@ -1,5 +1,3 @@ - - import sys diff --git a/src/calibre/ebooks/rtf2xml/output.py b/src/calibre/ebooks/rtf2xml/output.py index d4c5b44c35..7a3b7d1167 100644 --- a/src/calibre/ebooks/rtf2xml/output.py +++ b/src/calibre/ebooks/rtf2xml/output.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/override_table.py b/src/calibre/ebooks/rtf2xml/override_table.py index cb733b9a80..94201b6e5a 100644 --- a/src/calibre/ebooks/rtf2xml/override_table.py +++ b/src/calibre/ebooks/rtf2xml/override_table.py @@ -1,5 +1,3 @@ - - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/paragraph_def.py b/src/calibre/ebooks/rtf2xml/paragraph_def.py index 3fa89c9b82..1c5e870bde 100644 --- a/src/calibre/ebooks/rtf2xml/paragraph_def.py +++ b/src/calibre/ebooks/rtf2xml/paragraph_def.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/paragraphs.py b/src/calibre/ebooks/rtf2xml/paragraphs.py index 8c4fa6dfe9..425fd89312 100644 --- a/src/calibre/ebooks/rtf2xml/paragraphs.py +++ b/src/calibre/ebooks/rtf2xml/paragraphs.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/pict.py b/src/calibre/ebooks/rtf2xml/pict.py index 536136a8b1..e532c5f0a7 100644 --- a/src/calibre/ebooks/rtf2xml/pict.py +++ b/src/calibre/ebooks/rtf2xml/pict.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/preamble_div.py b/src/calibre/ebooks/rtf2xml/preamble_div.py index 4f1d6306af..adc3aaf68c 100644 --- a/src/calibre/ebooks/rtf2xml/preamble_div.py +++ b/src/calibre/ebooks/rtf2xml/preamble_div.py @@ -1,5 +1,3 @@ - - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/preamble_rest.py b/src/calibre/ebooks/rtf2xml/preamble_rest.py index 6a3bb64ab0..7bc731a4e3 100644 --- a/src/calibre/ebooks/rtf2xml/preamble_rest.py +++ b/src/calibre/ebooks/rtf2xml/preamble_rest.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/process_tokens.py b/src/calibre/ebooks/rtf2xml/process_tokens.py index 25ae382f51..f704d625f9 100644 --- a/src/calibre/ebooks/rtf2xml/process_tokens.py +++ b/src/calibre/ebooks/rtf2xml/process_tokens.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/replace_illegals.py b/src/calibre/ebooks/rtf2xml/replace_illegals.py index cb38251a5f..7b811fce95 100644 --- a/src/calibre/ebooks/rtf2xml/replace_illegals.py +++ b/src/calibre/ebooks/rtf2xml/replace_illegals.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/sections.py b/src/calibre/ebooks/rtf2xml/sections.py index 8d79d6d7a1..b96e58a25e 100644 --- a/src/calibre/ebooks/rtf2xml/sections.py +++ b/src/calibre/ebooks/rtf2xml/sections.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/styles.py b/src/calibre/ebooks/rtf2xml/styles.py index cd04b727df..e2e4cb2517 100644 --- a/src/calibre/ebooks/rtf2xml/styles.py +++ b/src/calibre/ebooks/rtf2xml/styles.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/table.py b/src/calibre/ebooks/rtf2xml/table.py index 3b209d3ee0..0ba9553408 100644 --- a/src/calibre/ebooks/rtf2xml/table.py +++ b/src/calibre/ebooks/rtf2xml/table.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/table_info.py b/src/calibre/ebooks/rtf2xml/table_info.py index c6df02425b..47332a747b 100644 --- a/src/calibre/ebooks/rtf2xml/table_info.py +++ b/src/calibre/ebooks/rtf2xml/table_info.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/rtf2xml/tokenize.py b/src/calibre/ebooks/rtf2xml/tokenize.py index 95d3e90b1b..da4c1317e7 100644 --- a/src/calibre/ebooks/rtf2xml/tokenize.py +++ b/src/calibre/ebooks/rtf2xml/tokenize.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # diff --git a/src/calibre/ebooks/snb/snbml.py b/src/calibre/ebooks/snb/snbml.py index e13877f7ad..3aa024d335 100644 --- a/src/calibre/ebooks/snb/snbml.py +++ b/src/calibre/ebooks/snb/snbml.py @@ -85,7 +85,7 @@ class SNBMLizer: from calibre.ebooks.oeb.base import XHTML from calibre.ebooks.oeb.stylizer import Stylizer from calibre.utils.xml_parse import safe_xml_fromstring - output = [u''] + output = [''] stylizer = Stylizer(self.item.data, self.item.href, self.oeb_book, self.opts, self.opts.output_profile) content = etree.tostring(self.item.data.find(XHTML('body')), encoding='unicode') # content = self.remove_newlines(content) diff --git a/src/calibre/ebooks/textile/__init__.py b/src/calibre/ebooks/textile/__init__.py index b8f48e442d..1acbfc38fc 100644 --- a/src/calibre/ebooks/textile/__init__.py +++ b/src/calibre/ebooks/textile/__init__.py @@ -1,4 +1,3 @@ - from .functions import textile, textile_restricted, Textile if False: diff --git a/src/calibre/ebooks/textile/functions.py b/src/calibre/ebooks/textile/functions.py index fc1cfb984a..ec0b475a08 100644 --- a/src/calibre/ebooks/textile/functions.py +++ b/src/calibre/ebooks/textile/functions.py @@ -100,7 +100,7 @@ def getimagesize(url): p.feed(s) if p.image: return 'width="%i" height="%i"' % p.image.size - except (IOError, ValueError): + except (OSError, ValueError): return None diff --git a/src/calibre/ebooks/textile/unsmarten.py b/src/calibre/ebooks/textile/unsmarten.py index 07ed152319..2cd6ae09f8 100644 --- a/src/calibre/ebooks/textile/unsmarten.py +++ b/src/calibre/ebooks/textile/unsmarten.py @@ -9,117 +9,117 @@ import re def unsmarten(txt): - txt = re.sub(u'¢|¢|¢', r'{c\}', txt) # cent - txt = re.sub(u'£|£|£', r'{L-}', txt) # pound - txt = re.sub(u'¥|¥|¥', r'{Y=}', txt) # yen - txt = re.sub(u'©|©|©', r'{(c)}', txt) # copyright - txt = re.sub(u'®|®|®', r'{(r)}', txt) # registered - txt = re.sub(u'¼|¼|¼', r'{1/4}', txt) # quarter - txt = re.sub(u'½|½|½', r'{1/2}', txt) # half - txt = re.sub(u'¾|¾|¾', r'{3/4}', txt) # three-quarter - txt = re.sub(u'À|À|À', r'{A`)}', txt) # A-grave - txt = re.sub(u'Á|Á|Á', r"{A'}", txt) # A-acute - txt = re.sub(u'Â|Â|Â', r'{A^}', txt) # A-circumflex - txt = re.sub(u'Ã|Ã|Ã', r'{A~}', txt) # A-tilde - txt = re.sub(u'Ä|Ä|Ä', r'{A"}', txt) # A-umlaut - txt = re.sub(u'Å|Å|Å', r'{Ao}', txt) # A-ring - txt = re.sub(u'Æ|Æ|Æ', r'{AE}', txt) # AE - txt = re.sub(u'Ç|Ç|Ç', r'{C,}', txt) # C-cedilla - txt = re.sub(u'È|È|È', r'{E`}', txt) # E-grave - txt = re.sub(u'É|É|É', r"{E'}", txt) # E-acute - txt = re.sub(u'Ê|Ê|Ê', r'{E^}', txt) # E-circumflex - txt = re.sub(u'Ë|Ë|Ë', r'{E"}', txt) # E-umlaut - txt = re.sub(u'Ì|Ì|Ì', r'{I`}', txt) # I-grave - txt = re.sub(u'Í|Í|Í', r"{I'}", txt) # I-acute - txt = re.sub(u'Î|Î|Î', r'{I^}', txt) # I-circumflex - txt = re.sub(u'Ï|Ï|Ï', r'{I"}', txt) # I-umlaut - txt = re.sub(u'Ð|Ð|Ð', r'{D-}', txt) # ETH - txt = re.sub(u'Ñ|Ñ|Ñ', r'{N~}', txt) # N-tilde - txt = re.sub(u'Ò|Ò|Ò', r'{O`}', txt) # O-grave - txt = re.sub(u'Ó|Ó|Ó', r"{O'}", txt) # O-acute - txt = re.sub(u'Ô|Ô|Ô', r'{O^}', txt) # O-circumflex - txt = re.sub(u'Õ|Õ|Õ', r'{O~}', txt) # O-tilde - txt = re.sub(u'Ö|Ö|Ö', r'{O"}', txt) # O-umlaut - txt = re.sub(u'×|×|×', r'{x}', txt) # dimension - txt = re.sub(u'Ø|Ø|Ø', r'{O/}', txt) # O-slash - txt = re.sub(u'Ù|Ù|Ù', r"{U`}", txt) # U-grave - txt = re.sub(u'Ú|Ú|Ú', r"{U'}", txt) # U-acute - txt = re.sub(u'Û|Û|Û', r'{U^}', txt) # U-circumflex - txt = re.sub(u'Ü|Ü|Ü', r'{U"}', txt) # U-umlaut - txt = re.sub(u'Ý|Ý|Ý', r"{Y'}", txt) # Y-grave - txt = re.sub(u'ß|ß|ß', r'{sz}', txt) # sharp-s - txt = re.sub(u'à|à|à', r'{a`}', txt) # a-grave - txt = re.sub(u'á|á|á', r"{a'}", txt) # a-acute - txt = re.sub(u'â|â|â', r'{a^}', txt) # a-circumflex - txt = re.sub(u'ã|ã|ã', r'{a~}', txt) # a-tilde - txt = re.sub(u'ä|ä|ä', r'{a"}', txt) # a-umlaut - txt = re.sub(u'å|å|å', r'{ao}', txt) # a-ring - txt = re.sub(u'æ|æ|æ', r'{ae}', txt) # ae - txt = re.sub(u'ç|ç|ç', r'{c,}', txt) # c-cedilla - txt = re.sub(u'è|è|è', r'{e`}', txt) # e-grave - txt = re.sub(u'é|é|é', r"{e'}", txt) # e-acute - txt = re.sub(u'ê|ê|ê', r'{e^}', txt) # e-circumflex - txt = re.sub(u'ë|ë|ë', r'{e"}', txt) # e-umlaut - txt = re.sub(u'ì|ì|ì', r'{i`}', txt) # i-grave - txt = re.sub(u'í|í|í', r"{i'}", txt) # i-acute - txt = re.sub(u'î|î|î', r'{i^}', txt) # i-circumflex - txt = re.sub(u'ï|ï|ï', r'{i"}', txt) # i-umlaut - txt = re.sub(u'ð|ð|ð', r'{d-}', txt) # eth - txt = re.sub(u'ñ|ñ|ñ', r'{n~}', txt) # n-tilde - txt = re.sub(u'ò|ò|ò', r'{o`}', txt) # o-grave - txt = re.sub(u'ó|ó|ó', r"{o'}", txt) # o-acute - txt = re.sub(u'ô|ô|ô', r'{o^}', txt) # o-circumflex - txt = re.sub(u'õ|õ|õ', r'{o~}', txt) # o-tilde - txt = re.sub(u'ö|ö|ö', r'{o"}', txt) # o-umlaut - txt = re.sub(u'ø|ø|ø', r'{o/}', txt) # o-stroke - txt = re.sub(u'ù|ù|ù', r'{u`}', txt) # u-grave - txt = re.sub(u'ú|ú|ú', r"{u'}", txt) # u-acute - txt = re.sub(u'û|û|û', r'{u^}', txt) # u-circumflex - txt = re.sub(u'ü|ü|ü', r'{u"}', txt) # u-umlaut - txt = re.sub(u'ý|ý|ý', r"{y'}", txt) # y-acute - txt = re.sub(u'ÿ|ÿ|ÿ', r'{y"}', txt) # y-umlaut + txt = re.sub('¢|¢|¢', r'{c\}', txt) # cent + txt = re.sub('£|£|£', r'{L-}', txt) # pound + txt = re.sub('¥|¥|¥', r'{Y=}', txt) # yen + txt = re.sub('©|©|©', r'{(c)}', txt) # copyright + txt = re.sub('®|®|®', r'{(r)}', txt) # registered + txt = re.sub('¼|¼|¼', r'{1/4}', txt) # quarter + txt = re.sub('½|½|½', r'{1/2}', txt) # half + txt = re.sub('¾|¾|¾', r'{3/4}', txt) # three-quarter + txt = re.sub('À|À|À', r'{A`)}', txt) # A-grave + txt = re.sub('Á|Á|Á', r"{A'}", txt) # A-acute + txt = re.sub('Â|Â|Â', r'{A^}', txt) # A-circumflex + txt = re.sub('Ã|Ã|Ã', r'{A~}', txt) # A-tilde + txt = re.sub('Ä|Ä|Ä', r'{A"}', txt) # A-umlaut + txt = re.sub('Å|Å|Å', r'{Ao}', txt) # A-ring + txt = re.sub('Æ|Æ|Æ', r'{AE}', txt) # AE + txt = re.sub('Ç|Ç|Ç', r'{C,}', txt) # C-cedilla + txt = re.sub('È|È|È', r'{E`}', txt) # E-grave + txt = re.sub('É|É|É', r"{E'}", txt) # E-acute + txt = re.sub('Ê|Ê|Ê', r'{E^}', txt) # E-circumflex + txt = re.sub('Ë|Ë|Ë', r'{E"}', txt) # E-umlaut + txt = re.sub('Ì|Ì|Ì', r'{I`}', txt) # I-grave + txt = re.sub('Í|Í|Í', r"{I'}", txt) # I-acute + txt = re.sub('Î|Î|Î', r'{I^}', txt) # I-circumflex + txt = re.sub('Ï|Ï|Ï', r'{I"}', txt) # I-umlaut + txt = re.sub('Ð|Ð|Ð', r'{D-}', txt) # ETH + txt = re.sub('Ñ|Ñ|Ñ', r'{N~}', txt) # N-tilde + txt = re.sub('Ò|Ò|Ò', r'{O`}', txt) # O-grave + txt = re.sub('Ó|Ó|Ó', r"{O'}", txt) # O-acute + txt = re.sub('Ô|Ô|Ô', r'{O^}', txt) # O-circumflex + txt = re.sub('Õ|Õ|Õ', r'{O~}', txt) # O-tilde + txt = re.sub('Ö|Ö|Ö', r'{O"}', txt) # O-umlaut + txt = re.sub('×|×|×', r'{x}', txt) # dimension + txt = re.sub('Ø|Ø|Ø', r'{O/}', txt) # O-slash + txt = re.sub('Ù|Ù|Ù', r"{U`}", txt) # U-grave + txt = re.sub('Ú|Ú|Ú', r"{U'}", txt) # U-acute + txt = re.sub('Û|Û|Û', r'{U^}', txt) # U-circumflex + txt = re.sub('Ü|Ü|Ü', r'{U"}', txt) # U-umlaut + txt = re.sub('Ý|Ý|Ý', r"{Y'}", txt) # Y-grave + txt = re.sub('ß|ß|ß', r'{sz}', txt) # sharp-s + txt = re.sub('à|à|à', r'{a`}', txt) # a-grave + txt = re.sub('á|á|á', r"{a'}", txt) # a-acute + txt = re.sub('â|â|â', r'{a^}', txt) # a-circumflex + txt = re.sub('ã|ã|ã', r'{a~}', txt) # a-tilde + txt = re.sub('ä|ä|ä', r'{a"}', txt) # a-umlaut + txt = re.sub('å|å|å', r'{ao}', txt) # a-ring + txt = re.sub('æ|æ|æ', r'{ae}', txt) # ae + txt = re.sub('ç|ç|ç', r'{c,}', txt) # c-cedilla + txt = re.sub('è|è|è', r'{e`}', txt) # e-grave + txt = re.sub('é|é|é', r"{e'}", txt) # e-acute + txt = re.sub('ê|ê|ê', r'{e^}', txt) # e-circumflex + txt = re.sub('ë|ë|ë', r'{e"}', txt) # e-umlaut + txt = re.sub('ì|ì|ì', r'{i`}', txt) # i-grave + txt = re.sub('í|í|í', r"{i'}", txt) # i-acute + txt = re.sub('î|î|î', r'{i^}', txt) # i-circumflex + txt = re.sub('ï|ï|ï', r'{i"}', txt) # i-umlaut + txt = re.sub('ð|ð|ð', r'{d-}', txt) # eth + txt = re.sub('ñ|ñ|ñ', r'{n~}', txt) # n-tilde + txt = re.sub('ò|ò|ò', r'{o`}', txt) # o-grave + txt = re.sub('ó|ó|ó', r"{o'}", txt) # o-acute + txt = re.sub('ô|ô|ô', r'{o^}', txt) # o-circumflex + txt = re.sub('õ|õ|õ', r'{o~}', txt) # o-tilde + txt = re.sub('ö|ö|ö', r'{o"}', txt) # o-umlaut + txt = re.sub('ø|ø|ø', r'{o/}', txt) # o-stroke + txt = re.sub('ù|ù|ù', r'{u`}', txt) # u-grave + txt = re.sub('ú|ú|ú', r"{u'}", txt) # u-acute + txt = re.sub('û|û|û', r'{u^}', txt) # u-circumflex + txt = re.sub('ü|ü|ü', r'{u"}', txt) # u-umlaut + txt = re.sub('ý|ý|ý', r"{y'}", txt) # y-acute + txt = re.sub('ÿ|ÿ|ÿ', r'{y"}', txt) # y-umlaut - txt = re.sub(u'Č|Č|Č', r'{Cˇ}', txt) # C-caron - txt = re.sub(u'č|č|č', r'{cˇ}', txt) # c-caron - txt = re.sub(u'Ď|Ď|Ď', r'{Dˇ}', txt) # D-caron - txt = re.sub(u'ď|ď|ď', r'{dˇ}', txt) # d-caron - txt = re.sub(u'Ě|Ě|Ě', r'{Eˇ}', txt) # E-caron - txt = re.sub(u'ě|ě|ě', r'{eˇ}', txt) # e-caron - txt = re.sub(u'Ĺ|Ĺ|Ĺ', r"{L'}", txt) # L-acute - txt = re.sub(u'ĺ|ĺ|ĺ', r"{l'}", txt) # l-acute - txt = re.sub(u'Ľ|Ľ|Ľ', r'{Lˇ}', txt) # L-caron - txt = re.sub(u'ľ|ľ|ľ', r'{lˇ}', txt) # l-caron - txt = re.sub(u'Ň|Ň|Ň', r'{Nˇ}', txt) # N-caron - txt = re.sub(u'ň|ň|ň', r'{nˇ}', txt) # n-caron + txt = re.sub('Č|Č|Č', r'{Cˇ}', txt) # C-caron + txt = re.sub('č|č|č', r'{cˇ}', txt) # c-caron + txt = re.sub('Ď|Ď|Ď', r'{Dˇ}', txt) # D-caron + txt = re.sub('ď|ď|ď', r'{dˇ}', txt) # d-caron + txt = re.sub('Ě|Ě|Ě', r'{Eˇ}', txt) # E-caron + txt = re.sub('ě|ě|ě', r'{eˇ}', txt) # e-caron + txt = re.sub('Ĺ|Ĺ|Ĺ', r"{L'}", txt) # L-acute + txt = re.sub('ĺ|ĺ|ĺ', r"{l'}", txt) # l-acute + txt = re.sub('Ľ|Ľ|Ľ', r'{Lˇ}', txt) # L-caron + txt = re.sub('ľ|ľ|ľ', r'{lˇ}', txt) # l-caron + txt = re.sub('Ň|Ň|Ň', r'{Nˇ}', txt) # N-caron + txt = re.sub('ň|ň|ň', r'{nˇ}', txt) # n-caron - txt = re.sub(u'Œ|Œ|Œ', r'{OE}', txt) # OE - txt = re.sub(u'œ|œ|œ', r'{oe}', txt) # oe + txt = re.sub('Œ|Œ|Œ', r'{OE}', txt) # OE + txt = re.sub('œ|œ|œ', r'{oe}', txt) # oe - txt = re.sub(u'Ŕ|Ŕ|Ŕ', r"{R'}", txt) # R-acute - txt = re.sub(u'ŕ|ŕ|ŕ', r"{r'}", txt) # r-acute - txt = re.sub(u'Ř|Ř|Ř', r'{Rˇ}', txt) # R-caron - txt = re.sub(u'ř|ř|ř', r'{rˇ}', txt) # r-caron - txt = re.sub(u'Ŝ|Ŝ', r'{S^}', txt) # S-circumflex - txt = re.sub(u'ŝ|ŝ', r'{s^}', txt) # s-circumflex - txt = re.sub(u'Š|Š|Š', r'{Sˇ}', txt) # S-caron - txt = re.sub(u'š|š|š', r'{sˇ}', txt) # s-caron - txt = re.sub(u'Ť|Ť|Ť', r'{Tˇ}', txt) # T-caron - txt = re.sub(u'ť|ť|ť', r'{tˇ}', txt) # t-caron - txt = re.sub(u'Ů|Ů|Ů', r'{U°}', txt) # U-ring - txt = re.sub(u'ů|ů|ů', r'{u°}', txt) # u-ring - txt = re.sub(u'Ž|Ž|Ž', r'{Zˇ}', txt) # Z-caron - txt = re.sub(u'ž|ž|ž', r'{zˇ}', txt) # z-caron + txt = re.sub('Ŕ|Ŕ|Ŕ', r"{R'}", txt) # R-acute + txt = re.sub('ŕ|ŕ|ŕ', r"{r'}", txt) # r-acute + txt = re.sub('Ř|Ř|Ř', r'{Rˇ}', txt) # R-caron + txt = re.sub('ř|ř|ř', r'{rˇ}', txt) # r-caron + txt = re.sub('Ŝ|Ŝ', r'{S^}', txt) # S-circumflex + txt = re.sub('ŝ|ŝ', r'{s^}', txt) # s-circumflex + txt = re.sub('Š|Š|Š', r'{Sˇ}', txt) # S-caron + txt = re.sub('š|š|š', r'{sˇ}', txt) # s-caron + txt = re.sub('Ť|Ť|Ť', r'{Tˇ}', txt) # T-caron + txt = re.sub('ť|ť|ť', r'{tˇ}', txt) # t-caron + txt = re.sub('Ů|Ů|Ů', r'{U°}', txt) # U-ring + txt = re.sub('ů|ů|ů', r'{u°}', txt) # u-ring + txt = re.sub('Ž|Ž|Ž', r'{Zˇ}', txt) # Z-caron + txt = re.sub('ž|ž|ž', r'{zˇ}', txt) # z-caron - txt = re.sub(u'•|•|•', r'{*}', txt) # bullet - txt = re.sub(u'₣|₣', r'{Fr}', txt) # Franc - txt = re.sub(u'₤|₤', r'{L=}', txt) # Lira - txt = re.sub(u'₨|₨', r'{Rs}', txt) # Rupee - txt = re.sub(u'€|€|€', r'{C=}', txt) # euro - txt = re.sub(u'™|™|™', r'{tm}', txt) # trademark - txt = re.sub(u'♠|♠|♠', r'{spade}', txt) # spade - txt = re.sub(u'♣|♣|♣', r'{club}', txt) # club - txt = re.sub(u'♥|♥|♥', r'{heart}', txt) # heart - txt = re.sub(u'♦|♦|♦', r'{diamond}', txt) # diamond + txt = re.sub('•|•|•', r'{*}', txt) # bullet + txt = re.sub('₣|₣', r'{Fr}', txt) # Franc + txt = re.sub('₤|₤', r'{L=}', txt) # Lira + txt = re.sub('₨|₨', r'{Rs}', txt) # Rupee + txt = re.sub('€|€|€', r'{C=}', txt) # euro + txt = re.sub('™|™|™', r'{tm}', txt) # trademark + txt = re.sub('♠|♠|♠', r'{spade}', txt) # spade + txt = re.sub('♣|♣|♣', r'{club}', txt) # club + txt = re.sub('♥|♥|♥', r'{heart}', txt) # heart + txt = re.sub('♦|♦|♦', r'{diamond}', txt) # diamond # Move into main code? # txt = re.sub(u'\xa0', r'p. ', txt) # blank paragraph diff --git a/src/calibre/ebooks/txt/markdownml.py b/src/calibre/ebooks/txt/markdownml.py index 7eaa293968..91657f7c51 100644 --- a/src/calibre/ebooks/txt/markdownml.py +++ b/src/calibre/ebooks/txt/markdownml.py @@ -138,7 +138,7 @@ class MarkdownMLizer(OEB2HTML): if 'margin-top' in style.cssdict() and style['margin-top'] != 'auto': ems = int(round(float(style.marginTop) / style.fontSize) - 1) if ems >= 1: - text.append(u'\n\n' * ems) + text.append('\n\n' * ems) bq = '> ' * self.blockquotes # Block level elements @@ -270,7 +270,7 @@ class MarkdownMLizer(OEB2HTML): if 'margin-bottom' in style.cssdict() and style['margin-bottom'] != 'auto': ems = int(round((float(style.marginBottom) / style.fontSize) - 1)) if ems >= 1: - text.append(u'\n\n' * ems) + text.append('\n\n' * ems) # Add the text that is outside of the tag. if hasattr(elem, 'tail') and elem.tail: diff --git a/src/calibre/ebooks/txt/processor.py b/src/calibre/ebooks/txt/processor.py index a8da8d8c32..37df950f8c 100644 --- a/src/calibre/ebooks/txt/processor.py +++ b/src/calibre/ebooks/txt/processor.py @@ -94,13 +94,13 @@ def convert_basic(txt, title='', epub_split_size_kb=0): for line in txt.split('\n'): if line.strip(): blank_count = 0 - lines.append(u'

%s

' % prepare_string_for_xml(line.replace('\n', ' '))) + lines.append('

%s

' % prepare_string_for_xml(line.replace('\n', ' '))) else: blank_count += 1 if blank_count == 2: - lines.append(u'

 

') + lines.append('

 

') - return HTML_TEMPLATE % (title, u'\n'.join(lines)) + return HTML_TEMPLATE % (title, '\n'.join(lines)) DEFAULT_MD_EXTENSIONS = ('footnotes', 'tables', 'toc') @@ -191,7 +191,7 @@ def separate_paragraphs_single_line(txt): def separate_paragraphs_print_formatted(txt): - txt = re.sub(u'(?miu)^(?P\t+|[ ]{2,})(?=.)', lambda mo: '\n%s' % mo.group('indent'), txt) + txt = re.sub('(?miu)^(?P\t+|[ ]{2,})(?=.)', lambda mo: '\n%s' % mo.group('indent'), txt) return txt diff --git a/src/calibre/ebooks/txt/textileml.py b/src/calibre/ebooks/txt/textileml.py index 71562c08c1..77860cc5dc 100644 --- a/src/calibre/ebooks/txt/textileml.py +++ b/src/calibre/ebooks/txt/textileml.py @@ -113,16 +113,16 @@ class TextileMLizer(OEB2HTML): # reduce blank lines text = re.sub(r'\n{3}', r'\n\np. \n\n', text) - text = re.sub(u'%\n(p[<>=]{1,2}\\.|p\\.)', r'%\n\n\1', text) + text = re.sub('%\n(p[<>=]{1,2}\\.|p\\.)', r'%\n\n\1', text) # Check span following blank para text = re.sub(r'\n+ +%', r' %', text) - text = re.sub(u'p[<>=]{1,2}\\.\n\n?', r'', text) + text = re.sub('p[<>=]{1,2}\\.\n\n?', r'', text) # blank paragraph text = re.sub(r'\n(p.*\.)\n', r'\n\1 \n\n', text) # blank paragraph - text = re.sub(u'\n\xa0', r'\np. ', text) + text = re.sub('\n\xa0', r'\np. ', text) # blank paragraph - text = re.sub(u'\np[<>=]{1,2}?\\. \xa0', r'\np. ', text) + text = re.sub('\np[<>=]{1,2}?\\. \xa0', r'\np. ', text) text = re.sub(r'(^|\n)(p.*\. ?\n)(p.*\.)', r'\1\3', text) text = re.sub(r'\n(p\. \n)(p.*\.|h.*\.)', r'\n\2', text) # sort out spaces in tables @@ -203,7 +203,7 @@ class TextileMLizer(OEB2HTML): if 'id' in attribs: txt = '(#'+attribs['id']+ ')' self.our_ids.append('#'+attribs['id']) - self.id_no_text = u'\xa0' + self.id_no_text = '\xa0' return txt def build_block(self, tag, style, attribs, stylizer): @@ -253,7 +253,7 @@ class TextileMLizer(OEB2HTML): if 'margin-top' in style.cssdict() and style['margin-top'] != 'auto': ems = min(int(round(float(style.marginTop) / style.fontSize) - 1), self.MAX_EM) if ems >= 1: - text.append(u'\n\n\xa0' * ems) + text.append('\n\n\xa0' * ems) if tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div'): if tag == 'div': @@ -449,7 +449,7 @@ class TextileMLizer(OEB2HTML): if not self.in_pre: txt = self.prepare_string_for_textile(self.remove_newlines(txt)) text.append(txt) - self.id_no_text = u'' + self.id_no_text = '' # Recurse down into tags within the tag we are in. for item in elem: @@ -471,7 +471,7 @@ class TextileMLizer(OEB2HTML): self.in_a_link = False t = '' text.append(self.id_no_text) - self.id_no_text = u'' + self.id_no_text = '' if t in ('*]', '*'): self.style_bold = False elif t in ('_]', '_'): @@ -490,7 +490,7 @@ class TextileMLizer(OEB2HTML): if 'margin-bottom' in style.cssdict() and style['margin-bottom'] != 'auto': ems = min(int(round((float(style.marginBottom) / style.fontSize) - 1)), self.MAX_EM) if ems >= 1: - text.append(u'\n\n\xa0' * ems) + text.append('\n\n\xa0' * ems) # Add the text that is outside of the tag. if hasattr(elem, 'tail') and elem.tail: diff --git a/src/calibre/ebooks/txt/txtml.py b/src/calibre/ebooks/txt/txtml.py index 8907f5fd3a..745de604d3 100644 --- a/src/calibre/ebooks/txt/txtml.py +++ b/src/calibre/ebooks/txt/txtml.py @@ -68,7 +68,7 @@ class TXTMLizer: from calibre.ebooks.oeb.base import XHTML from calibre.ebooks.oeb.stylizer import Stylizer from calibre.utils.xml_parse import safe_xml_fromstring - output = [u''] + output = [''] output.append(self.get_toc()) for item in self.oeb_book.spine: self.log.debug('Converting %s to TXT...' % item.href) @@ -118,7 +118,7 @@ class TXTMLizer: def cleanup_text(self, text): self.log.debug('\tClean up text...') # Replace bad characters. - text = text.replace(u'\xa0', ' ') + text = text.replace('\xa0', ' ') # Replace tabs, vertical tags and form feeds with single space. text = text.replace('\t+', ' ') @@ -135,7 +135,7 @@ class TXTMLizer: text = re.sub('\n[ ]+\n', '\n\n', text) if self.opts.remove_paragraph_spacing: text = re.sub('\n{2,}', '\n', text) - text = re.sub(r'(?msu)^(?P[^\t\n]+?)$', lambda mo: u'%s\n\n' % mo.group('t'), text) + text = re.sub(r'(?msu)^(?P[^\t\n]+?)$', lambda mo: '%s\n\n' % mo.group('t'), text) text = re.sub(r'(?msu)(?P[^\n])\n+(?P[^\t\n]+?)(?=\n)', lambda mo: '%s\n\n\n\n\n\n%s' % (mo.group('b'), mo.group('t')), text) else: text = re.sub('\n{7,}', '\n\n\n\n\n\n', text) diff --git a/src/calibre/ebooks/unihandecode/pykakasi/__init__.py b/src/calibre/ebooks/unihandecode/pykakasi/__init__.py index b7fc7265e7..705aced763 100644 --- a/src/calibre/ebooks/unihandecode/pykakasi/__init__.py +++ b/src/calibre/ebooks/unihandecode/pykakasi/__init__.py @@ -1,5 +1,3 @@ - - from calibre.ebooks.unihandecode.pykakasi.kakasi import kakasi kakasi diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 62f181d659..d0c2fc891e 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -916,7 +914,7 @@ class Application(QApplication): self.setAttribute(Qt.ApplicationAttribute.AA_SynthesizeTouchForUnhandledMouseEvents, False) try: base_dir() - except EnvironmentError as err: + except OSError as err: if not headless: show_temp_dir_error(err) raise SystemExit('Failed to create temporary folder') diff --git a/src/calibre/gui2/actions/annotate.py b/src/calibre/gui2/actions/annotate.py index 6e258b00e5..c0a5f2bfc6 100644 --- a/src/calibre/gui2/actions/annotate.py +++ b/src/calibre/gui2/actions/annotate.py @@ -155,7 +155,7 @@ class FetchAnnotationsAction(InterfaceAction): entries = [] for id_, tb in iteritems(errors): title = id_ - if isinstance(id_, type(1)): + if isinstance(id_, int): title = db.title(id_, index_is_id=True) entries.extend([title, tb, '']) error_dialog(self.gui, _('Some errors'), diff --git a/src/calibre/gui2/actions/browse_annots.py b/src/calibre/gui2/actions/browse_annots.py index 88731ed551..e8e34d2748 100644 --- a/src/calibre/gui2/actions/browse_annots.py +++ b/src/calibre/gui2/actions/browse_annots.py @@ -2,7 +2,6 @@ # vim:fileencoding=utf-8 # License: GPL v3 Copyright: 2020, Kovid Goyal -from __future__ import absolute_import, division, print_function, unicode_literals from qt.core import Qt diff --git a/src/calibre/gui2/actions/catalog.py b/src/calibre/gui2/actions/catalog.py index 8d3591a0e6..80be87eae3 100644 --- a/src/calibre/gui2/actions/catalog.py +++ b/src/calibre/gui2/actions/catalog.py @@ -99,7 +99,7 @@ class GenerateCatalogAction(InterfaceAction): sanitize_file_name(job.catalog_title), job.fmt.lower())) try: shutil.copyfile(job.catalog_file_path, destination) - except EnvironmentError as err: + except OSError as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied import traceback error_dialog(self.gui, _('Permission denied'), diff --git a/src/calibre/gui2/actions/convert.py b/src/calibre/gui2/actions/convert.py index 0b4acb8e12..c9c79182f2 100644 --- a/src/calibre/gui2/actions/convert.py +++ b/src/calibre/gui2/actions/convert.py @@ -91,7 +91,7 @@ class ConvertAction(InterfaceAction): of = prefs['output_format'].lower() for book_id in book_ids: fmts = db.formats(book_id, index_is_id=True) - fmts = set(x.lower() for x in fmts.split(',')) if fmts else set() + fmts = {x.lower() for x in fmts.split(',')} if fmts else set() if gprefs['auto_convert_same_fmt'] or of not in fmts: needed.add(book_id) if needed: diff --git a/src/calibre/gui2/actions/delete.py b/src/calibre/gui2/actions/delete.py index 1fba700bd7..1311e22c0c 100644 --- a/src/calibre/gui2/actions/delete.py +++ b/src/calibre/gui2/actions/delete.py @@ -158,7 +158,7 @@ class DeleteAction(InterfaceAction): for x in ids: fmts_ = db.formats(x, index_is_id=True, verify_formats=False) if fmts_: - for x in frozenset([x.lower() for x in fmts_.split(',')]): + for x in frozenset(x.lower() for x in fmts_.split(',')): c[x] += 1 d = SelectFormats(c, msg, parent=self.gui, exclude=exclude, single=single) @@ -381,7 +381,7 @@ class DeleteAction(InterfaceAction): if len(to_delete_ids) < 5: try: view.model().delete_books_by_id(to_delete_ids) - except IOError as err: + except OSError as err: if err.errno == errno.EACCES: import traceback fname = os.path.basename(getattr(err, 'filename', 'file') or 'file') diff --git a/src/calibre/gui2/actions/polish.py b/src/calibre/gui2/actions/polish.py index 4d6c545bf6..7f92017582 100644 --- a/src/calibre/gui2/actions/polish.py +++ b/src/calibre/gui2/actions/polish.py @@ -238,7 +238,7 @@ class Polish(QDialog): # {{{ show=True) gprefs['polishing_settings'] = saved_prefs self.queue_files() - return super(Polish, self).accept() + return super().accept() def queue_files(self): self.tdir = PersistentTemporaryDirectory('_queue_polish') @@ -390,7 +390,7 @@ class Report(QDialog): # {{{ if self.reports: self.show_next() return - super(Report, self).accept() + super().accept() def reject(self): if self.ign.isChecked(): @@ -398,7 +398,7 @@ class Report(QDialog): # {{{ if self.reports: self.show_next() return - super(Report, self).reject() + super().reject() # }}} diff --git a/src/calibre/gui2/add_filters.py b/src/calibre/gui2/add_filters.py index a667501979..4894049973 100644 --- a/src/calibre/gui2/add_filters.py +++ b/src/calibre/gui2/add_filters.py @@ -71,7 +71,7 @@ class RuleEdit(RuleEditBase): self.query.setText(str(rule.get('query', '')).strip()) def validate(self): - ans = super(RuleEdit, self).validate() + ans = super().validate() if ans: rule = self.rule if 'glob' in rule['match_type']: diff --git a/src/calibre/gui2/auto_add.py b/src/calibre/gui2/auto_add.py index e19b703f3e..fb41e3026f 100644 --- a/src/calibre/gui2/auto_add.py +++ b/src/calibre/gui2/auto_add.py @@ -106,7 +106,7 @@ class Worker(Thread): def safe_mtime(x): try: return os.path.getmtime(os.path.join(self.path, x)) - except EnvironmentError: + except OSError: return time.time() for fname in sorted(files, key=safe_mtime): diff --git a/src/calibre/gui2/bars.py b/src/calibre/gui2/bars.py index 406996803d..51b03acf56 100644 --- a/src/calibre/gui2/bars.py +++ b/src/calibre/gui2/bars.py @@ -644,8 +644,7 @@ class BarsManager(QObject): @property def bars(self): - for x in self.main_bars + self.child_bars: - yield x + yield from self.main_bars + self.child_bars @property def showing_donate(self): diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index 144c153cc9..c5177b022b 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -72,10 +72,10 @@ def copy_all(text_browser): def create_search_internet_menu(callback, author=None): - m = QMenu(( + m = QMenu( _('Search the internet for the author {}').format(author) if author is not None else - _('Search the internet for this book')) + _('Search the internet for this book') ) m.menuAction().setIcon(QIcon(I('search.png'))) items = all_book_searches() if author is None else all_author_searches() @@ -394,7 +394,7 @@ def create_copy_links(menu, data=None): field = 'authors' if field and field in ('tags', 'series', 'publisher', 'authors') or is_category(field): name = data['name' if data['type'] == 'author' else 'value'] - eq = f'{field}:"={name}"'.encode('utf-8').hex() + eq = f'{field}:"={name}"'.encode().hex() link(_('Link to show books matching {} in calibre').format(name), f'calibre://search/{library_id}?eq={eq}') diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.py b/src/calibre/gui2/catalog/catalog_epub_mobi.py index fe83a86eb1..5cf062d789 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.py +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.py @@ -105,7 +105,7 @@ class PluginWidget(QWidget,Ui_Form): 'name':_('Read book'), 'field':_('Tags'), 'pattern':'+', - 'prefix':u'\u2713'}, + 'prefix':'\u2713'}, {'ordinal':1, 'enabled':True, 'name':_('Wishlist item'), @@ -241,7 +241,7 @@ class PluginWidget(QWidget,Ui_Form): def fetch_eligible_custom_fields(self): self.all_custom_fields = self.db.custom_field_keys() custom_fields = {} - custom_fields[_('Tags')] = {'field':'tag', 'datatype':u'text'} + custom_fields[_('Tags')] = {'field':'tag', 'datatype':'text'} for custom_field in self.all_custom_fields: field_md = self.db.metadata_for_field(custom_field) if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']: @@ -1191,7 +1191,7 @@ class ExclusionRules(GenericRulesTable): 'PATTERN': {'ordinal': 3, 'name': _('Value')},} def __init__(self, parent, parent_gb_hl, object_name, rules): - super(ExclusionRules, self).__init__(parent, parent_gb_hl, object_name, rules) + super().__init__(parent, parent_gb_hl, object_name, rules) self.setObjectName("exclusion_rules_table") self._init_table_widget() self._initialize() @@ -1284,7 +1284,7 @@ class PrefixRules(GenericRulesTable): 'PATTERN':{'ordinal': 4, 'name': _('Value')},} def __init__(self, parent, parent_gb_hl, object_name, rules): - super(PrefixRules, self).__init__(parent, parent_gb_hl, object_name, rules) + super().__init__(parent, parent_gb_hl, object_name, rules) self.setObjectName("prefix_rules_table") self._init_table_widget() self._initialize() diff --git a/src/calibre/gui2/comments_editor.py b/src/calibre/gui2/comments_editor.py index 43a266e833..45e5c4addf 100644 --- a/src/calibre/gui2/comments_editor.py +++ b/src/calibre/gui2/comments_editor.py @@ -752,7 +752,7 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{ x.tag not in ('script', 'style')] if len(elems) > 1: - ans = '
%s
'%(u''.join(elems)) + ans = '
%s
'%(''.join(elems)) else: ans = ''.join(elems) if not ans.startswith('<'): @@ -776,7 +776,7 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{ try: with lopen(path, 'rb') as f: data = f.read() - except EnvironmentError: + except OSError: if path.rpartition('.')[-1].lower() in {'jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'}: return QByteArray(bytearray.fromhex( '89504e470d0a1a0a0000000d49484452' diff --git a/src/calibre/gui2/complete2.py b/src/calibre/gui2/complete2.py index fc9b02fb12..826a8f531d 100644 --- a/src/calibre/gui2/complete2.py +++ b/src/calibre/gui2/complete2.py @@ -458,7 +458,7 @@ class EditWithComplete(EnComboBox): self.lineEdit().set_add_separator(what) def show_initial_value(self, what): - what = str(what) if what else u'' + what = str(what) if what else '' self.setText(what) self.lineEdit().selectAll() @@ -532,7 +532,7 @@ if __name__ == '__main__': le = EditWithComplete(d) d.layout().addWidget(le) items = ['one', 'otwo', 'othree', 'ooone', 'ootwo', 'other', 'odd', 'over', 'orc', 'oven', 'owe', - 'oothree', 'a1', 'a2',u'Edgas', u'Èdgar', u'Édgaq', u'Edgar', u'Édgar'] + 'oothree', 'a1', 'a2','Edgas', 'Èdgar', 'Édgaq', 'Edgar', 'Édgar'] le.update_items_cache(items) le.show_initial_value('') d.exec_() diff --git a/src/calibre/gui2/convert/bulk.py b/src/calibre/gui2/convert/bulk.py index d4f7e1c143..272187d6ba 100644 --- a/src/calibre/gui2/convert/bulk.py +++ b/src/calibre/gui2/convert/bulk.py @@ -128,7 +128,7 @@ class BulkConfig(Config): preferred_output_format and preferred_output_format \ in output_formats else sort_formats_by_preference(output_formats, [prefs['output_format']])[0] - self.output_formats.addItems((str(x.upper()) for x in output_formats)) + self.output_formats.addItems(str(x.upper()) for x in output_formats) self.output_formats.setCurrentIndex(output_formats.index(preferred_output_format)) def accept(self): diff --git a/src/calibre/gui2/convert/look_and_feel.py b/src/calibre/gui2/convert/look_and_feel.py index 48b6f15259..516cdde411 100644 --- a/src/calibre/gui2/convert/look_and_feel.py +++ b/src/calibre/gui2/convert/look_and_feel.py @@ -85,7 +85,7 @@ class LookAndFeelWidget(Widget, Ui_Form): if g is self.opt_filter_css: if not val: val = '' - items = frozenset([x.strip().lower() for x in val.split(',')]) + items = frozenset(x.strip().lower() for x in val.split(',')) for key, vals in iteritems(self.FILTER_CSS): w = getattr(self, 'filter_css_%s'%key) if not vals - items: diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index f67447107f..0d4336e8bf 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -204,7 +204,7 @@ class MetadataWidget(Widget, Ui_Form): try: with open(_file, "rb") as f: cover = f.read() - except IOError as e: + except OSError as e: d = error_dialog(self.parent(), _('Error reading file'), _("

There was an error reading from file:
") + _file + "


"+str(e)) d.exec_() @@ -244,7 +244,7 @@ class MetadataWidget(Widget, Ui_Form): db.set_field('authors', {self.book_id:authors}) if self.cover_changed and self.cover_data is not None: self.db.set_cover(self.book_id, self.cover_data) - except EnvironmentError as err: + except OSError as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied import traceback fname = getattr(err, 'filename', None) or 'file' diff --git a/src/calibre/gui2/convert/search_and_replace.py b/src/calibre/gui2/convert/search_and_replace.py index 2e028d2c58..577507aa97 100644 --- a/src/calibre/gui2/convert/search_and_replace.py +++ b/src/calibre/gui2/convert/search_and_replace.py @@ -280,7 +280,7 @@ class SearchAndReplaceWidget(Widget, Ui_Form): rest[name] = val if rest: - super(SearchAndReplaceWidget, self).apply_recommendations(rest) + super().apply_recommendations(rest) self.set_value(self.opt_search_replace, None) if new_val is None and legacy: diff --git a/src/calibre/gui2/convert/single.py b/src/calibre/gui2/convert/single.py index 5b9c1ef873..981d080d25 100644 --- a/src/calibre/gui2/convert/single.py +++ b/src/calibre/gui2/convert/single.py @@ -265,8 +265,8 @@ class Config(QDialog): preferred_output_format in output_formats else \ sort_formats_by_preference(output_formats, [prefs['output_format']])[0] - self.input_formats.addItems((str(x.upper()) for x in input_formats)) - self.output_formats.addItems((str(x.upper()) for x in output_formats)) + self.input_formats.addItems(str(x.upper()) for x in input_formats) + self.output_formats.addItems(str(x.upper()) for x in output_formats) self.input_formats.setCurrentIndex(input_formats.index(input_format)) self.output_formats.setCurrentIndex(output_formats.index(preferred_output_format)) diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index bdf03984a4..a4ce10aaf4 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -54,7 +54,7 @@ def get_tooltip(col_metadata, add_index=False): key = col_metadata['label'] + ('_index' if add_index else '') label = col_metadata['name'] + (_(' index') if add_index else '') description = col_metadata.get('display', {}).get('description', '') - return '{0} (#{1}){2} {3}'.format( + return '{} (#{}){} {}'.format( label, key, ':' if description else '', description).strip() diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 6acd443e98..120846285f 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -1453,7 +1451,7 @@ class DeviceMixin: # {{{ self.location_manager.free[2] : 'cardb'} on_card = space.get(sorted(space.keys(), reverse=True)[0], None) try: - total_size = sum([os.stat(f).st_size for f in files]) + total_size = sum(os.stat(f).st_size for f in files) except: try: import traceback diff --git a/src/calibre/gui2/device_drivers/configwidget.py b/src/calibre/gui2/device_drivers/configwidget.py index 754d004ccc..fc9398a0a5 100644 --- a/src/calibre/gui2/device_drivers/configwidget.py +++ b/src/calibre/gui2/device_drivers/configwidget.py @@ -156,7 +156,7 @@ class ConfigWidget(QWidget, Ui_ConfigWidget): formats = set(self.format_map()) extra = formats - set(self.calibre_known_formats) if extra: - fmts = sorted((x.upper() for x in extra)) + fmts = sorted(x.upper() for x in extra) if not question_dialog(self, _('Unknown formats'), _('You have enabled the {0} formats for' ' your {1}. The {1} may not support them.' diff --git a/src/calibre/gui2/device_drivers/mtp_folder_browser.py b/src/calibre/gui2/device_drivers/mtp_folder_browser.py index 753bb470f1..8389ec40d0 100644 --- a/src/calibre/gui2/device_drivers/mtp_folder_browser.py +++ b/src/calibre/gui2/device_drivers/mtp_folder_browser.py @@ -166,8 +166,7 @@ class IgnoredFolders(QDialog): for i in range(node.childCount()): child = node.child(i) yield child - for gc in self.iterchildren(child): - yield gc + yield from self.iterchildren(child) def create_item(self, f, parent): name = f.name diff --git a/src/calibre/gui2/device_drivers/tabbed_device_config.py b/src/calibre/gui2/device_drivers/tabbed_device_config.py index 6dddd9987f..b467f8294a 100644 --- a/src/calibre/gui2/device_drivers/tabbed_device_config.py +++ b/src/calibre/gui2/device_drivers/tabbed_device_config.py @@ -153,7 +153,7 @@ class TabbedDeviceConfig(QTabWidget): def __getattr__(self, attr_name): "If the object doesn't have an attribute, then check each tab." try: - return super(TabbedDeviceConfig, self).__getattr__(attr_name) + return super().__getattr__(attr_name) except AttributeError as ae: for i in range(0, self.count()): atab = self.widget(i) @@ -235,7 +235,7 @@ class DeviceConfigTab(QWidget): # {{{ def __getattr__(self, attr_name): try: - return super(DeviceConfigTab, self).__getattr__(attr_name) + return super().__getattr__(attr_name) except AttributeError as ae: for awidget in self.device_widgets: try: @@ -248,7 +248,7 @@ class DeviceConfigTab(QWidget): # {{{ class ExtraCustomization(DeviceConfigTab): # {{{ def __init__(self, extra_customization_message, extra_customization_choices, device_settings): - super(ExtraCustomization, self).__init__() + super().__init__() debug_print("ExtraCustomization.__init__ - extra_customization_message=", extra_customization_message) debug_print("ExtraCustomization.__init__ - extra_customization_choices=", extra_customization_choices) diff --git a/src/calibre/gui2/dialogs/__init__.py b/src/calibre/gui2/dialogs/__init__.py index b2d51aa5f5..bb8be7ff3d 100644 --- a/src/calibre/gui2/dialogs/__init__.py +++ b/src/calibre/gui2/dialogs/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/dialogs/catalog.py b/src/calibre/gui2/dialogs/catalog.py index 62ddc6953d..a3741f2c3f 100644 --- a/src/calibre/gui2/dialogs/catalog.py +++ b/src/calibre/gui2/dialogs/catalog.py @@ -102,7 +102,7 @@ class Catalog(QDialog, Ui_Dialog): self.widgets = sorted(self.widgets, key=lambda x: x.TITLE) # Generate a sorted list of installed catalog formats/sync_enabled pairs - fmts = sorted((x[0] for x in self.fmts)) + fmts = sorted(x[0] for x in self.fmts) self.sync_enabled_formats = [] for fmt in self.fmts: diff --git a/src/calibre/gui2/dialogs/choose_format.py b/src/calibre/gui2/dialogs/choose_format.py index caa984ea0b..0e6e6509ba 100644 --- a/src/calibre/gui2/dialogs/choose_format.py +++ b/src/calibre/gui2/dialogs/choose_format.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/dialogs/choose_format_device.py b/src/calibre/gui2/dialogs/choose_format_device.py index bfe0f2da23..0ab1c53c5e 100644 --- a/src/calibre/gui2/dialogs/choose_format_device.py +++ b/src/calibre/gui2/dialogs/choose_format_device.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2011, John Schember ' diff --git a/src/calibre/gui2/dialogs/choose_library.py b/src/calibre/gui2/dialogs/choose_library.py index 902826bc1a..aadd5d13c4 100644 --- a/src/calibre/gui2/dialogs/choose_library.py +++ b/src/calibre/gui2/dialogs/choose_library.py @@ -176,7 +176,7 @@ class ChooseLibrary(QDialog, Ui_Dialog): if action == 'move': try: os.makedirs(loc) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EEXIST: raise if not loc or not os.path.exists(loc) or not os.path.isdir(loc): diff --git a/src/calibre/gui2/dialogs/conversion_error.py b/src/calibre/gui2/dialogs/conversion_error.py index 17e91ec8ad..48b1bab20c 100644 --- a/src/calibre/gui2/dialogs/conversion_error.py +++ b/src/calibre/gui2/dialogs/conversion_error.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/dialogs/device_category_editor.py b/src/calibre/gui2/dialogs/device_category_editor.py index fe1193c0e5..736379255c 100644 --- a/src/calibre/gui2/dialogs/device_category_editor.py +++ b/src/calibre/gui2/dialogs/device_category_editor.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/dialogs/exim.py b/src/calibre/gui2/dialogs/exim.py index a15edf54b6..836443adf6 100644 --- a/src/calibre/gui2/dialogs/exim.py +++ b/src/calibre/gui2/dialogs/exim.py @@ -36,7 +36,7 @@ def disk_usage(path_to_dir, abort=None): if stat.S_ISDIR(r.st_mode): stack.append(cpath) ans += r.st_size - except EnvironmentError: + except OSError: pass return ans diff --git a/src/calibre/gui2/dialogs/password.py b/src/calibre/gui2/dialogs/password.py index 9c59d82b27..3e5ab4ce57 100644 --- a/src/calibre/gui2/dialogs/password.py +++ b/src/calibre/gui2/dialogs/password.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/dialogs/quickview.py b/src/calibre/gui2/dialogs/quickview.py index f2bceb58f9..b02258ae69 100644 --- a/src/calibre/gui2/dialogs/quickview.py +++ b/src/calibre/gui2/dialogs/quickview.py @@ -857,7 +857,7 @@ def get_qv_field_list(fm, use_defaults=False): else: src = db.prefs fieldlist = list(src['qv_display_fields']) - names = frozenset([x[0] for x in fieldlist]) + names = frozenset(x[0] for x in fieldlist) for field in fm.displayable_field_keys(): if (field != 'comments' and fm[field]['datatype'] != 'comments' and field not in names): fieldlist.append((field, False)) diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index de660e34ec..6be18f6a14 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' @@ -114,8 +112,8 @@ class DaysOfWeek(Base): @property def schedule(self): - days_of_week = tuple([i for i, d in enumerate(self.days) if - d.isChecked()]) + days_of_week = tuple(i for i, d in enumerate(self.days) if + d.isChecked()) t = self.time.time() hour, minute = t.hour(), t.minute() return 'days_of_week', (days_of_week, int(hour), int(minute)) diff --git a/src/calibre/gui2/dialogs/search.py b/src/calibre/gui2/dialogs/search.py index c46c2674b8..74e29e3efd 100644 --- a/src/calibre/gui2/dialogs/search.py +++ b/src/calibre/gui2/dialogs/search.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -378,7 +376,7 @@ class SearchDialog(QDialog): if template and value: cb = self.template_test_type_box op = str(cb.itemData(cb.currentIndex())) - l = '{0}#@#:{1}:{2}'.format(template, op, value) + l = '{}#@#:{}:{}'.format(template, op, value) return 'template:"' + l + '"' return '' diff --git a/src/calibre/gui2/dialogs/tag_categories.py b/src/calibre/gui2/dialogs/tag_categories.py index e0fe3e6a85..29ee09c6b4 100644 --- a/src/calibre/gui2/dialogs/tag_categories.py +++ b/src/calibre/gui2/dialogs/tag_categories.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/dialogs/tag_editor.py b/src/calibre/gui2/dialogs/tag_editor.py index 36da31dee7..429b21f5ae 100644 --- a/src/calibre/gui2/dialogs/tag_editor.py +++ b/src/calibre/gui2/dialogs/tag_editor.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index 0d11c83c33..1908e6d272 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -327,7 +327,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): def search_for_books(self, item): from calibre.gui2.ui import get_gui - get_gui().search.set_search_string('{0}:"={1}"'.format(self.category, + get_gui().search.set_search_string('{}:"={}"'.format(self.category, str(item.text()).replace(r'"', r'\"'))) qv = get_quickview_action_plugin() diff --git a/src/calibre/gui2/dialogs/tag_list_editor_table_widget.py b/src/calibre/gui2/dialogs/tag_list_editor_table_widget.py index 417641e127..635f377116 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor_table_widget.py +++ b/src/calibre/gui2/dialogs/tag_list_editor_table_widget.py @@ -1,7 +1,6 @@ #!/usr/bin/env python # vim:fileencoding=utf-8 # License: GPLv3 Copyright: 2008, Kovid Goyal -from __future__ import absolute_import, division, print_function, unicode_literals from qt.core import (Qt, QTableWidget, pyqtSignal) diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py index f0e61cb456..a5237ddda7 100644 --- a/src/calibre/gui2/dialogs/template_dialog.py +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -50,7 +50,7 @@ class TemplateHighlighter(QSyntaxHighlighter): 'separator', 'break', 'continue', 'return', 'in', 'inlist'] def __init__(self, parent=None, builtin_functions=None): - super(TemplateHighlighter, self).__init__(parent) + super().__init__(parent) self.initializeFormats() @@ -141,7 +141,7 @@ class TemplateHighlighter(QSyntaxHighlighter): if not text: pass - elif text[0] == u"#": + elif text[0] == "#": self.setFormat(0, textLength, self.Formats["comment"]) return @@ -506,7 +506,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): (_('Template file'), ['txt']) ], select_only_single_file=True) if filename: - with open(filename[0], 'r') as f: + with open(filename[0]) as f: self.textbox.setPlainText(f.read()) def save_template(self): diff --git a/src/calibre/gui2/dnd.py b/src/calibre/gui2/dnd.py index 566b403544..4c1f2fa746 100644 --- a/src/calibre/gui2/dnd.py +++ b/src/calibre/gui2/dnd.py @@ -346,7 +346,7 @@ def _get_firefox_pair(md, exts, url, fname): def get_firefox_rurl(md, exts): - formats = frozenset([str(x) for x in md.formats()]) + formats = frozenset(str(x) for x in md.formats()) url = fname = None if 'application/x-moz-file-promise-url' in formats and \ 'application/x-moz-file-promise-dest-filename' in formats: diff --git a/src/calibre/gui2/email.py b/src/calibre/gui2/email.py index 87dabb3a4d..bf3d910d96 100644 --- a/src/calibre/gui2/email.py +++ b/src/calibre/gui2/email.py @@ -308,7 +308,7 @@ class EmailMixin: # {{{ pass def send_multiple_by_mail(self, recipients, delete_from_library): - ids = set(self.library_view.model().id(r) for r in self.library_view.selectionModel().selectedRows()) + ids = {self.library_view.model().id(r) for r in self.library_view.selectionModel().selectedRows()} if not ids: return db = self.current_db diff --git a/src/calibre/gui2/icon_theme.py b/src/calibre/gui2/icon_theme.py index 766269215b..a8201d9c4b 100644 --- a/src/calibre/gui2/icon_theme.py +++ b/src/calibre/gui2/icon_theme.py @@ -104,7 +104,7 @@ def read_theme_from_folder(path): try: with open(os.path.join(path, THEME_METADATA), 'rb') as f: metadata = json.load(f) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise metadata = {} @@ -124,7 +124,7 @@ def read_theme_from_folder(path): try: with open(os.path.join(path, THEME_COVER), 'rb') as f: theme.cover = f.read() - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise theme.cover = create_cover(ans) @@ -450,7 +450,7 @@ def get_cover(metadata): cdir = os.path.join(cache_dir(), 'icon-theme-covers') try: os.makedirs(cdir) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EEXIST: raise @@ -462,7 +462,7 @@ def get_cover(metadata): try: with open(path, 'rb') as f: return f.read() - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise return b'' @@ -808,14 +808,14 @@ def remove_icon_theme(): try: with open(metadata_file, 'rb') as f: metadata = json.load(f) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise return for name in metadata['files']: try: os.remove(os.path.join(icdir, *name.split('/'))) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise os.remove(metadata_file) diff --git a/src/calibre/gui2/image_popup.py b/src/calibre/gui2/image_popup.py index bdf4c0ae8f..ec78866a13 100644 --- a/src/calibre/gui2/image_popup.py +++ b/src/calibre/gui2/image_popup.py @@ -221,7 +221,7 @@ class ImageView(QDialog): def adjust_scrollbars(self, factor): for sb in (self.scrollarea.horizontalScrollBar(), self.scrollarea.verticalScrollBar()): - sb.setValue(int(factor*sb.value()) + int(((factor - 1) * sb.pageStep()/2))) + sb.setValue(int(factor*sb.value()) + int((factor - 1) * sb.pageStep()/2)) def rotate_image(self): pm = self.label.pixmap() diff --git a/src/calibre/gui2/keyboard.py b/src/calibre/gui2/keyboard.py index 68c07f2ce7..27643cc25a 100644 --- a/src/calibre/gui2/keyboard.py +++ b/src/calibre/gui2/keyboard.py @@ -185,8 +185,7 @@ class Node: return self.children[row] def __iter__(self): - for child in self.children: - yield child + yield from self.children class ConfigModel(SearchQueryParser, QAbstractItemModel): @@ -214,8 +213,7 @@ class ConfigModel(SearchQueryParser, QAbstractItemModel): @property def all_shortcuts(self): for group in self.data: - for sc in group: - yield sc + yield from group def rowCount(self, parent=ROOT): ip = parent.internalPointer() diff --git a/src/calibre/gui2/library/alternate_views.py b/src/calibre/gui2/library/alternate_views.py index 339359c8f7..575fec0261 100644 --- a/src/calibre/gui2/library/alternate_views.py +++ b/src/calibre/gui2/library/alternate_views.py @@ -397,7 +397,7 @@ class CoverDelegate(QStyledItemDelegate): self._animated_size = val def __init__(self, parent): - super(CoverDelegate, self).__init__(parent) + super().__init__(parent) self._animated_size = 1.0 self.animation = QPropertyAnimation(self, b'animated_size', self) self.animation.setEasingCurve(QEasingCurve.Type.OutInCirc) @@ -1153,7 +1153,7 @@ class GridView(QListView): def selectionCommand(self, index, event): if event and event.type() == QEvent.Type.KeyPress and event.key() in (Qt.Key.Key_Home, Qt.Key.Key_End) and event.modifiers() & Qt.Modifier.CTRL: return QItemSelectionModel.SelectionFlag.ClearAndSelect | QItemSelectionModel.SelectionFlag.Rows - return super(GridView, self).selectionCommand(index, event) + return super().selectionCommand(index, event) def wheelEvent(self, ev): if ev.phase() not in (Qt.ScrollPhase.ScrollUpdate, 0, Qt.ScrollPhase.ScrollMomentum): @@ -1179,6 +1179,6 @@ class GridView(QListView): if size_changed: self.delegate.cover_cache.clear() - return super(GridView, self).paintEvent(ev) + return super().paintEvent(ev) # }}} diff --git a/src/calibre/gui2/library/annotations.py b/src/calibre/gui2/library/annotations.py index 1971c89890..f53c398b11 100644 --- a/src/calibre/gui2/library/annotations.py +++ b/src/calibre/gui2/library/annotations.py @@ -827,7 +827,7 @@ class DetailsPanel(QWidget): series_text = '' if series: use_roman_numbers = config['use_roman_numerals_for_series_number'] - series_text = '{0} of {1}'.format(fmt_sidx(sidx, use_roman=use_roman_numbers), series) + series_text = '{} of {}'.format(fmt_sidx(sidx, use_roman=use_roman_numbers), series) annot = r['annotation'] atype = annotation_title(annot['type'], singular=True) book_format = r['format'] diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index efe0ca561a..18c6d81719 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -1139,7 +1139,7 @@ class BooksModel(QAbstractTableModel): # {{{ from calibre.gui2.ui import get_gui try: return self._set_data(index, value) - except (IOError, OSError) as err: + except OSError as err: import traceback if getattr(err, 'errno', None) == errno.EACCES: # Permission denied fname = getattr(err, 'filename', None) diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py index e6e6163e8f..79c4969d1e 100644 --- a/src/calibre/gui2/library/views.py +++ b/src/calibre/gui2/library/views.py @@ -1207,7 +1207,7 @@ class BooksView(QTableView): # {{{ def selectionCommand(self, index, event): if event and event.type() == QEvent.Type.KeyPress and event.key() in (Qt.Key.Key_Home, Qt.Key.Key_End) and event.modifiers() & Qt.Modifier.CTRL: return QItemSelectionModel.SelectionFlag.ClearAndSelect | QItemSelectionModel.SelectionFlag.Rows - return super(BooksView, self).selectionCommand(index, event) + return super().selectionCommand(index, event) def keyPressEvent(self, ev): if handle_enter_press(self, ev): @@ -1309,8 +1309,8 @@ class BooksView(QTableView): # {{{ ci = self.currentIndex() if not ci.isValid(): return None - selected_rows = frozenset([i.row() for i in self.selectedIndexes() if - i.isValid()]) + selected_rows = frozenset(i.row() for i in self.selectedIndexes() if + i.isValid()) column = ci.column() for i in range(ci.row()+1, self.row_count()): diff --git a/src/calibre/gui2/linux_file_dialogs.py b/src/calibre/gui2/linux_file_dialogs.py index 4203c490f3..5ac7c66213 100644 --- a/src/calibre/gui2/linux_file_dialogs.py +++ b/src/calibre/gui2/linux_file_dialogs.py @@ -124,7 +124,7 @@ def kdialog_supports_desktopfile(): if ans is None: try: raw = subprocess.check_output(['kdialog', '--help']) - except EnvironmentError: + except OSError: raw = b'--desktopfile' ans = kdialog_supports_desktopfile.ans = b'--desktopfile' in raw return ans diff --git a/src/calibre/gui2/lrf_renderer/__init__.py b/src/calibre/gui2/lrf_renderer/__init__.py index 86422d565c..f832dbb7fc 100644 --- a/src/calibre/gui2/lrf_renderer/__init__.py +++ b/src/calibre/gui2/lrf_renderer/__init__.py @@ -1,4 +1,2 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/lrf_renderer/bookview.py b/src/calibre/gui2/lrf_renderer/bookview.py index 4fb1bec8fd..75da51d783 100644 --- a/src/calibre/gui2/lrf_renderer/bookview.py +++ b/src/calibre/gui2/lrf_renderer/bookview.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/lrf_renderer/document.py b/src/calibre/gui2/lrf_renderer/document.py index ed4d1fb919..fb57bf9c70 100644 --- a/src/calibre/gui2/lrf_renderer/document.py +++ b/src/calibre/gui2/lrf_renderer/document.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/lrf_renderer/main.py b/src/calibre/gui2/lrf_renderer/main.py index 64de2f719b..3ccadde75e 100644 --- a/src/calibre/gui2/lrf_renderer/main.py +++ b/src/calibre/gui2/lrf_renderer/main.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/lrf_renderer/text.py b/src/calibre/gui2/lrf_renderer/text.py index 6c7212a22c..cd2a0cf2d1 100644 --- a/src/calibre/gui2/lrf_renderer/text.py +++ b/src/calibre/gui2/lrf_renderer/text.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -321,8 +319,7 @@ class TextBlock: break def __iter__(self): - for line in self.lines: - yield line + yield from self.lines def __str__(self): s = '' diff --git a/src/calibre/gui2/main_window.py b/src/calibre/gui2/main_window.py index e13587119c..81810d9e55 100644 --- a/src/calibre/gui2/main_window.py +++ b/src/calibre/gui2/main_window.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index 275ad14c0c..54203f8204 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -659,7 +659,7 @@ class SeriesIndexEdit(make_undoable(QDoubleSpinBox), ToMetadataMixin): data_changed = pyqtSignal() def __init__(self, parent, series_edit): - super(SeriesIndexEdit, self).__init__(parent) + super().__init__(parent) self.valueChanged.connect(self.data_changed) self.dialog = parent self.db = self.original_series_name = None @@ -1195,7 +1195,7 @@ class Cover(ImageView): # {{{ try: with open(_file, "rb") as f: cover = f.read() - except IOError as e: + except OSError as e: d = error_dialog( self, _('Error reading file'), _("

There was an error reading from file:
") + _file + "


"+str(e)) @@ -1356,7 +1356,7 @@ class RatingEdit(RatingEditor, ToMetadataMixin): # {{{ data_changed = pyqtSignal() def __init__(self, parent): - super(RatingEdit, self).__init__(parent) + super().__init__(parent) self.setToolTip(self.TOOLTIP) self.setWhatsThis(self.TOOLTIP) self.currentTextChanged.connect(self.data_changed) @@ -1850,7 +1850,7 @@ class DateEdit(make_undoable(DateTimeEdit), ToMetadataMixin): data_changed = pyqtSignal() def __init__(self, parent, create_clear_button=True): - super(DateEdit, self).__init__(parent) + super().__init__(parent) self.setToolTip(self.TOOLTIP) self.setWhatsThis(self.TOOLTIP) self.dateTimeChanged.connect(self.data_changed) @@ -1902,7 +1902,7 @@ class DateEdit(make_undoable(DateTimeEdit), ToMetadataMixin): elif ev.key() == Qt.Key.Key_Tab and is_date_undefined(self.current_val): ev.ignore() else: - return super(DateEdit, self).keyPressEvent(ev) + return super().keyPressEvent(ev) class PubdateEdit(DateEdit): diff --git a/src/calibre/gui2/metadata/config.py b/src/calibre/gui2/metadata/config.py index 20f6b05d79..53a5f36b0d 100644 --- a/src/calibre/gui2/metadata/config.py +++ b/src/calibre/gui2/metadata/config.py @@ -43,7 +43,7 @@ class FieldsModel(FM): # {{{ def restore_defaults(self): self.beginResetModel() - self.overrides = dict([(f, self.state(f, True)) for f in self.fields]) + self.overrides = {f: self.state(f, True) for f in self.fields} self.endResetModel() def commit(self): @@ -112,7 +112,7 @@ class ConfigWidget(QWidget): items.sort(key=lambda k_v: sort_key(k_v[1])) for key, label in items: widget.addItem(label, (key)) - idx = widget.findData((val)) + idx = widget.findData(val) widget.setCurrentIndex(idx) widget.opt = opt widget.setToolTip(textwrap.fill(opt.desc)) diff --git a/src/calibre/gui2/metadata/diff.py b/src/calibre/gui2/metadata/diff.py index 86b8ddf03b..e819148813 100644 --- a/src/calibre/gui2/metadata/diff.py +++ b/src/calibre/gui2/metadata/diff.py @@ -392,7 +392,7 @@ class CoverView(QWidget): f = p.font() f.setBold(True) p.setFont(f) - sz = u'\u00a0%d x %d\u00a0'%(self.pixmap.width(), self.pixmap.height()) + sz = '\u00a0%d x %d\u00a0'%(self.pixmap.width(), self.pixmap.height()) flags = int(Qt.AlignmentFlag.AlignBottom|Qt.AlignmentFlag.AlignRight|Qt.TextFlag.TextSingleLine) szrect = p.boundingRect(sztgt, flags, sz) p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200)) @@ -705,7 +705,7 @@ class CompareMany(QDialog): def accept(self): gprefs.set('diff_dialog_geom', bytearray(self.saveGeometry())) self.compare_widget.save_comments_controls_state() - super(CompareMany, self).accept() + super().accept() def reject(self): if self.stack.currentIndex() == 1: @@ -717,7 +717,7 @@ class CompareMany(QDialog): return gprefs.set('diff_dialog_geom', bytearray(self.saveGeometry())) self.compare_widget.save_comments_controls_state() - super(CompareMany, self).reject() + super().reject() @property def current_mi(self): diff --git a/src/calibre/gui2/metadata/pdf_covers.py b/src/calibre/gui2/metadata/pdf_covers.py index 8399fcf9d8..93c875cb21 100644 --- a/src/calibre/gui2/metadata/pdf_covers.py +++ b/src/calibre/gui2/metadata/pdf_covers.py @@ -90,7 +90,7 @@ class PDFCovers(QDialog): def cleanup(self): try: shutil.rmtree(self.tdir) - except EnvironmentError: + except OSError: pass def render(self): diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index b68377324d..c232a52598 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -78,7 +78,7 @@ class MetadataSingleDialogBase(QDialog): QKeySequence.SequenceFormat.PortableText)) p = self.parent() if hasattr(p, 'keyboard'): - kname = u'Interface Action: Edit Metadata (Edit Metadata) : menu action : download' + kname = 'Interface Action: Edit Metadata (Edit Metadata) : menu action : download' sc = p.keyboard.keys_map.get(kname, None) if sc: self.download_shortcut.setKey(sc[0]) @@ -409,7 +409,7 @@ class MetadataSingleDialogBase(QDialog): def update_window_title(self, *args): title = self.title.current_val if len(title) > 50: - title = title[:50] + u'\u2026' + title = title[:50] + '\u2026' self.setWindowTitle(BASE_TITLE + ' - ' + title + ' - ' + _(' [%(num)d of %(tot)d]')%dict(num=self.current_row+1, @@ -452,7 +452,7 @@ class MetadataSingleDialogBase(QDialog): try: mi, ext = self.formats_manager.get_selected_format_metadata(self.db, self.book_id) - except (IOError, OSError) as err: + except OSError as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied import traceback fname = err.filename if err.filename else 'file' @@ -618,7 +618,7 @@ class MetadataSingleDialogBase(QDialog): return False widget.commit(self.db, self.book_id) self.books_to_refresh |= getattr(widget, 'books_to_refresh', set()) - except (IOError, OSError) as err: + except OSError as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied show_locked_file_error(self, err) return False diff --git a/src/calibre/gui2/metadata/single_download.py b/src/calibre/gui2/metadata/single_download.py index 7550b26700..00a4d54403 100644 --- a/src/calibre/gui2/metadata/single_download.py +++ b/src/calibre/gui2/metadata/single_download.py @@ -241,7 +241,7 @@ class ResultsView(QTableView): # {{{ self.resizeColumnsToContents() def resizeEvent(self, ev): - ret = super(ResultsView, self).resizeEvent(ev) + ret = super().resizeEvent(ev) self.resize_delegate() return ret diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py index ea557dcb51..77c02be1af 100644 --- a/src/calibre/gui2/preferences/coloring.py +++ b/src/calibre/gui2/preferences/coloring.py @@ -617,7 +617,7 @@ class RuleEditor(QDialog): # {{{ def remove_image(self, name): try: os.remove(os.path.join(self.icon_folder, name)) - except EnvironmentError: + except OSError: pass else: self.populate_icon_filenames() diff --git a/src/calibre/gui2/preferences/columns.py b/src/calibre/gui2/preferences/columns.py index 4f8f513ded..11bcb52605 100644 --- a/src/calibre/gui2/preferences/columns.py +++ b/src/calibre/gui2/preferences/columns.py @@ -141,7 +141,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): else: coltype = self.column_desc[dt] coltype_info = (coltype if oldkey is None else - ' ' + _('(lookup name was {0}) {1}'.format(oldkey, coltype))) + ' ' + _('(lookup name was {}) {}'.format(oldkey, coltype))) item = QTableWidgetItem(coltype_info) item.setFlags(flags) @@ -251,7 +251,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def col_pos(x): return config_cols.index(x) if x in config_cols else sys.maxsize positions = {} - for i, col in enumerate((sorted(model.column_map, key=col_pos))): + for i, col in enumerate(sorted(model.column_map, key=col_pos)): positions[col] = i state = {'hidden_columns': hidden_cols, 'column_positions':positions} self.gui.library_view.apply_state(state) diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py index e9d64ed72f..788bce125b 100644 --- a/src/calibre/gui2/preferences/metadata_sources.py +++ b/src/calibre/gui2/preferences/metadata_sources.py @@ -140,11 +140,11 @@ class SourcesModel(QAbstractTableModel): # {{{ def restore_defaults(self): self.beginResetModel() - self.enabled_overrides = dict([(p, (Qt.CheckState.Unchecked if p.name in - default_disabled_plugins else Qt.CheckState.Checked)) for p in self.plugins]) - self.cover_overrides = dict([(p, - msprefs.defaults['cover_priorities'].get(p.name, 1)) - for p in self.plugins]) + self.enabled_overrides = {p: (Qt.CheckState.Unchecked if p.name in + default_disabled_plugins else Qt.CheckState.Checked) for p in self.plugins} + self.cover_overrides = {p: + msprefs.defaults['cover_priorities'].get(p.name, 1) + for p in self.plugins} self.endResetModel() # }}} @@ -209,17 +209,17 @@ class FieldsModel(QAbstractListModel): # {{{ def restore_defaults(self): self.beginResetModel() - self.overrides = dict([(f, self.state(f, Qt.CheckState.Checked)) for f in self.fields]) + self.overrides = {f: self.state(f, Qt.CheckState.Checked) for f in self.fields} self.endResetModel() def select_all(self): self.beginResetModel() - self.overrides = dict([(f, Qt.CheckState.Checked) for f in self.fields]) + self.overrides = {f: Qt.CheckState.Checked for f in self.fields} self.endResetModel() def clear_all(self): self.beginResetModel() - self.overrides = dict([(f, Qt.CheckState.Unchecked) for f in self.fields]) + self.overrides = {f: Qt.CheckState.Unchecked for f in self.fields} self.endResetModel() def setData(self, index, val, role): @@ -248,7 +248,7 @@ class FieldsModel(QAbstractListModel): # {{{ def select_user_defaults(self): self.beginResetModel() - self.overrides = dict([(f, self.user_default_state(f)) for f in self.fields]) + self.overrides = {f: self.user_default_state(f) for f in self.fields} self.endResetModel() def commit_user_defaults(self): diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py index 2c7cfbf90d..1baefbc577 100644 --- a/src/calibre/gui2/preferences/plugins.py +++ b/src/calibre/gui2/preferences/plugins.py @@ -383,7 +383,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): elif op == 'remove': if not confirm('

' + _('Are you sure you want to remove the plugin: %s?')% - '{0}'.format(plugin.name), + '{}'.format(plugin.name), 'confirm_plugin_removal_msg', parent=self): return diff --git a/src/calibre/gui2/preferences/server.py b/src/calibre/gui2/preferences/server.py index 898b5edb1b..7a361f35fd 100644 --- a/src/calibre/gui2/preferences/server.py +++ b/src/calibre/gui2/preferences/server.py @@ -1001,7 +1001,7 @@ class CustomList(QWidget): # {{{ if template == self.default_template: try: os.remove(custom_list_template.path) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise else: @@ -1173,7 +1173,7 @@ class SearchTheInternet(QWidget): else: try: os.remove(search_the_net_urls.path) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise return True @@ -1324,7 +1324,7 @@ class ConfigWidget(ConfigWidgetBase): el.setPlainText( share_open(log_error_file, 'rb').read().decode('utf8', 'replace') ) - except EnvironmentError: + except OSError: el.setPlainText(_('No error log found')) layout.addWidget(QLabel(_('Access log:'))) al = QPlainTextEdit(d) @@ -1333,7 +1333,7 @@ class ConfigWidget(ConfigWidgetBase): al.setPlainText( share_open(log_access_file, 'rb').read().decode('utf8', 'replace') ) - except EnvironmentError: + except OSError: al.setPlainText(_('No access log found')) loc = QLabel(_('The server log files are in: {}').format(os.path.dirname(log_error_file))) loc.setWordWrap(True) @@ -1354,7 +1354,7 @@ class ConfigWidget(ConfigWidgetBase): for x in (log_error_file, log_access_file): try: os.remove(x) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise el.setPlainText(''), al.setPlainText('') diff --git a/src/calibre/gui2/preferences/template_functions.py b/src/calibre/gui2/preferences/template_functions.py index 5513b44d5c..7532c7e83d 100644 --- a/src/calibre/gui2/preferences/template_functions.py +++ b/src/calibre/gui2/preferences/template_functions.py @@ -145,8 +145,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): traceback.print_exc() self.builtin_source_dict = {} - self.funcs = dict((k,v) for k,v in formatter_functions().get_functions().items() - if v.is_python) + self.funcs = {k:v for k,v in formatter_functions().get_functions().items() + if v.is_python} self.builtins = formatter_functions().get_builtins_and_aliases() diff --git a/src/calibre/gui2/qt_file_dialogs.py b/src/calibre/gui2/qt_file_dialogs.py index 1506111881..6026fcb1a0 100644 --- a/src/calibre/gui2/qt_file_dialogs.py +++ b/src/calibre/gui2/qt_file_dialogs.py @@ -20,7 +20,7 @@ def select_initial_dir(q): if os.path.exists(c): return c q = c - return os.path.expanduser(u'~') + return os.path.expanduser('~') class Dummy: @@ -42,7 +42,7 @@ class FileDialog(QObject): modal=True, name='', mode=QFileDialog.FileMode.ExistingFiles, - default_dir=u'~', + default_dir='~', no_save_dir=False, combine_file_and_saved_dir=False ): @@ -74,12 +74,12 @@ class FileDialog(QObject): if combine_file_and_saved_dir: bn = os.path.basename(default_dir) prev = dynamic.get(self.dialog_name, - os.path.expanduser(u'~')) + os.path.expanduser('~')) if os.path.exists(prev): if os.path.isfile(prev): prev = os.path.dirname(prev) else: - prev = os.path.expanduser(u'~') + prev = os.path.expanduser('~') initial_dir = os.path.join(prev, bn) elif no_save_dir: initial_dir = os.path.expanduser(default_dir) @@ -159,7 +159,7 @@ def choose_dir(window, name, title, default_dir='~', no_save_dir=False): def choose_files(window, name, title, - filters=[], all_files=True, select_only_single_file=False, default_dir=u'~'): + filters=[], all_files=True, select_only_single_file=False, default_dir='~'): ''' Ask user to choose a bunch of files. :param name: Unique dialog name used to store the opened directory diff --git a/src/calibre/gui2/save.py b/src/calibre/gui2/save.py index 33f2d0f1f1..18c7c15f15 100644 --- a/src/calibre/gui2/save.py +++ b/src/calibre/gui2/save.py @@ -214,7 +214,7 @@ class Saver(QObject): if os.path.dirname(base_dir) != base_dir: try: os.makedirs(base_dir) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise diff --git a/src/calibre/gui2/search_box.py b/src/calibre/gui2/search_box.py index 88c7f7dd38..e1388191e2 100644 --- a/src/calibre/gui2/search_box.py +++ b/src/calibre/gui2/search_box.py @@ -384,7 +384,7 @@ class SavedSearchBox(QComboBox): # {{{ self.search_box.clear() self.setEditText(qname) return - self.search_box.set_search_string(u'search:"%s"' % qname, emit_changed=False) + self.search_box.set_search_string('search:"%s"' % qname, emit_changed=False) self.setEditText(qname) self.setToolTip(db.saved_search_lookup(qname)) diff --git a/src/calibre/gui2/search_restriction_mixin.py b/src/calibre/gui2/search_restriction_mixin.py index 0b72679efc..785d6310f0 100644 --- a/src/calibre/gui2/search_restriction_mixin.py +++ b/src/calibre/gui2/search_restriction_mixin.py @@ -655,7 +655,7 @@ class SearchRestrictionMixin: db.data.get_search_restriction_name()) if x] t = ' :: '.join(restrictions) if len(t) > 20: - t = t[:19] + u'…' + t = t[:19] + '…' self.clear_vl.setVisible(True) self.clear_vl.setVisible(not gprefs['show_vl_tabs']) else: # No restriction or not library view diff --git a/src/calibre/gui2/store/loader.py b/src/calibre/gui2/store/loader.py index 09e2740bd0..2b01dc5405 100644 --- a/src/calibre/gui2/store/loader.py +++ b/src/calibre/gui2/store/loader.py @@ -40,7 +40,7 @@ def download_updates(ver_map={}, server='https://code.calibre-ebook.com'): name = name.decode('utf-8') d = decompressobj() src = d.decompress(raw) - src = src.decode('utf-8').lstrip(u'\ufeff') + src = src.decode('utf-8').lstrip('\ufeff') # Python complains if there is a coding declaration in a unicode string src = re.sub(r'^#.*coding\s*[:=]\s*([-\w.]+)', '#', src, flags=re.MULTILINE) # Translate newlines to \n @@ -130,8 +130,7 @@ class Stores(OrderedDict): import traceback traceback.print_exc() else: - for name, code in updates: - yield name, code + yield from updates def do_update(self): replacements = {} diff --git a/src/calibre/gui2/store/opensearch_store.py b/src/calibre/gui2/store/opensearch_store.py index 630b70bc83..24dbcc51ad 100644 --- a/src/calibre/gui2/store/opensearch_store.py +++ b/src/calibre/gui2/store/opensearch_store.py @@ -101,5 +101,4 @@ class OpenSearchOPDSStore(StorePlugin): def search(self, query, max_results=10, timeout=60): if not getattr(self, 'open_search_url', None): return - for result in open_search(self.open_search_url, query, max_results=max_results, timeout=timeout): - yield result + yield from open_search(self.open_search_url, query, max_results=max_results, timeout=timeout) diff --git a/src/calibre/gui2/store/search/models.py b/src/calibre/gui2/store/search/models.py index 23aed7f9a8..7e4cbc8fec 100644 --- a/src/calibre/gui2/store/search/models.py +++ b/src/calibre/gui2/store/search/models.py @@ -29,7 +29,7 @@ def comparable_price(text): # remove all separators accept fraction, # leave only 2 digits in fraction m = re.sub(r'\.(?!\d*$)', r'', m) - text = '{0:0>8.0f}'.format(float(m) * 100.) + text = '{:0>8.0f}'.format(float(m) * 100.) return text diff --git a/src/calibre/gui2/store/search/search.py b/src/calibre/gui2/store/search/search.py index 4a480322ec..20a013ba18 100644 --- a/src/calibre/gui2/store/search/search.py +++ b/src/calibre/gui2/store/search/search.py @@ -185,9 +185,9 @@ class SearchDialog(QDialog, Ui_Dialog): # Don't start a search if there is nothing to search for. query = [] if self.search_title.text(): - query.append(u'title2:"~%s"' % str(self.search_title.text()).replace('"', ' ')) + query.append('title2:"~%s"' % str(self.search_title.text()).replace('"', ' ')) if self.search_author.text(): - query.append(u'author2:"%s"' % str(self.search_author.text()).replace('"', ' ')) + query.append('author2:"%s"' % str(self.search_author.text()).replace('"', ' ')) if self.search_edit.text(): query.append(str(self.search_edit.text())) query = " ".join(query) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index 35b6283d16..210331f707 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -432,7 +432,7 @@ class TagsModel(QAbstractItemModel): # {{{ for i, key in enumerate(self.categories): is_gst = False if key.startswith('@') and key[1:] in gst: - tt = _(u'The grouped search term name is "{0}"').format(key) + tt = _('The grouped search term name is "{0}"').format(key) is_gst = True elif key == 'news': tt = '' @@ -443,7 +443,7 @@ class TagsModel(QAbstractItemModel): # {{{ cust_desc = fm['display'].get('description', '') if cust_desc: cust_desc = '\n' + _('Description:') + ' ' + cust_desc - tt = _(u'The lookup/search name is "{0}"{1}').format(key, cust_desc) + tt = _('The lookup/search name is "{0}"{1}').format(key, cust_desc) if self.category_custom_icons.get(key, None) is None: self.category_custom_icons[key] = QIcon(I( @@ -609,7 +609,7 @@ class TagsModel(QAbstractItemModel): # {{{ if first_chr == last_chr: cl_list[cur_idx] = first_chr else: - cl_list[cur_idx] = '{0} - {1}'.format(first_chr, last_chr) + cl_list[cur_idx] = '{} - {}'.format(first_chr, last_chr) cur_idx += 1 top_level_component = 'z' + data[key][0].original_name @@ -706,9 +706,9 @@ class TagsModel(QAbstractItemModel): # {{{ child_map = category_child_map top_level_component = comp else: - child_map = dict([((t.tag.name, t.tag.category), t) + child_map = {(t.tag.name, t.tag.category): t for t in node_parent.children - if t.type != TagTreeItem.CATEGORY]) + if t.type != TagTreeItem.CATEGORY} if (comp,tag.category) in child_map: node_parent = child_map[(comp,tag.category)] t = node_parent.tag @@ -993,8 +993,8 @@ class TagsModel(QAbstractItemModel): # {{{ fm_src = self.db.metadata_for_field(md.column_name) if md.column_name in ['authors', 'publisher', 'series'] or \ (fm_src['is_custom'] and ( - (fm_src['datatype'] in ['series', 'text', 'enumeration'] and - not fm_src['is_multiple']))or + fm_src['datatype'] in ['series', 'text', 'enumeration'] and + not fm_src['is_multiple'])or (fm_src['datatype'] == 'composite' and fm_src['display'].get('make_category', False))): mime = 'application/calibre+from_library' diff --git a/src/calibre/gui2/toc/location.py b/src/calibre/gui2/toc/location.py index 1cfcb564c6..a8076443d8 100644 --- a/src/calibre/gui2/toc/location.py +++ b/src/calibre/gui2/toc/location.py @@ -80,7 +80,7 @@ class Page(QWebEnginePage): # {{{ if ok and self.current_frag: self.runJavaScript(''' document.location = '#non-existent-anchor'; - document.location = '#' + {0}; + document.location = '#' + {}; '''.format(json.dumps(self.current_frag))) self.current_frag = None self.runJavaScript('window.pageYOffset/document.body.scrollHeight', QWebEngineScript.ScriptWorldId.ApplicationWorld, self.frag_shown.emit) @@ -206,7 +206,7 @@ class ItemEdit(QWidget): # Prevent pressing enter in the search box from triggering the dialog's accept() method ev.accept() return - return super(ItemEdit, self).keyPressEvent(ev) + return super().keyPressEvent(ev) def find(self, forwards=True): text = str(self.search_text.text()).strip() diff --git a/src/calibre/gui2/toc/main.py b/src/calibre/gui2/toc/main.py index c0837a84b5..55b4d7d348 100644 --- a/src/calibre/gui2/toc/main.py +++ b/src/calibre/gui2/toc/main.py @@ -127,7 +127,7 @@ class XPathDialog(QDialog): # {{{ def accept(self): if self.check(): self.prefs.set('xpath_toc_remove_duplicates', self.remove_duplicates_cb.isChecked()) - super(XPathDialog, self).accept() + super().accept() @property def xpaths(self): @@ -423,8 +423,7 @@ class TreeWidget(QTreeWidget): # {{{ for i in range(parent.childCount()): child = parent.child(i) yield child - for gc in self.iter_items(parent=child): - yield gc + yield from self.iter_items(parent=child) def update_status_tip(self, item): c = item.data(0, Qt.ItemDataRole.UserRole) @@ -475,12 +474,12 @@ class TreeWidget(QTreeWidget): # {{{ self.in_drop_event = True self.push_history() try: - super(TreeWidget, self).dropEvent(event) + super().dropEvent(event) finally: self.in_drop_event = False def selectedIndexes(self): - ans = super(TreeWidget, self).selectedIndexes() + ans = super().selectedIndexes() if self.in_drop_event: # For order to be be preserved when moving by drag and drop, we # have to ensure that selectedIndexes returns an ordered list of @@ -658,7 +657,7 @@ class TreeWidget(QTreeWidget): # {{{ self.del_items() ev.accept() else: - return super(TreeWidget, self).keyPressEvent(ev) + return super().keyPressEvent(ev) def show_context_menu(self, point): item = self.currentItem() @@ -776,7 +775,7 @@ class TOCView(QWidget): # {{{ if e.type() == QEvent.Type.StatusTip: txt = str(e.tip()) or self.default_msg self.hl.setText(txt) - return super(TOCView, self).event(e) + return super().event(e) def item_title(self, item): return str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') @@ -792,8 +791,7 @@ class TOCView(QWidget): # {{{ p.removeChild(item) def iter_items(self, parent=None): - for item in self.tocw.iter_items(parent=parent): - yield item + yield from self.tocw.iter_items(parent=parent) def flatten_toc(self): self.tocw.push_history() @@ -1075,10 +1073,10 @@ class TOCEditor(QDialog): # {{{ error_dialog(self, _('Failed to write book'), _('Could not write %s. Click "Show details" for' ' more information.')%self.book_title, det_msg=tb, show=True) - super(TOCEditor, self).reject() + super().reject() return self.write_result(0) - super(TOCEditor, self).accept() + super().accept() def reject(self): if not self.bb.isEnabled(): @@ -1093,7 +1091,7 @@ class TOCEditor(QDialog): # {{{ self.working = False self.prefs['toc_editor_window_geom'] = bytearray(self.saveGeometry()) self.write_result(1) - super(TOCEditor, self).reject() + super().reject() def write_result(self, res): if self.write_result_to: diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index 24eba47f55..8992901a44 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -1443,7 +1443,7 @@ class Boss(QObject): if '/' in name or os.sep in name: try: os.makedirs(os.path.dirname(dest)) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise self.export_file(name, dest) diff --git a/src/calibre/gui2/tweak_book/check.py b/src/calibre/gui2/tweak_book/check.py index 887135c319..eef84f7768 100644 --- a/src/calibre/gui2/tweak_book/check.py +++ b/src/calibre/gui2/tweak_book/check.py @@ -48,7 +48,7 @@ def prefix_for_level(level): class Delegate(QStyledItemDelegate): def initStyleOption(self, option, index): - super(Delegate, self).initStyleOption(option, index) + super().initStyleOption(option, index) if index.row() == self.parent().currentRow(): option.font.setBold(True) option.backgroundBrush = self.parent().palette().brush(QPalette.ColorRole.AlternateBase) @@ -244,7 +244,7 @@ class Check(QSplitter): def keyPressEvent(self, ev): if ev.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return): self.current_item_activated() - return super(Check, self).keyPressEvent(ev) + return super().keyPressEvent(ev) def clear(self): self.items.clear() diff --git a/src/calibre/gui2/tweak_book/completion/__init__.py b/src/calibre/gui2/tweak_book/completion/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/gui2/tweak_book/completion/__init__.py +++ b/src/calibre/gui2/tweak_book/completion/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/gui2/tweak_book/editor/help.py b/src/calibre/gui2/tweak_book/editor/help.py index 7176639914..a6bf310d01 100644 --- a/src/calibre/gui2/tweak_book/editor/help.py +++ b/src/calibre/gui2/tweak_book/editor/help.py @@ -26,7 +26,7 @@ class URLMap: except KeyError: try: self.cache[key] = ans = json.loads(P('editor-help/%s.json' % key, data=True)) - except EnvironmentError: + except OSError: raise KeyError('The mapping %s is not available' % key) return ans diff --git a/src/calibre/gui2/tweak_book/editor/image.py b/src/calibre/gui2/tweak_book/editor/image.py index f5e704a29c..4fad515d40 100644 --- a/src/calibre/gui2/tweak_book/editor/image.py +++ b/src/calibre/gui2/tweak_book/editor/image.py @@ -232,7 +232,7 @@ class Editor(QMainWindow): self.modification_state_changed.emit(True) self.fmt_label.setText(' ' + (self.canvas.original_image_format or '').upper()) im = self.canvas.current_image - self.size_label.setText('{0} x {1}{2}'.format(im.width(), im.height(), ' px')) + self.size_label.setText('{} x {}{}'.format(im.width(), im.height(), ' px')) def break_cycles(self): self.canvas.break_cycles() diff --git a/src/calibre/gui2/tweak_book/editor/insert_resource.py b/src/calibre/gui2/tweak_book/editor/insert_resource.py index d03f3234c7..2c6762d425 100644 --- a/src/calibre/gui2/tweak_book/editor/insert_resource.py +++ b/src/calibre/gui2/tweak_book/editor/insert_resource.py @@ -67,7 +67,7 @@ class ChooseName(Dialog): # {{{ n = str(self.name_edit.text()).replace('\\', '/') name, ext = n.rpartition('.')[0::2] self.filename = name + '.' + ext.lower() - super(ChooseName, self).accept() + super().accept() # }}} # Images {{{ @@ -78,7 +78,7 @@ class ImageDelegate(QStyledItemDelegate): MARGIN = 4 def __init__(self, parent): - super(ImageDelegate, self).__init__(parent) + super().__init__(parent) self.current_basic_size = tprefs.get('image-thumbnail-preview-size', [120, 160]) self.set_dimensions() @@ -343,7 +343,7 @@ class InsertImage(Dialog): def accept(self): self.chosen_image = str(self.view.currentIndex().data() or '') - super(InsertImage, self).accept() + super().accept() def filter_changed(self, *args): f = str(self.filter.text()) @@ -478,7 +478,7 @@ class NewBook(Dialog): # {{{ tprefs.set('previous_new_book_authors', str(self.authors.text())) tprefs.set('previous_new_book_lang', (self.languages.lang_codes or [get_lang()])[0]) self.languages.update_recently_used() - super(NewBook, self).accept() + super().accept() @property def mi(self): diff --git a/src/calibre/gui2/tweak_book/editor/smarts/html.py b/src/calibre/gui2/tweak_book/editor/smarts/html.py index b344025b99..0be8661bf1 100644 --- a/src/calibre/gui2/tweak_book/editor/smarts/html.py +++ b/src/calibre/gui2/tweak_book/editor/smarts/html.py @@ -502,7 +502,7 @@ class Smarts(NullSmarts): pos = min(c.position(), c.anchor()) m = re.match(r'[a-zA-Z0-9:-]+', name) cname = name if m is None else m.group() - c.insertText('<{0}>{1}'.format(name, text, cname)) + c.insertText('<{}>{}'.format(name, text, cname)) c.setPosition(pos + 2 + len(name)) editor.setTextCursor(c) diff --git a/src/calibre/gui2/tweak_book/editor/syntax/javascript.py b/src/calibre/gui2/tweak_book/editor/syntax/javascript.py index 0581678825..96fd34f362 100644 --- a/src/calibre/gui2/tweak_book/editor/syntax/javascript.py +++ b/src/calibre/gui2/tweak_book/editor/syntax/javascript.py @@ -18,7 +18,7 @@ JS_IDENT_START = ('(?:[$_' + uni.combine('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl') + ']|\\\\u[a-fA-F0-9]{4})') JS_IDENT_PART = ('(?:[$' + uni.combine('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl', 'Mn', 'Mc', 'Nd', 'Pc') + - u'\u200c\u200d]|\\\\u[a-fA-F0-9]{4})') + '\u200c\u200d]|\\\\u[a-fA-F0-9]{4})') JS_IDENT = JS_IDENT_START + '(?:' + JS_IDENT_PART + ')*' diff --git a/src/calibre/gui2/tweak_book/editor/syntax/pygments_highlighter.py b/src/calibre/gui2/tweak_book/editor/syntax/pygments_highlighter.py index 3f1b884543..e263f8ab36 100644 --- a/src/calibre/gui2/tweak_book/editor/syntax/pygments_highlighter.py +++ b/src/calibre/gui2/tweak_book/editor/syntax/pygments_highlighter.py @@ -35,8 +35,7 @@ def create_lexer(base_class): if type(action) is _TokenType: yield pos, action, m.group() else: - for item in action(self, m): - yield item + yield from action(self, m) pos = m.end() if new_state is not None: # state transition diff --git a/src/calibre/gui2/tweak_book/editor/text.py b/src/calibre/gui2/tweak_book/editor/text.py index 53249cce65..0e9bac6920 100644 --- a/src/calibre/gui2/tweak_book/editor/text.py +++ b/src/calibre/gui2/tweak_book/editor/text.py @@ -908,7 +908,7 @@ version="1.1" width="100%%" height="100%%" viewBox="0 0 {w} {h}" preserveAspectR

'''.format(w=width, h=height, a='xMidYMid meet' if preserve_aspect_ratio else 'none') else: alt = _('Image') - template = '{0}'.format(alt) + template = '{}'.format(alt) text = template % href c.insertText(text) if self.syntax == 'html' and not fullpage: diff --git a/src/calibre/gui2/tweak_book/editor/themes.py b/src/calibre/gui2/tweak_book/editor/themes.py index 5f79118732..0cf752f088 100644 --- a/src/calibre/gui2/tweak_book/editor/themes.py +++ b/src/calibre/gui2/tweak_book/editor/themes.py @@ -590,11 +590,11 @@ class ThemeEditor(Dialog): from calibre.gui2.tweak_book.editor.text import TextEdit self.preview = p = TextEdit(self, expected_geometry=(73, 50)) p.load_text(HELP_TEXT.format( - *['%s' % x for x in ( + *('%s' % x for x in ( 'Normal', 'Visual', 'CursorLine', 'LineNr', 'MatchParen', 'Function', 'Type', 'Statement', 'Constant', 'SpecialCharacter', 'Error', 'SpellError', 'Comment' - )] + )) )) p.setMaximumWidth(p.size_hint.width() + 5) s.setMinimumWidth(600) diff --git a/src/calibre/gui2/tweak_book/file_list.py b/src/calibre/gui2/tweak_book/file_list.py index e69b7fc00e..cff4731669 100644 --- a/src/calibre/gui2/tweak_book/file_list.py +++ b/src/calibre/gui2/tweak_book/file_list.py @@ -114,7 +114,7 @@ def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_na fmt = '%d' if leading_zeros: largest = num + number - 1 - fmt = '%0{0}d'.format(len(str(largest))) + fmt = '%0{}d'.format(len(str(largest))) ans['prefix'] = prefix + fmt ans['start'] = num if allow_spine_order: @@ -818,7 +818,7 @@ class FileList(QTreeWidget, OpenWithHandler): with self: text = self.categories['text'] pre_drop_order = {text.child(i).data(0, NAME_ROLE):i for i in range(text.childCount())} - super(FileList, self).dropEvent(event) + super().dropEvent(event) current_order = {text.child(i).data(0, NAME_ROLE):i for i in range(text.childCount())} if current_order != pre_drop_order: order = [] diff --git a/src/calibre/gui2/tweak_book/preferences.py b/src/calibre/gui2/tweak_book/preferences.py index 921b267c58..153f33ed95 100644 --- a/src/calibre/gui2/tweak_book/preferences.py +++ b/src/calibre/gui2/tweak_book/preferences.py @@ -682,8 +682,8 @@ class TemplatesDialog(Dialog): # {{{ self.helpl = la = QLabel(_( 'The variables {0} and {1} will be replaced with the title and author of the book. {2}' ' is where the cursor will be positioned. If you want to include braces in your template,' - ' for example for CSS rules, you have to escape them, like this: {3}').format(*['%s'%x for x in - ['{TITLE}', '{AUTHOR}', '%CURSOR%', 'body {{ color: red }}']])) + ' for example for CSS rules, you have to escape them, like this: {3}').format(*('%s'%x for x in + ['{TITLE}', '{AUTHOR}', '%CURSOR%', 'body {{ color: red }}']))) la.setWordWrap(True) l.addWidget(la) diff --git a/src/calibre/gui2/tweak_book/save.py b/src/calibre/gui2/tweak_book/save.py index 323af2bd3b..b0c55d3871 100644 --- a/src/calibre/gui2/tweak_book/save.py +++ b/src/calibre/gui2/tweak_book/save.py @@ -37,28 +37,28 @@ def save_container(container, path): st = None try: st = os.stat(path) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise # path may not exist if we are saving a copy, in which case we use # the metadata from the original book try: st = os.stat(container.path_to_ebook) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise # Somebody deleted the original file if st is not None: try: os.fchmod(fno, st.st_mode) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EPERM: raise - raise EnvironmentError('Failed to change permissions of %s to %s (%s), with error: %s. Most likely the %s directory has a restrictive umask' % ( + raise OSError('Failed to change permissions of %s to %s (%s), with error: %s. Most likely the %s directory has a restrictive umask' % ( temp.name, oct(st.st_mode), format_permissions(st.st_mode), errno.errorcode[err.errno], os.path.dirname(temp.name))) try: os.fchown(fno, st.st_uid, st.st_gid) - except EnvironmentError as err: + except OSError as err: if err.errno not in (errno.EPERM, errno.EACCES): # ignore chown failure as user could be editing file belonging # to a different user, in which case we really can't do anything diff --git a/src/calibre/gui2/tweak_book/spell.py b/src/calibre/gui2/tweak_book/spell.py index f4400bbab6..fcb39a5548 100644 --- a/src/calibre/gui2/tweak_book/spell.py +++ b/src/calibre/gui2/tweak_book/spell.py @@ -577,9 +577,9 @@ class ManageDictionaries(Dialog): # {{{ saf = self.fb font = item.data(0, Qt.ItemDataRole.FontRole) preferred = bool(font and font.italic()) - saf.setText((_( + saf.setText(_( 'This is already the preferred dictionary') if preferred else - _('Use this as the preferred dictionary'))) + _('Use this as the preferred dictionary')) saf.setEnabled(not preferred) self.remove_dictionary_button.setEnabled(not item.data(0, Qt.ItemDataRole.UserRole).builtin) diff --git a/src/calibre/gui2/tweak_book/toc.py b/src/calibre/gui2/tweak_book/toc.py index 5f724b8502..61dcd6048e 100644 --- a/src/calibre/gui2/tweak_book/toc.py +++ b/src/calibre/gui2/tweak_book/toc.py @@ -75,7 +75,7 @@ class TOCEditor(QDialog): elif self.stacks.currentIndex() == 0: self.write_toc() tprefs['toc_editor_window_geom'] = bytearray(self.saveGeometry()) - super(TOCEditor, self).accept() + super().accept() def really_accept(self, tb): tprefs['toc_editor_window_geom'] = bytearray(self.saveGeometry()) @@ -83,10 +83,10 @@ class TOCEditor(QDialog): error_dialog(self, _('Failed to write book'), _('Could not write %s. Click "Show details" for' ' more information.')%self.book_title, det_msg=tb, show=True) - super(TOCEditor, self).reject() + super().reject() return - super(TOCEditor, self).accept() + super().accept() def reject(self): if not self.bb.isEnabled(): @@ -99,7 +99,7 @@ class TOCEditor(QDialog): self.stacks.setCurrentIndex(0) else: tprefs['toc_editor_window_geom'] = bytearray(self.saveGeometry()) - super(TOCEditor, self).reject() + super().reject() def read_toc(self): self.toc_view(current_container()) @@ -192,8 +192,7 @@ class TOCViewer(QWidget): for i in range(parent.childCount()): child = parent.child(i) yield child - for gc in self.iter_items(parent=child): - yield gc + yield from self.iter_items(parent=child) def emit_navigate(self, *args): item = self.view.currentItem() @@ -229,7 +228,7 @@ class TOCViewer(QWidget): def showEvent(self, ev): if self.toc_name is None or not ev.spontaneous(): self.build() - return super(TOCViewer, self).showEvent(ev) + return super().showEvent(ev) def update_if_visible(self): if self.isVisible(): diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index a94c5ee05d..a1dff8a4dc 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -203,7 +203,7 @@ class Central(QStackedWidget): # {{{ self.search_panel.pre_fill(text) def eventFilter(self, obj, event): - base = super(Central, self) + base = super() if obj is not self.editor_tabs.tabBar() or event.type() != QEvent.Type.MouseButtonPress or event.button() not in ( Qt.MouseButton.RightButton, Qt.MouseButton.MidButton): return base.eventFilter(obj, event) @@ -870,7 +870,7 @@ class Main(MainWindow): def resizeEvent(self, ev): self.blocking_job.resize(ev.size()) - return super(Main, self).resizeEvent(ev) + return super().resizeEvent(ev) def update_window_title(self): cc = current_container() diff --git a/src/calibre/gui2/tweak_book/widgets.py b/src/calibre/gui2/tweak_book/widgets.py index 037a20e6d1..28a578bcd6 100644 --- a/src/calibre/gui2/tweak_book/widgets.py +++ b/src/calibre/gui2/tweak_book/widgets.py @@ -347,7 +347,7 @@ class Results(QWidget): self.current_result = 0 prefixes = [QStaticText('%s' % os.path.basename(x)) for x in results] [(p.setTextFormat(Qt.TextFormat.RichText), p.setTextOption(self.text_option)) for p in prefixes] - self.maxwidth = max([x.size().width() for x in prefixes]) + self.maxwidth = max(x.size().width() for x in prefixes) self.results = tuple((prefix, self.make_text(text, positions), text) for prefix, (text, positions) in zip(prefixes, iteritems(results))) else: @@ -1165,7 +1165,7 @@ class AddCover(Dialog): if name is not None: data = self.container.raw_data(name, decode=False) self.cover_view.set_pixmap(data) - self.info_label.setText('{0}x{1}px | {2}'.format( + self.info_label.setText('{}x{}px | {}'.format( self.cover_view.pixmap.width(), self.cover_view.pixmap.height(), human_readable(len(data)))) def import_image(self): diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index a7f0aad624..1d55ce1d02 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -80,7 +80,7 @@ def add_quick_start_guide(library_view, refresh_cover_browser=None): try: with lopen(P('quick_start/%s.epub' % l), 'rb') as src: buf = BytesIO(src.read()) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise with lopen(P('quick_start/eng.epub'), 'rb') as src: @@ -493,7 +493,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ if os.path.exists(os.path.join(config_dir, 'server.py')): try: os.remove(os.path.join(config_dir, 'server.py')) - except EnvironmentError: + except OSError: pass warning_dialog(self, _('Content server changed!'), _( 'calibre 3 comes with a completely re-written Content server.' @@ -920,7 +920,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ font.setBold(True) font.setItalic(True) self.virtual_library.setFont(font) - title = '{0} — || {1}{2} ||'.format( + title = '{} — || {}{} ||'.format( __appname__, self.iactions['Choose Library'].library_name(), restrictions) self.setWindowTitle(title) diff --git a/src/calibre/gui2/update.py b/src/calibre/gui2/update.py index b673f25508..6c3c442f09 100644 --- a/src/calibre/gui2/update.py +++ b/src/calibre/gui2/update.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -138,11 +136,11 @@ class UpdateNotification(QDialog): ver = calibre_version if ver.endswith('.0'): ver = ver[:-2] - self.label = QLabel(('

'+ _( + self.label = QLabel('

'+ _( 'New version {ver} of {app} is available for download. ' 'See the new features.').format( url=localize_website_link('https://calibre-ebook.com/whats-new'), - app=__appname__, ver=ver))) + app=__appname__, ver=ver)) self.label.setOpenExternalLinks(True) self.label.setWordWrap(True) self.setWindowTitle(_('Update available!')) diff --git a/src/calibre/gui2/viewer/annotations.py b/src/calibre/gui2/viewer/annotations.py index 8daddbc87e..da47e7af6c 100644 --- a/src/calibre/gui2/viewer/annotations.py +++ b/src/calibre/gui2/viewer/annotations.py @@ -48,7 +48,7 @@ def split_lines(chunk, length=80): def save_annots_to_epub(path, serialized_annots): try: zf = open(path, 'r+b') - except IOError: + except OSError: return with zf: serialized_annots = EPUB_FILE_TYPE_MAGIC + b'\n'.join(split_lines(as_base64_bytes(serialized_annots))) diff --git a/src/calibre/gui2/viewer/convert_book.py b/src/calibre/gui2/viewer/convert_book.py index 996a105469..cff4a7cbec 100644 --- a/src/calibre/gui2/viewer/convert_book.py +++ b/src/calibre/gui2/viewer/convert_book.py @@ -46,7 +46,7 @@ def book_hash(path, size, mtime): def safe_makedirs(path): try: os.makedirs(path) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise return path @@ -61,7 +61,7 @@ def robust_rmtree(x): except UnicodeDecodeError: rmtree(as_bytes(x)) return True - except EnvironmentError: + except OSError: time.sleep(0.1) return False @@ -72,7 +72,7 @@ def robust_rename(a, b): try: os.rename(a, b) return True - except EnvironmentError: + except OSError: time.sleep(0.1) return False diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index bfdd9c3ac9..16c97cbf98 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -188,7 +188,7 @@ def main(args=sys.argv): finally: try: os.remove(internal_book_data_path) - except EnvironmentError: + except OSError: pass args = processed_args app = Application(args, override_program_name=override, windows_app_uid=VIEWER_APP_UID) diff --git a/src/calibre/gui2/viewer/printing.py b/src/calibre/gui2/viewer/printing.py index 98d41564df..8ed366cf26 100644 --- a/src/calibre/gui2/viewer/printing.py +++ b/src/calibre/gui2/viewer/printing.py @@ -156,7 +156,7 @@ class DoPrint(Thread): self.log = f.read().decode('utf-8', 'replace') try: os.remove(f.name) - except EnvironmentError: + except OSError: pass except Exception: import traceback @@ -215,7 +215,7 @@ class Printing(QProgressDialog): try: if self.thread.worker.poll() is None: self.thread.worker.kill() - except EnvironmentError: + except OSError: import traceback traceback.print_exc() self.timer.stop() diff --git a/src/calibre/gui2/viewer/search.py b/src/calibre/gui2/viewer/search.py index 0a449da0f5..99662af029 100644 --- a/src/calibre/gui2/viewer/search.py +++ b/src/calibre/gui2/viewer/search.py @@ -359,12 +359,12 @@ class SearchInput(QWidget): # {{{ qt.addItem(_('Contains'), 'normal') qt.addItem(_('Whole words'), 'word') qt.addItem(_('Regex'), 'regex') - qt.setToolTip(('

' + _( + qt.setToolTip('

' + _( 'Choose the type of search:

    ' '
  • Contains will search for the entered text anywhere.' '
  • Whole words will search for whole words that equal the entered text.' '
  • Regex will interpret the text as a regular expression.' - ))) + )) qt.setCurrentIndex(qt.findData(vprefs.get('viewer-{}-mode'.format(self.panel_name), 'normal') or 'normal')) qt.currentIndexChanged.connect(self.save_search_type) h.addWidget(qt) diff --git a/src/calibre/gui2/viewer/ui.py b/src/calibre/gui2/viewer/ui.py index ef89e26358..fb9aeb8d83 100644 --- a/src/calibre/gui2/viewer/ui.py +++ b/src/calibre/gui2/viewer/ui.py @@ -106,7 +106,7 @@ class EbookViewer(MainWindow): self.addToolBar(Qt.ToolBarArea.LeftToolBarArea, at) try: os.makedirs(annotations_dir) - except EnvironmentError: + except OSError: pass self.current_book_data = {} get_current_book_data(self.current_book_data) diff --git a/src/calibre/gui2/viewer/web_view.py b/src/calibre/gui2/viewer/web_view.py index 2f6e741376..719514882b 100644 --- a/src/calibre/gui2/viewer/web_view.py +++ b/src/calibre/gui2/viewer/web_view.py @@ -75,7 +75,7 @@ def get_data(name): try: with share_open(path, 'rb') as f: return f.read(), guess_type(name) - except EnvironmentError as err: + except OSError as err: prints('Failed to read from book file: {} with error: {}'.format(name, as_unicode(err))) return None, None @@ -122,7 +122,7 @@ def handle_mathjax_request(rq, name): try: with lopen(path, 'rb') as f: raw = f.read() - except EnvironmentError as err: + except OSError as err: prints("Failed to get mathjax file: {} with error: {}".format(name, err), file=sys.stderr) rq.fail(QWebEngineUrlRequestJob.Error.RequestFailed) return @@ -366,7 +366,7 @@ class WebPage(QWebEnginePage): prints('%s: %s:%s: %s' % (prefix, source_id, linenumber, msg), file=sys.stderr) try: sys.stderr.flush() - except EnvironmentError: + except OSError: pass def acceptNavigationRequest(self, url, req_type, is_main_frame): diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index 26076f1595..102069751c 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' ''' @@ -835,7 +833,7 @@ class PythonHighlighter(QSyntaxHighlighter): # {{{ CONSTANTS = ["False", "True", "None", "NotImplemented", "Ellipsis"] def __init__(self, parent=None): - super(PythonHighlighter, self).__init__(parent) + super().__init__(parent) self.initializeFormats() diff --git a/src/calibre/gui2/widgets2.py b/src/calibre/gui2/widgets2.py index d56c25d3b2..e2cf387760 100644 --- a/src/calibre/gui2/widgets2.py +++ b/src/calibre/gui2/widgets2.py @@ -539,7 +539,7 @@ class HTMLDisplay(QTextBrowser): try: with lopen(path, 'rb') as f: data = f.read() - except EnvironmentError: + except OSError: if path.rpartition('.')[-1].lower() in {'jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'}: return QByteArray(bytearray.fromhex( '89504e470d0a1a0a0000000d49484452' diff --git a/src/calibre/gui2/win_file_dialogs.py b/src/calibre/gui2/win_file_dialogs.py index 5406761a3a..9340f67ead 100644 --- a/src/calibre/gui2/win_file_dialogs.py +++ b/src/calibre/gui2/win_file_dialogs.py @@ -262,7 +262,7 @@ def choose_dir(window, name, title, default_dir='~', no_save_dir=False): def choose_files(window, name, title, - filters=(), all_files=True, select_only_single_file=False, default_dir=u'~'): + filters=(), all_files=True, select_only_single_file=False, default_dir='~'): name, initial_folder = get_initial_folder(name, title, default_dir) file_types = list(filters) if all_files: diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index 9ca7af1a38..8ce45d1e73 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -358,7 +358,7 @@ class Android(Device): @classmethod def commit(cls): from calibre.customize.ui import device_plugins - super(Android, cls).commit() + super().commit() for plugin in device_plugins(include_disabled=True): if hasattr(plugin, 'configure_for_generic_epub_app'): plugin.configure_for_generic_epub_app() diff --git a/src/calibre/library/__init__.py b/src/calibre/library/__init__.py index 2772be8144..6b9978a8be 100644 --- a/src/calibre/library/__init__.py +++ b/src/calibre/library/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' diff --git a/src/calibre/library/add_to_library.py b/src/calibre/library/add_to_library.py index 9f7e7bf6c3..4429887e9a 100644 --- a/src/calibre/library/add_to_library.py +++ b/src/calibre/library/add_to_library.py @@ -77,8 +77,7 @@ class FormatCollection: # {{{ return len(self) == 0 def __iter__(self): - for x in self.path_map: - yield x + yield from self.path_map def __len__(self): return len(self.path_map) diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py index c191a71426..206fdee456 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -905,7 +905,7 @@ class ResultCache(SearchQueryParser): # {{{ self.search_restriction_name = s def search_restriction_applied(self): - return bool(self.search_restriction) or bool((self.base_restriction)) + return bool(self.search_restriction) or bool(self.base_restriction) def get_search_restriction_book_count(self): return self.search_restriction_book_count diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index 388f5b455d..0a74b3f250 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -849,7 +849,7 @@ class CatalogBuilder: if self.DEBUG and self.opts.verbose: self.opts.log.info("\nfetch_books_by_author(): %d unique authors" % len(unique_authors)) for author in unique_authors: - self.opts.log.info((u" %-50s %-25s %2d" % (author[0][0:45], author[1][0:20], + self.opts.log.info((" %-50s %-25s %2d" % (author[0][0:45], author[1][0:20], author[2])).encode('utf-8')) self.opts.log.info("\nfetch_books_by_author(): %d individual authors" % len(individual_authors)) for author in sorted(individual_authors): @@ -881,7 +881,7 @@ class CatalogBuilder: self.opts.log.info("fetch_books_by_title(): %d books" % len(self.books_by_title)) self.opts.log.info(" %-40s %-40s" % ('title', 'title_sort')) for title in self.books_by_title: - self.opts.log.info((u" %-40s %-40s" % (title['title'][0:40], + self.opts.log.info((" %-40s %-40s" % (title['title'][0:40], title['title_sort'][0:40])).encode('utf-8')) else: error_msg = _("No books to catalog.\nCheck 'Excluded books' rules in the E-book options.\n") @@ -1070,7 +1070,7 @@ class CatalogBuilder: if self.DEBUG: if self.prefix_rules: - self.opts.log.info(" Added prefixes (bools_are_tristate: {0}):".format(self.db.new_api.pref('bools_are_tristate'))) + self.opts.log.info(" Added prefixes (bools_are_tristate: {}):".format(self.db.new_api.pref('bools_are_tristate'))) else: self.opts.log.info(" No added prefixes") @@ -3279,9 +3279,9 @@ class CatalogBuilder: for (i, books) in enumerate(books_by_letter): sec_id = "%sTitles-ID" % (title_letters[i].upper()) if len(title_letters[i]) > 1: - fmt_string = _(u"Titles beginning with %s") + fmt_string = _("Titles beginning with %s") else: - fmt_string = _(u"Titles beginning with '%s'") + fmt_string = _("Titles beginning with '%s'") sec_text = fmt_string % (title_letters[i] if len(title_letters[i]) > 1 else title_letters[i]) if title_letters[i] == self.SYMBOLS: content_src = "content/%s.html#%s_titles" % (output, self.SYMBOLS) @@ -3356,9 +3356,9 @@ class CatalogBuilder: for authors_by_letter in master_author_list: sec_id = "%sauthors-ID" % (authors_by_letter[1]) if authors_by_letter[1] == self.SYMBOLS: - fmt_string = _(u"Authors beginning with %s") + fmt_string = _("Authors beginning with %s") else: - fmt_string = _(u"Authors beginning with '%s'") + fmt_string = _("Authors beginning with '%s'") sec_text = fmt_string % authors_by_letter[1] if authors_by_letter[1] == self.SYMBOLS: content_src = "%s#%s_authors" % (HTML_file, authors_by_letter[1]) diff --git a/src/calibre/library/check_library.py b/src/calibre/library/check_library.py index 26ddd7346f..76c5749d36 100644 --- a/src/calibre/library/check_library.py +++ b/src/calibre/library/check_library.py @@ -48,10 +48,10 @@ class CheckLibrary: self.is_case_sensitive = db.is_case_sensitive - self.all_authors = frozenset([x[1] for x in db.all_authors()]) - self.all_ids = frozenset([id_ for id_ in db.all_ids()]) + self.all_authors = frozenset(x[1] for x in db.all_authors()) + self.all_ids = frozenset(id_ for id_ in db.all_ids()) self.all_dbpaths = frozenset(self.dbpath(id_) for id_ in self.all_ids) - self.all_lc_dbpaths = frozenset([f.lower() for f in self.all_dbpaths]) + self.all_lc_dbpaths = frozenset(f.lower() for f in self.all_dbpaths) self.db_id_regexp = re.compile(r'^.* \((\d+)\)$') @@ -91,7 +91,7 @@ class CheckLibrary: def scan_library(self, name_ignores, extension_ignores): self.ignore_names = frozenset(name_ignores) - self.ignore_ext = frozenset(['.'+ e for e in extension_ignores]) + self.ignore_ext = frozenset('.'+ e for e in extension_ignores) lib = self.src_library_path for auth_dir in os.listdir(lib): @@ -158,8 +158,8 @@ class CheckLibrary: path = self.dbpath(id_) if not os.path.exists(os.path.join(lib, path)): title_dir = os.path.basename(path) - book_formats = frozenset([x for x in - self.db.format_files(id_, index_is_id=True)]) + book_formats = frozenset(x for x in + self.db.format_files(id_, index_is_id=True)) for fmt in book_formats: self.missing_formats.append((title_dir, os.path.join(path, fmt[0]+'.'+fmt[1].lower()), id_)) @@ -180,13 +180,13 @@ class CheckLibrary: def process_book(self, lib, book_info): (db_path, title_dir, book_id) = book_info - filenames = frozenset([f for f in os.listdir(os.path.join(lib, db_path)) + filenames = frozenset(f for f in os.listdir(os.path.join(lib, db_path)) if os.path.splitext(f)[1] not in self.ignore_ext or - f == 'cover.jpg']) + f == 'cover.jpg') book_id = int(book_id) formats = frozenset(filter(self.is_ebook_file, filenames)) - book_formats = frozenset([x[0]+'.'+x[1].lower() for x in - self.db.format_files(book_id, index_is_id=True)]) + book_formats = frozenset(x[0]+'.'+x[1].lower() for x in + self.db.format_files(book_id, index_is_id=True)) if self.is_case_sensitive: unknowns = frozenset(filenames-formats-NORMALS) @@ -219,10 +219,10 @@ class CheckLibrary: fn[ff] = f return fn - filenames_lc = frozenset([f.lower() for f in filenames]) - formats_lc = frozenset([f.lower() for f in formats]) + filenames_lc = frozenset(f.lower() for f in filenames) + formats_lc = frozenset(f.lower() for f in formats) unknowns = frozenset(filenames_lc-formats_lc-NORMALS) - book_formats_lc = frozenset([f.lower() for f in book_formats]) + book_formats_lc = frozenset(f.lower() for f in book_formats) missing = book_formats_lc - formats_lc # Check: any books that aren't formats or normally there? diff --git a/src/calibre/library/coloring.py b/src/calibre/library/coloring.py index 4420fc32ad..545393d7ce 100644 --- a/src/calibre/library/coloring.py +++ b/src/calibre/library/coloring.py @@ -176,9 +176,9 @@ class Rule: # {{{ "format_date(today(), 'yyyy-MM-dd')), '1', '', ''), '')") %(col, val, col)) if action == 'is set': - return (("test(field('%s'), '1', '')"%(col))) + return ("test(field('%s'), '1', '')"%(col)) if action == 'is not set': - return (("test(field('%s'), '', '1')"%(col))) + return ("test(field('%s'), '', '1')"%(col)) lt, eq, gt = { 'eq': ('', '1', ''), 'lt': ('1', '', ''), diff --git a/src/calibre/library/comments.py b/src/calibre/library/comments.py index cf934ada8a..d002904233 100644 --- a/src/calibre/library/comments.py +++ b/src/calibre/library/comments.py @@ -47,7 +47,7 @@ def comments_to_html(comments): ''' if not comments: - return u'

    ' + return '

    ' if not isinstance(comments, str): comments = comments.decode(preferred_encoding, 'replace') @@ -57,7 +57,7 @@ def comments_to_html(comments): if '<' not in comments: comments = prepare_string_for_xml(comments) - parts = [u'

    %s

    '%x.replace(u'\n', u'
    ') + parts = ['

    %s

    '%x.replace('\n', '
    ') for x in comments.split('\n\n')] return '\n'.join(parts) @@ -67,7 +67,7 @@ def comments_to_html(comments): except: import traceback traceback.print_exc() - return u'

    ' + return '

    ' # Explode lost CRs to \n\n comments = lost_cr_exception_pat.sub(lambda m: m.group().replace('.', @@ -78,11 +78,11 @@ def comments_to_html(comments): lost_cr.group(2), lost_cr.group(3))) - comments = comments.replace(u'\r', u'') + comments = comments.replace('\r', '') # Convert \n\n to

    s - comments = comments.replace(u'\n\n', u'

    ') + comments = comments.replace('\n\n', '

    ') # Convert solo returns to
    - comments = comments.replace(u'\n', '
    ') + comments = comments.replace('\n', '
    ') # Convert two hyphens to emdash comments = comments.replace('--', '—') diff --git a/src/calibre/library/custom_columns.py b/src/calibre/library/custom_columns.py index 50bb00bd27..42a50e2791 100644 --- a/src/calibre/library/custom_columns.py +++ b/src/calibre/library/custom_columns.py @@ -199,7 +199,7 @@ class CustomColumns: else: is_category = False is_m = v['multiple_seps'] - tn = 'custom_column_{0}'.format(v['num']) + tn = 'custom_column_{}'.format(v['num']) self.field_metadata.add_custom_field(label=v['label'], table=tn, column='value', datatype=v['datatype'], colnum=v['num'], name=v['name'], display=v['display'], diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py index 3b405cca0c..f3c0b7dd4c 100644 --- a/src/calibre/library/database.py +++ b/src/calibre/library/database.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -1383,8 +1381,7 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; def get_feeds(self): feeds = self.conn.get('SELECT title, script FROM feeds') - for title, script in feeds: - yield title, script + yield from feeds def get_feed(self, id): return self.conn.get('SELECT script FROM feeds WHERE id=%d'%id, diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index f3a0ec540b..49c77f7373 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' @@ -328,7 +326,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): prints('found user category case overlap', catmap[uc]) cat = catmap[uc][0] suffix = 1 - while icu_lower((cat + str(suffix))) in catmap: + while icu_lower(cat + str(suffix)) in catmap: suffix += 1 prints('Renaming user category %s to %s'%(cat, cat+str(suffix))) user_cats[cat + str(suffix)] = user_cats[cat] @@ -469,7 +467,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): DROP VIEW IF EXISTS meta2; CREATE TEMP VIEW meta2 AS SELECT - {0} + {} FROM books; '''.format(', \n'.join(lines)) self.conn.executescript(script) @@ -756,7 +754,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if os.access(path, os.R_OK): try: f = lopen(path, 'rb') - except (IOError, OSError): + except OSError: time.sleep(0.2) f = lopen(path, 'rb') with f: @@ -1164,7 +1162,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if os.path.exists(path): try: os.remove(path) - except (IOError, OSError): + except OSError: time.sleep(0.2) os.remove(path) self.conn.execute('UPDATE books SET has_cover=0 WHERE id=?', (id,)) @@ -1199,7 +1197,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): data = data.read() try: save_cover_data_to(data, path) - except (IOError, OSError): + except OSError: time.sleep(0.2) save_cover_data_to(data, path) now = nowf() @@ -1458,7 +1456,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if os.access(path, os.R_OK): try: f = lopen(path, 'rb') - except (IOError, OSError): + except OSError: time.sleep(0.2) f = lopen(path, 'rb') with f: @@ -1724,7 +1722,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): ans = self.conn.get( 'SELECT book FROM books_{tn}_link WHERE {col}=?'.format( tn=field['table'], col=field['link_column']), (id_,)) - return set(x[0] for x in ans) + return {x[0] for x in ans} # data structures for get_categories @@ -1829,7 +1827,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): elif cat['datatype'] == 'rating': for l in list: (id, val) = (l[0], l[1]) - tids[category][val] = (id, '{0:05.2f}'.format(val)) + tids[category][val] = (id, '{:05.2f}'.format(val)) elif cat['datatype'] == 'text' and cat['is_multiple'] and \ cat['display'].get('is_names', False): for l in list: @@ -1932,11 +1930,11 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): tn = cat['table'] cn = cat['column'] if ids is None: - query = '''SELECT id, {0}, count, avg_rating, sort - FROM tag_browser_{1}'''.format(cn, tn) + query = '''SELECT id, {}, count, avg_rating, sort + FROM tag_browser_{}'''.format(cn, tn) else: - query = '''SELECT id, {0}, count, avg_rating, sort - FROM tag_browser_filtered_{1}'''.format(cn, tn) + query = '''SELECT id, {}, count, avg_rating, sort + FROM tag_browser_filtered_{}'''.format(cn, tn) # results will be sorted later data = self.conn.get(query) for r in data: @@ -2714,7 +2712,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): table = self.field_metadata[field]['table'] link = self.field_metadata[field]['link_column'] bks = self.conn.get( - 'SELECT book from books_{0}_link WHERE {1}=?'.format(table, link), + 'SELECT book from books_{}_link WHERE {}=?'.format(table, link), (id,)) books = [] for (book_id,) in bks: diff --git a/src/calibre/library/field_metadata.py b/src/calibre/library/field_metadata.py index 8b460e365b..09bcfb7139 100644 --- a/src/calibre/library/field_metadata.py +++ b/src/calibre/library/field_metadata.py @@ -1,5 +1,3 @@ - - ''' Created on 25 May 2010 @@ -422,8 +420,7 @@ class FieldMetadata: del self._tb_cats[key] def __iter__(self): - for key in self._tb_cats: - yield key + yield from self._tb_cats def __contains__(self, key): return key in self._tb_cats or key == 'title_sort' @@ -484,8 +481,7 @@ class FieldMetadata: return [k for k in self._tb_cats.keys() if self._tb_cats[k]['kind']=='field'] def iterkeys(self): - for key in self._tb_cats: - yield key + yield from self._tb_cats def itervalues(self): return itervalues(self._tb_cats) @@ -499,8 +495,7 @@ class FieldMetadata: iter_items = iteritems def custom_iteritems(self): - for key, meta in iteritems(self._tb_custom_fields): - yield (key, meta) + yield from iteritems(self._tb_custom_fields) def items(self): return list(self.iter_items()) diff --git a/src/calibre/library/restore.py b/src/calibre/library/restore.py index 48d8320a53..f0b2d8ee6d 100644 --- a/src/calibre/library/restore.py +++ b/src/calibre/library/restore.py @@ -40,7 +40,7 @@ class RestoreDatabase(LibraryDatabase2): class Restore(Thread): def __init__(self, library_path, progress_callback=None): - super(Restore, self).__init__() + super().__init__() if isbytestring(library_path): library_path = library_path.decode(filesystem_encoding) self.src_library_path = os.path.abspath(library_path) @@ -114,7 +114,7 @@ class Restore(Thread): self.create_cc_metadata() self.restore_books() if self.successes == 0 and len(self.dirs) > 0: - raise Exception(('Something bad happened')) + raise Exception('Something bad happened') self.replace_db() except: self.tb = traceback.format_exc() diff --git a/src/calibre/library/save_to_disk.py b/src/calibre/library/save_to_disk.py index cc8cd9c0c9..afa58c8c7f 100644 --- a/src/calibre/library/save_to_disk.py +++ b/src/calibre/library/save_to_disk.py @@ -333,7 +333,7 @@ def do_save_book_to_disk(db, book_id, mi, plugboards, dirpath = os.path.dirname(base_path) try: os.makedirs(dirpath) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise diff --git a/src/calibre/library/sqlite.py b/src/calibre/library/sqlite.py index b634de5c24..09504736e6 100644 --- a/src/calibre/library/sqlite.py +++ b/src/calibre/library/sqlite.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' diff --git a/src/calibre/linux.py b/src/calibre/linux.py index e78ed1c00c..8a4e6e0adb 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -94,7 +94,7 @@ class PreserveMIMEDefaults: # {{{ f.seek(0) f.truncate() f.write(val) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EACCES: raise # }}} @@ -343,7 +343,7 @@ class ZshCompleter: # {{{ recipe = recipe.replace(':', '\\:').replace('"', '\\"') w('\n "%s.recipe"'%(recipe)) w('\n ); _describe -t recipes "ebook-convert builtin recipes" extras') - w('\n _files -g "%s"'%' '.join(('*.%s'%x for x in iexts))) + w('\n _files -g "%s"'%' '.join('*.%s'%x for x in iexts)) w('\n}\n') # Arg 2 @@ -352,7 +352,7 @@ class ZshCompleter: # {{{ for x in output_fmts: w('\n ".{0}:Convert to a .{0} file with the same name as the input file"'.format(x)) w('\n ); _describe -t output "ebook-convert output" extras') - w('\n _files -g "%s"'%' '.join(('*.%s'%x for x in oexts))) + w('\n _files -g "%s"'%' '.join('*.%s'%x for x in oexts)) w('\n _path_files -/') w('\n}\n') @@ -439,7 +439,7 @@ class ZshCompleter: # {{{ opt_lines.append(ostrings + help_txt + ' \\') opt_lines = ('\n' + (' ' * 8)).join(opt_lines) - polyglot_write(f)((''' + polyglot_write(f)(''' _ebook_edit() { local curcontext="$curcontext" state line ebookfile expl typeset -A opt_args @@ -466,7 +466,7 @@ _ebook_edit() { return 1 } -''' % (opt_lines, '|'.join(tweakable_fmts)) + '\n\n')) +''' % (opt_lines, '|'.join(tweakable_fmts)) + '\n\n') def do_calibredb(self, f): from calibre.db.cli.main import COMMANDS, option_parser_for @@ -508,7 +508,7 @@ _ebook_edit() { subcommands.append(';;') w('\n_calibredb() {') - w(( + w( r''' local state line state_descr context typeset -A opt_args @@ -531,7 +531,7 @@ _ebook_edit() { esac return ret - '''%'\n '.join(subcommands))) + '''%'\n '.join(subcommands)) w('\n}\n\n') def write(self): @@ -835,7 +835,7 @@ class PostInstall: print('You need python-lxml >= 2.0.5 for calibre') sys.exit(1) raise - except EnvironmentError as e: + except OSError as e: if e.errno == errno.EACCES: self.warning('Failed to setup completion, permission denied') if self.opts.fatal_errors: diff --git a/src/calibre/ptempfile.py b/src/calibre/ptempfile.py index a8a2e4663a..c0588dbb64 100644 --- a/src/calibre/ptempfile.py +++ b/src/calibre/ptempfile.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' """ diff --git a/src/calibre/rpdb.py b/src/calibre/rpdb.py index 4d9a986a16..1f4c0b1da5 100644 --- a/src/calibre/rpdb.py +++ b/src/calibre/rpdb.py @@ -52,7 +52,7 @@ class RemotePdb(pdb.Pdb): try: self.sock.shutdown(socket.SHUT_RDWR) self.sock.close() - except socket.error: + except OSError: pass return pdb.Pdb.do_continue(self, None) @@ -100,13 +100,13 @@ def cli(port=4444): try: sock.connect(('127.0.0.1', port)) break - except socket.error: + except OSError: pass time.sleep(0.1) else: try: sock.connect(('127.0.0.1', port)) - except socket.error as err: + except OSError as err: print('Failed to connect to remote debugger:', err, file=sys.stderr) raise SystemExit(1) print('Connected to remote process', flush=True) @@ -118,7 +118,7 @@ def cli(port=4444): histfile = os.path.join(cache_dir(), 'rpdb.history') try: readline.read_history_file(histfile) - except IOError: + except OSError: pass atexit.register(readline.write_history_file, histfile) p = pdb.Pdb() diff --git a/src/calibre/srv/ajax.py b/src/calibre/srv/ajax.py index 661283c3a5..0215e49118 100644 --- a/src/calibre/srv/ajax.py +++ b/src/calibre/srv/ajax.py @@ -82,7 +82,7 @@ def book_to_json(ctx, rd, db, book_id, if mtime is not None: v['mtime'] = isoformat(mtime, as_utc=True) data['format_metadata'] = mi.format_metadata - fmts = set(x.lower() for x in mi.format_metadata) + fmts = {x.lower() for x in mi.format_metadata} pf = prefs['output_format'].lower() other_fmts = list(fmts) try: @@ -402,7 +402,7 @@ def category(ctx, rd, encoded_name, library_id): '.' in x.original_name] if subcategory is None: - children = set(x[0] for x in category_names) + children = {x[0] for x in category_names} category_name = [meta['name']] items = [x for x in categories[toplevel] if '.' not in x.original_name] else: @@ -410,16 +410,16 @@ def category(ctx, rd, encoded_name, library_id): category_name = [meta['name']] + subcategory_parts lsp = len(subcategory_parts) - children = set('.'.join(x) for x in category_names if len(x) == - lsp+1 and x[:lsp] == subcategory_parts) + children = {'.'.join(x) for x in category_names if len(x) == + lsp+1 and x[:lsp] == subcategory_parts} items = [x for x in categories[toplevel] if x.original_name in children] item_names = {x:x.original_name.rpartition('.')[-1] for x in items} # Only mark the subcategories that have children themselves as # subcategories - children = set('.'.join(x[:lsp+1]) for x in category_names if len(x) > - lsp+1 and x[:lsp] == subcategory_parts) + children = {'.'.join(x[:lsp+1]) for x in category_names if len(x) > + lsp+1 and x[:lsp] == subcategory_parts} subcategories = [{'name':x.rpartition('.')[-1], 'url':toplevel+'.'+x, 'icon':category_icon(toplevel, meta)} for x in children] diff --git a/src/calibre/srv/auto_reload.py b/src/calibre/srv/auto_reload.py index cd82d890e9..b6e05ed0dc 100644 --- a/src/calibre/srv/auto_reload.py +++ b/src/calibre/srv/auto_reload.py @@ -297,7 +297,7 @@ class Worker: self.retry_count = 0 try: compile_srv() - except EnvironmentError as e: + except OSError as e: # Happens if the editor deletes and replaces a file being edited if e.errno != errno.ENOENT or not getattr(e, 'filename', False): raise @@ -327,7 +327,7 @@ class Worker: s = ssl.wrap_socket(s) s.connect(('localhost', self.port)) return - except socket.error: + except OSError: time.sleep(0.01) finally: s.close() diff --git a/src/calibre/srv/books.py b/src/calibre/srv/books.py index 8cedfcf0d7..955c669374 100644 --- a/src/calibre/srv/books.py +++ b/src/calibre/srv/books.py @@ -46,7 +46,7 @@ def books_cache_dir(): for d in 'sf': try: os.makedirs(os.path.join(base, d)) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EEXIST: raise _books_cache_dir = base @@ -66,7 +66,7 @@ def safe_remove(x, is_file=None): is_file = os.path.isfile(x) try: os.remove(x) if is_file else rmtree(x, ignore_errors=True) - except EnvironmentError: + except OSError: pass @@ -101,7 +101,7 @@ def clean_final(interval=24 * 60 * 60): for x in os.listdir(fdir): try: tm = os.path.getmtime(os.path.join(fdir, x, 'calibre-book-manifest.json')) - except EnvironmentError: + except OSError: continue if now - tm >= interval: # This book has not been accessed for a long time, delete it @@ -154,7 +154,7 @@ def book_manifest(ctx, rd, book_id, fmt): ans['last_read_positions'] = db.get_last_read_positions(book_id, fmt, user) if user else [] ans['annotations_map'] = db.annotations_map_for_book(book_id, fmt, user_type='web', user=user or '*') return ans - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise x = failed_jobs.pop(bhash, None) @@ -179,7 +179,7 @@ def book_file(ctx, rd, book_id, fmt, size, mtime, name): raise HTTPNotFound('No book file with hash: %s and name: %s' % (bhash, name)) try: return rd.filesystem_file_with_custom_etag(lopen(mpath, 'rb'), bhash, name) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise raise HTTPNotFound('No book file with hash: %s and name: %s' % (bhash, name)) diff --git a/src/calibre/srv/code.py b/src/calibre/srv/code.py index f5d40223c9..58ec95b505 100644 --- a/src/calibre/srv/code.py +++ b/src/calibre/srv/code.py @@ -176,7 +176,7 @@ def update_interface_data(ctx, rd, translations_hash): def get_field_list(db): fieldlist = list(db.pref('book_display_fields', ())) - names = frozenset([x[0] for x in fieldlist]) + names = frozenset(x[0] for x in fieldlist) available = frozenset(db.field_metadata.displayable_field_keys()) for field in available: if field not in names: @@ -209,9 +209,9 @@ def get_library_init_data(ctx, rd, db, num, sorts, orders, vl): ans['book_display_fields'] = get_field_list(db) mdata = ans['metadata'] = {} try: - extra_books = set( + extra_books = { int(x) for x in rd.query.get('extra_books', '').split(',') - ) + } except Exception: extra_books = () for coll in (ans['search_result']['book_ids'], extra_books): diff --git a/src/calibre/srv/content.py b/src/calibre/srv/content.py index daab3cc34e..6254bbec1f 100644 --- a/src/calibre/srv/content.py +++ b/src/calibre/srv/content.py @@ -47,10 +47,10 @@ def reset_caches(): def open_for_write(fname): try: return share_open(fname, 'w+b') - except EnvironmentError: + except OSError: try: os.makedirs(os.path.dirname(fname)) - except EnvironmentError: + except OSError: pass return share_open(fname, 'w+b') @@ -102,7 +102,7 @@ def create_file_copy(ctx, rd, prefix, library_id, book_id, ext, mtime, copy_func try: ans = share_open(fname, 'rb') used_cache = 'yes' - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise ans = open_for_write(fname) @@ -226,7 +226,7 @@ def static(ctx, rd, what): path = P('content-server/' + path) try: return share_open(path, 'rb') - except EnvironmentError: + except OSError: raise HTTPNotFound() @@ -265,17 +265,17 @@ def icon(ctx, rd, which): if sz == 'full': try: return share_open(path, 'rb') - except EnvironmentError: + except OSError: raise HTTPNotFound() with lock: cached = os.path.join(rd.tdir, 'icons', '%d-%s.png' % (sz, which)) try: return share_open(cached, 'rb') - except EnvironmentError: + except OSError: pass try: src = share_open(path, 'rb') - except EnvironmentError: + except OSError: raise HTTPNotFound() with src: idata = src.read() diff --git a/src/calibre/srv/convert.py b/src/calibre/srv/convert.py index 36660e2f79..7eb32c1d88 100644 --- a/src/calibre/srv/convert.py +++ b/src/calibre/srv/convert.py @@ -70,14 +70,14 @@ def expire_old_jobs(): def safe_delete_file(path): try: os.remove(path) - except EnvironmentError: + except OSError: pass def safe_delete_tree(path): try: shutil.rmtree(path, ignore_errors=True) - except EnvironmentError: + except OSError: pass diff --git a/src/calibre/srv/embedded.py b/src/calibre/srv/embedded.py index b23852ccb6..bf71e12095 100644 --- a/src/calibre/srv/embedded.py +++ b/src/calibre/srv/embedded.py @@ -29,7 +29,7 @@ def read_json(path): try: with lopen(path, 'rb') as f: raw = f.read() - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise return @@ -59,7 +59,7 @@ class Server: lp, lap = log_paths() try: os.makedirs(cache_dir()) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise log_size = opts.max_log_size * 1024 * 1024 diff --git a/src/calibre/srv/http_response.py b/src/calibre/srv/http_response.py index 40cd17cc73..a20b2fc6d0 100644 --- a/src/calibre/srv/http_response.py +++ b/src/calibre/srv/http_response.py @@ -130,7 +130,7 @@ def get_ranges(headervalue, content_length): # {{{ return None for brange in byteranges.split(","): - start, stop = [x.strip() for x in brange.split("-", 1)] + start, stop = (x.strip() for x in brange.split("-", 1)) if start: if not stop: stop = content_length - 1 @@ -402,7 +402,7 @@ class HTTPConnection(HTTPRequest): # Something bad happened, was the file modified on disk by # another process? self.use_sendfile = self.ready = False - raise IOError('sendfile() failed to write any bytes to the socket') + raise OSError('sendfile() failed to write any bytes to the socket') else: data = buf.read(min(limit, self.send_bufsize)) sent = self.send(data) diff --git a/src/calibre/srv/jobs.py b/src/calibre/srv/jobs.py index 0baa9b2f15..d41e8ca777 100644 --- a/src/calibre/srv/jobs.py +++ b/src/calibre/srv/jobs.py @@ -66,7 +66,7 @@ class Job(Thread): if lp: try: os.remove(lp) - except EnvironmentError: + except OSError: pass def read_log(self): @@ -75,7 +75,7 @@ class Job(Thread): try: with lopen(self.log_path, 'rb') as f: ans = f.read() - except EnvironmentError: + except OSError: pass if isinstance(ans, bytes): ans = force_unicode(ans, 'utf-8') diff --git a/src/calibre/srv/legacy.py b/src/calibre/srv/legacy.py index 0cabae678d..307c705e95 100644 --- a/src/calibre/srv/legacy.py +++ b/src/calibre/srv/legacy.py @@ -169,7 +169,7 @@ def build_index(rd, books, num, search, sort, order, start, total, url_base, fie href=ctx.url_for('/legacy/get', what=fmt, book_id=book.id, library_id=library_id, filename=book_filename(rd, book.id, book, fmt)) ), class_='button') - s.tail = u'' + s.tail = '' data.append(s) div = E.div(class_='data-container') diff --git a/src/calibre/srv/loop.py b/src/calibre/srv/loop.py index e0f2c89e34..18bf483da2 100644 --- a/src/calibre/srv/loop.py +++ b/src/calibre/srv/loop.py @@ -192,7 +192,7 @@ class Connection: # {{{ if self.send_bufsize < DESIRED_SEND_BUFFER_SIZE: try: self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, DESIRED_SEND_BUFFER_SIZE) - except socket.error: + except OSError: pass else: self.send_bufsize = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF) @@ -228,7 +228,7 @@ class Connection: # {{{ return ret except ssl.SSLWantWriteError: return 0 - except socket.error as e: + except OSError as e: if e.errno in socket_errors_nonblocking or e.errno in socket_errors_eintr: return 0 elif e.errno in socket_errors_socket_closed: @@ -255,7 +255,7 @@ class Connection: # {{{ return data except ssl.SSLWantReadError: return b'' - except socket.error as e: + except OSError as e: if e.errno in socket_errors_nonblocking or e.errno in socket_errors_eintr: return b'' if e.errno in socket_errors_socket_closed: @@ -280,7 +280,7 @@ class Connection: # {{{ return bytes_read except ssl.SSLWantReadError: return 0 - except socket.error as e: + except OSError as e: if e.errno in socket_errors_nonblocking or e.errno in socket_errors_eintr: return 0 if e.errno in socket_errors_socket_closed: @@ -298,7 +298,7 @@ class Connection: # {{{ self.ready = False except ssl.SSLWantReadError: return - except socket.error as e: + except OSError as e: if e.errno in socket_errors_nonblocking or e.errno in socket_errors_eintr: return if e.errno in socket_errors_socket_closed: @@ -315,7 +315,7 @@ class Connection: # {{{ self.log.error('Error while reading SSL data from client: %s' % as_unicode(e)) self.ready = False return - except socket.error as e: + except OSError as e: if e.errno in socket_errors_nonblocking or e.errno in socket_errors_eintr: return if e.errno in socket_errors_socket_closed: @@ -329,7 +329,7 @@ class Connection: # {{{ try: self.socket.shutdown(socket.SHUT_WR) self.socket.close() - except socket.error: + except OSError: pass def queue_job(self, func, *args): @@ -469,7 +469,7 @@ class ServerLoop: af, socktype, proto, canonname, sa = res try: self.bind(af, socktype, proto) - except socket.error as serr: + except OSError as serr: msg = "%s -- (%s: %s)" % (msg, sa, as_unicode(serr)) if self.socket: self.socket.close() @@ -477,13 +477,13 @@ class ServerLoop: continue break if not self.socket: - raise socket.error(msg) + raise OSError(msg) def initialize_socket(self): if self.pre_activated_socket is None: try: self.do_bind() - except socket.error as err: + except OSError as err: if not self.opts.fallback_to_detected_interface: raise ip = get_external_ip() @@ -539,7 +539,7 @@ class ServerLoop: self.bind_address[0] in ('::', '::0', '::0.0.0.0')): try: self.socket.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) - except (AttributeError, socket.error): + except (AttributeError, OSError): # Apparently, the socket option is not available in # this machine's TCP stack pass @@ -597,7 +597,7 @@ class ServerLoop: self.ready = False self.log.error('Listening socket was unexpectedly terminated') return - except (select.error, socket.error) as e: + except OSError as e: # select.error has no errno attribute. errno is instead # e.args[0] if getattr(e, 'errno', e.args[0]) in socket_errors_eintr: @@ -605,7 +605,7 @@ class ServerLoop: for s, conn in tuple(iteritems(self.connection_map)): try: select.select([s], [], [], 0) - except (select.error, socket.error) as e: + except OSError as e: if getattr(e, 'errno', e.args[0]) not in socket_errors_eintr: self.close(s, conn) # Bad socket, discard return @@ -695,7 +695,7 @@ class ServerLoop: f = self.control_out.recv if iswindows else self.control_out.read try: c = f(1) - except (socket.error, OSError) as e: + except OSError as e: if not self.ready: return self.log.error('Control connection raised an error:', e) @@ -724,7 +724,7 @@ class ServerLoop: sock, addr = self.socket.accept() set_socket_inherit(sock, False), sock.setblocking(False) return sock, addr - except socket.error: + except OSError: return None, None def stop(self): diff --git a/src/calibre/srv/metadata.py b/src/calibre/srv/metadata.py index dc08e6d9f7..51e72b54c1 100644 --- a/src/calibre/srv/metadata.py +++ b/src/calibre/srv/metadata.py @@ -476,8 +476,7 @@ def process_category_node( def iternode_descendants(node): for child in node['children']: yield child - for x in iternode_descendants(child): - yield x + yield from iternode_descendants(child) def fillout_tree(root, items, node_id_map, category_nodes, category_data, field_metadata, opts, book_rating_map): diff --git a/src/calibre/srv/opts.py b/src/calibre/srv/opts.py index 84a9636e21..5c281c4a9d 100644 --- a/src/calibre/srv/opts.py +++ b/src/calibre/srv/opts.py @@ -21,7 +21,7 @@ Option = namedtuple('Option', 'name default longdoc shortdoc choices') class Choices(frozenset): def __new__(cls, *args): - self = super(Choices, cls).__new__(cls, args) + self = super().__new__(cls, args) self.default = args[0] return self @@ -276,7 +276,7 @@ def parse_config_file(path=DEFAULT_CONFIG): try: with ExclusiveFile(path) as f: raw = f.read().decode('utf-8') - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise raw = '' diff --git a/src/calibre/srv/pre_activated.py b/src/calibre/srv/pre_activated.py index 183cba1571..472d4cf54f 100644 --- a/src/calibre/srv/pre_activated.py +++ b/src/calibre/srv/pre_activated.py @@ -30,7 +30,7 @@ if islinux: addr = SOCKADDR_NL(0, 0, 0, 0) sz = ctypes.c_int(ctypes.sizeof(addr)) if ctypes.CDLL(None, use_errno=True).getsockname(fd, ctypes.pointer(addr), ctypes.pointer(sz)) != 0: - raise EnvironmentError(errno.errcode[ctypes.get_errno()]) + raise OSError(errno.errcode[ctypes.get_errno()]) return addr.nl_family try: @@ -45,15 +45,15 @@ if islinux: def pre_activated_socket(): # noqa num = systemd.sd_listen_fds(1) # Remove systemd env vars so that child processes do not inherit them if num > 1: - raise EnvironmentError('Too many file descriptors received from systemd') + raise OSError('Too many file descriptors received from systemd') if num != 1: return None fd = 3 # systemd starts activated sockets at 3 ret = systemd.sd_is_socket(fd, socket.AF_UNSPEC, socket.SOCK_STREAM, -1) if ret == 0: - raise EnvironmentError('The systemd socket file descriptor is not valid') + raise OSError('The systemd socket file descriptor is not valid') if ret < 0: - raise EnvironmentError('Failed to check the systemd socket file descriptor for validity') + raise OSError('Failed to check the systemd socket file descriptor for validity') family = getsockfamily(fd) return socket.fromfd(fd, family, socket.SOCK_STREAM) diff --git a/src/calibre/srv/render_book.py b/src/calibre/srv/render_book.py index aab2996f2a..b9fb136466 100644 --- a/src/calibre/srv/render_book.py +++ b/src/calibre/srv/render_book.py @@ -443,11 +443,11 @@ class RenderManager: del self.workers try: rmtree(self.tdir) - except EnvironmentError: + except OSError: time.sleep(0.1) try: rmtree(self.tdir) - except EnvironmentError: + except OSError: pass del self.tdir @@ -764,8 +764,7 @@ def get_stored_annotations(container, bookmark_data): return if raw.startswith(EPUB_FILE_TYPE_MAGIC): raw = raw[len(EPUB_FILE_TYPE_MAGIC):].replace(b'\n', b'') - for annot in json_loads(from_base64_bytes(raw)): - yield annot + yield from json_loads(from_base64_bytes(raw)) return from calibre.ebooks.oeb.iterator.bookmarks import parse_bookmarks diff --git a/src/calibre/srv/tests/__init__.py b/src/calibre/srv/tests/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/srv/tests/__init__.py +++ b/src/calibre/srv/tests/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/srv/tests/ajax.py b/src/calibre/srv/tests/ajax.py index 67debbec4c..70fafaa64a 100644 --- a/src/calibre/srv/tests/ajax.py +++ b/src/calibre/srv/tests/ajax.py @@ -20,7 +20,7 @@ from polyglot.urllib import quote, urlencode def make_request(conn, url, headers={}, prefix='/ajax', username=None, password=None, method='GET', data=None): if username and password: - headers[b'Authorization'] = b'Basic ' + as_base64_bytes((username + ':' + password)) + headers[b'Authorization'] = b'Basic ' + as_base64_bytes(username + ':' + password) conn.request(method, prefix + url, headers=headers, body=data) r = conn.getresponse() data = r.read() diff --git a/src/calibre/srv/tests/base.py b/src/calibre/srv/tests/base.py index 865f139c5e..f9be9d0edd 100644 --- a/src/calibre/srv/tests/base.py +++ b/src/calibre/srv/tests/base.py @@ -58,7 +58,7 @@ class LibraryBaseTest(BaseTest): gc.collect(), gc.collect() try: shutil.rmtree(self.library_path) - except EnvironmentError: + except OSError: # Try again in case something transient has a file lock on windows gc.collect(), gc.collect() time.sleep(2) diff --git a/src/calibre/srv/tests/content.py b/src/calibre/srv/tests/content.py index 4df6eb1891..97697aeba8 100644 --- a/src/calibre/srv/tests/content.py +++ b/src/calibre/srv/tests/content.py @@ -124,7 +124,7 @@ class ContentTest(LibraryBaseTest): import calibre.library.save_to_disk as c orig, c.DEBUG = c.DEBUG, False try: - db.set_pref('plugboards', {u'epub': {u'content_server': [[u'changed, {title}', u'title']]}}) + db.set_pref('plugboards', {'epub': {'content_server': [['changed, {title}', 'title']]}}) # this is needed as the cache is not invalidated for plugboard changes db.set_field('title', {1:'again'}) r, data = get('epub', 1) diff --git a/src/calibre/srv/tests/http.py b/src/calibre/srv/tests/http.py index e3464218e9..348890c66e 100644 --- a/src/calibre/srv/tests/http.py +++ b/src/calibre/srv/tests/http.py @@ -40,7 +40,7 @@ class TestHTTP(BaseTest): b'\r\n', a='one', b='two 2 3', c='three') test('Non-ascii headers parsing', - 'a:mūs\r'.encode('utf-8'), b'\r\n', a='mūs') + 'a:mūs\r'.encode(), b'\r\n', a='mūs') test('Comma-separated parsing', b'Accept-Encoding: one', diff --git a/src/calibre/srv/tests/web_sockets.py b/src/calibre/srv/tests/web_sockets.py index 0803697a9e..a8577ec09d 100644 --- a/src/calibre/srv/tests/web_sockets.py +++ b/src/calibre/srv/tests/web_sockets.py @@ -76,7 +76,7 @@ class WSClient: return data[:max_amt + 1] try: return self.socket.recv(max_amt) - except socket.error as err: + except OSError as err: if err.errno != errno.ECONNRESET: raise return b'' @@ -291,7 +291,7 @@ class WebSocketTest(BaseTest): simple_test([ {'opcode':TEXT, 'fin':0}, {'opcode':CONTINUATION, 'fin':0, 'payload':'x'}, {'opcode':CONTINUATION},], ['x']) - for q in (b'\xc2\xb5', b'\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5', "Hello-µ@ßöäüàá-UTF-8!!".encode('utf-8')): + for q in (b'\xc2\xb5', b'\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5', "Hello-µ@ßöäüàá-UTF-8!!".encode()): frags = [] for i in range(len(q)): b = q[i:i+1] diff --git a/src/calibre/srv/users.py b/src/calibre/srv/users.py index a6f98e9f61..2bc6ef0261 100644 --- a/src/calibre/srv/users.py +++ b/src/calibre/srv/users.py @@ -78,7 +78,7 @@ def connect(path, exc_class=ValueError): raise exc_class('Failed to open userdb database at {} with error: {}'.format(path, as_unicode(e))) try: os.makedirs(pdir) - except EnvironmentError as e: + except OSError as e: raise exc_class('Failed to make directory for userdb database at {} with error: {}'.format(pdir, as_unicode(e))) try: return apsw.Connection(path) diff --git a/src/calibre/srv/utils.py b/src/calibre/srv/utils.py index abc025750d..74ba63e307 100644 --- a/src/calibre/srv/utils.py +++ b/src/calibre/srv/utils.py @@ -70,8 +70,7 @@ class MultiDict(dict): # {{{ f = dict.values for v in f(self): if duplicates: - for x in v: - yield x + yield from v else: yield v[-1] itervalues = values @@ -235,7 +234,7 @@ def eintr_retry_call(func, *args, **kwargs): while True: try: return func(*args, **kwargs) - except EnvironmentError as e: + except OSError as e: if getattr(e, 'errno', None) in socket_errors_eintr: continue raise @@ -287,7 +286,7 @@ class RotatingStream: self.stream = open(os.open(self.filename, os.O_WRONLY|os.O_APPEND|os.O_CREAT|os.O_CLOEXEC), 'w') try: self.stream.tell() - except EnvironmentError: + except OSError: # Happens if filename is /dev/stdout for example self.max_size = None @@ -306,7 +305,7 @@ class RotatingStream: winutil.move_file(src, dest) else: os.rename(src, dest) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: # the source of the rename does not exist raise @@ -327,13 +326,13 @@ class RotatingStream: failed = {} try: os.remove(self.filename) - except EnvironmentError as e: + except OSError as e: failed[self.filename] = e import glob for f in glob.glob(self.filename + '.*'): try: os.remove(f) - except EnvironmentError as e: + except OSError as e: failed[f] = e self.set_output() return failed diff --git a/src/calibre/startup.py b/src/calibre/startup.py index 4d5131d66e..5e92a98d82 100644 --- a/src/calibre/startup.py +++ b/src/calibre/startup.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' @@ -52,7 +51,7 @@ def initialize_calibre(): from calibre.ptempfile import base_dir try: base_dir() - except EnvironmentError: + except OSError: pass # Ignore this error during startup, so we can show a better error message to the user later. # diff --git a/src/calibre/test_build.py b/src/calibre/test_build.py index 0d52db5957..5aef0cb0b8 100644 --- a/src/calibre/test_build.py +++ b/src/calibre/test_build.py @@ -71,7 +71,7 @@ class BuildTest(unittest.TestCase): def test_chardet(self): from cchardet import detect - raw = 'mūsi Füße'.encode('utf-8') + raw = 'mūsi Füße'.encode() data = detect(raw) self.assertEqual(data['encoding'].lower(), 'utf-8') self.assertGreater(data['confidence'], 0.5) diff --git a/src/calibre/translations/__init__.py b/src/calibre/translations/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/translations/__init__.py +++ b/src/calibre/translations/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/translations/dynamic.py b/src/calibre/translations/dynamic.py index 909c7325b9..97d1478fcf 100644 --- a/src/calibre/translations/dynamic.py +++ b/src/calibre/translations/dynamic.py @@ -1,4 +1,3 @@ - ''' Dynamic language lookup of translations for user-visible strings. ''' diff --git a/src/calibre/translations/msgfmt.py b/src/calibre/translations/msgfmt.py index 0e9b325a96..bba5225951 100644 --- a/src/calibre/translations/msgfmt.py +++ b/src/calibre/translations/msgfmt.py @@ -122,7 +122,7 @@ def make(filename, outfile): try: with open(infile, 'rb') as f: lines = f.readlines() - except IOError as msg: + except OSError as msg: print(msg, file=sys.stderr) sys.exit(1) @@ -230,7 +230,7 @@ def make(filename, outfile): else: with open(outfile, "wb") as f: f.write(output) - except IOError as msg: + except OSError as msg: print(msg, file=sys.stderr) diff --git a/src/calibre/utils/bibtex.py b/src/calibre/utils/bibtex.py index 5a8c726548..4063bb24b6 100644 --- a/src/calibre/utils/bibtex.py +++ b/src/calibre/utils/bibtex.py @@ -1,5 +1,3 @@ - - """ Collection of python utility-methodes commonly used by other bibliograph packages. From http://pypi.python.org/pypi/bibliograph.core/ diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index 68294d8733..4269070ac0 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' @@ -227,7 +225,7 @@ class DynamicConfig(dict): try: with share_open(path, 'rb') as f: raw = f.read() - except EnvironmentError: + except OSError: raw = b'' try: d = pickle_loads(raw).copy() @@ -324,13 +322,13 @@ class XMLConfig(dict): def mtime(self): try: return os.path.getmtime(self.file_path) - except EnvironmentError: + except OSError: return 0 def touch(self): try: os.utime(self.file_path, None) - except EnvironmentError: + except OSError: pass def raw_to_object(self, raw): diff --git a/src/calibre/utils/config_base.py b/src/calibre/utils/config_base.py index 9b9e1d4172..4e1bc6bd7c 100644 --- a/src/calibre/utils/config_base.py +++ b/src/calibre/utils/config_base.py @@ -255,7 +255,7 @@ class OptionSet: if opt.help: opt.help = t(opt.help) if opt.name == 'use_primary_find_in_search': - opt.help = opt.help.format(u'ñ') + opt.help = opt.help.format('ñ') def option_parser(self, user_defaults=None, usage='', gui_mode=False): from calibre.utils.config import OptionParser @@ -295,7 +295,7 @@ class OptionSet: def parse_string(self, src): options = {} if src: - is_old_style = (isinstance(src, bytes) and src.startswith(b'#')) or (isinstance(src, str) and src.startswith(u'#')) + is_old_style = (isinstance(src, bytes) and src.startswith(b'#')) or (isinstance(src, str) and src.startswith('#')) if is_old_style: options = parse_old_style(src) else: @@ -477,7 +477,7 @@ def create_global_prefs(conf_obj=None): c.add_opt('database_path', default=os.path.expanduser('~/library1.db'), help=_('Path to the database in which books are stored')) - c.add_opt('filename_pattern', default=u'(?P.+) - (?P<author>[^_]+)', + c.add_opt('filename_pattern', default='(?P<title>.+) - (?P<author>[^_]+)', help=_('Pattern to guess metadata from filenames')) c.add_opt('isbndb_com_key', default='', help=_('Access key for isbndb.com')) @@ -532,10 +532,10 @@ def create_global_prefs(conf_obj=None): 'separated by commas. Only takes effect if you set the option ' 'to limit search columns above.')) c.add_opt('use_primary_find_in_search', default=True, - help=_(u'Characters typed in the search box will match their ' + help=_('Characters typed in the search box will match their ' 'accented versions, based on the language you have chosen ' 'for the calibre interface. For example, in ' - u'English, searching for n will match both {} and n, but if ' + 'English, searching for n will match both {} and n, but if ' 'your language is Spanish it will only match n. Note that ' 'this is much slower than a simple search on very large ' 'libraries. Also, this option will have no effect if you turn ' diff --git a/src/calibre/utils/exim.py b/src/calibre/utils/exim.py index 3492ed17e2..97a4ba8c62 100644 --- a/src/calibre/utils/exim.py +++ b/src/calibre/utils/exim.py @@ -142,7 +142,7 @@ class Exporter: try: with lopen(fpath, 'rb') as f: self.add_file(f, key) - except EnvironmentError: + except OSError: if not iswindows: raise time.sleep(1) @@ -290,7 +290,7 @@ class Importer: try: with lopen(path, 'wb') as dest: shutil.copyfileobj(f, dest) - except EnvironmentError: + except OSError: os.makedirs(os.path.dirname(path)) with lopen(path, 'wb') as dest: shutil.copyfileobj(f, dest) @@ -299,7 +299,7 @@ class Importer: try: with lopen(gpath, 'rb') as f: raw = f.read() - except EnvironmentError: + except OSError: raw = b'' try: lpath = library_usage_stats.most_common(1)[0][0] @@ -332,7 +332,7 @@ def import_data(importer, library_path_map, config_location=None, progress1=None progress1(dest, i, total) try: os.makedirs(dest) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise if not os.path.isdir(dest): @@ -355,14 +355,14 @@ def import_data(importer, library_path_map, config_location=None, progress1=None if os.path.exists(config_location): try: shutil.rmtree(config_location) - except EnvironmentError: + except OSError: if not iswindows: raise time.sleep(1) shutil.rmtree(config_location) try: os.rename(base_dir, config_location) - except EnvironmentError: + except OSError: time.sleep(2) os.rename(base_dir, config_location) from calibre.gui2 import gprefs @@ -384,7 +384,7 @@ def test_import(export_dir='/t/ex', import_dir='/t/imp'): def cli_report(*args, **kw): try: prints(*args, **kw) - except EnvironmentError: + except OSError: pass diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index ba934e3d81..08202faee5 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -1,4 +1,3 @@ - ''' Make strings safe for use as ASCII filenames, while trying to preserve as much meaning as possible. @@ -208,7 +207,7 @@ def case_preserving_open_file(path, mode='wb', mkdir_mode=0o777): cl = fname.lower() try: candidates = [c for c in os.listdir(cpath) if c.lower() == cl] - except EnvironmentError: + except OSError: # The containing directory, somehow disappeared? candidates = [] if len(candidates) == 1: @@ -259,7 +258,7 @@ def samefile(src, dst): # Unix try: return os.path.samefile(src, dst) - except EnvironmentError: + except OSError: return False # All other platforms: check for same pathname. @@ -294,7 +293,7 @@ def windows_hardlink(src, dest): try: if windows_get_size(dest) == src_size: return - except EnvironmentError: + except OSError: pass time.sleep(0.3) @@ -575,7 +574,7 @@ def copytree_using_links(path, dest, dest_is_parent=True, filecopyfunc=copyfile) hardlink = get_hardlink_function(path, dest) try: os.makedirs(dest) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EEXIST: raise for dirpath, dirnames, filenames in os.walk(path): @@ -584,7 +583,7 @@ def copytree_using_links(path, dest, dest_is_parent=True, filecopyfunc=copyfile) for dname in dirnames: try: os.mkdir(os.path.join(dest_base, dname)) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EEXIST: raise for fname in filenames: diff --git a/src/calibre/utils/fonts/scanner.py b/src/calibre/utils/fonts/scanner.py index bbefd8b357..2d967bfbbe 100644 --- a/src/calibre/utils/fonts/scanner.py +++ b/src/calibre/utils/fonts/scanner.py @@ -271,7 +271,7 @@ class FontScanner(Thread): from calibre.utils.fonts.utils import (supports_text, panose_to_css_generic_family, get_printable_characters) if not isinstance(text, str): - raise TypeError(u'%r is not unicode'%text) + raise TypeError('%r is not unicode'%text) text = get_printable_characters(text) found = {} @@ -329,7 +329,7 @@ class FontScanner(Thread): continue try: files = tuple(walk(folder)) - except EnvironmentError as e: + except OSError as e: if DEBUG: prints('Failed to walk font folder:', folder, as_unicode(e)) @@ -340,9 +340,9 @@ class FontScanner(Thread): candidate = os.path.normcase(os.path.abspath(candidate)) try: s = os.stat(candidate) - except EnvironmentError: + except OSError: continue - fileid = '{0}||{1}:{2}'.format(candidate, s.st_size, s.st_mtime) + fileid = '{}||{}:{}'.format(candidate, s.st_size, s.st_mtime) if fileid in cached_fonts: # Use previously cached metadata, since the file size and # last modified timestamp have not changed. diff --git a/src/calibre/utils/fonts/sfnt/cff/table.py b/src/calibre/utils/fonts/sfnt/cff/table.py index 9bc6b4eefa..943b5e6eca 100644 --- a/src/calibre/utils/fonts/sfnt/cff/table.py +++ b/src/calibre/utils/fonts/sfnt/cff/table.py @@ -125,14 +125,14 @@ class Index(list): class Strings(Index): def __init__(self, raw, offset): - super(Strings, self).__init__(raw, offset, prepend=[x.encode('ascii') + super().__init__(raw, offset, prepend=[x.encode('ascii') for x in cff_standard_strings]) class Charset(list): def __init__(self, raw, offset, strings, num_glyphs, is_CID): - super(Charset, self).__init__() + super().__init__() self.standard_charset = offset if offset in {0, 1, 2} else None if is_CID and self.standard_charset is not None: raise ValueError("CID font must not use a standard charset") diff --git a/src/calibre/utils/fonts/sfnt/cmap.py b/src/calibre/utils/fonts/sfnt/cmap.py index d0e706b51e..7caae73d9d 100644 --- a/src/calibre/utils/fonts/sfnt/cmap.py +++ b/src/calibre/utils/fonts/sfnt/cmap.py @@ -170,7 +170,7 @@ class BMPTable: class CmapTable(UnknownTable): def __init__(self, *args, **kwargs): - super(CmapTable, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.version, self.num_tables = unpack_from(b'>HH', self.raw) diff --git a/src/calibre/utils/fonts/sfnt/container.py b/src/calibre/utils/fonts/sfnt/container.py index 6791a95eb9..1655bd601f 100644 --- a/src/calibre/utils/fonts/sfnt/container.py +++ b/src/calibre/utils/fonts/sfnt/container.py @@ -79,8 +79,7 @@ class Sfnt: def __iter__(self): '''Iterate over the table tags in order.''' - for x in sorted(self.tables): - yield x + yield from sorted(self.tables) # Although the optimal order is not alphabetical, the OTF spec says # they should be alphabetical, so we stick with that. See # http://partners.adobe.com/public/developer/opentype/index_recs.html diff --git a/src/calibre/utils/fonts/sfnt/glyf.py b/src/calibre/utils/fonts/sfnt/glyf.py index 44c9050dbd..da4d157fb3 100644 --- a/src/calibre/utils/fonts/sfnt/glyf.py +++ b/src/calibre/utils/fonts/sfnt/glyf.py @@ -47,7 +47,7 @@ class SimpleGlyph: class CompositeGlyph(SimpleGlyph): def __init__(self, num_of_countours, raw): - super(CompositeGlyph, self).__init__(num_of_countours, raw) + super().__init__(num_of_countours, raw) self.is_composite = True flags = MORE_COMPONENTS diff --git a/src/calibre/utils/fonts/sfnt/head.py b/src/calibre/utils/fonts/sfnt/head.py index 3124bb37c3..b4c57e6961 100644 --- a/src/calibre/utils/fonts/sfnt/head.py +++ b/src/calibre/utils/fonts/sfnt/head.py @@ -22,7 +22,7 @@ class HeadTable(UnknownTable): font_revision = FixedProperty('_font_revision') def __init__(self, *args, **kwargs): - super(HeadTable, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) field_types = ( '_version_number' , 'l', diff --git a/src/calibre/utils/fonts/sfnt/kern.py b/src/calibre/utils/fonts/sfnt/kern.py index 5cf90a4418..5e94caf729 100644 --- a/src/calibre/utils/fonts/sfnt/kern.py +++ b/src/calibre/utils/fonts/sfnt/kern.py @@ -18,7 +18,7 @@ class KernTable(UnknownTable): version = FixedProperty('_version') def __init__(self, *args, **kwargs): - super(KernTable, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._version, self.num_tables = unpack_from(b'>HH', self.raw) if self._version == 1 and len(self.raw) >= 8: self._version, self.num_tables = unpack_from(b'>LL', self.raw) diff --git a/src/calibre/utils/fonts/sfnt/maxp.py b/src/calibre/utils/fonts/sfnt/maxp.py index 32558f63b5..3067976728 100644 --- a/src/calibre/utils/fonts/sfnt/maxp.py +++ b/src/calibre/utils/fonts/sfnt/maxp.py @@ -17,7 +17,7 @@ class MaxpTable(UnknownTable): version = FixedProperty('_version') def __init__(self, *args, **kwargs): - super(MaxpTable, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._fmt = b'>lH' self._version, self.num_glyphs = unpack_from(self._fmt, self.raw) diff --git a/src/calibre/utils/fonts/sfnt/subset.py b/src/calibre/utils/fonts/sfnt/subset.py index 9fcdada014..9a037cbc23 100644 --- a/src/calibre/utils/fonts/sfnt/subset.py +++ b/src/calibre/utils/fonts/sfnt/subset.py @@ -324,7 +324,7 @@ def test_mem(): def test(): raw = P('fonts/liberation/LiberationSerif-Regular.ttf', data=True) - sf, old_stats, new_stats = subset(raw, set(('a', 'b', 'c')), ()) + sf, old_stats, new_stats = subset(raw, {'a', 'b', 'c'}, ()) if len(sf) > 0.3 * len(raw): raise Exception('Subsetting failed') @@ -343,7 +343,7 @@ def all(): total += 1 try: w = [] - sf, old_stats, new_stats = subset(raw, set(('a', 'b', 'c')), + sf, old_stats, new_stats = subset(raw, {'a', 'b', 'c'}, (), w) if w: warnings[font['full_name'] + ' (%s)'%font['path']] = w diff --git a/src/calibre/utils/fonts/utils.py b/src/calibre/utils/fonts/utils.py index 3e61d42981..e74b8d9ce1 100644 --- a/src/calibre/utils/fonts/utils.py +++ b/src/calibre/utils/fonts/utils.py @@ -19,7 +19,7 @@ class UnsupportedFont(ValueError): def get_printable_characters(text): import unicodedata - return u''.join(x for x in unicodedata.normalize('NFC', text) + return ''.join(x for x in unicodedata.normalize('NFC', text) if unicodedata.category(x)[0] not in {'C', 'Z', 'M'}) @@ -418,8 +418,7 @@ def get_glyph_ids(raw, text, raw_is_table=False): if bmp_table is None: raise UnsupportedFont('Not a supported font, has no format 4 cmap table') - for glyph_id in get_bmp_glyph_ids(table, bmp_table, map(ord, text)): - yield glyph_id + yield from get_bmp_glyph_ids(table, bmp_table, map(ord, text)) def supports_text(raw, text, has_only_printable_chars=False): @@ -454,7 +453,7 @@ def test_glyph_ids(): data = P('fonts/liberation/LiberationSerif-Regular.ttf', data=True) ft = FreeType() font = ft.load_font(data) - text = u'诶йab' + text = '诶йab' ft_glyphs = tuple(font.glyph_ids(text)) glyphs = tuple(get_glyph_ids(data, text)) if ft_glyphs != glyphs: diff --git a/src/calibre/utils/formatter.py b/src/calibre/utils/formatter.py index 14acf8735c..c9773e793a 100644 --- a/src/calibre/utils/formatter.py +++ b/src/calibre/utils/formatter.py @@ -1,4 +1,3 @@ - ''' Created on 23 Sep 2010 diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 78dc90fcb6..a625e4905e 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -1776,7 +1776,7 @@ class BuiltinUserCategories(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals_): if hasattr(mi, '_proxy_metadata'): - cats = set(k for k, v in iteritems(mi._proxy_metadata.user_categories) if v) + cats = {k for k, v in iteritems(mi._proxy_metadata.user_categories) if v} cats = sorted(cats, key=sort_key) return ', '.join(cats) return _('This function can be used only in the GUI') @@ -1790,7 +1790,7 @@ class BuiltinTransliterate(BuiltinFormatterFunction): 'formed by approximating the sound of the words in the ' 'source string. For example, if the source is "{0}"' ' the function returns "{1}".').format( - u"Фёдор Миха́йлович Достоевский", 'Fiodor Mikhailovich Dostoievskii') + "Фёдор Миха́йлович Достоевский", 'Fiodor Mikhailovich Dostoievskii') def evaluate(self, formatter, kwargs, mi, locals, source): from calibre.utils.filenames import ascii_text @@ -1866,7 +1866,7 @@ class BuiltinConnectedDeviceName(BuiltinFormatterFunction): try: if storage_location not in {'main', 'carda', 'cardb'}: raise ValueError( - _('connected_device_name: invalid storage location "{0}"' + _('connected_device_name: invalid storage location "{}"' .format(storage_location))) info = info['info'][4] if storage_location not in info: @@ -1900,7 +1900,7 @@ class BuiltinConnectedDeviceUUID(BuiltinFormatterFunction): try: if storage_location not in {'main', 'carda', 'cardb'}: raise ValueError( - _('connected_device_name: invalid storage location "{0}"' + _('connected_device_name: invalid storage location "{}"' .format(storage_location))) info = info['info'][4] if storage_location not in info: diff --git a/src/calibre/utils/hyphenation/dictionaries.py b/src/calibre/utils/hyphenation/dictionaries.py index 39fd6928e4..d6cb5d9174 100644 --- a/src/calibre/utils/hyphenation/dictionaries.py +++ b/src/calibre/utils/hyphenation/dictionaries.py @@ -79,7 +79,7 @@ def extract_dicts(cache_path): with TemporaryDirectory(dir=cache_path) as trash: try: os.rename(dest, os.path.join(trash, 'f')) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise os.rename(tdir, dest) @@ -95,7 +95,7 @@ def is_cache_up_to_date(cache_path): if actual_hash == expected_hash(): is_cache_up_to_date.updated = True return True - except EnvironmentError: + except OSError: pass return False @@ -105,7 +105,7 @@ def get_cache_path(cd): cache_path = os.path.join(cd, 'hyphenation') try: os.makedirs(cache_path) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.EEXIST: raise return cache_path diff --git a/src/calibre/utils/hyphenation/test_hyphenation.py b/src/calibre/utils/hyphenation/test_hyphenation.py index 7360ebd59b..467c07af52 100644 --- a/src/calibre/utils/hyphenation/test_hyphenation.py +++ b/src/calibre/utils/hyphenation/test_hyphenation.py @@ -40,7 +40,7 @@ class TestHyphenation(unittest.TestCase): is_cache_up_to_date.updated = False try: shutil.rmtree(path_to_dictionary.cache_dir) - except EnvironmentError: + except OSError: pass path_to_dictionary.cache_dir = None diff --git a/src/calibre/utils/icu_test.py b/src/calibre/utils/icu_test.py index 281288e0e9..e628cb5725 100644 --- a/src/calibre/utils/icu_test.py +++ b/src/calibre/utils/icu_test.py @@ -65,7 +65,7 @@ class TestICU(unittest.TestCase): with make_collation_func('scmp', 'es', maker=icu.make_two_arg_func) as scmp: self.assertNotEqual(0, scmp('pena', 'peña')) - for k, v in iteritems({u'pèché': u'peche', u'flüße':u'Flusse', u'Štepánek':u'ŠtepaneK'}): + for k, v in iteritems({'pèché': 'peche', 'flüße':'Flusse', 'Štepánek':'ŠtepaneK'}): self.ae(0, icu.primary_strcmp(k, v)) # Test different types of collation @@ -99,7 +99,7 @@ class TestICU(unittest.TestCase): self.ae((1, 1), icu.find('\U0001f431', 'x\U0001f431x')) self.ae((1, 1), icu.find('y', '\U0001f431y')) self.ae((0, 4), icu.primary_find('pena', 'peña')) - for k, v in iteritems({u'pèché': u'peche', u'flüße':u'Flusse', u'Štepánek':u'ŠtepaneK'}): + for k, v in iteritems({'pèché': 'peche', 'flüße':'Flusse', 'Štepánek':'ŠtepaneK'}): self.ae((1, len(k)), icu.primary_find(v, ' ' + k), 'Failed to find %s in %s' % (v, k)) self.assertTrue(icu.startswith(b'abc', b'ab')) self.assertTrue(icu.startswith('abc', 'abc')) @@ -131,7 +131,7 @@ class TestICU(unittest.TestCase): def test_roundtrip(self): ' Test roundtripping ' - for r in (u'xxx\0\u2219\U0001f431xxx', u'\0', u'', u'simple'): + for r in ('xxx\0\u2219\U0001f431xxx', '\0', '', 'simple'): self.ae(r, icu._icu.roundtrip(r)) self.ae(icu._icu.roundtrip('\ud8e81'), '\ufffd1') self.ae(icu._icu.roundtrip('\udc01\ud8e8'), '\ufffd\ufffd') @@ -156,20 +156,20 @@ class TestICU(unittest.TestCase): ' Test contractions ' self.skipTest('Skipping as this depends too much on ICU version') c = icu._icu.Collator('cs') - self.ae(icu.contractions(c), frozenset({u'Z\u030c', u'z\u030c', u'Ch', - u'C\u030c', u'ch', u'cH', u'c\u030c', u's\u030c', u'r\u030c', u'CH', - u'S\u030c', u'R\u030c'})) + self.ae(icu.contractions(c), frozenset({'Z\u030c', 'z\u030c', 'Ch', + 'C\u030c', 'ch', 'cH', 'c\u030c', 's\u030c', 'r\u030c', 'CH', + 'S\u030c', 'R\u030c'})) def test_break_iterator(self): ' Test the break iterator ' from calibre.spell.break_iterator import split_into_words as split, index_of, split_into_words_and_positions, count_words for q in ('one two three', ' one two three', 'one\ntwo three ', ): self.ae(split(str(q)), ['one', 'two', 'three'], 'Failed to split: %r' % q) - self.ae(split(u'I I\'m'), ['I', "I'm"]) - self.ae(split(u'out-of-the-box'), ['out-of-the-box']) - self.ae(split(u'-one two-'), ['-one', 'two-']) - self.ae(split(u'-one a-b-c-d e'), ['-one', 'a-b-c-d', 'e']) - self.ae(split(u'-one -a-b-c-d- e'), ['-one', '-a-b-c-d-', 'e']) + self.ae(split('I I\'m'), ['I', "I'm"]) + self.ae(split('out-of-the-box'), ['out-of-the-box']) + self.ae(split('-one two-'), ['-one', 'two-']) + self.ae(split('-one a-b-c-d e'), ['-one', 'a-b-c-d', 'e']) + self.ae(split('-one -a-b-c-d- e'), ['-one', '-a-b-c-d-', 'e']) self.ae(split_into_words_and_positions('one \U0001f431 three'), [(0, 3), (6, 5)]) self.ae(count_words('a b c d e f'), 6) for needle, haystack, pos in ( diff --git a/src/calibre/utils/img.py b/src/calibre/utils/img.py index e97c22d316..0652b55fad 100644 --- a/src/calibre/utils/img.py +++ b/src/calibre/utils/img.py @@ -570,7 +570,7 @@ def run_optimizer(file_path, cmd, as_filter=False, input_data=None): outw.join(60.0), inw.join(60.0) try: sz = os.path.getsize(outfile) - except EnvironmentError: + except OSError: sz = 0 if sz < 1: return '%s returned a zero size image' % cmd[0] @@ -579,12 +579,12 @@ def run_optimizer(file_path, cmd, as_filter=False, input_data=None): finally: try: os.remove(outfile) - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise try: os.remove(outfile + '.bak') # optipng creates these files - except EnvironmentError as err: + except OSError as err: if err.errno != errno.ENOENT: raise diff --git a/src/calibre/utils/inotify.py b/src/calibre/utils/inotify.py index b4904ad28d..fc2e47fcfe 100644 --- a/src/calibre/utils/inotify.py +++ b/src/calibre/utils/inotify.py @@ -23,7 +23,7 @@ class BaseDirChanged(ValueError): class DirTooLarge(ValueError): def __init__(self, bdir): - ValueError.__init__(self, 'The directory {0} is too large to monitor. Try increasing the value in /proc/sys/fs/inotify/max_user_watches'.format(bdir)) + ValueError.__init__(self, 'The directory {} is too large to monitor. Try increasing the value in /proc/sys/fs/inotify/max_user_watches'.format(bdir)) _inotify = None @@ -212,7 +212,7 @@ class INotifyTreeWatcher(INotify): is_dummy = False def __init__(self, basedir, ignore_event=None): - super(INotifyTreeWatcher, self).__init__() + super().__init__() self.basedir = realpath(basedir) self.watch_tree() self.modified = set() @@ -242,13 +242,13 @@ class INotifyTreeWatcher(INotify): # The entry could have been deleted between listdir() and # add_watch(). if top_level: - raise NoSuchDir('The dir {0} does not exist'.format(base)) + raise NoSuchDir('The dir {} does not exist'.format(base)) return if e.errno == errno.EACCES: # We silently ignore entries for which we dont have permission, # unless they are the top level dir if top_level: - raise NoSuchDir('You do not have permission to monitor {0}'.format(base)) + raise NoSuchDir('You do not have permission to monitor {}'.format(base)) return raise else: @@ -260,14 +260,14 @@ class INotifyTreeWatcher(INotify): # The dir was deleted/replaced between the add_watch() # and listdir() if top_level: - raise NoSuchDir('The dir {0} does not exist'.format(base)) + raise NoSuchDir('The dir {} does not exist'.format(base)) return raise for x in files: self.add_watches(os.path.join(base, x), top_level=False) elif top_level: # The top level dir is a file, not good. - raise NoSuchDir('The dir {0} does not exist'.format(base)) + raise NoSuchDir('The dir {} does not exist'.format(base)) def add_watch(self, path): import ctypes @@ -283,7 +283,7 @@ class INotifyTreeWatcher(INotify): eno = ctypes.get_errno() if eno == errno.ENOTDIR: return False - raise OSError(eno, 'Failed to add watch for: {0}: {1}'.format(path, self.os.strerror(eno))) + raise OSError(eno, 'Failed to add watch for: {}: {}'.format(path, self.os.strerror(eno))) self.watched_dirs[path] = wd self.watched_rmap[wd] = path return True diff --git a/src/calibre/utils/ipc/__init__.py b/src/calibre/utils/ipc/__init__.py index b8e688553a..b94651333e 100644 --- a/src/calibre/utils/ipc/__init__.py +++ b/src/calibre/utils/ipc/__init__.py @@ -23,7 +23,7 @@ def eintr_retry_call(func, *args, **kwargs): while True: try: return func(*args, **kwargs) - except EnvironmentError as e: + except OSError as e: if getattr(e, 'errno', None) == errno.EINTR: continue raise diff --git a/src/calibre/utils/ipc/launch.py b/src/calibre/utils/ipc/launch.py index 2498af4c51..6d970bfb08 100644 --- a/src/calibre/utils/ipc/launch.py +++ b/src/calibre/utils/ipc/launch.py @@ -153,7 +153,7 @@ class Worker: env = self.env try: origwd = cwd or os.path.abspath(os.getcwd()) - except EnvironmentError: + except OSError: # cwd no longer exists origwd = cwd or os.path.expanduser('~') env[native_string_type('ORIGWD')] = environ_item(as_hex_unicode(msgpack_dumps(origwd))) diff --git a/src/calibre/utils/ipc/pool.py b/src/calibre/utils/ipc/pool.py index b150389b81..32c6d24ce3 100644 --- a/src/calibre/utils/ipc/pool.py +++ b/src/calibre/utils/ipc/pool.py @@ -60,11 +60,11 @@ def get_stdout(process): if raw: try: sys.stdout.buffer.write(raw) - except EnvironmentError: + except OSError: pass else: time.sleep(0.1) - except (EOFError, EnvironmentError): + except (EOFError, OSError): break @@ -294,7 +294,7 @@ class Pool(Thread): if worker.process.poll() is None: try: worker.process.terminate() - except EnvironmentError: + except OSError: pass # If the process has already been killed workers = [w.process for w in self.available_workers + list(self.busy_workers)] aw = list(self.available_workers) @@ -323,14 +323,14 @@ class Pool(Thread): if w.poll() is None: try: w.kill() - except EnvironmentError: + except OSError: pass del self.available_workers[:] self.busy_workers.clear() if hasattr(self, 'cd_file'): try: os.remove(self.cd_file.name) - except EnvironmentError: + except OSError: pass diff --git a/src/calibre/utils/ipc/simple_worker.py b/src/calibre/utils/ipc/simple_worker.py index 1cc36aa8a5..e834da9498 100644 --- a/src/calibre/utils/ipc/simple_worker.py +++ b/src/calibre/utils/ipc/simple_worker.py @@ -71,7 +71,7 @@ class OffloadWorker: def shutdown(self): try: eintr_retry_call(self.conn.send, None) - except IOError: + except OSError: pass except: import traceback diff --git a/src/calibre/utils/ipc/worker.py b/src/calibre/utils/ipc/worker.py index 2113e3f6e8..0240131143 100644 --- a/src/calibre/utils/ipc/worker.py +++ b/src/calibre/utils/ipc/worker.py @@ -223,11 +223,11 @@ def main(): try: sys.stdout.flush() - except EnvironmentError: + except OSError: pass # Happens sometimes on OS X for GUI processes (EPIPE) try: sys.stderr.flush() - except EnvironmentError: + except OSError: pass # Happens sometimes on OS X for GUI processes (EPIPE) return 0 diff --git a/src/calibre/utils/iso8601.py b/src/calibre/utils/iso8601.py index 09acabda09..7689a4eae1 100644 --- a/src/calibre/utils/iso8601.py +++ b/src/calibre/utils/iso8601.py @@ -16,7 +16,7 @@ class SafeLocalTimeZone(tzlocal): # older versions of dateutil) # In such cases, just assume that dt is not DST. try: - return super(SafeLocalTimeZone, self)._isdst(dt) + return super()._isdst(dt) except Exception: pass return False @@ -26,7 +26,7 @@ class SafeLocalTimeZone(tzlocal): # newer versions of dateutil) # In such cases, just assume that dt is not DST. try: - return super(SafeLocalTimeZone, self)._naive_is_dst(dt) + return super()._naive_is_dst(dt) except Exception: pass return False diff --git a/src/calibre/utils/localization.py b/src/calibre/utils/localization.py index de9c4a3f4c..e005c45eb7 100644 --- a/src/calibre/utils/localization.py +++ b/src/calibre/utils/localization.py @@ -522,7 +522,7 @@ def user_manual_stats(): import json try: stats = json.loads(P('user-manual-translation-stats.json', allow_user_override=False, data=True)) - except EnvironmentError: + except OSError: stats = {} user_manual_stats.stats = stats return stats @@ -549,7 +549,7 @@ def website_languages(): if stats is None: try: stats = frozenset(P('localization/website-languages.txt', allow_user_override=False, data=True).decode('utf-8').split()) - except EnvironmentError: + except OSError: stats = frozenset() website_languages.stats = stats return stats diff --git a/src/calibre/utils/localunzip.py b/src/calibre/utils/localunzip.py index 1bd9c029e1..7c8d2280ae 100644 --- a/src/calibre/utils/localunzip.py +++ b/src/calibre/utils/localunzip.py @@ -223,7 +223,7 @@ def _extractall(f, path=None, file_info=None): dest = os.path.join(path, *parts) try: df = open(dest, 'wb') - except EnvironmentError: + except OSError: if is_reserved_filename(os.path.basename(dest)): raise ValueError('This ZIP file contains a file with a reserved filename' ' that cannot be processed on Windows: {}'.format(os.path.basename(dest))) diff --git a/src/calibre/utils/lock.py b/src/calibre/utils/lock.py index 12046f018a..36237c34fb 100644 --- a/src/calibre/utils/lock.py +++ b/src/calibre/utils/lock.py @@ -33,7 +33,7 @@ def unix_open(path): try: fd = os.open(path, flags | speedup.O_CLOEXEC, excl_file_mode) has_cloexec = True - except EnvironmentError as err: + except OSError as err: # Kernel may not support O_CLOEXEC if err.errno != errno.EINVAL: raise @@ -76,7 +76,7 @@ def retry_for_a_time(timeout, sleep_time, func, error_retry, *args): while True: try: return func(*args) - except EnvironmentError as err: + except OSError as err: if not error_retry(err) or monotonic() > limit: raise time.sleep(sleep_time) @@ -115,11 +115,11 @@ class ExclusiveFile: def _clean_lock_file(file_obj): try: os.remove(file_obj.name) - except EnvironmentError: + except OSError: pass try: file_obj.close() - except EnvironmentError: + except OSError: pass @@ -147,7 +147,7 @@ elif islinux: sock = socket.socket(family=socket.AF_UNIX) try: eintr_retry_call(sock.bind, address) - except socket.error as err: + except OSError as err: sock.close() if getattr(err, 'errno', None) == errno.EADDRINUSE: return @@ -170,7 +170,7 @@ else: for loc in locs: if os.access(loc, os.W_OK | os.R_OK | os.X_OK): return os.path.join(loc, ('.' if loc is home else '') + name) - raise EnvironmentError( + raise OSError( 'Failed to find a suitable filesystem location for the lock file' ) @@ -181,7 +181,7 @@ else: try: eintr_retry_call(fcntl.lockf, f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) return partial(_clean_lock_file, f) - except EnvironmentError as err: + except OSError as err: f.close() if err.errno not in (errno.EAGAIN, errno.EACCES): raise diff --git a/src/calibre/utils/matcher.py b/src/calibre/utils/matcher.py index 0548162723..b78f63b7d0 100644 --- a/src/calibre/utils/matcher.py +++ b/src/calibre/utils/matcher.py @@ -264,8 +264,7 @@ class CScorer: def __call__(self, query): scores, positions = self.m.calculate_scores(query) - for score, pos in zip(scores, positions): - yield score, pos + yield from zip(scores, positions) def test(return_tests=False): diff --git a/src/calibre/utils/mdns.py b/src/calibre/utils/mdns.py index fc299472b8..c094abc1c0 100644 --- a/src/calibre/utils/mdns.py +++ b/src/calibre/utils/mdns.py @@ -84,7 +84,7 @@ def verify_ipV4_address(ip_address): socket.inet_aton(ip_address) if len(ip_address.split('.')) == 4: result = ip_address - except (socket.error, OSError): + except OSError: # Not legal ip address pass return result diff --git a/src/calibre/utils/open_with/__init__.py b/src/calibre/utils/open_with/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/utils/open_with/__init__.py +++ b/src/calibre/utils/open_with/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/utils/open_with/linux.py b/src/calibre/utils/open_with/linux.py index 98dfe08cd9..7c802e6237 100644 --- a/src/calibre/utils/open_with/linux.py +++ b/src/calibre/utils/open_with/linux.py @@ -38,7 +38,7 @@ def parse_desktop_file(path): try: with open(path, 'rb') as f: raw = f.read().decode('utf-8') - except (EnvironmentError, UnicodeDecodeError): + except (OSError, UnicodeDecodeError): return group = None ans = {} @@ -131,14 +131,14 @@ def find_icons(): for loc in base_dirs: try: subdirs = os.listdir(loc) - except EnvironmentError: + except OSError: continue for dname in subdirs: d = os.path.join(loc, dname) if os.path.isdir(d): try: mtime = os.stat(d).st_mtime - except EnvironmentError: + except OSError: continue seen_dirs.add(d) if mtime != mtimes[d]: diff --git a/src/calibre/utils/open_with/osx.py b/src/calibre/utils/open_with/osx.py index 5dd3f8cc21..a98988db91 100644 --- a/src/calibre/utils/open_with/osx.py +++ b/src/calibre/utils/open_with/osx.py @@ -215,7 +215,7 @@ PUBLIC_UTI_RMAP = dict(PUBLIC_UTI_RMAP) def find_applications_in(base): try: entries = os.listdir(base) - except EnvironmentError: + except OSError: return for name in entries: path = os.path.join(base, name) @@ -223,15 +223,13 @@ def find_applications_in(base): if name.lower().endswith('.app'): yield path else: - for app in find_applications_in(path): - yield app + yield from find_applications_in(path) def find_applications(): for base in application_locations: base = os.path.expanduser(base) - for app in find_applications_in(base): - yield app + yield from find_applications_in(base) def get_extensions_from_utis(utis, plist): @@ -325,7 +323,7 @@ def get_icon(path, pixmap_to_data=None, as_data=False, size=64): return try: names = os.listdir(iconset) - except EnvironmentError: + except OSError: return if not names: return diff --git a/src/calibre/utils/opensearch/__init__.py b/src/calibre/utils/opensearch/__init__.py index b364b9dbac..134a07e2e2 100644 --- a/src/calibre/utils/opensearch/__init__.py +++ b/src/calibre/utils/opensearch/__init__.py @@ -1,5 +1,3 @@ - - ''' Based on the OpenSearch Python module by Ed Summers <ehs@pobox.com> from https://github.com/edsu/opensearch . diff --git a/src/calibre/utils/rapydscript.py b/src/calibre/utils/rapydscript.py index 7c2e44344e..d7299be32a 100644 --- a/src/calibre/utils/rapydscript.py +++ b/src/calibre/utils/rapydscript.py @@ -196,7 +196,7 @@ def module_cache_dir(): _cache_dir = os.path.join(base, '.build-cache', 'pyj') try: os.makedirs(_cache_dir) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EEXIST: raise return _cache_dir diff --git a/src/calibre/utils/run_tests.py b/src/calibre/utils/run_tests.py index 2b5034b01b..0592f43b3f 100644 --- a/src/calibre/utils/run_tests.py +++ b/src/calibre/utils/run_tests.py @@ -23,7 +23,7 @@ def no_endl(f): class TestResult(unittest.TextTestResult): def __init__(self, *args, **kwargs): - super(TestResult, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.start_time = {} for x in ('Success', 'Error', 'Failure', 'Skip', 'ExpectedFailure', 'UnexpectedSuccess'): x = 'add' + x @@ -32,12 +32,12 @@ class TestResult(unittest.TextTestResult): def startTest(self, test): self.start_time[test] = monotonic() - return super(TestResult, self).startTest(test) + return super().startTest(test) def stopTest(self, test): orig = self.stream.writeln self.stream.writeln = self.stream.write - super(TestResult, self).stopTest(test) + super().stopTest(test) elapsed = monotonic() elapsed -= self.start_time.get(test, elapsed) self.times[test] = elapsed @@ -45,7 +45,7 @@ class TestResult(unittest.TextTestResult): self.stream.writeln(' [%.1f s]' % elapsed) def stopTestRun(self): - super(TestResult, self).stopTestRun() + super().stopTestRun() if self.wasSuccessful(): tests = sorted(self.times, key=self.times.get, reverse=True) slowest = ['%s [%.1f s]' % (t.id(), self.times[t]) for t in tests[:3]] diff --git a/src/calibre/utils/search_query_parser_test.py b/src/calibre/utils/search_query_parser_test.py index 49807def13..cadd9f1987 100644 --- a/src/calibre/utils/search_query_parser_test.py +++ b/src/calibre/utils/search_query_parser_test.py @@ -12,292 +12,292 @@ from calibre.utils.search_query_parser import SearchQueryParser, Parser class Tester(SearchQueryParser): texts = { - 1: [u'Eugenie Grandet', u'Honor\xe9 de Balzac', u'manybooks.net', u'lrf'], - 2: [u'Fanny Hill', u'John Cleland', u'manybooks.net', u'lrf'], - 3: [u'Persuasion', u'Jane Austen', u'manybooks.net', u'lrf'], - 4: [u'Psmith, Journalist', u'P. G. Wodehouse', u'Some Publisher', u'lrf'], - 5: [u'The Complete Works of William Shakespeare', - u'William Shakespeare', - u'manybooks.net', - u'lrf'], - 6: [u'The History of England, Volume I', - u'David Hume', - u'manybooks.net', - u'lrf'], - 7: [u'Someone Comes to Town, Someone Leaves Town', - u'Cory Doctorow', - u'Tor Books', - u'lrf'], - 8: [u'Stalky and Co.', u'Rudyard Kipling', u'manybooks.net', u'lrf'], - 9: [u'A Game of Thrones', u'George R. R. Martin', None, u'lrf,rar'], - 10: [u'A Clash of Kings', u'George R. R. Martin', None, u'lrf,rar'], - 11: [u'A Storm of Swords', u'George R. R. Martin', None, u'lrf,rar'], - 12: [u'Biggles - Pioneer Air Fighter', u'W. E. Johns', None, u'lrf,rtf'], - 13: [u'Biggles of the Camel Squadron', - u'W. E. Johns', - u'London:Thames, (1977)', - u'lrf,rtf'], - 14: [u'A Feast for Crows', u'George R. R. Martin', None, u'lrf,rar'], - 15: [u'Cryptonomicon', u'Neal Stephenson', None, u'lrf,rar'], - 16: [u'Quicksilver', u'Neal Stephenson', None, u'lrf,zip'], - 17: [u'The Comedies of William Shakespeare', - u'William Shakespeare', + 1: ['Eugenie Grandet', 'Honor\xe9 de Balzac', 'manybooks.net', 'lrf'], + 2: ['Fanny Hill', 'John Cleland', 'manybooks.net', 'lrf'], + 3: ['Persuasion', 'Jane Austen', 'manybooks.net', 'lrf'], + 4: ['Psmith, Journalist', 'P. G. Wodehouse', 'Some Publisher', 'lrf'], + 5: ['The Complete Works of William Shakespeare', + 'William Shakespeare', + 'manybooks.net', + 'lrf'], + 6: ['The History of England, Volume I', + 'David Hume', + 'manybooks.net', + 'lrf'], + 7: ['Someone Comes to Town, Someone Leaves Town', + 'Cory Doctorow', + 'Tor Books', + 'lrf'], + 8: ['Stalky and Co.', 'Rudyard Kipling', 'manybooks.net', 'lrf'], + 9: ['A Game of Thrones', 'George R. R. Martin', None, 'lrf,rar'], + 10: ['A Clash of Kings', 'George R. R. Martin', None, 'lrf,rar'], + 11: ['A Storm of Swords', 'George R. R. Martin', None, 'lrf,rar'], + 12: ['Biggles - Pioneer Air Fighter', 'W. E. Johns', None, 'lrf,rtf'], + 13: ['Biggles of the Camel Squadron', + 'W. E. Johns', + 'London:Thames, (1977)', + 'lrf,rtf'], + 14: ['A Feast for Crows', 'George R. R. Martin', None, 'lrf,rar'], + 15: ['Cryptonomicon', 'Neal Stephenson', None, 'lrf,rar'], + 16: ['Quicksilver', 'Neal Stephenson', None, 'lrf,zip'], + 17: ['The Comedies of William Shakespeare', + 'William Shakespeare', None, - u'lrf'], - 18: [u'The Histories of William Shakespeare', - u'William Shakespeare', + 'lrf'], + 18: ['The Histories of William Shakespeare', + 'William Shakespeare', None, - u'lrf'], - 19: [u'The Tragedies of William Shakespeare', - u'William Shakespeare', + 'lrf'], + 19: ['The Tragedies of William Shakespeare', + 'William Shakespeare', None, - u'lrf'], - 20: [u'An Ideal Husband', u'Oscar Wilde', u'manybooks.net', u'lrf'], - 21: [u'Flight of the Nighthawks', u'Raymond E. Feist', None, u'lrf,rar'], - 22: [u'Into a Dark Realm', u'Raymond E. Feist', None, u'lrf,rar'], - 23: [u'The Sundering', u'Walter Jon Williams', None, u'lrf,rar'], - 24: [u'The Praxis', u'Walter Jon Williams', None, u'lrf,rar'], - 25: [u'Conventions of War', u'Walter Jon Williams', None, u'lrf,rar'], - 26: [u'Banewreaker', u'Jacqueline Carey', None, u'lrf,rar'], - 27: [u'Godslayer', u'Jacqueline Carey', None, u'lrf,rar'], - 28: [u"Kushiel's Scion", u'Jacqueline Carey', None, u'lrf,rar'], - 29: [u'Underworld', u'Don DeLillo', None, u'lrf,rar'], - 30: [u'Genghis Khan and The Making of the Modern World', - u'Jack Weatherford Orc', - u'Three Rivers Press', - u'lrf,zip'], - 31: [u'The Best and the Brightest', - u'David Halberstam', - u'Modern Library', - u'lrf,zip'], - 32: [u'The Killer Angels', u'Michael Shaara', None, u'html,lrf'], - 33: [u'Band Of Brothers', u'Stephen E Ambrose', None, u'lrf,txt'], - 34: [u'The Gates of Rome', u'Conn Iggulden', None, u'lrf,rar'], - 35: [u'The Death of Kings', u'Conn Iggulden', u'Bantam Dell', u'lit,lrf'], - 36: [u'The Field of Swords', u'Conn Iggulden', None, u'lrf,rar'], - 37: [u'Masterman Ready', u'Marryat, Captain Frederick', None, u'lrf'], - 38: [u'With the Lightnings', - u'David Drake', - u'Baen Publishing Enterprises', - u'lit,lrf'], - 39: [u'Lt. Leary, Commanding', - u'David Drake', - u'Baen Publishing Enterprises', - u'lit,lrf'], - 40: [u'The Far Side of The Stars', - u'David Drake', - u'Baen Publishing Enterprises', - u'lrf,rar'], - 41: [u'The Way to Glory', - u'David Drake', - u'Baen Publishing Enterprises', - u'lrf,rar'], - 42: [u'Some Golden Harbor', u'David Drake', u'Baen Books', u'lrf,rar'], - 43: [u'Harry Potter And The Half-Blood Prince', - u'J. K. Rowling', + 'lrf'], + 20: ['An Ideal Husband', 'Oscar Wilde', 'manybooks.net', 'lrf'], + 21: ['Flight of the Nighthawks', 'Raymond E. Feist', None, 'lrf,rar'], + 22: ['Into a Dark Realm', 'Raymond E. Feist', None, 'lrf,rar'], + 23: ['The Sundering', 'Walter Jon Williams', None, 'lrf,rar'], + 24: ['The Praxis', 'Walter Jon Williams', None, 'lrf,rar'], + 25: ['Conventions of War', 'Walter Jon Williams', None, 'lrf,rar'], + 26: ['Banewreaker', 'Jacqueline Carey', None, 'lrf,rar'], + 27: ['Godslayer', 'Jacqueline Carey', None, 'lrf,rar'], + 28: ["Kushiel's Scion", 'Jacqueline Carey', None, 'lrf,rar'], + 29: ['Underworld', 'Don DeLillo', None, 'lrf,rar'], + 30: ['Genghis Khan and The Making of the Modern World', + 'Jack Weatherford Orc', + 'Three Rivers Press', + 'lrf,zip'], + 31: ['The Best and the Brightest', + 'David Halberstam', + 'Modern Library', + 'lrf,zip'], + 32: ['The Killer Angels', 'Michael Shaara', None, 'html,lrf'], + 33: ['Band Of Brothers', 'Stephen E Ambrose', None, 'lrf,txt'], + 34: ['The Gates of Rome', 'Conn Iggulden', None, 'lrf,rar'], + 35: ['The Death of Kings', 'Conn Iggulden', 'Bantam Dell', 'lit,lrf'], + 36: ['The Field of Swords', 'Conn Iggulden', None, 'lrf,rar'], + 37: ['Masterman Ready', 'Marryat, Captain Frederick', None, 'lrf'], + 38: ['With the Lightnings', + 'David Drake', + 'Baen Publishing Enterprises', + 'lit,lrf'], + 39: ['Lt. Leary, Commanding', + 'David Drake', + 'Baen Publishing Enterprises', + 'lit,lrf'], + 40: ['The Far Side of The Stars', + 'David Drake', + 'Baen Publishing Enterprises', + 'lrf,rar'], + 41: ['The Way to Glory', + 'David Drake', + 'Baen Publishing Enterprises', + 'lrf,rar'], + 42: ['Some Golden Harbor', 'David Drake', 'Baen Books', 'lrf,rar'], + 43: ['Harry Potter And The Half-Blood Prince', + 'J. K. Rowling', None, - u'lrf,rar'], - 44: [u'Harry Potter and the Order of the Phoenix', - u'J. K. Rowling', + 'lrf,rar'], + 44: ['Harry Potter and the Order of the Phoenix', + 'J. K. Rowling', None, - u'lrf,rtf'], - 45: [u'The Stars at War', u'David Weber , Steve White', None, u'lrf,rtf'], - 46: [u'The Stars at War II', - u'Steve White', - u'Baen Publishing Enterprises', - u'lrf,rar'], - 47: [u'Exodus', u'Steve White,Shirley Meier', u'Baen Books', u'lrf,rar'], - 48: [u'Harry Potter and the Goblet of Fire', - u'J. K. Rowling', + 'lrf,rtf'], + 45: ['The Stars at War', 'David Weber , Steve White', None, 'lrf,rtf'], + 46: ['The Stars at War II', + 'Steve White', + 'Baen Publishing Enterprises', + 'lrf,rar'], + 47: ['Exodus', 'Steve White,Shirley Meier', 'Baen Books', 'lrf,rar'], + 48: ['Harry Potter and the Goblet of Fire', + 'J. K. Rowling', None, - u'lrf,rar'], - 49: [u'Harry Potter and the Prisoner of Azkaban', - u'J. K. Rowling', + 'lrf,rar'], + 49: ['Harry Potter and the Prisoner of Azkaban', + 'J. K. Rowling', None, - u'lrf,rtf'], - 50: [u'Harry Potter and the Chamber of Secrets', - u'J. K. Rowling', + 'lrf,rtf'], + 50: ['Harry Potter and the Chamber of Secrets', + 'J. K. Rowling', None, - u'lit,lrf'], - 51: [u'Harry Potter and the Deathly Hallows', - u'J.K. Rowling', + 'lit,lrf'], + 51: ['Harry Potter and the Deathly Hallows', + 'J.K. Rowling', None, - u'lit,lrf,pdf'], - 52: [u"His Majesty's Dragon", u'Naomi Novik', None, u'lrf,rar'], - 53: [u'Throne of Jade', u'Naomi Novik', u'Del Rey', u'lit,lrf'], - 54: [u'Black Powder War', u'Naomi Novik', u'Del Rey', u'lrf,rar'], - 55: [u'War and Peace', u'Leo Tolstoy', u'gutenberg.org', u'lrf,txt'], - 56: [u'Anna Karenina', u'Leo Tolstoy', u'gutenberg.org', u'lrf,txt'], - 57: [u'A Shorter History of Rome', - u'Eugene Lawrence,Sir William Smith', - u'gutenberg.org', - u'lrf,zip'], - 58: [u'The Name of the Rose', u'Umberto Eco', None, u'lrf,rar'], - 71: [u"Wind Rider's Oath", u'David Weber', u'Baen', u'lrf'], - 74: [u'Rally Cry', u'William R Forstchen', None, u'htm,lrf'], - 86: [u'Empire of Ivory', u'Naomi Novik', None, u'lrf,rar'], - 87: [u"Renegade's Magic", u'Robin Hobb', None, u'lrf,rar'], - 89: [u'Master and commander', - u"Patrick O'Brian", - u'Fontana,\n1971', - u'lit,lrf'], - 91: [u'A Companion to Wolves', - u'Sarah Monette,Elizabeth Beär', + 'lit,lrf,pdf'], + 52: ["His Majesty's Dragon", 'Naomi Novik', None, 'lrf,rar'], + 53: ['Throne of Jade', 'Naomi Novik', 'Del Rey', 'lit,lrf'], + 54: ['Black Powder War', 'Naomi Novik', 'Del Rey', 'lrf,rar'], + 55: ['War and Peace', 'Leo Tolstoy', 'gutenberg.org', 'lrf,txt'], + 56: ['Anna Karenina', 'Leo Tolstoy', 'gutenberg.org', 'lrf,txt'], + 57: ['A Shorter History of Rome', + 'Eugene Lawrence,Sir William Smith', + 'gutenberg.org', + 'lrf,zip'], + 58: ['The Name of the Rose', 'Umberto Eco', None, 'lrf,rar'], + 71: ["Wind Rider's Oath", 'David Weber', 'Baen', 'lrf'], + 74: ['Rally Cry', 'William R Forstchen', None, 'htm,lrf'], + 86: ['Empire of Ivory', 'Naomi Novik', None, 'lrf,rar'], + 87: ["Renegade's Magic", 'Robin Hobb', None, 'lrf,rar'], + 89: ['Master and commander', + "Patrick O'Brian", + 'Fontana,\n1971', + 'lit,lrf'], + 91: ['A Companion to Wolves', + 'Sarah Monette,Elizabeth Beär', None, - u'lrf,rar'], - 92: [u'The Lions of al-Rassan', u'Guy Gavriel Kay', u'Eos', u'lit,lrf'], - 93: [u'Gardens of the Moon', u'Steven Erikson', u'Tor Fantasy', u'lit,lrf'], - 95: [u'The Master and Margarita', - u'Mikhail Bulgakov', - u'N.Y. : Knopf, 1992.', - u'lrf,rtf'], - 120: [u'Deadhouse Gates', - u'Steven Erikson', - u'London : Bantam Books, 2001.', - u'lit,lrf'], - 121: [u'Memories of Ice', u'Steven Erikson', u'Bantam Books', u'lit,lrf'], - 123: [u'House of Chains', u'Steven Erikson', u'Bantam Books', u'lit,lrf'], - 125: [u'Midnight Tides', u'Steven Erikson', u'Bantam Books', u'lit,lrf'], - 126: [u'The Bonehunters', u'Steven Erikson', u'Bantam Press', u'lit,lrf'], - 129: [u'Guns, germs, and steel: the fates of human societies', - u'Jared Diamond', - u'New York : W.W. Norton, c1997.', - u'lit,lrf'], - 136: [u'Wildcards', u'George R. R. Martin', None, u'html,lrf'], - 138: [u'Off Armageddon Reef', u'David Weber', u'Tor Books', u'lit,lrf'], - 144: [u'Atonement', - u'Ian McEwan', - u'New York : Nan A. Talese/Doubleday, 2002.', - u'lrf,rar'], - 146: [u'1632', u'Eric Flint', u'Baen Books', u'lit,lrf'], - 147: [u'1633', u'David Weber,Eric Flint,Dru Blair', u'Baen', u'lit,lrf'], - 148: [u'1634: The Baltic War', - u'David Weber,Eric Flint', - u'Baen', - u'lit,lrf'], - 150: [u'The Dragonbone Chair', u'Tad Williams', u'DAW Trade', u'lrf,rtf'], - 152: [u'The Little Book That Beats the Market', - u'Joel Greenblatt', - u'Wiley', - u'epub,lrf'], - 153: [u'Pride of Carthage', u'David Anthony Durham', u'Anchor', u'lit,lrf'], - 154: [u'Stone of farewell', - u'Tad Williams', - u'New York : DAW Books, 1990.', - u'lrf,txt'], - 166: [u'American Gods', u'Neil Gaiman', u'HarperTorch', u'lit,lrf'], - 176: [u'Pillars of the Earth', - u'Ken Follett', - u'New American Library', - u'lit,lrf'], - 182: [u'The Eye of the world', - u'Robert Jordan', - u'New York : T. Doherty Associates, c1990.', - u'lit,lrf'], - 188: [u'The Great Hunt', u'Robert Jordan', u'ATOM', u'lrf,zip'], - 189: [u'The Dragon Reborn', u'Robert Jordan', None, u'lit,lrf'], - 190: [u'The Shadow Rising', u'Robert Jordan', None, u'lit,lrf'], - 191: [u'The Fires of Heaven', - u'Robert Jordan', - u'Time Warner Books Uk', - u'lit,lrf'], - 216: [u'Lord of chaos', - u'Robert Jordan', - u'New York : TOR, c1994.', - u'lit,lrf'], - 217: [u'A Crown of Swords', u'Robert Jordan', None, u'lit,lrf'], - 236: [u'The Path of Daggers', u'Robert Jordan', None, u'lit,lrf'], - 238: [u'The Client', - u'John Grisham', - u'New York : Island, 1994, c1993.', - u'lit,lrf'], - 240: [u"Winter's Heart", u'Robert Jordan', None, u'lit,lrf'], - 242: [u'In the Beginning was the Command Line', - u'Neal Stephenson', + 'lrf,rar'], + 92: ['The Lions of al-Rassan', 'Guy Gavriel Kay', 'Eos', 'lit,lrf'], + 93: ['Gardens of the Moon', 'Steven Erikson', 'Tor Fantasy', 'lit,lrf'], + 95: ['The Master and Margarita', + 'Mikhail Bulgakov', + 'N.Y. : Knopf, 1992.', + 'lrf,rtf'], + 120: ['Deadhouse Gates', + 'Steven Erikson', + 'London : Bantam Books, 2001.', + 'lit,lrf'], + 121: ['Memories of Ice', 'Steven Erikson', 'Bantam Books', 'lit,lrf'], + 123: ['House of Chains', 'Steven Erikson', 'Bantam Books', 'lit,lrf'], + 125: ['Midnight Tides', 'Steven Erikson', 'Bantam Books', 'lit,lrf'], + 126: ['The Bonehunters', 'Steven Erikson', 'Bantam Press', 'lit,lrf'], + 129: ['Guns, germs, and steel: the fates of human societies', + 'Jared Diamond', + 'New York : W.W. Norton, c1997.', + 'lit,lrf'], + 136: ['Wildcards', 'George R. R. Martin', None, 'html,lrf'], + 138: ['Off Armageddon Reef', 'David Weber', 'Tor Books', 'lit,lrf'], + 144: ['Atonement', + 'Ian McEwan', + 'New York : Nan A. Talese/Doubleday, 2002.', + 'lrf,rar'], + 146: ['1632', 'Eric Flint', 'Baen Books', 'lit,lrf'], + 147: ['1633', 'David Weber,Eric Flint,Dru Blair', 'Baen', 'lit,lrf'], + 148: ['1634: The Baltic War', + 'David Weber,Eric Flint', + 'Baen', + 'lit,lrf'], + 150: ['The Dragonbone Chair', 'Tad Williams', 'DAW Trade', 'lrf,rtf'], + 152: ['The Little Book That Beats the Market', + 'Joel Greenblatt', + 'Wiley', + 'epub,lrf'], + 153: ['Pride of Carthage', 'David Anthony Durham', 'Anchor', 'lit,lrf'], + 154: ['Stone of farewell', + 'Tad Williams', + 'New York : DAW Books, 1990.', + 'lrf,txt'], + 166: ['American Gods', 'Neil Gaiman', 'HarperTorch', 'lit,lrf'], + 176: ['Pillars of the Earth', + 'Ken Follett', + 'New American Library', + 'lit,lrf'], + 182: ['The Eye of the world', + 'Robert Jordan', + 'New York : T. Doherty Associates, c1990.', + 'lit,lrf'], + 188: ['The Great Hunt', 'Robert Jordan', 'ATOM', 'lrf,zip'], + 189: ['The Dragon Reborn', 'Robert Jordan', None, 'lit,lrf'], + 190: ['The Shadow Rising', 'Robert Jordan', None, 'lit,lrf'], + 191: ['The Fires of Heaven', + 'Robert Jordan', + 'Time Warner Books Uk', + 'lit,lrf'], + 216: ['Lord of chaos', + 'Robert Jordan', + 'New York : TOR, c1994.', + 'lit,lrf'], + 217: ['A Crown of Swords', 'Robert Jordan', None, 'lit,lrf'], + 236: ['The Path of Daggers', 'Robert Jordan', None, 'lit,lrf'], + 238: ['The Client', + 'John Grisham', + 'New York : Island, 1994, c1993.', + 'lit,lrf'], + 240: ["Winter's Heart", 'Robert Jordan', None, 'lit,lrf'], + 242: ['In the Beginning was the Command Line', + 'Neal Stephenson', None, - u'lrf,txt'], - 249: [u'Crossroads of Twilight', u'Robert Jordan', None, u'lit,lrf'], - 251: [u'Caves of Steel', u'Isaac Asimov', u'Del Rey', u'lrf,zip'], - 253: [u"Hunter's Run", - u'George R. R. Martin,Gardner Dozois,Daniel Abraham', - u'Eos', - u'lrf,rar'], - 257: [u'Knife of Dreams', u'Robert Jordan', None, u'lit,lrf'], - 258: [u'Saturday', - u'Ian McEwan', - u'London : Jonathan Cape, 2005.', - u'lrf,txt'], - 259: [u'My name is Red', - u'Orhan Pamuk; translated from the Turkish by Erda\u011f G\xf6knar', - u'New York : Alfred A. Knopf, 2001.', - u'lit,lrf'], - 265: [u'Harbinger', u'David Mack', u'Star Trek', u'lit,lrf'], - 267: [u'Summon the Thunder', - u'Dayton Ward,Kevin Dilmore', - u'Pocket Books', - u'lit,lrf'], - 268: [u'Shalimar the Clown', - u'Salman Rushdie', - u'New York : Random House, 2005.', - u'lit,lrf'], - 269: [u'Reap the Whirlwind', u'David Mack', u'Star Trek', u'lit,lrf'], - 272: [u'Mistborn', u'Brandon Sanderson', u'Tor Fantasy', u'lrf,rar'], - 273: [u'The Thousandfold Thought', - u'R. Scott Bakker', - u'Overlook TP', - u'lrf,rtf'], - 276: [u'Elantris', - u'Brandon Sanderson', - u'New York : Tor, 2005.', - u'lrf,rar'], - 291: [u'Sundiver', - u'David Brin', - u'New York : Bantam Books, 1995.', - u'lit,lrf'], - 299: [u'Imperium', u'Robert Harris', u'Arrow', u'lrf,rar'], - 300: [u'Startide Rising', u'David Brin', u'Bantam', u'htm,lrf'], - 301: [u'The Uplift War', u'David Brin', u'Spectra', u'lit,lrf'], - 304: [u'Brightness Reef', u'David Brin', u'Orbit', u'lrf,rar'], - 305: [u"Infinity's Shore", u'David Brin', u'Spectra', u'txt'], - 306: [u"Heaven's Reach", u'David Brin', u'Spectra', u'lrf,rar'], - 325: [u"Foundation's Triumph", u'David Brin', u'Easton Press', u'lit,lrf'], - 327: [u'I am Charlotte Simmons', u'Tom Wolfe', u'Vintage', u'htm,lrf'], - 335: [u'The Currents of Space', u'Isaac Asimov', None, u'lit,lrf'], - 340: [u'The Other Boleyn Girl', - u'Philippa Gregory', - u'Touchstone', - u'lit,lrf'], - 341: [u"Old Man's War", u'John Scalzi', u'Tor', u'htm,lrf'], - 342: [u'The Ghost Brigades', - u'John Scalzi', - u'Tor Science Fiction', - u'html,lrf'], - 343: [u'The Last Colony', u'John S"calzi', u'Tor Books', u'html,lrf'], - 344: [u'Gossip Girl', u'Cecily von Ziegesar', u'Warner Books', u'lrf,rtf'], - 347: [u'Little Brother', u'Cory Doctorow', u'Tor Teen', u'lrf'], - 348: [u'The Reality Dysfunction', - u'Peter F. Hamilton', - u'Pan MacMillan', - u'lit,lrf'], - 353: [u'A Thousand Splendid Suns', - u'Khaled Hosseini', - u'Center Point Large Print', - u'lit,lrf'], - 354: [u'Amsterdam', u'Ian McEwan', u'Anchor', u'lrf,txt'], - 355: [u'The Neutronium Alchemist', - u'Peter F. Hamilton', - u'Aspect', - u'lit,lrf'], - 356: [u'The Naked God', u'Peter F. Hamilton', u'Aspect', u'lit,lrf'], - 421: [u'A Shadow in Summer', u'Daniel Abraham', u'Tor Fantasy', u'lrf,rar'], - 427: [u'Lonesome Dove', u'Larry M\\cMurtry', None, u'lit,lrf'], - 440: [u'Ghost', u'John Ringo', u'Baen', u'lit,lrf'], - 441: [u'Kildar', u'John Ringo', u'Baen', u'lit,lrf'], - 443: [u'Hidden Empire ', u'Kevin J. Anderson', u'Aspect', u'lrf,rar'], - 444: [u'The Gun Seller', - u'Hugh Laurie', - u'Washington Square Press', - u'lrf,rar'] + 'lrf,txt'], + 249: ['Crossroads of Twilight', 'Robert Jordan', None, 'lit,lrf'], + 251: ['Caves of Steel', 'Isaac Asimov', 'Del Rey', 'lrf,zip'], + 253: ["Hunter's Run", + 'George R. R. Martin,Gardner Dozois,Daniel Abraham', + 'Eos', + 'lrf,rar'], + 257: ['Knife of Dreams', 'Robert Jordan', None, 'lit,lrf'], + 258: ['Saturday', + 'Ian McEwan', + 'London : Jonathan Cape, 2005.', + 'lrf,txt'], + 259: ['My name is Red', + 'Orhan Pamuk; translated from the Turkish by Erda\u011f G\xf6knar', + 'New York : Alfred A. Knopf, 2001.', + 'lit,lrf'], + 265: ['Harbinger', 'David Mack', 'Star Trek', 'lit,lrf'], + 267: ['Summon the Thunder', + 'Dayton Ward,Kevin Dilmore', + 'Pocket Books', + 'lit,lrf'], + 268: ['Shalimar the Clown', + 'Salman Rushdie', + 'New York : Random House, 2005.', + 'lit,lrf'], + 269: ['Reap the Whirlwind', 'David Mack', 'Star Trek', 'lit,lrf'], + 272: ['Mistborn', 'Brandon Sanderson', 'Tor Fantasy', 'lrf,rar'], + 273: ['The Thousandfold Thought', + 'R. Scott Bakker', + 'Overlook TP', + 'lrf,rtf'], + 276: ['Elantris', + 'Brandon Sanderson', + 'New York : Tor, 2005.', + 'lrf,rar'], + 291: ['Sundiver', + 'David Brin', + 'New York : Bantam Books, 1995.', + 'lit,lrf'], + 299: ['Imperium', 'Robert Harris', 'Arrow', 'lrf,rar'], + 300: ['Startide Rising', 'David Brin', 'Bantam', 'htm,lrf'], + 301: ['The Uplift War', 'David Brin', 'Spectra', 'lit,lrf'], + 304: ['Brightness Reef', 'David Brin', 'Orbit', 'lrf,rar'], + 305: ["Infinity's Shore", 'David Brin', 'Spectra', 'txt'], + 306: ["Heaven's Reach", 'David Brin', 'Spectra', 'lrf,rar'], + 325: ["Foundation's Triumph", 'David Brin', 'Easton Press', 'lit,lrf'], + 327: ['I am Charlotte Simmons', 'Tom Wolfe', 'Vintage', 'htm,lrf'], + 335: ['The Currents of Space', 'Isaac Asimov', None, 'lit,lrf'], + 340: ['The Other Boleyn Girl', + 'Philippa Gregory', + 'Touchstone', + 'lit,lrf'], + 341: ["Old Man's War", 'John Scalzi', 'Tor', 'htm,lrf'], + 342: ['The Ghost Brigades', + 'John Scalzi', + 'Tor Science Fiction', + 'html,lrf'], + 343: ['The Last Colony', 'John S"calzi', 'Tor Books', 'html,lrf'], + 344: ['Gossip Girl', 'Cecily von Ziegesar', 'Warner Books', 'lrf,rtf'], + 347: ['Little Brother', 'Cory Doctorow', 'Tor Teen', 'lrf'], + 348: ['The Reality Dysfunction', + 'Peter F. Hamilton', + 'Pan MacMillan', + 'lit,lrf'], + 353: ['A Thousand Splendid Suns', + 'Khaled Hosseini', + 'Center Point Large Print', + 'lit,lrf'], + 354: ['Amsterdam', 'Ian McEwan', 'Anchor', 'lrf,txt'], + 355: ['The Neutronium Alchemist', + 'Peter F. Hamilton', + 'Aspect', + 'lit,lrf'], + 356: ['The Naked God', 'Peter F. Hamilton', 'Aspect', 'lit,lrf'], + 421: ['A Shadow in Summer', 'Daniel Abraham', 'Tor Fantasy', 'lrf,rar'], + 427: ['Lonesome Dove', 'Larry M\\cMurtry', None, 'lit,lrf'], + 440: ['Ghost', 'John Ringo', 'Baen', 'lit,lrf'], + 441: ['Kildar', 'John Ringo', 'Baen', 'lit,lrf'], + 443: ['Hidden Empire ', 'Kevin J. Anderson', 'Aspect', 'lrf,rar'], + 444: ['The Gun Seller', + 'Hugh Laurie', + 'Washington Square Press', + 'lrf,rar'] } tests = { @@ -309,7 +309,7 @@ class Tester(SearchQueryParser): '(tag:txt OR tag:pdf) and author:Tolstoy': {55, 56}, 'Tolstoy txt': {55, 56}, 'Hamilton Amsterdam' : set(), - u'Beär' : {91}, + 'Beär' : {91}, 'dysfunc or tolstoy': {348, 55, 56}, 'tag:txt AND NOT tolstoy': {33, 258, 354, 305, 242, 154}, 'not tag:lrf' : {305}, @@ -343,12 +343,12 @@ class Tester(SearchQueryParser): return set() query = query.lower() if candidates: - return set(key for key, val in self.texts.items() + return {key for key, val in self.texts.items() if key in candidates and query and query - in getattr(getter(val), 'lower', lambda : '')()) + in getattr(getter(val), 'lower', lambda : '')()} else: - return set(key for key, val in self.texts.items() - if query and query in getattr(getter(val), 'lower', lambda : '')()) + return {key for key, val in self.texts.items() + if query and query in getattr(getter(val), 'lower', lambda : '')()} def run_tests(self, ae): for query in self.tests.keys(): @@ -361,7 +361,7 @@ class TestSQP(unittest.TestCase): def do_test(self, optimize=False): tester = Tester(['authors', 'author', 'series', 'formats', 'format', 'publisher', 'rating', 'tags', 'tag', 'comments', 'comment', 'cover', - 'isbn', 'ondevice', 'pubdate', 'size', 'date', 'title', u'#read', + 'isbn', 'ondevice', 'pubdate', 'size', 'date', 'title', '#read', 'all', 'search'], test=True, optimize=optimize) tester.run_tests(self.assertEqual) diff --git a/src/calibre/utils/smtp.py b/src/calibre/utils/smtp.py index b63fc3856d..6c302c4403 100644 --- a/src/calibre/utils/smtp.py +++ b/src/calibre/utils/smtp.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL 3' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __docformat__ = 'restructuredtext en' @@ -141,7 +139,7 @@ def sendmail_direct(from_, to, msg, timeout, localhost, verbose, last_error, last_traceback = e, traceback.format_exc() if last_error is not None: print(last_traceback) - raise IOError('Failed to send mail: '+repr(last_error)) + raise OSError('Failed to send mail: '+repr(last_error)) def get_smtp_class(use_ssl=False, debuglevel=0): diff --git a/src/calibre/utils/smtplib.py b/src/calibre/utils/smtplib.py index 2fce3da7b1..cc8ccffe7f 100644 --- a/src/calibre/utils/smtplib.py +++ b/src/calibre/utils/smtplib.py @@ -329,7 +329,7 @@ class SMTP: try: port = int(port) except ValueError: - raise socket.error("nonnumeric port") + raise OSError("nonnumeric port") if not port: port = self.default_port if self.debuglevel > 0: @@ -349,7 +349,7 @@ class SMTP: if hasattr(self, 'sock') and self.sock: try: self.sock.sendall(str) - except socket.error: + except OSError: self.close() raise SMTPServerDisconnected('Server not connected') else: @@ -382,7 +382,7 @@ class SMTP: while True: try: line = self.file.readline(_MAXLINE + 1) - except socket.error as e: + except OSError as e: self.close() raise SMTPServerDisconnected("Connection unexpectedly closed: " + str(e)) if line == '': @@ -868,7 +868,7 @@ class LMTP(SMTP): try: self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.connect(host) - except socket.error: + except OSError: if self.debuglevel > 0: self.debug('connect fail:', host) if self.sock: diff --git a/src/calibre/utils/tdir_in_cache.py b/src/calibre/utils/tdir_in_cache.py index 995d5f4147..c79d67d954 100644 --- a/src/calibre/utils/tdir_in_cache.py +++ b/src/calibre/utils/tdir_in_cache.py @@ -13,7 +13,7 @@ from calibre.constants import cache_dir, iswindows from calibre.ptempfile import remove_dir from calibre.utils.monotonic import monotonic -TDIR_LOCK = u'tdir-lock' +TDIR_LOCK = 'tdir-lock' if iswindows: from calibre.utils.lock import windows_open @@ -32,7 +32,7 @@ if iswindows: try: with windows_open(os.path.join(path, TDIR_LOCK)): pass - except EnvironmentError: + except OSError: return True return False else: @@ -61,7 +61,7 @@ else: eintr_retry_call(fcntl.lockf, f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) eintr_retry_call(fcntl.lockf, f.fileno(), fcntl.LOCK_UN) return False - except EnvironmentError: + except OSError: return True finally: f.close() @@ -70,7 +70,7 @@ else: def tdirs_in(b): try: tdirs = os.listdir(b) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.ENOENT: raise tdirs = () @@ -105,7 +105,7 @@ def tdir_in_cache(base): b = os.path.join(os.path.realpath(cache_dir()), base) try: os.makedirs(b) - except EnvironmentError as e: + except OSError as e: if e.errno != errno.EEXIST: raise global_lock = retry_lock_tdir(b) diff --git a/src/calibre/utils/terminal.py b/src/calibre/utils/terminal.py index aea2e94b69..75d632de92 100644 --- a/src/calibre/utils/terminal.py +++ b/src/calibre/utils/terminal.py @@ -156,7 +156,7 @@ class ANSIStream(Detect): ANSI_RE = r'\033\[((?:\d|;)*)([a-zA-Z])' def __init__(self, stream=None): - super(ANSIStream, self).__init__(stream) + super().__init__(stream) self.encoding = getattr(self.stream, 'encoding', None) or 'utf-8' self._ansi_re_bin = self._ansi_re_unicode = None diff --git a/src/calibre/utils/test_lock.py b/src/calibre/utils/test_lock.py index 60b6965d2a..b565e057a1 100644 --- a/src/calibre/utils/test_lock.py +++ b/src/calibre/utils/test_lock.py @@ -33,7 +33,7 @@ class Other(Thread): try: with FastFailEF('testsp'): self.locked = True - except EnvironmentError: + except OSError: self.locked = False @@ -72,7 +72,7 @@ class IPCLockTest(unittest.TestCase): try: shutil.rmtree(self.tdir) break - except EnvironmentError: + except OSError: time.sleep(0.1) def test_exclusive_file_same_process(self): @@ -154,7 +154,7 @@ class IPCLockTest(unittest.TestCase): self.assertFalse(is_tdir_locked(tdirs[0])) clean_tdirs_in('t') self.assertFalse(os.path.exists(tdirs[0])) - self.assertEqual(os.listdir('t'), [u'tdir-lock']) + self.assertEqual(os.listdir('t'), ['tdir-lock']) def other1(): diff --git a/src/calibre/utils/threadpool.py b/src/calibre/utils/threadpool.py index b8debbeee4..e02df84b66 100644 --- a/src/calibre/utils/threadpool.py +++ b/src/calibre/utils/threadpool.py @@ -1,5 +1,3 @@ - - """Easy to use object-oriented thread pool framework. A thread pool is an object that maintains a pool of worker threads to perform diff --git a/src/calibre/utils/unrar.py b/src/calibre/utils/unrar.py index f0da49c9b7..b25b724ef8 100644 --- a/src/calibre/utils/unrar.py +++ b/src/calibre/utils/unrar.py @@ -45,7 +45,7 @@ class StreamAsPath: if self.temppath is not None: try: os.remove(self.temppath) - except EnvironmentError: + except OSError: pass self.temppath = None @@ -59,8 +59,7 @@ def extract(path_or_stream, location): def names(path_or_stream): from unrardll import names with StreamAsPath(path_or_stream) as path: - for name in names(path, only_useful=True): - yield name + yield from names(path, only_useful=True) def comment(path_or_stream): diff --git a/src/calibre/utils/winreg/__init__.py b/src/calibre/utils/winreg/__init__.py index 8b13789179..e69de29bb2 100644 --- a/src/calibre/utils/winreg/__init__.py +++ b/src/calibre/utils/winreg/__init__.py @@ -1 +0,0 @@ - diff --git a/src/calibre/utils/zipfile.py b/src/calibre/utils/zipfile.py index 53391854ad..c2edd8c024 100644 --- a/src/calibre/utils/zipfile.py +++ b/src/calibre/utils/zipfile.py @@ -1,4 +1,3 @@ - """ Read and write ZIP files. Modified by Kovid Goyal to support replacing files in a zip archive, detecting filename encoding, updating zip files, etc. @@ -181,7 +180,7 @@ def _check_zipfile(fp): try: if _EndRecData(fp): return True # file has correct magic number - except IOError: + except OSError: pass return False @@ -198,7 +197,7 @@ def is_zipfile(filename): else: with open(filename, "rb") as fp: result = _check_zipfile(fp) - except IOError: + except OSError: pass return result @@ -209,7 +208,7 @@ def _EndRecData64(fpin, offset, endrec): """ try: fpin.seek(offset - sizeEndCentDir64Locator, 2) - except IOError: + except OSError: # If the seek fails, the file is not large enough to contain a ZIP64 # end-of-archive record, so just return the end record we were given. return endrec @@ -257,7 +256,7 @@ def _EndRecData(fpin): # file if this is the case). try: fpin.seek(-sizeEndCentDir, 2) - except IOError: + except OSError: return None data = fpin.read() if data[0:4] == stringEndArchive and data[-2:] == b"\000\000": @@ -760,7 +759,7 @@ class ZipFile: modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} try: self.fp = open(file, modeDict[mode]) - except IOError: + except OSError: if mode == 'a': mode = key = 'w' self.fp = open(file, modeDict[mode]) @@ -819,7 +818,7 @@ class ZipFile: fp = self.fp try: endrec = _EndRecData(fp) - except IOError: + except OSError: raise BadZipfile("File is not a zip file") if not endrec: raise BadZipfile("File is not a zip file") diff --git a/src/calibre/web/__init__.py b/src/calibre/web/__init__.py index 6b42051f75..4c4f3be0f4 100644 --- a/src/calibre/web/__init__.py +++ b/src/calibre/web/__init__.py @@ -1,5 +1,3 @@ - - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' diff --git a/src/calibre/web/feeds/__init__.py b/src/calibre/web/feeds/__init__.py index cec8c7aefb..14d3951a9c 100644 --- a/src/calibre/web/feeds/__init__.py +++ b/src/calibre/web/feeds/__init__.py @@ -172,8 +172,8 @@ class Feed: if delta.days*24*3600 + delta.seconds <= 24*3600*self.oldest_article: self.articles.append(article) else: - t = strftime(u'%a, %d %b, %Y %H:%M', article.localtime.timetuple()) - self.logger.debug(u'Skipping article %s (%s) from feed %s as it is too old.'% + t = strftime('%a, %d %b, %Y %H:%M', article.localtime.timetuple()) + self.logger.debug('Skipping article %s (%s) from feed %s as it is too old.'% (title, t, self.title)) d = item.get('date', '') article.formatted_date = d diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 915d4d1e46..92223d5c04 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' ''' diff --git a/src/calibre/web/feeds/recipes/model.py b/src/calibre/web/feeds/recipes/model.py index b934471a49..979513b7ba 100644 --- a/src/calibre/web/feeds/recipes/model.py +++ b/src/calibre/web/feeds/recipes/model.py @@ -163,8 +163,8 @@ class RecipeModel(QAbstractItemModel, AdaptSQP): try: with zipfile.ZipFile(P('builtin_recipes.zip', allow_user_override=False), 'r') as zf: - self.favicons = dict([(x.filename, x) for x in zf.infolist() if - x.filename.endswith('.png')]) + self.favicons = {x.filename: x for x in zf.infolist() if + x.filename.endswith('.png')} except: self.favicons = {} self.do_refresh() diff --git a/src/calibre/web/fetch/__init__.py b/src/calibre/web/fetch/__init__.py index 9d7bde35f7..f832dbb7fc 100644 --- a/src/calibre/web/fetch/__init__.py +++ b/src/calibre/web/fetch/__init__.py @@ -1,3 +1,2 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' diff --git a/src/calibre/web/fetch/simple.py b/src/calibre/web/fetch/simple.py index 54c7910e95..b66e2d6889 100644 --- a/src/calibre/web/fetch/simple.py +++ b/src/calibre/web/fetch/simple.py @@ -115,7 +115,7 @@ def save_soup(soup, target): class response(bytes): def __new__(cls, *args): - obj = super(response, cls).__new__(cls, *args) + obj = super().__new__(cls, *args) obj.newurl = None return obj