diff --git a/setup/browser_data.py b/setup/browser_data.py index ac86afcf40..6b17747857 100644 --- a/setup/browser_data.py +++ b/setup/browser_data.py @@ -9,7 +9,6 @@ import sys from datetime import datetime from urllib.request import urlopen -from polyglot.builtins import filter from setup import download_securely diff --git a/setup/translations.py b/setup/translations.py index 907f8edc38..269a2c24fd 100644 --- a/setup/translations.py +++ b/setup/translations.py @@ -13,7 +13,7 @@ from functools import partial from setup import Command, __appname__, __version__, require_git_master, build_cache_dir, edit_file, dump_json from setup.parallel_build import batched_parallel_jobs -from polyglot.builtins import codepoint_to_chr, iteritems, range +from polyglot.builtins import codepoint_to_chr, iteritems is_ci = os.environ.get('CI', '').lower() == 'true' diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 09ea2b7e78..3dc777a64a 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -1,11 +1,10 @@ - ''' E-book management software''' __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' __docformat__ = 'restructuredtext en' import sys, os, re, time, random, warnings -from polyglot.builtins import codepoint_to_chr, unicode_type, range, hasenv, native_string_type +from polyglot.builtins import codepoint_to_chr, hasenv, native_string_type from math import floor from functools import partial @@ -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, @@ -71,7 +70,7 @@ def get_types_map(): def to_unicode(raw, encoding='utf-8', errors='strict'): - if isinstance(raw, unicode_type): + if isinstance(raw, str): return raw return raw.decode(encoding, errors) @@ -259,7 +258,7 @@ def get_parsed_proxy(typ='http', debug=True): traceback.print_exc() else: if debug: - prints('Using http proxy', unicode_type(ans)) + prints('Using http proxy', str(ans)) return ans @@ -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 @@ -419,7 +418,7 @@ def strftime(fmt, t=None): fmt = fmt.decode('mbcs' if iswindows else 'utf-8', 'replace') ans = time.strftime(fmt, t) if early_year: - ans = ans.replace('_early year hack##', unicode_type(orig_year)) + ans = ans.replace('_early year hack##', str(orig_year)) return ans @@ -531,7 +530,7 @@ def force_unicode(obj, enc=preferred_encoding): def as_unicode(obj, enc=preferred_encoding): if not isbytestring(obj): try: - obj = unicode_type(obj) + obj = str(obj) except Exception: try: obj = native_string_type(obj) @@ -554,7 +553,7 @@ def human_readable(size, sep=' '): if size < (1 << ((i + 1) * 10)): divisor, suffix = (1 << (i * 10)), candidate break - size = unicode_type(float(size)/divisor) + size = str(float(size)/divisor) if size.find(".") > -1: size = size[:size.find(".")+2] if size.endswith('.0'): diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 65eb5f51ec..bded43cacf 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -1,12 +1,12 @@ #!/usr/bin/env python # vim:fileencoding=utf-8 # License: GPLv3 Copyright: 2015, Kovid Goyal -from polyglot.builtins import map, unicode_type, environ_item, hasenv, getenv +from polyglot.builtins import environ_item, hasenv import sys, locale, codecs, os, collections, collections.abc __appname__ = 'calibre' numeric_version = (5, 29, 0) -__version__ = '.'.join(map(unicode_type, numeric_version)) +__version__ = '.'.join(map(str, numeric_version)) git_version = None __author__ = "Kovid Goyal " @@ -118,18 +118,18 @@ 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: return confcache - ccd = getenv('CALIBRE_CACHE_DIRECTORY') + ccd = os.getenv('CALIBRE_CACHE_DIRECTORY') if ccd is not None: ans = os.path.abspath(ccd) try: os.makedirs(ans) return ans - except EnvironmentError as err: + except OSError as err: if err.errno == errno.EEXIST: return ans @@ -141,7 +141,7 @@ def _get_cache_dir(): elif ismacos: candidate = os.path.join(os.path.expanduser('~/Library/Caches'), __appname__) else: - candidate = getenv('XDG_CACHE_HOME', '~/.cache') + candidate = os.getenv('XDG_CACHE_HOME', '~/.cache') candidate = os.path.join(os.path.expanduser(candidate), __appname__) if isinstance(candidate, bytes): @@ -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 @@ -340,7 +340,7 @@ if plugins is None: CONFIG_DIR_MODE = 0o700 -cconfd = getenv('CALIBRE_CONFIG_DIRECTORY') +cconfd = os.getenv('CALIBRE_CONFIG_DIRECTORY') if cconfd is not None: config_dir = os.path.abspath(cconfd) elif iswindows: @@ -354,7 +354,7 @@ elif iswindows: elif ismacos: config_dir = os.path.expanduser('~/Library/Preferences/calibre') else: - bdir = os.path.abspath(os.path.expanduser(getenv('XDG_CONFIG_HOME', '~/.config'))) + bdir = os.path.abspath(os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config'))) config_dir = os.path.join(bdir, 'calibre') try: os.makedirs(config_dir, mode=CONFIG_DIR_MODE) @@ -386,7 +386,7 @@ if getattr(sys, 'frozen', False): else: is_running_from_develop = running_in_develop_mode() -in_develop_mode = getenv('CALIBRE_ENABLE_DEVELOP_MODE') == '1' +in_develop_mode = os.getenv('CALIBRE_ENABLE_DEVELOP_MODE') == '1' def get_version(): @@ -415,7 +415,7 @@ def get_appname_for_display(): def get_portable_base(): 'Return path to the directory that contains calibre-portable.exe or None' if isportable: - return os.path.dirname(os.path.dirname(getenv('CALIBRE_PORTABLE_BUILD'))) + return os.path.dirname(os.path.dirname(os.getenv('CALIBRE_PORTABLE_BUILD'))) def get_windows_username(): diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index 048fbe7c41..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 ' @@ -6,7 +5,6 @@ import os, sys, zipfile, importlib, enum from calibre.constants import numeric_version, iswindows, ismacos from calibre.ptempfile import PersistentTemporaryFile -from polyglot.builtins import unicode_type if iswindows: platform = 'windows' @@ -207,7 +205,7 @@ class Plugin: # {{{ config_dialog.exec_() if config_dialog.result() == QDialog.DialogCode.Accepted: - sc = unicode_type(sc.text()).strip() + sc = str(sc.text()).strip() customize_plugin(self, sc) geom = bytearray(config_dialog.saveGeometry()) 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/conversion.py b/src/calibre/customize/conversion.py index 60aebf0e5a..5cda8c420e 100644 --- a/src/calibre/customize/conversion.py +++ b/src/calibre/customize/conversion.py @@ -7,7 +7,6 @@ import re, os, shutil, numbers from calibre import CurrentDir from calibre.customize import Plugin -from polyglot.builtins import unicode_type class ConversionOption: @@ -81,7 +80,7 @@ class OptionRecommendation: self.option.choices: raise ValueError('OpRec: %s: Recommended value not in choices'% self.option.name) - if not (isinstance(self.recommended_value, (numbers.Number, bytes, unicode_type)) or self.recommended_value is None): + if not (isinstance(self.recommended_value, (numbers.Number, bytes, str)) or self.recommended_value is None): raise ValueError('OpRec: %s:'%self.option.name + repr( self.recommended_value) + ' is not a string or a number') @@ -342,7 +341,7 @@ class OutputFormatPlugin(Plugin): @property def is_periodical(self): return self.oeb.metadata.publication_type and \ - unicode_type(self.oeb.metadata.publication_type[0]).startswith('periodical:') + str(self.oeb.metadata.publication_type[0]).startswith('periodical:') def specialize_options(self, log, opts, input_fmt): ''' diff --git a/src/calibre/customize/profiles.py b/src/calibre/customize/profiles.py index f7ac476391..08452b2062 100644 --- a/src/calibre/customize/profiles.py +++ b/src/calibre/customize/profiles.py @@ -5,7 +5,6 @@ __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' from calibre.customize import Plugin as _Plugin -from polyglot.builtins import zip FONT_SIZES = [('xx-small', 1), ('x-small', None), @@ -32,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 @@ -487,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 f5eda15643..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 ' @@ -22,7 +21,7 @@ from calibre.utils.config import (make_config_dir, Config, ConfigProxy, plugin_dir, OptionParser) from calibre.ebooks.metadata.sources.base import Source from calibre.constants import DEBUG, numeric_version, system_plugins_loc -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues builtin_names = frozenset(p.name for p in builtin_plugins) BLACKLISTED_PLUGINS = frozenset({'Marvin XD', 'iOS reader applications'}) @@ -769,8 +768,7 @@ initialize_plugins() def initialized_plugins(): - for plugin in _initialized_plugins: - yield plugin + yield from _initialized_plugins # }}} @@ -781,12 +779,12 @@ def build_plugin(path): from calibre import prints from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.zipfile import ZipFile, ZIP_STORED - path = unicode_type(path) + path = str(path) names = frozenset(os.listdir(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 ec5aeaeaeb..3fb6c7de34 100644 --- a/src/calibre/customize/zipplugin.py +++ b/src/calibre/customize/zipplugin.py @@ -22,7 +22,7 @@ from calibre import as_unicode from calibre.customize import ( InvalidPlugin, Plugin, PluginNotFound, numeric_version, platform ) -from polyglot.builtins import itervalues, map, reload, string_or_bytes, unicode_type +from polyglot.builtins import itervalues, reload, string_or_bytes # PEP 302 based plugin loading mechanism, works around the bug in zipimport in # python 2.x that prevents importing from zip files in locations whose paths @@ -307,7 +307,7 @@ class CalibrePluginFinder: if ans.minimum_calibre_version > numeric_version: raise InvalidPlugin( 'The plugin at %s needs a version of calibre >= %s' % - (as_unicode(path_to_zip_file), '.'.join(map(unicode_type, + (as_unicode(path_to_zip_file), '.'.join(map(str, ans.minimum_calibre_version)))) if platform not in ans.supported_platforms: @@ -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 73c707727c..75d9fccc4b 100644 --- a/src/calibre/db/__init__.py +++ b/src/calibre/db/__init__.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' SPOOL_SIZE = 30*1024*1024 import numbers -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems def _get_next_series_num_for_list(series_indices, unwrap=True): @@ -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 11e955d265..c2ffd5901a 100644 --- a/src/calibre/db/adding.py +++ b/src/calibre/db/adding.py @@ -16,7 +16,7 @@ from calibre import prints from calibre.constants import filesystem_encoding, ismacos, iswindows from calibre.ebooks import BOOK_EXTENSIONS from calibre.utils.filenames import make_long_path_useable -from polyglot.builtins import itervalues, map as it_map, unicode_type +from polyglot.builtins import itervalues def splitext(path): @@ -71,7 +71,7 @@ def metadata_extensions(): # but not actually added) global _metadata_extensions if _metadata_extensions is None: - _metadata_extensions = frozenset(it_map(unicode_type, BOOK_EXTENSIONS)) | {'opf'} + _metadata_extensions = frozenset(BOOK_EXTENSIONS) | {'opf'} return _metadata_extensions @@ -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) @@ -146,7 +146,7 @@ def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=( for path in listdir_impl(dirpath, sort_by_mtime=True): key, ext = splitext(path) if allow_path(path, ext, compiled_rules): - books[icu_lower(key) if isinstance(key, unicode_type) else key.lower()][ext] = path + books[icu_lower(key) if isinstance(key, str) else key.lower()][ext] = path for formats in itervalues(books): if formats_ok(formats): @@ -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 ead5537d70..43817e8dcb 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -50,8 +50,7 @@ from calibre.utils.formatter_functions import ( from calibre.utils.icu import sort_key from calibre.utils.img import save_cover_data_to from polyglot.builtins import ( - cmp, iteritems, itervalues, native_string_type, reraise, string_or_bytes, - unicode_type + cmp, iteritems, itervalues, native_string_type, reraise, string_or_bytes ) # }}} @@ -108,7 +107,7 @@ class DBPrefs(dict): # {{{ dict.__setitem__(self, key, val) def raw_to_object(self, raw): - if not isinstance(raw, unicode_type): + if not isinstance(raw, str): raw = raw.decode(preferred_encoding) return json.loads(raw, object_hook=from_json) @@ -152,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): @@ -262,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: @@ -352,7 +351,7 @@ class Connection(apsw.Connection): # {{{ self.createscalarfunction('title_sort', title_sort, 1) self.createscalarfunction('author_to_author_sort', _author_to_author_sort, 1) - self.createscalarfunction('uuid4', lambda: unicode_type(uuid.uuid4()), + self.createscalarfunction('uuid4', lambda: str(uuid.uuid4()), 0) # Dummy functions for dynamically created filters @@ -403,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 @@ -646,10 +645,10 @@ class DB: prints('found user category case overlap', catmap[uc]) cat = catmap[uc][0] suffix = 1 - while icu_lower((cat + unicode_type(suffix))) in catmap: + while icu_lower(cat + str(suffix)) in catmap: suffix += 1 - prints('Renaming user category %s to %s'%(cat, cat+unicode_type(suffix))) - user_cats[cat + unicode_type(suffix)] = user_cats[cat] + prints('Renaming user category %s to %s'%(cat, cat+str(suffix))) + user_cats[cat + str(suffix)] = user_cats[cat] del user_cats[cat] cats_changed = True if cats_changed: @@ -755,25 +754,25 @@ class DB: if d['is_multiple']: if x is None: return [] - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): x = x.split(d['multiple_seps']['ui_to_list']) x = [y.strip() for y in x if y.strip()] x = [y.decode(preferred_encoding, 'replace') if not isinstance(y, - unicode_type) else y for y in x] - return [u' '.join(y.split()) for y in x] + str) else y for y in x] + return [' '.join(y.split()) for y in x] else: - return x if x is None or isinstance(x, unicode_type) else \ + return x if x is None or isinstance(x, str) else \ x.decode(preferred_encoding, 'replace') def adapt_datetime(x, d): - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): if isinstance(x, bytes): x = x.decode(preferred_encoding, 'replace') x = parse_date(x, assume_utc=False, as_utc=False) return x def adapt_bool(x, d): - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): if isinstance(x, bytes): x = x.decode(preferred_encoding, 'replace') x = x.lower() @@ -796,7 +795,7 @@ class DB: def adapt_number(x, d): if x is None: return None - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): if isinstance(x, bytes): x = x.decode(preferred_encoding, 'replace') if x.lower() == 'none': @@ -825,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'], @@ -888,7 +887,7 @@ class DB: # account for the series index column. Field_metadata knows that # the series index is one larger than the series. If you change # it here, be sure to change it there as well. - self.FIELD_MAP[unicode_type(data['num'])+'_index'] = base = base+1 + self.FIELD_MAP[str(data['num'])+'_index'] = base = base+1 self.field_metadata.set_field_record_index(label_+'_index', base, prefer_custom=True) @@ -1311,7 +1310,7 @@ class DB: if getattr(self, '_library_id_', None) is None: ans = self.conn.get('SELECT uuid FROM library_id', all=False) if ans is None: - ans = unicode_type(uuid.uuid4()) + ans = str(uuid.uuid4()) self.library_id = ans else: self._library_id_ = ans @@ -1319,7 +1318,7 @@ class DB: @library_id.setter def library_id(self, val): - self._library_id_ = unicode_type(val) + self._library_id_ = str(val) self.execute(''' DELETE FROM library_id; INSERT INTO library_id (uuid) VALUES (?); @@ -1429,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): @@ -1445,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)) @@ -1479,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: @@ -1520,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: @@ -1530,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) @@ -1616,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 @@ -1728,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) @@ -1811,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, @@ -2026,7 +2024,7 @@ class DB: def map_data(x): if not isinstance(x, string_or_bytes): x = native_string_type(x) - x = x.encode('utf-8') if isinstance(x, unicode_type) else x + x = x.encode('utf-8') if isinstance(x, str) else x x = pickle_binary_string(x) return x options = [(book_id, fmt.upper(), map_data(data)) for book_id, data in iteritems(options)] @@ -2067,7 +2065,7 @@ class DB: copyfile_using_links(src, dest, dest_is_dir=False) old_files.add(src) x = path_map[x] - if not isinstance(x, unicode_type): + if not isinstance(x, str): x = x.decode(filesystem_encoding, 'replace') progress(x, i+1, total) @@ -2081,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 12a05047bc..a50792e9e3 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -47,9 +47,7 @@ from calibre.utils.config import prefs, tweaks from calibre.utils.date import UNDEFINED_DATE, now as nowf, utcnow from calibre.utils.icu import sort_key from calibre.utils.localization import canonicalize_lang -from polyglot.builtins import ( - cmp, iteritems, itervalues, string_or_bytes, unicode_type, zip -) +from polyglot.builtins import cmp, iteritems, itervalues, string_or_bytes def api(f): @@ -581,14 +579,14 @@ class Cache: @read_api def get_item_id(self, field, item_name): ' Return the item id for item_name (case-insensitive) ' - rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in iteritems(self.fields[field].table.id_map)} - return rmap.get(icu_lower(item_name) if isinstance(item_name, unicode_type) else item_name, None) + rmap = {icu_lower(v) if isinstance(v, str) else v:k for k, v in iteritems(self.fields[field].table.id_map)} + return rmap.get(icu_lower(item_name) if isinstance(item_name, str) else item_name, None) @read_api def get_item_ids(self, field, item_names): ' Return the item id for item_name (case-insensitive) ' - rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in iteritems(self.fields[field].table.id_map)} - return {name:rmap.get(icu_lower(name) if isinstance(name, unicode_type) else name, None) for name in item_names} + rmap = {icu_lower(v) if isinstance(v, str) else v:k for k, v in iteritems(self.fields[field].table.id_map)} + return {name:rmap.get(icu_lower(name) if isinstance(name, str) else name, None) for name in item_names} @read_api def author_data(self, author_ids=None): @@ -1329,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 6e57afef2a..685f303832 100644 --- a/src/calibre/db/categories.py +++ b/src/calibre/db/categories.py @@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en' import copy from functools import partial -from polyglot.builtins import iteritems, unicode_type, map, native_string_type +from polyglot.builtins import iteritems, native_string_type from calibre.ebooks.metadata import author_to_author_sort from calibre.utils.config_base import tweaks @@ -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 @@ -101,8 +101,8 @@ def clean_user_categories(dbcache): if len(comps) == 0: i = 1 while True: - if unicode_type(i) not in user_cats: - new_cats[unicode_type(i)] = user_cats[k] + if str(i) not in user_cats: + new_cats[str(i)] = user_cats[k] break i += 1 else: diff --git a/src/calibre/db/cli/cmd_add.py b/src/calibre/db/cli/cmd_add.py index b68e3c18dc..5684cfc6a4 100644 --- a/src/calibre/db/cli/cmd_add.py +++ b/src/calibre/db/cli/cmd_add.py @@ -21,7 +21,6 @@ from calibre.ptempfile import TemporaryDirectory from calibre.srv.changes import books_added, formats_added from calibre.utils.localization import canonicalize_lang from calibre.utils.short_uuid import uuid4 -from polyglot.builtins import unicode_type readonly = False version = 0 # change this if you change signature of implementation() @@ -264,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( @@ -296,9 +295,9 @@ def do_add( prints(' ', path) if added_ids: - prints(_('Added book ids: %s') % (', '.join(map(unicode_type, added_ids)))) + prints(_('Added book ids: %s') % (', '.join(map(str, added_ids)))) if merged_ids: - prints(_('Merged book ids: %s') % (', '.join(map(unicode_type, merged_ids)))) + prints(_('Merged book ids: %s') % (', '.join(map(str, merged_ids)))) def option_parser(get_parser, args): @@ -463,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/cli/cmd_list.py b/src/calibre/db/cli/cmd_list.py index bc1af37fd5..94913a8005 100644 --- a/src/calibre/db/cli/cmd_list.py +++ b/src/calibre/db/cli/cmd_list.py @@ -11,7 +11,7 @@ from textwrap import TextWrapper from calibre.db.cli.utils import str_width from calibre.ebooks.metadata import authors_to_string from calibre.utils.date import isoformat -from polyglot.builtins import as_bytes, iteritems, map, unicode_type +from polyglot.builtins import as_bytes, iteritems readonly = True version = 0 # change this if you change signature of implementation() @@ -123,10 +123,10 @@ def prepare_output_table(fields, book_ids, data, metadata): ans.append(row) for field in fields: if field == 'id': - row.append(unicode_type(book_id)) + row.append(str(book_id)) continue val = data.get(field.replace('*', '#'), {}).get(book_id) - row.append(unicode_type(val).replace('\n', ' ')) + row.append(str(val).replace('\n', ' ')) return ans @@ -308,7 +308,7 @@ List the books available in the calibre database. def main(opts, args, dbctx): afields = set(FIELDS) | {'id'} if opts.fields.strip(): - fields = [unicode_type(f.strip().lower()) for f in opts.fields.split(',')] + fields = [str(f.strip().lower()) for f in opts.fields.split(',')] else: fields = [] diff --git a/src/calibre/db/cli/cmd_list_categories.py b/src/calibre/db/cli/cmd_list_categories.py index 83be465204..cb73569ae3 100644 --- a/src/calibre/db/cli/cmd_list_categories.py +++ b/src/calibre/db/cli/cmd_list_categories.py @@ -8,7 +8,7 @@ import sys from textwrap import TextWrapper from calibre import prints -from polyglot.builtins import as_bytes, map, unicode_type +from polyglot.builtins import as_bytes readonly = True version = 0 # change this if you change signature of implementation() @@ -78,7 +78,7 @@ def do_list(fields, data, opts): widths = list(map(lambda x: 0, fields)) for i in data: for j, field in enumerate(fields): - widths[j] = max(widths[j], max(len(field), len(unicode_type(i[field])))) + widths[j] = max(widths[j], max(len(field), len(str(i[field])))) screen_width = geometry()[0] if not screen_width: @@ -109,7 +109,7 @@ def do_list(fields, data, opts): for record in data: text = [ - wrappers[i].wrap(unicode_type(record[field])) + wrappers[i].wrap(str(record[field])) for i, field in enumerate(fields) ] lines = max(map(len, text)) @@ -167,11 +167,11 @@ def main(opts, args, dbctx): is_rating = category_metadata(category)['datatype'] == 'rating' for tag in category_data[category]: if is_rating: - tag.name = unicode_type(len(tag.name)) + tag.name = str(len(tag.name)) data.append({ 'category': category, 'tag_name': tag.name, - 'count': unicode_type(tag.count), + 'count': str(tag.count), 'rating': fmtr(tag.avg_rating), }) else: @@ -179,7 +179,7 @@ def main(opts, args, dbctx): data.append({ 'category': category, 'tag_name': _('CATEGORY ITEMS'), - 'count': unicode_type(len(category_data[category])), + 'count': str(len(category_data[category])), 'rating': '' }) diff --git a/src/calibre/db/cli/cmd_remove_custom_column.py b/src/calibre/db/cli/cmd_remove_custom_column.py index dbbf18a7af..5ac8a3d998 100644 --- a/src/calibre/db/cli/cmd_remove_custom_column.py +++ b/src/calibre/db/cli/cmd_remove_custom_column.py @@ -6,7 +6,6 @@ import sys from calibre import prints from calibre.db.legacy import LibraryDatabase -from polyglot.builtins import raw_input readonly = False version = 0 # change this if you change signature of implementation() @@ -39,7 +38,7 @@ columns with the custom_columns command. def input_unicode(prompt): - ans = raw_input(prompt) + ans = input(prompt) if isinstance(ans, bytes): ans = ans.decode(sys.stdin.encoding) return ans diff --git a/src/calibre/db/cli/cmd_set_metadata.py b/src/calibre/db/cli/cmd_set_metadata.py index 57ae7232cd..1c36ecc529 100644 --- a/src/calibre/db/cli/cmd_set_metadata.py +++ b/src/calibre/db/cli/cmd_set_metadata.py @@ -10,7 +10,7 @@ from calibre.ebooks.metadata.book.base import field_from_string from calibre.ebooks.metadata.book.serialize import read_cover from calibre.ebooks.metadata.opf import get_metadata from calibre.srv.changes import metadata -from polyglot.builtins import iteritems, unicode_type, getcwd +from polyglot.builtins import iteritems readonly = False version = 0 # change this if you change signature of implementation() @@ -147,7 +147,7 @@ def main(opts, args, dbctx): with lopen(opf, 'rb') as stream: mi = get_metadata(stream)[0] if mi.cover: - mi.cover = os.path.join(os.path.dirname(opf), os.path.relpath(mi.cover, getcwd())) + mi.cover = os.path.join(os.path.dirname(opf), os.path.relpath(mi.cover, os.getcwd())) final_mi = dbctx.run('set_metadata', 'opf', book_id, read_cover(mi)) if not final_mi: raise SystemExit(_('No book with id: %s in the database') % book_id) @@ -181,5 +181,5 @@ def main(opts, args, dbctx): if not final_mi: raise SystemExit(_('No book with id: %s in the database') % book_id) - prints(unicode_type(final_mi)) + prints(str(final_mi)) return 0 diff --git a/src/calibre/db/cli/cmd_show_metadata.py b/src/calibre/db/cli/cmd_show_metadata.py index e9743efd2f..2c0e098156 100644 --- a/src/calibre/db/cli/cmd_show_metadata.py +++ b/src/calibre/db/cli/cmd_show_metadata.py @@ -3,11 +3,11 @@ # License: GPLv3 Copyright: 2017, Kovid Goyal +import os import sys from calibre import prints from calibre.ebooks.metadata.opf2 import OPFCreator -from polyglot.builtins import unicode_type, getcwd readonly = True version = 0 # change this if you change signature of implementation() @@ -49,9 +49,9 @@ def main(opts, args, dbctx): raise SystemExit('Id #%d is not present in database.' % id) if opts.as_opf: stdout = getattr(sys.stdout, 'buffer', sys.stdout) - mi = OPFCreator(getcwd(), mi) + mi = OPFCreator(os.getcwd(), mi) mi.render(stdout) else: - prints(unicode_type(mi)) + prints(str(mi)) return 0 diff --git a/src/calibre/db/cli/utils.py b/src/calibre/db/cli/utils.py index 175cd7582f..e15609dcea 100644 --- a/src/calibre/db/cli/utils.py +++ b/src/calibre/db/cli/utils.py @@ -3,8 +3,6 @@ # License: GPLv3 Copyright: 2017, Kovid Goyal -from polyglot.builtins import map - import unicodedata eaw = unicodedata.east_asian_width 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 e5818e5ecf..efbac26aa1 100644 --- a/src/calibre/db/fields.py +++ b/src/calibre/db/fields.py @@ -18,7 +18,7 @@ from calibre.utils.config_base import tweaks from calibre.utils.icu import sort_key from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, parse_date from calibre.utils.localization import calibre_langcode_to_name -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def bool_sort_key(bools_are_tristate): @@ -85,7 +85,7 @@ class Field: self._sort_key = lambda x: sort_key(author_to_author_sort(x)) self.sort_sort_key = False self.default_value = {} if name == 'identifiers' else () if self.is_multiple else None - self.category_formatter = unicode_type + self.category_formatter = str if dt == 'rating': if self.metadata['display'].get('allow_half_stars', False): self.category_formatter = lambda x: rating_to_stars(x, True) @@ -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/lazy.py b/src/calibre/db/lazy.py index 2ca5b2f46b..5fba1ab907 100644 --- a/src/calibre/db/lazy.py +++ b/src/calibre/db/lazy.py @@ -14,7 +14,7 @@ from copy import deepcopy from calibre.ebooks.metadata.book.base import Metadata, SIMPLE_GET, TOP_LEVEL_IDENTIFIERS, NULL_VALUES, ALL_METADATA_FIELDS from calibre.ebooks.metadata.book.formatter import SafeFormat from calibre.utils.date import utcnow -from polyglot.builtins import unicode_type, native_string_type +from polyglot.builtins import native_string_type # Lazy format metadata retrieval {{{ ''' @@ -46,7 +46,7 @@ class MutableBase: @resolved def __unicode__(self): - return unicode_type(self._values) + return str(self._values) @resolved def __len__(self): diff --git a/src/calibre/db/legacy.py b/src/calibre/db/legacy.py index 709e2168bc..3b90bad0e6 100644 --- a/src/calibre/db/legacy.py +++ b/src/calibre/db/legacy.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' import os, traceback, weakref -from polyglot.builtins import iteritems, zip +from polyglot.builtins import iteritems from collections.abc import MutableMapping from calibre import force_unicode, isbytestring @@ -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 c9b293b608..c31c110270 100644 --- a/src/calibre/db/restore.py +++ b/src/calibre/db/restore.py @@ -17,7 +17,7 @@ from calibre.db.cache import Cache from calibre.constants import filesystem_encoding from calibre.utils.date import utcfromtimestamp from calibre import isbytestring, force_unicode -from polyglot.builtins import iteritems, filter +from polyglot.builtins import iteritems NON_EBOOK_EXTENSIONS = frozenset(( 'jpg', 'jpeg', 'gif', 'png', 'bmp', @@ -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/schema_upgrades.py b/src/calibre/db/schema_upgrades.py index 1916a4d216..c957d0bde3 100644 --- a/src/calibre/db/schema_upgrades.py +++ b/src/calibre/db/schema_upgrades.py @@ -10,7 +10,7 @@ import os from calibre import prints from calibre.utils.date import isoformat, DEFAULT_DATE -from polyglot.builtins import itervalues, unicode_type +from polyglot.builtins import itervalues class SchemaUpgrade: @@ -598,10 +598,10 @@ class SchemaUpgrade: existing = frozenset(map(int, custom_recipes)) if id_ in existing: id_ = max(existing) + 1000 - id_ = unicode_type(id_) + id_ = str(id_) fname = custom_recipe_filename(id_, title) custom_recipes[id_] = (title, fname) - if isinstance(script, unicode_type): + if isinstance(script, str): script = script.encode('utf-8') with open(os.path.join(bdir, fname), 'wb') as f: f.write(script) diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py index 6980fcb8bd..897b96d0dc 100644 --- a/src/calibre/db/search.py +++ b/src/calibre/db/search.py @@ -18,7 +18,7 @@ from calibre.utils.date import parse_date, UNDEFINED_DATE, now, dt_as_local from calibre.utils.icu import primary_contains, sort_key from calibre.utils.localization import lang_map, canonicalize_lang from calibre.utils.search_query_parser import SearchQueryParser, ParseException -from polyglot.builtins import iteritems, unicode_type, string_or_bytes +from polyglot.builtins import iteritems, string_or_bytes CONTAINS_MATCH = 0 EQUALS_MATCH = 1 @@ -149,7 +149,7 @@ class DateSearch: # {{{ if query == 'false': for v, book_ids in field_iter(): - if isinstance(v, (bytes, unicode_type)): + if isinstance(v, (bytes, str)): if isinstance(v, bytes): v = v.decode(preferred_encoding, 'replace') v = parse_date(v) @@ -159,7 +159,7 @@ class DateSearch: # {{{ if query == 'true': for v, book_ids in field_iter(): - if isinstance(v, (bytes, unicode_type)): + if isinstance(v, (bytes, str)): if isinstance(v, bytes): v = v.decode(preferred_encoding, 'replace') v = parse_date(v) @@ -413,7 +413,7 @@ class SavedSearchQueries: # {{{ return self._db() def force_unicode(self, x): - if not isinstance(x, unicode_type): + if not isinstance(x, str): x = x.decode(preferred_encoding, 'replace') return x diff --git a/src/calibre/db/tables.py b/src/calibre/db/tables.py index 89295bdbd3..91fba0a106 100644 --- a/src/calibre/db/tables.py +++ b/src/calibre/db/tables.py @@ -12,7 +12,7 @@ from collections import defaultdict from calibre.utils.date import parse_date, UNDEFINED_DATE, utc_tz from calibre.ebooks.metadata import author_to_author_sort -from polyglot.builtins import iteritems, itervalues, range +from polyglot.builtins import iteritems, itervalues from calibre_extensions.speedup import parse_date as _c_speedup @@ -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 9c3c36713b..edd190baf7 100644 --- a/src/calibre/db/tests/base.py +++ b/src/calibre/db/tests/base.py @@ -9,7 +9,6 @@ __docformat__ = 'restructuredtext en' import unittest, os, shutil, tempfile, atexit, gc, time from functools import partial from io import BytesIO -from polyglot.builtins import map, unicode_type rmtree = partial(shutil.rmtree, ignore_errors=True) @@ -33,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) @@ -82,7 +81,7 @@ class BaseTest(unittest.TestCase): atexit.register(rmtree, self.clone_dir) self.clone_count = 0 self.clone_count += 1 - dest = os.path.join(self.clone_dir, unicode_type(self.clone_count)) + dest = os.path.join(self.clone_dir, str(self.clone_count)) shutil.copytree(library_path, dest) return dest diff --git a/src/calibre/db/tests/legacy.py b/src/calibre/db/tests/legacy.py index 01846511df..efbe7944be 100644 --- a/src/calibre/db/tests/legacy.py +++ b/src/calibre/db/tests/legacy.py @@ -12,7 +12,7 @@ from operator import itemgetter from calibre.library.field_metadata import fm_as_dict from calibre.db.tests.base import BaseTest -from polyglot.builtins import iteritems, range, unicode_type, zip +from polyglot.builtins import iteritems from polyglot import reprlib # Utils {{{ @@ -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] @@ -116,7 +116,7 @@ class LegacyTest(BaseTest): for label, loc in iteritems(db.FIELD_MAP): if isinstance(label, numbers.Integral): label = '#'+db.custom_column_num_map[label]['label'] - label = unicode_type(label) + label = str(label) ans[label] = tuple(db.get_property(i, index_is_id=True, loc=loc) for i in db.all_ids()) if label in ('id', 'title', '#tags'): @@ -282,7 +282,7 @@ class LegacyTest(BaseTest): old = db.get_data_as_dict(prefix='test-prefix') new = ndb.get_data_as_dict(prefix='test-prefix') for o, n in zip(old, new): - o = {unicode_type(k) if isinstance(k, bytes) else k:set(v) if isinstance(v, list) else v for k, v in iteritems(o)} + o = {str(k) if isinstance(k, bytes) else k:set(v) if isinstance(v, list) else v for k, v in iteritems(o)} n = {k:set(v) if isinstance(v, list) else v for k, v in iteritems(n)} self.assertEqual(o, n) @@ -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/tests/locking.py b/src/calibre/db/tests/locking.py index 6c2ace6551..633ebddff0 100644 --- a/src/calibre/db/tests/locking.py +++ b/src/calibre/db/tests/locking.py @@ -9,7 +9,6 @@ import time, random from threading import Thread from calibre.db.tests.base import BaseTest from calibre.db.locking import SHLock, RWLockWrapper, LockingError -from polyglot.builtins import range def wait_for(period): diff --git a/src/calibre/db/tests/reading.py b/src/calibre/db/tests/reading.py index e807b5b719..2af44ae003 100644 --- a/src/calibre/db/tests/reading.py +++ b/src/calibre/db/tests/reading.py @@ -13,7 +13,7 @@ from time import time from calibre.utils.date import utc_tz from calibre.utils.localization import calibre_langcode_to_name from calibre.db.tests.base import BaseTest -from polyglot.builtins import iteritems, itervalues, range +from polyglot.builtins import iteritems, itervalues def p(x): diff --git a/src/calibre/db/tests/writing.py b/src/calibre/db/tests/writing.py index 0d07e58797..1b17518a9f 100644 --- a/src/calibre/db/tests/writing.py +++ b/src/calibre/db/tests/writing.py @@ -15,7 +15,7 @@ from calibre.ebooks.metadata.book.base import Metadata from calibre.utils.date import UNDEFINED_DATE from calibre.db.tests.base import BaseTest, IMG from calibre.db.backend import FTSQueryError -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues class WritingTest(BaseTest): @@ -664,11 +664,11 @@ class WritingTest(BaseTest): def test_set_author_data(self): # {{{ cache = self.init_cache() adata = cache.author_data() - ldata = {aid:unicode_type(aid) for aid in adata} + ldata = {aid:str(aid) for aid in adata} self.assertEqual({1,2,3}, cache.set_link_for_authors(ldata)) for c in (cache, self.init_cache()): self.assertEqual(ldata, {aid:d['link'] for aid, d in iteritems(c.author_data())}) - self.assertEqual({3}, cache.set_link_for_authors({aid:'xxx' if aid == max(adata) else unicode_type(aid) for aid in adata}), + self.assertEqual({3}, cache.set_link_for_authors({aid:'xxx' if aid == max(adata) else str(aid) for aid in adata}), 'Setting the author link to the same value as before, incorrectly marked some books as dirty') sdata = {aid:'%s, changed' % aid for aid in adata} self.assertEqual({1,2,3}, cache.set_sort_for_authors(sdata)) diff --git a/src/calibre/db/utils.py b/src/calibre/db/utils.py index a9816a2142..81737f350f 100644 --- a/src/calibre/db/utils.py +++ b/src/calibre/db/utils.py @@ -8,7 +8,7 @@ __copyright__ = '2013, Kovid Goyal ' import os, errno, sys, re from locale import localeconv from collections import OrderedDict, namedtuple -from polyglot.builtins import iteritems, itervalues, map, unicode_type, string_or_bytes, filter +from polyglot.builtins import iteritems, itervalues, string_or_bytes from threading import Lock from calibre import as_unicode, prints @@ -18,7 +18,7 @@ from calibre.utils.localization import canonicalize_lang def force_to_bool(val): - if isinstance(val, (bytes, unicode_type)): + if isinstance(val, (bytes, str)): if isinstance(val, bytes): val = val.decode(preferred_encoding, 'replace') try: @@ -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))) @@ -227,10 +227,10 @@ class ThumbnailCache: def _write_order(self): if hasattr(self, 'items'): try: - data = '\n'.join(group_id + ' ' + unicode_type(book_id) for (group_id, book_id) in self.items) + 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 be8fa4601e..751046b891 100644 --- a/src/calibre/db/view.py +++ b/src/calibre/db/view.py @@ -8,8 +8,7 @@ __docformat__ = 'restructuredtext en' import weakref, operator, numbers from functools import partial -from polyglot.builtins import (iteritems, itervalues, map, - unicode_type, range) +from polyglot.builtins import iteritems, itervalues from calibre.ebooks.metadata import title_sort from calibre.utils.config_base import tweaks, prefs @@ -175,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) @@ -281,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: @@ -297,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) @@ -374,10 +372,10 @@ 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: unicode_type(v) for k, v in iteritems(id_dict)} + self.marked_ids = {k: str(v) for k, v in iteritems(id_dict)} # This invalidates all searches in the cache even though the cache may # be shared by multiple views. This is not ideal, but... cmids = set(self.marked_ids) diff --git a/src/calibre/db/write.py b/src/calibre/db/write.py index ed00376cb0..6be1d29374 100644 --- a/src/calibre/db/write.py +++ b/src/calibre/db/write.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import re from functools import partial from datetime import datetime -from polyglot.builtins import iteritems, itervalues, unicode_type, zip +from polyglot.builtins import iteritems, itervalues from calibre.constants import preferred_encoding from calibre.ebooks.metadata import author_to_author_sort, title_sort @@ -30,7 +30,7 @@ def sqlite_datetime(x): def single_text(x): if x is None: return x - if not isinstance(x, unicode_type): + if not isinstance(x, str): x = x.decode(preferred_encoding, 'replace') x = x.strip() return x if x else None @@ -58,7 +58,7 @@ def multiple_text(sep, ui_sep, x): return () if isinstance(x, bytes): x = x.decode(preferred_encoding, 'replace') - if isinstance(x, unicode_type): + if isinstance(x, str): x = x.split(sep) else: x = (y.decode(preferred_encoding, 'replace') if isinstance(y, bytes) @@ -70,7 +70,7 @@ def multiple_text(sep, ui_sep, x): def adapt_datetime(x): - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): x = parse_date(x, assume_utc=False, as_utc=False) if x and is_date_undefined(x): x = UNDEFINED_DATE @@ -78,7 +78,7 @@ def adapt_datetime(x): def adapt_date(x): - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): x = parse_only_date(x) if x is None or is_date_undefined(x): x = UNDEFINED_DATE @@ -88,7 +88,7 @@ def adapt_date(x): def adapt_number(typ, x): if x is None: return None - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): if isinstance(x, bytes): x = x.decode(preferred_encoding, 'replace') if not x or x.lower() == 'none': @@ -97,7 +97,7 @@ def adapt_number(typ, x): def adapt_bool(x): - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): if isinstance(x, bytes): x = x.decode(preferred_encoding, 'replace') x = x.lower() @@ -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 2f7fb6bee4..c0168e56e3 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -12,7 +12,7 @@ from calibre.utils.config import OptionParser from calibre.constants import iswindows from calibre import prints from calibre.startup import get_debug_executable -from polyglot.builtins import exec_path, raw_input, unicode_type, getcwd +from polyglot.builtins import exec_path def run_calibre_debug(*args, **kw): @@ -156,7 +156,7 @@ def debug_device_driver(): from calibre.devices import debug debug(ioreg_to_tmp=True, buf=sys.stdout) if iswindows: # no2to3 - raw_input('Press Enter to continue...') # no2to3 + input('Press Enter to continue...') # no2to3 def add_simple_plugin(path_to_plugin): @@ -164,7 +164,7 @@ def add_simple_plugin(path_to_plugin): tdir = tempfile.mkdtemp() open(os.path.join(tdir, 'custom_plugin.py'), 'wb').write(open(path_to_plugin, 'rb').read()) - odir = getcwd() + odir = os.getcwd() os.chdir(tdir) zf = zipfile.ZipFile('plugin.zip', 'w') zf.write('custom_plugin.py') @@ -204,11 +204,11 @@ def print_basic_debug_info(out=None): out('Linux:', platform.linux_distribution()) except: pass - out('Interface language:', unicode_type(set_translators.lang)) + out('Interface language:', str(set_translators.lang)) 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 290b8dc6d2..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 ' @@ -8,7 +7,6 @@ Device drivers. import sys, time, pprint from functools import partial -from polyglot.builtins import zip, unicode_type DAY_MAP = dict(Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6) MONTH_MAP = dict(Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8, Sep=9, Oct=10, Nov=11, Dec=12) @@ -19,8 +17,8 @@ INVERSE_MONTH_MAP = dict(zip(MONTH_MAP.values(), MONTH_MAP.keys())) def strptime(src): src = src.strip() src = src.split() - src[0] = unicode_type(DAY_MAP[src[0][:-1]])+',' - src[2] = unicode_type(MONTH_MAP[src[2]]) + src[0] = str(DAY_MAP[src[0][:-1]])+',' + src[2] = str(MONTH_MAP[src[2]]) return time.strptime(' '.join(src), '%w, %d %m %Y %H:%M:%S %Z') 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 46c7b8983a..1497f81ae4 100755 --- a/src/calibre/devices/cli.py +++ b/src/calibre/devices/cli.py @@ -17,7 +17,6 @@ from calibre.devices.errors import ArgumentError, DeviceError, DeviceLocked from calibre.customize.ui import device_plugins from calibre.devices.scanner import DeviceScanner from calibre.utils.config import device_prefs -from polyglot.builtins import unicode_type from polyglot.io import PolyglotStringIO MINIMUM_COL_WIDTH = 12 # : Minimum width of columns in ls output @@ -125,7 +124,7 @@ def ls(dev, path, recurse=False, human_readable_size=False, ll=False, cols=0): maxlen = 0 if ll: # Calculate column width for size column for file in files: - size = len(unicode_type(file.size)) + size = len(str(file.size)) if human_readable_size: file = FileFormatter(file) size = len(file.human_readable_size) @@ -137,10 +136,10 @@ def ls(dev, path, recurse=False, human_readable_size=False, ll=False, cols=0): lsoutput.append(name) lscoloutput.append(name) if ll: - size = unicode_type(file.size) + size = str(file.size) if human_readable_size: size = file.human_readable_size - prints(file.mode_string, ("%"+unicode_type(maxlen)+"s")%size, file.modification_time, name, file=output) + prints(file.mode_string, ("%"+str(maxlen)+"s")%size, file.modification_time, name, file=output) if not ll and len(lsoutput) > 0: trytable = [] for colwidth in range(MINIMUM_COL_WIDTH, cols): @@ -244,7 +243,7 @@ def main(): print("Filesystem\tSize \tUsed \tAvail \tUse%") for i in range(3): print("%-10s\t%s\t%s\t%s\t%s"%(where[i], human_readable(total[i]), human_readable(total[i]-free[i]), human_readable(free[i]), - unicode_type(0 if total[i]==0 else int(100*(total[i]-free[i])/(total[i]*1.)))+"%")) + str(0 if total[i]==0 else int(100*(total[i]-free[i])/(total[i]*1.)))+"%")) elif command == 'eject': dev.eject() elif command == "books": @@ -302,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 @@ -312,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 48ad9bcb87..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 ' ''' @@ -7,7 +5,7 @@ Write a t2b file to disk. ''' import io -from polyglot.builtins import int_to_byte, unicode_type +from polyglot.builtins import int_to_byte DEFAULT_T2B_DATA = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xff\xff\xff\xf0\xff\x0f\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x00\xff\xff\xff\xf0\xff\x0f\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\xff\xf0\xff\xff\xff\xf0\xff\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc3\xff\xff\xff\xff\xff\xf0\xff\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\xff\xff\xfc\x00?\xf0\xff\x0f\xc3\x00?\xf0\xc0\xfe\x00?\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xf0<\x0f\xf0\xff\x0f\xc0,\x0f\xf0\x0e\xf0,\x0f\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xc3\xf0\xff\x0f\xc0\xff\x0f\xf0\xff\xf0\xff\xc7\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xc3\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\x00\x03\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xc3\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xf0\x1f\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc0\x00\x03\xff\xff\xff\xff\xff\xff\xff\x0b\xff\xff\xf0\xff\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc3\xff\xff\xf3\xff\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\xff\xfc\xf0\xff\x03\xf0\xff\x0f\xc0\xff\x0f\xf0\xff\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x0f\x00\xf08\x03\xf0\xff\x0f\xc0,\x0f\xf0\xff\xf0\x1f\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xfc\x00\xc3\xf0\xff\x0f\xc3\x00?\xf0\xff\xff\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\xfe\x94\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xfc\x7f\xfe\x94\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x0f\xff\xfe\xa9@\xff\xff\xff\xff\xff\xff\xfc?\xfe\xa4\xff\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xe9P\xff\xff\xff\xff\xff\xff\xfe/\xfe\xa8\xff\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xf9T\xff\xff\xff\xff\xf0@\x00+\xfa\xa8?\xff\xff\xff\xff\xff\xff\xff\xfc\xbf\xff\xff\xf9T\xff\xff\xff\xff\xcb\xe4}*\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfc\xbf\xff\xff\xe9T\xff\xff\xff\xff\xc7\xe4\xfd\x1a\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfc\xaf\xea\xaa\xa6\xa4\xff@\x00\x0f\xc3\xe8\xfe\x1a\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4\x00\x7f\xfe\x90\x03\xe8\xfe\n\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4?\xff\xff\xa5C\xe8\xfe\x06\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4?\xff\xff\xeaC\xe8\xbe\x06\xaa\xaa\x0f\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4/\xff\xff\xea\x82\xe8j\x06\xaa\xaa\x0f\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4/\xff\xff\xaa\x82\xe8*F\xaa\xaa\x8f\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4+\xff\xfe\xaa\x82\xe8*\x86\xaa\xaa\x8f\xff\xff\x80\xff\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x86\xaa\xaa\x8f\xf0\x00T?\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x81\xaa\xaa\x8c\x03\xff\x95?\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x81\xaa\xaa\x80\xbf\xff\x95?\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x81\xaa\xaa\x9b\xff\xff\x95\x0f\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8\x1a\x81\xaa\xaa\x9a\xff\xfe\x95\x0f\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8\n\x81\xaa\xaa\xa6\xbf\xfeUO\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xa8\n\x91j\xaa\xa5\xaa\xa9ZO\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xa8\n\xa0j\xaa\xa5Z\x95ZO\xff\xff\xff\xfcj\x95UV\xa4*\xfa\xaa\xaa\x82\xa9\n\xa0j\xaa\xa5UUZC\xff\xff\xff\xfcj\x95UV\xa4*\xfa\xaa\xaa\x82\xaa\n\xa0j\xaa\xa4UUZS\xff\xff\xff\xfcZ\x95UV\xa4*\xfa\xaa\xaa\x82\xaa\n\xa0j\xaa\xa4UUZS\xff\xff\xff\xfcZ\x95UU\xa4*\xfa\xaa\xaa\x82\xaa\n\xa0j\xaa\xa8UUVS\xff\xff\xff\xfcZ\x95UU\xa4*\xea\xaa\xaa\x82\xaa\x06\xa0Z\xaa\xa8UUV\x93\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x81\xaa\x02\xa0\x1a\xaa\xa8UUV\x90\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa\x02\xa0\x1a\xaa\xa8\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa"\xa0\x1a\xaa\xa8\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa2\xa4\x16\xaa\xa8\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa2\xa8\x16\xa6\xa9\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa2\xa8\x16\xa6\xa9\x05UUT?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x84\xaa2\xa8\x16\xaa\xaa\x05UUU?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x88\xaa2\xa8\x06\xaa\xaa\x05UUU?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa1\xa8\xc5\xaa\xaa\x05UUU?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa0\xa8E\xa9\xaa\x05UUU/\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa<\xa8\x05\xa9\xaaAUUU\x0f\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa<\xa8\x05\xa9\xaaAUUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa<\xa9\x05\xaa\xaaAUUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x1c\xaa\x01\xaa\xaa\x81UUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0c\xaa\x01\xaa\xaa\x81UUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0c\xaa1j\xaa\x80UUUC\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0cj1jj\x90UUUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0c*1jj\x90UUUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaaL*1jj\xa0UUUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x8f* j\xaa\xa0\x15UUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x8f*@j\xaa\xa0\x15UUP\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x8f*\x8cZ\xaa\xa1\x15UUT\xff\xff\xfcZ\x95UU\xa4j\xaa\xaa\xaa\x8c\xaa\x8f*\x8cZ\x9a\xa0\x15UUT\xff\xff\xfcZ\x95UU\xa4j\xaa\xaa\xaa\x8c\xaa\x8f*\x8cZ\x9a\xa0\x15UUT\xff\xff\xfcZ\x95UU\xa4j\xaa\xaa\xaa\x8c\xaa\x8f\x1a\x8cZ\x9a\xa4\x15UUT?\xff\xfcZ\x95UU\x94j\xaa\xaa\xaa\x8cj\x8f\n\x8cVj\xa4\x05UU\xa4?\xff\xfcVUUU\xa4j\xaa\xaa\xaa\x8cj\x8fJ\x8c\x16\xaa\xa8\xc5UZ\xa5?\xff\xfcUUUV\xa4j\xaa\xaa\xaa\x8cj\x8f\xca\x8f\x16\xaa\xa8\xc5V\xaa\xa5?\xff\xfcUj\xaa\xaa\xa4j\xaa\xaa\xaa\x8cj\x8f\xca\x8f\x1a\xaa\xa8\x05Z\xaaU?\xff\xfcV\xaa\xaa\xaa\xa5j\xaa\xaa\xaa\x8e*\x8f\xca\x83\x1a\xaa\xa4\x01eUU?\xff\xfcZ\xaa\xaa\xaa\xa5j\xaa\xaa\xaa\x8f*\x8f\xca\x83\x1a\xa5U\x01U\x00\x00\x0f\xff\xfcUUUUUZ\xaa\xaa\xaaO%\x8f\xc6\x93\x15\x00\x001@\x0f\xff\xff\xff\xfcP\x00\x00\x00\x15\x00\x00\x00\x00\x0f\x00\x07\xc0\x03\x00\xff\xff0\x1f\xff\xff\xff\xff\xfc\x00\xff\xff\xf8\x00?\xff\xff\xff\x0f?\xc7\xc3\xf7\x0f\xff\xff\xf1\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xf4\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' # noqa @@ -24,7 +22,7 @@ def reduce_color(c): def i2b(n): - return "".join([unicode_type((n >> y) & 1) for y in range(1, -1, -1)]) + return "".join([str((n >> y) & 1) for y in range(1, -1, -1)]) def write_t2b(t2bfile, coverdata=None): diff --git a/src/calibre/devices/cybook/t4b.py b/src/calibre/devices/cybook/t4b.py index dca767e9df..33a327ea2d 100644 --- a/src/calibre/devices/cybook/t4b.py +++ b/src/calibre/devices/cybook/t4b.py @@ -7,7 +7,6 @@ Write a t4b file to disk. ''' from io import BytesIO -from polyglot.builtins import range DEFAULT_T4B_DATA = b'\x74\x34\x62\x70\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc4\x00\x16\xdf\xff\xff\xf7\x6d\xff\xff\xfd\x7a\xff\xff\xff\xe7\x77\x76\xff\xf6\x77\x77\x8d\xff\xff\xe7\x77\x78\xbf\xff\xff\xf7\x77\x77\x77\x7d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe4\x03\x78\x61\x07\xff\xff\x90\x04\xff\xff\xfc\x05\xff\xff\xff\xd5\x30\x35\xff\xf0\x13\x32\x00\x5f\xff\xd0\x03\x32\x01\xbf\xff\xe0\x00\x00\x00\x0b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x50\x8f\xff\xff\x75\xff\xff\x40\x30\xef\xff\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x6f\xff\xf5\x0d\xff\xd0\x4f\xff\xd0\x0f\xff\xe0\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\x05\xff\xff\xff\xfe\xff\xfe\x03\xa0\x8f\xff\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x6f\xff\xfb\x0b\xff\xd0\x4f\xff\xf7\x0d\xff\xe0\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf6\x0e\xff\xff\xff\xff\xff\xfa\x0b\xe0\x3f\xff\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x6f\xff\xf5\x0e\xff\xd0\x4f\xff\xf8\x0e\xff\xe0\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf1\x1f\xff\xff\xff\xff\xff\xf2\x0f\xf3\x0d\xff\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x39\x88\x30\xaf\xff\xd0\x4f\xff\xf2\x1f\xff\xe0\x18\x88\x88\x8d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x3f\xff\xff\xff\xff\xff\xd0\x6f\xfc\x09\xff\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x01\x11\x00\x2c\xff\xd0\x3a\xa8\x20\xcf\xff\xe0\x00\x00\x00\x0b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x2f\xff\xff\xff\xff\xff\x60\xaf\xff\x11\xff\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x6f\xff\xfd\x10\xef\xd0\x00\x00\x1e\xff\xff\xe0\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf2\x0f\xff\xff\xff\xff\xfe\x20\x12\x22\x00\xcf\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x6f\xff\xff\x90\x9f\xd0\x3d\xd8\x09\xff\xff\xe0\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x0b\xff\xff\xff\xff\xfc\x03\x88\x88\x60\x4f\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x6f\xff\xff\xa0\x8f\xd0\x4f\xff\x40\xcf\xff\xe0\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\xef\xff\xff\xfb\xf7\x0d\xff\xff\xf1\x1e\xfc\x06\xff\xff\xff\xff\xa0\x9f\xff\xf0\x6f\xff\xff\x60\xcf\xd0\x4f\xff\xf3\x0d\xff\xe0\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x2c\xff\xfa\x05\xf0\x2f\xff\xff\xf6\x0b\xfc\x03\x88\x88\x88\xff\xb0\xaf\xff\xf0\x5d\xcc\xa3\x05\xff\xd0\x4f\xff\xfe\x11\xef\xe0\x18\x88\x88\x8d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x10\x01\x00\x3b\xb0\x9f\xff\xff\xfd\x06\xfc\x00\x00\x00\x00\xd0\x00\x00\xff\xf0\x00\x00\x02\x7f\xff\xe1\x5f\xff\xff\xc0\x5f\xe1\x00\x00\x00\x0b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xed\xa9\xbd\xff\xed\xff\xff\xff\xff\xde\xff\xdd\xdd\xdd\xdd\xfd\xdd\xdd\xff\xfd\xdd\xdd\xee\xff\xff\xfd\xef\xff\xff\xfe\xdf\xfd\xdd\xdd\xdd\xdf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xed\xdb\x86\x8e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xb7\x42\x00\x00\x0b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\x00\x00\x00\x00\x09\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\x00\x00\x01\x11\x17\xef\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xee\xee\xee\xee\xee\xee\xee\xee\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x22\x45\x78\x9b\x95\xef\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xb8\x77\x78\x88\x88\x88\x87\x87\x89\xdf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x57\x9a\xaa\xaa\x94\xdf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\x00\x00\x11\x11\x22\x12\x11\x11\x10\x7e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x76\xaa\xaa\xab\xa4\xcf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x33\x33\x33\x33\x32\x21\x6e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xa5\xaa\xa9\x99\xa5\xaf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x33\x44\x44\x44\x33\x21\x6d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xb4\xaa\xa9\xa9\xb6\x8f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x23\x34\x44\x54\x55\x44\x44\x31\x6d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc5\x9a\x99\x9a\xb8\x7e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x23\x34\x44\x44\x55\x45\x44\x31\x6d\xff\xff\xff\xff\xff\xff\xff\xff\xee\xdd\xdd\xee\xee\xc5\x9a\x88\x8a\xa9\x6e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x44\x44\x44\x44\x44\x31\x6d\xff\xff\xff\xff\xff\xff\xff\xfe\xdc\xbb\xab\xcc\xca\x84\x8a\xa9\x99\xaa\x5d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x44\x44\x44\x44\x44\x31\x6d\xff\xff\xff\xff\xff\xff\xff\xed\xa9\x99\x78\x87\x78\x84\x7a\xaa\x89\x9a\x6c\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x23\x34\x44\x45\x55\x55\x44\x31\x6d\xff\xff\xff\xff\xff\xff\xff\xec\x98\x88\x76\x98\x88\x74\x7a\xaa\xa7\x9a\x6b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x23\x33\x34\x44\x54\x44\x44\x31\x6d\xff\xff\xff\xff\xff\xff\xff\xdb\x98\x88\x76\x98\x88\x74\x5a\xaa\x89\x9b\x7a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x44\x45\x55\x54\x43\x31\x6d\xff\xff\xff\xff\xff\xff\xfe\xdb\x98\x88\x76\x98\x88\x84\x4a\xaa\x97\xbb\x79\xef\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x34\x44\x44\x44\x44\x31\x5b\xcc\xcc\xcc\xcc\xcc\xcc\xcb\xba\x98\x88\x76\x88\x88\x85\x39\xa9\x8a\xab\x97\xef\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x33\x34\x44\x44\x43\x31\x34\x44\x44\x55\x55\x55\x55\x44\x46\x98\x88\x76\x78\x88\x85\x28\xa8\x9a\xab\xa5\xef\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf9\x00\x11\x11\x11\x12\x22\x22\x11\x10\x00\x01\x22\x23\x33\x33\x33\x31\x11\x88\x88\x76\x68\x88\x85\x27\xa9\xa9\xab\xa5\xdf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x33\x33\x44\x43\x33\x21\x00\x12\x33\x44\x55\x55\x65\x42\x11\x78\x88\x76\x68\x88\x85\x36\xaa\xaa\xab\xb5\xcf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x34\x44\x54\x44\x44\x21\x01\x23\x44\x55\x66\x66\x66\x53\x21\x78\x88\x86\x68\x88\x85\x45\xaa\xaa\xbb\xb6\xaf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x34\x44\x44\x44\x33\x21\x01\x23\x45\x56\x67\x77\x77\x54\x21\x78\x88\x86\x68\x88\x85\x54\xaa\xab\xbb\xb7\x8f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x44\x44\x44\x44\x43\x21\x01\x23\x57\x8a\xaa\xaa\x99\x74\x21\x79\x88\x86\x68\x88\x75\x44\x9a\xab\xbb\xb9\x6e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x34\x44\x44\x55\x43\x21\x01\x24\x56\x78\x89\x99\x88\x74\x21\x69\x88\x87\x68\x88\x75\x53\x9a\xab\xbb\xba\x5e\xff\xff\xff\xff\xff\xed\xa7\x9e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x44\x34\x44\x54\x44\x21\x01\x23\x45\x56\x67\x77\x77\x64\x21\x69\x88\x87\x68\x88\x65\x53\x8a\xaa\xaa\xba\x5d\xff\xff\xff\xed\xb9\x75\x54\x5b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x84\x66\x48\x54\x43\x21\x01\x23\x45\x56\x67\x77\x76\x64\x21\x6a\x88\x87\x68\x88\x66\x54\x7a\xaa\x9a\xbb\x6b\xff\xee\xb9\x66\x66\x78\x75\x69\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x64\x54\x47\x54\x43\x21\x01\x23\x45\x66\x77\x67\x67\x64\x21\x6a\x88\x87\x68\x88\x76\x54\x6a\xbb\xba\xbb\x79\xca\x75\x56\x77\x88\x88\x85\x68\xef\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x23\x33\xba\xba\xac\x44\x43\x21\x01\x23\x45\x56\x66\x66\x76\x64\x21\x6a\x88\x87\x67\x88\x66\x54\x5a\xbb\xa9\xbb\x83\x45\x67\x78\x64\x78\x88\x86\x66\xdf\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x87\x77\x79\x54\x43\x21\x01\x23\x45\x56\x66\x67\x77\x54\x21\x6a\x88\x87\x67\x88\x66\x54\x4a\xbb\xab\xbb\x93\x47\x88\x88\x66\x38\x88\x98\x66\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x44\x44\x44\x54\x44\x21\x01\x23\x45\x56\x66\x67\x77\x64\x21\x6a\x88\x88\x66\x98\x66\x55\x3a\xab\xba\xab\xa4\x47\x88\x87\x68\x43\x89\x99\x57\x8f\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x32\x34\x3a\x44\x43\x21\x01\x23\x45\x56\x66\x67\x66\x64\x31\x69\x88\x88\x65\x98\x66\x55\x39\xbb\xba\xbc\xa4\x47\x88\x87\x77\x85\x37\xaa\x78\x7e\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\xad\x76\xc5\x44\x33\x21\x01\x23\x44\x56\x66\x77\x76\x54\x21\x69\x98\x88\x65\x98\x66\x65\x38\xbb\xb9\xbb\xb5\x46\x77\x86\x68\x87\x78\x9a\x87\x7c\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x84\x7b\x44\x44\x33\x21\x01\x23\x44\x56\x67\x76\x76\x63\x21\x79\x98\x88\x76\x87\x66\x65\x46\xaa\x99\xab\xb5\x45\x88\x76\x67\x77\x78\x9a\x96\x8a\xff\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x63\x54\x46\x54\x43\x21\x01\x23\x44\x55\x66\x67\x76\x64\x21\x79\x98\x88\x76\x77\x66\x65\x44\xab\xbb\xaa\xb7\x35\x88\x87\x77\x89\x99\x9a\x96\x89\xef\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\xbb\xba\xbc\x44\x43\x21\x01\x23\x44\x56\x67\x66\x76\x63\x21\x79\x98\x88\x76\x68\x66\x65\x53\xab\xba\xaa\xb8\x35\x78\x88\x89\x99\x99\x9a\xa7\x88\xef\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x54\x44\x45\x44\x34\x21\x01\x23\x44\x56\x66\x86\x66\x54\x21\x79\x98\x88\x76\x68\x66\x65\x63\x9a\xba\xab\xb9\x35\x68\x88\x99\x99\x9a\x9a\xa8\x77\xcf\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x33\x43\x43\x44\x43\x21\x01\x23\x44\x55\x66\x76\x66\x54\x21\x7a\x98\x88\x76\x68\x66\x65\x63\x8a\xab\xa9\xba\x35\x58\x88\x99\x99\x99\x9a\xa9\x67\xaf\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x69\x2a\xd9\x34\x33\x21\x01\x23\x44\x55\x67\x67\x66\x53\x21\x7a\x98\x88\x76\x67\x66\x66\x54\x7a\xa9\x9a\xbb\x44\x48\x99\x99\x89\x99\xaa\xaa\x68\x8e\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x97\x98\x47\x44\x34\x21\x01\x23\x44\x56\x66\x76\x66\x53\x21\x7a\x98\x88\x76\x67\x66\x66\x55\x6a\xbb\x9a\xbb\x54\x57\x99\x98\x79\x9a\xaa\xaa\x87\x7d\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x53\x44\x36\x54\x44\x21\x00\x23\x44\x55\x66\x66\x66\x53\x21\x7a\x98\x87\x76\x67\x66\x66\x55\x5a\xaa\xaa\xbb\x73\x66\x99\x66\x59\x77\xaa\xaa\x97\x8b\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\xcc\xcc\xcd\x44\x33\x21\x01\x23\x34\x55\x66\x66\x66\x53\x21\x7b\x98\x88\x76\x66\x66\x66\x65\x4a\xaa\xab\xab\x83\x66\x88\x55\x48\x84\x5a\xaa\xa6\x89\xff\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x44\x34\x45\x44\x33\x21\x01\x23\x44\x55\x56\x66\x66\x53\x21\x7b\x98\x88\x76\x66\x66\x66\x56\x49\x9a\xaa\x9b\x94\x55\x88\x66\x78\x86\x98\xaa\xa7\x88\xef\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x33\x33\x44\x44\x33\x21\x00\x22\x34\x55\x66\x66\x66\x53\x21\x8b\xa7\x88\x86\x66\x66\x66\x56\x38\xa7\x99\xaa\x95\x56\x79\x99\x97\x76\x96\xaa\xa8\x88\xdf\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x33\x76\x77\x78\x44\x33\x21\x01\x22\x34\x45\x54\x66\x66\x53\x21\x8b\xa7\x78\x86\x56\x66\x66\x55\x48\xaa\xaa\xaa\xa5\x56\x69\x99\x99\x85\x79\x7a\xa9\x68\xbf\xff\xff\xff\xff\xff\xff\xfa\x11\x12\x33\xaa\xaa\xab\x34\x33\x21\x00\x23\x34\x45\x6b\x66\x66\x53\x21\x8b\xa8\x78\x76\x56\x76\x66\x65\x47\xaa\xa9\x9a\xa6\x66\x59\x99\x99\xa6\x6a\x6a\xaa\x68\x9f\xff\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x43\x33\x33\x34\x33\x21\x00\x22\x34\x45\x68\x86\x66\x53\x21\x8c\xa8\x77\x76\x56\x76\x66\x66\x45\xaa\xa9\xab\xb6\x85\x58\x99\x99\x99\x6a\x69\xaa\x67\x7e\xff\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x33\x34\x49\x75\x33\x21\x00\x22\x34\x45\x66\x66\x65\x53\x21\x8c\xa8\x77\x66\x55\x76\x66\x66\x54\xa9\x99\x9b\xa7\x76\x66\x99\x99\xa6\x69\x88\xaa\x87\x6c\xff\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x33\x33\x37\x34\x33\x21\x00\x12\x34\x45\x59\x86\x66\x53\x21\x8c\xb9\x77\x66\x55\x76\x66\x65\x63\x9a\xaa\xba\xb8\x67\x66\x99\x99\x97\x68\x96\xaa\xa6\x7a\xff\xff\xff\xff\xff\xff\xfa\x11\x22\x23\x54\x44\x46\x44\x43\x21\x00\x22\x34\x58\x59\xa5\x65\x53\x21\x8c\xb9\x77\x76\x56\x76\x66\x65\x63\x8a\xaa\xaa\xb9\x58\x65\x89\x99\x99\x86\xa3\xaa\xa6\x88\xef\xff\xff\xff\xff\xff\xfa\x11\x12\x23\xab\xbb\xbc\x33\x33\x21\x00\x12\x34\x46\x66\x66\x55\x43\x21\x8c\xb9\x77\x76\x56\x76\x66\x65\x64\x7a\xaa\x9a\xba\x49\x66\x89\x99\x99\x95\xa4\x5a\xa7\x87\xdf\xff\xff\xff\xff\xff\xfa\x11\x12\x22\x42\x33\x35\x44\x33\x21\x00\x12\x34\x48\x86\x85\x55\x43\x21\x8c\xb9\x67\x77\x56\x67\x66\x66\x65\x6a\xaa\x9a\xba\x4a\x67\x79\x99\x86\x76\x86\x27\xa8\x67\xcf\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x33\x33\x35\x33\x33\x21\x00\x12\x33\x54\x88\x56\x65\x43\x21\x8d\xba\x66\x77\x56\x57\x66\x66\x65\x5a\xab\xaa\xbb\x59\x76\x59\x99\x99\x97\x98\x24\xa9\x67\xaf\xff\xff\xff\xff\xff\xfa\x11\x12\x22\x21\x36\x9b\x33\x33\x21\x00\x12\x34\x45\x56\x76\x55\x43\x21\x8d\xca\x76\x77\x66\x57\x66\x65\x65\x5a\xaa\x9a\xbb\x78\x96\x58\x99\x99\x88\x9a\x44\xa9\x67\x8e\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x6a\xb7\x44\x43\x33\x21\x00\x12\x34\x44\x55\x85\x55\x43\x21\x8d\xca\x77\x67\x66\x67\x66\x66\x66\x49\xaa\xaa\xab\x87\xc5\x57\x98\x98\x87\x68\x85\x99\x76\x6d\xff\xff\xff\xff\xff\xfa\x11\x12\x23\x96\x33\x43\x33\x33\x21\x00\x12\x33\x44\x65\x55\x55\x43\x21\x8d\xca\x87\x76\x66\x67\x66\x66\x56\x59\xa9\x99\xab\x96\xc6\x65\x98\x89\x99\x68\x98\x99\x86\x6b\xff\xff\xff\xff\xff\xfa\x11\x12\x22\x44\x75\x23\x33\x33\x21\x00\x12\x33\x44\x6a\x65\x55\x43\x21\x8d\xca\x87\x76\x66\x67\x66\x66\x66\x58\xa8\x9a\x9b\xa5\xc9\x65\x88\x89\x99\x77\x98\x99\x95\x68\xff\xff\xff\xff\xff\xfa\x11\x12\x22\x22\x24\x79\x33\x33\x21\x00\x12\x34\x44\x56\x75\x55\x43\x21\x8d\xda\x87\x77\x66\x67\x66\x66\x66\x47\xa9\x9a\xbb\xa6\xcb\x65\x78\x88\x88\x85\x68\x99\x96\x66\xef\xff\xff\xff\xff\xfa\x11\x12\x23\x11\x33\x34\x33\x32\x21\x00\x12\x33\x44\x57\x65\x55\x43\x21\x8d\xda\x87\x77\x65\x76\x76\x66\x67\x56\xaa\xbb\xaa\xa6\xbc\x66\x68\x88\x88\x85\x88\x89\x97\x66\xcf\xff\xff\xff\xff\xfa\x11\x12\x23\x95\x23\x36\x33\x33\x21\x00\x12\x33\x44\x58\x65\x55\x43\x21\x8d\xda\x96\x77\x65\x77\x66\x66\x57\x55\xaa\xaa\xaa\xb6\xad\x66\x58\x88\x88\x85\x78\x88\x98\x66\xaf\xff\xff\xff\xff\xfa\x11\x12\x22\x52\x33\x35\x33\x33\x21\x00\x12\x33\x44\x55\x65\x55\x42\x21\x8e\xdb\x97\x67\x75\x77\x66\x66\x56\x64\xaa\xbb\xaa\xa7\x8e\x85\x58\x87\x88\x87\x88\x88\x88\x56\x8f\xff\xff\xff\xff\xfa\x11\x12\x22\x42\x23\x35\x43\x32\x21\x00\x12\x33\x44\x48\x85\x55\x43\x21\x8e\xdb\x97\x67\x75\x77\x66\x66\x66\x73\x9b\xaa\xaa\xb8\x6e\xb4\x57\x87\x87\x77\x78\x88\x88\x56\x7e\xff\xff\xff\xff\xfa\x11\x12\x22\x42\x33\x28\x33\x32\x21\x00\x12\x33\x44\x55\x55\x55\x43\x21\x8e\xdb\x97\x76\x76\x67\x76\x66\x66\x74\x8a\xba\xaa\xb9\x5d\xd5\x55\x77\x77\x77\x47\x88\x88\x65\x5d\xff\xff\xff\xff\xfa\x10\x12\x22\x63\x11\x78\x33\x32\x20\x00\x12\x33\x34\x47\x84\x55\x42\x21\x8e\xec\x97\x77\x66\x67\x87\x76\x66\x74\x7a\xaa\xaa\xba\x4d\xe7\x54\x77\x77\x77\x56\x87\x88\x74\x5a\xff\xff\xff\xff\xfa\x11\x12\x22\x28\x9a\x83\x33\x32\x20\x00\x12\x33\x44\x55\x55\x55\x42\x21\x9e\xec\x97\x77\x66\x67\x76\x66\x66\x76\x6a\xaa\x99\xba\x4b\xfa\x54\x67\x77\x77\x65\x77\x77\x84\x57\xef\xff\xff\xff\xfa\x11\x12\x22\x22\x33\x33\x33\x22\x10\x00\x12\x33\x33\x56\x45\x54\x42\x11\x9e\xec\x97\x77\x75\x67\x76\x66\x65\x67\x5a\xaa\x99\xba\x59\xfc\x54\x57\x77\x76\x65\x77\x77\x75\x55\xdf\xff\xff\xff\xfa\x11\x12\x22\x22\x33\x33\x33\x22\x20\x00\x12\x33\x35\x45\x65\x54\x42\x21\x9e\xec\xa7\x77\x76\x67\x86\x66\x65\x68\x4a\xa9\x8a\xbb\x77\xfd\x65\x56\x76\x76\x64\x67\x77\x76\x55\xbf\xff\xff\xff\xfa\x11\x12\x22\x22\x32\x33\x23\x22\x20\x00\x12\x23\x45\x55\x54\x44\x42\x11\x9e\xec\xa7\x67\x76\x68\x77\x66\x66\x68\x4a\xb9\x88\xaa\x96\xef\x75\x46\x66\x66\x65\x45\x77\x77\x45\x9f\xff\xff\xff\xfa\x10\x12\x22\x22\x22\x33\x32\x22\x20\x00\x12\x23\x33\x44\x54\x54\x42\x21\x8e\xed\xa8\x76\x76\x58\x77\x66\x66\x67\x59\xba\xa8\xa9\xa5\xef\x94\x46\x66\x66\x66\x46\x67\x77\x45\x7e\xff\xff\xff\xfa\x11\x12\x22\x22\x33\x33\x23\x32\x21\x00\x12\x23\x34\x54\x44\x44\x42\x11\x8e\xfd\xb8\x76\x67\x67\x68\x77\x66\x67\x68\xaa\xa9\x7b\xa5\xcf\xc3\x45\x66\x66\x66\x67\x66\x67\x55\x5d\xff\xff\xff\xf9\x00\x00\x11\x11\x11\x11\x11\x11\x10\x00\x12\x23\x34\x34\x44\x44\x42\x11\x8e\xfd\xb8\x77\x66\x67\x77\x66\x66\x67\x77\xaa\xa8\xa9\xb6\xbf\xe5\x44\x66\x66\x66\x66\x66\x67\x54\x4b\xff\xff\xff\xf9\x00\x01\x11\x11\x11\x11\x11\x11\x10\x00\x12\x23\x33\x44\x44\x44\x32\x11\x8e\xfd\xb8\x77\x76\x67\x77\x66\x66\x57\x76\xba\xa8\x7a\xb6\xaf\xf8\x43\x66\x66\x66\x66\x66\x66\x63\x48\xff\xff\xff\xfa\x10\x11\x22\x22\x22\x22\x32\x22\x10\x00\x12\x23\x34\x44\x44\x44\x32\x11\x8e\xfd\xb9\x77\x76\x57\x87\x66\x66\x66\x85\xbb\xa8\x8b\xa7\x9f\xfb\x43\x56\x66\x66\x66\x66\x66\x64\x45\xef\xff\xff\xfa\x10\x12\x22\x22\x22\x32\x22\x22\x10\x00\x12\x23\x33\x44\x44\x44\x32\x11\x8e\xfe\xb9\x67\x77\x57\x87\x76\x66\x66\x84\xab\x89\xaa\xb8\x8e\xfd\x54\x46\x66\x55\x55\x55\x66\x65\x43\xdf\xff\xff\xfa\x10\x12\x22\x22\x22\x32\x22\x22\x20\x00\x12\x23\x33\x44\x44\x44\x32\x11\x8e\xfe\xca\x66\x77\x57\x87\x77\x66\x67\x84\xab\x9a\xa9\xb9\x6e\xfe\x64\x35\x66\x55\x66\x65\x56\x66\x34\x9f\xff\xff\xfa\x10\x11\x12\x22\x22\x33\x22\x22\x10\x00\x11\x23\x34\x44\x55\x44\x32\x11\x8e\xfe\xca\x76\x77\x66\x87\x76\x66\x57\x84\x9b\x9a\x9a\xaa\x5d\xff\x84\x35\x66\x56\x66\x55\x45\x66\x44\x7f\xff\xff\xfa\x00\x11\x22\x22\x22\x22\x32\x22\x10\x00\x12\x34\x67\x78\x88\x76\x53\x11\x8e\xfe\xca\x76\x67\x66\x88\x66\x66\x56\x85\x7b\xaa\xba\xaa\x4c\xff\xb4\x45\x66\x55\x55\x45\x45\x66\x44\x5d\xff\xff\xfa\x10\x11\x22\x22\x33\x33\x23\x32\x10\x00\x12\x23\x34\x44\x44\x44\x42\x11\x8e\xfe\xca\x77\x66\x66\x88\x66\x66\x66\x87\x6b\xba\xab\xbb\x4b\xff\xd4\x44\x65\x54\x44\x44\x45\x55\x43\x4c\xff\xff\xfa\x00\x11\x22\x22\x22\x22\x22\x22\x10\x00\x11\x22\x33\x34\x44\x44\x32\x11\x8d\xed\xb9\x87\x76\x66\x78\x76\x66\x66\x78\x4b\xba\x98\x65\x18\xff\xe6\x33\x55\x54\x44\x55\x55\x54\x42\x5d\xff\xff\xea\x00\x11\x11\x22\x22\x22\x22\x21\x10\x00\x11\x12\x22\x22\x33\x32\x21\x10\x6a\xba\x98\x87\x77\x66\x66\x77\x76\x66\x77\x23\x11\x11\x11\x05\xcd\xd8\x33\x55\x55\x55\x54\x44\x34\x7b\xdf\xee\xee\xd8\x00\x01\x11\x11\x11\x11\x11\x11\x00\x00\x00\x11\x11\x12\x22\x12\x11\x00\x59\x99\x87\x87\x77\x66\x66\x76\x76\x66\x77\x10\x11\x11\x11\x02\xaa\xa9\x33\x45\x55\x44\x44\x58\xbd\xee\xff\xdd\xcc\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11\x11\x11\x10\x00\x69\x99\x87\x97\x77\x76\x76\x76\x65\x55\x67\x20\x10\x00\x00\x05\x99\x98\x43\x24\x33\x46\x89\xbc\xcd\xde\xee\xdc\xcc\xba\x42\x22\x22\x22\x22\x22\x22\x22\x22\x42\x11\x22\x22\x22\x22\x22\x21\x24\x79\x99\x88\x97\x66\x77\x77\x86\x67\x77\x88\x50\x00\x23\x46\x88\x99\x99\x63\x25\x78\x9a\xab\xbc\xcd\xde\xee\xee\xed\xdc\xbb\xaa\xa9\x99\x99\x99\x88\x88\x88\x88\x77\x77\x77\x77\x77\x77\x77\x78\x99\x99\x98\x88\x88\x88\x88\x88\x88\x88\x99\x87\x78\x99\x99\xaa\xaa\xaa\xa9\xaa\xbb\xcc\xcd\xdd\xee\xef\xff\xff\xff\xff\xee\xee\xed\xdd\xdd\xdc\xcc\xcc\xcc\xbb\xbb\xbb\xbb\xbb\xbb\xba\xaa\xaa\xab\xba\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcd\xdd\xdd\xde\xee\xee\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xed\xdd\xdd\xdd\xee\xee\xee\xee\xee\xee\xee\xee\xee\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' # noqa 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 ce088eae2e..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 ' """ @@ -8,7 +6,6 @@ Defines the errors that the device drivers generate. G{classtree ProtocolError} """ -from polyglot.builtins import unicode_type class ProtocolError(Exception): @@ -95,7 +92,7 @@ class DeviceBusy(ProtocolError): def __init__(self, uerr=""): ProtocolError.__init__( self, "Device is in use by another application:" - "\nUnderlying error:" + unicode_type(uerr) + "\nUnderlying error:" + str(uerr) ) @@ -138,9 +135,9 @@ class ControlError(ProtocolError): def __str__(self): if self.query and self.response: return "Got unexpected response:\n" + \ - "query:\n"+unicode_type(self.query.query)+"\n"+\ - "expected:\n"+unicode_type(self.query.response)+"\n" +\ - "actual:\n"+unicode_type(self.response) + "query:\n"+str(self.query.query)+"\n"+\ + "expected:\n"+str(self.query.response)+"\n" +\ + "actual:\n"+str(self.response) if self.desc: return self.desc return "Unknown control error occurred" 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/jetbook/driver.py b/src/calibre/devices/jetbook/driver.py index 2683570808..a047bdedad 100644 --- a/src/calibre/devices/jetbook/driver.py +++ b/src/calibre/devices/jetbook/driver.py @@ -15,7 +15,6 @@ import re from calibre.constants import filesystem_encoding from calibre.devices.usbms.driver import USBMS from calibre.ebooks.metadata import string_to_authors -from polyglot.builtins import unicode_type, map class JETBOOK(USBMS): @@ -65,7 +64,7 @@ class JETBOOK(USBMS): def metadata_from_path(cls, path): def check_unicode(txt): - if not isinstance(txt, unicode_type): + if not isinstance(txt, str): txt = txt.decode(filesystem_encoding, 'replace') txt = txt.replace('_', ' ') return txt 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/apnx.py b/src/calibre/devices/kindle/apnx.py index d93d32327c..36acd431f0 100644 --- a/src/calibre/devices/kindle/apnx.py +++ b/src/calibre/devices/kindle/apnx.py @@ -18,7 +18,7 @@ from calibre.ebooks.mobi.reader.headers import MetadataHeader from calibre.utils.logging import default_log from calibre import prints, fsync from calibre.constants import DEBUG -from polyglot.builtins import range, as_unicode, as_bytes, unicode_type, map +from polyglot.builtins import as_unicode, as_bytes class APNXBuilder: @@ -33,7 +33,7 @@ class APNXBuilder: using either the fast or accurate algorithm. ''' import uuid - apnx_meta = {'guid': unicode_type(uuid.uuid4()).replace('-', '')[:8], 'asin': + apnx_meta = {'guid': str(uuid.uuid4()).replace('-', '')[:8], 'asin': '', 'cdetype': 'EBOK', 'format': 'MOBI_7', 'acr': ''} with lopen(mobi_file_path, 'rb') as mf: @@ -53,11 +53,11 @@ class APNXBuilder: if mh.exth is None or not mh.exth.cdetype: apnx_meta['cdetype'] = 'EBOK' else: - apnx_meta['cdetype'] = unicode_type(mh.exth.cdetype) + apnx_meta['cdetype'] = str(mh.exth.cdetype) if mh.exth is None or not mh.exth.uuid: apnx_meta['asin'] = '' else: - apnx_meta['asin'] = unicode_type(mh.exth.uuid) + apnx_meta['asin'] = str(mh.exth.uuid) # Get the pages depending on the chosen parser pages = [] 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 4a5b9e117f..826bbe98af 100644 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -15,7 +15,7 @@ from calibre.constants import DEBUG, filesystem_encoding from calibre.devices.kindle.bookmark import Bookmark from calibre.devices.usbms.driver import USBMS from calibre import strftime, fsync, prints -from polyglot.builtins import unicode_type, as_bytes, as_unicode +from polyglot.builtins import as_bytes, as_unicode ''' Notes on collections: @@ -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: @@ -610,7 +610,7 @@ class KINDLE2(KINDLE): cust_col_name = opts.extra_customization[self.OPT_APNX_METHOD_COL] if cust_col_name: try: - temp = unicode_type(metadata.get(cust_col_name)).lower() + temp = str(metadata.get(cust_col_name)).lower() if temp in self.EXTRA_CUSTOMIZATION_CHOICES[self.OPT_APNX_METHOD]: method = temp else: 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 60ecc209e2..cfbcfe69c7 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -33,7 +33,7 @@ from calibre import prints, fsync from calibre.ptempfile import PersistentTemporaryFile, better_mktemp from calibre.constants import DEBUG from calibre.utils.config_base import prefs -from polyglot.builtins import iteritems, itervalues, unicode_type, string_or_bytes +from polyglot.builtins import iteritems, itervalues, string_or_bytes EPUB_EXT = '.epub' KEPUB_EXT = '.kepub' @@ -47,7 +47,7 @@ def qhash(inputstr): instr = b"" if isinstance(inputstr, bytes): instr = inputstr - elif isinstance(inputstr, unicode_type): + elif isinstance(inputstr, str): instr = inputstr.encode("utf8") else: return -1 @@ -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) @@ -377,7 +377,7 @@ class KOBO(USBMS): try: cursor.execute(query) except Exception as e: - err = unicode_type(e) + err = str(e) if not (any_in(err, '___ExpirationStatus', 'FavouritesIndex', 'Accessibility', 'IsDownloaded')): raise query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' @@ -483,13 +483,13 @@ class KOBO(USBMS): cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0, ___ExpirationStatus=3 ' 'where BookID is Null and ContentID =?',t) except Exception as e: - if 'no such column' not in unicode_type(e): + if 'no such column' not in str(e): raise try: cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0 ' 'where BookID is Null and ContentID =?',t) except Exception as e: - if 'no such column' not in unicode_type(e): + if 'no such column' not in str(e): raise cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\' ' 'where BookID is Null and ContentID =?',t) @@ -833,7 +833,7 @@ class KOBO(USBMS): cursor.execute(query) except Exception as e: debug_print(' Database Exception: Unable to reset Shortlist list') - if 'no such column' not in unicode_type(e): + if 'no such column' not in str(e): raise finally: cursor.close() @@ -847,7 +847,7 @@ class KOBO(USBMS): cursor.execute('update content set FavouritesIndex=1 where BookID is Null and ContentID = ?', t) except Exception as e: debug_print(' Database Exception: Unable set book as Shortlist') - if 'no such column' not in unicode_type(e): + if 'no such column' not in str(e): raise finally: cursor.close() @@ -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: @@ -1808,7 +1808,7 @@ class KOBOTOUCH(KOBO): debug_print('KoboTouch:update_booklist - book file does not exist. ContentID="%s"'%ContentID) except Exception as e: - debug_print("KoboTouch:update_booklist - exception creating book: '%s'"%unicode_type(e)) + debug_print("KoboTouch:update_booklist - exception creating book: '%s'"%str(e)) debug_print(" prefix: ", prefix, "lpath: ", lpath, "title: ", title, "authors: ", authors, "MimeType: ", MimeType, "DateCreated: ", DateCreated, "ContentType: ", ContentType, "ImageID: ", ImageID) raise @@ -1870,7 +1870,7 @@ class KOBOTOUCH(KOBO): bookshelves.append(row['ShelfName']) cursor.close() -# debug_print("KoboTouch:get_bookshelvesforbook - count bookshelves=" + unicode_type(count_bookshelves)) +# debug_print("KoboTouch:get_bookshelvesforbook - count bookshelves=" + str(count_bookshelves)) return bookshelves self.debug_index = 0 @@ -1963,7 +1963,7 @@ class KOBOTOUCH(KOBO): try: cursor.execute(query) except Exception as e: - err = unicode_type(e) + err = str(e) if not (any_in(err, '___ExpirationStatus', 'FavouritesIndex', 'Accessibility', 'IsDownloaded', 'Series', 'ExternalId')): raise query= ('SELECT Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' @@ -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: @@ -2174,12 +2174,12 @@ class KOBOTOUCH(KOBO): cursor.close() except Exception as e: - debug_print('KoboTouch:upload_books - Exception: %s'%unicode_type(e)) + debug_print('KoboTouch:upload_books - Exception: %s'%str(e)) 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) @@ -2318,7 +2318,7 @@ class KOBOTOUCH(KOBO): debug_print('KoboTouch:delete_via_sql: finished SQL') debug_print('KoboTouch:delete_via_sql: After SQL, no exception') except Exception as e: - debug_print('KoboTouch:delete_via_sql - Database Exception: %s'%unicode_type(e)) + debug_print('KoboTouch:delete_via_sql - Database Exception: %s'%str(e)) debug_print('KoboTouch:delete_via_sql: imageId="%s"'%imageId) if imageId is None: @@ -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): @@ -2451,7 +2451,7 @@ class KOBOTOUCH(KOBO): if self.manage_collections: if collections: - # debug_print("KoboTouch:update_device_database_collections - length collections=" + unicode_type(len(collections))) + # debug_print("KoboTouch:update_device_database_collections - length collections=" + str(len(collections))) # Need to reset the collections outside the particular loops # otherwise the last item will not be removed @@ -2621,7 +2621,7 @@ class KOBOTOUCH(KOBO): self.keep_cover_aspect, self.letterbox_fs_covers, self.png_covers, letterbox_color=self.letterbox_fs_covers_color) except Exception as e: - debug_print('KoboTouch: FAILED to upload cover=%s Exception=%s'%(filepath, unicode_type(e))) + debug_print('KoboTouch: FAILED to upload cover=%s Exception=%s'%(filepath, str(e))) def imageid_from_contentid(self, ContentID): ImageID = ContentID.replace('/', '_') @@ -2831,7 +2831,7 @@ class KOBOTOUCH(KOBO): f.write(data) fsync(f) except Exception as e: - err = unicode_type(e) + err = str(e) debug_print("KoboTouch:_upload_cover - Exception string: %s"%err) raise @@ -2978,7 +2978,7 @@ class KOBOTOUCH(KOBO): # count_bookshelves = i + 1 cursor.close() -# debug_print("KoboTouch:get_bookshelflist - count bookshelves=" + unicode_type(count_bookshelves)) +# debug_print("KoboTouch:get_bookshelflist - count bookshelves=" + str(count_bookshelves)) return bookshelves @@ -3062,7 +3062,7 @@ class KOBOTOUCH(KOBO): cursor.execute(addquery, add_values) elif result['_IsDeleted'] == 'true': debug_print("KoboTouch:check_for_bookshelf - Shelf '%s' is deleted - undeleting. result['_IsDeleted']='%s'" % ( - bookshelf_name, unicode_type(result['_IsDeleted']))) + bookshelf_name, str(result['_IsDeleted']))) cursor.execute(updatequery, test_values) cursor.close() @@ -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 046bb8afb5..e45384f0de 100644 --- a/src/calibre/devices/kobo/kobotouch_config.py +++ b/src/calibre/devices/kobo/kobotouch_config.py @@ -16,7 +16,6 @@ from calibre.devices.usbms.driver import debug_print from calibre.gui2 import error_dialog from calibre.gui2.widgets2 import ColorButton from calibre.gui2.dialogs.template_dialog import TemplateDialog -from polyglot.builtins import unicode_type def wrap_msg(msg): @@ -40,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) @@ -66,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 @@ -96,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 @@ -128,7 +127,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig): p['support_newer_firmware'] = self.support_newer_firmware p['debugging_title'] = self.debugging_title - p['driver_version'] = '.'.join([unicode_type(i) for i in self.device.version]) + p['driver_version'] = '.'.join([str(i) for i in self.device.version]) return p @@ -136,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) @@ -160,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) @@ -188,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() @@ -230,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() @@ -297,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() @@ -416,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() @@ -466,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() @@ -480,7 +479,7 @@ class AdvancedGroupBox(DeviceOptionsGroupBox): 'to perform full read-write functionality - Here be Dragons!! ' 'Enable only if you are comfortable with restoring your kobo ' 'to factory defaults and testing software. ' - 'This driver supports firmware V2.x.x and DBVersion up to ') + unicode_type( + 'This driver supports firmware V2.x.x and DBVersion up to ') + str( device.supported_dbversion), device.get_pref('support_newer_firmware') ) @@ -515,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() @@ -638,7 +637,7 @@ class TemplateConfig(QWidget): # {{{ @property def template(self): - return unicode_type(self.t.text()).strip() + return str(self.t.text()).strip() @template.setter def template(self, template): @@ -660,7 +659,7 @@ class TemplateConfig(QWidget): # {{{ except Exception as err: error_dialog(self, _('Invalid template'), '

'+_('The template "%s" is invalid:')%tmpl + - '
'+unicode_type(err), show=True) + '
'+str(err), show=True) return False # }}} 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/driver.py b/src/calibre/devices/mtp/driver.py index a47cfff3ff..54276b55a2 100644 --- a/src/calibre/devices/mtp/driver.py +++ b/src/calibre/devices/mtp/driver.py @@ -16,7 +16,7 @@ from calibre.devices.mtp.base import debug from calibre.devices.mtp.defaults import DeviceDefaults from calibre.ptempfile import SpooledTemporaryFile, PersistentTemporaryDirectory from calibre.utils.filenames import shorten_components_to -from polyglot.builtins import iteritems, itervalues, unicode_type, zip, as_bytes +from polyglot.builtins import iteritems, itervalues, as_bytes BASE = importlib.import_module('calibre.devices.mtp.%s.driver'%( 'windows' if iswindows else 'unix')).MTP_DEVICE @@ -76,7 +76,7 @@ class MTP_DEVICE(BASE): def is_folder_ignored(self, storage_or_storage_id, path, ignored_folders=None): - storage_id = unicode_type(getattr(storage_or_storage_id, 'object_id', + storage_id = str(getattr(storage_or_storage_id, 'object_id', storage_or_storage_id)) lpath = tuple(icu_lower(name) for name in path) if ignored_folders is None: @@ -168,14 +168,14 @@ class MTP_DEVICE(BASE): traceback.print_exc() dinfo = {} if dinfo.get('device_store_uuid', None) is None: - dinfo['device_store_uuid'] = unicode_type(uuid.uuid4()) + dinfo['device_store_uuid'] = str(uuid.uuid4()) if dinfo.get('device_name', None) is None: dinfo['device_name'] = self.current_friendly_name if name is not None: dinfo['device_name'] = name dinfo['location_code'] = location_code dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) - dinfo['calibre_version'] = '.'.join([unicode_type(i) for i in numeric_version]) + dinfo['calibre_version'] = '.'.join([str(i) for i in numeric_version]) dinfo['date_last_connected'] = isoformat(now()) dinfo['mtp_prefix'] = storage.storage_prefix raw = as_bytes(json.dumps(dinfo, default=to_json)) diff --git a/src/calibre/devices/mtp/filesystem_cache.py b/src/calibre/devices/mtp/filesystem_cache.py index 3ddf5a22f1..632f5a3fb4 100644 --- a/src/calibre/devices/mtp/filesystem_cache.py +++ b/src/calibre/devices/mtp/filesystem_cache.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import weakref, sys, json from collections import deque from operator import attrgetter -from polyglot.builtins import itervalues, map, unicode_type +from polyglot.builtins import itervalues from datetime import datetime from calibre import human_readable, prints, force_unicode @@ -73,7 +73,7 @@ class FileOrFolder: def __repr__(self): name = 'Folder' if self.is_folder else 'File' try: - path = unicode_type(self.full_path) + path = str(self.full_path) except: path = '' datum = 'size=%s'%(self.size) @@ -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/test.py b/src/calibre/devices/mtp/test.py index ab16043530..45a81d4d53 100644 --- a/src/calibre/devices/mtp/test.py +++ b/src/calibre/devices/mtp/test.py @@ -12,7 +12,6 @@ from calibre.constants import iswindows, islinux from calibre.utils.icu import lower from calibre.devices.mtp.driver import MTP_DEVICE from calibre.devices.scanner import DeviceScanner -from polyglot.builtins import range class ProgressCallback: diff --git a/src/calibre/devices/mtp/unix/driver.py b/src/calibre/devices/mtp/unix/driver.py index 2343f8d964..8130f088b3 100644 --- a/src/calibre/devices/mtp/unix/driver.py +++ b/src/calibre/devices/mtp/unix/driver.py @@ -15,7 +15,6 @@ from calibre.constants import islinux, ismacos from calibre.ptempfile import SpooledTemporaryFile from calibre.devices.errors import OpenFailed, DeviceError, BlacklistedDevice, OpenActionNeeded from calibre.devices.mtp.base import MTPDeviceBase, synchronous, debug -from polyglot.builtins import unicode_type MTPDevice = namedtuple('MTPDevice', 'busnum devnum vendor_id product_id ' 'bcd serial manufacturer product') @@ -76,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): @@ -222,7 +221,7 @@ class MTP_DEVICE(MTPDeviceBase): try: storage = sorted(self.dev.storage_info, key=operator.itemgetter('id')) except self.libmtp.MTPError as e: - if "The device has no storage information." in unicode_type(e): + if "The device has no storage information." in str(e): # This happens on newer Android devices while waiting for # the user to allow access. Apparently what happens is # that when the user clicks allow, the device disconnects @@ -317,7 +316,7 @@ class MTP_DEVICE(MTPDeviceBase): storage.append({'id':sid, 'size':capacity, 'is_folder':True, 'name':name, 'can_delete':False, 'is_system':True}) - self._currently_getting_sid = unicode_type(sid) + self._currently_getting_sid = str(sid) items, errs = self.dev.get_filesystem(sid, partial(self._filesystem_callback, {})) all_items.extend(items), all_errs.extend(errs) 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/mtp/windows/driver.py b/src/calibre/devices/mtp/windows/driver.py index 1bb06f6e9f..3bfbe1f451 100644 --- a/src/calibre/devices/mtp/windows/driver.py +++ b/src/calibre/devices/mtp/windows/driver.py @@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en' import time, threading, traceback from functools import wraps, partial -from polyglot.builtins import iteritems, itervalues, unicode_type, zip +from polyglot.builtins import iteritems, itervalues from itertools import chain from calibre import as_unicode, prints, force_unicode @@ -268,7 +268,7 @@ class MTP_DEVICE(MTPDeviceBase): break storage = {'id':storage_id, 'size':capacity, 'name':name, 'is_folder':True, 'can_delete':False, 'is_system':True} - self._currently_getting_sid = unicode_type(storage_id) + self._currently_getting_sid = str(storage_id) id_map = self.dev.get_filesystem(storage_id, partial( self._filesystem_callback, {})) for x in itervalues(id_map): 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 d025a994f0..d77273ae9c 100644 --- a/src/calibre/devices/prs505/sony_cache.py +++ b/src/calibre/devices/prs505/sony_cache.py @@ -17,7 +17,6 @@ from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.metadata import authors_to_string, title_sort, \ authors_to_sort_string from polyglot.binary import from_base64_bytes -from polyglot.builtins import unicode_type, zip ''' cacheExt.xml @@ -66,8 +65,8 @@ INVERSE_MONTH_MAP = dict(zip(MONTH_MAP.values(), MONTH_MAP.keys())) def strptime(src): src = src.strip() src = src.split() - src[0] = unicode_type(DAY_MAP[src[0][:-1]])+',' - src[2] = unicode_type(MONTH_MAP[src[2]]) + src[0] = str(DAY_MAP[src[0][:-1]])+',' + src[2] = str(MONTH_MAP[src[2]]) return time.strptime(' '.join(src), '%w, %d %m %Y %H:%M:%S %Z') @@ -84,7 +83,7 @@ def strftime(epoch, zone=time.localtime): def uuid(): from uuid import uuid4 - return unicode_type(uuid4()).replace('-', '', 1).upper() + return str(uuid4()).replace('-', '', 1).upper() # }}} @@ -197,8 +196,8 @@ class XMLCache: playlist.set('title', title) if title in seen: for i in range(2, 1000): - if title+unicode_type(i) not in seen: - title = title+unicode_type(i) + if title+str(i) not in seen: + title = title+str(i) playlist.set('title', title) seen.add(title) break @@ -271,7 +270,7 @@ class XMLCache: nsmap=root.nsmap, attrib={ 'uuid' : uuid(), 'title': title, - 'id' : unicode_type(self.max_id(root)+1), + 'id' : str(self.max_id(root)+1), 'sourceid': '1' }) root.append(ans) @@ -310,13 +309,13 @@ class XMLCache: def ensure_media_xml_base_ids(root): for num, tag in enumerate(('library', 'watchSpecial')): for x in root.xpath('//*[local-name()="%s"]'%tag): - x.set('id', unicode_type(num)) + x.set('id', str(num)) def rebase_ids(root, base, sourceid, pl_sourceid): 'Rebase all ids and also make them consecutive' for item in root.xpath('//*[@sourceid]'): sid = pl_sourceid if item.tag.endswith('playlist') else sourceid - item.set('sourceid', unicode_type(sid)) + item.set('sourceid', str(sid)) # Only rebase ids of nodes that are immediate children of the # record root (that way playlist/itemnodes are unaffected items = root.xpath('child::*[@id]') @@ -326,8 +325,8 @@ class XMLCache: old = int(item.get('id')) new = base + i if old != new: - item.set('id', unicode_type(new)) - idmap[unicode_type(old)] = unicode_type(new) + item.set('id', str(new)) + idmap[str(old)] = str(new) return idmap self.prune_empty_playlists() @@ -356,7 +355,7 @@ class XMLCache: last_bl = max(self.roots.keys()) max_id = self.max_id(self.roots[last_bl]) - self.roots[0].set('nextID', unicode_type(max_id+1)) + self.roots[0].set('nextID', str(max_id+1)) debug_print('Finished running fix_ids()') # }}} @@ -513,7 +512,7 @@ class XMLCache: # Ensure each book has an ID. for rec in records: if rec.get('id', None) is None: - rec.set('id', unicode_type(self.max_id(root)+1)) + rec.set('id', str(self.max_id(root)+1)) ids = [x.get('id', None) for x in records] # Given that we set the ids, there shouldn't be any None's. But # better to be safe... @@ -570,7 +569,7 @@ class XMLCache: id_ = self.max_id(root)+1 attrib = { 'page':'0', 'part':'0','pageOffset':'0','scale':'0', - 'id':unicode_type(id_), 'sourceid':'1', 'path':lpath} + 'id':str(id_), 'sourceid':'1', 'path':lpath} ans = root.makeelement('{%s}text'%namespace, attrib=attrib, nsmap=root.nsmap) root.append(ans) return ans @@ -589,7 +588,7 @@ class XMLCache: if thumbnail and thumbnail[-1]: ans.text = '\n' + '\t\t' t = root.makeelement('{%s}thumbnail'%namespace, - attrib={'width':unicode_type(thumbnail[0]), 'height':unicode_type(thumbnail[1])}, + attrib={'width':str(thumbnail[0]), 'height':str(thumbnail[1])}, nsmap=root.nsmap) t.text = 'main_thumbnail.jpg' ans.append(t) @@ -658,7 +657,7 @@ class XMLCache: date = strftime(timestamp, zone=tz) record.set('date', clean(date)) try: - record.set('size', clean(unicode_type(os.stat(path).st_size))) + record.set('size', clean(str(os.stat(path).st_size))) except: record.set('size', '0') title = book.title if book.title else _('Unknown') @@ -688,7 +687,7 @@ class XMLCache: record.set('sourceid', '1') if 'id' not in record.attrib: num = self.max_id(record.getroottree().getroot()) - record.set('id', unicode_type(num+1)) + record.set('id', str(num+1)) return (gtz_count, ltz_count, use_tz_var) # }}} @@ -759,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 a46bc469b2..8ef883af64 100644 --- a/src/calibre/devices/prst1/driver.py +++ b/src/calibre/devices/prst1/driver.py @@ -23,7 +23,7 @@ from calibre.devices.usbms.books import CollectionsBookList from calibre.devices.usbms.books import BookList from calibre.ebooks.metadata import authors_to_sort_string, authors_to_string from calibre.constants import islinux -from polyglot.builtins import unicode_type, long_type +from polyglot.builtins import long_type DBPATH = 'Sony_Reader/database/books.db' THUMBPATH = 'Sony_Reader/database/cache/books/%s/thumbnail/main_thumbnail.jpg' @@ -170,7 +170,7 @@ class PRST1(USBMS): with closing(sqlite.connect(dbpath)) as connection: # Replace undecodable characters in the db instead of erroring out - connection.text_factory = lambda x: x if isinstance(x, unicode_type) else x.decode('utf-8', 'replace') + connection.text_factory = lambda x: x if isinstance(x, str) else x.decode('utf-8', 'replace') cursor = connection.cursor() # Query collections @@ -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 9a0e6f2535..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 ' ''' @@ -13,7 +12,6 @@ from threading import Lock from calibre import prints, as_unicode from calibre.constants import (iswindows, ismacos, islinux, isfreebsd, isnetbsd) -from polyglot.builtins import range osx_scanner = linux_scanner = freebsd_scanner = netbsd_scanner = None @@ -41,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, @@ -142,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 6a2fa5f937..7e9292bb66 100644 --- a/src/calibre/devices/smart_device_app/driver.py +++ b/src/calibre/devices/smart_device_app/driver.py @@ -47,7 +47,7 @@ from calibre.utils.mdns import ( ) from calibre.utils.socket_inheritance import set_socket_inherit from polyglot import queue -from polyglot.builtins import as_bytes, iteritems, itervalues, unicode_type +from polyglot.builtins import as_bytes, iteritems, itervalues def synchronous(tlockname): @@ -125,13 +125,13 @@ class ConnectionListener(Thread): content_server_port = '' try: from calibre.srv.opts import server_config - content_server_port = unicode_type(server_config().port) + content_server_port = str(server_config().port) except Exception: pass message = (self.driver.ZEROCONF_CLIENT_STRING + ' (on ' + - unicode_type(socket.gethostname().partition('.')[0]) + + str(socket.gethostname().partition('.')[0]) + ');' + content_server_port + - ',' + unicode_type(self.driver.port)).encode('utf-8') + ',' + str(self.driver.port)).encode('utf-8') self.driver._debug('received broadcast', packet, message) self.driver.broadcast_socket.sendto(message, remote) except: @@ -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) @@ -414,7 +414,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): if isinstance(a, dict): printable = {} for k,v in iteritems(a): - if isinstance(v, (bytes, unicode_type)) and len(v) > 50: + if isinstance(v, (bytes, str)) and len(v) > 50: printable[k] = 'too long' else: printable[k] = v @@ -436,14 +436,14 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): if not isinstance(dinfo, dict): dinfo = {} if dinfo.get('device_store_uuid', None) is None: - dinfo['device_store_uuid'] = unicode_type(uuid.uuid4()) + dinfo['device_store_uuid'] = str(uuid.uuid4()) if dinfo.get('device_name') is None: dinfo['device_name'] = self.get_gui_name() if name is not None: dinfo['device_name'] = name dinfo['location_code'] = location_code dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) - dinfo['calibre_version'] = '.'.join([unicode_type(i) for i in numeric_version]) + dinfo['calibre_version'] = '.'.join([str(i) for i in numeric_version]) dinfo['date_last_connected'] = isoformat(now()) dinfo['prefix'] = self.PREFIX return dinfo @@ -495,9 +495,9 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): from calibre.library.save_to_disk import config, get_components opts = config().parse() - if not isinstance(template, unicode_type): + if not isinstance(template, str): template = template.decode('utf-8') - app_id = unicode_type(getattr(mdata, 'application_id', '')) + app_id = str(getattr(mdata, 'application_id', '')) id_ = mdata.get('id', fname) extra_components = get_components(template, mdata, id_, timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1, @@ -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') @@ -747,7 +747,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): from calibre.utils.date import now, parse_date try: key = self._make_metadata_cache_key(uuid, ext_or_lpath) - if isinstance(lastmod, unicode_type): + if isinstance(lastmod, str): if lastmod == 'None': return None lastmod = parse_date(lastmod) @@ -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() @@ -1909,7 +1909,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): 'between 50 and 99. Forced to be %d.')%self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY self._debug(message) self.set_option('thumbnail_compression_quality', - unicode_type(self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY)) + str(self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY)) try: self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 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 18770fb816..6c3cf2532e 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -27,7 +27,7 @@ from calibre.devices.errors import DeviceError from calibre.devices.interface import DevicePlugin from calibre.devices.usbms.deviceconfig import DeviceConfig from calibre.utils.filenames import ascii_filename as sanitize -from polyglot.builtins import iteritems, map, string_or_bytes +from polyglot.builtins import iteritems, string_or_bytes if ismacos: osx_sanitize_name_pat = re.compile(r'[.-]') @@ -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/deviceconfig.py b/src/calibre/devices/usbms/deviceconfig.py index f915f15f55..0f61f7dc47 100644 --- a/src/calibre/devices/usbms/deviceconfig.py +++ b/src/calibre/devices/usbms/deviceconfig.py @@ -6,7 +6,6 @@ __copyright__ = '2009, John Schember ' __docformat__ = 'restructuredtext en' from calibre.utils.config_base import Config, ConfigProxy -from polyglot.builtins import unicode_type class DeviceConfig: @@ -109,15 +108,15 @@ class DeviceConfig: if hasattr(config_widget.opt_extra_customization[i], 'isChecked'): ec.append(config_widget.opt_extra_customization[i].isChecked()) elif hasattr(config_widget.opt_extra_customization[i], 'currentText'): - ec.append(unicode_type(config_widget.opt_extra_customization[i].currentText()).strip()) + ec.append(str(config_widget.opt_extra_customization[i].currentText()).strip()) else: - ec.append(unicode_type(config_widget.opt_extra_customization[i].text()).strip()) + ec.append(str(config_widget.opt_extra_customization[i].text()).strip()) else: - ec = unicode_type(config_widget.opt_extra_customization.text()).strip() + ec = str(config_widget.opt_extra_customization.text()).strip() if not ec: ec = None proxy['extra_customization'] = ec - st = unicode_type(config_widget.opt_save_template.text()) + st = str(config_widget.opt_save_template.text()) proxy['save_template'] = st @classmethod diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index a0551b9d8a..dde84a97c9 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -21,7 +21,7 @@ from calibre.devices.usbms.cli import CLI from calibre.devices.usbms.device import Device from calibre.devices.usbms.books import BookList, Book from calibre.ebooks.metadata.book.json_codec import JsonCodec -from polyglot.builtins import itervalues, unicode_type, string_or_bytes, zip +from polyglot.builtins import itervalues, string_or_bytes def debug_print(*args, **kw): @@ -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 @@ -107,14 +106,14 @@ class USBMS(CLI, Device): if not isinstance(dinfo, dict): dinfo = {} if dinfo.get('device_store_uuid', None) is None: - dinfo['device_store_uuid'] = unicode_type(uuid.uuid4()) + dinfo['device_store_uuid'] = str(uuid.uuid4()) if dinfo.get('device_name', None) is None: dinfo['device_name'] = self.get_gui_name() if name is not None: dinfo['device_name'] = name dinfo['location_code'] = location_code dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) - dinfo['calibre_version'] = '.'.join([unicode_type(i) for i in numeric_version]) + dinfo['calibre_version'] = '.'.join([str(i) for i in numeric_version]) dinfo['date_last_connected'] = isoformat(now()) dinfo['prefix'] = prefix.replace('\\', '/') return dinfo @@ -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 0cb0ad1bd9..d0543174cd 100644 --- a/src/calibre/devices/utils.py +++ b/src/calibre/devices/utils.py @@ -10,7 +10,6 @@ import os, time, re from functools import partial from calibre.devices.errors import DeviceError, WrongDestinationError, FreeSpaceError -from polyglot.builtins import unicode_type def sanity_check(on_card, files, card_prefixes, free_space): @@ -60,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]*$)') @@ -91,15 +90,15 @@ 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] opts = config().parse() - if not isinstance(template, unicode_type): + if not isinstance(template, str): template = template.decode('utf-8') - app_id = unicode_type(getattr(mdata, 'application_id', '')) + app_id = str(getattr(mdata, 'application_id', '')) id_ = mdata.get('id', fname) extra_components = get_components(template, mdata, id_, timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1, diff --git a/src/calibre/devices/winusb.py b/src/calibre/devices/winusb.py index 1caed21561..e00531f1d2 100644 --- a/src/calibre/devices/winusb.py +++ b/src/calibre/devices/winusb.py @@ -13,7 +13,7 @@ from ctypes import ( ) from ctypes.wintypes import DWORD, WORD, ULONG, LPCWSTR, HWND, BOOL, LPWSTR, UINT, BYTE, HANDLE, USHORT from pprint import pprint, pformat -from polyglot.builtins import iteritems, itervalues, map, filter +from polyglot.builtins import iteritems, itervalues from calibre import prints, as_unicode @@ -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/BeautifulSoup.py b/src/calibre/ebooks/BeautifulSoup.py index ac445ad6b6..e297330f4d 100644 --- a/src/calibre/ebooks/BeautifulSoup.py +++ b/src/calibre/ebooks/BeautifulSoup.py @@ -9,13 +9,12 @@ from bs4 import ( # noqa SoupStrainer, Tag, __version__ ) -from polyglot.builtins import unicode_type def parse_html(markup): from calibre.ebooks.chardet import strip_encoding_declarations, xml_to_unicode, substitute_entites from calibre.utils.cleantext import clean_xml_chars - if isinstance(markup, unicode_type): + if isinstance(markup, str): markup = strip_encoding_declarations(markup) markup = substitute_entites(markup) else: diff --git a/src/calibre/ebooks/__init__.py b/src/calibre/ebooks/__init__.py index ab2260345e..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 ' @@ -11,7 +9,6 @@ from various formats. import os, re, numbers, sys from calibre import prints from calibre.ebooks.chardet import xml_to_unicode -from polyglot.builtins import unicode_type class ConversionError(Exception): @@ -82,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(unicode_type, body.findAll(text=True))) + text = ''.join(map(str, body.findAll(text=True))) if text.strip(): # Body has text, abort return @@ -152,7 +149,7 @@ def check_ebook_format(stream, current_guess): def normalize(x): - if isinstance(x, unicode_type): + if isinstance(x, str): import unicodedata x = unicodedata.normalize('NFC', x) return x diff --git a/src/calibre/ebooks/azw4/reader.py b/src/calibre/ebooks/azw4/reader.py index c07b620d63..c4a0463566 100644 --- a/src/calibre/ebooks/azw4/reader.py +++ b/src/calibre/ebooks/azw4/reader.py @@ -16,7 +16,6 @@ import os import re from calibre.ebooks.pdb.formatreader import FormatReader -from polyglot.builtins import getcwd def unwrap(stream, output_path): @@ -46,7 +45,7 @@ class Reader(FormatReader): if mo: data = mo.group() - pdf_n = os.path.join(getcwd(), 'tmp.pdf') + pdf_n = os.path.join(os.getcwd(), 'tmp.pdf') with open(pdf_n, 'wb') as pdf: pdf.write(data) from calibre.customize.ui import plugin_for_input_format diff --git a/src/calibre/ebooks/chardet.py b/src/calibre/ebooks/chardet.py index b17290b657..ced93f410b 100644 --- a/src/calibre/ebooks/chardet.py +++ b/src/calibre/ebooks/chardet.py @@ -7,7 +7,6 @@ __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' import re, codecs, sys -from polyglot.builtins import unicode_type _encoding_pats = ( # XML declaration @@ -34,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() @@ -52,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 @@ -140,7 +138,7 @@ def force_encoding(raw, verbose, assume_utf8=False): def detect_xml_encoding(raw, verbose=False, assume_utf8=False): - if not raw or isinstance(raw, unicode_type): + if not raw or isinstance(raw, str): return raw, None for x in ('utf8', 'utf-16-le', 'utf-16-be'): bom = getattr(codecs, 'BOM_'+x.upper().replace('-16', '16').replace( @@ -184,7 +182,7 @@ def xml_to_unicode(raw, verbose=False, strip_encoding_pats=False, return '', None raw, encoding = detect_xml_encoding(raw, verbose=verbose, assume_utf8=assume_utf8) - if not isinstance(raw, unicode_type): + if not isinstance(raw, str): raw = raw.decode(encoding, 'replace') if strip_encoding_pats: diff --git a/src/calibre/ebooks/chm/reader.py b/src/calibre/ebooks/chm/reader.py index 20c2ef15e9..2feb362a5a 100644 --- a/src/calibre/ebooks/chm/reader.py +++ b/src/calibre/ebooks/chm/reader.py @@ -13,7 +13,7 @@ from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.metadata.toc import TOC from chm.chm import CHMFile, chmlib -from polyglot.builtins import as_unicode, getcwd, unicode_type +from polyglot.builtins import as_unicode def match_string(s1, s2_already_lowered): @@ -43,7 +43,7 @@ class CHMReader(CHMFile): def __init__(self, input, log, input_encoding=None): CHMFile.__init__(self) - if isinstance(input, unicode_type): + if isinstance(input, str): enc = 'mbcs' if iswindows else filesystem_encoding try: input = input.encode(enc) @@ -113,7 +113,7 @@ class CHMReader(CHMFile): def get_encoding(self): return self.encoding_from_system_file or self.encoding_from_lcid or 'cp1252' - def _parse_toc(self, ul, basedir=getcwd()): + def _parse_toc(self, ul, basedir=os.getcwd()): toc = TOC(play_order=self._playorder, base_path=basedir, text='') self._playorder += 1 for li in ul('li', recursive=False): @@ -157,7 +157,7 @@ class CHMReader(CHMFile): def get_home(self): return self.GetFile(self.home) - def ExtractFiles(self, output_dir=getcwd(), debug_dump=False): + def ExtractFiles(self, output_dir=os.getcwd(), debug_dump=False): html_files = set() for path in self.Contents(): fpath = path @@ -192,7 +192,7 @@ class CHMReader(CHMFile): with lopen(lpath, 'r+b') as f: data = f.read() data = self._reformat(data, lpath) - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') f.seek(0) f.truncate() @@ -336,5 +336,5 @@ class CHMReader(CHMFile): if not os.path.isdir(dir): os.makedirs(dir) - def extract_content(self, output_dir=getcwd(), debug_dump=False): + def extract_content(self, output_dir=os.getcwd(), debug_dump=False): self.ExtractFiles(output_dir=output_dir, debug_dump=debug_dump) diff --git a/src/calibre/ebooks/comic/input.py b/src/calibre/ebooks/comic/input.py index ae80bc6769..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' @@ -16,7 +14,6 @@ from calibre.ptempfile import PersistentTemporaryDirectory from calibre.utils.icu import numeric_sort_key from calibre.utils.ipc.server import Server from calibre.utils.ipc.job import ParallelJob -from polyglot.builtins import unicode_type, map from polyglot.queue import Empty # If the specified screen has either dimension larger than this value, no image @@ -29,7 +26,7 @@ def extract_comic(path_to_comic_file): Un-archive the comic file. ''' tdir = PersistentTemporaryDirectory(suffix='_comic_extract') - if not isinstance(tdir, unicode_type): + if not isinstance(tdir, str): # Needed in case the zip file has wrongly encoded unicode file/dir # names tdir = tdir.decode(filesystem_encoding) diff --git a/src/calibre/ebooks/compression/palmdoc.py b/src/calibre/ebooks/compression/palmdoc.py index b142cefe73..9b607cb8e7 100644 --- a/src/calibre/ebooks/compression/palmdoc.py +++ b/src/calibre/ebooks/compression/palmdoc.py @@ -8,7 +8,6 @@ __copyright__ = '2008, Kovid Goyal ' import io from struct import pack -from polyglot.builtins import range from calibre_extensions import cPalmdoc diff --git a/src/calibre/ebooks/compression/tcr.py b/src/calibre/ebooks/compression/tcr.py index b13f49009f..d4ec4cc8be 100644 --- a/src/calibre/ebooks/compression/tcr.py +++ b/src/calibre/ebooks/compression/tcr.py @@ -6,7 +6,7 @@ __copyright__ = '2009, John Schember ' __docformat__ = 'restructuredtext en' import re -from polyglot.builtins import int_to_byte, range +from polyglot.builtins import int_to_byte class TCRCompressor: 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 ec2da77273..3d0828da1e 100644 --- a/src/calibre/ebooks/conversion/config.py +++ b/src/calibre/ebooks/conversion/config.py @@ -13,7 +13,6 @@ from calibre.utils.lock import ExclusiveFile from calibre import sanitize_file_name from calibre.customize.conversion import OptionRecommendation from calibre.customize.ui import available_output_formats -from polyglot.builtins import unicode_type config_dir = os.path.join(config_dir, 'conversion') @@ -71,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 @@ -90,7 +89,7 @@ class GuiRecommendations(dict): def serialize(self): ans = json.dumps(self, indent=2, ensure_ascii=False) - if isinstance(ans, unicode_type): + if isinstance(ans, str): ans = ans.encode('utf-8') return b'json:' + ans diff --git a/src/calibre/ebooks/conversion/plugins/azw4_input.py b/src/calibre/ebooks/conversion/plugins/azw4_input.py index 0c31739ba3..505e41b3fe 100644 --- a/src/calibre/ebooks/conversion/plugins/azw4_input.py +++ b/src/calibre/ebooks/conversion/plugins/azw4_input.py @@ -5,8 +5,9 @@ __license__ = 'GPL v3' __copyright__ = '2011, John Schember ' __docformat__ = 'restructuredtext en' +import os + from calibre.customize.conversion import InputFormatPlugin -from polyglot.builtins import getcwd class AZW4Input(InputFormatPlugin): @@ -24,6 +25,6 @@ class AZW4Input(InputFormatPlugin): header = PdbHeaderReader(stream) reader = Reader(header, stream, log, options) - opf = reader.extract_content(getcwd()) + opf = reader.extract_content(os.getcwd()) return opf diff --git a/src/calibre/ebooks/conversion/plugins/chm_input.py b/src/calibre/ebooks/conversion/plugins/chm_input.py index dab7b32a48..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 ,' \ @@ -10,7 +8,7 @@ import os from calibre.customize.conversion import InputFormatPlugin from calibre.ptempfile import TemporaryDirectory from calibre.constants import filesystem_encoding -from polyglot.builtins import unicode_type, as_bytes +from polyglot.builtins import as_bytes class CHMInput(InputFormatPlugin): @@ -37,7 +35,7 @@ class CHMInput(InputFormatPlugin): log.debug('Processing CHM...') with TemporaryDirectory('_chm2oeb') as tdir: - if not isinstance(tdir, unicode_type): + if not isinstance(tdir, str): tdir = tdir.decode(filesystem_encoding) html_input = plugin_for_input_format('html') for opt in html_input.options: @@ -128,7 +126,7 @@ class CHMInput(InputFormatPlugin): base = os.path.dirname(os.path.abspath(htmlpath)) def unquote(x): - if isinstance(x, unicode_type): + if isinstance(x, str): x = x.encode('utf-8') return _unquote(x).decode('utf-8') diff --git a/src/calibre/ebooks/conversion/plugins/comic_input.py b/src/calibre/ebooks/conversion/plugins/comic_input.py index 2983caa511..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' @@ -13,7 +11,6 @@ import shutil, textwrap, codecs, os from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation from calibre import CurrentDir from calibre.ptempfile import PersistentTemporaryDirectory -from polyglot.builtins import getcwd, map class ComicInput(InputFormatPlugin): @@ -198,7 +195,7 @@ class ComicInput(InputFormatPlugin): mi = MetaInformation(os.path.basename(stream.name).rpartition('.')[0], [_('Unknown')]) - opf = OPFCreator(getcwd(), mi) + opf = OPFCreator(os.getcwd(), mi) entries = [] def href(x): diff --git a/src/calibre/ebooks/conversion/plugins/djvu_input.py b/src/calibre/ebooks/conversion/plugins/djvu_input.py index ee28db18cc..9d2d5c6b97 100644 --- a/src/calibre/ebooks/conversion/plugins/djvu_input.py +++ b/src/calibre/ebooks/conversion/plugins/djvu_input.py @@ -9,7 +9,6 @@ import os from io import BytesIO from calibre.customize.conversion import InputFormatPlugin -from polyglot.builtins import getcwd class DJVUInput(InputFormatPlugin): @@ -40,7 +39,7 @@ class DJVUInput(InputFormatPlugin): for opt in html_input.options: setattr(options, opt.option.name, opt.recommended_value) options.input_encoding = 'utf-8' - base = getcwd() + base = os.getcwd() htmlfile = os.path.join(base, 'index.html') c = 0 while os.path.exists(htmlfile): diff --git a/src/calibre/ebooks/conversion/plugins/epub_input.py b/src/calibre/ebooks/conversion/plugins/epub_input.py index 2e599e0002..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' @@ -8,7 +6,6 @@ import os, re, posixpath from itertools import cycle from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation -from polyglot.builtins import getcwd ADOBE_OBFUSCATION = 'http://ns.adobe.com/pdf/enc#RC' IDPF_OBFUSCATION = 'http://www.idpf.org/2008/embedding' @@ -246,7 +243,7 @@ class EPUBInput(InputFormatPlugin): path = attr(r, 'full-path') if not path: continue - path = os.path.join(getcwd(), *path.split('/')) + path = os.path.join(os.getcwd(), *path.split('/')) if os.path.exists(path): return path except Exception: @@ -260,7 +257,7 @@ class EPUBInput(InputFormatPlugin): from calibre.ebooks.metadata.opf2 import OPF try: zf = ZipFile(stream) - zf.extractall(getcwd()) + zf.extractall(os.getcwd()) except: log.exception('EPUB appears to be invalid ZIP file, trying a' ' more forgiving ZIP parser') @@ -280,7 +277,7 @@ class EPUBInput(InputFormatPlugin): if opf is None: raise ValueError('%s is not a valid EPUB file (could not find opf)'%path) - opf = os.path.relpath(opf, getcwd()) + opf = os.path.relpath(opf, os.getcwd()) parts = os.path.split(opf) opf = OPF(opf, os.path.dirname(os.path.abspath(opf))) @@ -405,7 +402,7 @@ class EPUBInput(InputFormatPlugin): with NamedTemporaryFile(suffix='.ncx', dir=os.path.dirname(nav_path), delete=False) as f: f.write(etree.tostring(ncx, encoding='utf-8')) - ncx_href = os.path.relpath(f.name, getcwd()).replace(os.sep, '/') + ncx_href = os.path.relpath(f.name, os.getcwd()).replace(os.sep, '/') ncx_id = opf.create_manifest_item(ncx_href, NCX_MIME, append=True).get('id') for spine in opf.root.xpath('//*[local-name()="spine"]'): spine.set('toc', ncx_id) diff --git a/src/calibre/ebooks/conversion/plugins/epub_output.py b/src/calibre/ebooks/conversion/plugins/epub_output.py index ac107e32e3..aef9448b72 100644 --- a/src/calibre/ebooks/conversion/plugins/epub_output.py +++ b/src/calibre/ebooks/conversion/plugins/epub_output.py @@ -12,7 +12,7 @@ from calibre.customize.conversion import (OutputFormatPlugin, OptionRecommendation) from calibre.ptempfile import TemporaryDirectory from calibre import CurrentDir -from polyglot.builtins import unicode_type, filter, map, zip, range, as_bytes +from polyglot.builtins import as_bytes block_level_tags = ( 'address', @@ -225,15 +225,15 @@ class EPUBOutput(OutputFormatPlugin): identifiers = oeb.metadata['identifier'] uuid = None for x in identifiers: - if x.get(OPF('scheme'), None).lower() == 'uuid' or unicode_type(x).startswith('urn:uuid:'): - uuid = unicode_type(x).split(':')[-1] + if x.get(OPF('scheme'), None).lower() == 'uuid' or str(x).startswith('urn:uuid:'): + uuid = str(x).split(':')[-1] break encrypted_fonts = getattr(input_plugin, 'encrypted_fonts', []) if uuid is None: self.log.warn('No UUID identifier found') from uuid import uuid4 - uuid = unicode_type(uuid4()) + uuid = str(uuid4()) oeb.metadata.add('identifier', uuid, scheme='uuid', id=uuid) if encrypted_fonts and not uuid.startswith('urn:uuid:'): @@ -241,7 +241,7 @@ class EPUBOutput(OutputFormatPlugin): # for some absurd reason, or it will throw a hissy fit and refuse # to use the obfuscated fonts. for x in identifiers: - if unicode_type(x) == uuid: + if str(x) == uuid: x.content = 'urn:uuid:'+uuid with TemporaryDirectory('_epub_output') as tdir: @@ -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): # {{{ @@ -336,7 +336,7 @@ class EPUBOutput(OutputFormatPlugin): f.write(bytes(bytearray(data[i] ^ key[i%16] for i in range(1024)))) else: self.log.warn('Font', path, 'is invalid, ignoring') - if not isinstance(uri, unicode_type): + if not isinstance(uri, str): uri = uri.decode('utf-8') fonts.append(''' diff --git a/src/calibre/ebooks/conversion/plugins/fb2_input.py b/src/calibre/ebooks/conversion/plugins/fb2_input.py index 76d7f62633..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 ' """ @@ -9,7 +7,7 @@ import os, re from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation from calibre import guess_type -from polyglot.builtins import iteritems, getcwd +from polyglot.builtins import iteritems FB2NS = 'http://www.gribuser.ru/xml/fictionbook/2.0' FB21NS = 'http://www.gribuser.ru/xml/fictionbook/2.1' @@ -145,15 +143,15 @@ class FB2Input(InputFormatPlugin): cpath = os.path.abspath(href) break - opf = OPFCreator(getcwd(), mi) - entries = [(f2, guess_type(f2)[0]) for f2 in os.listdir(u'.')] + opf = OPFCreator(os.getcwd(), mi) + entries = [(f2, guess_type(f2)[0]) for f2 in os.listdir('.')] opf.create_manifest(entries) opf.create_spine(['index.xhtml']) if cpath: opf.guide.set_cover(cpath) with open('metadata.opf', 'wb') as f: opf.render(f) - return os.path.join(getcwd(), 'metadata.opf') + return os.path.join(os.getcwd(), 'metadata.opf') def extract_embedded_content(self, doc): from calibre.ebooks.fb2 import base64_decode diff --git a/src/calibre/ebooks/conversion/plugins/html_input.py b/src/calibre/ebooks/conversion/plugins/html_input.py index 30d1bf6b3c..a75809e120 100644 --- a/src/calibre/ebooks/conversion/plugins/html_input.py +++ b/src/calibre/ebooks/conversion/plugins/html_input.py @@ -17,7 +17,7 @@ from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation from calibre.utils.filenames import ascii_filename from calibre.utils.imghdr import what from calibre.utils.localization import get_lang -from polyglot.builtins import as_unicode, getcwd, unicode_type, zip +from polyglot.builtins import as_unicode def sanitize_file_name(x): @@ -70,7 +70,7 @@ class HTMLInput(InputFormatPlugin): def convert(self, stream, opts, file_ext, log, accelerators): self._is_case_sensitive = None - basedir = getcwd() + basedir = os.getcwd() self.opts = opts fname = None @@ -144,7 +144,7 @@ class HTMLInput(InputFormatPlugin): if not metadata.title: oeb.logger.warn('Title not specified') metadata.add('title', self.oeb.translate(__('Unknown'))) - bookid = unicode_type(uuid.uuid4()) + bookid = str(uuid.uuid4()) metadata.add('identifier', bookid, id='uuid_id', scheme='uuid') for ident in metadata.identifier: if 'id' in ident.attrib: @@ -228,19 +228,19 @@ class HTMLInput(InputFormatPlugin): continue toc.add(title, item.href) - oeb.container = DirContainer(getcwd(), oeb.log, ignore_opf=True) + oeb.container = DirContainer(os.getcwd(), oeb.log, ignore_opf=True) return oeb def link_to_local_path(self, link_, base=None): from calibre.ebooks.html.input import Link - if not isinstance(link_, unicode_type): + if not isinstance(link_, str): try: link_ = link_.decode('utf-8', 'error') except: self.log.warn('Failed to decode link %r. Ignoring'%link_) return None, None try: - l = Link(link_, base if base else getcwd()) + l = Link(link_, base if base else os.getcwd()) except: self.log.exception('Failed to process link: %r'%link_) return None, None @@ -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: @@ -298,7 +298,7 @@ class HTMLInput(InputFormatPlugin): # bhref refers to an already existing file. The read() method of # DirContainer will call unquote on it before trying to read the # file, therefore we quote it here. - if isinstance(bhref, unicode_type): + if isinstance(bhref, str): bhref = bhref.encode('utf-8') item.html_input_href = as_unicode(quote(bhref)) if is_stylesheet: diff --git a/src/calibre/ebooks/conversion/plugins/html_output.py b/src/calibre/ebooks/conversion/plugins/html_output.py index 9323d3c65e..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' @@ -10,7 +8,6 @@ from os.path import dirname, abspath, relpath as _relpath, exists, basename from calibre.customize.conversion import OutputFormatPlugin, OptionRecommendation from calibre import CurrentDir from calibre.ptempfile import PersistentTemporaryDirectory -from polyglot.builtins import unicode_type def relpath(*args): @@ -140,7 +137,7 @@ class HTMLOutput(OutputFormatPlugin): toc=html_toc, meta=meta, nextLink=nextLink, tocUrl=tocUrl, cssLink=cssLink, firstContentPageLink=nextLink) - if isinstance(t, unicode_type): + if isinstance(t, str): t = t.encode('utf-8') f.write(t) diff --git a/src/calibre/ebooks/conversion/plugins/htmlz_input.py b/src/calibre/ebooks/conversion/plugins/htmlz_input.py index 7ad449a584..c67fcbb153 100644 --- a/src/calibre/ebooks/conversion/plugins/htmlz_input.py +++ b/src/calibre/ebooks/conversion/plugins/htmlz_input.py @@ -9,7 +9,6 @@ import os from calibre import guess_type from calibre.customize.conversion import InputFormatPlugin -from polyglot.builtins import getcwd class HTMLZInput(InputFormatPlugin): @@ -27,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. @@ -36,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,12 +85,12 @@ class HTMLZInput(InputFormatPlugin): for opt in html_input.options: setattr(options, opt.option.name, opt.recommended_value) options.input_encoding = 'utf-8' - base = getcwd() - htmlfile = os.path.join(base, u'index.html') + base = os.getcwd() + 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 @@ -113,16 +112,16 @@ 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: - opf = OPF(opf, basedir=getcwd()) + opf = OPF(opf, basedir=os.getcwd()) cover_path = opf.raster_cover or opf.cover # Set the cover. if cover_path: cdata = None - with open(os.path.join(getcwd(), cover_path), 'rb') as cf: + with open(os.path.join(os.getcwd(), cover_path), 'rb') as cf: cdata = cf.read() cover_name = os.path.basename(cover_path) id, href = oeb.manifest.generate('cover', cover_name) diff --git a/src/calibre/ebooks/conversion/plugins/htmlz_output.py b/src/calibre/ebooks/conversion/plugins/htmlz_output.py index 0f5d9b5333..c206062ec4 100644 --- a/src/calibre/ebooks/conversion/plugins/htmlz_output.py +++ b/src/calibre/ebooks/conversion/plugins/htmlz_output.py @@ -11,7 +11,6 @@ import os from calibre.customize.conversion import OutputFormatPlugin, \ OptionRecommendation from calibre.ptempfile import TemporaryDirectory -from polyglot.builtins import unicode_type class HTMLZOutput(OutputFormatPlugin): @@ -73,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(unicode_type(oeb_book.metadata.title[0])),))[0] - with open(os.path.join(tdir, fname+u'.html'), 'wb') as tf: - if isinstance(html, unicode_type): + fname = shorten_components_to(100, (ascii_filename(str(oeb_book.metadata.title[0])),))[0] + 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) @@ -115,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) @@ -124,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/lrf_output.py b/src/calibre/ebooks/conversion/plugins/lrf_output.py index 2a13288296..718db0a55a 100644 --- a/src/calibre/ebooks/conversion/plugins/lrf_output.py +++ b/src/calibre/ebooks/conversion/plugins/lrf_output.py @@ -10,7 +10,6 @@ import sys, os from calibre.customize.conversion import OutputFormatPlugin from calibre.customize.conversion import OptionRecommendation -from polyglot.builtins import unicode_type class LRFOptions: @@ -18,7 +17,7 @@ class LRFOptions: def __init__(self, output, opts, oeb): def f2s(f): try: - return unicode_type(f[0]) + return str(f[0]) except: return '' m = oeb.metadata @@ -32,13 +31,13 @@ class LRFOptions: self.title_sort = self.author_sort = '' for x in m.creator: if x.role == 'aut': - self.author = unicode_type(x) - fa = unicode_type(getattr(x, 'file_as', '')) + self.author = str(x) + fa = str(getattr(x, 'file_as', '')) if fa: self.author_sort = fa for x in m.title: - if unicode_type(x.file_as): - self.title_sort = unicode_type(x.file_as) + if str(x.file_as): + self.title_sort = str(x.file_as) self.freetext = f2s(m.description) self.category = f2s(m.subject) self.cover = None diff --git a/src/calibre/ebooks/conversion/plugins/mobi_input.py b/src/calibre/ebooks/conversion/plugins/mobi_input.py index 64d71c8a1a..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' @@ -7,7 +5,6 @@ __docformat__ = 'restructuredtext en' import os from calibre.customize.conversion import InputFormatPlugin -from polyglot.builtins import unicode_type class MOBIInput(InputFormatPlugin): @@ -51,7 +48,7 @@ class MOBIInput(InputFormatPlugin): raw = parse_cache.pop('calibre_raw_mobi_markup', False) if raw: - if isinstance(raw, unicode_type): + if isinstance(raw, str): raw = raw.encode('utf-8') with lopen('debug-raw.html', 'wb') as f: f.write(raw) diff --git a/src/calibre/ebooks/conversion/plugins/mobi_output.py b/src/calibre/ebooks/conversion/plugins/mobi_output.py index e0501ca639..425b992fcd 100644 --- a/src/calibre/ebooks/conversion/plugins/mobi_output.py +++ b/src/calibre/ebooks/conversion/plugins/mobi_output.py @@ -8,7 +8,6 @@ __docformat__ = 'restructuredtext en' from calibre.customize.conversion import (OutputFormatPlugin, OptionRecommendation) -from polyglot.builtins import unicode_type def remove_html_cover(oeb, log): @@ -122,7 +121,7 @@ class MOBIOutput(OutputFormatPlugin): if not found: from calibre.ebooks import generate_masthead self.oeb.log.debug('No masthead found in manifest, generating default mastheadImage...') - raw = generate_masthead(unicode_type(self.oeb.metadata['title'][0])) + raw = generate_masthead(str(self.oeb.metadata['title'][0])) id, href = self.oeb.manifest.generate('masthead', 'masthead') self.oeb.manifest.add(id, href, 'image/gif', data=raw) self.oeb.guide.add('masthead', 'Masthead Image', href) @@ -166,7 +165,7 @@ class MOBIOutput(OutputFormatPlugin): sec.nodes.remove(a) root = TOC(klass='periodical', href=self.oeb.spine[0].href, - title=unicode_type(self.oeb.metadata.title[0])) + title=str(self.oeb.metadata.title[0])) for s in sections: if articles[id(s)]: 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/pdb_input.py b/src/calibre/ebooks/conversion/plugins/pdb_input.py index ddc5af4295..3eafb90a66 100644 --- a/src/calibre/ebooks/conversion/plugins/pdb_input.py +++ b/src/calibre/ebooks/conversion/plugins/pdb_input.py @@ -5,8 +5,9 @@ __license__ = 'GPL v3' __copyright__ = '2009, John Schember ' __docformat__ = 'restructuredtext en' +import os + from calibre.customize.conversion import InputFormatPlugin -from polyglot.builtins import getcwd class PDBInput(InputFormatPlugin): @@ -32,6 +33,6 @@ class PDBInput(InputFormatPlugin): log.debug('Detected ebook format as: %s with identity: %s' % (IDENTITY_TO_NAME[header.ident], header.ident)) reader = Reader(header, stream, log, options) - opf = reader.extract_content(getcwd()) + opf = reader.extract_content(os.getcwd()) return opf diff --git a/src/calibre/ebooks/conversion/plugins/pdf_input.py b/src/calibre/ebooks/conversion/plugins/pdf_input.py index cddf73d3f6..72f76e18dc 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_input.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_input.py @@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en' import os from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation -from polyglot.builtins import as_bytes, getcwd +from polyglot.builtins import as_bytes class PDFInput(InputFormatPlugin): @@ -35,11 +35,11 @@ class PDFInput(InputFormatPlugin): from calibre.utils.cleantext import clean_ascii_chars from calibre.ebooks.pdf.reflow import PDFDocument - pdftohtml(getcwd(), stream.name, self.opts.no_images, as_xml=True) + pdftohtml(os.getcwd(), stream.name, self.opts.no_images, as_xml=True) with lopen('index.xml', 'rb') as f: xml = clean_ascii_chars(f.read()) PDFDocument(xml, self.opts, self.log) - return os.path.join(getcwd(), 'metadata.opf') + return os.path.join(os.getcwd(), 'metadata.opf') def convert(self, stream, options, file_ext, log, accelerators): @@ -51,16 +51,16 @@ class PDFInput(InputFormatPlugin): self.opts, self.log = options, log if options.new_pdf_engine: return self.convert_new(stream, accelerators) - pdftohtml(getcwd(), stream.name, options.no_images) + pdftohtml(os.getcwd(), stream.name, options.no_images) from calibre.ebooks.metadata.meta import get_metadata log.debug('Retrieving document metadata...') mi = get_metadata(stream, 'pdf') - opf = OPFCreator(getcwd(), mi) + opf = OPFCreator(os.getcwd(), mi) manifest = [('index.html', None)] - images = os.listdir(getcwd()) + images = os.listdir(os.getcwd()) images.remove('index.html') for i in images: manifest.append((i, None)) @@ -79,4 +79,4 @@ class PDFInput(InputFormatPlugin): f.seek(0) f.write(raw) - return os.path.join(getcwd(), 'metadata.opf') + return os.path.join(os.getcwd(), 'metadata.opf') diff --git a/src/calibre/ebooks/conversion/plugins/pdf_output.py b/src/calibre/ebooks/conversion/plugins/pdf_output.py index 66ff9d6060..f9fe1b96e5 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_output.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_output.py @@ -14,7 +14,7 @@ import glob, os from calibre.customize.conversion import (OutputFormatPlugin, OptionRecommendation) from calibre.ptempfile import TemporaryDirectory -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems UNITS = ('millimeter', 'centimeter', 'point', 'inch' , 'pica' , 'didot', 'cicero', 'devicepixel') @@ -193,8 +193,8 @@ class PDFOutput(OutputFormatPlugin): def get_cover_data(self): oeb = self.oeb - if (oeb.metadata.cover and unicode_type(oeb.metadata.cover[0]) in oeb.manifest.ids): - cover_id = unicode_type(oeb.metadata.cover[0]) + if (oeb.metadata.cover and str(oeb.metadata.cover[0]) in oeb.manifest.ids): + cover_id = str(oeb.metadata.cover[0]) item = oeb.manifest.ids[cover_id] if isinstance(item.data, bytes): self.cover_data = item.data diff --git a/src/calibre/ebooks/conversion/plugins/pml_input.py b/src/calibre/ebooks/conversion/plugins/pml_input.py index 02595af9c1..2d7ab50f66 100644 --- a/src/calibre/ebooks/conversion/plugins/pml_input.py +++ b/src/calibre/ebooks/conversion/plugins/pml_input.py @@ -11,7 +11,6 @@ import shutil from calibre.customize.conversion import InputFormatPlugin from calibre.ptempfile import TemporaryDirectory -from polyglot.builtins import getcwd class PMLInput(InputFormatPlugin): @@ -76,10 +75,10 @@ class PMLInput(InputFormatPlugin): if not imgs: imgs = glob.glob(os.path.join(os.path.join(tdir, 'images'), '*.png')) if imgs: - os.makedirs(os.path.join(getcwd(), 'images')) + os.makedirs(os.path.join(os.getcwd(), 'images')) for img in imgs: pimg_name = os.path.basename(img) - pimg_path = os.path.join(getcwd(), 'images', pimg_name) + pimg_path = os.path.join(os.getcwd(), 'images', pimg_name) images.append('images/' + pimg_name) @@ -107,7 +106,7 @@ class PMLInput(InputFormatPlugin): pmls = glob.glob(os.path.join(tdir, '*.pml')) for pml in pmls: html_name = os.path.splitext(os.path.basename(pml))[0]+'.html' - html_path = os.path.join(getcwd(), html_name) + html_path = os.path.join(os.getcwd(), html_name) pages.append(html_name) log.debug('Processing PML item %s...' % pml) @@ -133,7 +132,7 @@ class PMLInput(InputFormatPlugin): mi = get_metadata(stream, 'pml') if 'images/cover.png' in images: mi.cover = 'images/cover.png' - opf = OPFCreator(getcwd(), mi) + opf = OPFCreator(os.getcwd(), mi) log.debug('Generating manifest...') opf.create_manifest(manifest_items) opf.create_spine(pages) @@ -142,7 +141,7 @@ class PMLInput(InputFormatPlugin): with lopen('toc.ncx', 'wb') as tocfile: opf.render(opffile, tocfile, 'toc.ncx') - return os.path.join(getcwd(), 'metadata.opf') + return os.path.join(os.getcwd(), 'metadata.opf') def postprocess_book(self, oeb, opts, log): from calibre.ebooks.oeb.base import XHTML, barename diff --git a/src/calibre/ebooks/conversion/plugins/pml_output.py b/src/calibre/ebooks/conversion/plugins/pml_output.py index 4daf944d75..5d8619af8a 100644 --- a/src/calibre/ebooks/conversion/plugins/pml_output.py +++ b/src/calibre/ebooks/conversion/plugins/pml_output.py @@ -10,7 +10,6 @@ import os, io from calibre.customize.conversion import (OutputFormatPlugin, OptionRecommendation) from calibre.ptempfile import TemporaryDirectory -from polyglot.builtins import unicode_type class PMLOutput(OutputFormatPlugin): @@ -42,7 +41,7 @@ class PMLOutput(OutputFormatPlugin): with TemporaryDirectory('_pmlz_output') as tdir: pmlmlizer = PMLMLizer(log) - pml = unicode_type(pmlmlizer.extract_content(oeb_book, opts)) + pml = str(pmlmlizer.extract_content(oeb_book, opts)) with lopen(os.path.join(tdir, 'index.pml'), 'wb') as out: out.write(pml.encode(opts.pml_output_encoding, 'replace')) diff --git a/src/calibre/ebooks/conversion/plugins/rb_input.py b/src/calibre/ebooks/conversion/plugins/rb_input.py index 434f9e1ef7..82c0804811 100644 --- a/src/calibre/ebooks/conversion/plugins/rb_input.py +++ b/src/calibre/ebooks/conversion/plugins/rb_input.py @@ -6,8 +6,9 @@ __copyright__ = '2009, John Schember ' __docformat__ = 'restructuredtext en' +import os + from calibre.customize.conversion import InputFormatPlugin -from polyglot.builtins import getcwd class RBInput(InputFormatPlugin): @@ -23,6 +24,6 @@ class RBInput(InputFormatPlugin): from calibre.ebooks.rb.reader import Reader reader = Reader(stream, log, options.input_encoding) - opf = reader.extract_content(getcwd()) + opf = reader.extract_content(os.getcwd()) return opf diff --git a/src/calibre/ebooks/conversion/plugins/recipe_input.py b/src/calibre/ebooks/conversion/plugins/recipe_input.py index 43cca8b130..104a842c08 100644 --- a/src/calibre/ebooks/conversion/plugins/recipe_input.py +++ b/src/calibre/ebooks/conversion/plugins/recipe_input.py @@ -11,7 +11,6 @@ import os from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation from calibre.constants import numeric_version from calibre import walk -from polyglot.builtins import unicode_type class RecipeDisabled(Exception): @@ -164,6 +163,6 @@ class RecipeInput(InputFormatPlugin): def save_download(self, zf): raw = self.recipe_source - if isinstance(raw, unicode_type): + if isinstance(raw, str): raw = raw.encode('utf-8') zf.writestr('download.recipe', raw) diff --git a/src/calibre/ebooks/conversion/plugins/rtf_input.py b/src/calibre/ebooks/conversion/plugins/rtf_input.py index c35085328b..e4e15b2a80 100644 --- a/src/calibre/ebooks/conversion/plugins/rtf_input.py +++ b/src/calibre/ebooks/conversion/plugins/rtf_input.py @@ -1,11 +1,10 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' import os, glob, re, textwrap from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation -from polyglot.builtins import iteritems, filter, getcwd, as_bytes +from polyglot.builtins import iteritems, as_bytes border_style_map = { 'single' : 'solid', @@ -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:] @@ -304,11 +303,11 @@ class RTFInput(InputFormatPlugin): mi.title = _('Unknown') if not mi.authors: mi.authors = [_('Unknown')] - opf = OPFCreator(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 = OPFCreator(os.getcwd(), mi) + 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/conversion/plugins/snb_input.py b/src/calibre/ebooks/conversion/plugins/snb_input.py index a349862c1d..66ede4cea5 100644 --- a/src/calibre/ebooks/conversion/plugins/snb_input.py +++ b/src/calibre/ebooks/conversion/plugins/snb_input.py @@ -10,7 +10,6 @@ import os from calibre.customize.conversion import InputFormatPlugin from calibre.ptempfile import TemporaryDirectory from calibre.utils.filenames import ascii_filename -from polyglot.builtins import unicode_type HTML_TEMPLATE = '%s\n%s\n' @@ -75,7 +74,7 @@ class SNBInput(InputFormatPlugin): if d['cover'] != '': oeb.guide.add('cover', 'Cover', d['cover']) - bookid = unicode_type(uuid.uuid4()) + bookid = str(uuid.uuid4()) oeb.metadata.add('identifier', bookid, id='uuid_id', scheme='uuid') for ident in oeb.metadata.identifier: if 'id' in ident.attrib: diff --git a/src/calibre/ebooks/conversion/plugins/snb_output.py b/src/calibre/ebooks/conversion/plugins/snb_output.py index e8a75d96e8..0c89fd10f3 100644 --- a/src/calibre/ebooks/conversion/plugins/snb_output.py +++ b/src/calibre/ebooks/conversion/plugins/snb_output.py @@ -10,7 +10,6 @@ import os from calibre.customize.conversion import OutputFormatPlugin, OptionRecommendation from calibre.ptempfile import TemporaryDirectory from calibre.constants import __appname__, __version__ -from polyglot.builtins import unicode_type class SNBOutput(OutputFormatPlugin): @@ -75,20 +74,20 @@ class SNBOutput(OutputFormatPlugin): # Process Meta data meta = oeb_book.metadata if meta.title: - title = unicode_type(meta.title[0]) + title = str(meta.title[0]) else: title = '' - authors = [unicode_type(x) for x in meta.creator if x.role == 'aut'] + authors = [str(x) for x in meta.creator if x.role == 'aut'] if meta.publisher: - publishers = unicode_type(meta.publisher[0]) + publishers = str(meta.publisher[0]) else: publishers = '' if meta.language: - lang = unicode_type(meta.language[0]).upper() + lang = str(meta.language[0]).upper() else: lang = '' if meta.description: - abstract = unicode_type(meta.description[0]) + abstract = str(meta.description[0]) else: abstract = '' diff --git a/src/calibre/ebooks/conversion/plugins/txt_input.py b/src/calibre/ebooks/conversion/plugins/txt_input.py index a149e982ef..1636839281 100644 --- a/src/calibre/ebooks/conversion/plugins/txt_input.py +++ b/src/calibre/ebooks/conversion/plugins/txt_input.py @@ -9,7 +9,6 @@ import os from calibre import _ent_pat, walk, xml_entity_to_unicode from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation -from polyglot.builtins import getcwd MD_EXTENSIONS = { 'abbr': _('Abbreviations'), @@ -143,7 +142,7 @@ class TXTInput(InputFormatPlugin): txt = b'' log.debug('Reading text from file...') length = 0 - base_dir = self.output_dir = getcwd() + base_dir = self.output_dir = os.getcwd() # Extract content from zip archive. if file_ext == 'txtz': diff --git a/src/calibre/ebooks/conversion/plumber.py b/src/calibre/ebooks/conversion/plumber.py index 37957b4b8a..8de61ce6a6 100644 --- a/src/calibre/ebooks/conversion/plumber.py +++ b/src/calibre/ebooks/conversion/plumber.py @@ -20,7 +20,7 @@ from calibre.utils.zipfile import ZipFile from calibre import (extract, walk, isbytestring, filesystem_encoding, get_types_map) from calibre.constants import __version__ -from polyglot.builtins import unicode_type, string_or_bytes, map +from polyglot.builtins import string_or_bytes DEBUG_README=b''' This debug folder contains snapshots of the e-book as it passes through the @@ -794,7 +794,7 @@ OptionRecommendation(name='search_replace', def unarchive(self, path, tdir): extract(path, tdir) files = list(walk(tdir)) - files = [f if isinstance(f, unicode_type) else f.decode(filesystem_encoding) + files = [f if isinstance(f, str) else f.decode(filesystem_encoding) for f in files] from calibre.customize.ui import available_input_formats fmts = set(available_input_formats()) @@ -847,7 +847,7 @@ OptionRecommendation(name='search_replace', rec = self.get_option_by_name(name) help = getattr(rec, 'help', None) if help is not None: - return help.replace('%default', unicode_type(rec.recommended_value)) + return help.replace('%default', str(rec.recommended_value)) def get_all_help(self): ans = {} @@ -915,7 +915,7 @@ OptionRecommendation(name='search_replace', try: val = parse_date(val, assume_utc=x=='timestamp') except: - self.log.exception(_('Failed to parse date/time') + ' ' + unicode_type(val)) + self.log.exception(_('Failed to parse date/time') + ' ' + str(val)) continue setattr(mi, x, val) diff --git a/src/calibre/ebooks/conversion/preprocess.py b/src/calibre/ebooks/conversion/preprocess.py index 56887ff02d..dd1322c8a0 100644 --- a/src/calibre/ebooks/conversion/preprocess.py +++ b/src/calibre/ebooks/conversion/preprocess.py @@ -10,7 +10,6 @@ import functools, re, json from math import ceil from calibre import entity_to_unicode, as_unicode -from polyglot.builtins import unicode_type, range XMLDECL_RE = re.compile(r'^\s*<[?]xml.*?[?]>') SVG_NS = 'http://www.w3.org/2000/svg' @@ -75,8 +74,8 @@ def smarten_punctuation(html, log=None): from calibre.ebooks.conversion.utils import HeuristicProcessor preprocessor = HeuristicProcessor(log=log) from uuid import uuid4 - start = 'calibre-smartypants-'+unicode_type(uuid4()) - stop = 'calibre-smartypants-'+unicode_type(uuid4()) + start = 'calibre-smartypants-'+str(uuid4()) + stop = 'calibre-smartypants-'+str(uuid4()) html = html.replace('', stop) html = preprocessor.fix_nbsp_indents(html) @@ -152,20 +151,20 @@ class DocAnalysis: maxLineLength=1900 # Discard larger than this to stay in range buckets=20 # Each line is divided into a bucket based on length - # print("there are "+unicode_type(len(lines))+" lines") + # print("there are "+str(len(lines))+" lines") # max = 0 # for line in self.lines: # l = len(line) # if l > max: # max = l - # print("max line found is "+unicode_type(max)) + # print("max line found is "+str(max)) # Build the line length histogram hRaw = [0 for i in range(0,buckets)] for line in self.lines: l = len(line) if l > minLineLength and l < maxLineLength: l = int(l // 100) - # print("adding "+unicode_type(l)) + # print("adding "+str(l)) hRaw[l]+=1 # Normalize the histogram into percents @@ -174,8 +173,8 @@ class DocAnalysis: h = [float(count)/totalLines for count in hRaw] else: h = [] - # print("\nhRaw histogram lengths are: "+unicode_type(hRaw)) - # print(" percents are: "+unicode_type(h)+"\n") + # print("\nhRaw histogram lengths are: "+str(hRaw)) + # print(" percents are: "+str(h)+"\n") # Find the biggest bucket maxValue = 0 @@ -187,7 +186,7 @@ class DocAnalysis: # print("Line lengths are too variable. Not unwrapping.") return False else: - # print(unicode_type(maxValue)+" of the lines were in one bucket") + # print(str(maxValue)+" of the lines were in one bucket") return True @@ -223,8 +222,8 @@ class Dehyphenator: wraptags = match.group('wraptags') except: wraptags = '' - hyphenated = unicode_type(firsthalf) + "-" + unicode_type(secondhalf) - dehyphenated = unicode_type(firsthalf) + unicode_type(secondhalf) + hyphenated = str(firsthalf) + "-" + str(secondhalf) + dehyphenated = str(firsthalf) + str(secondhalf) if self.suffixes.match(secondhalf) is None: lookupword = self.removesuffixes.sub('', dehyphenated) else: @@ -330,7 +329,7 @@ class CSSPreProcessor: # are commented lines before the first @import or @charset rule. Since # the conversion will remove all stylesheets anyway, we don't lose # anything - data = re.sub(unicode_type(r'/\*.*?\*/'), '', data, flags=re.DOTALL) + data = re.sub(r'/\*.*?\*/', '', data, flags=re.DOTALL) ans, namespaced = [], False for line in data.splitlines(): @@ -538,7 +537,7 @@ class HTMLPreProcessor: docanalysis = DocAnalysis('pdf', html) length = docanalysis.line_length(getattr(self.extra_opts, 'unwrap_factor')) if length: - # print("The pdf line length returned is " + unicode_type(length)) + # print("The pdf line length returned is " + str(length)) # unwrap em/en dashes end_rules.append((re.compile( r'(?<=.{%i}[–—])\s*

\s*(?=[\[a-z\d])' % length), lambda match: '')) diff --git a/src/calibre/ebooks/conversion/utils.py b/src/calibre/ebooks/conversion/utils.py index fb49bde3f4..2ec154a951 100644 --- a/src/calibre/ebooks/conversion/utils.py +++ b/src/calibre/ebooks/conversion/utils.py @@ -11,7 +11,6 @@ from math import ceil from calibre.ebooks.conversion.preprocess import DocAnalysis, Dehyphenator from calibre.utils.logging import default_log from calibre.utils.wordcount import get_wordcount_obj -from polyglot.builtins import unicode_type class HeuristicProcessor: @@ -54,8 +53,8 @@ class HeuristicProcessor: title = match.group('title') if not title: self.html_preprocess_sections = self.html_preprocess_sections + 1 - self.log.debug("marked " + unicode_type(self.html_preprocess_sections) + - " chapters. - " + unicode_type(chap)) + self.log.debug("marked " + str(self.html_preprocess_sections) + + " chapters. - " + str(chap)) return '

'+chap+'

\n' else: delete_whitespace = re.compile('^\\s*(?P.*?)\\s*$') @@ -63,16 +62,16 @@ class HeuristicProcessor: txt_chap = delete_quotes.sub('', delete_whitespace.sub('\\g', html2text(chap))) txt_title = delete_quotes.sub('', delete_whitespace.sub('\\g', html2text(title))) self.html_preprocess_sections = self.html_preprocess_sections + 1 - self.log.debug("marked " + unicode_type(self.html_preprocess_sections) + - " chapters & titles. - " + unicode_type(chap) + ", " + unicode_type(title)) + self.log.debug("marked " + str(self.html_preprocess_sections) + + " chapters & titles. - " + str(chap) + ", " + str(title)) return '

'+chap+'

\n

'+title+'

\n' def chapter_break(self, match): chap = match.group('section') styles = match.group('styles') self.html_preprocess_sections = self.html_preprocess_sections + 1 - self.log.debug("marked " + unicode_type(self.html_preprocess_sections) + - " section markers based on punctuation. - " + unicode_type(chap)) + self.log.debug("marked " + str(self.html_preprocess_sections) + + " section markers based on punctuation. - " + str(chap)) return '<'+styles+' style="page-break-before:always">'+chap def analyze_title_matches(self, match): @@ -115,8 +114,8 @@ class HeuristicProcessor: line_end = line_end_ere.findall(raw) tot_htm_ends = len(htm_end) tot_ln_fds = len(line_end) - # self.log.debug("There are " + unicode_type(tot_ln_fds) + " total Line feeds, and " + - # unicode_type(tot_htm_ends) + " marked up endings") + # self.log.debug("There are " + str(tot_ln_fds) + " total Line feeds, and " + + # str(tot_htm_ends) + " marked up endings") if percent > 1: percent = 1 @@ -124,7 +123,7 @@ class HeuristicProcessor: percent = 0 min_lns = tot_ln_fds * percent - # self.log.debug("There must be fewer than " + unicode_type(min_lns) + " unmarked lines to add markup") + # self.log.debug("There must be fewer than " + str(min_lns) + " unmarked lines to add markup") return min_lns > tot_htm_ends def dump(self, raw, where): @@ -161,17 +160,17 @@ class HeuristicProcessor: ] ITALICIZE_STYLE_PATS = [ - unicode_type(r'(?msu)(?<=[\s>"“\'‘])_\*/(?P[^\*_]+)/\*_'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])~~(?P[^~]+)~~'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])_/(?P[^/_]+)/_'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])_\*(?P[^\*_]+)\*_'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])\*/(?P[^/\*]+)/\*'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])/:(?P[^:/]+):/'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])\|:(?P[^:\|]+):\|'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])\*(?P[^\*]+)\*'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])~(?P[^~]+)~'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])/(?P[^/\*><]+)/'), - unicode_type(r'(?msu)(?<=[\s>"“\'‘])_(?P[^_]+)_'), + r'(?msu)(?<=[\s>"“\'‘])_\*/(?P[^\*_]+)/\*_', + r'(?msu)(?<=[\s>"“\'‘])~~(?P[^~]+)~~', + r'(?msu)(?<=[\s>"“\'‘])_/(?P[^/_]+)/_', + r'(?msu)(?<=[\s>"“\'‘])_\*(?P[^\*_]+)\*_', + r'(?msu)(?<=[\s>"“\'‘])\*/(?P[^/\*]+)/\*', + r'(?msu)(?<=[\s>"“\'‘])/:(?P[^:/]+):/', + r'(?msu)(?<=[\s>"“\'‘])\|:(?P[^:\|]+):\|', + r'(?msu)(?<=[\s>"“\'‘])\*(?P[^\*]+)\*', + r'(?msu)(?<=[\s>"“\'‘])~(?P[^~]+)~', + r'(?msu)(?<=[\s>"“\'‘])/(?P[^/\*><]+)/', + r'(?msu)(?<=[\s>"“\'‘])_(?P[^_]+)_', ] for word in ITALICIZE_WORDS: @@ -181,10 +180,10 @@ class HeuristicProcessor: search_text = re.sub(r'<[^>]*>', '', search_text) for pat in ITALICIZE_STYLE_PATS: for match in re.finditer(pat, search_text): - ital_string = unicode_type(match.group('words')) - # self.log.debug("italicising "+unicode_type(match.group(0))+" with "+ital_string+"") + ital_string = str(match.group('words')) + # self.log.debug("italicising "+str(match.group(0))+" with "+ital_string+"") try: - html = re.sub(re.escape(unicode_type(match.group(0))), '%s' % ital_string, html) + html = re.sub(re.escape(str(match.group(0))), '%s' % ital_string, html) except OverflowError: # match.group(0) was too large to be compiled into a regex continue @@ -209,10 +208,10 @@ class HeuristicProcessor: if wordcount > 200000: typical_chapters = 15000. self.min_chapters = int(ceil(wordcount / typical_chapters)) - self.log.debug("minimum chapters required are: "+unicode_type(self.min_chapters)) + self.log.debug("minimum chapters required are: "+str(self.min_chapters)) heading = re.compile(']*>', re.IGNORECASE) self.html_preprocess_sections = len(heading.findall(html)) - self.log.debug("found " + unicode_type(self.html_preprocess_sections) + " pre-existing headings") + self.log.debug("found " + str(self.html_preprocess_sections) + " pre-existing headings") # Build the Regular Expressions in pieces init_lookahead = "(?=<(p|div))" @@ -302,7 +301,7 @@ class HeuristicProcessor: if n_lookahead_req: n_lookahead = re.sub("(ou|in|cha)", "lookahead_", full_chapter_line) if not analyze: - self.log.debug("Marked " + unicode_type(self.html_preprocess_sections) + " headings, " + log_message) + self.log.debug("Marked " + str(self.html_preprocess_sections) + " headings, " + log_message) chapter_marker = arg_ignorecase+init_lookahead+full_chapter_line+blank_lines+lp_n_lookahead_open+n_lookahead+lp_n_lookahead_close+ \ lp_opt_title_open+title_line_open+title_header_open+lp_title+title_header_close+title_line_close+lp_opt_title_close @@ -316,10 +315,10 @@ class HeuristicProcessor: title_req = True strict_title = False self.log.debug( - unicode_type(type_name)+" had "+unicode_type(hits)+ - " hits - "+unicode_type(self.chapters_no_title)+" chapters with no title, "+ - unicode_type(self.chapters_with_title)+" chapters with titles, "+ - unicode_type(float(self.chapters_with_title) / float(hits))+" percent. ") + str(type_name)+" had "+str(hits)+ + " hits - "+str(self.chapters_no_title)+" chapters with no title, "+ + str(self.chapters_with_title)+" chapters with titles, "+ + str(float(self.chapters_with_title) / float(hits))+" percent. ") if type_name == 'common': analysis_result.append([chapter_type, n_lookahead_req, strict_title, ignorecase, title_req, log_message, type_name]) elif self.min_chapters <= hits < max_chapters or self.min_chapters < 3 > hits: @@ -336,8 +335,8 @@ class HeuristicProcessor: words_per_chptr = wordcount if words_per_chptr > 0 and self.html_preprocess_sections > 0: words_per_chptr = wordcount // self.html_preprocess_sections - self.log.debug("Total wordcount is: "+ unicode_type(wordcount)+", Average words per section is: "+ - unicode_type(words_per_chptr)+", Marked up "+unicode_type(self.html_preprocess_sections)+" chapters") + self.log.debug("Total wordcount is: "+ str(wordcount)+", Average words per section is: "+ + str(words_per_chptr)+", Marked up "+str(self.html_preprocess_sections)+" chapters") return html def punctuation_unwrap(self, length, content, format): @@ -367,8 +366,8 @@ class HeuristicProcessor: # define the pieces of the regex # (?)?\\s*()?" blanklines = "\\s*(?P<(p|span|div)[^>]*>\\s*(<(p|span|div)[^>]*>\\s*\\s*)\\s*){0,3}\\s*" @@ -428,18 +427,18 @@ class HeuristicProcessor: return html def fix_nbsp_indents(self, html): - txtindent = re.compile(unicode_type(r'<(?Pp|div)(?P[^>]*)>\s*(?P(]*>\s*)+)?\s*(\u00a0){2,}'), re.IGNORECASE) + txtindent = re.compile(r'<(?Pp|div)(?P[^>]*)>\s*(?P(]*>\s*)+)?\s*(\u00a0){2,}', re.IGNORECASE) html = txtindent.sub(self.insert_indent, html) if self.found_indents > 1: - self.log.debug("replaced "+unicode_type(self.found_indents)+ " nbsp indents with inline styles") + self.log.debug("replaced "+str(self.found_indents)+ " nbsp indents with inline styles") return html def cleanup_markup(self, html): # remove remaining non-breaking spaces - html = re.sub(unicode_type(r'\u00a0'), ' ', html) + html = re.sub(r'\u00a0', ' ', html) # Get rid of various common microsoft specific tags which can cause issues later # Get rid of empty tags to simplify other processing - html = re.sub(unicode_type(r'\s*\s*'), ' ', html) + html = re.sub(r'\s*\s*', ' ', html) # Delete microsoft 'smart' tags html = re.sub('(?i)', '', html) # Re-open self closing paragraph tags @@ -479,8 +478,8 @@ class HeuristicProcessor: blanklines = self.blankreg.findall(html) lines = self.linereg.findall(html) if len(lines) > 1: - self.log.debug("There are " + unicode_type(len(blanklines)) + " blank lines. " + - unicode_type(float(len(blanklines)) / float(len(lines))) + " percent blank") + self.log.debug("There are " + str(len(blanklines)) + " blank lines. " + + str(float(len(blanklines)) / float(len(lines))) + " percent blank") if float(len(blanklines)) / float(len(lines)) > 0.40: return True @@ -502,11 +501,11 @@ class HeuristicProcessor: lines = float(len(self.single_blank.findall(to_merge))) - 1. em = base_em + (em_per_line * lines) if to_merge.find('whitespace'): - newline = self.any_multi_blank.sub('\n

', match.group(0)) + newline = self.any_multi_blank.sub('\n

', match.group(0)) else: - newline = self.any_multi_blank.sub('\n

', match.group(0)) + newline = self.any_multi_blank.sub('\n

', match.group(0)) return newline html = self.any_multi_blank.sub(merge_matches, html) @@ -530,9 +529,9 @@ class HeuristicProcessor: top_margin = '' bottom_margin = '' if initblanks is not None: - top_margin = 'margin-top:'+unicode_type(len(self.single_blank.findall(initblanks)))+'em;' + top_margin = 'margin-top:'+str(len(self.single_blank.findall(initblanks)))+'em;' if endblanks is not None: - bottom_margin = 'margin-bottom:'+unicode_type(len(self.single_blank.findall(endblanks)))+'em;' + bottom_margin = 'margin-bottom:'+str(len(self.single_blank.findall(endblanks)))+'em;' if initblanks is None and endblanks is None: return content @@ -609,7 +608,7 @@ class HeuristicProcessor: else: replacement_break = re.sub('(?i)(width=\\d+\\%?|width:\\s*\\d+(\\%|px|pt|em)?;?)', '', replacement_break) divpercent = (100 - width) // 2 - hr_open = re.sub('45', unicode_type(divpercent), hr_open) + hr_open = re.sub('45', str(divpercent), hr_open) scene_break = hr_open+replacement_break+'' else: scene_break = hr_open+'
' @@ -669,12 +668,12 @@ class HeuristicProcessor: else: styles = match.group('styles').split(';') is_paragraph = self.check_paragraph(content) - # print "styles for this line are: "+unicode_type(styles) + # print "styles for this line are: "+str(styles) split_styles = [] for style in styles: - # print "style is: "+unicode_type(style) + # print "style is: "+str(style) newstyle = style.split(':') - # print "newstyle is: "+unicode_type(newstyle) + # print "newstyle is: "+str(newstyle) split_styles.append(newstyle) styles = split_styles for style, setting in styles: @@ -685,7 +684,7 @@ class HeuristicProcessor: if 9 < setting < 14: text_indent = indented_text else: - text_indent = style+':'+unicode_type(setting)+'pt;' + text_indent = style+':'+str(setting)+'pt;' if style == 'padding': setting = re.sub('pt', '', setting).split(' ') if int(setting[1]) < 16 and int(setting[3]) < 16: @@ -706,23 +705,23 @@ class HeuristicProcessor: blockquote_open_loop = blockquote_open if debugabby: self.log.debug('\n\n******\n') - self.log.debug('padding top is: '+unicode_type(setting[0])) - self.log.debug('padding right is:' +unicode_type(setting[1])) - self.log.debug('padding bottom is: ' + unicode_type(setting[2])) - self.log.debug('padding left is: ' +unicode_type(setting[3])) + self.log.debug('padding top is: '+str(setting[0])) + self.log.debug('padding right is:' +str(setting[1])) + self.log.debug('padding bottom is: ' + str(setting[2])) + self.log.debug('padding left is: ' +str(setting[3])) - # print "text-align is: "+unicode_type(text_align) - # print "\n***\nline is:\n "+unicode_type(match.group(0))+'\n' + # print "text-align is: "+str(text_align) + # print "\n***\nline is:\n "+str(match.group(0))+'\n' if debugabby: - # print "this line is a paragraph = "+unicode_type(is_paragraph)+", previous line was "+unicode_type(self.previous_was_paragraph) + # print "this line is a paragraph = "+str(is_paragraph)+", previous line was "+str(self.previous_was_paragraph) self.log.debug("styles for this line were:", styles) self.log.debug('newline is:') self.log.debug(blockquote_open_loop+blockquote_close_loop+ paragraph_before+'

'+content+'

'+paragraph_after+'\n\n\n\n\n') - # print "is_paragraph is "+unicode_type(is_paragraph)+", previous_was_paragraph is "+unicode_type(self.previous_was_paragraph) + # print "is_paragraph is "+str(is_paragraph)+", previous_was_paragraph is "+str(self.previous_was_paragraph) self.previous_was_paragraph = is_paragraph - # print "previous_was_paragraph is now set to "+unicode_type(self.previous_was_paragraph)+"\n\n\n" + # print "previous_was_paragraph is now set to "+str(self.previous_was_paragraph)+"\n\n\n" return blockquote_open_loop+blockquote_close_loop+paragraph_before+'

'+content+'

'+paragraph_after html = abbyy_line.sub(convert_styles, html) @@ -805,12 +804,12 @@ class HeuristicProcessor: # more of the lines break in the same region of the document then unwrapping is required docanalysis = DocAnalysis(format, html) hardbreaks = docanalysis.line_histogram(.50) - self.log.debug("Hard line breaks check returned "+unicode_type(hardbreaks)) + self.log.debug("Hard line breaks check returned "+str(hardbreaks)) # Calculate Length unwrap_factor = getattr(self.extra_opts, 'html_unwrap_factor', 0.4) length = docanalysis.line_length(unwrap_factor) - self.log.debug("Median line length is " + unicode_type(length) + ", calculated with " + format + " format") + self.log.debug("Median line length is " + str(length) + ", calculated with " + format + " format") # ##### Unwrap lines ###### if getattr(self.extra_opts, 'unwrap_lines', False): @@ -832,7 +831,7 @@ class HeuristicProcessor: # If still no sections after unwrapping mark split points on lines with no punctuation if self.html_preprocess_sections < self.min_chapters and getattr(self.extra_opts, 'markup_chapter_headings', False): self.log.debug("Looking for more split points based on punctuation," - " currently have " + unicode_type(self.html_preprocess_sections)) + " currently have " + str(self.html_preprocess_sections)) chapdetect3 = re.compile( r'<(?P(p|div)[^>]*)>\s*(?P
(]*>)?\s*(?!([\W]+\s*)+)' r'(<[ibu][^>]*>){0,2}\s*(]*>)?\s*(<[ibu][^>]*>){0,2}\s*(]*>)?\s*' diff --git a/src/calibre/ebooks/covers.py b/src/calibre/ebooks/covers.py index 154d84d67f..52c4dbbd9b 100644 --- a/src/calibre/ebooks/covers.py +++ b/src/calibre/ebooks/covers.py @@ -9,7 +9,7 @@ import re, random, unicodedata, numbers from collections import namedtuple from contextlib import contextmanager from math import ceil, sqrt, cos, sin, atan2 -from polyglot.builtins import iteritems, itervalues, map, zip, string_or_bytes +from polyglot.builtins import iteritems, itervalues, string_or_bytes from itertools import chain from qt.core import ( @@ -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/css_transform_rules.py b/src/calibre/ebooks/css_transform_rules.py index 09fe12df77..8efb390bd7 100644 --- a/src/calibre/ebooks/css_transform_rules.py +++ b/src/calibre/ebooks/css_transform_rules.py @@ -12,7 +12,7 @@ from css_parser.css import Property, CSSRule from calibre import force_unicode from calibre.ebooks import parse_css_length from calibre.ebooks.oeb.normalize_css import normalizers, safe_parser -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def compile_pat(pat): @@ -161,7 +161,7 @@ def transform_number(val, op, raw): v = op(v, val) if int(v) == v: v = int(v) - return unicode_type(v) + u + return str(v) + u class Rule: @@ -379,7 +379,7 @@ def test(return_tests=False): # {{{ r = Rule(**rule) decl = StyleDeclaration(safe_parser().parseStyle(style)) r.process_declaration(decl) - return unicode_type(decl) + return str(decl) class TestTransforms(unittest.TestCase): longMessage = True diff --git a/src/calibre/ebooks/djvu/djvubzzdec.py b/src/calibre/ebooks/djvu/djvubzzdec.py index 592f78fe2e..84b8bd1a2f 100644 --- a/src/calibre/ebooks/djvu/djvubzzdec.py +++ b/src/calibre/ebooks/djvu/djvubzzdec.py @@ -2,7 +2,6 @@ # coding: utf-8 -from polyglot.builtins import range __license__ = 'GPL v3' __copyright__ = '2011, Anthon van der Neut ' diff --git a/src/calibre/ebooks/docx/cleanup.py b/src/calibre/ebooks/docx/cleanup.py index 983133200d..1231e693ec 100644 --- a/src/calibre/ebooks/docx/cleanup.py +++ b/src/calibre/ebooks/docx/cleanup.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' import os -from polyglot.builtins import itervalues, range +from polyglot.builtins import itervalues NBSP = '\xa0' 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/fonts.py b/src/calibre/ebooks/docx/fonts.py index 9faeda731b..4235c75c60 100644 --- a/src/calibre/ebooks/docx/fonts.py +++ b/src/calibre/ebooks/docx/fonts.py @@ -13,7 +13,7 @@ from calibre.utils.filenames import ascii_filename from calibre.utils.fonts.scanner import font_scanner, NoFonts from calibre.utils.fonts.utils import panose_to_css_generic_family, is_truetype_font from calibre.utils.icu import ord_string -from polyglot.builtins import codepoint_to_chr, iteritems, range +from polyglot.builtins import codepoint_to_chr, iteritems Embed = namedtuple('Embed', 'name key subsetted') diff --git a/src/calibre/ebooks/docx/footnotes.py b/src/calibre/ebooks/docx/footnotes.py index b5eaecd4b3..f0652e471f 100644 --- a/src/calibre/ebooks/docx/footnotes.py +++ b/src/calibre/ebooks/docx/footnotes.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' from collections import OrderedDict -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class Note: @@ -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: @@ -52,8 +51,8 @@ class Footnotes: if note is not None and note.type == 'normal': self.counter += 1 anchor = 'note_%d' % self.counter - self.notes[anchor] = (unicode_type(self.counter), note) - return anchor, unicode_type(self.counter) + self.notes[anchor] = (str(self.counter), note) + return anchor, str(self.counter) return None, None def __iter__(self): 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/index.py b/src/calibre/ebooks/docx/index.py index 39419284c0..9be71fc7ac 100644 --- a/src/calibre/ebooks/docx/index.py +++ b/src/calibre/ebooks/docx/index.py @@ -10,7 +10,7 @@ from operator import itemgetter from lxml import etree from calibre.utils.icu import partition_by_first_letter, sort_key -from polyglot.builtins import iteritems, filter +from polyglot.builtins import iteritems def get_applicable_xe_fields(index, xe_fields, XPath, expand): diff --git a/src/calibre/ebooks/docx/numbering.py b/src/calibre/ebooks/docx/numbering.py index 16a1af875c..f5f193544f 100644 --- a/src/calibre/ebooks/docx/numbering.py +++ b/src/calibre/ebooks/docx/numbering.py @@ -14,7 +14,7 @@ from lxml.html.builder import OL, UL, SPAN from calibre.ebooks.docx.block_styles import ParagraphStyle from calibre.ebooks.docx.char_styles import RunStyle, inherit from calibre.ebooks.metadata import roman -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems STYLE_MAP = { 'aiueo': 'hiragana', @@ -291,7 +291,7 @@ class Numbering: seen_instances.add(num_id) p.tag = 'li' p.set('value', '%s' % counter[ilvl]) - p.set('list-lvl', unicode_type(ilvl)) + p.set('list-lvl', str(ilvl)) p.set('list-id', num_id) if lvl.num_template is not None: val = lvl.format_template(counter, ilvl, lvl.num_template) 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 4926325ba0..45c43151b9 100644 --- a/src/calibre/ebooks/docx/tables.py +++ b/src/calibre/ebooks/docx/tables.py @@ -9,7 +9,7 @@ from lxml.html.builder import TABLE, TR, TD from calibre.ebooks.docx.block_styles import inherit, read_shd as rs, read_border, binary_property, border_props, ParagraphStyle, border_to_css from calibre.ebooks.docx.char_styles import RunStyle -from polyglot.builtins import filter, iteritems, itervalues, range, unicode_type +from polyglot.builtins import iteritems, itervalues # Read from XML {{{ read_shd = rs @@ -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') @@ -646,9 +644,9 @@ class Table: td = TD() style_map[td] = s = self.style_map[tc] if s.col_span is not inherit: - td.set('colspan', unicode_type(s.col_span)) + td.set('colspan', str(s.col_span)) if s.row_span is not inherit: - td.set('rowspan', unicode_type(s.row_span)) + td.set('rowspan', str(s.row_span)) td.tail = '\n\t\t\t' tr.append(td) for x in self.namespace.XPath('./w:p|./w:tbl')(tc): diff --git a/src/calibre/ebooks/docx/to_html.py b/src/calibre/ebooks/docx/to_html.py index c79b13794f..a10a6ce181 100644 --- a/src/calibre/ebooks/docx/to_html.py +++ b/src/calibre/ebooks/docx/to_html.py @@ -28,7 +28,7 @@ from calibre.ebooks.docx.fields import Fields from calibre.ebooks.docx.settings import Settings from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1 -from polyglot.builtins import iteritems, itervalues, filter, getcwd, map, unicode_type +from polyglot.builtins import iteritems, itervalues NBSP = '\xa0' @@ -69,7 +69,7 @@ class Convert: self.notes_text = notes_text or _('Notes') self.notes_nopb = notes_nopb self.nosupsub = nosupsub - self.dest_dir = dest_dir or getcwd() + self.dest_dir = dest_dir or os.getcwd() self.mi = self.docx.metadata self.body = BODY() self.theme = Theme(self.namespace) @@ -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) @@ -480,7 +480,7 @@ class Convert: current_hyperlink = x elif x.tag.endswith('}instrText') and x.text and x.text.strip().startswith('TOC '): old_anchor = current_anchor - anchor = unicode_type(uuid.uuid4()) + anchor = str(uuid.uuid4()) self.anchor_map[anchor] = current_anchor = generate_anchor('toc', frozenset(itervalues(self.anchor_map))) self.toc_anchor = current_anchor if old_anchor is not None: @@ -507,7 +507,7 @@ class Convert: if m is not None: n = min(6, max(1, int(m.group(1)))) dest.tag = 'h%d' % n - dest.set('data-heading-level', unicode_type(n)) + dest.set('data-heading-level', str(n)) if style.bidi is True: dest.set('dir', 'rtl') @@ -842,7 +842,7 @@ if __name__ == '__main__': import shutil from calibre.utils.logging import default_log default_log.filter_level = default_log.DEBUG - dest_dir = os.path.join(getcwd(), 'docx_input') + dest_dir = os.path.join(os.getcwd(), 'docx_input') if os.path.exists(dest_dir): shutil.rmtree(dest_dir) os.mkdir(dest_dir) diff --git a/src/calibre/ebooks/docx/toc.py b/src/calibre/ebooks/docx/toc.py index 0fb2e7ea8b..5d73af07c6 100644 --- a/src/calibre/ebooks/docx/toc.py +++ b/src/calibre/ebooks/docx/toc.py @@ -12,7 +12,7 @@ from lxml.etree import tostring from calibre.ebooks.metadata.toc import TOC from calibre.ebooks.oeb.polish.toc import elem_to_toc_text -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems def from_headings(body, log, namespace, num_levels=3): diff --git a/src/calibre/ebooks/docx/writer/container.py b/src/calibre/ebooks/docx/writer/container.py index 413ffd64e8..fcdb9a8a34 100644 --- a/src/calibre/ebooks/docx/writer/container.py +++ b/src/calibre/ebooks/docx/writer/container.py @@ -18,7 +18,7 @@ from calibre.ebooks.pdf.render.common import PAPER_SIZES from calibre.utils.date import utcnow from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1 from calibre.utils.zipfile import ZipFile -from polyglot.builtins import iteritems, map, unicode_type, native_string_type +from polyglot.builtins import iteritems, native_string_type def xml2str(root, pretty_print=False, with_tail=False): @@ -65,9 +65,9 @@ def create_skeleton(opts, namespaces=None): def margin(which): val = page_margin(opts, which) - return w(which), unicode_type(int(val * 20)) + return w(which), str(int(val * 20)) body.append(E.sectPr( - E.pgSz(**{w('w'):unicode_type(width), w('h'):unicode_type(height)}), + E.pgSz(**{w('w'):str(width), w('h'):str(height)}), E.pgMar(**dict(map(margin, 'left top right bottom'.split()))), E.cols(**{w('space'):'720'}), E.docGrid(**{w('linePitch'):"360"}), diff --git a/src/calibre/ebooks/docx/writer/fonts.py b/src/calibre/ebooks/docx/writer/fonts.py index d7bb42c786..838e060af3 100644 --- a/src/calibre/ebooks/docx/writer/fonts.py +++ b/src/calibre/ebooks/docx/writer/fonts.py @@ -10,7 +10,6 @@ from uuid import uuid4 from calibre.ebooks.oeb.base import OEB_STYLES from calibre.ebooks.oeb.transforms.subset import find_font_face_rules -from polyglot.builtins import range def obfuscate_font_data(data, key): diff --git a/src/calibre/ebooks/docx/writer/from_html.py b/src/calibre/ebooks/docx/writer/from_html.py index 985ae8ede8..eb11eb444a 100644 --- a/src/calibre/ebooks/docx/writer/from_html.py +++ b/src/calibre/ebooks/docx/writer/from_html.py @@ -18,7 +18,7 @@ from calibre.ebooks.docx.writer.lists import ListsManager from calibre.ebooks.oeb.stylizer import Stylizer as Sz, Style as St from calibre.ebooks.oeb.base import XPath, barename from calibre.utils.localization import lang_as_iso639_1 -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes def lang_for_tag(tag): @@ -108,7 +108,7 @@ class TextRun: for text, preserve_whitespace, bookmark in self.texts: if bookmark is not None: bid = links_manager.bookmark_id - makeelement(r, 'w:bookmarkStart', w_id=unicode_type(bid), w_name=bookmark) + makeelement(r, 'w:bookmarkStart', w_id=str(bid), w_name=bookmark) if text is None: makeelement(r, 'w:br', w_clear=preserve_whitespace) elif hasattr(text, 'xpath'): @@ -123,7 +123,7 @@ class TextRun: else: add_text('', preserve_whitespace) if bookmark is not None: - makeelement(r, 'w:bookmarkEnd', w_id=unicode_type(bid)) + makeelement(r, 'w:bookmarkEnd', w_id=str(bid)) def __repr__(self): return repr(self.texts) @@ -139,7 +139,7 @@ class TextRun: def style_weight(self): ans = 0 for text, preserve_whitespace, bookmark in self.texts: - if isinstance(text, unicode_type): + if isinstance(text, str): ans += len(text) return ans @@ -219,7 +219,7 @@ class Block: p = makeelement(body, 'w:p') end_bookmarks = [] for bmark in self.bookmarks: - end_bookmarks.append(unicode_type(self.links_manager.bookmark_id)) + end_bookmarks.append(str(self.links_manager.bookmark_id)) makeelement(p, 'w:bookmarkStart', w_id=end_bookmarks[-1], w_name=bmark) if self.block_lang: rpr = makeelement(p, 'w:rPr') @@ -232,8 +232,8 @@ class Block: self.float_spec.serialize(self, ppr) if self.numbering_id is not None: numpr = makeelement(ppr, 'w:numPr') - makeelement(numpr, 'w:ilvl', w_val=unicode_type(self.numbering_id[1])) - makeelement(numpr, 'w:numId', w_val=unicode_type(self.numbering_id[0])) + makeelement(numpr, 'w:ilvl', w_val=str(self.numbering_id[1])) + makeelement(numpr, 'w:numId', w_val=str(self.numbering_id[0])) if self.linked_style is not None: makeelement(ppr, 'w:pStyle', w_val=self.linked_style.id) elif self.style.id: @@ -453,8 +453,8 @@ class Convert: if self.add_toc: self.links_manager.process_toc_links(self.oeb) - if self.add_cover and self.oeb.metadata.cover and unicode_type(self.oeb.metadata.cover[0]) in self.oeb.manifest.ids: - cover_id = unicode_type(self.oeb.metadata.cover[0]) + if self.add_cover and self.oeb.metadata.cover and str(self.oeb.metadata.cover[0]) in self.oeb.manifest.ids: + cover_id = str(self.oeb.metadata.cover[0]) item = self.oeb.manifest.ids[cover_id] self.cover_img = self.images_manager.read_image(item.href) diff --git a/src/calibre/ebooks/docx/writer/images.py b/src/calibre/ebooks/docx/writer/images.py index 546c40329c..4ae6cbb334 100644 --- a/src/calibre/ebooks/docx/writer/images.py +++ b/src/calibre/ebooks/docx/writer/images.py @@ -9,7 +9,7 @@ import os import posixpath from collections import namedtuple from functools import partial -from polyglot.builtins import iteritems, itervalues, map, unicode_type +from polyglot.builtins import iteritems, itervalues from lxml import etree @@ -34,7 +34,7 @@ def get_image_margins(style): ans = {} for edge in 'Left Right Top Bottom'.split(): val = as_num(getattr(style, 'padding' + edge)) + as_num(getattr(style, 'margin' + edge)) - ans['dist' + edge[0]] = unicode_type(pt_to_emu(val)) + ans['dist' + edge[0]] = str(pt_to_emu(val)) return ans @@ -131,7 +131,7 @@ class ImagesManager: makeelement(parent, 'wp:simplePos', x='0', y='0') makeelement(makeelement(parent, 'wp:positionH', relativeFrom='margin'), 'wp:align').text = floating makeelement(makeelement(parent, 'wp:positionV', relativeFrom='line'), 'wp:align').text = 'top' - makeelement(parent, 'wp:extent', cx=unicode_type(width), cy=unicode_type(height)) + makeelement(parent, 'wp:extent', cx=str(width), cy=str(height)) if fake_margins: # DOCX does not support setting margins for inline images, so we # fake it by using effect extents to simulate margins @@ -149,7 +149,7 @@ class ImagesManager: def create_docx_image_markup(self, parent, name, alt, img_rid, width, height): makeelement, namespaces = self.document_relationships.namespace.makeelement, self.document_relationships.namespace.namespaces - makeelement(parent, 'wp:docPr', id=unicode_type(self.count), name=name, descr=alt) + makeelement(parent, 'wp:docPr', id=str(self.count), name=name, descr=alt) makeelement(makeelement(parent, 'wp:cNvGraphicFramePr'), 'a:graphicFrameLocks', noChangeAspect="1") g = makeelement(parent, 'a:graphic') gd = makeelement(g, 'a:graphicData', uri=namespaces['pic']) @@ -162,7 +162,7 @@ class ImagesManager: makeelement(makeelement(bf, 'a:stretch'), 'a:fillRect') spPr = makeelement(pic, 'pic:spPr') xfrm = makeelement(spPr, 'a:xfrm') - makeelement(xfrm, 'a:off', x='0', y='0'), makeelement(xfrm, 'a:ext', cx=unicode_type(width), cy=unicode_type(height)) + makeelement(xfrm, 'a:off', x='0', y='0'), makeelement(xfrm, 'a:ext', cx=str(width), cy=str(height)) makeelement(makeelement(spPr, 'a:prstGeom', prst='rect'), 'a:avLst') def create_filename(self, href, fmt): @@ -173,7 +173,7 @@ class ImagesManager: base = fname while fname.lower() in self.seen_filenames: num += 1 - fname = base + unicode_type(num) + fname = base + str(num) self.seen_filenames.add(fname.lower()) fname += os.extsep + fmt.lower() return fname @@ -208,7 +208,7 @@ class ImagesManager: makeelement(makeelement(parent, 'wp:positionH', relativeFrom='page'), 'wp:align').text = 'center' makeelement(makeelement(parent, 'wp:positionV', relativeFrom='page'), 'wp:align').text = 'center' width, height = map(pt_to_emu, (width, height)) - makeelement(parent, 'wp:extent', cx=unicode_type(width), cy=unicode_type(height)) + makeelement(parent, 'wp:extent', cx=str(width), cy=str(height)) makeelement(parent, 'wp:effectExtent', l='0', r='0', t='0', b='0') makeelement(parent, 'wp:wrapTopAndBottom') self.create_docx_image_markup(parent, 'cover.jpg', _('Cover'), img.rid, width, height) diff --git a/src/calibre/ebooks/docx/writer/links.py b/src/calibre/ebooks/docx/writer/links.py index 6b0825a544..71e5eadf83 100644 --- a/src/calibre/ebooks/docx/writer/links.py +++ b/src/calibre/ebooks/docx/writer/links.py @@ -10,7 +10,6 @@ from uuid import uuid4 from calibre.ebooks.oeb.base import urlquote from calibre.utils.filenames import ascii_text -from polyglot.builtins import unicode_type from polyglot.urllib import urlparse @@ -37,7 +36,7 @@ class TOCItem: p = makeelement(body, 'w:p', append=False) ppr = makeelement(p, 'w:pPr') makeelement(ppr, 'w:pStyle', w_val="Normal") - makeelement(ppr, 'w:ind', w_left='0', w_firstLineChars='0', w_firstLine='0', w_leftChars=unicode_type(200 * self.level)) + makeelement(ppr, 'w:ind', w_left='0', w_firstLineChars='0', w_firstLine='0', w_leftChars=str(200 * self.level)) if self.is_first: makeelement(ppr, 'w:pageBreakBefore', w_val='off') r = makeelement(p, 'w:r') @@ -71,7 +70,7 @@ class LinksManager: self.namespace = namespace self.log = log self.document_relationships = document_relationships - self.top_anchor = unicode_type(uuid4().hex) + self.top_anchor = str(uuid4().hex) self.anchor_map = {} self.used_bookmark_names = set() self.bmark_id = 0 diff --git a/src/calibre/ebooks/docx/writer/lists.py b/src/calibre/ebooks/docx/writer/lists.py index db0a3f17df..f28ba17781 100644 --- a/src/calibre/ebooks/docx/writer/lists.py +++ b/src/calibre/ebooks/docx/writer/lists.py @@ -8,7 +8,7 @@ __copyright__ = '2015, Kovid Goyal ' from collections import defaultdict from operator import attrgetter -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues LIST_STYLES = frozenset( 'disc circle square decimal decimal-leading-zero lower-roman upper-roman' @@ -83,7 +83,7 @@ class NumberingDefinition: def serialize(self, parent): makeelement = self.namespace.makeelement - an = makeelement(parent, 'w:abstractNum', w_abstractNumId=unicode_type(self.num_id)) + an = makeelement(parent, 'w:abstractNum', w_abstractNumId=str(self.num_id)) makeelement(an, 'w:multiLevelType', w_val='hybridMultilevel') makeelement(an, 'w:name', w_val='List %d' % (self.num_id + 1)) for level in self.levels: @@ -114,12 +114,12 @@ class Level: return hash((self.start, self.num_fmt, self.lvl_text)) def serialize(self, parent, makeelement): - lvl = makeelement(parent, 'w:lvl', w_ilvl=unicode_type(self.ilvl)) - makeelement(lvl, 'w:start', w_val=unicode_type(self.start)) + lvl = makeelement(parent, 'w:lvl', w_ilvl=str(self.ilvl)) + makeelement(lvl, 'w:start', w_val=str(self.start)) makeelement(lvl, 'w:numFmt', w_val=self.num_fmt) makeelement(lvl, 'w:lvlText', w_val=self.lvl_text) makeelement(lvl, 'w:lvlJc', w_val='left') - makeelement(makeelement(lvl, 'w:pPr'), 'w:ind', w_hanging='360', w_left=unicode_type(1152 + self.ilvl * 360)) + makeelement(makeelement(lvl, 'w:pPr'), 'w:ind', w_hanging='360', w_left=str(1152 + self.ilvl * 360)) if self.num_fmt == 'bullet': ff = {'\uf0b7':'Symbol', '\uf0a7':'Wingdings'}.get(self.lvl_text, 'Courier New') makeelement(makeelement(lvl, 'w:rPr'), 'w:rFonts', w_ascii=ff, w_hAnsi=ff, w_hint="default") @@ -165,5 +165,5 @@ class ListsManager: defn.serialize(parent) makeelement = self.namespace.makeelement for defn in self.definitions: - n = makeelement(parent, 'w:num', w_numId=unicode_type(defn.num_id + 1)) - makeelement(n, 'w:abstractNumId', w_val=unicode_type(defn.num_id)) + n = makeelement(parent, 'w:num', w_numId=str(defn.num_id + 1)) + makeelement(n, 'w:abstractNumId', w_val=str(defn.num_id)) diff --git a/src/calibre/ebooks/docx/writer/styles.py b/src/calibre/ebooks/docx/writer/styles.py index 1ee8631775..5a57c6d279 100644 --- a/src/calibre/ebooks/docx/writer/styles.py +++ b/src/calibre/ebooks/docx/writer/styles.py @@ -14,7 +14,7 @@ from lxml import etree from calibre.ebooks import parse_css_length from calibre.ebooks.docx.writer.utils import convert_color, int_or_zero from calibre.utils.localization import lang_as_iso639_1 -from polyglot.builtins import iteritems, filter, unicode_type +from polyglot.builtins import iteritems from tinycss.css21 import CSS21Parser css_parser = CSS21Parser() @@ -76,7 +76,7 @@ class CombinedStyle: pPr = makeelement(block, 'w:pPr') self.bs.serialize_properties(pPr, normal_style.bs) if self.outline_level is not None: - makeelement(pPr, 'w:outlineLvl', w_val=unicode_type(self.outline_level + 1)) + makeelement(pPr, 'w:outlineLvl', w_val=str(self.outline_level + 1)) rPr = makeelement(block, 'w:rPr') self.rs.serialize_properties(rPr, normal_style.rs) @@ -109,16 +109,16 @@ class FloatSpec: def serialize(self, block, parent): if self.is_dropcaps: - attrs = dict(w_dropCap='drop', w_lines=unicode_type(self.dropcaps_lines), w_wrap='around', w_vAnchor='text', w_hAnchor='text') + attrs = dict(w_dropCap='drop', w_lines=str(self.dropcaps_lines), w_wrap='around', w_vAnchor='text', w_hAnchor='text') else: attrs = dict( w_wrap='around', w_vAnchor='text', w_hAnchor='text', w_xAlign=self.x_align, w_y='1', - w_hSpace=unicode_type(self.h_space), w_vSpace=unicode_type(self.v_space), w_hRule=self.h_rule + w_hSpace=str(self.h_space), w_vSpace=str(self.v_space), w_hRule=self.h_rule ) if self.w is not None: - attrs['w_w'] = unicode_type(self.w) + attrs['w_w'] = str(self.w) if self.h is not None: - attrs['w_h'] = unicode_type(self.h) + attrs['w_h'] = str(self.h) self.makeelement(parent, 'w:framePr', **attrs) # Margins are already applied by the frame style, so override them to # be zero on individual blocks @@ -138,7 +138,7 @@ class FloatSpec: width = getattr(self, 'border_%s_width' % edge) bstyle = getattr(self, 'border_%s_style' % edge) self.makeelement( - bdr, 'w:'+edge, w_space=unicode_type(padding), w_val=bstyle, w_sz=unicode_type(width), w_color=getattr(self, 'border_%s_color' % edge)) + bdr, 'w:'+edge, w_space=str(padding), w_val=bstyle, w_sz=str(width), w_color=getattr(self, 'border_%s_color' % edge)) class DOCXStyle: @@ -234,7 +234,7 @@ class TextStyle(DOCXStyle): self.spacing = None va = css.first_vertical_align if isinstance(va, numbers.Number): - self.vertical_align = unicode_type(int(va * 2)) + self.vertical_align = str(int(va * 2)) else: val = { 'top':'superscript', 'text-top':'superscript', 'sup':'superscript', 'super':'superscript', @@ -290,9 +290,9 @@ class TextStyle(DOCXStyle): w = self.w is_normal_style = self is normal_style if is_normal_style or self.padding != normal_style.padding: - bdr.set(w('space'), unicode_type(self.padding)) + bdr.set(w('space'), str(self.padding)) if is_normal_style or self.border_width != normal_style.border_width: - bdr.set(w('sz'), unicode_type(self.border_width)) + bdr.set(w('sz'), str(self.border_width)) if is_normal_style or self.border_style != normal_style.border_style: bdr.set(w('val'), self.border_style) if is_normal_style or self.border_color != normal_style.border_color: @@ -342,7 +342,7 @@ class TextStyle(DOCXStyle): if check_attr('shadow'): rPr.append(makeelement(rPr, 'shadow', val=bmap(self.shadow))) if check_attr('spacing'): - rPr.append(makeelement(rPr, 'spacing', val=unicode_type(self.spacing or 0))) + rPr.append(makeelement(rPr, 'spacing', val=str(self.spacing or 0))) if is_normal_style: rPr.append(makeelement(rPr, 'vertAlign', val=self.vertical_align if self.vertical_align in {'superscript', 'subscript'} else 'baseline')) elif self.vertical_align != normal_style.vertical_align: @@ -380,7 +380,7 @@ class DescendantTextStyle: for name, attr in (('sz', 'font_size'), ('b', 'bold'), ('i', 'italic')): pval, cval = vals(attr) if pval != cval: - val = 'on' if attr in {'bold', 'italic'} else unicode_type(cval) # bold, italic are toggle properties + val = 'on' if attr in {'bold', 'italic'} else str(cval) # bold, italic are toggle properties for suffix in ('', 'Cs'): add(name + suffix, val=val) @@ -401,7 +401,7 @@ class DescendantTextStyle: if check('shadow'): add('shadow', val='on') # toggle property if check('spacing'): - add('spacing', val=unicode_type(child_style.spacing or 0)) + add('spacing', val=str(child_style.spacing or 0)) if check('vertical_align'): val = child_style.vertical_align if val in {'superscript', 'subscript', 'baseline'}: @@ -411,9 +411,9 @@ class DescendantTextStyle: bdr = {} if check('padding'): - bdr['space'] = unicode_type(child_style.padding) + bdr['space'] = str(child_style.padding) if check('border_width'): - bdr['sz'] = unicode_type(child_style.border_width) + bdr['sz'] = str(child_style.border_width) if check('border_style'): bdr['val'] = child_style.border_style if check('border_color'): @@ -537,14 +537,14 @@ class BlockStyle(DOCXStyle): e = bdr.makeelement(w(edge)) padding = getattr(self, 'padding_' + edge) if (self is normal_style and padding > 0) or (padding != getattr(normal_style, 'padding_' + edge)): - e.set(w('space'), unicode_type(padding)) + e.set(w('space'), str(padding)) width = getattr(self, 'border_%s_width' % edge) bstyle = getattr(self, 'border_%s_style' % edge) if (self is normal_style and width > 0 and bstyle != 'none' ) or width != getattr(normal_style, 'border_%s_width' % edge ) or bstyle != getattr(normal_style, 'border_%s_style' % edge): e.set(w('val'), bstyle) - e.set(w('sz'), unicode_type(width)) + e.set(w('sz'), str(width)) e.set(w('color'), getattr(self, 'border_%s_color' % edge)) if e.attrib: bdr.append(e) @@ -568,15 +568,15 @@ class BlockStyle(DOCXStyle): if css_unit in ('em', 'ex'): lines = max(0, int(css_val * (50 if css_unit == 'ex' else 100))) if (self is normal_style and lines > 0) or getter(self) != getter(normal_style): - spacing.set(w(attr + 'Lines'), unicode_type(lines)) + spacing.set(w(attr + 'Lines'), str(lines)) else: getter = attrgetter('margin_' + edge) val = getter(self) if (self is normal_style and val > 0) or val != getter(normal_style): - spacing.set(w(attr), unicode_type(val)) + spacing.set(w(attr), str(val)) if self is normal_style or self.line_height != normal_style.line_height: - spacing.set(w('line'), unicode_type(self.line_height)) + spacing.set(w('line'), str(self.line_height)) spacing.set(w('lineRule'), 'atLeast') if spacing.attrib: @@ -589,31 +589,31 @@ class BlockStyle(DOCXStyle): if css_unit in ('em', 'ex'): chars = max(0, int(css_val * (50 if css_unit == 'ex' else 100))) if (self is normal_style and chars > 0) or getter(self) != getter(normal_style): - ind.set(w(edge + 'Chars'), unicode_type(chars)) + ind.set(w(edge + 'Chars'), str(chars)) else: getter = attrgetter('margin_' + edge) val = getter(self) if (self is normal_style and val > 0) or val != getter(normal_style): - ind.set(w(edge), unicode_type(val)) + ind.set(w(edge), str(val)) ind.set(w(edge + 'Chars'), '0') # This is needed to override any declaration in the parent style css_val, css_unit = parse_css_length(self.css_text_indent) if css_unit in ('em', 'ex'): chars = int(css_val * (50 if css_unit == 'ex' else 100)) if css_val >= 0: if (self is normal_style and chars > 0) or self.css_text_indent != normal_style.css_text_indent: - ind.set(w('firstLineChars'), unicode_type(chars)) + ind.set(w('firstLineChars'), str(chars)) else: if (self is normal_style and chars < 0) or self.css_text_indent != normal_style.css_text_indent: - ind.set(w('hangingChars'), unicode_type(abs(chars))) + ind.set(w('hangingChars'), str(abs(chars))) else: val = self.text_indent if val >= 0: if (self is normal_style and val > 0) or self.text_indent != normal_style.text_indent: - ind.set(w('firstLine'), unicode_type(val)) + ind.set(w('firstLine'), str(val)) ind.set(w('firstLineChars'), '0') # This is needed to override any declaration in the parent style else: if (self is normal_style and val < 0) or self.text_indent != normal_style.text_indent: - ind.set(w('hanging'), unicode_type(abs(val))) + ind.set(w('hanging'), str(abs(val))) ind.set(w('hangingChars'), '0') if ind.attrib: pPr.append(ind) @@ -687,7 +687,7 @@ class StylesManager: pure_block_styles.add(bs) self.pure_block_styles = sorted(pure_block_styles, key=block_counts.__getitem__) - bnum = len(unicode_type(max(1, len(pure_block_styles) - 1))) + bnum = len(str(max(1, len(pure_block_styles) - 1))) for i, bs in enumerate(self.pure_block_styles): bs.id = bs.name = '%0{}d Block'.format(bnum) % i bs.seq = i @@ -707,7 +707,7 @@ class StylesManager: heading_style = styles[-1] heading_style.outline_level = i - snum = len(unicode_type(max(1, len(counts) - 1))) + snum = len(str(max(1, len(counts) - 1))) heading_styles = [] for i, (style, count) in enumerate(counts.most_common()): if i == 0: @@ -735,7 +735,7 @@ class StylesManager: if run.descendant_style is None: run.descendant_style = descendant_style_map[ds] = ds ds_counts[run.descendant_style] += run.style_weight - rnum = len(unicode_type(max(1, len(ds_counts) - 1))) + rnum = len(str(max(1, len(ds_counts) - 1))) for i, (text_style, count) in enumerate(ds_counts.most_common()): text_style.id = 'Text%d' % i text_style.name = '%0{}d Text'.format(rnum) % i diff --git a/src/calibre/ebooks/docx/writer/tables.py b/src/calibre/ebooks/docx/writer/tables.py index 4a57ffb31e..8141448333 100644 --- a/src/calibre/ebooks/docx/writer/tables.py +++ b/src/calibre/ebooks/docx/writer/tables.py @@ -9,7 +9,7 @@ from collections import namedtuple from calibre.ebooks.docx.writer.utils import convert_color from calibre.ebooks.docx.writer.styles import read_css_block_borders as rcbb, border_edges -from polyglot.builtins import iteritems, range, unicode_type +from polyglot.builtins import iteritems class Dummy: @@ -115,7 +115,7 @@ class Cell: def serialize(self, parent, makeelement): tc = makeelement(parent, 'w:tc') tcPr = makeelement(tc, 'w:tcPr') - makeelement(tcPr, 'w:tcW', w_type=self.width[0], w_w=unicode_type(self.width[1])) + makeelement(tcPr, 'w:tcW', w_type=self.width[0], w_w=str(self.width[1])) # For some reason, Word 2007 refuses to honor at the table or row # level, despite what the specs say, so we inherit and apply at the # cell level @@ -126,7 +126,7 @@ class Cell: b = makeelement(tcPr, 'w:tcBorders', append=False) for edge, border in iteritems(self.borders): if border is not None and border.width > 0 and border.style != 'none': - makeelement(b, 'w:' + edge, w_val=border.style, w_sz=unicode_type(border.width), w_color=border.color) + makeelement(b, 'w:' + edge, w_val=border.style, w_sz=str(border.width), w_color=border.color) if len(b) > 0: tcPr.append(b) @@ -136,7 +136,7 @@ class Cell: if edge in {'top', 'bottom'} or (edge == 'left' and self is self.row.first_cell) or (edge == 'right' and self is self.row.last_cell): padding += getattr(self.row, 'padding_' + edge) if padding > 0: - makeelement(m, 'w:' + edge, w_type='dxa', w_w=unicode_type(int(padding * 20))) + makeelement(m, 'w:' + edge, w_type='dxa', w_w=str(int(padding * 20))) if len(m) > 0: tcPr.append(m) @@ -356,14 +356,14 @@ class Table: return tbl = makeelement(parent, 'w:tbl') tblPr = makeelement(tbl, 'w:tblPr') - makeelement(tblPr, 'w:tblW', w_type=self.width[0], w_w=unicode_type(self.width[1])) + makeelement(tblPr, 'w:tblW', w_type=self.width[0], w_w=str(self.width[1])) if self.float in {'left', 'right'}: kw = {'w_vertAnchor':'text', 'w_horzAnchor':'text', 'w_tblpXSpec':self.float} for edge in border_edges: val = getattr(self, 'margin_' + edge) or 0 if {self.float, edge} == {'left', 'right'}: val = max(val, 2) - kw['w_' + edge + 'FromText'] = unicode_type(max(0, int(val *20))) + kw['w_' + edge + 'FromText'] = str(max(0, int(val *20))) makeelement(tblPr, 'w:tblpPr', **kw) if self.jc is not None: makeelement(tblPr, 'w:jc', w_val=self.jc) 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/epub/cfi/parse.py b/src/calibre/ebooks/epub/cfi/parse.py index 4e69ae1a16..5bdd790cde 100644 --- a/src/calibre/ebooks/epub/cfi/parse.py +++ b/src/calibre/ebooks/epub/cfi/parse.py @@ -6,7 +6,6 @@ __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' import regex -from polyglot.builtins import map, zip class Parser: diff --git a/src/calibre/ebooks/epub/cfi/tests.py b/src/calibre/ebooks/epub/cfi/tests.py index 5ebce70935..e8f92be52e 100644 --- a/src/calibre/ebooks/epub/cfi/tests.py +++ b/src/calibre/ebooks/epub/cfi/tests.py @@ -6,10 +6,9 @@ __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' import unittest, numbers -from polyglot.builtins import map from calibre.ebooks.epub.cfi.parse import parser, cfi_sort_key, decode_cfi -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class Tests(unittest.TestCase): @@ -60,7 +59,7 @@ class Tests(unittest.TestCase): if after is not None: ta['after'] = after if params: - ta['params'] = {unicode_type(k):(v,) if isinstance(v, unicode_type) else v for k, v in iteritems(params)} + ta['params'] = {str(k):(v,) if isinstance(v, str) else v for k, v in iteritems(params)} if ta: step['text_assertion'] = ta return ans diff --git a/src/calibre/ebooks/epub/pages.py b/src/calibre/ebooks/epub/pages.py index ed824d0a44..da06eef01e 100644 --- a/src/calibre/ebooks/epub/pages.py +++ b/src/calibre/ebooks/epub/pages.py @@ -12,7 +12,6 @@ from itertools import count from calibre.ebooks.oeb.base import XHTML_NS from calibre.ebooks.oeb.base import OEBBook from lxml.etree import XPath -from polyglot.builtins import unicode_type NSMAP = {'h': XHTML_NS, 'html': XHTML_NS, 'xhtml': XHTML_NS} PAGE_RE = re.compile(r'page', re.IGNORECASE) @@ -32,7 +31,7 @@ def filter_name(name): def build_name_for(expr): if not expr: counter = count(1) - return lambda elem: unicode_type(next(counter)) + return lambda elem: str(next(counter)) selector = XPath(expr, namespaces=NSMAP) def name_for(elem): diff --git a/src/calibre/ebooks/epub/periodical.py b/src/calibre/ebooks/epub/periodical.py index 97fb17ccdb..6efdbe3c3d 100644 --- a/src/calibre/ebooks/epub/periodical.py +++ b/src/calibre/ebooks/epub/periodical.py @@ -12,7 +12,6 @@ import time from calibre.constants import __appname__, __version__ from calibre import strftime, prepare_string_for_xml as xml from calibre.utils.date import parse_date -from polyglot.builtins import unicode_type, filter SONY_METADATA = '''\ @@ -83,21 +82,21 @@ SONY_ATOM_ENTRY = '''\ def sony_metadata(oeb): m = oeb.metadata - title = short_title = unicode_type(m.title[0]) + title = short_title = str(m.title[0]) publisher = __appname__ + ' ' + __version__ try: - pt = unicode_type(oeb.metadata.publication_type[0]) + pt = str(oeb.metadata.publication_type[0]) short_title = ':'.join(pt.split(':')[2:]) except: pass try: - date = parse_date(unicode_type(m.date[0]), + date = parse_date(str(m.date[0]), as_utc=False).strftime('%Y-%m-%d') except: date = strftime('%Y-%m-%d') try: - language = unicode_type(m.language[0]).replace('_', '-') + language = str(m.language[0]).replace('_', '-') except: language = 'en' short_title = xml(short_title, True) @@ -115,9 +114,9 @@ def sony_metadata(oeb): return True try: - base_id = unicode_type(list(filter(cal_id, m.identifier))[0]) + base_id = str(list(filter(cal_id, m.identifier))[0]) except: - base_id = unicode_type(uuid4()) + base_id = str(uuid4()) toc = oeb.toc @@ -130,7 +129,7 @@ def sony_metadata(oeb): for x in toc: section.nodes.append(x) toc = TOC(klass='periodical', href=oeb.spine[2].href, - title=unicode_type(oeb.metadata.title[0])) + title=str(oeb.metadata.title[0])) toc.nodes.append(section) entries = [] @@ -145,7 +144,7 @@ def sony_metadata(oeb): d = 1 bsectitle = sectitle while sectitle in seen_titles: - sectitle = bsectitle + ' ' + unicode_type(d) + sectitle = bsectitle + ' ' + str(d) d += 1 seen_titles.add(sectitle) sectitle = xml(sectitle, True) @@ -164,7 +163,7 @@ def sony_metadata(oeb): btitle = atitle d = 1 while atitle in seen_titles: - atitle = btitle + ' ' + unicode_type(d) + atitle = btitle + ' ' + str(d) d += 1 auth = article.author if article.author else '' @@ -181,7 +180,7 @@ def sony_metadata(oeb): short_title=short_title, section_title=sectitle, href=article.href, - word_count=unicode_type(1), + word_count=str(1), id=xml(base_id)+'/'+secid+'/'+aid )) diff --git a/src/calibre/ebooks/fb2/fb2ml.py b/src/calibre/ebooks/fb2/fb2ml.py index 176fc324a0..f310f68991 100644 --- a/src/calibre/ebooks/fb2/fb2ml.py +++ b/src/calibre/ebooks/fb2/fb2ml.py @@ -20,7 +20,7 @@ from calibre.utils.localization import lang_as_iso639_1 from calibre.utils.xml_parse import safe_xml_fromstring from calibre.utils.img import save_cover_data_to from calibre.ebooks.oeb.base import urlnormalize -from polyglot.builtins import unicode_type, string_or_bytes, range, filter +from polyglot.builtins import string_or_bytes from polyglot.binary import as_base64_unicode from polyglot.urllib import urlparse @@ -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 @@ -154,7 +154,7 @@ class FB2MLizer: metadata['author'] = '' metadata['keywords'] = '' - tags = list(map(unicode_type, self.oeb_book.metadata.subject)) + tags = list(map(str, self.oeb_book.metadata.subject)) if tags: tags = ', '.join(prepare_string_for_xml(x) for x in tags) metadata['keywords'] = '%s'%tags @@ -169,12 +169,12 @@ class FB2MLizer: year = publisher = isbn = '' identifiers = self.oeb_book.metadata['identifier'] for x in identifiers: - if x.get(OPF('scheme'), None).lower() == 'uuid' or unicode_type(x).startswith('urn:uuid:'): - metadata['id'] = unicode_type(x).split(':')[-1] + if x.get(OPF('scheme'), None).lower() == 'uuid' or str(x).startswith('urn:uuid:'): + metadata['id'] = str(x).split(':')[-1] break if metadata['id'] is None: self.log.warn('No UUID identifier found') - metadata['id'] = unicode_type(uuid.uuid4()) + metadata['id'] = str(uuid.uuid4()) try: date = self.oeb_book.metadata['date'][0] @@ -236,7 +236,7 @@ class FB2MLizer: ''') % metadata # Remove empty lines. - return '\n'.join(filter(unicode_type.strip, header.splitlines())) + return '\n'.join(filter(str.strip, header.splitlines())) def fb2_footer(self): return '' @@ -247,8 +247,8 @@ class FB2MLizer: cover_href = None # Get the raster cover if it's available. - if self.oeb_book.metadata.cover and unicode_type(self.oeb_book.metadata.cover[0]) in self.oeb_book.manifest.ids: - id = unicode_type(self.oeb_book.metadata.cover[0]) + if self.oeb_book.metadata.cover and str(self.oeb_book.metadata.cover[0]) in self.oeb_book.manifest.ids: + id = str(self.oeb_book.metadata.cover[0]) cover_item = self.oeb_book.manifest.ids[id] if cover_item.media_type in OEB_RASTER_IMAGES: cover_href = cover_item.href @@ -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 ed652fedb0..1527883dfc 100644 --- a/src/calibre/ebooks/html/input.py +++ b/src/calibre/ebooks/html/input.py @@ -17,7 +17,6 @@ from calibre.ebooks.oeb.base import urlunquote from calibre.ebooks.chardet import detect_xml_encoding from calibre.constants import iswindows from calibre import unicode_path, as_unicode, replace_entities -from polyglot.builtins import unicode_type from polyglot.urllib import urlparse, urlunparse @@ -46,7 +45,7 @@ class Link: :param base: The base folder that relative URLs are with respect to. Must be a unicode string. ''' - assert isinstance(url, unicode_type) and isinstance(base, unicode_type) + assert isinstance(url, str) and isinstance(base, str) self.url = url self.parsed_url = urlparse(self.url) self.is_local = self.parsed_url.scheme in ('', 'file') @@ -122,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: @@ -155,7 +154,7 @@ class HTMLFile: return 'HTMLFile:%d:%s:%r'%(self.level, 'b' if self.is_binary else 'a', self.path) def __repr__(self): - return unicode_type(self) + return str(self) def find_links(self, src): for match in self.LINK_PAT.finditer(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/html/to_zip.py b/src/calibre/ebooks/html/to_zip.py index be8a7b5e8f..9f7dc613cb 100644 --- a/src/calibre/ebooks/html/to_zip.py +++ b/src/calibre/ebooks/html/to_zip.py @@ -10,7 +10,6 @@ import textwrap, os, glob from calibre.customize import FileTypePlugin from calibre.constants import numeric_version -from polyglot.builtins import unicode_type class HTML2ZIP(FileTypePlugin): @@ -114,7 +113,7 @@ every time you add an HTML file to the library.\ config_dialog.exec_() if config_dialog.result() == QDialog.DialogCode.Accepted: - sc = unicode_type(sc.text()).strip() + sc = str(sc.text()).strip() if bf.isChecked(): sc += '|bf' customize_plugin(self, sc) diff --git a/src/calibre/ebooks/htmlz/oeb2html.py b/src/calibre/ebooks/htmlz/oeb2html.py index 7335739cfe..5d4166d8cf 100644 --- a/src/calibre/ebooks/htmlz/oeb2html.py +++ b/src/calibre/ebooks/htmlz/oeb2html.py @@ -20,7 +20,7 @@ from calibre.ebooks.oeb.base import ( XHTML, XHTML_NS, SVG_NS, barename, namespace, OEB_IMAGES, XLINK, rewrite_links, urlnormalize) from calibre.ebooks.oeb.stylizer import Stylizer from calibre.utils.logging import default_log -from polyglot.builtins import unicode_type, string_or_bytes, as_unicode +from polyglot.builtins import string_or_bytes, as_unicode from polyglot.urllib import urldefrag SELF_CLOSING_TAGS = {'area', 'base', 'basefont', 'br', 'hr', 'input', 'img', 'link', 'meta'} @@ -46,7 +46,7 @@ class OEB2HTML: self.log.info('Converting OEB book to HTML...') self.opts = opts try: - self.book_title = unicode_type(oeb_book.metadata.title[0]) + self.book_title = str(oeb_book.metadata.title[0]) except Exception: self.book_title = _('Unknown') self.links = {} @@ -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 94882c7de2..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 ' @@ -7,7 +5,6 @@ __copyright__ = '2008, Marshall T. Vandegrift ' Microsoft LIT OPF tag and attribute tables, copied from ConvertLIT. """ -from polyglot.builtins import range TAGS = [ None, diff --git a/src/calibre/ebooks/lit/mssha1.py b/src/calibre/ebooks/lit/mssha1.py index 265d0ad7ea..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. @@ -9,7 +8,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' import struct, copy -from polyglot.builtins import range, long_type +from polyglot.builtins import long_type # ====================================================================== # Bit-Manipulation helpers diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 1ab059e695..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. ''' @@ -17,7 +16,7 @@ import calibre.ebooks.lit.mssha1 as mssha1 from calibre.ebooks.oeb.base import urlnormalize, xpath from calibre.ebooks.oeb.reader import OEBReader from calibre.ebooks import DRMError -from polyglot.builtins import codepoint_to_chr, unicode_type, string_or_bytes, range, itervalues +from polyglot.builtins import codepoint_to_chr, string_or_bytes, itervalues from polyglot.urllib import unquote as urlunquote, urldefrag from calibre_extensions import lzx, msdes @@ -117,11 +116,11 @@ 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): - return unicode_type(string).encode('ascii', 'xmlcharrefreplace') + return str(string).encode('ascii', 'xmlcharrefreplace') class UnBinary: @@ -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' @@ -325,7 +324,7 @@ class UnBinary: c = '"' elif c == '<': c = '<' - if isinstance(c, unicode_type): + if isinstance(c, str): c = c.encode('ascii', 'xmlcharrefreplace') buf.write(c) count -= 1 @@ -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 9f9c005a8b..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. ''' @@ -29,7 +28,7 @@ from calibre.ebooks.lit.lzx import Compressor import calibre from calibre_extensions import msdes import calibre.ebooks.lit.mssha1 as mssha1 -from polyglot.builtins import codepoint_to_chr, unicode_type, string_or_bytes, range, zip, native_string_type +from polyglot.builtins import codepoint_to_chr, string_or_bytes, native_string_type from polyglot.urllib import urldefrag, unquote __all__ = ['LitWriter'] @@ -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) @@ -164,8 +163,8 @@ class ReBinary: try: value = codepoint_to_chr(value) except OverflowError: - self.logger.warn('unicode_type overflow for integer:', value) - value = u'?' + self.logger.warn('Unicode overflow for integer:', value) + value = '?' self.buf.write(value.encode('utf-8')) def is_block(self, style): @@ -283,7 +282,7 @@ class ReBinary: data.write(codepoint_to_chr(len(self.anchors)).encode('utf-8')) for anchor, offset in self.anchors: data.write(codepoint_to_chr(len(anchor)).encode('utf-8')) - if isinstance(anchor, unicode_type): + if isinstance(anchor, str): anchor = anchor.encode('utf-8') data.write(anchor) data.write(pack(' 0 and self.link_level <= self.link_levels: for path in paths: @@ -358,7 +358,7 @@ class HTMLConverter: os.makedirs(tdir) try: with open(os.path.join(tdir, 'html2lrf-verbose.html'), 'wb') as f: - f.write(unicode_type(soup).encode('utf-8')) + f.write(str(soup).encode('utf-8')) self.log.info(_('Written preprocessed HTML to ')+f.name) except: pass @@ -391,7 +391,7 @@ class HTMLConverter: self.log.info(_('\tConverting to BBeB...')) self.current_style = {} self.page_break_found = False - if not isinstance(path, unicode_type): + if not isinstance(path, str): path = path.decode(sys.getfilesystemencoding()) self.target_prefix = path self.previous_text = '\n' @@ -401,7 +401,7 @@ class HTMLConverter: def parse_css(self, style): """ Parse the contents of a \n' objects += '\n' if write_files: 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 6fc763f485..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 ' ''' @@ -22,7 +20,7 @@ from calibre.ebooks.lrf.pylrs.pylrs import ( TextStyle ) from calibre.utils.config import OptionParser -from polyglot.builtins import string_or_bytes, unicode_type +from polyglot.builtins import string_or_bytes class LrsParser: @@ -55,7 +53,7 @@ class LrsParser: for key, val in tag.attrs: if key in exclude: continue - result[unicode_type(key)] = val + result[str(key)] = val return result def text_tag_to_element(self, tag): diff --git a/src/calibre/ebooks/lrf/meta.py b/src/calibre/ebooks/lrf/meta.py index a003b82db6..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 ' @@ -22,7 +20,7 @@ from functools import wraps from calibre.ebooks.chardet import xml_to_unicode from calibre.utils.cleantext import clean_xml_chars from calibre.ebooks.metadata import MetaInformation, string_to_authors -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes BYTE = "\n' - s += unicode_type(self.content) + s += str(self.content) s += '\n'%(self.name,) return s return s.rstrip() + ' />\n' @@ -710,7 +703,7 @@ class Text(LRFStream): lineposition_map = {1:'before', 2:'after'} def add_text(self, text): - s = unicode_type(text, "utf-16-le") + s = str(text, "utf-16-le") if s: s = s.translate(self.text_map) self.content.append(self.entity_pattern.sub(entity_to_unicode, s)) @@ -850,7 +843,7 @@ class Text(LRFStream): self.add_text(stream.read(tag.word)) elif tag.id in self.__class__.text_tags: # A Text tag action = self.__class__.text_tags[tag.id] - if isinstance(action, unicode_type): + if isinstance(action, str): getattr(self, action)(tag, stream) else: getattr(self, action[0])(tag, action[1]) @@ -874,14 +867,14 @@ class Text(LRFStream): s = '' open_containers = collections.deque() for c in self.content: - if isinstance(c, unicode_type): + if isinstance(c, str): s += prepare_string_for_xml(c).replace('\0', '') elif c is None: if open_containers: p = open_containers.pop() s += ''%(p.name,) else: - s += unicode_type(c) + s += str(c) if not c.self_closing: open_containers.append(c) @@ -897,7 +890,7 @@ class Text(LRFStream): open_containers = collections.deque() in_p = False for c in self.content: - if isinstance(c, unicode_type): + if isinstance(c, str): s += c elif c is None: p = open_containers.pop() @@ -992,13 +985,12 @@ class Canvas(LRFStream): s += '%s="%s" '%(attr, self.attrs[attr]) s = s.rstrip() + '>\n' for po in self: - s += unicode_type(po) + '\n' + s += str(po) + '\n' s += '\n'%(self.__class__.__name__,) return s def __iter__(self): - for i in self._contents: - yield i + yield from self._contents class Header(Canvas): @@ -1025,7 +1017,7 @@ class ImageStream(LRFStream): def end_stream(self, *args): LRFStream.end_stream(self, *args) - self.file = unicode_type(self.id) + '.' + self.encoding.lower() + self.file = str(self.id) + '.' + self.encoding.lower() if self._document is not None: self._document.image_map[self.id] = self @@ -1189,7 +1181,7 @@ class BookAttr(StyleObject, LRFObject): s += '\n'%\ (self.binding_map[doc.binding], doc.dpi, doc.width, doc.height, doc.color_depth) for font in self._document.font_map.values(): - s += unicode_type(font) + s += str(font) s += '\n' return s @@ -1224,13 +1216,12 @@ class TOCObject(LRFStream): c -= 1 def __iter__(self): - for i in self._contents: - yield i + yield from self._contents def __str__(self): s = '\n' for i in self: - s += unicode_type(i) + s += str(i) return 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 f38c2253b1..79ee5ba864 100644 --- a/src/calibre/ebooks/lrf/pylrs/elements.py +++ b/src/calibre/ebooks/lrf/pylrs/elements.py @@ -1,8 +1,6 @@ - - """ elements.py -- replacements and helpers for ElementTree """ -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes class ElementWriter: @@ -25,9 +23,9 @@ class ElementWriter: return text def _writeAttribute(self, f, name, value): - f.write(' %s="' % unicode_type(name)) + f.write(' %s="' % str(name)) if not isinstance(value, string_or_bytes): - value = unicode_type(value) + value = str(value) value = self._encodeCdata(value) value = value.replace('"', '"') f.write(value) @@ -38,7 +36,7 @@ class ElementWriter: f.write(text) def _write(self, f, e): - f.write('<' + unicode_type(e.tag)) + f.write('<' + str(e.tag)) attributes = e.items() attributes.sort() diff --git a/src/calibre/ebooks/lrf/pylrs/pylrf.py b/src/calibre/ebooks/lrf/pylrs/pylrf.py index 3a9c73bb14..91889b14ae 100644 --- a/src/calibre/ebooks/lrf/pylrs/pylrf.py +++ b/src/calibre/ebooks/lrf/pylrs/pylrf.py @@ -12,7 +12,7 @@ import codecs import os from .pylrfopt import tagListOptimizer -from polyglot.builtins import iteritems, string_or_bytes, unicode_type +from polyglot.builtins import iteritems, string_or_bytes PYLRF_VERSION = "1.0" @@ -85,7 +85,7 @@ def writeWord(f, word): if int(word) > 65535: raise LrfError('Cannot encode a number greater than 65535 in a word.') if int(word) < 0: - raise LrfError('Cannot encode a number < 0 in a word: '+unicode_type(word)) + raise LrfError('Cannot encode a number < 0 in a word: '+str(word)) f.write(struct.pack(" @@ -54,7 +52,7 @@ DEFAULT_GENREADING = "fs" # default is yes to both lrf and lrs from calibre import __appname__, __version__ from calibre import entity_to_unicode -from polyglot.builtins import string_or_bytes, unicode_type, iteritems, native_string_type +from polyglot.builtins import string_or_bytes, iteritems, native_string_type class LrsError(Exception): @@ -229,7 +227,7 @@ class LrsAttributes: raise LrsError("%s does not support setting %s" % (self.__class__.__name__, name)) if isinstance(value, int): - value = unicode_type(value) + value = str(value) self.attrs[name] = value @@ -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: @@ -333,13 +330,13 @@ class LrsObject: def lrsObjectElement(self, name, objlabel="objlabel", labelName=None, labelDecorate=True, **settings): element = Element(name) - element.attrib["objid"] = unicode_type(self.objId) + element.attrib["objid"] = str(self.objId) if labelName is None: labelName = name if labelDecorate: label = "%s.%d" % (labelName, self.objId) else: - label = unicode_type(self.objId) + label = str(self.objId) element.attrib[objlabel] = label element.attrib.update(settings) return element @@ -565,7 +562,7 @@ class Book(Delegator): factor = base_font_size / old_base_font_size def rescale(old): - return unicode_type(int(int(old) * factor)) + return str(int(int(old) * factor)) text_blocks = list(main.get_all(lambda x: isinstance(x, TextBlock))) for tb in text_blocks: @@ -696,7 +693,7 @@ class TableOfContents: def addTocEntry(self, tocLabel, textBlock): if not isinstance(textBlock, (Canvas, TextBlock, ImageBlock, RuledLine)): raise LrsError("TOC destination must be a Canvas, TextBlock, ImageBlock or RuledLine"+ - " not a " + unicode_type(type(textBlock))) + " not a " + str(type(textBlock))) if textBlock.parent is None: raise LrsError("TOC text block must be already appended to a page") @@ -746,8 +743,8 @@ class TocLabel: def toElement(self, se): return ElementWithText("TocLabel", self.label, - refobj=unicode_type(self.textBlock.objId), - refpage=unicode_type(self.textBlock.parent.objId)) + refobj=str(self.textBlock.objId), + refpage=str(self.textBlock.parent.objId)) class BookInfo: @@ -808,7 +805,7 @@ class DocInfo: self.thumbnail = None self.language = "en" self.creator = None - self.creationdate = unicode_type(isoformat(date.today())) + self.creationdate = str(isoformat(date.today())) self.producer = "%s v%s"%(__appname__, __version__) self.numberofpages = "0" @@ -832,7 +829,7 @@ class DocInfo: docInfo.append(ElementWithText("Creator", self.creator)) docInfo.append(ElementWithText("CreationDate", self.creationdate)) docInfo.append(ElementWithText("Producer", self.producer)) - docInfo.append(ElementWithText("SumPage", unicode_type(self.numberofpages))) + docInfo.append(ElementWithText("SumPage", str(self.numberofpages))) return docInfo @@ -1094,7 +1091,7 @@ class LrsStyle(LrsObject, LrsAttributes, LrsContainer): self.elementName = elementName self.objectsAppended = False # self.label = "%s.%d" % (elementName, self.objId) - # self.label = unicode_type(self.objId) + # self.label = str(self.objId) # self.parent = None def update(self, settings): @@ -1104,11 +1101,11 @@ class LrsStyle(LrsObject, LrsAttributes, LrsContainer): self.attrs[name] = value def getLabel(self): - return unicode_type(self.objId) + return str(self.objId) def toElement(self, se): element = Element(self.elementName, stylelabel=self.getLabel(), - objid=unicode_type(self.objId)) + objid=str(self.objId)) element.attrib.update(self.attrs) return element @@ -1236,14 +1233,14 @@ class PageStyle(LrsStyle): del settings[evenbase] if evenObj.parent is None: parent.append(evenObj) - settings[evenbase + "id"] = unicode_type(evenObj.objId) + settings[evenbase + "id"] = str(evenObj.objId) if oddbase in settings: oddObj = settings[oddbase] del settings[oddbase] if oddObj.parent is None: parent.append(oddObj) - settings[oddbase + "id"] = unicode_type(oddObj.objId) + settings[oddbase + "id"] = str(oddObj.objId) def appendReferencedObjects(self, parent): if self.objectsAppended: @@ -1486,7 +1483,7 @@ class Paragraph(LrsContainer): def __init__(self, text=None): LrsContainer.__init__(self, [Text, CR, DropCaps, CharButton, - LrsSimpleChar1, bytes, unicode_type]) + LrsSimpleChar1, bytes, str]) if text is not None: if isinstance(text, string_or_bytes): text = Text(text) @@ -1521,7 +1518,7 @@ class Paragraph(LrsContainer): class LrsTextTag(LrsContainer): def __init__(self, text, validContents): - LrsContainer.__init__(self, [Text, bytes, unicode_type] + validContents) + LrsContainer.__init__(self, [Text, bytes, str] + validContents) if text is not None: self.append(text) @@ -1580,7 +1577,7 @@ class DropCaps(LrsTextTag): return self.text is None or not self.text.strip() def toElement(self, se): - elem = Element('DrawChar', line=unicode_type(self.line)) + elem = Element('DrawChar', line=str(self.line)) appendTextElements(elem, self.contents, se) return elem @@ -1656,7 +1653,7 @@ class JumpTo(LrsContainer): self.textBlock = textBlock def toElement(self, se): - return Element("JumpTo", refpage=unicode_type(self.textBlock.parent.objId), refobj=unicode_type(self.textBlock.objId)) + return Element("JumpTo", refpage=str(self.textBlock.parent.objId), refobj=str(self.textBlock.objId)) class Plot(LrsSimpleChar1, LrsContainer): @@ -1688,8 +1685,8 @@ class Plot(LrsSimpleChar1, LrsContainer): parent.append(self.obj) def toElement(self, se): - elem = Element('Plot', xsize=unicode_type(self.xsize), ysize=unicode_type(self.ysize), - refobj=unicode_type(self.obj.objId)) + elem = Element('Plot', xsize=str(self.xsize), ysize=str(self.ysize), + refobj=str(self.obj.objId)) if self.adjustment: elem.set('adjustment', self.adjustment) return elem @@ -1771,7 +1768,7 @@ class Space(LrsSimpleChar1, LrsContainer): if self.xsize == 0: return - return Element("Space", xsize=unicode_type(self.xsize)) + return Element("Space", xsize=str(self.xsize)) def toLrfContainer(self, lrfWriter, container): if self.xsize != 0: @@ -1785,7 +1782,7 @@ class Box(LrsSimpleChar1, LrsContainer): """ def __init__(self, linetype="solid"): - LrsContainer.__init__(self, [Text, bytes, unicode_type]) + LrsContainer.__init__(self, [Text, bytes, str]) if linetype not in LINE_TYPE_ENCODING: raise LrsError(linetype + " is not a valid line type") self.linetype = linetype @@ -1805,7 +1802,7 @@ class Box(LrsSimpleChar1, LrsContainer): class Span(LrsSimpleChar1, LrsContainer): def __init__(self, text=None, **attrs): - LrsContainer.__init__(self, [LrsSimpleChar1, Text, bytes, unicode_type]) + LrsContainer.__init__(self, [LrsSimpleChar1, Text, bytes, str]) if text is not None: if isinstance(text, string_or_bytes): text = Text(text) @@ -1858,7 +1855,7 @@ class Span(LrsSimpleChar1, LrsContainer): def toElement(self, se): element = Element('Span') for (key, value) in self.attrs.items(): - element.set(key, unicode_type(value)) + element.set(key, str(value)) appendTextElements(element, self.contents, se) return element @@ -1871,9 +1868,9 @@ class EmpLine(LrsTextTag, LrsSimpleChar1): def __init__(self, text=None, emplineposition='before', emplinetype='solid'): LrsTextTag.__init__(self, text, [LrsSimpleChar1]) if emplineposition not in self.__class__.emplinepositions: - raise LrsError('emplineposition for an EmpLine must be one of: '+unicode_type(self.__class__.emplinepositions)) + raise LrsError('emplineposition for an EmpLine must be one of: '+str(self.__class__.emplinepositions)) if emplinetype not in self.__class__.emplinetypes: - raise LrsError('emplinetype for an EmpLine must be one of: '+unicode_type(self.__class__.emplinetypes)) + raise LrsError('emplinetype for an EmpLine must be one of: '+str(self.__class__.emplinetypes)) self.emplinetype = emplinetype self.emplineposition = emplineposition @@ -1933,9 +1930,9 @@ class BlockSpace(LrsContainer): element = Element("BlockSpace") if self.xspace != 0: - element.attrib["xspace"] = unicode_type(self.xspace) + element.attrib["xspace"] = str(self.xspace) if self.yspace != 0: - element.attrib["yspace"] = unicode_type(self.yspace) + element.attrib["yspace"] = str(self.yspace) return element @@ -1949,7 +1946,7 @@ class CharButton(LrsSimpleChar1, LrsContainer): """ def __init__(self, button, text=None): - LrsContainer.__init__(self, [bytes, unicode_type, Text, LrsSimpleChar1]) + LrsContainer.__init__(self, [bytes, str, Text, LrsSimpleChar1]) self.button = None if button is not None: self.setButton(button) @@ -1979,7 +1976,7 @@ class CharButton(LrsSimpleChar1, LrsContainer): container.appendLrfTag(LrfTag("CharButtonEnd")) def toElement(self, se): - cb = Element("CharButton", refobj=unicode_type(self.button.objId)) + cb = Element("CharButton", refobj=str(self.button.objId)) appendTextElements(cb, self.contents, se) return cb @@ -2081,8 +2078,8 @@ class JumpButton(LrsObject, LrsContainer): b = self.lrsObjectElement("Button") pb = SubElement(b, "PushButton") SubElement(pb, "JumpTo", - refpage=unicode_type(self.textBlock.parent.objId), - refobj=unicode_type(self.textBlock.objId)) + refpage=str(self.textBlock.parent.objId), + refobj=str(self.textBlock.objId)) return b @@ -2230,8 +2227,8 @@ class PutObj(LrsContainer): self.content.objId))) def toElement(self, se): - el = Element("PutObj", x1=unicode_type(self.x1), y1=unicode_type(self.y1), - refobj=unicode_type(self.content.objId)) + el = Element("PutObj", x1=str(self.x1), y1=str(self.y1), + refobj=str(self.content.objId)) return el @@ -2313,9 +2310,9 @@ class Image(LrsObject, LrsContainer, LrsAttributes): def toElement(self, se): element = self.lrsObjectElement("Image", **self.attrs) - element.set("refstream", unicode_type(self.refstream.objId)) + element.set("refstream", str(self.refstream.objId)) for name in ["x0", "y0", "x1", "y1", "xsize", "ysize"]: - element.set(name, unicode_type(getattr(self, name))) + element.set(name, str(getattr(self, name))) return element def toLrf(self, lrfWriter): @@ -2396,9 +2393,9 @@ class ImageBlock(LrsObject, LrsContainer, LrsAttributes): def toElement(self, se): element = self.lrsObjectElement("ImageBlock", **self.attrs) - element.set("refstream", unicode_type(self.refstream.objId)) + element.set("refstream", str(self.refstream.objId)) for name in ["x0", "y0", "x1", "y1", "xsize", "ysize"]: - element.set(name, unicode_type(getattr(self, name))) + element.set(name, str(getattr(self, name))) element.text = self.alttext return element diff --git a/src/calibre/ebooks/lrf/tags.py b/src/calibre/ebooks/lrf/tags.py index 9005217665..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 ' '''''' @@ -7,7 +5,6 @@ __copyright__ = '2008, Kovid Goyal ' import struct from calibre.ebooks.lrf import LRFParseError -from polyglot.builtins import unicode_type class Tag: @@ -198,7 +195,7 @@ class Tag: self.id = 0xF500 + tag_id[0] size, self.name = self.__class__.tags[tag_id[0]] - if isinstance(size, unicode_type): + if isinstance(size, str): parser = getattr(self, size + '_parser') self.contents = parser(stream) else: @@ -241,7 +238,7 @@ class Tag: @classmethod def string_parser(self, stream): size = struct.unpack("= 4000 or int(num) != num: - return unicode_type(num) + return str(num) result = [] for d, r in coding: while num >= d: @@ -222,7 +222,7 @@ def fmt_sidx(i, fmt='%.2f', use_roman=False): try: i = float(i) except Exception: - return unicode_type(i) + return str(i) if int(i) == float(i): return roman(int(i)) if use_roman else '%d'%int(i) return fmt%i @@ -242,7 +242,7 @@ class Resource: ''' - def __init__(self, href_or_path, basedir=getcwd(), is_path=True): + def __init__(self, href_or_path, basedir=os.getcwd(), is_path=True): self._href = None self._basedir = basedir self.path = None @@ -266,7 +266,7 @@ class Resource: self._href = href_or_path else: pc = url[2] - if isinstance(pc, unicode_type): + if isinstance(pc, str): pc = pc.encode('utf-8') pc = unquote(pc).decode('utf-8') self.path = os.path.abspath(os.path.join(basedir, pc.replace('/', os.sep))) @@ -284,10 +284,10 @@ class Resource: if self._basedir: basedir = self._basedir else: - basedir = getcwd() + basedir = os.getcwd() if self.path is None: return self._href - f = self.fragment.encode('utf-8') if isinstance(self.fragment, unicode_type) else self.fragment + f = self.fragment.encode('utf-8') if isinstance(self.fragment, str) else self.fragment frag = '#'+as_unicode(quote(f)) if self.fragment else '' if self.path == basedir: return ''+frag @@ -295,7 +295,7 @@ class Resource: rpath = relpath(self.path, basedir) except OSError: # On windows path and basedir could be on different drives rpath = self.path - if isinstance(rpath, unicode_type): + if isinstance(rpath, str): rpath = rpath.encode('utf-8') return as_unicode(quote(rpath.replace(os.sep, '/')))+frag @@ -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) @@ -332,7 +331,7 @@ class ResourceCollection: return '[%s]'%', '.join(resources) def __repr__(self): - return unicode_type(self) + return str(self) def append(self, resource): if not isinstance(resource, Resource): diff --git a/src/calibre/ebooks/metadata/archive.py b/src/calibre/ebooks/metadata/archive.py index b04c1bdb35..25831ad9b2 100644 --- a/src/calibre/ebooks/metadata/archive.py +++ b/src/calibre/ebooks/metadata/archive.py @@ -11,7 +11,6 @@ from contextlib import closing from calibre.customize import FileTypePlugin from calibre.utils.localization import canonicalize_lang -from polyglot.builtins import filter, unicode_type def is_comic(list_of_names): @@ -157,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 @@ -170,7 +169,7 @@ def get_comic_book_info(d, mi, series_index='volume'): from datetime import date try: dt = date(puby, 6 if pubm is None else pubm, 15) - dt = parse_only_date(unicode_type(dt)) + dt = parse_only_date(str(dt)) mi.pubdate = dt except Exception: pass diff --git a/src/calibre/ebooks/metadata/author_mapper.py b/src/calibre/ebooks/metadata/author_mapper.py index 922ca7770c..efffaa6fc4 100644 --- a/src/calibre/ebooks/metadata/author_mapper.py +++ b/src/calibre/ebooks/metadata/author_mapper.py @@ -7,7 +7,6 @@ import re from collections import deque from calibre.utils.icu import capitalize, lower, upper -from polyglot.builtins import filter, unicode_type def cap_author_token(token): @@ -161,9 +160,9 @@ def find_tests(): def run(rules, authors, expected): if isinstance(rules, dict): rules = [rules] - if isinstance(authors, unicode_type): + if isinstance(authors, str): authors = [x.strip() for x in authors.split('&')] - if isinstance(expected, unicode_type): + if isinstance(expected, str): expected = [x.strip() for x in expected.split('&')] ans = map_authors(authors, compile_rules(rules)) self.assertEqual(ans, expected) diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index f3f20c224a..b547d68dc5 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -15,7 +15,7 @@ from calibre.ebooks.metadata.book import (SC_COPYABLE_FIELDS, TOP_LEVEL_IDENTIFIERS, ALL_METADATA_FIELDS) from calibre.library.field_metadata import FieldMetadata from calibre.utils.icu import sort_key -from polyglot.builtins import iteritems, unicode_type, filter, map, string_or_bytes +from polyglot.builtins import iteritems, string_or_bytes # Special sets used to optimize the performance of getting and setting # attributes on Metadata objects @@ -28,7 +28,7 @@ def human_readable(size, precision=2): ans = size/(1024*1024) if ans < 0.1: return '<0.1MB' - return ('%.'+unicode_type(precision)+'f'+ 'MB') % ans + return ('%.'+str(precision)+'f'+ 'MB') % ans NULL_VALUES = { @@ -626,14 +626,14 @@ class Metadata: return authors_to_string(self.authors) def format_tags(self): - return ', '.join([unicode_type(t) for t in sorted(self.tags, key=sort_key)]) + return ', '.join([str(t) for t in sorted(self.tags, key=sort_key)]) def format_rating(self, v=None, divide_by=1): if v is None: if self.rating is not None: - return unicode_type(self.rating/divide_by) + return str(self.rating/divide_by) return 'None' - return unicode_type(v/divide_by) + return str(v/divide_by) def format_field(self, key, series_with_index=True): ''' @@ -657,15 +657,15 @@ class Metadata: if cmeta and cmeta['datatype'] == 'series': if self.get(tkey): res = self.get_extra(tkey) - return (unicode_type(cmeta['name']+'_index'), + return (str(cmeta['name']+'_index'), self.format_series_index(res), res, cmeta) else: - return (unicode_type(cmeta['name']+'_index'), '', '', cmeta) + return (str(cmeta['name']+'_index'), '', '', cmeta) if key in self.custom_field_keys(): res = self.get(key, None) # get evaluates all necessary composites cmeta = self.get_user_metadata(key, make_copy=False) - name = unicode_type(cmeta['name']) + name = str(cmeta['name']) if res is None or res == '': # can't check "not res" because of numeric fields return (name, res, None, None) orig_res = res @@ -688,7 +688,7 @@ class Metadata: res = fmt.format(res) except: pass - return (name, unicode_type(res), orig_res, cmeta) + return (name, str(res), orig_res, cmeta) # convert top-level ids into their value if key in TOP_LEVEL_IDENTIFIERS: @@ -702,11 +702,11 @@ class Metadata: if fmkey in field_metadata and field_metadata[fmkey]['kind'] == 'field': res = self.get(key, None) fmeta = field_metadata[fmkey] - name = unicode_type(fmeta['name']) + name = str(fmeta['name']) if res is None or res == '': return (name, res, None, None) orig_res = res - name = unicode_type(fmeta['name']) + name = str(fmeta['name']) datatype = fmeta['datatype'] if key == 'authors': res = authors_to_string(res) @@ -724,7 +724,7 @@ class Metadata: res = '%.2g'%(res/2) elif key == 'size': res = human_readable(res) - return (name, unicode_type(res), orig_res, fmeta) + return (name, str(res), orig_res, fmeta) return (None, None, None, None) @@ -738,7 +738,7 @@ class Metadata: ans = [] def fmt(x, y): - ans.append('%-20s: %s'%(unicode_type(x), unicode_type(y))) + ans.append('%-20s: %s'%(str(x), str(y))) fmt('Title', self.title) if self.title_sort: @@ -752,7 +752,7 @@ class Metadata: if getattr(self, 'book_producer', False): fmt('Book Producer', self.book_producer) if self.tags: - fmt('Tags', ', '.join([unicode_type(t) for t in self.tags])) + fmt('Tags', ', '.join([str(t) for t in self.tags])) if self.series: fmt('Series', self.series + ' #%s'%self.format_series_index()) if not self.is_null('languages'): @@ -765,7 +765,7 @@ class Metadata: if self.pubdate is not None: fmt('Published', isoformat(self.pubdate)) if self.rights is not None: - fmt('Rights', unicode_type(self.rights)) + fmt('Rights', str(self.rights)) if self.identifiers: fmt('Identifiers', ', '.join(['%s:%s'%(k, v) for k, v in iteritems(self.identifiers)])) @@ -776,7 +776,7 @@ class Metadata: val = self.get(key, None) if val: (name, val) = self.format_field(key) - fmt(name, unicode_type(val)) + fmt(name, str(val)) return '\n'.join(ans) def to_html(self): @@ -785,22 +785,22 @@ class Metadata: ''' from calibre.ebooks.metadata import authors_to_string from calibre.utils.date import isoformat - ans = [(_('Title'), unicode_type(self.title))] + ans = [(_('Title'), str(self.title))] ans += [(_('Author(s)'), (authors_to_string(self.authors) if self.authors else _('Unknown')))] - ans += [(_('Publisher'), unicode_type(self.publisher))] - ans += [(_('Producer'), unicode_type(self.book_producer))] - ans += [(_('Comments'), unicode_type(self.comments))] - ans += [('ISBN', unicode_type(self.isbn))] - ans += [(_('Tags'), ', '.join([unicode_type(t) for t in self.tags]))] + ans += [(_('Publisher'), str(self.publisher))] + ans += [(_('Producer'), str(self.book_producer))] + ans += [(_('Comments'), str(self.comments))] + ans += [('ISBN', str(self.isbn))] + ans += [(_('Tags'), ', '.join([str(t) for t in self.tags]))] if self.series: - ans += [(ngettext('Series', 'Series', 1), unicode_type(self.series) + ' #%s'%self.format_series_index())] + ans += [(ngettext('Series', 'Series', 1), str(self.series) + ' #%s'%self.format_series_index())] ans += [(_('Languages'), ', '.join(self.languages))] if self.timestamp is not None: - ans += [(_('Timestamp'), unicode_type(isoformat(self.timestamp, as_utc=False, sep=' ')))] + ans += [(_('Timestamp'), str(isoformat(self.timestamp, as_utc=False, sep=' ')))] if self.pubdate is not None: - ans += [(_('Published'), unicode_type(isoformat(self.pubdate, as_utc=False, sep=' ')))] + ans += [(_('Published'), str(isoformat(self.pubdate, as_utc=False, sep=' ')))] if self.rights is not None: - ans += [(_('Rights'), unicode_type(self.rights))] + ans += [(_('Rights'), str(self.rights))] for key in self.custom_field_keys(): val = self.get(key, None) if val: 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 2cb9ee201a..c4912894f2 100644 --- a/src/calibre/ebooks/metadata/book/render.py +++ b/src/calibre/ebooks/metadata/book/render.py @@ -19,7 +19,6 @@ from calibre.utils.formatter import EvalFormatter from calibre.utils.date import is_date_undefined from calibre.utils.localization import calibre_langcode_to_name from calibre.utils.serialize import json_dumps -from polyglot.builtins import filter from polyglot.binary import as_hex_unicode default_sort = ('title', 'title_sort', 'authors', 'author_sort', 'series', 'rating', 'pubdate', 'tags', 'publisher', 'identifiers') @@ -98,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) @@ -148,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': @@ -173,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 = '' @@ -209,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': @@ -242,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 @@ -309,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))) @@ -320,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__ def __repr__(self): - return unicode_type(self) + return str(self) def __getitem__(self, index): if index == 0: @@ -386,7 +385,7 @@ class Guide(ResourceCollection): # {{{ return ans + '/>' @staticmethod - def from_opf_guide(references, base_dir=getcwd()): + def from_opf_guide(references, base_dir=os.getcwd()): coll = Guide() for ref in references: try: @@ -411,7 +410,7 @@ class Guide(ResourceCollection): # {{{ class MetadataField: def __init__(self, name, is_dc=True, formatter=None, none_is=None, - renderer=lambda x: unicode_type(x)): + renderer=lambda x: str(x)): self.name = name self.is_dc = is_dc self.formatter = formatter @@ -587,7 +586,7 @@ class OPF: # {{{ author_link_map = MetadataField('author_link_map', is_dc=False, formatter=json.loads, renderer=dump_dict) - def __init__(self, stream, basedir=getcwd(), unquote_urls=True, + def __init__(self, stream, basedir=os.getcwd(), unquote_urls=True, populate_spine=True, try_to_guess_cover=True, preparsed_opf=None, read_toc=True): self.try_to_guess_cover = try_to_guess_cover self.basedir = self.base_dir = basedir @@ -811,7 +810,7 @@ class OPF: # {{{ def unquote_urls(self): def get_href(item): raw = unquote(item.get('href', '')) - if not isinstance(raw, unicode_type): + if not isinstance(raw, str): raw = raw.decode('utf-8') return raw for item in self.itermanifest(): @@ -840,7 +839,7 @@ class OPF: # {{{ titles = () if val: title = titles[0] if titles else self.create_metadata_element('title') - title.text = re.sub(r'\s+', ' ', unicode_type(val)) + title.text = re.sub(r'\s+', ' ', str(val)) @property def authors(self): @@ -883,7 +882,7 @@ class OPF: # {{{ for key in matches[0].attrib: if key.endswith('file-as'): matches[0].attrib.pop(key) - matches[0].set('{%s}file-as'%self.NAMESPACES['opf'], unicode_type(val)) + matches[0].set('{%s}file-as'%self.NAMESPACES['opf'], str(val)) @property def tags(self): @@ -900,7 +899,7 @@ class OPF: # {{{ tag.getparent().remove(tag) for tag in val: elem = self.create_metadata_element('subject') - self.set_text(elem, unicode_type(tag)) + self.set_text(elem, str(tag)) @property def pubdate(self): @@ -956,7 +955,7 @@ class OPF: # {{{ xid = x.get('id', None) is_package_identifier = uuid_id is not None and uuid_id == xid if is_package_identifier: - self.set_text(x, unicode_type(uuid.uuid4())) + self.set_text(x, str(uuid.uuid4())) for attr in x.attrib: if attr.endswith('scheme'): x.attrib[attr] = 'uuid' @@ -967,7 +966,7 @@ class OPF: # {{{ attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'ISBN'} matches = [self.create_metadata_element('identifier', attrib=attrib)] - self.set_text(matches[0], unicode_type(val)) + self.set_text(matches[0], str(val)) def get_identifiers(self): identifiers = {} @@ -1030,7 +1029,7 @@ class OPF: # {{{ for typ, val in iteritems(identifiers): attrib = {'{%s}scheme'%self.NAMESPACES['opf']: typ.upper()} self.set_text(self.create_metadata_element( - 'identifier', attrib=attrib), unicode_type(val)) + 'identifier', attrib=attrib), str(val)) @property def application_id(self): @@ -1053,7 +1052,7 @@ class OPF: # {{{ if uuid_id and uuid_id in removed_ids: attrib['id'] = uuid_id self.set_text(self.create_metadata_element( - 'identifier', attrib=attrib), unicode_type(val)) + 'identifier', attrib=attrib), str(val)) @property def uuid(self): @@ -1067,7 +1066,7 @@ class OPF: # {{{ attrib = {'{%s}scheme'%self.NAMESPACES['opf']: 'uuid'} matches = [self.create_metadata_element('identifier', attrib=attrib)] - self.set_text(matches[0], unicode_type(val)) + self.set_text(matches[0], str(val)) @property def language(self): @@ -1098,7 +1097,7 @@ class OPF: # {{{ for lang in val: l = self.create_metadata_element('language') - self.set_text(l, unicode_type(lang)) + self.set_text(l, str(lang)) @property def raw_languages(self): @@ -1118,11 +1117,10 @@ class OPF: # {{{ if not matches: matches = [self.create_metadata_element('contributor')] matches[0].set('{%s}role'%self.NAMESPACES['opf'], 'bkp') - self.set_text(matches[0], unicode_type(val)) + 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): @@ -1381,7 +1379,7 @@ class OPFCreator(Metadata): self.page_progression_direction = None self.primary_writing_mode = None if self.application_id is None: - self.application_id = unicode_type(uuid.uuid4()) + self.application_id = str(uuid.uuid4()) if not isinstance(self.toc, TOC): self.toc = None if not self.authors: @@ -1505,7 +1503,7 @@ class OPFCreator(Metadata): a(DC_ELEM('contributor', '%s (%s) [%s]'%(__appname__, __version__, 'https://calibre-ebook.com'), opf_attrs={'role':'bkp', 'file-as':__appname__})) - a(DC_ELEM('identifier', unicode_type(self.application_id), + a(DC_ELEM('identifier', str(self.application_id), opf_attrs={'scheme':__appname__}, dc_attrs={'id':__appname__+'_id'})) if getattr(self, 'pubdate', None) is not None: @@ -1533,7 +1531,7 @@ class OPFCreator(Metadata): if self.title_sort: a(CAL_ELEM('calibre:title_sort', self.title_sort)) if self.rating is not None: - a(CAL_ELEM('calibre:rating', unicode_type(self.rating))) + a(CAL_ELEM('calibre:rating', str(self.rating))) if self.timestamp is not None: a(CAL_ELEM('calibre:timestamp', self.timestamp.isoformat())) if self.publication_type is not None: @@ -1550,7 +1548,7 @@ class OPFCreator(Metadata): href = ref.href() if isinstance(href, bytes): href = href.decode('utf-8') - item = E.item(id=unicode_type(ref.id), href=href) + item = E.item(id=str(ref.id), href=href) item.set('media-type', ref.mime_type) manifest.append(item) spine = E.spine() @@ -1601,10 +1599,10 @@ def metadata_to_opf(mi, as_string=True, default_lang=None): from calibre.ebooks.oeb.base import OPF, DC if not mi.application_id: - mi.application_id = unicode_type(uuid.uuid4()) + mi.application_id = str(uuid.uuid4()) if not mi.uuid: - mi.uuid = unicode_type(uuid.uuid4()) + mi.uuid = str(uuid.uuid4()) if not mi.book_producer: mi.book_producer = __appname__ + ' (%s) '%__version__ + \ @@ -1685,7 +1683,7 @@ def metadata_to_opf(mi, as_string=True, default_lang=None): if mi.series_index is not None: meta('series_index', mi.format_series_index()) if mi.rating is not None: - meta('rating', unicode_type(mi.rating)) + meta('rating', str(mi.rating)) if hasattr(mi.timestamp, 'isoformat'): meta('timestamp', isoformat(mi.timestamp)) if mi.publication_type: @@ -1703,7 +1701,7 @@ def metadata_to_opf(mi, as_string=True, default_lang=None): metadata[-1].tail = '\n' +(' '*4) if mi.cover: - if not isinstance(mi.cover, unicode_type): + if not isinstance(mi.cover, str): mi.cover = mi.cover.decode(filesystem_encoding) guide.text = '\n'+(' '*8) r = guide.makeelement(OPF('reference'), @@ -1780,13 +1778,13 @@ def suite(): ''' ) - self.opf = OPF(self.stream, getcwd()) + self.opf = OPF(self.stream, os.getcwd()) 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']) @@ -1811,11 +1809,11 @@ def suite(): self.opf.render() def testCreator(self): - opf = OPFCreator(getcwd(), self.opf) + opf = OPFCreator(os.getcwd(), self.opf) buf = io.BytesIO() opf.render(buf) raw = buf.getvalue() - self.testReading(opf=OPF(io.BytesIO(raw), getcwd())) + self.testReading(opf=OPF(io.BytesIO(raw), os.getcwd())) def testSmartUpdate(self): self.opf.smart_update(MetaInformation(self.opf)) @@ -1832,16 +1830,16 @@ 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) - opfc = OPFCreator(getcwd(), other=mi) + opfc = OPFCreator(os.getcwd(), other=mi) out = io.BytesIO() opfc.render(out) raw2 = out.getvalue() diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py index 3c071fd2e3..46f947fa6a 100644 --- a/src/calibre/ebooks/metadata/opf3.py +++ b/src/calibre/ebooks/metadata/opf3.py @@ -7,7 +7,7 @@ import json import re from collections import defaultdict, namedtuple from functools import wraps -from polyglot.builtins import iteritems, map, filter +from polyglot.builtins import iteritems from lxml import etree @@ -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 8e4733bd7c..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''' @@ -13,7 +11,7 @@ from calibre.ptempfile import TemporaryDirectory from calibre.ebooks.metadata import ( MetaInformation, string_to_authors, check_isbn, check_doi) from calibre.utils.ipc.simple_worker import fork_job, WorkerError -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def get_tools(): @@ -90,8 +88,8 @@ def page_images(pdfpath, outputdir='.', first=1, last=1, image_format='jpeg', pr args['creationflags'] = subprocess.HIGH_PRIORITY_CLASS | subprocess.CREATE_NO_WINDOW try: subprocess.check_call([ - pdftoppm, '-cropbox', '-' + image_format, '-f', unicode_type(first), - '-l', unicode_type(last), pdfpath, os.path.join(outputdir, prefix) + pdftoppm, '-cropbox', '-' + image_format, '-f', str(first), + '-l', str(last), pdfpath, os.path.join(outputdir, prefix) ], **args) except subprocess.CalledProcessError as e: raise ValueError('Failed to render PDF, pdftoppm errorcode: %s'%e.returncode) diff --git a/src/calibre/ebooks/metadata/plucker.py b/src/calibre/ebooks/metadata/plucker.py index 89deaa40a6..0403879a4b 100644 --- a/src/calibre/ebooks/metadata/plucker.py +++ b/src/calibre/ebooks/metadata/plucker.py @@ -16,7 +16,6 @@ from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.pdb.header import PdbHeaderReader from calibre.ebooks.pdb.plucker.reader import SectionHeader, DATATYPE_METADATA, \ MIBNUM_TO_NAME -from polyglot.builtins import range def get_metadata(stream, extract_cover=True): diff --git a/src/calibre/ebooks/metadata/rb.py b/src/calibre/ebooks/metadata/rb.py index 9869f2cd30..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''' @@ -8,7 +6,6 @@ import sys, struct from calibre import prints from calibre.ebooks.metadata import MetaInformation, string_to_authors -from polyglot.builtins import unicode_type MAGIC = b'\xb0\x0c\xb0\x0c\x02\x00NUVO\x00\x00\x00\x00' @@ -49,7 +46,7 @@ def get_metadata(stream): elif key.strip() == 'AUTHOR': mi.authors = string_to_authors(value) except Exception as err: - msg = 'Couldn\'t read metadata from rb: %s with error %s'%(mi.title, unicode_type(err)) + msg = 'Couldn\'t read metadata from rb: %s with error %s'%(mi.title, str(err)) prints(msg, file=sys.stderr) raise return mi diff --git a/src/calibre/ebooks/metadata/rtf.py b/src/calibre/ebooks/metadata/rtf.py index f425137321..799a166e19 100644 --- a/src/calibre/ebooks/metadata/rtf.py +++ b/src/calibre/ebooks/metadata/rtf.py @@ -11,7 +11,7 @@ import re from calibre import force_unicode from calibre.ebooks.metadata import MetaInformation -from polyglot.builtins import codepoint_to_chr, string_or_bytes, unicode_type, int_to_byte, filter +from polyglot.builtins import codepoint_to_chr, string_or_bytes, int_to_byte title_pat = re.compile(br'\{\\info.*?\{\\title(.*?)(? 1: diff --git a/src/calibre/ebooks/metadata/sources/cli.py b/src/calibre/ebooks/metadata/sources/cli.py index 1c3f505ec8..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 ' @@ -20,7 +19,6 @@ from calibre.ebooks.metadata.sources.base import create_log from calibre.ebooks.metadata.sources.identify import identify from calibre.ebooks.metadata.sources.covers import download_cover from calibre.ebooks.metadata.sources.update import patch_plugins -from polyglot.builtins import unicode_type def option_parser(): @@ -104,7 +102,7 @@ def main(args=sys.argv): getattr(sys.stdout, 'buffer', sys.stdout).write(metadata_to_opf(result)) print() else: - prints(unicode_type(result)) + prints(str(result)) if not opts.opf and opts.cover: prints('Cover :', cf) diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py index 7e341e7e64..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 ' @@ -23,7 +22,7 @@ from calibre.utils.date import UNDEFINED_DATE, as_utc, utc_tz from calibre.utils.formatter import EvalFormatter from calibre.utils.html2text import html2text from calibre.utils.icu import lower, primary_sort_key -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues from polyglot.queue import Empty, Queue from polyglot.urllib import quote, urlparse @@ -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 @@ -470,7 +469,7 @@ def identify(log, abort, # {{{ for r in presults: log('\n\n---') try: - log(unicode_type(r)) + log(str(r)) except TypeError: log(repr(r)) if plog: @@ -554,7 +553,7 @@ def urls_from_identifiers(identifiers, sort_results=False): # {{{ for k, val in iteritems(identifiers): val = val.replace('|', ',') vals = { - 'id':unicode_type(quote(val if isinstance(val, bytes) else val.encode('utf-8'))), + 'id':str(quote(val if isinstance(val, bytes) else val.encode('utf-8'))), 'id_unquoted': str(val), } items = rules.get(k) or () diff --git a/src/calibre/ebooks/metadata/tag_mapper.py b/src/calibre/ebooks/metadata/tag_mapper.py index 740733fc4e..2c32d61bb1 100644 --- a/src/calibre/ebooks/metadata/tag_mapper.py +++ b/src/calibre/ebooks/metadata/tag_mapper.py @@ -5,8 +5,6 @@ from collections import deque -from polyglot.builtins import filter, unicode_type - def compile_pat(pat): import regex @@ -145,9 +143,9 @@ def find_tests(): def run(rules, tags, expected): if isinstance(rules, dict): rules = [rules] - if isinstance(tags, unicode_type): + if isinstance(tags, str): tags = [x.strip() for x in tags.split(',')] - if isinstance(expected, unicode_type): + if isinstance(expected, str): expected = [x.strip() for x in expected.split(',')] ans = map_tags(tags, rules) self.assertEqual(ans, expected) diff --git a/src/calibre/ebooks/metadata/toc.py b/src/calibre/ebooks/metadata/toc.py index a0dccc2274..b6558a560e 100644 --- a/src/calibre/ebooks/metadata/toc.py +++ b/src/calibre/ebooks/metadata/toc.py @@ -14,7 +14,6 @@ from calibre.constants import __appname__, __version__ from calibre.ebooks.chardet import xml_to_unicode from calibre.utils.xml_parse import safe_xml_fromstring from calibre.utils.cleantext import clean_xml_chars -from polyglot.builtins import unicode_type, getcwd from polyglot.urllib import unquote, urlparse NCX_NS = "http://www.daisy.org/z3986/2005/ncx/" @@ -47,7 +46,7 @@ def parse_html_toc(data): class TOC(list): def __init__(self, href=None, fragment=None, text=None, parent=None, - play_order=0, base_path=getcwd(), type='unknown', author=None, + play_order=0, base_path=os.getcwd(), type='unknown', author=None, description=None, toc_thumbnail=None): self.href = href self.fragment = fragment @@ -65,7 +64,7 @@ class TOC(list): def __str__(self): lines = ['TOC: %s#%s %s'%(self.href, self.fragment, self.text)] for child in self: - c = unicode_type(child).splitlines() + c = str(child).splitlines() for l in c: lines.append('\t'+l) return '\n'.join(lines) @@ -115,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): @@ -243,8 +241,8 @@ class TOC(list): def render(self, stream, uid): root = E.ncx( E.head( - E.meta(name='dtb:uid', content=unicode_type(uid)), - E.meta(name='dtb:depth', content=unicode_type(self.depth())), + E.meta(name='dtb:uid', content=str(uid)), + E.meta(name='dtb:depth', content=str(self.depth())), E.meta(name='dtb:generator', content='%s (%s)'%(__appname__, __version__)), E.meta(name='dtb:totalPageCount', content='0'), @@ -266,10 +264,10 @@ class TOC(list): text = clean_xml_chars(text) elem = E.navPoint( E.navLabel(E.text(re.sub(r'\s+', ' ', text))), - E.content(src=unicode_type(np.href)+(('#' + unicode_type(np.fragment)) + E.content(src=str(np.href)+(('#' + str(np.fragment)) if np.fragment else '')), id=item_id, - playOrder=unicode_type(np.play_order) + playOrder=str(np.play_order) ) au = getattr(np, 'author', None) if au: 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/utils.py b/src/calibre/ebooks/metadata/utils.py index 3bfff79b38..a0d815fe5e 100644 --- a/src/calibre/ebooks/metadata/utils.py +++ b/src/calibre/ebooks/metadata/utils.py @@ -11,7 +11,6 @@ from calibre.spell import parse_lang_code from calibre.utils.cleantext import clean_xml_chars from calibre.utils.localization import lang_as_iso639_1 from calibre.utils.xml_parse import safe_xml_fromstring -from polyglot.builtins import filter, map OPFVersion = namedtuple('OPFVersion', 'major minor patch') 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/xmp.py b/src/calibre/ebooks/metadata/xmp.py index af41279875..9f9a3f89ff 100644 --- a/src/calibre/ebooks/metadata/xmp.py +++ b/src/calibre/ebooks/metadata/xmp.py @@ -19,7 +19,7 @@ from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.opf2 import dump_dict from calibre.utils.date import parse_date, isoformat, now from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1 -from polyglot.builtins import iteritems, string_or_bytes, filter +from polyglot.builtins import iteritems, string_or_bytes _xml_declaration = re.compile(r'<\?xml[^<>]+encoding\s*=\s*[\'"](.*?)[\'"][^<>]*>', re.IGNORECASE) diff --git a/src/calibre/ebooks/metadata/zip.py b/src/calibre/ebooks/metadata/zip.py index 025e03e7f8..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 ' @@ -8,7 +6,6 @@ import os from calibre.utils.zipfile import ZipFile from calibre.ptempfile import TemporaryDirectory from calibre import CurrentDir -from polyglot.builtins import getcwd def get_metadata(stream): @@ -49,7 +46,7 @@ def zip_opf_metadata(opfpath, zf): from calibre.ebooks.metadata.opf2 import OPF if hasattr(opfpath, 'read'): f = opfpath - opfpath = getattr(f, 'name', getcwd()) + opfpath = getattr(f, 'name', os.getcwd()) else: f = open(opfpath, 'rb') opf = OPF(f, os.path.dirname(opfpath)) diff --git a/src/calibre/ebooks/mobi/debug/containers.py b/src/calibre/ebooks/mobi/debug/containers.py index beb558f4c5..0ee1cb92a3 100644 --- a/src/calibre/ebooks/mobi/debug/containers.py +++ b/src/calibre/ebooks/mobi/debug/containers.py @@ -8,7 +8,6 @@ __copyright__ = '2014, Kovid Goyal ' from struct import unpack_from from calibre.ebooks.mobi.debug.headers import EXTHHeader -from polyglot.builtins import filter, unicode_type class ContainerHeader: @@ -63,4 +62,4 @@ class ContainerHeader: a('Null bytes after EXTH: %d' % self.null_bytes_after_exth) if len(self.bytes_after_exth) != self.null_bytes_after_exth: a('Non-null bytes present after EXTH header!!!!') - return '\n'.join(ans) + '\n\n' + unicode_type(self.exth) + '\n\n' + ('Title: %s' % self.title) + return '\n'.join(ans) + '\n\n' + str(self.exth) + '\n\n' + ('Title: %s' % self.title) diff --git a/src/calibre/ebooks/mobi/debug/headers.py b/src/calibre/ebooks/mobi/debug/headers.py index 707ae3adac..b886bdc563 100644 --- a/src/calibre/ebooks/mobi/debug/headers.py +++ b/src/calibre/ebooks/mobi/debug/headers.py @@ -13,7 +13,7 @@ from calibre.ebooks.mobi.reader.headers import NULL_INDEX from calibre.ebooks.mobi.langcodes import main_language, sub_language from calibre.ebooks.mobi.debug import format_bytes from calibre.ebooks.mobi.utils import get_trailing_data -from polyglot.builtins import iteritems, range, unicode_type +from polyglot.builtins import iteritems # PalmDB {{{ @@ -43,7 +43,7 @@ class PalmDOCAttributes: self.val)) def __str__(self): - attrs = '\n\t'.join([unicode_type(x) for x in self.attributes]) + attrs = '\n\t'.join([str(x) for x in self.attributes]) return 'PalmDOC Attributes: %s\n\t%s'%(bin(self.val), attrs) __unicode__ = __str__ @@ -86,7 +86,7 @@ class PalmDB: def __str__(self): ans = ['*'*20 + ' PalmDB Header '+ '*'*20] ans.append('Name: %r'%self.name) - ans.append(unicode_type(self.attributes)) + ans.append(str(self.attributes)) ans.append('Version: %s'%self.version) ans.append('Creation date: %s (%s)'%(self.creation_date.isoformat(), self.creation_date_raw)) @@ -258,7 +258,7 @@ class EXTHHeader: ans.append('Number of EXTH records: %d'%self.count) ans.append('EXTH records...') for r in self.records: - ans.append(unicode_type(r)) + ans.append(str(r)) return '\n'.join(ans) __unicode__ = __str__ @@ -501,7 +501,7 @@ class MOBIHeader: # {{{ ans = '\n'.join(ans) if self.has_exth: - ans += '\n\n' + unicode_type(self.exth) + ans += '\n\n' + str(self.exth) ans += '\n\nBytes after EXTH (%d bytes): %s'%( len(self.bytes_after_exth), format_bytes(self.bytes_after_exth)) diff --git a/src/calibre/ebooks/mobi/debug/index.py b/src/calibre/ebooks/mobi/debug/index.py index 23fc92989a..d8ab38f3ac 100644 --- a/src/calibre/ebooks/mobi/debug/index.py +++ b/src/calibre/ebooks/mobi/debug/index.py @@ -14,7 +14,7 @@ from calibre.ebooks.mobi.reader.headers import NULL_INDEX from calibre.ebooks.mobi.reader.index import (CNCX, parse_indx_header, parse_tagx_section, parse_index_record, INDEX_HEADER_FIELDS) from calibre.ebooks.mobi.reader.ncx import (tag_fieldname_map, default_entry) -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems File = namedtuple('File', 'file_number name divtbl_count start_position length') @@ -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/debug/mobi6.py b/src/calibre/ebooks/mobi/debug/mobi6.py index b9fa965946..36c81749d4 100644 --- a/src/calibre/ebooks/mobi/debug/mobi6.py +++ b/src/calibre/ebooks/mobi/debug/mobi6.py @@ -19,7 +19,7 @@ from calibre.ebooks.mobi.utils import (decode_hex_number, decint, from calibre.utils.imghdr import what from calibre.ebooks.mobi.debug import format_bytes from calibre.ebooks.mobi.debug.headers import TextRecord -from polyglot.builtins import unicode_type, range, iteritems, as_bytes, print_to_binary_file +from polyglot.builtins import iteritems, as_bytes, print_to_binary_file class TagX: # {{{ @@ -368,7 +368,7 @@ class IndexEntry: # {{{ self.index, len(self.tags))] for tag in self.tags: if tag.value is not None: - ans.append('\t'+unicode_type(tag)) + ans.append('\t'+str(tag)) if self.first_child_index != -1: ans.append('\tNumber of children: %d'%(self.last_child_index - self.first_child_index + 1)) @@ -421,7 +421,7 @@ class IndexRecord: # {{{ len(w), not bool(w.replace(b'\0', b'')))) for entry in self.indices: offset = entry.offset - a(unicode_type(entry)) + a(str(entry)) t = self.alltext if offset is not None and self.alltext is not None: a('\tHTML before offset: %r'%t[offset-50:offset]) @@ -564,7 +564,7 @@ class TBSIndexing: # {{{ def get_index(self, idx): for i in self.indices: - if i.index in {idx, unicode_type(idx)}: + if i.index in {idx, str(idx)}: return i raise IndexError('Index %d not found'%idx) @@ -608,7 +608,7 @@ class TBSIndexing: # {{{ return as_bytes('0'*(4-len(ans)) + ans) def repr_extra(x): - return unicode_type({bin4(k):v for k, v in iteritems(extra)}) + return str({bin4(k):v for k, v in iteritems(extra)}) tbs_type = 0 is_periodical = self.doc_type in (257, 258, 259) @@ -789,14 +789,14 @@ class MOBIFile: # {{{ def print_header(self, f=sys.stdout): p = print_to_binary_file(f) - p(unicode_type(self.palmdb)) + p(str(self.palmdb)) p() p('Record headers:') for i, r in enumerate(self.records): p('%6d. %s'%(i, r.header)) p() - p(unicode_type(self.mobi_header)) + p(str(self.mobi_header)) # }}} @@ -822,20 +822,20 @@ def inspect_mobi(mobi_file, ddir): f.index_record.alltext = alltext with open(os.path.join(ddir, 'index.txt'), 'wb') as out: print = print_to_binary_file(out) - print(unicode_type(f.index_header), file=out) + print(str(f.index_header), file=out) print('\n\n', file=out) if f.secondary_index_header is not None: - print(unicode_type(f.secondary_index_header), file=out) + print(str(f.secondary_index_header), file=out) print('\n\n', file=out) if f.secondary_index_record is not None: - print(unicode_type(f.secondary_index_record), file=out) + print(str(f.secondary_index_record), file=out) print('\n\n', file=out) - print(unicode_type(f.cncx), file=out) + print(str(f.cncx), file=out) print('\n\n', file=out) - print(unicode_type(f.index_record), file=out) + print(str(f.index_record), file=out) with open(os.path.join(ddir, 'tbs_indexing.txt'), 'wb') as out: print = print_to_binary_file(out) - print(unicode_type(f.tbs_indexing), file=out) + print(str(f.tbs_indexing), file=out) f.tbs_indexing.dump(ddir) for tdir, attr in [('text', 'text_records'), ('images', 'image_records'), diff --git a/src/calibre/ebooks/mobi/debug/mobi8.py b/src/calibre/ebooks/mobi/debug/mobi8.py index c268510fbe..dd619db2ea 100644 --- a/src/calibre/ebooks/mobi/debug/mobi8.py +++ b/src/calibre/ebooks/mobi/debug/mobi8.py @@ -17,7 +17,7 @@ from calibre.ebooks.mobi.utils import read_font_record, decode_tbs, RECORD_SIZE from calibre.ebooks.mobi.debug import format_bytes from calibre.ebooks.mobi.reader.headers import NULL_INDEX from calibre.utils.imghdr import what -from polyglot.builtins import iteritems, itervalues, map, unicode_type, zip, print_to_binary_file +from polyglot.builtins import iteritems, itervalues, print_to_binary_file class FDST: @@ -95,14 +95,14 @@ class MOBIFile: def print_header(self, f=sys.stdout): p = print_to_binary_file(f) - p(unicode_type(self.mf.palmdb)) + p(str(self.mf.palmdb)) p() p('Record headers:') for i, r in enumerate(self.mf.records): p('%6d. %s'%(i, r.header)) p() - p(unicode_type(self.mf.mobi8_header)) + p(str(self.mf.mobi8_header)) def read_fdst(self): self.fdst = None @@ -314,23 +314,23 @@ def inspect_mobi(mobi_file, ddir): for i, container in enumerate(f.containers): with open(os.path.join(ddir, 'container%d.txt' % (i + 1)), 'wb') as cf: - cf.write(unicode_type(container).encode('utf-8')) + cf.write(str(container).encode('utf-8')) if f.fdst: with open(os.path.join(ddir, 'fdst.record'), 'wb') as fo: - fo.write(unicode_type(f.fdst).encode('utf-8')) + fo.write(str(f.fdst).encode('utf-8')) with open(os.path.join(ddir, 'skel.record'), 'wb') as fo: - fo.write(unicode_type(f.skel_index).encode('utf-8')) + fo.write(str(f.skel_index).encode('utf-8')) with open(os.path.join(ddir, 'chunks.record'), 'wb') as fo: - fo.write(unicode_type(f.sect_index).encode('utf-8')) + fo.write(str(f.sect_index).encode('utf-8')) with open(os.path.join(ddir, 'ncx.record'), 'wb') as fo: - fo.write(unicode_type(f.ncx_index).encode('utf-8')) + fo.write(str(f.ncx_index).encode('utf-8')) with open(os.path.join(ddir, 'guide.record'), 'wb') as fo: - fo.write(unicode_type(f.guide_index).encode('utf-8')) + fo.write(str(f.guide_index).encode('utf-8')) with open(os.path.join(ddir, 'tbs.txt'), 'wb') as fo: fo.write(('\n'.join(f.indexing_data)).encode('utf-8')) diff --git a/src/calibre/ebooks/mobi/huffcdic.py b/src/calibre/ebooks/mobi/huffcdic.py index 63f78b5c41..c17d4096df 100644 --- a/src/calibre/ebooks/mobi/huffcdic.py +++ b/src/calibre/ebooks/mobi/huffcdic.py @@ -14,7 +14,6 @@ and igorsk. import struct from calibre.ebooks.mobi import MobiError -from polyglot.builtins import map class Reader: diff --git a/src/calibre/ebooks/mobi/mobiml.py b/src/calibre/ebooks/mobi/mobiml.py index 9982bcd60e..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. ''' @@ -17,7 +15,7 @@ from calibre.ebooks.oeb.stylizer import Stylizer from calibre.ebooks.oeb.transforms.flatcss import KeyMapper from calibre.ebooks.mobi.utils import convert_color_for_font_tag from calibre.utils.imghdr import identify -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes MBP_NS = 'http://mobipocket.com/ns/mbp' @@ -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() @@ -163,7 +161,7 @@ class MobiMLizer: return "%dem" % int(round(ptsize / embase)) def preize_text(self, text, pre_wrap=False): - text = unicode_type(text) + text = str(text) if pre_wrap: # Replace n consecutive spaces with n-1 NBSP + space text = re.sub(r' {2,}', lambda m:('\xa0'*(len(m.group())-1) + ' '), text) @@ -211,7 +209,7 @@ class MobiMLizer: bstate.nested.append(para) if tag == 'li' and len(istates) > 1: istates[-2].list_num += 1 - para.attrib['value'] = unicode_type(istates[-2].list_num) + para.attrib['value'] = str(istates[-2].list_num) elif tag in NESTABLE_TAGS and istate.rendered: para = wrapper = bstate.nested[-1] elif not self.opts.mobi_ignore_margins and left > 0 and indent >= 0: @@ -240,7 +238,7 @@ class MobiMLizer: while vspace > 0: wrapper.addprevious(etree.Element(XHTML('br'))) vspace -= 1 - if istate.halign != 'auto' and isinstance(istate.halign, (bytes, unicode_type)): + if istate.halign != 'auto' and isinstance(istate.halign, (bytes, str)): if isinstance(istate.halign, bytes): istate.halign = istate.halign.decode('utf-8') para.attrib['align'] = istate.halign @@ -297,7 +295,7 @@ class MobiMLizer: if fsize != 3: inline = etree.SubElement(inline, XHTML('font'), - size=unicode_type(fsize)) + size=str(fsize)) if istate.family == 'monospace': inline = etree.SubElement(inline, XHTML('tt')) if istate.italic: @@ -462,7 +460,7 @@ class MobiMLizer: (72/self.profile.dpi))) except: continue - result = unicode_type(pixs) + result = str(pixs) istate.attrib[prop] = result if 'width' not in istate.attrib or 'height' not in istate.attrib: href = self.current_spine_item.abshref(elem.attrib['src']) @@ -479,8 +477,8 @@ class MobiMLizer: else: if 'width' not in istate.attrib and 'height' not in \ istate.attrib: - istate.attrib['width'] = unicode_type(width) - istate.attrib['height'] = unicode_type(height) + istate.attrib['width'] = str(width) + istate.attrib['height'] = str(height) else: ar = width / height if 'width' not in istate.attrib: @@ -488,13 +486,13 @@ class MobiMLizer: width = int(istate.attrib['height'])*ar except: pass - istate.attrib['width'] = unicode_type(int(width)) + istate.attrib['width'] = str(int(width)) else: try: height = int(istate.attrib['width'])/ar except: pass - istate.attrib['height'] = unicode_type(int(height)) + istate.attrib['height'] = str(int(height)) item.unload_data_from_memory() elif tag == 'hr' and asfloat(style['width']) > 0 and style._get('width') not in {'100%', 'auto'}: raww = style._get('width') diff --git a/src/calibre/ebooks/mobi/reader/headers.py b/src/calibre/ebooks/mobi/reader/headers.py index e175830213..c24c0c2006 100644 --- a/src/calibre/ebooks/mobi/reader/headers.py +++ b/src/calibre/ebooks/mobi/reader/headers.py @@ -16,7 +16,6 @@ from calibre.ebooks.mobi.langcodes import main_language, sub_language, mobi2iana from calibre.utils.cleantext import clean_ascii_chars, clean_xml_chars from calibre.utils.localization import canonicalize_lang from calibre.utils.config_base import tweaks -from polyglot.builtins import unicode_type NULL_INDEX = 0xffffffff @@ -250,7 +249,7 @@ class BookHeader: self.exth_flag, = struct.unpack('>L', raw[0x80:0x84]) self.exth = None - if not isinstance(self.title, unicode_type): + if not isinstance(self.title, str): self.title = self.title.decode(self.codec, 'replace') if self.exth_flag & 0x40: try: diff --git a/src/calibre/ebooks/mobi/reader/index.py b/src/calibre/ebooks/mobi/reader/index.py index e6338a6535..7913542c99 100644 --- a/src/calibre/ebooks/mobi/reader/index.py +++ b/src/calibre/ebooks/mobi/reader/index.py @@ -11,7 +11,7 @@ from collections import OrderedDict, namedtuple from calibre.ebooks.mobi.utils import (decint, count_set_bits, decode_string) -from polyglot.builtins import iteritems, range, zip +from polyglot.builtins import iteritems TagX = namedtuple('TagX', 'tag num_of_values bitmask eof') PTagX = namedtuple('PTagX', 'tag value_count value_bytes num_of_values') @@ -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/mobi6.py b/src/calibre/ebooks/mobi/reader/mobi6.py index 767dc5838e..9ea4376a91 100644 --- a/src/calibre/ebooks/mobi/reader/mobi6.py +++ b/src/calibre/ebooks/mobi/reader/mobi6.py @@ -28,7 +28,7 @@ from calibre.utils.cleantext import clean_ascii_chars, clean_xml_chars from calibre.utils.img import AnimatedGIF, gif_data_to_png_data, save_cover_data_to from calibre.utils.imghdr import what from calibre.utils.logging import default_log -from polyglot.builtins import iteritems, map, range, unicode_type +from polyglot.builtins import iteritems class TopazError(ValueError): @@ -302,7 +302,7 @@ class MobiReader: pass def write_as_utf8(path, data): - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') with lopen(path, 'wb') as f: f.write(data) diff --git a/src/calibre/ebooks/mobi/reader/mobi8.py b/src/calibre/ebooks/mobi/reader/mobi8.py index c23e0c3b30..73318be22e 100644 --- a/src/calibre/ebooks/mobi/reader/mobi8.py +++ b/src/calibre/ebooks/mobi/reader/mobi8.py @@ -23,7 +23,7 @@ from calibre.ebooks.metadata.toc import TOC from calibre.ebooks.mobi.utils import read_font_record from calibre.ebooks.oeb.parse_utils import parse_html from calibre.ebooks.oeb.base import XPath, XHTML, xml2text -from polyglot.builtins import range, zip, unicode_type, getcwd, as_unicode +from polyglot.builtins import as_unicode from polyglot.urllib import urldefrag Part = namedtuple('Part', @@ -225,7 +225,7 @@ class Mobi8Reader: self.parts.append(skeleton) if divcnt < 1: # Empty file - aidtext = unicode_type(uuid4()) + aidtext = str(uuid4()) filename = aidtext + '.html' self.partinfo.append(Part(skelnum, 'text', filename, skelpos, baseptr, aidtext)) @@ -357,7 +357,7 @@ class Mobi8Reader: if isinstance(idtext, bytes): idtext = idtext.decode(self.header.codec) linktgt += '#' + idtext - g = Guide.Reference(linktgt, getcwd()) + g = Guide.Reference(linktgt, os.getcwd()) g.title, g.type = ref_title, ref_type if g.title == 'start' or g.type == 'text': has_start = True @@ -371,7 +371,7 @@ class Mobi8Reader: linktgt = fi.filename if idtext: linktgt += '#' + idtext - g = Guide.Reference('%s/%s'%(fi.type, linktgt), getcwd()) + g = Guide.Reference('%s/%s'%(fi.type, linktgt), os.getcwd()) g.title, g.type = 'start', 'text' guide.append(g) @@ -485,7 +485,7 @@ class Mobi8Reader: except: self.log.exception('Failed to read inline ToC') - opf = OPFCreator(getcwd(), mi) + opf = OPFCreator(os.getcwd(), mi) opf.guide = guide def exclude(path): @@ -505,7 +505,7 @@ class Mobi8Reader: except: pass - opf.create_manifest_from_files_in([getcwd()], exclude=exclude) + opf.create_manifest_from_files_in([os.getcwd()], exclude=exclude) for entry in opf.manifest: if entry.mime_type == 'text/html': entry.mime_type = 'application/xhtml+xml' @@ -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/reader/ncx.py b/src/calibre/ebooks/mobi/reader/ncx.py index 37520378c2..be49c2ea95 100644 --- a/src/calibre/ebooks/mobi/reader/ncx.py +++ b/src/calibre/ebooks/mobi/reader/ncx.py @@ -6,11 +6,13 @@ __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import os + from calibre import replace_entities from calibre.ebooks.metadata.toc import TOC from calibre.ebooks.mobi.reader.headers import NULL_INDEX from calibre.ebooks.mobi.reader.index import read_index -from polyglot.builtins import iteritems, getcwd +from polyglot.builtins import iteritems tag_fieldname_map = { 1: ['pos',0], @@ -81,7 +83,7 @@ def read_ncx(sections, index, codec): def build_toc(index_entries): - ans = TOC(base_path=getcwd()) + ans = TOC(base_path=os.getcwd()) levels = {x['hlvl'] for x in index_entries} num_map = {-1: ans} level_map = {l:[x for x in index_entries if x['hlvl'] == l] for l in diff --git a/src/calibre/ebooks/mobi/utils.py b/src/calibre/ebooks/mobi/utils.py index 590f21fc2d..ab34265fa9 100644 --- a/src/calibre/ebooks/mobi/utils.py +++ b/src/calibre/ebooks/mobi/utils.py @@ -13,7 +13,7 @@ from io import BytesIO from calibre.utils.img import save_cover_data_to, scale_image, image_to_data, image_from_data, resize_image, png_data_to_gif_data from calibre.utils.imghdr import what from calibre.ebooks import normalize -from polyglot.builtins import unicode_type, range, as_bytes, map +from polyglot.builtins import as_bytes from tinycss.color3 import parse_color_string IMAGE_MAX_SIZE = 10 * 1024 * 1024 @@ -23,17 +23,17 @@ RECORD_SIZE = 0x1000 # 4096 (Text record size (uncompressed)) class PolyglotDict(dict): def __setitem__(self, key, val): - if isinstance(key, unicode_type): + if isinstance(key, str): key = key.encode('utf-8') dict.__setitem__(self, key, val) def __getitem__(self, key): - if isinstance(key, unicode_type): + if isinstance(key, str): key = key.encode('utf-8') return dict.__getitem__(self, key) def __contains__(self, key): - if isinstance(key, unicode_type): + if isinstance(key, str): key = key.encode('utf-8') return dict.__contains__(self, key) @@ -335,7 +335,7 @@ def utf8_text(text): ''' if text and text.strip(): text = text.strip() - if not isinstance(text, unicode_type): + if not isinstance(text, str): text = text.decode('utf-8', 'replace') text = normalize(text).encode('utf-8') else: @@ -638,7 +638,7 @@ def is_guide_ref_start(ref): def convert_color_for_font_tag(val): - rgba = parse_color_string(unicode_type(val or '')) + rgba = parse_color_string(str(val or '')) if rgba is None or rgba == 'currentColor': return str(val) clamp = lambda x: min(x, max(0, x), 1) diff --git a/src/calibre/ebooks/mobi/writer2/indexer.py b/src/calibre/ebooks/mobi/writer2/indexer.py index b264fd0dfa..0fc15b1161 100644 --- a/src/calibre/ebooks/mobi/writer2/indexer.py +++ b/src/calibre/ebooks/mobi/writer2/indexer.py @@ -13,7 +13,7 @@ from collections import OrderedDict, defaultdict from calibre.ebooks.mobi.utils import (encint, encode_number_as_hex, encode_tbs, align_block, RECORD_SIZE, CNCX as CNCX_) -from polyglot.builtins import filter, iteritems, itervalues, map, range +from polyglot.builtins import iteritems, itervalues class CNCX(CNCX_): # {{{ @@ -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/main.py b/src/calibre/ebooks/mobi/writer2/main.py index f28f7876d0..c583d927da 100644 --- a/src/calibre/ebooks/mobi/writer2/main.py +++ b/src/calibre/ebooks/mobi/writer2/main.py @@ -18,7 +18,7 @@ from calibre.ebooks.mobi.writer2 import (PALMDOC, UNCOMPRESSED) from calibre.ebooks.mobi.utils import (encint, encode_trailing_data, align_block, detect_periodical, RECORD_SIZE, create_text_record) from calibre.ebooks.mobi.writer2.indexer import Indexer -from polyglot.builtins import iteritems, unicode_type, range +from polyglot.builtins import iteritems # Disabled as I dont care about uncrossable breaks WRITE_UNCROSSABLE_BREAKS = False @@ -51,7 +51,7 @@ class MobiWriter: self.log = oeb.log pt = None if oeb.metadata.publication_type: - x = unicode_type(oeb.metadata.publication_type[0]).split(':') + x = str(oeb.metadata.publication_type[0]).split(':') if len(x) > 1: pt = x[1].lower() self.publication_type = pt @@ -238,7 +238,7 @@ class MobiWriter: 0 # Unused )) # 0 - 15 (0x0 - 0xf) uid = random.randint(0, 0xffffffff) - title = normalize(unicode_type(metadata.title[0])).encode('utf-8') + title = normalize(str(metadata.title[0])).encode('utf-8') # 0x0 - 0x3 record0.write(b'MOBI') @@ -281,7 +281,7 @@ class MobiWriter: # 0x4c - 0x4f : Language specifier record0.write(iana2mobi( - unicode_type(metadata.language[0]))) + str(metadata.language[0]))) # 0x50 - 0x57 : Input language and Output language record0.write(b'\0' * 8) @@ -458,7 +458,7 @@ class MobiWriter: ''' Write the PalmDB header ''' - title = ascii_filename(unicode_type(self.oeb.metadata.title[0])).replace( + title = ascii_filename(str(self.oeb.metadata.title[0])).replace( ' ', '_') if not isinstance(title, bytes): title = title.encode('ascii') diff --git a/src/calibre/ebooks/mobi/writer2/resources.py b/src/calibre/ebooks/mobi/writer2/resources.py index 36535d56f5..2bf2d22d96 100644 --- a/src/calibre/ebooks/mobi/writer2/resources.py +++ b/src/calibre/ebooks/mobi/writer2/resources.py @@ -17,7 +17,7 @@ from calibre.ebooks import generate_masthead from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.imghdr import what -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems PLACEHOLDER_GIF = b'GIF89a\x01\x00\x01\x00\xf0\x00\x00\x00\x00\x00\xff\xff\xff!\xf9\x04\x01\x00\x00\x00\x00!\xfe calibre-placeholder-gif-for-azw3\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;' # noqa @@ -90,7 +90,7 @@ class Resources: self.image_indices.add(0) elif self.is_periodical: # Generate a default masthead - data = generate_masthead(unicode_type(self.oeb.metadata['title'][0])) + data = generate_masthead(str(self.oeb.metadata['title'][0])) self.records.append(data) self.used_image_indices.add(0) self.image_indices.add(0) @@ -98,8 +98,8 @@ class Resources: cover_href = self.cover_offset = self.thumbnail_offset = None if (oeb.metadata.cover and - unicode_type(oeb.metadata.cover[0]) in oeb.manifest.ids): - cover_id = unicode_type(oeb.metadata.cover[0]) + str(oeb.metadata.cover[0]) in oeb.manifest.ids): + cover_id = str(oeb.metadata.cover[0]) item = oeb.manifest.ids[cover_id] cover_href = item.href diff --git a/src/calibre/ebooks/mobi/writer2/serializer.py b/src/calibre/ebooks/mobi/writer2/serializer.py index ad98becd9e..e8aaa11341 100644 --- a/src/calibre/ebooks/mobi/writer2/serializer.py +++ b/src/calibre/ebooks/mobi/writer2/serializer.py @@ -17,14 +17,14 @@ from calibre.ebooks.mobi.utils import is_guide_ref_start from calibre.ebooks.oeb.base import ( OEB_DOCS, XHTML, XHTML_NS, XML_NS, namespace, prefixname, urlnormalize ) -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes from polyglot.urllib import urldefrag class Buf(BytesIO): def write(self, x): - if isinstance(x, unicode_type): + if isinstance(x, str): x = x.encode('utf-8') BytesIO.write(self, x) @@ -230,7 +230,7 @@ class Serializer: buf.write(b'
') else: t = tocref.title - if isinstance(t, unicode_type): + if isinstance(t, str): t = t.encode('utf-8') buf.write(b'

' + t + b'

') @@ -250,7 +250,7 @@ class Serializer: buf.write(b'0000000000') buf.write(b' >') t = tocitem.title - if isinstance(t, unicode_type): + if isinstance(t, str): t = t.encode('utf-8') buf.write(t) buf.write(b'') @@ -365,10 +365,10 @@ 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, unicode_type): + if isinstance(text, str): text = unicodedata.normalize('NFC', text) self.buf.write(text.encode('utf-8')) diff --git a/src/calibre/ebooks/mobi/writer8/exth.py b/src/calibre/ebooks/mobi/writer8/exth.py index d8f62a90a5..1c3fc6d6a2 100644 --- a/src/calibre/ebooks/mobi/writer8/exth.py +++ b/src/calibre/ebooks/mobi/writer8/exth.py @@ -14,7 +14,7 @@ from calibre.constants import iswindows, ismacos from calibre.ebooks.mobi.utils import (utf8_text, to_base) from calibre.utils.localization import lang_as_iso639_1 from calibre.ebooks.metadata import authors_to_sort_string -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems EXTH_CODES = { 'creator': 100, @@ -63,14 +63,14 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, items = metadata[term] if term == 'creator': if prefer_author_sort: - creators = [authors_to_sort_string([unicode_type(c)]) for c in + creators = [authors_to_sort_string([str(c)]) for c in items] else: - creators = [unicode_type(c) for c in items] + creators = [str(c) for c in items] items = creators elif term == 'rights': try: - rights = utf8_text(unicode_type(metadata.rights[0])) + rights = utf8_text(str(metadata.rights[0])) except: rights = b'Unknown' exth.write(pack(b'>II', EXTH_CODES['rights'], len(rights) + 8)) @@ -79,7 +79,7 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, continue for item in items: - data = unicode_type(item) + data = str(item) if term != 'description': data = COLLAPSE_RE.sub(' ', data) if term == 'identifier': @@ -103,14 +103,14 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, from calibre.ebooks.oeb.base import OPF for x in metadata['identifier']: if (x.get(OPF('scheme'), None).lower() == 'uuid' or - unicode_type(x).startswith('urn:uuid:')): - uuid = unicode_type(x).split(':')[-1] + str(x).startswith('urn:uuid:')): + uuid = str(x).split(':')[-1] break if uuid is None: from uuid import uuid4 - uuid = unicode_type(uuid4()) + uuid = str(uuid4()) - if isinstance(uuid, unicode_type): + if isinstance(uuid, str): uuid = uuid.encode('utf-8') if not share_not_sync: exth.write(pack(b'>II', 113, len(uuid) + 8)) @@ -138,9 +138,9 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, # Add a publication date entry if metadata['date']: - datestr = unicode_type(metadata['date'][0]) + datestr = str(metadata['date'][0]) elif metadata['timestamp']: - datestr = unicode_type(metadata['timestamp'][0]) + datestr = str(metadata['timestamp'][0]) if datestr is None: raise ValueError("missing date or timestamp") 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 5b80b9963b..20028f1d83 100644 --- a/src/calibre/ebooks/mobi/writer8/index.py +++ b/src/calibre/ebooks/mobi/writer8/index.py @@ -1,8 +1,6 @@ #!/usr/bin/env python # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai -from polyglot.builtins import map - __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' @@ -10,7 +8,6 @@ __docformat__ = 'restructuredtext en' from collections import namedtuple from struct import pack from io import BytesIO -from polyglot.builtins import unicode_type, zip, range from calibre.ebooks.mobi.utils import CNCX, encint, align_block from calibre.ebooks.mobi.writer8.header import Header @@ -145,7 +142,7 @@ class Index: # {{{ for i, (index_num, tags) in enumerate(self.entries): control_bytes = self.control_bytes[i] buf.seek(0), buf.truncate(0) - index_num = (index_num.encode('utf-8') if isinstance(index_num, unicode_type) else index_num) + index_num = (index_num.encode('utf-8') if isinstance(index_num, str) else index_num) raw = bytearray(index_num) raw.insert(0, len(index_num)) buf.write(bytes(raw)) @@ -341,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/main.py b/src/calibre/ebooks/mobi/writer8/main.py index 78e552ad75..8657423929 100644 --- a/src/calibre/ebooks/mobi/writer8/main.py +++ b/src/calibre/ebooks/mobi/writer8/main.py @@ -30,7 +30,7 @@ from calibre.ebooks.mobi.writer8.index import (NCXIndex, SkelIndex, from calibre.ebooks.mobi.writer8.mobi import KF8Book from calibre.ebooks.mobi.writer8.tbs import apply_trailing_byte_sequences from calibre.ebooks.mobi.writer8.toc import TOCAdder -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems XML_DOCS = OEB_DOCS | {SVG_MIME} @@ -333,7 +333,7 @@ class KF8Writer: self.flows[0] = chunker.text def create_text_records(self): - self.flows = [x.encode('utf-8') if isinstance(x, unicode_type) else x for x + self.flows = [x.encode('utf-8') if isinstance(x, str) else x for x in self.flows] text = b''.join(self.flows) self.text_length = len(text) diff --git a/src/calibre/ebooks/mobi/writer8/mobi.py b/src/calibre/ebooks/mobi/writer8/mobi.py index 58e57ef6e8..d22dd33d96 100644 --- a/src/calibre/ebooks/mobi/writer8/mobi.py +++ b/src/calibre/ebooks/mobi/writer8/mobi.py @@ -15,7 +15,6 @@ from calibre.ebooks.mobi.writer2 import (PALMDOC, UNCOMPRESSED) from calibre.ebooks.mobi.langcodes import iana2mobi from calibre.ebooks.mobi.writer8.exth import build_exth from calibre.utils.filenames import ascii_filename -from polyglot.builtins import unicode_type NULL_INDEX = 0xffffffff FLIS = b'FLIS\0\0\0\x08\0\x41\0\0\0\0\0\0\xff\xff\xff\xff\0\x01\0\x03\0\0\0\x03\0\0\0\x01'+ b'\xff'*4 @@ -200,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) # }}} @@ -282,14 +281,14 @@ class KF8Book: # Miscellaneous header fields self.compression = writer.compress self.book_type = 0x101 if writer.opts.mobi_periodical else 2 - self.full_title = utf8_text(unicode_type(metadata.title[0])) + self.full_title = utf8_text(str(metadata.title[0])) self.title_length = len(self.full_title) self.extra_data_flags = 0b1 if writer.has_tbs: self.extra_data_flags |= 0b10 self.uid = random.randint(0, 0xffffffff) - self.language_code = iana2mobi(unicode_type(metadata.language[0])) + self.language_code = iana2mobi(str(metadata.language[0])) self.exth_flags = 0b1010000 if writer.opts.mobi_periodical: self.exth_flags |= 0b1000 diff --git a/src/calibre/ebooks/mobi/writer8/skeleton.py b/src/calibre/ebooks/mobi/writer8/skeleton.py index 85c4d4fd8e..4a4b5c95df 100644 --- a/src/calibre/ebooks/mobi/writer8/skeleton.py +++ b/src/calibre/ebooks/mobi/writer8/skeleton.py @@ -16,7 +16,7 @@ from lxml import etree from calibre import my_unichr from calibre.ebooks.oeb.base import XHTML_NS, extract from calibre.ebooks.mobi.utils import to_base, PolyglotDict -from polyglot.builtins import iteritems, unicode_type, as_bytes +from polyglot.builtins import iteritems, as_bytes CHUNK_SIZE = 8192 @@ -69,7 +69,7 @@ def tostring(raw, **kwargs): xml_declaration = kwargs.pop('xml_declaration', False) encoding = kwargs.pop('encoding', 'UTF-8') - kwargs['encoding'] = unicode_type + kwargs['encoding'] = str kwargs['xml_declaration'] = False ans = etree.tostring(raw, **kwargs) if xml_declaration: @@ -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 76adcf9d0e..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' @@ -20,7 +19,7 @@ from odf.namespaces import TEXTNS as odTEXTNS from calibre import CurrentDir, walk from calibre.ebooks.oeb.base import _css_logger from calibre.utils.xml_parse import safe_xml_fromstring -from polyglot.builtins import unicode_type, string_or_bytes, filter, getcwd, as_bytes +from polyglot.builtins import string_or_bytes, as_bytes class Extract(ODF2XHTML): @@ -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() @@ -174,7 +173,7 @@ class Extract(ODF2XHTML): css = style.text if css: css, sel_map = self.do_filter_css(css) - if not isinstance(css, unicode_type): + if not isinstance(css, str): css = css.decode('utf-8', 'ignore') style.text = css for x in root.xpath('//*[@class]'): @@ -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: @@ -296,9 +295,9 @@ class Extract(ODF2XHTML): f.write(as_bytes(html)) zf = ZipFile(stream, 'r') self.extract_pictures(zf) - opf = OPFCreator(os.path.abspath(getcwd()), mi) + opf = OPFCreator(os.path.abspath(os.getcwd()), mi) opf.create_manifest([(os.path.abspath(f2), None) for f2 in - walk(getcwd())]) + walk(os.getcwd())]) opf.create_spine([os.path.abspath('index.xhtml')]) with open('metadata.opf', 'wb') as f: opf.render(f) 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 11ce2ab2f5..f57727c483 100644 --- a/src/calibre/ebooks/oeb/base.py +++ b/src/calibre/ebooks/oeb/base.py @@ -22,7 +22,7 @@ from calibre import (isbytestring, as_unicode, get_types_map) from calibre.ebooks.oeb.parse_utils import barename, XHTML_NS, namespace, XHTML, parse_html, NotHTML from calibre.utils.cleantext import clean_xml_chars from calibre.utils.short_uuid import uuid4 -from polyglot.builtins import iteritems, unicode_type, string_or_bytes, range, itervalues, filter, codepoint_to_chr +from polyglot.builtins import iteritems, string_or_bytes, itervalues, codepoint_to_chr from polyglot.urllib import unquote as urlunquote, urldefrag, urljoin, urlparse, urlunparse from calibre.utils.icu import numeric_sort_key @@ -122,7 +122,7 @@ def as_string_type(pat, for_unicode): if isinstance(pat, bytes): pat = pat.decode('utf-8') else: - if isinstance(pat, unicode_type): + if isinstance(pat, str): pat = pat.encode('utf-8') return pat @@ -141,7 +141,7 @@ def self_closing_pat(for_unicode): def close_self_closing_tags(raw): - for_unicode = isinstance(raw, unicode_type) + for_unicode = isinstance(raw, str) repl = as_string_type(r'<\g\g>>', for_unicode) pat = self_closing_pat(for_unicode) return pat.sub(repl, raw) @@ -423,11 +423,11 @@ def serialize(data, media_type, pretty_print=False): # incorrectly by some browser based renderers ans = close_self_closing_tags(ans) return ans - if isinstance(data, unicode_type): + if isinstance(data, str): return data.encode('utf-8') if hasattr(data, 'cssText'): data = data.cssText - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') return data + b'\n' return bytes(data) @@ -569,7 +569,7 @@ class DirContainer: # If it runs on a unicode object, it returns a double encoded unicode # string: unquote(u'%C3%A4') != unquote(b'%C3%A4').decode('utf-8') # and the latter is correct - if isinstance(path, unicode_type): + if isinstance(path, str): path = path.encode('utf-8') return urlunquote(path).decode('utf-8') @@ -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): @@ -913,9 +912,9 @@ class Manifest: """ def __init__(self, oeb, id, href, media_type, - fallback=None, loader=unicode_type, data=None): + fallback=None, loader=str, data=None): if href: - href = unicode_type(href) + href = str(href) self.oeb = oeb self.id = id self.href = self.path = urlnormalize(href) @@ -969,7 +968,7 @@ class Manifest: title = self.oeb.metadata.title if title: - title = unicode_type(title[0]) + title = str(title[0]) else: title = _('Unknown') @@ -1003,7 +1002,7 @@ class Manifest: self.oeb.logger.warn('CSS import of non-CSS file %r' % path) return (None, None) data = item.data.cssText - enc = None if isinstance(data, unicode_type) else 'utf-8' + enc = None if isinstance(data, str) else 'utf-8' return (enc, data) # }}} @@ -1087,11 +1086,11 @@ class Manifest: data = self.data if isinstance(data, etree._Element): return xml2text(data, pretty_print=self.oeb.pretty_print) - if isinstance(data, unicode_type): + if isinstance(data, str): return data if hasattr(data, 'cssText'): return css_text(data) - return unicode_type(data) + return str(data) @property def bytes_representation(self): @@ -1203,7 +1202,7 @@ class Manifest: base = id index = 1 while id in self.ids: - id = base + unicode_type(index) + id = base + str(index) index += 1 if href is not None: href = urlnormalize(href) @@ -1211,13 +1210,12 @@ class Manifest: index = 1 lhrefs = {x.lower() for x in self.hrefs} while href.lower() in lhrefs: - href = base + unicode_type(index) + ext + href = base + str(index) + ext index += 1 - return id, unicode_type(href) + 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] @@ -1427,7 +1424,7 @@ class Guide: def add(self, type, title, href): """Add a new reference to the `Guide`.""" if href: - href = unicode_type(href) + href = str(href) ref = self.Reference(self.oeb, type, title, href) self.refs[type] = ref return ref @@ -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] @@ -1626,7 +1617,7 @@ class TOC: po = node.play_order if po == 0: po = 1 - attrib = {'id': id, 'playOrder': unicode_type(po)} + attrib = {'id': id, 'playOrder': str(po)} if node.klass: attrib['class'] = node.klass point = element(parent, NCX('navPoint'), attrib=attrib) @@ -1697,7 +1688,7 @@ class PageList: TYPES = {'front', 'normal', 'special'} def __init__(self, name, href, type='normal', klass=None, id=None): - self.name = unicode_type(name) + self.name = str(name) self.href = urlnormalize(href) self.type = type if type in self.TYPES else 'normal' self.id = id @@ -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] @@ -1734,7 +1724,7 @@ class PageList: for page in self.pages: id = page.id or uuid_id() type = page.type - value = unicode_type(next(values[type])) + value = str(next(values[type])) attrib = {'id': id, 'value': value, 'type': type, 'playOrder': '0'} if page.klass: attrib['class'] = page.klass @@ -1827,7 +1817,7 @@ class OEBBook: def translate(self, text): """Translate :param:`text` into the book's primary language.""" - lang = unicode_type(self.metadata.language[0]) + lang = str(self.metadata.language[0]) lang = lang.split('-', 1)[0].lower() return translate(lang, text) @@ -1835,7 +1825,7 @@ class OEBBook: """Automatically decode :param:`data` into a `unicode` object.""" def fix_data(d): return d.replace('\r\n', '\n').replace('\r', '\n') - if isinstance(data, unicode_type): + if isinstance(data, str): return fix_data(data) bom_enc = None if data[:4] in (b'\0\0\xfe\xff', b'\xff\xfe\0\0'): @@ -1909,36 +1899,36 @@ class OEBBook: for i, elem in enumerate(xpath(ncx, '//*[@playOrder and ./ncx:content[@src]]')): href = urlnormalize(selector(elem)[0]) order = playorder.get(href, i) - elem.attrib['playOrder'] = unicode_type(order) + elem.attrib['playOrder'] = str(order) return def _to_ncx(self): - lang = unicode_type(self.metadata.language[0]) + lang = str(self.metadata.language[0]) lang = lang.replace('_', '-') ncx = etree.Element(NCX('ncx'), attrib={'version': '2005-1', XML('lang'): lang}, nsmap={None: NCX_NS}) head = etree.SubElement(ncx, NCX('head')) etree.SubElement(head, NCX('meta'), - name='dtb:uid', content=unicode_type(self.uid)) + name='dtb:uid', content=str(self.uid)) etree.SubElement(head, NCX('meta'), - name='dtb:depth', content=unicode_type(self.toc.depth())) + name='dtb:depth', content=str(self.toc.depth())) generator = ''.join(['calibre (', __version__, ')']) etree.SubElement(head, NCX('meta'), name='dtb:generator', content=generator) etree.SubElement(head, NCX('meta'), - name='dtb:totalPageCount', content=unicode_type(len(self.pages))) + name='dtb:totalPageCount', content=str(len(self.pages))) maxpnum = etree.SubElement(head, NCX('meta'), name='dtb:maxPageNumber', content='0') title = etree.SubElement(ncx, NCX('docTitle')) text = etree.SubElement(title, NCX('text')) - text.text = unicode_type(self.metadata.title[0]) + text.text = str(self.metadata.title[0]) navmap = etree.SubElement(ncx, NCX('navMap')) self.toc.to_ncx(navmap) if len(self.pages) > 0: plist = self.pages.to_ncx(ncx) value = max(int(x) for x in xpath(plist, '//@value')) - maxpnum.attrib['content'] = unicode_type(value) + maxpnum.attrib['content'] = str(value) self._update_playorder(ncx) return ncx diff --git a/src/calibre/ebooks/oeb/iterator/bookmarks.py b/src/calibre/ebooks/oeb/iterator/bookmarks.py index e158cae23b..3146b5cc36 100644 --- a/src/calibre/ebooks/oeb/iterator/bookmarks.py +++ b/src/calibre/ebooks/oeb/iterator/bookmarks.py @@ -10,10 +10,10 @@ import os, numbers from io import BytesIO from calibre.utils.zipfile import safe_replace -from polyglot.builtins import unicode_type, as_unicode +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 = unicode_type(pos) + pos = str(pos) else: - pos = pos.replace(u'^', BM_LEGACY_ESC) - rec = BM_FIELD_SEP.join([bm['title'], unicode_type(bm['spine']), pos]) + 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 24ab3f6d79..5ae81275ae 100644 --- a/src/calibre/ebooks/oeb/iterator/spine.py +++ b/src/calibre/ebooks/oeb/iterator/spine.py @@ -1,7 +1,6 @@ #!/usr/bin/env python # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai -from polyglot.builtins import map, unicode_type __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' @@ -44,14 +43,14 @@ def all_links(html): return ans -class SpineItem(unicode_type): +class SpineItem(str): def __new__(cls, path, mime_type=None, read_anchor_map=True, run_char_count=True, from_epub=False, read_links=True): 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 cb8353bfcd..19db58fd0f 100644 --- a/src/calibre/ebooks/oeb/normalize_css.py +++ b/src/calibre/ebooks/oeb/normalize_css.py @@ -12,7 +12,7 @@ from css_parser.css import PropertyValue from css_parser import profile as cssprofiles, CSSParser from tinycss.fonts3 import parse_font, serialize_font_family from calibre.ebooks.oeb.base import css_text -from polyglot.builtins import iteritems, string_or_bytes, unicode_type, zip +from polyglot.builtins import iteritems, string_or_bytes DEFAULTS = {'azimuth': 'center', 'background-attachment': 'scroll', # {{{ 'background-color': 'transparent', 'background-image': 'none', @@ -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', @@ -393,7 +393,7 @@ def test_normalization(return_tests=False): # {{{ tuple('0 0 0 0'.split()) : '0', }): for prefix in ('margin', 'padding'): - css = {'%s-%s' % (prefix, x) : unicode_type(y)+'pt' if isinstance(y, numbers.Number) else y + css = {'%s-%s' % (prefix, x) : str(y)+'pt' if isinstance(y, numbers.Number) else y for x, y in zip(('left', 'top', 'right', 'bottom'), s)} css = '; '.join(('%s:%s' % (k, v) for k, v in iteritems(css))) style = parseStyle(css) diff --git a/src/calibre/ebooks/oeb/parse_utils.py b/src/calibre/ebooks/oeb/parse_utils.py index b7e96a4b01..f4557dbccb 100644 --- a/src/calibre/ebooks/oeb/parse_utils.py +++ b/src/calibre/ebooks/oeb/parse_utils.py @@ -14,7 +14,7 @@ from calibre import xml_replace_entities, force_unicode from calibre.utils.xml_parse import safe_xml_fromstring from calibre.constants import filesystem_encoding from calibre.ebooks.chardet import xml_to_unicode, strip_encoding_declarations -from polyglot.builtins import iteritems, itervalues, unicode_type, string_or_bytes, map +from polyglot.builtins import iteritems, itervalues, string_or_bytes RECOVER_PARSER = etree.XMLParser(recover=True, no_network=True, resolve_entities=False) XHTML_NS = 'http://www.w3.org/1999/xhtml' @@ -165,7 +165,7 @@ def parse_html(data, log=None, decoder=None, preprocessor=None, filename = force_unicode(filename, enc=filesystem_encoding) - if not isinstance(data, unicode_type): + if not isinstance(data, str): if decoder is not None: data = decoder(data) else: @@ -247,7 +247,7 @@ def parse_html(data, log=None, decoder=None, preprocessor=None, nroot = safe_xml_fromstring('') has_body = False for child in list(data): - if isinstance(child.tag, (unicode_type, bytes)) and barename(child.tag) == 'body': + if isinstance(child.tag, (str, bytes)) and barename(child.tag) == 'body': has_body = True break parent = nroot diff --git a/src/calibre/ebooks/oeb/polish/cascade.py b/src/calibre/ebooks/oeb/polish/cascade.py index 2475c906f9..d6c42e86a6 100644 --- a/src/calibre/ebooks/oeb/polish/cascade.py +++ b/src/calibre/ebooks/oeb/polish/cascade.py @@ -18,7 +18,7 @@ from calibre.ebooks.oeb.base import OEB_STYLES, XHTML, css_text from calibre.ebooks.oeb.normalize_css import normalizers, DEFAULTS from calibre.ebooks.oeb.stylizer import media_ok, INHERITED from tinycss.fonts3 import serialize_font_family, parse_font_family -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues _html_css_stylesheet = None @@ -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) @@ -233,7 +231,7 @@ _defvals = None def defvals(): global _defvals if _defvals is None: - _defvals = {k:Values(Property(k, unicode_type(val)).propertyValue) for k, val in iteritems(DEFAULTS)} + _defvals = {k:Values(Property(k, str(val)).propertyValue) for k, val in iteritems(DEFAULTS)} return _defvals diff --git a/src/calibre/ebooks/oeb/polish/check/base.py b/src/calibre/ebooks/oeb/polish/check/base.py index 0a9be5bb7b..292ebfe51e 100644 --- a/src/calibre/ebooks/oeb/polish/check/base.py +++ b/src/calibre/ebooks/oeb/polish/check/base.py @@ -10,7 +10,6 @@ from functools import partial from contextlib import closing from calibre import detect_ncpus as cpu_count -from polyglot.builtins import range DEBUG, INFO, WARN, ERROR, CRITICAL = range(5) diff --git a/src/calibre/ebooks/oeb/polish/check/links.py b/src/calibre/ebooks/oeb/polish/check/links.py index 575377c132..5f118394b6 100644 --- a/src/calibre/ebooks/oeb/polish/check/links.py +++ b/src/calibre/ebooks/oeb/polish/check/links.py @@ -17,7 +17,7 @@ from calibre.ebooks.oeb.polish.replace import remove_links_to from calibre.ebooks.oeb.polish.cover import get_raster_cover_name from calibre.ebooks.oeb.polish.utils import guess_type, actual_case_for_name, corrected_case_for_name from calibre.ebooks.oeb.polish.check.base import BaseError, WARN, INFO -from polyglot.builtins import iteritems, map, range, itervalues +from polyglot.builtins import iteritems, itervalues from polyglot.urllib import urlparse from polyglot.queue import Queue, Empty diff --git a/src/calibre/ebooks/oeb/polish/check/main.py b/src/calibre/ebooks/oeb/polish/check/main.py index d72d292799..4d84c5e5a8 100644 --- a/src/calibre/ebooks/oeb/polish/check/main.py +++ b/src/calibre/ebooks/oeb/polish/check/main.py @@ -5,7 +5,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' -from polyglot.builtins import iteritems, map +from polyglot.builtins import iteritems from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES from calibre.ebooks.oeb.polish.utils import guess_type diff --git a/src/calibre/ebooks/oeb/polish/check/parsing.py b/src/calibre/ebooks/oeb/polish/check/parsing.py index 9f06944928..f626aa29c5 100644 --- a/src/calibre/ebooks/oeb/polish/check/parsing.py +++ b/src/calibre/ebooks/oeb/polish/check/parsing.py @@ -17,13 +17,13 @@ from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style as fix_style from calibre.ebooks.oeb.polish.utils import PositionFinder, guess_type from calibre.ebooks.oeb.polish.check.base import BaseError, WARN, ERROR, INFO from calibre.ebooks.oeb.base import OEB_DOCS, XHTML_NS, urlquote, URL_SAFE, XHTML -from polyglot.builtins import iteritems, unicode_type, error_message +from polyglot.builtins import iteritems, error_message 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+') @@ -203,7 +203,7 @@ class NonUTF8(BaseError): def __call__(self, container): raw = container.raw_data(self.name) - if isinstance(raw, unicode_type): + if isinstance(raw, str): raw, changed = replace_encoding_declarations(raw) if changed: container.open(self.name, 'wb').write(raw.encode('utf-8')) @@ -443,7 +443,7 @@ class ErrorHandler: info = debug = setLevel = getEffectiveLevel = addHandler = removeHandler = __noop def __handle(self, level, *args): - msg = ' '.join(map(unicode_type, args)) + msg = ' '.join(map(str, args)) line = col = None for pat in pos_pats: m = pat.search(msg) diff --git a/src/calibre/ebooks/oeb/polish/container.py b/src/calibre/ebooks/oeb/polish/container.py index f15ca81fab..13b00d0be6 100644 --- a/src/calibre/ebooks/oeb/polish/container.py +++ b/src/calibre/ebooks/oeb/polish/container.py @@ -51,7 +51,7 @@ from calibre.utils.ipc.simple_worker import WorkerError, fork_job from calibre.utils.logging import default_log from calibre.utils.xml_parse import safe_xml_fromstring from calibre.utils.zipfile import ZipFile -from polyglot.builtins import iteritems, map, unicode_type, zip +from polyglot.builtins import iteritems from polyglot.urllib import urlparse exists, join, relpath = os.path.exists, os.path.join, os.path.relpath @@ -166,7 +166,7 @@ class ContainerBase: # {{{ """ def fix_data(d): return d.replace('\r\n', '\n').replace('\r', '\n') - if isinstance(data, unicode_type): + if isinstance(data, str): return fix_data(data) bom_enc = None if data[:4] in {b'\0\0\xfe\xff', b'\xff\xfe\0\0'}: @@ -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'): @@ -697,14 +697,13 @@ class Container(ContainerBase): # {{{ ''' The names of all manifest items whose media-type matches predicate. `predicate` can be a set, a list, a string or a function taking a single argument, which will be called with the media-type. ''' - if isinstance(predicate, unicode_type): + if isinstance(predicate, str): predicate = predicate.__eq__ elif hasattr(predicate, '__contains__'): 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/cover.py b/src/calibre/ebooks/oeb/polish/cover.py index 44f9ea6792..801068bfa1 100644 --- a/src/calibre/ebooks/oeb/polish/cover.py +++ b/src/calibre/ebooks/oeb/polish/cover.py @@ -10,7 +10,7 @@ import shutil, re, os from calibre.ebooks.oeb.base import OPF, OEB_DOCS, XPath, XLINK, xml2text from calibre.ebooks.oeb.polish.replace import replace_links, get_recommended_folders from calibre.utils.imghdr import identify -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def set_azw3_cover(container, cover_path, report, options=None): @@ -384,8 +384,8 @@ def create_epub_cover(container, cover_path, existing_image, options=None): ar = 'xMidYMid meet' if keep_aspect else 'none' templ = CoverManager.SVG_TEMPLATE.replace('__ar__', ar) templ = templ.replace('__viewbox__', '0 0 %d %d'%(width, height)) - templ = templ.replace('__width__', unicode_type(width)) - templ = templ.replace('__height__', unicode_type(height)) + templ = templ.replace('__width__', str(width)) + templ = templ.replace('__height__', str(height)) folder = recommended_folders[tname] if folder: tname = folder + '/' + tname 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 be78c33f9c..9d0f83c450 100644 --- a/src/calibre/ebooks/oeb/polish/css.py +++ b/src/calibre/ebooks/oeb/polish/css.py @@ -19,7 +19,7 @@ from calibre.ebooks.oeb.normalize_css import normalize_filter_css, normalizers from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style, pretty_xml_tree, serialize from calibre.utils.icu import numeric_sort_key from css_selectors import Select, SelectorError -from polyglot.builtins import iteritems, itervalues, unicode_type, filter +from polyglot.builtins import iteritems, itervalues from polyglot.functools import lru_cache @@ -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): @@ -456,10 +455,10 @@ def sort_sheet(container, sheet_or_text): ''' Sort the rules in a stylesheet. Note that in the general case this can change the effective styles, but for most common sheets, it should be safe. ''' - sheet = container.parse_css(sheet_or_text) if isinstance(sheet_or_text, unicode_type) else sheet_or_text + sheet = container.parse_css(sheet_or_text) if isinstance(sheet_or_text, str) else sheet_or_text def text_sort_key(x): - return numeric_sort_key(unicode_type(x or '')) + return numeric_sort_key(str(x or '')) def selector_sort_key(x): return (x.specificity, text_sort_key(x.selectorText)) diff --git a/src/calibre/ebooks/oeb/polish/embed.py b/src/calibre/ebooks/oeb/polish/embed.py index 7937ce7f89..cc0b08e461 100644 --- a/src/calibre/ebooks/oeb/polish/embed.py +++ b/src/calibre/ebooks/oeb/polish/embed.py @@ -7,7 +7,6 @@ __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' import sys -from polyglot.builtins import map from lxml import etree 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/fonts.py b/src/calibre/ebooks/oeb/polish/fonts.py index 6af8921457..f083021332 100644 --- a/src/calibre/ebooks/oeb/polish/fonts.py +++ b/src/calibre/ebooks/oeb/polish/fonts.py @@ -9,7 +9,7 @@ from calibre.ebooks.oeb.base import css_text from calibre.ebooks.oeb.polish.container import OEB_STYLES, OEB_DOCS from calibre.ebooks.oeb.normalize_css import normalize_font from tinycss.fonts3 import parse_font_family, parse_font, serialize_font_family, serialize_font -from polyglot.builtins import iteritems, filter +from polyglot.builtins import iteritems def unquote(x): diff --git a/src/calibre/ebooks/oeb/polish/images.py b/src/calibre/ebooks/oeb/polish/images.py index 1b62a5ff83..7d325d92b9 100644 --- a/src/calibre/ebooks/oeb/polish/images.py +++ b/src/calibre/ebooks/oeb/polish/images.py @@ -8,7 +8,7 @@ from functools import partial from threading import Thread, Event from calibre import detect_ncpus, human_readable, force_unicode, filesystem_encoding -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems from polyglot.queue import Queue, Empty diff --git a/src/calibre/ebooks/oeb/polish/parsing.py b/src/calibre/ebooks/oeb/polish/parsing.py index 097b7a53bd..be85e69d43 100644 --- a/src/calibre/ebooks/oeb/polish/parsing.py +++ b/src/calibre/ebooks/oeb/polish/parsing.py @@ -14,7 +14,6 @@ from calibre import xml_replace_entities from calibre.utils.xml_parse import safe_xml_fromstring from calibre.ebooks.chardet import xml_to_unicode, strip_encoding_declarations from calibre.utils.cleantext import clean_xml_chars -from polyglot.builtins import unicode_type XHTML_NS = 'http://www.w3.org/1999/xhtml' @@ -84,7 +83,7 @@ def parse(raw, decoder=None, log=None, line_numbers=True, linenumber_attribute=N if linenumber_attribute: for elem in ans.iter(LxmlElement): if elem.sourceline is not None: - elem.set(linenumber_attribute, unicode_type(elem.sourceline)) + elem.set(linenumber_attribute, str(elem.sourceline)) return ans except Exception: if log is not None: diff --git a/src/calibre/ebooks/oeb/polish/pretty.py b/src/calibre/ebooks/oeb/polish/pretty.py index 3916cd2faa..005699f964 100644 --- a/src/calibre/ebooks/oeb/polish/pretty.py +++ b/src/calibre/ebooks/oeb/polish/pretty.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' import textwrap -from polyglot.builtins import iteritems, map +from polyglot.builtins import iteritems # from lxml.etree import Element diff --git a/src/calibre/ebooks/oeb/polish/replace.py b/src/calibre/ebooks/oeb/polish/replace.py index 0da3cf7f66..b16876597a 100644 --- a/src/calibre/ebooks/oeb/polish/replace.py +++ b/src/calibre/ebooks/oeb/polish/replace.py @@ -7,7 +7,7 @@ __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' import codecs, shutil, os, posixpath -from polyglot.builtins import iteritems, itervalues, map +from polyglot.builtins import iteritems, itervalues from functools import partial from collections import Counter, defaultdict @@ -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 9aad8282d1..1c25cb898e 100644 --- a/src/calibre/ebooks/oeb/polish/spell.py +++ b/src/calibre/ebooks/oeb/polish/spell.py @@ -16,7 +16,7 @@ from calibre.ebooks.oeb.polish.container import OPF_NAMESPACES, get_container from calibre.ebooks.oeb.polish.parsing import parse from calibre.ebooks.oeb.polish.toc import find_existing_ncx_toc, find_existing_nav_toc from calibre.utils.icu import ord_string -from polyglot.builtins import iteritems, unicode_type, filter +from polyglot.builtins import iteritems _patterns = None @@ -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(): @@ -82,7 +82,7 @@ def filter_words(word): def get_words(text, lang): try: - ans = split_into_words(unicode_type(text), lang) + ans = split_into_words(str(text), lang) except (TypeError, ValueError): return () return list(filter(filter_words, ans)) @@ -318,7 +318,7 @@ def merge_locations(locs1, locs2): def replace(text, original_word, new_word, lang): indices = [] - original_word, new_word, text = unicode_type(original_word), unicode_type(new_word), unicode_type(text) + original_word, new_word, text = str(original_word), str(new_word), str(text) q = text offset = 0 while True: diff --git a/src/calibre/ebooks/oeb/polish/split.py b/src/calibre/ebooks/oeb/polish/split.py index e1660af443..689f7ab3c7 100644 --- a/src/calibre/ebooks/oeb/polish/split.py +++ b/src/calibre/ebooks/oeb/polish/split.py @@ -6,13 +6,13 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' import copy, os, re -from polyglot.builtins import map, string_or_bytes, range +from polyglot.builtins import string_or_bytes from calibre.ebooks.oeb.base import barename, XPNSMAP, XPath, OPF, XHTML, OEB_DOCS from calibre.ebooks.oeb.polish.errors import MalformedMarkup from calibre.ebooks.oeb.polish.toc import node_from_loc from calibre.ebooks.oeb.polish.replace import LinkRebaser -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems from polyglot.urllib import urlparse @@ -184,7 +184,7 @@ def split(container, name, loc_or_xpath, before=True, totals=None): ''' root = container.parsed(name) - if isinstance(loc_or_xpath, unicode_type): + if isinstance(loc_or_xpath, str): split_point = root.xpath(loc_or_xpath)[0] else: try: @@ -282,7 +282,7 @@ def multisplit(container, name, xpath, before=True): raise AbortError('Cannot split on the tag') for i, tag in enumerate(nodes): - tag.set('calibre-split-point', unicode_type(i)) + tag.set('calibre-split-point', str(i)) current = name all_names = [name] diff --git a/src/calibre/ebooks/oeb/polish/stats.py b/src/calibre/ebooks/oeb/polish/stats.py index 30b13289c1..028e24ab63 100644 --- a/src/calibre/ebooks/oeb/polish/stats.py +++ b/src/calibre/ebooks/oeb/polish/stats.py @@ -15,7 +15,7 @@ import regex from calibre.ebooks.oeb.base import XHTML, css_text from calibre.ebooks.oeb.polish.cascade import iterrules, resolve_styles, iterdeclaration from calibre.utils.icu import ord_string, safe_chr -from polyglot.builtins import iteritems, itervalues, range, unicode_type +from polyglot.builtins import iteritems, itervalues from tinycss.fonts3 import parse_font_family @@ -23,7 +23,7 @@ def normalize_font_properties(font): w = font.get('font-weight', None) if not w and w != 0: w = 'normal' - w = unicode_type(w) + w = str(w) w = {'normal':'400', 'bold':'700'}.get(w, w) if w not in {'100', '200', '300', '400', '500', '600', '700', '800', '900'}: @@ -161,7 +161,7 @@ def get_font_dict(elem, resolve_property, pseudo=None): for p in 'weight', 'style', 'stretch': p = 'font-' + p rp = resolve_property(elem, p) if pseudo is None else resolve_property(elem, pseudo, p) - ans[p] = unicode_type(rp[0].value) + ans[p] = str(rp[0].value) normalize_font_properties(ans) return ans diff --git a/src/calibre/ebooks/oeb/polish/tests/base.py b/src/calibre/ebooks/oeb/polish/tests/base.py index fbdf11cc1e..791b5c4231 100644 --- a/src/calibre/ebooks/oeb/polish/tests/base.py +++ b/src/calibre/ebooks/oeb/polish/tests/base.py @@ -12,7 +12,7 @@ from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import PersistentTemporaryDirectory from calibre.utils.logging import DevNull import calibre.ebooks.oeb.polish.container as pc -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def get_cache(): @@ -24,7 +24,7 @@ def get_cache(): def needs_recompile(obj, srcs): - if isinstance(srcs, unicode_type): + if isinstance(srcs, str): srcs = [srcs] try: obj_mtime = os.stat(obj).st_mtime diff --git a/src/calibre/ebooks/oeb/polish/tests/cascade.py b/src/calibre/ebooks/oeb/polish/tests/cascade.py index f74f135d8c..b56ea68286 100644 --- a/src/calibre/ebooks/oeb/polish/tests/cascade.py +++ b/src/calibre/ebooks/oeb/polish/tests/cascade.py @@ -18,7 +18,7 @@ from calibre.ebooks.oeb.polish.container import ContainerBase, href_to_name from calibre.ebooks.oeb.polish.stats import StatsCollector, font_keys, normalize_font_properties, prepare_font_rule from calibre.ebooks.oeb.polish.tests.base import BaseTest from calibre.utils.logging import Log, Stream -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class VirtualContainer(ContainerBase): @@ -83,7 +83,7 @@ class CascadeTest(BaseTest): elem = next(select(selector)) ans = resolve_property(elem, name) if val is None: - val = unicode_type(DEFAULTS[name]) + val = str(DEFAULTS[name]) self.assertEqual(val, ans.cssText) def test_pseudo_property(select, resolve_pseudo_property, selector, prop, name, val=None, abort_on_missing=False): @@ -94,7 +94,7 @@ class CascadeTest(BaseTest): self.assertTrue(ans is None) return if val is None: - val = unicode_type(DEFAULTS[name]) + val = str(DEFAULTS[name]) self.assertEqual(val, ans.cssText) def get_maps(html, styles=None, pseudo=False): diff --git a/src/calibre/ebooks/oeb/polish/tests/container.py b/src/calibre/ebooks/oeb/polish/tests/container.py index 5f54f94059..6da8d73388 100644 --- a/src/calibre/ebooks/oeb/polish/tests/container.py +++ b/src/calibre/ebooks/oeb/polish/tests/container.py @@ -15,7 +15,7 @@ from calibre.ebooks.oeb.polish.replace import rename_files, rationalize_folders from calibre.ebooks.oeb.polish.split import split, merge from calibre.utils.filenames import nlinks_file from calibre.ptempfile import TemporaryFile, TemporaryDirectory -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues def get_container(*args, **kwargs): @@ -98,7 +98,7 @@ class ContainerTests(BaseTest): def new_container(): count[0] += 1 - tdir = os.mkdir(os.path.join(self.tdir, unicode_type(count[0]))) + tdir = os.mkdir(os.path.join(self.tdir, str(count[0]))) return get_container(book, tdir=tdir) # Test simple opf rename diff --git a/src/calibre/ebooks/oeb/polish/tests/parsing.py b/src/calibre/ebooks/oeb/polish/tests/parsing.py index 383057465a..9f5df26063 100644 --- a/src/calibre/ebooks/oeb/polish/tests/parsing.py +++ b/src/calibre/ebooks/oeb/polish/tests/parsing.py @@ -14,7 +14,7 @@ from calibre.ebooks.oeb.polish.tests.base import BaseTest from calibre.ebooks.oeb.polish.parsing import parse_html5 as parse from calibre.ebooks.oeb.base import XPath, XHTML_NS, SVG_NS, XLINK_NS from calibre.ebooks.oeb.parse_utils import html5_parse -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems def nonvoid_cdata_elements(test, parse_function): diff --git a/src/calibre/ebooks/oeb/polish/tests/structure.py b/src/calibre/ebooks/oeb/polish/tests/structure.py index 5b84ed0220..4d575c73d5 100644 --- a/src/calibre/ebooks/oeb/polish/tests/structure.py +++ b/src/calibre/ebooks/oeb/polish/tests/structure.py @@ -19,7 +19,6 @@ from calibre.ebooks.oeb.polish.utils import guess_type from calibre.ebooks.oeb.base import OEB_DOCS from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.opf3 import CALIBRE_PREFIX -from polyglot.builtins import unicode_type OPF_TEMPLATE = ''' @@ -64,7 +63,7 @@ def create_epub(manifest, spine=(), guide=(), meta_cover=None, ver=3): ''') zf.writestr('content.opf', opf.encode('utf-8')) for name, data, properties in manifest: - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') zf.writestr(name, data or b'\0') buf.seek(0) @@ -78,7 +77,7 @@ class Structure(BaseTest): def create_epub(self, *args, **kw): n = next(counter) - ep = os.path.join(self.tdir, unicode_type(n) + 'book.epub') + ep = os.path.join(self.tdir, str(n) + 'book.epub') with open(ep, 'wb') as f: f.write(create_epub(*args, **kw).getvalue()) c = get_container(ep, tdir=os.path.join(self.tdir, 'container%d' % n), tweak_mode=True) diff --git a/src/calibre/ebooks/oeb/polish/toc.py b/src/calibre/ebooks/oeb/polish/toc.py index adf1a9e3fc..41e9fb5fcf 100644 --- a/src/calibre/ebooks/oeb/polish/toc.py +++ b/src/calibre/ebooks/oeb/polish/toc.py @@ -23,7 +23,7 @@ from calibre.ebooks.oeb.polish.opf import set_guide_item, get_book_language from calibre.ebooks.oeb.polish.pretty import pretty_html_tree from calibre.translations.dynamic import translate from calibre.utils.localization import get_lang, canonicalize_lang, lang_as_iso639_1 -from polyglot.builtins import iteritems, map, unicode_type +from polyglot.builtins import iteritems from polyglot.urllib import urlparse ns = etree.FunctionNamespace('calibre_xpath_extensions') @@ -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() @@ -173,11 +171,11 @@ def parse_ncx(container, ncx_name): toc_root.lang = toc_root.uid = None for attr, val in iteritems(root.attrib): if attr.endswith('lang'): - toc_root.lang = unicode_type(val) + toc_root.lang = str(val) break for uid in root.xpath('//*[calibre:lower-case(local-name()) = "meta" and @name="dtb:uid"]/@content'): if uid: - toc_root.uid = unicode_type(uid) + toc_root.uid = str(uid) break for pl in root.xpath('//*[calibre:lower-case(local-name()) = "pagelist"]'): for pt in pl.xpath('descendant::*[calibre:lower-case(local-name()) = "pagetarget"]'): @@ -584,9 +582,9 @@ def create_ncx(toc, to_href, btitle, lang, uid): nsmap={None: NCX_NS}) head = etree.SubElement(ncx, NCX('head')) etree.SubElement(head, NCX('meta'), - name='dtb:uid', content=unicode_type(uid)) + name='dtb:uid', content=str(uid)) etree.SubElement(head, NCX('meta'), - name='dtb:depth', content=unicode_type(toc.depth)) + name='dtb:depth', content=str(toc.depth)) generator = ''.join(['calibre (', __version__, ')']) etree.SubElement(head, NCX('meta'), name='dtb:generator', content=generator) @@ -604,7 +602,7 @@ def create_ncx(toc, to_href, btitle, lang, uid): for child in toc_parent: play_order['c'] += 1 point = etree.SubElement(xml_parent, NCX('navPoint'), id='num_%d' % play_order['c'], - playOrder=unicode_type(play_order['c'])) + playOrder=str(play_order['c'])) label = etree.SubElement(point, NCX('navLabel')) title = child.title if title: @@ -770,7 +768,7 @@ def commit_nav_toc(container, toc, lang=None, landmarks=None, previous_nav=None) for entry in toc.page_list: if container.has_name(entry['dest']) and container.mime_map[entry['dest']] in OEB_DOCS: a = create_li(ol, entry) - a.text = unicode_type(entry['pagenum']) + a.text = str(entry['pagenum']) pretty_xml_tree(nav) collapse_li(nav) container.replace(tocname, root) diff --git a/src/calibre/ebooks/oeb/polish/utils.py b/src/calibre/ebooks/oeb/polish/utils.py index 658e2cb72f..added0bb97 100644 --- a/src/calibre/ebooks/oeb/polish/utils.py +++ b/src/calibre/ebooks/oeb/polish/utils.py @@ -9,7 +9,6 @@ import re, os from bisect import bisect from calibre import guess_type as _guess_type, replace_entities -from polyglot.builtins import filter def guess_type(x): @@ -60,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/reader.py b/src/calibre/ebooks/oeb/reader.py index 6031856d76..961187a91a 100644 --- a/src/calibre/ebooks/oeb/reader.py +++ b/src/calibre/ebooks/oeb/reader.py @@ -27,7 +27,6 @@ from calibre.utils.localization import get_lang from calibre.ptempfile import TemporaryDirectory from calibre.constants import __appname__, __version__ from calibre import guess_type, xml_replace_entities -from polyglot.builtins import unicode_type, zip from polyglot.urllib import unquote, urldefrag, urlparse __all__ = ['OEBReader'] @@ -145,7 +144,7 @@ class OEBReader: dict(a=__appname__, v=__version__) meta_info_to_oeb_metadata(mi, self.oeb.metadata, self.logger) m = self.oeb.metadata - m.add('identifier', unicode_type(uuid.uuid4()), id='uuid_id', scheme='uuid') + m.add('identifier', str(uuid.uuid4()), id='uuid_id', scheme='uuid') self.oeb.uid = self.oeb.metadata.identifier[-1] if not m.title: m.add('title', self.oeb.translate(__('Unknown'))) @@ -448,7 +447,7 @@ class OEBReader: ncx = item.data title = ''.join(xpath(ncx, 'ncx:docTitle/ncx:text/text()')) title = COLLAPSE_RE.sub(' ', title.strip()) - title = title or unicode_type(self.oeb.metadata.title[0]) + title = title or str(self.oeb.metadata.title[0]) toc = self.oeb.toc toc.title = title navmaps = xpath(ncx, 'ncx:navMap') @@ -635,7 +634,7 @@ class OEBReader: def _locate_cover_image(self): if self.oeb.metadata.cover: - id = unicode_type(self.oeb.metadata.cover[0]) + id = str(self.oeb.metadata.cover[0]) item = self.oeb.manifest.ids.get(id, None) if item is not None and item.media_type in OEB_IMAGES: return item diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py index 9e36083589..55551116f3 100644 --- a/src/calibre/ebooks/oeb/stylizer.py +++ b/src/calibre/ebooks/oeb/stylizer.py @@ -21,7 +21,7 @@ from calibre.ebooks import unit_convert from calibre.ebooks.oeb.base import XHTML, XHTML_NS, CSS_MIME, OEB_STYLES, xpath, urlnormalize from calibre.ebooks.oeb.normalize_css import DEFAULTS, normalizers from css_selectors import Select, SelectorError, INAPPROPRIATE_PSEUDO_CLASSES -from polyglot.builtins import iteritems, unicode_type, filter +from polyglot.builtins import iteritems from tinycss.media3 import CSSMedia3Parser css_parser_log.setLevel(logging.WARN) @@ -324,7 +324,7 @@ class Stylizer: for x in elem.iter('*'): if x.text: punctuation_chars = [] - text = unicode_type(x.text) + text = str(x.text) while text: category = unicodedata.category(text[0]) if category[0] not in {'P', 'Z'}: @@ -603,7 +603,7 @@ class Style: x = self._style.get(attr) if x is not None: if x == 'auto': - ans = self._unit_convert(unicode_type(img_size) + 'px', base=base) + ans = self._unit_convert(str(img_size) + 'px', base=base) else: x = self._unit_convert(x, base=base) if isinstance(x, numbers.Number): @@ -615,7 +615,7 @@ class Style: if isinstance(x, numbers.Number): ans = x if ans is None: - ans = self._unit_convert(unicode_type(img_size) + 'px', base=base) + ans = self._unit_convert(str(img_size) + 'px', base=base) maa = self._style.get('max-' + attr) if maa is not None: x = self._unit_convert(maa, base=base) @@ -651,12 +651,12 @@ class Style: result = base else: result = self._unit_convert(width, base=base) - if isinstance(result, (unicode_type, bytes)): + if isinstance(result, (str, bytes)): result = self._profile.width self._width = result if 'max-width' in self._style: result = self._unit_convert(self._style['max-width'], base=base) - if isinstance(result, (unicode_type, bytes)): + if isinstance(result, (str, bytes)): result = self._width if result < self._width: self._width = result @@ -688,12 +688,12 @@ class Style: result = base else: result = self._unit_convert(height, base=base) - if isinstance(result, (unicode_type, bytes)): + if isinstance(result, (str, bytes)): result = self._profile.height self._height = result if 'max-height' in self._style: result = self._unit_convert(self._style['max-height'], base=base) - if isinstance(result, (unicode_type, bytes)): + if isinstance(result, (str, bytes)): result = self._height if result < self._height: self._height = result diff --git a/src/calibre/ebooks/oeb/transforms/cover.py b/src/calibre/ebooks/oeb/transforms/cover.py index 158ce3554d..ccbd567f95 100644 --- a/src/calibre/ebooks/oeb/transforms/cover.py +++ b/src/calibre/ebooks/oeb/transforms/cover.py @@ -11,7 +11,6 @@ import textwrap from calibre import guess_type from calibre.utils.imghdr import identify from calibre.utils.xml_parse import safe_xml_fromstring -from polyglot.builtins import unicode_type from polyglot.urllib import unquote @@ -92,14 +91,14 @@ class CoverManager: return None self.log('Generating default cover') m = self.oeb.metadata - title = unicode_type(m.title[0]) - authors = [unicode_type(x) for x in m.creator if x.role == 'aut'] + title = str(m.title[0]) + authors = [str(x) for x in m.creator if x.role == 'aut'] try: from calibre.ebooks.covers import create_cover series = series_index = None if m.series: try: - series, series_index = unicode_type(m.series[0]), m.series_index[0] + series, series_index = str(m.series[0]), m.series_index[0] except IndexError: pass img_data = create_cover(title, authors, series, series_index) @@ -146,9 +145,9 @@ class CoverManager: self.svg_template = self.svg_template.replace('__viewbox__', '0 0 %d %d'%(width, height)) self.svg_template = self.svg_template.replace('__width__', - unicode_type(width)) + str(width)) self.svg_template = self.svg_template.replace('__height__', - unicode_type(height)) + str(height)) if href is not None: templ = self.non_svg_template if self.no_svg_cover \ diff --git a/src/calibre/ebooks/oeb/transforms/embed_fonts.py b/src/calibre/ebooks/oeb/transforms/embed_fonts.py index fcff0aabcf..6e7780e409 100644 --- a/src/calibre/ebooks/oeb/transforms/embed_fonts.py +++ b/src/calibre/ebooks/oeb/transforms/embed_fonts.py @@ -17,11 +17,11 @@ from calibre.ebooks.oeb.transforms.subset import get_font_properties, find_font_ from calibre.utils.filenames import ascii_filename from calibre.utils.fonts.scanner import font_scanner, NoFonts from calibre.ebooks.oeb.polish.embed import font_key -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def font_families_from_style(style): - return [unicode_type(f) for f in style.get('font-family', []) if unicode_type(f).lower() not in { + return [str(f) for f in style.get('font-family', []) if str(f).lower() not in { 'serif', 'sansserif', 'sans-serif', 'fantasy', 'cursive', 'monospace'}] @@ -39,7 +39,7 @@ def used_font(style, embedded_fonts): ff = font_families_from_style(style) if not ff: return False, None - lnames = {unicode_type(x).lower() for x in ff} + lnames = {str(x).lower() for x in ff} matching_set = [] @@ -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 a7eb4b25de..e9ee981765 100644 --- a/src/calibre/ebooks/oeb/transforms/flatcss.py +++ b/src/calibre/ebooks/oeb/transforms/flatcss.py @@ -21,7 +21,7 @@ from calibre.ebooks.oeb.base import (XHTML, XHTML_NS, CSS_MIME, OEB_STYLES, from calibre.ebooks.oeb.stylizer import Stylizer from calibre.utils.filenames import ascii_filename, ascii_text from calibre.utils.icu import numeric_sort_key -from polyglot.builtins import iteritems, unicode_type, string_or_bytes, map +from polyglot.builtins import iteritems, string_or_bytes COLLAPSE = re.compile(r'[ \t\r\n\v]+') STRIPNUM = re.compile(r'[-0-9]+$') @@ -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], @@ -251,7 +251,7 @@ class CSSFlattener: cfont = { 'font-family': '"%s"'%font['font-family'], - 'panose-1': ' '.join(map(unicode_type, font['panose'])), + 'panose-1': ' '.join(map(str, font['panose'])), 'src': 'url(%s)'%item.href, } @@ -477,7 +477,7 @@ class CSSFlattener: minlh = self.context.minimum_line_height / 100. slh = style['line-height'] if not is_drop_cap and isinstance(slh, numbers.Number) and slh < minlh * fsize: - cssdict['line-height'] = unicode_type(minlh) + cssdict['line-height'] = str(minlh) except Exception: self.oeb.logger.exception('Failed to set minimum line-height') @@ -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 @@ -539,7 +539,7 @@ class CSSFlattener: if css in styles: match = styles[css] else: - match = klass + unicode_type(names[klass] or '') + match = klass + str(names[klass] or '') styles[css] = match names[klass] += 1 node.attrib['class'] = match @@ -559,7 +559,7 @@ class CSSFlattener: # then the class attribute for a.x tags will contain both # that class and the class for a.x:hover, which is wrong. klass = 'pcalibre' - match = klass + unicode_type(names[klass] or '') + match = klass + str(names[klass] or '') pstyles[css] = match names[klass] += 1 keep_classes.add(match) diff --git a/src/calibre/ebooks/oeb/transforms/htmltoc.py b/src/calibre/ebooks/oeb/transforms/htmltoc.py index 3de45ebdf2..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. ''' @@ -9,7 +8,6 @@ __copyright__ = '2008, Marshall T. Vandegrift ' from calibre.ebooks.oeb.base import XML, XHTML, XHTML_NS from calibre.ebooks.oeb.base import XHTML_MIME, CSS_MIME from calibre.ebooks.oeb.base import element, XPath -from polyglot.builtins import unicode_type __all__ = ['HTMLTOCAdder'] @@ -95,7 +93,7 @@ class HTMLTOCAdder: style = 'nested' id, css_href = oeb.manifest.generate('tocstyle', 'tocstyle.css') oeb.manifest.add(id, css_href, CSS_MIME, data=STYLE_CSS[style]) - language = unicode_type(oeb.metadata.language[0]) + language = str(oeb.metadata.language[0]) contents = element(None, XHTML('html'), nsmap={None: XHTML_NS}, attrib={XML('lang'): language}) head = element(contents, XHTML('head')) diff --git a/src/calibre/ebooks/oeb/transforms/jacket.py b/src/calibre/ebooks/oeb/transforms/jacket.py index 87859f6790..fc621a032f 100644 --- a/src/calibre/ebooks/oeb/transforms/jacket.py +++ b/src/calibre/ebooks/oeb/transforms/jacket.py @@ -25,7 +25,6 @@ from calibre.library.comments import comments_to_html, markdown from calibre.utils.config import tweaks from calibre.utils.date import as_local_time, format_date, is_date_undefined from calibre.utils.icu import sort_key -from polyglot.builtins import map, unicode_type JACKET_XPATH = '//h:meta[@name="calibre-content" and @content="jacket"]' @@ -108,22 +107,22 @@ class Jacket(Base): self.log('Inserting metadata into book...') try: - tags = list(map(unicode_type, self.oeb.metadata.subject)) + tags = list(map(str, self.oeb.metadata.subject)) except Exception: tags = [] try: - comments = unicode_type(self.oeb.metadata.description[0]) + comments = str(self.oeb.metadata.description[0]) except: comments = '' try: - title = unicode_type(self.oeb.metadata.title[0]) + title = str(self.oeb.metadata.title[0]) except: title = _('Unknown') try: - authors = list(map(unicode_type, self.oeb.metadata.creator)) + authors = list(map(str, self.oeb.metadata.creator)) except: authors = [_('Unknown')] @@ -180,7 +179,7 @@ def get_rating(rating, rchar, e_rchar): return ans -class Series(unicode_type): +class Series(str): def __new__(self, series, series_index): if series and series_index is not None: @@ -189,8 +188,8 @@ class Series(unicode_type): combined = _('{1} of {0}').format( escape(series), escape(fmt_sidx(series_index, use_roman=False))) else: - combined = roman = escape(series or u'') - s = unicode_type.__new__(self, combined) + combined = roman = escape(series or '') + s = str.__new__(self, combined) s.roman = roman s.name = escape(series or '') s.number = escape(fmt_sidx(series_index or 1.0, use_roman=False)) @@ -219,11 +218,11 @@ class Timestamp: return '' -class Tags(unicode_type): +class Tags(str): def __new__(self, tags, output_profile): tags = [escape(x) for x in tags or ()] - t = unicode_type.__new__(self, ', '.join(tags)) + t = str.__new__(self, ', '.join(tags)) t.alphabetical = ', '.join(sorted(tags, key=sort_key)) t.tags_list = tags return t 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 bacae3d8ee..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. ''' @@ -17,7 +16,6 @@ from calibre.ebooks.oeb.base import urlnormalize from calibre.ebooks.oeb.stylizer import Stylizer from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.imghdr import what -from polyglot.builtins import unicode_type from polyglot.urllib import urldefrag IMAGE_TAGS = {XHTML('img'), XHTML('object')} @@ -77,7 +75,7 @@ class SVGRasterizer: logger.info('Found SVG image height in %, trying to convert...') try: h = float(image.get('height').replace('%', ''))/100. - image.set('height', unicode_type(h*sizes[1])) + image.set('height', str(h*sizes[1])) except: logger.exception('Failed to convert percentage height:', image.get('height')) @@ -223,11 +221,11 @@ class SVGRasterizer: covers = self.oeb.metadata.cover if not covers: return - if unicode_type(covers[0]) not in self.oeb.manifest.ids: + if str(covers[0]) not in self.oeb.manifest.ids: self.oeb.logger.warn('Cover not in manifest, skipping.') self.oeb.metadata.clear('cover') return - cover = self.oeb.manifest.ids[unicode_type(covers[0])] + cover = self.oeb.manifest.ids[str(covers[0])] if not cover.media_type == SVG_MIME: return width = (self.profile.width / 72) * self.profile.dpi diff --git a/src/calibre/ebooks/oeb/transforms/split.py b/src/calibre/ebooks/oeb/transforms/split.py index 0c5885af93..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' @@ -20,7 +19,7 @@ from calibre.ebooks.epub import rules from calibre.ebooks.oeb.base import (OEB_STYLES, XPNSMAP as NAMESPACES, urldefrag, rewrite_links, XHTML, urlnormalize) from calibre.ebooks.oeb.polish.split import do_split -from polyglot.builtins import iteritems, range, map, unicode_type +from polyglot.builtins import iteritems from polyglot.urllib import unquote from css_selectors import Select, SelectorError @@ -123,7 +122,7 @@ class Split: for i, elem in enumerate(item.data.iter('*')): try: - elem.set('pb_order', unicode_type(i)) + elem.set('pb_order', str(i)) except TypeError: # Can't set attributes on comment nodes etc. continue diff --git a/src/calibre/ebooks/oeb/transforms/structure.py b/src/calibre/ebooks/oeb/transforms/structure.py index bea143006b..53551feda7 100644 --- a/src/calibre/ebooks/oeb/transforms/structure.py +++ b/src/calibre/ebooks/oeb/transforms/structure.py @@ -13,7 +13,7 @@ from collections import OrderedDict, Counter from calibre.ebooks.oeb.base import XPNSMAP, TOC, XHTML, xml2text, barename from calibre.ebooks import ConversionError -from polyglot.builtins import itervalues, unicode_type +from polyglot.builtins import itervalues from polyglot.urllib import urlparse @@ -124,7 +124,7 @@ class DetectStructure: elem = matches[0] eid = elem.get('id', None) if not eid: - eid = 'start_reading_at_'+unicode_type(uuid.uuid4()).replace('-', '') + eid = 'start_reading_at_'+str(uuid.uuid4()).replace('-', '') elem.set('id', eid) if 'text' in self.oeb.guide: self.oeb.guide.remove('text') diff --git a/src/calibre/ebooks/oeb/transforms/subset.py b/src/calibre/ebooks/oeb/transforms/subset.py index 21b3a93185..0e62aff9b4 100644 --- a/src/calibre/ebooks/oeb/transforms/subset.py +++ b/src/calibre/ebooks/oeb/transforms/subset.py @@ -10,7 +10,7 @@ from collections import defaultdict from calibre.ebooks.oeb.base import urlnormalize, css_text from calibre.utils.fonts.sfnt.subset import subset, NoGlyphs, UnsupportedFont -from polyglot.builtins import iteritems, itervalues, unicode_type, range +from polyglot.builtins import iteritems, itervalues from tinycss.fonts3 import parse_font_family @@ -35,7 +35,7 @@ def get_font_properties(rule, default=None): except (IndexError, KeyError, AttributeError, TypeError, ValueError): val = None if q in {'src', 'font-family'} else default if q in {'font-weight', 'font-stretch', 'font-style'}: - val = unicode_type(val).lower() if (val or val == 0) else val + val = str(val).lower() if (val or val == 0) else val if val == 'inherit': val = default if q == 'font-weight': @@ -236,7 +236,7 @@ class SubsetFonts: no match is found (can happen if no family matches). ''' ff = style.get('font-family', []) - lnames = {unicode_type(x).lower() for x in ff} + lnames = {str(x).lower() for x in ff} matching_set = [] # Filter on font-family diff --git a/src/calibre/ebooks/pdb/ereader/reader132.py b/src/calibre/ebooks/pdb/ereader/reader132.py index 2bcab72d86..4e653de423 100644 --- a/src/calibre/ebooks/pdb/ereader/reader132.py +++ b/src/calibre/ebooks/pdb/ereader/reader132.py @@ -19,7 +19,6 @@ from calibre.ebooks import DRMError from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.pdb.ereader import EreaderError from calibre.ebooks.pdb.formatreader import FormatReader -from polyglot.builtins import unicode_type, range class HeaderRecord: @@ -115,7 +114,7 @@ class Reader132(FormatReader): os.makedirs(output_dir) title = self.mi.title - if not isinstance(title, unicode_type): + if not isinstance(title, str): title = title.decode('utf-8', 'replace') html = '%s' % title diff --git a/src/calibre/ebooks/pdb/ereader/reader202.py b/src/calibre/ebooks/pdb/ereader/reader202.py index 444137cba8..9ecec974af 100644 --- a/src/calibre/ebooks/pdb/ereader/reader202.py +++ b/src/calibre/ebooks/pdb/ereader/reader202.py @@ -15,7 +15,7 @@ from calibre import CurrentDir from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.pdb.ereader import EreaderError from calibre.ebooks.pdb.formatreader import FormatReader -from polyglot.builtins import as_unicode, range, unicode_type +from polyglot.builtins import as_unicode class HeaderRecord: @@ -98,7 +98,7 @@ class Reader202(FormatReader): pml += self.get_text_page(i) title = self.mi.title - if not isinstance(title, unicode_type): + if not isinstance(title, str): title = title.decode('utf-8', 'replace') html = '%s%s' % \ diff --git a/src/calibre/ebooks/pdb/ereader/writer.py b/src/calibre/ebooks/pdb/ereader/writer.py index 4e5043ad63..cae9f3838c 100644 --- a/src/calibre/ebooks/pdb/ereader/writer.py +++ b/src/calibre/ebooks/pdb/ereader/writer.py @@ -19,7 +19,7 @@ from PIL import Image from calibre.ebooks.pdb.formatwriter import FormatWriter from calibre.ebooks.pdb.header import PdbHeaderBuilder from calibre.ebooks.pml.pmlml import PMLMLizer -from polyglot.builtins import unicode_type, as_bytes +from polyglot.builtins import as_bytes IDENTITY = 'PNRdPPrs' @@ -36,7 +36,7 @@ class Writer(FormatWriter): def write_content(self, oeb_book, out_stream, metadata=None): pmlmlizer = PMLMLizer(self.log) - pml = unicode_type(pmlmlizer.extract_content(oeb_book, self.opts)).encode('cp1252', 'replace') + pml = str(pmlmlizer.extract_content(oeb_book, self.opts)).encode('cp1252', 'replace') text, text_sizes = self._text(pml) chapter_index = self._index_item(br'(?s)\\C(?P[0-4])="(?P.+?)"', pml) diff --git a/src/calibre/ebooks/pdb/haodoo/reader.py b/src/calibre/ebooks/pdb/haodoo/reader.py index 6118ee8dc8..cdf3400dd3 100644 --- a/src/calibre/ebooks/pdb/haodoo/reader.py +++ b/src/calibre/ebooks/pdb/haodoo/reader.py @@ -17,38 +17,37 @@ from calibre import prepare_string_for_xml from calibre.ebooks.pdb.formatreader import FormatReader from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.txt.processor import opf_writer, HTML_TEMPLATE -from polyglot.builtins import range, map 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" ", + "︵": "(", + "︶": ")", + "︷": "{", + "︸": "}", + "︹": "〔", + "︺": "〕", + "︻": "【", + "︼": "】", + "︗": "〖", + "︘": "〗", + "﹇": "[]", + "﹈": "[]", + "︽": "《", + "︾": "》", + "︿": "〈", + "﹀": "〉", + "﹁": "「", + "﹂": "」", + "﹃": "『", + "﹄": "』", + "|": "—", + "︙": "…", + "ⸯ": "~", + "│": "…", + "¦": "…", + " ": " ", } @@ -125,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 @@ -144,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/pdf/reader.py b/src/calibre/ebooks/pdb/pdf/reader.py index f683621e25..5b6a022035 100644 --- a/src/calibre/ebooks/pdb/pdf/reader.py +++ b/src/calibre/ebooks/pdb/pdf/reader.py @@ -12,7 +12,6 @@ __docformat__ = 'restructuredtext en' from calibre.ebooks.pdb.formatreader import FormatReader from calibre.ptempfile import PersistentTemporaryFile -from polyglot.builtins import range class Reader(FormatReader): diff --git a/src/calibre/ebooks/pdb/plucker/reader.py b/src/calibre/ebooks/pdb/plucker/reader.py index 0c090dd172..fa7af3cb44 100644 --- a/src/calibre/ebooks/pdb/plucker/reader.py +++ b/src/calibre/ebooks/pdb/plucker/reader.py @@ -16,7 +16,7 @@ from calibre.ebooks.pdb.formatreader import FormatReader from calibre.ebooks.compression.palmdoc import decompress_doc from calibre.utils.imghdr import identify from calibre.utils.img import save_cover_data_to, Canvas, image_from_data -from polyglot.builtins import codepoint_to_chr, range +from polyglot.builtins import codepoint_to_chr DATATYPE_PHTML = 0 DATATYPE_PHTML_COMPRESSED = 1 @@ -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 43c4bcda4c..2f82f75199 100644 --- a/src/calibre/ebooks/pdf/html_writer.py +++ b/src/calibre/ebooks/pdf/html_writer.py @@ -44,7 +44,7 @@ from calibre.utils.podofo import ( dedup_type3_fonts, get_podofo, remove_unused_fonts, set_metadata_implementation ) from calibre.utils.short_uuid import uuid4 -from polyglot.builtins import filter, iteritems, map, range, unicode_type +from polyglot.builtins import iteritems from polyglot.urllib import urlparse OK, KILL_SIGNAL = range(0, 2) @@ -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) @@ -645,7 +645,7 @@ def get_page_number_display_map(render_manager, opts, num_pages, log): for (var i=1; i <= NUM_PAGES; i++) ans[i] = map_num(i); JSON.stringify(ans); '''.replace('MAP_EXPRESSION', json.dumps(opts.pdf_page_number_map), 1).replace( - 'NUM_PAGES', unicode_type(num_pages), 1) + 'NUM_PAGES', str(num_pages), 1) result = render_manager.evaljs(js) try: result = json.loads(result) @@ -933,10 +933,10 @@ def add_header_footer(manager, opts, pdf_doc, container, page_number_display_map return ans def format_template(template, page_num, height): - template = template.replace('_TOP_LEVEL_SECTION_PAGES_', unicode_type(toplevel_pagenum_map[page_num - 1])) - template = template.replace('_TOP_LEVEL_SECTION_PAGENUM_', unicode_type(toplevel_pages_map[page_num - 1])) - template = template.replace('_TOTAL_PAGES_', unicode_type(pages_in_doc)) - template = template.replace('_PAGENUM_', unicode_type(page_number_display_map[page_num])) + template = template.replace('_TOP_LEVEL_SECTION_PAGES_', str(toplevel_pagenum_map[page_num - 1])) + template = template.replace('_TOP_LEVEL_SECTION_PAGENUM_', str(toplevel_pages_map[page_num - 1])) + template = template.replace('_TOTAL_PAGES_', str(pages_in_doc)) + template = template.replace('_PAGENUM_', str(page_number_display_map[page_num])) template = template.replace('_TITLE_', prepare_string_for_xml(pdf_metadata.title, True)) template = template.replace('_AUTHOR_', prepare_string_for_xml(pdf_metadata.author, True)) template = template.replace('_TOP_LEVEL_SECTION_', prepare_string_for_xml(toplevel_toc_map[page_num - 1])) diff --git a/src/calibre/ebooks/pdf/reflow.py b/src/calibre/ebooks/pdf/reflow.py index b8faef4aa5..7aec7f8458 100644 --- a/src/calibre/ebooks/pdf/reflow.py +++ b/src/calibre/ebooks/pdf/reflow.py @@ -11,7 +11,6 @@ from itertools import count from lxml import etree -from polyglot.builtins import range, map from calibre.utils.xml_parse import safe_xml_fromstring @@ -78,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) @@ -180,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) @@ -320,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: @@ -563,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 - @@ -695,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 9cfe82a9bf..71205f19d9 100644 --- a/src/calibre/ebooks/pdf/render/common.py +++ b/src/calibre/ebooks/pdf/render/common.py @@ -11,7 +11,7 @@ from io import BytesIO from datetime import datetime from calibre.utils.logging import default_log -from polyglot.builtins import iteritems, unicode_type, codepoint_to_chr +from polyglot.builtins import iteritems, codepoint_to_chr from polyglot.binary import as_hex_bytes from calibre_extensions.speedup import pdf_float @@ -57,7 +57,7 @@ PAPER_SIZES = {k:globals()[k.upper()] for k in ('a0 a1 a2 a3 a4 a5 a6 b0 b1 b2' def fmtnum(o): if isinstance(o, float): return pdf_float(o) - return unicode_type(o) + return str(o) def serialize(o, stream): @@ -67,7 +67,7 @@ def serialize(o, stream): # Must check bool before int as bools are subclasses of int stream.write_raw(b'true' if o else b'false') elif isinstance(o, numbers.Integral): - stream.write_raw(unicode_type(o).encode('ascii')) + stream.write_raw(str(o).encode('ascii')) elif hasattr(o, 'pdf_serialize'): o.pdf_serialize(stream) elif o is None: @@ -81,7 +81,7 @@ def serialize(o, stream): raise ValueError('Unknown object: %r'%o) -class Name(unicode_type): +class Name(str): def pdf_serialize(self, stream): raw = self.encode('ascii') @@ -118,7 +118,7 @@ def escape_pdf_string(bytestring): return bytes(ba) -class String(unicode_type): +class String(str): def pdf_serialize(self, stream): try: @@ -130,7 +130,7 @@ class String(unicode_type): stream.write(b'('+escape_pdf_string(raw)+b')') -class UTF16String(unicode_type): +class UTF16String(str): def pdf_serialize(self, stream): raw = codecs.BOM_UTF16_BE + self.encode('utf-16-be') @@ -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/fonts.py b/src/calibre/ebooks/pdf/render/fonts.py index 2522345a4c..5ddd7e4f2f 100644 --- a/src/calibre/ebooks/pdf/render/fonts.py +++ b/src/calibre/ebooks/pdf/render/fonts.py @@ -10,7 +10,7 @@ import re from itertools import groupby from operator import itemgetter from collections import Counter, OrderedDict -from polyglot.builtins import iteritems, map, zip, unicode_type, codepoint_to_chr +from polyglot.builtins import iteritems, codepoint_to_chr from calibre import as_unicode from calibre.ebooks.pdf.render.common import (Array, String, Stream, @@ -122,7 +122,7 @@ class Font: def __init__(self, metrics, num, objects, compress): self.metrics, self.compress = metrics, compress self.is_otf = self.metrics.is_otf - self.subset_tag = unicode_type( + self.subset_tag = str( re.sub('.', lambda m: codepoint_to_chr(int(m.group())+ord('A')), oct(num).replace('o', '') )).rjust(6, 'A') self.font_stream = FontStream(metrics.is_otf, compress=compress) diff --git a/src/calibre/ebooks/pdf/render/gradients.py b/src/calibre/ebooks/pdf/render/gradients.py index f39feedfdf..f2d6d88440 100644 --- a/src/calibre/ebooks/pdf/render/gradients.py +++ b/src/calibre/ebooks/pdf/render/gradients.py @@ -7,7 +7,6 @@ __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' import sys, copy -from polyglot.builtins import map, range from collections import namedtuple from qt.core import QLinearGradient, QPointF, sip 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 5df4fb1592..c922da96a5 100644 --- a/src/calibre/ebooks/pdf/render/serialize.py +++ b/src/calibre/ebooks/pdf/render/serialize.py @@ -7,7 +7,7 @@ __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' import hashlib, numbers -from polyglot.builtins import map, iteritems +from polyglot.builtins import iteritems from qt.core import QBuffer, QByteArray, QImage, Qt, QColor, qRgba, QPainter @@ -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/pml/__init__.py b/src/calibre/ebooks/pml/__init__.py index e4091d8e48..92cef986da 100644 --- a/src/calibre/ebooks/pml/__init__.py +++ b/src/calibre/ebooks/pml/__init__.py @@ -5,7 +5,6 @@ __license__ = 'GPL v3' __copyright__ = '2009, John Schember ' __docformat__ = 'restructuredtext en' -from polyglot.builtins import range def r(*a): diff --git a/src/calibre/ebooks/pml/pmlml.py b/src/calibre/ebooks/pml/pmlml.py index 83700ddf11..3b3853ef91 100644 --- a/src/calibre/ebooks/pml/pmlml.py +++ b/src/calibre/ebooks/pml/pmlml.py @@ -16,7 +16,7 @@ from lxml import etree from calibre.ebooks.pdb.ereader import image_name from calibre.utils.xml_parse import safe_xml_fromstring from calibre.ebooks.pml import unipmlcode -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes TAG_MAP = { 'b' : 'B', @@ -177,7 +177,7 @@ class PMLMLizer: def prepare_text(self, text): # Replace empty paragraphs with \c pml codes used to denote empty lines. - text = re.sub(unicode_type(r'(?<=

)\s*]*>[\xc2\xa0\s]*

'), r'\\c\n\\c', text) + text = re.sub(r'(?<=

)\s*]*>[\xc2\xa0\s]*

', r'\\c\n\\c', text) return text def clean_text(self, text): diff --git a/src/calibre/ebooks/rb/__init__.py b/src/calibre/ebooks/rb/__init__.py index 4a44bf10e3..6d0b69b892 100644 --- a/src/calibre/ebooks/rb/__init__.py +++ b/src/calibre/ebooks/rb/__init__.py @@ -7,7 +7,6 @@ __docformat__ = 'restructuredtext en' import os -from polyglot.builtins import unicode_type HEADER = b'\xb0\x0c\xb0\x0c\x02\x00NUVO\x00\x00\x00\x00' @@ -24,7 +23,7 @@ def unique_name(name, used_names): ext = os.path.splitext(name)[1][:3] base_name = name[:22] for i in range(0, 9999): - name = '%s-%s.%s' % (unicode_type(i).rjust('0', 4)[:4], base_name, ext) + name = '%s-%s.%s' % (str(i).rjust('0', 4)[:4], base_name, ext) if name not in used_names: break return name 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/rb/reader.py b/src/calibre/ebooks/rb/reader.py index 088308b83a..cda2f3898e 100644 --- a/src/calibre/ebooks/rb/reader.py +++ b/src/calibre/ebooks/rb/reader.py @@ -14,7 +14,7 @@ from calibre.ebooks.rb import HEADER from calibre.ebooks.rb import RocketBookError from calibre.ebooks.metadata.rb import get_metadata from calibre.ebooks.metadata.opf2 import OPFCreator -from polyglot.builtins import range, as_unicode +from polyglot.builtins import as_unicode from polyglot.urllib import unquote 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 4a72f053f7..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 @@ -7,7 +5,7 @@ import lxml.html from calibre.ebooks.readability.cleaners import normalize_spaces, clean_attributes from calibre.ebooks.chardet import xml_to_unicode -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def build_doc(page): @@ -122,5 +120,5 @@ def shorten_title(doc): def get_body(doc): [elem.drop_tree() for elem in doc.xpath('.//script | .//link | .//style')] - raw_html = unicode_type(tostring(doc.body or doc)) + raw_html = str(tostring(doc.body or doc)) return clean_attributes(raw_html) diff --git a/src/calibre/ebooks/readability/readability.py b/src/calibre/ebooks/readability/readability.py index 4853101aa0..52c8e8dc5c 100644 --- a/src/calibre/ebooks/readability/readability.py +++ b/src/calibre/ebooks/readability/readability.py @@ -5,7 +5,7 @@ import re, sys from collections import defaultdict -from polyglot.builtins import reraise, unicode_type +from polyglot.builtins import reraise from lxml.html import (fragment_fromstring, document_fromstring, tostring as htostring) @@ -15,7 +15,7 @@ from calibre.ebooks.readability.cleaners import html_cleaner, clean_attributes def tounicode(tree_or_node, **kwargs): - kwargs['encoding'] = unicode_type + kwargs['encoding'] = str return htostring(tree_or_node, **kwargs) @@ -156,7 +156,7 @@ class Document: return cleaned_article except Exception as e: self.log.exception('error getting summary: ') - reraise(Unparsable, Unparsable(unicode_type(e)), sys.exc_info()[2]) + reraise(Unparsable, Unparsable(str(e)), sys.exc_info()[2]) def get_article(self, candidates, best_candidate): # Now that we have the top candidate, look through its siblings for content that might also be related. @@ -216,7 +216,7 @@ class Document: def score_paragraphs(self, ): MIN_LEN = self.options.get('min_text_length', self.TEXT_LENGTH_THRESHOLD) candidates = {} - # self.debug(unicode_type([describe(node) for node in self.tags(self.html, "div")])) + # self.debug(str([describe(node) for node in self.tags(self.html, "div")])) ordered = [] for elem in self.tags(self.html, "p", "pre", "td"): @@ -313,7 +313,7 @@ class Document: def transform_misused_divs_into_paragraphs(self): for elem in self.tags(self.html, 'div'): # transform
s that do not contain other block elements into

s - if not REGEXES['divToPElementsRe'].search(unicode_type(''.join(map(tounicode, list(elem))))): + if not REGEXES['divToPElementsRe'].search(str(''.join(map(tounicode, list(elem))))): # self.debug("Altering %s to p" % (describe(elem))) elem.tag = "p" # print("Fixed element "+describe(elem)) @@ -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) @@ -457,7 +455,7 @@ class Document: siblings.append(sib_content_length) if j == x: break - # self.debug(unicode_type(siblings)) + # self.debug(str(siblings)) if siblings and sum(siblings) > 1000 : to_remove = False self.debug("Allowing %s" % describe(el)) 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 654c5803cd..f28844c0c9 100644 --- a/src/calibre/ebooks/rtf/rtfml.py +++ b/src/calibre/ebooks/rtf/rtfml.py @@ -19,7 +19,7 @@ from lxml import etree from calibre.ebooks.metadata import authors_to_string from calibre.utils.img import save_cover_data_to from calibre.utils.imghdr import identify -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes TAGS = { 'b': '\\b', @@ -78,7 +78,7 @@ def txt2rtf(text): text = text.replace('}', r'\'7d') text = text.replace('\\', r'\'5c') - if not isinstance(text, unicode_type): + if not isinstance(text, str): return text buf = io.StringIO() @@ -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 3c7065eb69..2e9d024baa 100644 --- a/src/calibre/ebooks/rtf2xml/ParseRtf.py +++ b/src/calibre/ebooks/rtf2xml/ParseRtf.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -26,7 +25,6 @@ from calibre.ebooks.rtf2xml import headings_to_sections, \ body_styles, preamble_rest, group_styles, \ inline from calibre.ebooks.rtf2xml.old_rtf import OldRtf -from polyglot.builtins import unicode_type from . import open_for_read, open_for_write @@ -250,7 +248,7 @@ class ParseRtf: enc = encode_obj.get_codepage() # TODO: to check if cp is a good idea or if I should use a dict to convert enc = 'cp' + enc - msg = '%s\nException in token processing' % unicode_type(msg) + msg = '%s\nException in token processing' % str(msg) if check_encoding_obj.check_encoding(self.__file, enc): file_name = self.__file if isinstance(self.__file, bytes) \ else self.__file.encode('utf-8') 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/check_encoding.py b/src/calibre/ebooks/rtf2xml/check_encoding.py index 1c14d66c3f..053d058100 100644 --- a/src/calibre/ebooks/rtf2xml/check_encoding.py +++ b/src/calibre/ebooks/rtf2xml/check_encoding.py @@ -3,7 +3,6 @@ import sys -from polyglot.builtins import unicode_type class CheckEncoding: @@ -18,7 +17,7 @@ class CheckEncoding: try: char.decode(encoding) except ValueError as msg: - sys.stderr.write('line: %s char: %s\n%s\n' % (line_num, char_position, unicode_type(msg))) + sys.stderr.write('line: %s char: %s\n%s\n' % (line_num, char_position, str(msg))) def check_encoding(self, path, encoding='us-ascii', verbose=True): line_num = 0 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 c6b7c8fdb2..7303f95011 100644 --- a/src/calibre/ebooks/rtf2xml/footnote.py +++ b/src/calibre/ebooks/rtf2xml/footnote.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -15,7 +14,6 @@ import os from calibre.ebooks.rtf2xml import copy from calibre.ptempfile import better_mktemp -from polyglot.builtins import unicode_type from . import open_for_read, open_for_write @@ -58,7 +56,7 @@ class Footnote: if self.__first_line: self.__first_line_func(line) if self.__token_info == 'cw 3: sys.stderr.write( 'Old rtf construction %s (bracket %s, line %s)\n' % ( - self.__inline_info, unicode_type(self.__ob_group), line_num) + self.__inline_info, str(self.__ob_group), line_num) ) return True self.__previous_token = line[6:16] 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 2af1af1506..7a3b7d1167 100644 --- a/src/calibre/ebooks/rtf2xml/output.py +++ b/src/calibre/ebooks/rtf2xml/output.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -12,7 +11,6 @@ # # ######################################################################### import sys, os -from polyglot.builtins import raw_input from . import open_for_read, open_for_write # , codecs @@ -84,7 +82,7 @@ class Output: msg += ('Type "o" to overwrite.\n' 'Type any other key to print to standard output.\n') sys.stderr.write(msg) - user_response = raw_input() + user_response = input() if user_response == 'o': with open_for_read(self.__file) as read_obj: with open_for_write(self.output_file) as write_obj: 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 e1992c34b1..1c5e870bde 100644 --- a/src/calibre/ebooks/rtf2xml/paragraph_def.py +++ b/src/calibre/ebooks/rtf2xml/paragraph_def.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -15,7 +14,6 @@ import sys, os from calibre.ebooks.rtf2xml import copy, border_parse from calibre.ptempfile import better_mktemp -from polyglot.builtins import unicode_type from . import open_for_read, open_for_write @@ -624,7 +622,7 @@ if another paragraph_def is found, the state changes to collect_tokens. num = len(self.__style_num_strings) new_style = 1 num = '%04d' % num - self.__att_val_dict['style-num'] = 's' + unicode_type(num) + self.__att_val_dict['style-num'] = 's' + str(num) if new_style: self.__write_body_styles() 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 2298dc98fc..e532c5f0a7 100644 --- a/src/calibre/ebooks/rtf2xml/pict.py +++ b/src/calibre/ebooks/rtf2xml/pict.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -15,7 +14,6 @@ import sys, os from calibre.ebooks.rtf2xml import copy from calibre.ptempfile import better_mktemp -from polyglot.builtins import unicode_type from . import open_for_read, open_for_write @@ -78,7 +76,7 @@ class Pict: try: os.mkdir(self.__dir_name) except OSError as msg: - msg = "%sCouldn't make directory '%s':\n" % (unicode_type(msg), self.__dir_name) + msg = "%sCouldn't make directory '%s':\n" % (str(msg), self.__dir_name) raise self.__bug_handler else: if self.__run_level > 1: 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 66f9d8192b..f704d625f9 100644 --- a/src/calibre/ebooks/rtf2xml/process_tokens.py +++ b/src/calibre/ebooks/rtf2xml/process_tokens.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -15,7 +14,6 @@ import os, re from calibre.ebooks.rtf2xml import copy, check_brackets from calibre.ptempfile import better_mktemp -from polyglot.builtins import unicode_type from . import open_for_read, open_for_write @@ -695,7 +693,7 @@ class ProcessTokens: if num[-1] == ';': num = num[:-1] third_field = 'en' - num = unicode_type('%X' % int(num)) + num = '%X' % int(num) if len(num) != 2: num = "0" + num return 'cw<%s<%s<%s<%s\n' % (pre, token, third_field, num) @@ -732,7 +730,7 @@ class ProcessTokens: return 0 num = '%0.2f' % round(numerator/denominator, 2) return num - string_num = unicode_type(num) + string_num = str(num) if string_num[-2:] == ".0": string_num = string_num[:-2] return string_num 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 817a6d6a14..b96e58a25e 100644 --- a/src/calibre/ebooks/rtf2xml/sections.py +++ b/src/calibre/ebooks/rtf2xml/sections.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -15,7 +14,6 @@ import sys, os from calibre.ebooks.rtf2xml import copy from calibre.ptempfile import better_mktemp -from polyglot.builtins import unicode_type from . import open_for_read, open_for_write @@ -276,8 +274,8 @@ class Sections: my_string += 'mi%s' 'rtf-native' '0\n' - % (unicode_type(self.__section_num), unicode_type(self.__section_num)) + % (str(self.__section_num), str(self.__section_num)) ) self.__found_first_sec = 1 elif self.__token_info == 'tx%s' 'rtf-native' '0\n' - % (unicode_type(self.__section_num), unicode_type(self.__section_num)) + % (str(self.__section_num), str(self.__section_num)) ) self.__write_obj.write( 'cw%s' % unicode_type(num) + 'mi%s' % str(num) ) if self.__list_of_sec_values: keys = self.__list_of_sec_values[0].keys() @@ -473,7 +471,7 @@ class Sections: self.__list_of_sec_values = self.__list_of_sec_values[1:] self.__write_obj.write('0') self.__write_obj.write('rtf-native') - self.__write_obj.write('%s' % unicode_type(self.__section_num)) + self.__write_obj.write('%s' % str(self.__section_num)) self.__write_obj.write('\n') # Look here 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 f045e77b04..0ba9553408 100644 --- a/src/calibre/ebooks/rtf2xml/table.py +++ b/src/calibre/ebooks/rtf2xml/table.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -15,7 +14,6 @@ import sys, os from calibre.ebooks.rtf2xml import copy, border_parse from calibre.ptempfile import better_mktemp -from polyglot.builtins import unicode_type from . import open_for_read, open_for_write @@ -400,13 +398,13 @@ class Table: left_position = float(left_position) width = new_cell_position - self.__last_cell_position - left_position # width = round(width, 2) - width = unicode_type('%.2f' % width) + width = '%.2f' % width self.__last_cell_position = new_cell_position widths_exists = self.__row_dict.get('widths') if widths_exists: - self.__row_dict['widths'] += ', %s' % unicode_type(width) + self.__row_dict['widths'] += ', %s' % str(width) else: - self.__row_dict['widths'] = unicode_type(width) + self.__row_dict['widths'] = str(width) self.__cell_list[-1]['width'] = width self.__cell_list.append({}) self.__cell_widths.append(width) 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 752a3ec82d..da4c1317e7 100644 --- a/src/calibre/ebooks/rtf2xml/tokenize.py +++ b/src/calibre/ebooks/rtf2xml/tokenize.py @@ -1,4 +1,3 @@ - ######################################################################### # # # # @@ -16,7 +15,7 @@ import os, re from calibre.ebooks.rtf2xml import copy from calibre.utils.mreplace import MReplace from calibre.ptempfile import better_mktemp -from polyglot.builtins import codepoint_to_chr, range, filter, map +from polyglot.builtins import codepoint_to_chr from . import open_for_read, open_for_write diff --git a/src/calibre/ebooks/snb/snbfile.py b/src/calibre/ebooks/snb/snbfile.py index d76d719d0b..57566afe0b 100644 --- a/src/calibre/ebooks/snb/snbfile.py +++ b/src/calibre/ebooks/snb/snbfile.py @@ -8,7 +8,6 @@ __docformat__ = 'restructuredtext en' import sys, struct, zlib, bz2, os from calibre import guess_type -from polyglot.builtins import unicode_type class FileStream: @@ -160,7 +159,7 @@ class SNBFile: with open(os.path.join(tdir,fileName), 'rb') as data: f.fileBody = data.read() f.fileName = fileName.replace(os.sep, '/') - if isinstance(f.fileName, unicode_type): + if isinstance(f.fileName, str): f.fileName = f.fileName.encode("ascii", "ignore") self.files.append(f) @@ -171,7 +170,7 @@ class SNBFile: with open(os.path.join(tdir,fileName), 'rb') as data: f.fileBody = data.read() f.fileName = fileName.replace(os.sep, '/') - if isinstance(f.fileName, unicode_type): + if isinstance(f.fileName, str): f.fileName = f.fileName.encode("ascii", "ignore") self.files.append(f) diff --git a/src/calibre/ebooks/snb/snbml.py b/src/calibre/ebooks/snb/snbml.py index 5186caddd4..3aa024d335 100644 --- a/src/calibre/ebooks/snb/snbml.py +++ b/src/calibre/ebooks/snb/snbml.py @@ -13,7 +13,7 @@ import os import re from lxml import etree -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes def ProcessFileName(fileName): @@ -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) @@ -130,7 +130,7 @@ class SNBMLizer: else: prefix = '' etree.SubElement(bodyTree, "text").text = \ - etree.CDATA(unicode_type(prefix + line)) + etree.CDATA(str(prefix + line)) if self.opts and self.opts.snb_insert_empty_line: etree.SubElement(bodyTree, "text").text = \ etree.CDATA('') 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 4abac7c89a..ec0b475a08 100644 --- a/src/calibre/ebooks/textile/functions.py +++ b/src/calibre/ebooks/textile/functions.py @@ -65,7 +65,6 @@ import re import uuid from calibre.utils.smartypants import smartyPants -from polyglot.builtins import unicode_type from polyglot.urllib import urlopen, urlparse @@ -101,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 @@ -690,7 +689,7 @@ class Textile: def footnoteID(self, match): id, t = match.groups() if id not in self.fn: - self.fn[id] = unicode_type(uuid.uuid4()) + self.fn[id] = str(uuid.uuid4()) fnid = self.fn[id] if not t: t = '' @@ -795,7 +794,7 @@ class Textile: return url def shelve(self, text): - id = unicode_type(uuid.uuid4()) + 'c' + id = str(uuid.uuid4()) + 'c' self.shelf[id] = text return id 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 b195170c87..91657f7c51 100644 --- a/src/calibre/ebooks/txt/markdownml.py +++ b/src/calibre/ebooks/txt/markdownml.py @@ -16,7 +16,7 @@ from functools import partial from calibre.ebooks.htmlz.oeb2html import OEB2HTML from calibre.ebooks.oeb.base import XHTML, XHTML_NS, barename, namespace, rewrite_links from calibre.ebooks.oeb.stylizer import Stylizer -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes class MarkdownMLizer(OEB2HTML): @@ -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 @@ -227,7 +227,7 @@ class MarkdownMLizer(OEB2HTML): text.append('+ ') elif li['name'] == 'ol': li['num'] += 1 - text.append(unicode_type(li['num']) + '. ') + text.append(str(li['num']) + '. ') # Process tags that contain text. if hasattr(elem, 'text') and elem.text: @@ -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 fe46e39b1d..37df950f8c 100644 --- a/src/calibre/ebooks/txt/processor.py +++ b/src/calibre/ebooks/txt/processor.py @@ -17,7 +17,7 @@ from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.conversion.preprocess import DocAnalysis from calibre.utils.cleantext import clean_ascii_chars -from polyglot.builtins import iteritems, unicode_type, map, range +from polyglot.builtins import iteritems HTML_TEMPLATE = '%s \n%s\n' @@ -62,7 +62,7 @@ def split_txt(txt, epub_split_size_kb=0): ''' # Takes care if there is no point to split if epub_split_size_kb > 0: - if isinstance(txt, unicode_type): + if isinstance(txt, str): txt = txt.encode('utf-8') if len(txt) > epub_split_size_kb * 1024: chunk_size = max(16, epub_split_size_kb - 32) * 1024 @@ -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/ebooks/unihandecode/pykakasi/h2a.py b/src/calibre/ebooks/unihandecode/pykakasi/h2a.py index ff76aa2e56..4a76457af0 100644 --- a/src/calibre/ebooks/unihandecode/pykakasi/h2a.py +++ b/src/calibre/ebooks/unihandecode/pykakasi/h2a.py @@ -22,9 +22,6 @@ # */ -from polyglot.builtins import range - - class H2a : H2a_table = { diff --git a/src/calibre/ebooks/unihandecode/pykakasi/jisyo.py b/src/calibre/ebooks/unihandecode/pykakasi/jisyo.py index a9feea295d..5b66e81a21 100644 --- a/src/calibre/ebooks/unihandecode/pykakasi/jisyo.py +++ b/src/calibre/ebooks/unihandecode/pykakasi/jisyo.py @@ -6,7 +6,6 @@ from zlib import decompress -from polyglot.builtins import unicode_type class jisyo : @@ -36,8 +35,8 @@ class jisyo : P('localization/pykakasi/kanadict2.calibre_msgpack', data=True)) def load_jisyo(self, char): - if not isinstance(char, unicode_type): - char = unicode_type(char, 'utf-8') + if not isinstance(char, str): + char = str(char, 'utf-8') key = "%04x"%ord(char) try: # already exist? diff --git a/src/calibre/ebooks/unihandecode/pykakasi/k2a.py b/src/calibre/ebooks/unihandecode/pykakasi/k2a.py index 02ce52ada9..117ef64b54 100644 --- a/src/calibre/ebooks/unihandecode/pykakasi/k2a.py +++ b/src/calibre/ebooks/unihandecode/pykakasi/k2a.py @@ -23,7 +23,6 @@ from calibre.ebooks.unihandecode.pykakasi.jisyo import jisyo -from polyglot.builtins import range class K2a : diff --git a/src/calibre/ebooks/unihandecode/unidecoder.py b/src/calibre/ebooks/unihandecode/unidecoder.py index 9c449b2aaf..cb9e9dc41e 100644 --- a/src/calibre/ebooks/unihandecode/unidecoder.py +++ b/src/calibre/ebooks/unihandecode/unidecoder.py @@ -63,7 +63,6 @@ it under the same terms as Perl itself. import re from calibre.ebooks.unihandecode.unicodepoints import CODEPOINTS from calibre.ebooks.unihandecode.zhcodepoints import CODEPOINTS as HANCODES -from polyglot.builtins import unicode_type class Unidecoder: @@ -96,8 +95,8 @@ class Unidecoder: Find what group character is a part of. ''' # Code groups within CODEPOINTS take the form 'xAB' - if not isinstance(character, unicode_type): - character = unicode_type(character, "utf-8") + if not isinstance(character, str): + character = str(character, "utf-8") return 'x%02x' % (ord(character) >> 8) def grouped_point(self, character): @@ -105,6 +104,6 @@ class Unidecoder: Return the location the replacement character is in the list for a the group character is a part of. ''' - if not isinstance(character, unicode_type): - character = unicode_type(character, "utf-8") + if not isinstance(character, str): + character = str(character, "utf-8") return ord(character) & 255 diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 23742b5733..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 ' @@ -38,9 +36,7 @@ from calibre.utils.date import UNDEFINED_DATE from calibre.utils.file_type_icons import EXT_MAP from calibre.utils.localization import get_lang from polyglot import queue -from polyglot.builtins import ( - iteritems, itervalues, range, string_or_bytes, unicode_type, map -) +from polyglot.builtins import iteritems, itervalues, string_or_bytes try: NO_URL_FORMATTING = QUrl.UrlFormattingOption.None_ @@ -424,7 +420,7 @@ def question_dialog(parent, title, msg, det_msg='', show_copy_button=False, from calibre.gui2.dialogs.message_box import MessageBox prefs = gui_prefs() - if not isinstance(skip_dialog_name, unicode_type): + if not isinstance(skip_dialog_name, str): skip_dialog_name = None try: auto_skip = set(prefs.get('questions_to_auto_skip', ())) @@ -644,7 +640,7 @@ class FileIconProvider(QFileIconProvider): if fileinfo.isDir(): key = 'dir' else: - ext = unicode_type(fileinfo.completeSuffix()).lower() + ext = str(fileinfo.completeSuffix()).lower() key = self.key_from_ext(ext) return self.cached_icon(key) @@ -770,7 +766,7 @@ class Translator(QTranslator): def translate(self, *args, **kwargs): try: - src = unicode_type(args[1]) + src = str(args[1]) except: return '' t = _ @@ -801,7 +797,7 @@ def load_builtin_fonts(): fid = QFontDatabase.addApplicationFontFromData(s.read()) if fid > -1: fam = QFontDatabase.applicationFontFamilies(fid) - fam = set(map(unicode_type, fam)) + fam = set(map(str, fam)) if 'calibre Symbols' in fam: _rating_font = 'calibre Symbols' @@ -881,7 +877,7 @@ class Application(QApplication): if iswindows: self.windows_app_uid = None if windows_app_uid: - windows_app_uid = unicode_type(windows_app_uid) + windows_app_uid = str(windows_app_uid) if set_app_uid(windows_app_uid): self.windows_app_uid = windows_app_uid self.file_event_hook = None @@ -894,7 +890,7 @@ class Application(QApplication): args = sys.argv[:1] args.extend(['-platformpluginpath', plugins_loc, '-platform', 'headless']) self.headless = headless - qargs = [i.encode('utf-8') if isinstance(i, unicode_type) else i for i in args] + qargs = [i.encode('utf-8') if isinstance(i, str) else i for i in args] from calibre_extensions import progress_indicator self.pi = progress_indicator if not ismacos and not headless: @@ -918,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') @@ -952,7 +948,7 @@ class Application(QApplication): self.line_height = max(12, QFontMetrics(self.font()).lineSpacing()) dl = QLocale(get_lang()) - if unicode_type(dl.bcp47Name()) != 'C': + if str(dl.bcp47Name()) != 'C': QLocale.setDefault(dl) global gui_thread, qt_app gui_thread = QThread.currentThread() @@ -1177,7 +1173,7 @@ class Application(QApplication): self._file_open_paths.append(url) QTimer.singleShot(1000, self._send_file_open_events) return True - path = unicode_type(e.file()) + path = str(e.file()) if os.access(path, os.R_OK): with self._file_open_lock: self._file_open_paths.append(path) @@ -1417,7 +1413,7 @@ def elided_text(text, font=None, width=300, pos='middle'): chomp = {'middle':remove_middle, 'left':lambda x:(ellipsis + x[delta:]), 'right':lambda x:(x[:-delta] + ellipsis)}[pos] while len(text) > delta and fm.width(text) > width: text = chomp(text) - return unicode_type(text) + return str(text) def find_forms(srcdir): @@ -1508,7 +1504,7 @@ def set_app_uid(val): AppUserModelID.argtypes = [wintypes.LPCWSTR] AppUserModelID.restype = HRESULT try: - AppUserModelID(unicode_type(val)) + AppUserModelID(str(val)) except Exception as err: prints('Failed to set app uid with error:', as_unicode(err)) return False @@ -1518,7 +1514,7 @@ def set_app_uid(val): def add_to_recent_docs(path): from calibre_extensions import winutil app = QApplication.instance() - winutil.add_to_recent_docs(unicode_type(path), app.windows_app_uid) + winutil.add_to_recent_docs(str(path), app.windows_app_uid) def windows_is_system_dark_mode_enabled(): diff --git a/src/calibre/gui2/actions/__init__.py b/src/calibre/gui2/actions/__init__.py index 44bd894c77..194df43693 100644 --- a/src/calibre/gui2/actions/__init__.py +++ b/src/calibre/gui2/actions/__init__.py @@ -16,7 +16,7 @@ from calibre import prints from calibre.constants import ismacos from calibre.gui2 import Dispatcher from calibre.gui2.keyboard import NameConflict -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes def menu_action_unique_name(plugin, unique_name): @@ -164,7 +164,7 @@ class InterfaceAction(QObject): action = QAction(text, self.gui) if attr == 'qaction': if hasattr(self.action_menu_clone_qaction, 'rstrip'): - mt = unicode_type(self.action_menu_clone_qaction) + mt = str(self.action_menu_clone_qaction) else: mt = action.text() self.menuless_qaction = ma = QAction(action.icon(), mt, self.gui) @@ -183,7 +183,7 @@ class InterfaceAction(QObject): keys = ((shortcut,) if isinstance(shortcut, string_or_bytes) else tuple(shortcut)) if shortcut_name is None and spec[0]: - shortcut_name = unicode_type(spec[0]) + shortcut_name = str(spec[0]) if shortcut_name and self.action_spec[0] and not ( attr == 'qaction' and self.popup_type == QToolButton.ToolButtonPopupMode.InstantPopup): @@ -195,7 +195,7 @@ class InterfaceAction(QObject): persist_shortcut=persist_shortcut) except NameConflict as e: try: - prints(unicode_type(e)) + prints(str(e)) except: pass shortcut_action.setShortcuts([QKeySequence(key, @@ -250,7 +250,7 @@ class InterfaceAction(QObject): ''' if shortcut_name is None: - shortcut_name = unicode_type(text) + shortcut_name = str(text) ac = menu.addAction(text) if icon is not None: if not isinstance(icon, QIcon): diff --git a/src/calibre/gui2/actions/add.py b/src/calibre/gui2/actions/add.py index cfe65c8c2a..661f053ba8 100644 --- a/src/calibre/gui2/actions/add.py +++ b/src/calibre/gui2/actions/add.py @@ -27,7 +27,7 @@ from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.config_base import tweaks from calibre.utils.filenames import ascii_filename, make_long_path_useable from calibre.utils.icu import sort_key -from polyglot.builtins import iteritems, range, string_or_bytes +from polyglot.builtins import iteritems, string_or_bytes def get_filters(): diff --git a/src/calibre/gui2/actions/annotate.py b/src/calibre/gui2/actions/annotate.py index a618e3b63b..c0a5f2bfc6 100644 --- a/src/calibre/gui2/actions/annotate.py +++ b/src/calibre/gui2/actions/annotate.py @@ -13,7 +13,7 @@ from calibre.gui2 import error_dialog from calibre.gui2.actions import InterfaceAction from calibre.devices.usbms.device import Device from calibre.gui2.dialogs.progress import ProgressDialog -from polyglot.builtins import iteritems, range, map +from polyglot.builtins import iteritems class Updater(QThread): # {{{ @@ -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/author_mapper.py b/src/calibre/gui2/actions/author_mapper.py index 3616901b3b..4f1f4ae99f 100644 --- a/src/calibre/gui2/actions/author_mapper.py +++ b/src/calibre/gui2/actions/author_mapper.py @@ -6,7 +6,7 @@ from qt.core import QDialog from calibre.gui2 import gprefs from calibre.gui2.actions import InterfaceAction -from polyglot.builtins import iteritems, map, range +from polyglot.builtins import iteritems class AuthorMapAction(InterfaceAction): 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 cdb998954d..80be87eae3 100644 --- a/src/calibre/gui2/actions/catalog.py +++ b/src/calibre/gui2/actions/catalog.py @@ -15,7 +15,6 @@ from calibre.gui2.tools import generate_catalog from calibre.utils.config import dynamic from calibre.gui2.actions import InterfaceAction from calibre import sanitize_file_name -from polyglot.builtins import range, map class GenerateCatalogAction(InterfaceAction): @@ -100,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/choose_library.py b/src/calibre/gui2/actions/choose_library.py index 7cb3ec20ac..b71332e666 100644 --- a/src/calibre/gui2/actions/choose_library.py +++ b/src/calibre/gui2/actions/choose_library.py @@ -20,7 +20,6 @@ from calibre.utils.icu import sort_key from calibre.gui2 import (gprefs, warning_dialog, Dispatcher, error_dialog, question_dialog, info_dialog, open_local_file, choose_dir) from calibre.gui2.actions import InterfaceAction -from polyglot.builtins import unicode_type, range def db_class(): @@ -144,7 +143,7 @@ class MovedDialog(QDialog): # {{{ self.stats.remove(self.location) def accept(self): - newloc = unicode_type(self.loc.text()) + newloc = str(self.loc.text()) if not db_class().exists_at(newloc): error_dialog(self, _('No library found'), _('No existing calibre library found at %s')%newloc, @@ -269,7 +268,7 @@ class ChooseLibraryAction(InterfaceAction): for i in range(5): ac = self.create_action(spec=('', None, None, None), attr='switch_action%d'%i) - ac.setObjectName(unicode_type(i)) + ac.setObjectName(str(i)) self.switch_actions.append(ac) ac.setVisible(False) connect_lambda(ac.triggered, self, lambda self: @@ -474,7 +473,7 @@ class ChooseLibraryAction(InterfaceAction): 'Choose a new name for the library %s. ')%name + '

'+_( 'Note that the actual library folder will be renamed.'), text=old_name) - newname = sanitize_file_name(unicode_type(newname)) + newname = sanitize_file_name(str(newname)) if not ok or not newname or newname == old_name: return newloc = os.path.join(base, newname) 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/copy_to_library.py b/src/calibre/gui2/actions/copy_to_library.py index 9407901ac7..f0c6c25c69 100644 --- a/src/calibre/gui2/actions/copy_to_library.py +++ b/src/calibre/gui2/actions/copy_to_library.py @@ -27,7 +27,7 @@ from calibre.gui2.widgets2 import Dialog from calibre.utils.config import prefs from calibre.utils.icu import sort_key, numeric_sort_key from calibre.db.copy_to_library import copy_one_book -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues def ask_about_cc_mismatch(gui, db, newdb, missing_cols, incompatible_cols): # {{{ @@ -134,7 +134,7 @@ class Worker(Thread): # {{{ except Exception as err: import traceback try: - err = unicode_type(err) + err = str(err) except: err = repr(err) self.error = (err, traceback.format_exc()) @@ -263,7 +263,7 @@ class ChooseLibrary(Dialog): # {{{ @property def args(self): - return (unicode_type(self.le.text()), self.delete_after_copy) + return (str(self.le.text()), self.delete_after_copy) # }}} @@ -301,7 +301,7 @@ class DuplicatesQuestion(QDialog): # {{{ self.resize(600, 400) def copy_to_clipboard(self): - items = [('✓' if item.checkState() == Qt.CheckState.Checked else '✗') + ' ' + unicode_type(item.text()) + items = [('✓' if item.checkState() == Qt.CheckState.Checked else '✗') + ' ' + str(item.text()) for item in self.items] QApplication.clipboard().setText('\n'.join(items)) 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/device.py b/src/calibre/gui2/actions/device.py index c2cfcad581..90e2936ef9 100644 --- a/src/calibre/gui2/actions/device.py +++ b/src/calibre/gui2/actions/device.py @@ -13,7 +13,6 @@ from calibre.gui2.actions import InterfaceAction from calibre.gui2.dialogs.smartdevice import SmartdeviceDialog from calibre.utils.icu import primary_sort_key from calibre.utils.smtp import config as email_config -from polyglot.builtins import unicode_type class ShareConnMenu(QMenu): # {{{ @@ -56,7 +55,7 @@ class ShareConnMenu(QMenu): # {{{ gr = ConnectShareAction.action_spec[0] for attr in ('folder', ): ac = getattr(self, 'connect_to_%s_action'%attr) - r(prefix + attr, unicode_type(ac.text()), action=ac, + r(prefix + attr, str(ac.text()), action=ac, group=gr) r(prefix+' content server', _('Start/stop Content server'), action=self.toggle_server_action, group=gr) diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py index b37a1bfac3..edadd5dc49 100644 --- a/src/calibre/gui2/actions/edit_metadata.py +++ b/src/calibre/gui2/actions/edit_metadata.py @@ -30,7 +30,7 @@ from calibre.library.comments import merge_comments from calibre.utils.config import tweaks from calibre.utils.date import is_date_undefined from calibre.utils.icu import sort_key -from polyglot.builtins import iteritems, map, unicode_type +from polyglot.builtins import iteritems class EditMetadataAction(InterfaceAction): @@ -173,7 +173,7 @@ class EditMetadataAction(InterfaceAction): book_id = db.id(rows[0].row()) mi = db.new_api.get_metadata(book_id) md = QMimeData() - md.setText(unicode_type(mi)) + md.setText(str(mi)) md.setData('application/calibre-book-metadata', bytearray(metadata_to_opf(mi, default_lang='und'))) img = db.new_api.cover(book_id, as_image=True) if img: @@ -702,7 +702,7 @@ class EditMetadataAction(InterfaceAction): if not dest_mi.comments: dest_mi.comments = src_mi.comments else: - dest_mi.comments = unicode_type(dest_mi.comments) + '\n\n' + unicode_type(src_mi.comments) + dest_mi.comments = str(dest_mi.comments) + '\n\n' + str(src_mi.comments) if src_mi.title and (not dest_mi.title or dest_mi.title == _('Unknown')): dest_mi.title = src_mi.title if (src_mi.authors and src_mi.authors[0] != _('Unknown')) and (not dest_mi.authors or dest_mi.authors[0] == _('Unknown')): @@ -755,7 +755,7 @@ class EditMetadataAction(InterfaceAction): if not dest_value: db.set_custom(dest_id, src_value, num=colnum) else: - dest_value = unicode_type(dest_value) + '\n\n' + unicode_type(src_value) + dest_value = str(dest_value) + '\n\n' + str(src_value) db.set_custom(dest_id, dest_value, num=colnum) if (dt in {'bool', 'int', 'float', 'rating', 'datetime'} and dest_value is None): db.set_custom(dest_id, src_value, num=colnum) @@ -781,7 +781,7 @@ class EditMetadataAction(InterfaceAction): to_rename = d.to_rename # dict of new text to old ids to_delete = d.to_delete # list of ids for old_id, new_name in iteritems(to_rename): - model.rename_collection(old_id, new_name=unicode_type(new_name)) + model.rename_collection(old_id, new_name=str(new_name)) for item in to_delete: model.delete_collection_using_id(item) self.gui.upload_collections(model.db, view=view, oncard=oncard) diff --git a/src/calibre/gui2/actions/mark_books.py b/src/calibre/gui2/actions/mark_books.py index 9146386ce0..15464d093c 100644 --- a/src/calibre/gui2/actions/mark_books.py +++ b/src/calibre/gui2/actions/mark_books.py @@ -11,7 +11,6 @@ from qt.core import QTimer, QApplication, Qt, QEvent from calibre.gui2 import error_dialog from calibre.gui2.actions import InterfaceAction -from polyglot.builtins import unicode_type class MarkBooksAction(InterfaceAction): @@ -120,7 +119,7 @@ class MarkBooksAction(InterfaceAction): def clear_all_marked(self): self.gui.current_db.data.set_marked_ids(()) - if unicode_type(self.gui.search.text()).startswith('marked:'): + if str(self.gui.search.text()).startswith('marked:'): self.gui.search.set_search_string('') def mark_field(self, field, add): diff --git a/src/calibre/gui2/actions/polish.py b/src/calibre/gui2/actions/polish.py index 15f66cf543..7f92017582 100644 --- a/src/calibre/gui2/actions/polish.py +++ b/src/calibre/gui2/actions/polish.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import os, weakref, shutil, textwrap from collections import OrderedDict from functools import partial -from polyglot.builtins import iteritems, itervalues, map, unicode_type +from polyglot.builtins import iteritems, itervalues from qt.core import (QDialog, QGridLayout, QIcon, QCheckBox, QLabel, QFrame, QApplication, QDialogButtonBox, Qt, QSize, QSpacerItem, @@ -159,7 +159,7 @@ class Polish(QDialog): # {{{ name, ok = QInputDialog.getText(self, _('Choose name'), _('Choose a name for these settings')) if ok: - name = unicode_type(name).strip() + name = str(name).strip() if name: settings = {ac:getattr(self, 'opt_'+ac).isChecked() for ac in self.all_actions} @@ -198,7 +198,7 @@ class Polish(QDialog): # {{{ self.help_label.setText(self.help_text[name]) def help_link_activated(self, link): - link = unicode_type(link)[1:] + link = str(link)[1:] self.help_label.setText(self.help_text[link]) @property @@ -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') @@ -272,7 +272,7 @@ class Polish(QDialog): # {{{ QTimer.singleShot(0, self.do_one) def do_book(self, num, book_id, formats): - base = os.path.join(self.tdir, unicode_type(book_id)) + base = os.path.join(self.tdir, str(book_id)) os.mkdir(base) db = self.db() opf = os.path.join(base, 'metadata.opf') @@ -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/actions/save_to_disk.py b/src/calibre/gui2/actions/save_to_disk.py index 780fbe7314..fc28a97d8b 100644 --- a/src/calibre/gui2/actions/save_to_disk.py +++ b/src/calibre/gui2/actions/save_to_disk.py @@ -12,7 +12,7 @@ from functools import partial from calibre.utils.config import prefs from calibre.gui2 import error_dialog, Dispatcher, choose_dir from calibre.gui2.actions import InterfaceAction -from polyglot.builtins import itervalues, map +from polyglot.builtins import itervalues class SaveToDiskAction(InterfaceAction): diff --git a/src/calibre/gui2/actions/tag_mapper.py b/src/calibre/gui2/actions/tag_mapper.py index dfb8e9c0b8..e684b86f33 100644 --- a/src/calibre/gui2/actions/tag_mapper.py +++ b/src/calibre/gui2/actions/tag_mapper.py @@ -4,7 +4,7 @@ from qt.core import QDialog -from polyglot.builtins import iteritems, map, range +from polyglot.builtins import iteritems from calibre.gui2 import gprefs from calibre.gui2.actions import InterfaceAction diff --git a/src/calibre/gui2/actions/toc_edit.py b/src/calibre/gui2/actions/toc_edit.py index b0ebee7aec..69265ac540 100644 --- a/src/calibre/gui2/actions/toc_edit.py +++ b/src/calibre/gui2/actions/toc_edit.py @@ -15,7 +15,7 @@ from qt.core import ( from calibre.gui2 import error_dialog, gprefs, question_dialog from calibre.gui2.actions import InterfaceAction from calibre.utils.monotonic import monotonic -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems SUPPORTED = {'EPUB', 'AZW3'} @@ -56,7 +56,7 @@ class ChooseFormat(QDialog): # {{{ def formats(self): for b in self.buttons: if b.isChecked(): - yield unicode_type(b.text())[1:] + yield str(b.text())[1:] @formats.setter def formats(self, formats): diff --git a/src/calibre/gui2/actions/unpack_book.py b/src/calibre/gui2/actions/unpack_book.py index 6b646aa465..dbea570b46 100644 --- a/src/calibre/gui2/actions/unpack_book.py +++ b/src/calibre/gui2/actions/unpack_book.py @@ -18,7 +18,6 @@ from calibre.gui2.actions import InterfaceAction from calibre.ptempfile import (PersistentTemporaryDirectory, PersistentTemporaryFile) from calibre.utils.config import prefs, tweaks -from polyglot.builtins import unicode_type class UnpackBook(QDialog): @@ -36,7 +35,7 @@ class UnpackBook(QDialog): index_is_id=True)) button = self.fmt_choice_buttons[0] - button_map = {unicode_type(x.text()):x for x in self.fmt_choice_buttons} + button_map = {str(x.text()):x for x in self.fmt_choice_buttons} of = prefs['output_format'].upper() df = tweaks.get('default_tweak_format', None) lf = gprefs.get('last_tweak_format', None) @@ -283,7 +282,7 @@ class UnpackBook(QDialog): def current_format(self): for b in self.fmt_choice_buttons: if b.isChecked(): - return unicode_type(b.text()) + return str(b.text()) class UnpackBookAction(InterfaceAction): diff --git a/src/calibre/gui2/actions/view.py b/src/calibre/gui2/actions/view.py index 2f067743a8..189459a778 100644 --- a/src/calibre/gui2/actions/view.py +++ b/src/calibre/gui2/actions/view.py @@ -21,7 +21,7 @@ from calibre.gui2.actions import InterfaceAction from calibre.gui2.dialogs.choose_format import ChooseFormatDialog from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.config import prefs, tweaks -from polyglot.builtins import as_bytes, unicode_type +from polyglot.builtins import as_bytes def preferred_format(formats): @@ -180,7 +180,7 @@ class ViewAction(InterfaceAction): ext = name.rpartition('.')[-1] if ext: try: - prog = winutil.file_association(unicode_type('.' + ext)) + prog = winutil.file_association(str('.' + ext)) except Exception: prog = None if prog and prog.lower().endswith('calibre.exe'): diff --git a/src/calibre/gui2/add.py b/src/calibre/gui2/add.py index bad02f007e..0e4211991d 100644 --- a/src/calibre/gui2/add.py +++ b/src/calibre/gui2/add.py @@ -33,7 +33,7 @@ from calibre.utils import join_with_timeout from calibre.utils.config import prefs from calibre.utils.filenames import make_long_path_useable from calibre.utils.ipc.pool import Failure, Pool -from polyglot.builtins import iteritems, map, string_or_bytes, unicode_type +from polyglot.builtins import iteritems, string_or_bytes from polyglot.queue import Empty @@ -180,7 +180,7 @@ class Adder(QObject): self.file_groups[len(self.file_groups)] = files else: def find_files(root): - if isinstance(root, unicode_type): + if isinstance(root, str): root = root.encode(filesystem_encoding) for dirpath, dirnames, filenames in os.walk(root): try: @@ -314,7 +314,7 @@ class Adder(QObject): except Failure as err: error_dialog(self.pd, _('Cannot add books'), _( 'Failed to add some books, click "Show details" for more information.'), - det_msg=unicode_type(err.failure_message) + '\n' + unicode_type(err.details), show=True) + det_msg=str(err.failure_message) + '\n' + str(err.details), show=True) self.pd.canceled = True else: # All tasks completed diff --git a/src/calibre/gui2/add_filters.py b/src/calibre/gui2/add_filters.py index b00fe84d0f..4894049973 100644 --- a/src/calibre/gui2/add_filters.py +++ b/src/calibre/gui2/add_filters.py @@ -4,7 +4,6 @@ from collections import OrderedDict -from polyglot.builtins import map, unicode_type from calibre.db.adding import compile_glob, filter_filename, compile_rule from calibre.gui2 import elided_text, Application, error_dialog @@ -64,15 +63,15 @@ class RuleEdit(RuleEditBase): def rule(self, rule): def sc(name): c = getattr(self, name) - idx = c.findData(unicode_type(rule.get(name, ''))) + idx = c.findData(str(rule.get(name, ''))) if idx < 0: idx = 0 c.setCurrentIndex(idx) sc('action'), sc('match_type') - self.query.setText(unicode_type(rule.get('query', '')).strip()) + 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/author_mapper.py b/src/calibre/gui2/author_mapper.py index 322cc415b3..3191a76237 100644 --- a/src/calibre/gui2/author_mapper.py +++ b/src/calibre/gui2/author_mapper.py @@ -14,7 +14,6 @@ from calibre.gui2.tag_mapper import ( Tester as TesterBase ) from calibre.utils.config import JSONConfig -from polyglot.builtins import unicode_type author_maps = JSONConfig('author-mapping-rules') @@ -66,13 +65,13 @@ class RuleEdit(RuleEditBase): def rule(self, rule): def sc(name): c = getattr(self, name) - idx = c.findData(unicode_type(rule.get(name, ''))) + idx = c.findData(str(rule.get(name, ''))) if idx < 0: idx = 0 c.setCurrentIndex(idx) sc('match_type'), sc('action') - self.query.setText(unicode_type(rule.get('query', '')).strip()) - self.replace.setText(unicode_type(rule.get('replace', '')).strip()) + self.query.setText(str(rule.get('query', '')).strip()) + self.replace.setText(str(rule.get('replace', '')).strip()) class RuleEditDialog(RuleEditDialogBase): diff --git a/src/calibre/gui2/auto_add.py b/src/calibre/gui2/auto_add.py index fbaf3a10ff..fb41e3026f 100644 --- a/src/calibre/gui2/auto_add.py +++ b/src/calibre/gui2/auto_add.py @@ -17,7 +17,6 @@ from calibre.ebooks import BOOK_EXTENSIONS from calibre.gui2 import gprefs from calibre.gui2.dialogs.duplicates import DuplicatesQuestion from calibre.utils.tdir_in_cache import tdir_in_cache -from polyglot.builtins import map AUTO_ADDED = frozenset(BOOK_EXTENSIONS) - {'pdr', 'mbp', 'tan'} @@ -107,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 6a0ff0acdb..51b03acf56 100644 --- a/src/calibre/gui2/bars.py +++ b/src/calibre/gui2/bars.py @@ -14,7 +14,7 @@ from qt.core import ( from calibre.constants import ismacos from calibre.gui2 import gprefs, native_menubar_defaults, config from calibre.gui2.throbber import ThrobbingButton -from polyglot.builtins import itervalues, unicode_type, map, range +from polyglot.builtins import itervalues class RevealBar(QWidget): # {{{ @@ -300,7 +300,7 @@ class ToolBar(QToolBar): # {{{ mime = 'application/calibre+from_device' if md.hasFormat(mime): - paths = [unicode_type(u.toLocalFile()) for u in md.urls()] + paths = [str(u.toLocalFile()) for u in md.urls()] if paths: self.gui.iactions['Add Books'].add_books_from_device( self.gui.current_view(), paths=paths) @@ -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 1325a00771..c5177b022b 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -36,7 +36,6 @@ from calibre.utils.img import blend_image, image_from_x from calibre.utils.localization import is_rtl, langnames_to_langcodes from calibre.utils.serialize import json_loads from polyglot.binary import from_hex_bytes -from polyglot.builtins import unicode_type InternetSearch = namedtuple('InternetSearch', 'author where') @@ -59,7 +58,7 @@ def css(reset=False): del css.ans if not hasattr(css, 'ans'): val = P('templates/book_details.css', data=True).decode('utf-8') - css.ans = re.sub(unicode_type(r'/\*.*?\*/'), '', val, flags=re.DOTALL) + css.ans = re.sub(r'/\*.*?\*/', '', val, flags=re.DOTALL) return css.ans @@ -73,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() @@ -180,7 +179,7 @@ def render_html(mi, vertical, widget, all_fields=False, render_data_func=None, p if col.isValid(): col = col.toRgb() if col.isValid(): - ans = unicode_type(col.name()) + ans = str(col.name()) return ans templ = '''\ @@ -395,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}') @@ -789,9 +788,9 @@ class BookInfo(HTMLDisplay): self.manage_category.emit(*self.manage_action.current_fmt) def link_activated(self, link): - if unicode_type(link.scheme()) in ('http', 'https'): + if str(link.scheme()) in ('http', 'https'): return safe_open_url(link) - link = unicode_type(link.toString(NO_URL_FORMATTING)) + link = str(link.toString(NO_URL_FORMATTING)) self.link_clicked.emit(link) def show_data(self, mi): diff --git a/src/calibre/gui2/catalog/catalog_bibtex.py b/src/calibre/gui2/catalog/catalog_bibtex.py index 3f4072999b..0932cdfecf 100644 --- a/src/calibre/gui2/catalog/catalog_bibtex.py +++ b/src/calibre/gui2/catalog/catalog_bibtex.py @@ -11,7 +11,6 @@ from qt.core import QWidget, QListWidgetItem from calibre.gui2 import gprefs from calibre.gui2.catalog.catalog_bibtex_ui import Ui_Form -from polyglot.builtins import unicode_type, range class PluginWidget(QWidget, Ui_Form): @@ -51,7 +50,7 @@ class PluginWidget(QWidget, Ui_Form): # Restore the activated db_fields from last use for x in range(self.db_fields.count()): item = self.db_fields.item(x) - item.setSelected(unicode_type(item.text()) in fields) + item.setSelected(str(item.text()) in fields) self.bibfile_enc.clear() self.bibfile_enc.addItems(['utf-8', 'cp1252', 'ascii/LaTeX']) self.bibfile_enctag.clear() @@ -76,12 +75,12 @@ class PluginWidget(QWidget, Ui_Form): for x in range(self.db_fields.count()): item = self.db_fields.item(x) if item.isSelected(): - fields.append(unicode_type(item.text())) + fields.append(str(item.text())) gprefs.set(self.name+'_db_fields', fields) # Dictionary currently activated fields if len(self.db_fields.selectedItems()): - opts_dict = {'fields':[unicode_type(i.text()) for i in self.db_fields.selectedItems()]} + opts_dict = {'fields':[str(i.text()) for i in self.db_fields.selectedItems()]} else: opts_dict = {'fields':['all']} @@ -94,7 +93,7 @@ class PluginWidget(QWidget, Ui_Form): elif opt[0] in ['impcit', 'addfiles'] : opt_value = getattr(self, opt[0]).isChecked() else : - opt_value = unicode_type(getattr(self, opt[0]).text()) + opt_value = str(getattr(self, opt[0]).text()) gprefs.set(self.name + '_' + opt[0], opt_value) opts_dict[opt[0]] = opt_value diff --git a/src/calibre/gui2/catalog/catalog_csv_xml.py b/src/calibre/gui2/catalog/catalog_csv_xml.py index 9242287143..c18b9a3c3b 100644 --- a/src/calibre/gui2/catalog/catalog_csv_xml.py +++ b/src/calibre/gui2/catalog/catalog_csv_xml.py @@ -11,7 +11,6 @@ from qt.core import QWidget, QListWidgetItem, Qt, QVBoxLayout, QLabel, QListWidg from calibre.constants import ismacos from calibre.gui2 import gprefs from calibre.gui2.ui import get_gui -from polyglot.builtins import unicode_type, range def get_saved_field_data(name, all_fields): @@ -87,16 +86,16 @@ class PluginWidget(QWidget): # Restore the activated fields from last use for x in range(self.db_fields.count()): item = self.db_fields.item(x) - item.setCheckState(Qt.CheckState.Checked if unicode_type(item.data(Qt.ItemDataRole.UserRole)) in fields else Qt.CheckState.Unchecked) + item.setCheckState(Qt.CheckState.Checked if str(item.data(Qt.ItemDataRole.UserRole)) in fields else Qt.CheckState.Unchecked) def options(self): # Save the currently activated fields fields, all_fields = [], [] for x in range(self.db_fields.count()): item = self.db_fields.item(x) - all_fields.append(unicode_type(item.data(Qt.ItemDataRole.UserRole))) + all_fields.append(str(item.data(Qt.ItemDataRole.UserRole))) if item.checkState() == Qt.CheckState.Checked: - fields.append(unicode_type(item.data(Qt.ItemDataRole.UserRole))) + fields.append(str(item.data(Qt.ItemDataRole.UserRole))) set_saved_field_data(self.name, fields, {x:i for i, x in enumerate(all_fields)}) # Return a dictionary with current options for this widget diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.py b/src/calibre/gui2/catalog/catalog_epub_mobi.py index 813beada14..5cf062d789 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.py +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.py @@ -15,7 +15,7 @@ from calibre.gui2 import gprefs, open_url, question_dialog, error_dialog from calibre.utils.config import JSONConfig from calibre.utils.icu import sort_key from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import native_string_type, unicode_type, zip, range +from polyglot.builtins import native_string_type from .catalog_epub_mobi_ui import Ui_Form from qt.core import (Qt, QAbstractItemView, QCheckBox, QComboBox, @@ -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'), @@ -199,7 +199,7 @@ class PluginWidget(QWidget,Ui_Form): results = _('No genres will be excluded') - regex = unicode_type(getattr(self, 'exclude_genre').text()).strip() + regex = str(getattr(self, 'exclude_genre').text()).strip() if not regex: self.exclude_genre_results.clear() self.exclude_genre_results.setText(results) @@ -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']: @@ -274,7 +274,7 @@ class PluginWidget(QWidget,Ui_Form): new_source = self.genre_source_field.currentText() self.genre_source_field_name = new_source if new_source != _('Tags'): - genre_source_spec = self.genre_source_fields[unicode_type(new_source)] + genre_source_spec = self.genre_source_fields[str(new_source)] self.genre_source_field_name = genre_source_spec['field'] self.exclude_genre_changed() @@ -294,7 +294,7 @@ class PluginWidget(QWidget,Ui_Form): new_source = self.header_note_source_field.currentText() self.header_note_source_field_name = new_source if new_source: - header_note_source_spec = self.header_note_source_fields[unicode_type(new_source)] + header_note_source_spec = self.header_note_source_fields[str(new_source)] self.header_note_source_field_name = header_note_source_spec['field'] def initialize(self, name, db): @@ -335,7 +335,7 @@ class PluginWidget(QWidget,Ui_Form): c_name, c_def, c_type = opt opt_value = gprefs.get(self.name + '_' + c_name, c_def) if c_type in ['check_box']: - getattr(self, c_name).setChecked(eval(unicode_type(opt_value))) + getattr(self, c_name).setChecked(eval(str(opt_value))) getattr(self, c_name).clicked.connect(partial(self.settings_changed, c_name)) elif c_type in ['combo_box']: if opt_value is None: @@ -382,21 +382,21 @@ class PluginWidget(QWidget,Ui_Form): # Init self.merge_source_field_name self.merge_source_field_name = '' - cs = unicode_type(self.merge_source_field.currentText()) + cs = str(self.merge_source_field.currentText()) if cs: merge_source_spec = self.merge_source_fields[cs] self.merge_source_field_name = merge_source_spec['field'] # Init self.header_note_source_field_name self.header_note_source_field_name = '' - cs = unicode_type(self.header_note_source_field.currentText()) + cs = str(self.header_note_source_field.currentText()) if cs: header_note_source_spec = self.header_note_source_fields[cs] self.header_note_source_field_name = header_note_source_spec['field'] # Init self.genre_source_field_name self.genre_source_field_name = _('Tags') - cs = unicode_type(self.genre_source_field.currentText()) + cs = str(self.genre_source_field.currentText()) if cs != _('Tags'): genre_source_spec = self.genre_source_fields[cs] self.genre_source_field_name = genre_source_spec['field'] @@ -430,7 +430,7 @@ class PluginWidget(QWidget,Ui_Form): new_source = self.merge_source_field.currentText() self.merge_source_field_name = new_source if new_source: - merge_source_spec = self.merge_source_fields[unicode_type(new_source)] + merge_source_spec = self.merge_source_fields[str(new_source)] self.merge_source_field_name = merge_source_spec['field'] if not self.merge_before.isChecked() and not self.merge_after.isChecked(): self.merge_after.setChecked(True) @@ -465,11 +465,11 @@ class PluginWidget(QWidget,Ui_Form): if c_type in ['check_box', 'radio_button']: opt_value = getattr(self, c_name).isChecked() elif c_type in ['combo_box']: - opt_value = unicode_type(getattr(self,c_name).currentText()).strip() + opt_value = str(getattr(self,c_name).currentText()).strip() elif c_type in ['line_edit']: - opt_value = unicode_type(getattr(self, c_name).text()).strip() + opt_value = str(getattr(self, c_name).text()).strip() elif c_type in ['spin_box']: - opt_value = unicode_type(getattr(self, c_name).value()) + opt_value = str(getattr(self, c_name).value()) elif c_type in ['table_widget']: if c_name == 'prefix_rules_tw': opt_value = self.prefix_rules_table.get_data() @@ -497,21 +497,21 @@ class PluginWidget(QWidget,Ui_Form): # Init self.merge_source_field_name self.merge_source_field_name = '' - cs = unicode_type(self.merge_source_field.currentText()) + cs = str(self.merge_source_field.currentText()) if cs and cs in self.merge_source_fields: merge_source_spec = self.merge_source_fields[cs] self.merge_source_field_name = merge_source_spec['field'] # Init self.header_note_source_field_name self.header_note_source_field_name = '' - cs = unicode_type(self.header_note_source_field.currentText()) + cs = str(self.header_note_source_field.currentText()) if cs and cs in self.header_note_source_fields: header_note_source_spec = self.header_note_source_fields[cs] self.header_note_source_field_name = header_note_source_spec['field'] # Init self.genre_source_field_name self.genre_source_field_name = _('Tags') - cs = unicode_type(self.genre_source_field.currentText()) + cs = str(self.genre_source_field.currentText()) if cs != _('Tags') and cs and cs in self.genre_source_fields: genre_source_spec = self.genre_source_fields[cs] self.genre_source_field_name = genre_source_spec['field'] @@ -638,9 +638,9 @@ class PluginWidget(QWidget,Ui_Form): else: continue if c_type in ['check_box']: - getattr(self, c_name).setChecked(eval(unicode_type(opt_value))) + getattr(self, c_name).setChecked(eval(str(opt_value))) if c_name == 'generate_genres': - self.genre_source_field.setEnabled(eval(unicode_type(opt_value))) + self.genre_source_field.setEnabled(eval(str(opt_value))) elif c_type in ['combo_box']: if opt_value is None: index = 0 @@ -701,7 +701,7 @@ class PluginWidget(QWidget,Ui_Form): return item_id = self.preset_field.currentIndex() - item_name = unicode_type(self.preset_field.currentText()) + item_name = str(self.preset_field.currentText()) self.preset_field.blockSignals(True) self.preset_field.removeItem(item_id) @@ -729,7 +729,7 @@ class PluginWidget(QWidget,Ui_Form): error_dialog(self, _("Save catalog preset"), _("You must provide a name."), show=True) new = True - name = unicode_type(name) + name = str(name) if name in self.presets.keys(): if not question_dialog(self, _("Save catalog preset"), _("That saved preset already exists and will be overwritten. " @@ -753,11 +753,11 @@ class PluginWidget(QWidget,Ui_Form): elif c_type in ['combo_box']: if c_name == 'preset_field': continue - opt_value = unicode_type(getattr(self,c_name).currentText()).strip() + opt_value = str(getattr(self,c_name).currentText()).strip() elif c_type in ['line_edit']: - opt_value = unicode_type(getattr(self, c_name).text()).strip() + opt_value = str(getattr(self, c_name).text()).strip() elif c_type in ['spin_box']: - opt_value = unicode_type(getattr(self, c_name).value()) + opt_value = str(getattr(self, c_name).value()) elif c_type in ['table_widget']: if c_name == 'prefix_rules_tw': opt_value = self.prefix_rules_table.get_data() @@ -786,8 +786,8 @@ class PluginWidget(QWidget,Ui_Form): preset['merge_comments_rule'] = "%s:%s:%s" % \ (self.merge_source_field_name, checked, include_hr) - preset['header_note_source_field'] = unicode_type(self.header_note_source_field.currentText()) - preset['genre_source_field'] = unicode_type(self.genre_source_field.currentText()) + preset['header_note_source_field'] = str(self.header_note_source_field.currentText()) + preset['genre_source_field'] = str(self.genre_source_field.currentText()) # Append the current output profile try: @@ -998,7 +998,7 @@ class GenericRulesTable(QTableWidget): first = rows[0].row() + 1 last = rows[-1].row() + 1 - first_rule_name = unicode_type(self.cellWidget(first-1,self.COLUMNS['NAME']['ordinal']).text()).strip() + first_rule_name = str(self.cellWidget(first-1,self.COLUMNS['NAME']['ordinal']).text()).strip() message = _("Are you sure you want to delete '%s'?") % (first_rule_name) if len(rows) > 1: message = _('Are you sure you want to delete rules #%(first)d-%(last)d?') % dict(first=first, last=last) @@ -1153,15 +1153,15 @@ class GenericRulesTable(QTableWidget): elif source_field == _('Tags'): values = sorted(self.db.all_tags(), key=sort_key) else: - if self.eligible_custom_fields[unicode_type(source_field)]['datatype'] in ['enumeration', 'text']: + if self.eligible_custom_fields[str(source_field)]['datatype'] in ['enumeration', 'text']: values = self.db.all_custom(self.db.field_metadata.key_to_label( - self.eligible_custom_fields[unicode_type(source_field)]['field'])) + self.eligible_custom_fields[str(source_field)]['field'])) values = sorted(values, key=sort_key) - elif self.eligible_custom_fields[unicode_type(source_field)]['datatype'] in ['bool']: + elif self.eligible_custom_fields[str(source_field)]['datatype'] in ['bool']: values = [_('True'),_('False'),_('unspecified')] - elif self.eligible_custom_fields[unicode_type(source_field)]['datatype'] in ['composite']: + elif self.eligible_custom_fields[str(source_field)]['datatype'] in ['composite']: values = [_('any value'),_('unspecified')] - elif self.eligible_custom_fields[unicode_type(source_field)]['datatype'] in ['datetime']: + elif self.eligible_custom_fields[str(source_field)]['datatype'] in ['datetime']: values = [_('any date'),_('unspecified')] values_combo = ComboBox(self, values, pattern) @@ -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() @@ -1215,9 +1215,9 @@ class ExclusionRules(GenericRulesTable): data = self.create_blank_row_data() data['ordinal'] = row data['enabled'] = self.item(row,self.COLUMNS['ENABLED']['ordinal']).checkState() == Qt.CheckState.Checked - data['name'] = unicode_type(self.cellWidget(row,self.COLUMNS['NAME']['ordinal']).text()).strip() - data['field'] = unicode_type(self.cellWidget(row,self.COLUMNS['FIELD']['ordinal']).currentText()).strip() - data['pattern'] = unicode_type(self.cellWidget(row,self.COLUMNS['PATTERN']['ordinal']).currentText()).strip() + data['name'] = str(self.cellWidget(row,self.COLUMNS['NAME']['ordinal']).text()).strip() + data['field'] = str(self.cellWidget(row,self.COLUMNS['FIELD']['ordinal']).currentText()).strip() + data['pattern'] = str(self.cellWidget(row,self.COLUMNS['PATTERN']['ordinal']).currentText()).strip() return data def create_blank_row_data(self): @@ -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() @@ -1309,10 +1309,10 @@ class PrefixRules(GenericRulesTable): data = self.create_blank_row_data() data['ordinal'] = row data['enabled'] = self.item(row,self.COLUMNS['ENABLED']['ordinal']).checkState() == Qt.CheckState.Checked - data['name'] = unicode_type(self.cellWidget(row,self.COLUMNS['NAME']['ordinal']).text()).strip() - data['prefix'] = unicode_type(self.cellWidget(row,self.COLUMNS['PREFIX']['ordinal']).currentText()).strip() - data['field'] = unicode_type(self.cellWidget(row,self.COLUMNS['FIELD']['ordinal']).currentText()).strip() - data['pattern'] = unicode_type(self.cellWidget(row,self.COLUMNS['PATTERN']['ordinal']).currentText()).strip() + data['name'] = str(self.cellWidget(row,self.COLUMNS['NAME']['ordinal']).text()).strip() + data['prefix'] = str(self.cellWidget(row,self.COLUMNS['PREFIX']['ordinal']).currentText()).strip() + data['field'] = str(self.cellWidget(row,self.COLUMNS['FIELD']['ordinal']).currentText()).strip() + data['pattern'] = str(self.cellWidget(row,self.COLUMNS['PATTERN']['ordinal']).currentText()).strip() return data def create_blank_row_data(self): diff --git a/src/calibre/gui2/comments_editor.py b/src/calibre/gui2/comments_editor.py index 01259a1f0e..45e5c4addf 100644 --- a/src/calibre/gui2/comments_editor.py +++ b/src/calibre/gui2/comments_editor.py @@ -31,7 +31,7 @@ from calibre.gui2.widgets2 import to_plain_text from calibre.utils.cleantext import clean_xml_chars from calibre.utils.config import tweaks from calibre.utils.imghdr import what -from polyglot.builtins import filter, iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues # Cleanup Qt markup {{{ @@ -602,7 +602,7 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{ return url = self.parse_link(link) if url.isValid(): - url = unicode_type(url.toString(NO_URL_FORMATTING)) + url = str(url.toString(NO_URL_FORMATTING)) self.focus_self() with self.editing_cursor() as c: if is_image: @@ -692,7 +692,7 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{ d.resize(d.sizeHint()) link, name, is_image = None, None, False if d.exec_() == QDialog.DialogCode.Accepted: - link, name = unicode_type(d.url.text()).strip(), unicode_type(d.name.text()).strip() + link, name = str(d.url.text()).strip(), str(d.name.text()).strip() is_image = d.treat_as_image.isChecked() return link, name, is_image @@ -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 6f90f3b479..826a8f531d 100644 --- a/src/calibre/gui2/complete2.py +++ b/src/calibre/gui2/complete2.py @@ -15,7 +15,6 @@ from calibre.constants import ismacos from calibre.utils.icu import sort_key, primary_startswith, primary_contains from calibre.gui2.widgets import EnComboBox, LineEditECM from calibre.utils.config import tweaks -from polyglot.builtins import unicode_type def containsq(x, prefix): @@ -108,7 +107,7 @@ class Completer(QListView): # {{{ return self.hide() text = self.model().data(index, Qt.ItemDataRole.DisplayRole) - self.item_selected.emit(unicode_type(text)) + self.item_selected.emit(str(text)) def set_items(self, items): self.model().set_items(items) @@ -380,7 +379,7 @@ class LineEdit(QLineEdit, LineEditECM): def update_completions(self): ' Update the list of completions ' self.original_cursor_pos = cpos = self.cursorPosition() - text = unicode_type(self.text()) + text = str(self.text()) prefix = text[:cpos] complete_prefix = prefix.lstrip() if self.sep: @@ -397,7 +396,7 @@ class LineEdit(QLineEdit, LineEditECM): cursor_pos = self.cursorPosition() self.original_cursor_pos = None # Split text - curtext = unicode_type(self.text()) + curtext = str(self.text()) before_text = curtext[:cursor_pos] after_text = curtext[cursor_pos:].rstrip() # Remove the completion prefix from the before text @@ -417,7 +416,7 @@ class LineEdit(QLineEdit, LineEditECM): return before_text + completed_text, after_text def completion_selected(self, text): - before_text, after_text = self.get_completed_text(unicode_type(text)) + before_text, after_text = self.get_completed_text(str(text)) self.setText(before_text + after_text) self.setCursorPosition(len(before_text)) self.item_selected.emit(text) @@ -459,7 +458,7 @@ class EditWithComplete(EnComboBox): self.lineEdit().set_add_separator(what) def show_initial_value(self, what): - what = unicode_type(what) if what else u'' + what = str(what) if what else '' self.setText(what) self.lineEdit().selectAll() @@ -487,7 +486,7 @@ class EditWithComplete(EnComboBox): # }}} def text(self): - return unicode_type(self.lineEdit().text()) + return str(self.lineEdit().text()) def selectAll(self): self.lineEdit().selectAll() @@ -533,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/__init__.py b/src/calibre/gui2/convert/__init__.py index f5d35fe092..65c4c866d0 100644 --- a/src/calibre/gui2/convert/__init__.py +++ b/src/calibre/gui2/convert/__init__.py @@ -19,7 +19,6 @@ from calibre.ebooks.conversion.config import ( from calibre import prepare_string_for_xml from calibre.customize.ui import plugin_for_input_format from calibre.gui2.font_family_chooser import FontFamilyChooser -from polyglot.builtins import unicode_type def config_widget_for_input_plugin(plugin): @@ -101,7 +100,7 @@ class Widget(QWidget): buddy = g.buddy() if buddy is not None and hasattr(buddy, '_help'): g._help = buddy._help - htext = unicode_type(buddy.toolTip()).strip() + htext = str(buddy.toolTip()).strip() g.setToolTip(htext) g.setWhatsThis(htext) g.__class__.enterEvent = lambda obj, event: self.set_help(getattr(obj, '_help', obj.toolTip())) @@ -152,18 +151,18 @@ class Widget(QWidget): return g.value() elif isinstance(g, (QLineEdit, QTextEdit, QPlainTextEdit)): func = getattr(g, 'toPlainText', getattr(g, 'text', None))() - ans = unicode_type(func) + ans = str(func) if self.STRIP_TEXT_FIELDS: ans = ans.strip() if not ans: ans = None return ans elif isinstance(g, QFontComboBox): - return unicode_type(QFontInfo(g.currentFont()).family()) + return str(QFontInfo(g.currentFont()).family()) elif isinstance(g, FontFamilyChooser): return g.font_family elif isinstance(g, EncodingComboBox): - ans = unicode_type(g.currentText()).strip() + ans = str(g.currentText()).strip() try: codecs.lookup(ans) except: @@ -172,7 +171,7 @@ class Widget(QWidget): ans = None return ans elif isinstance(g, QComboBox): - return unicode_type(g.currentText()) + return str(g.currentText()) elif isinstance(g, QCheckBox): return bool(g.isChecked()) elif isinstance(g, XPathEdit): @@ -251,7 +250,7 @@ class Widget(QWidget): g.edit.setText(val if val else '') else: raise Exception('Can\'t set value %s in %s'%(repr(val), - unicode_type(g.objectName()))) + str(g.objectName()))) self.post_set_value(g, val) def set_help(self, msg): diff --git a/src/calibre/gui2/convert/bulk.py b/src/calibre/gui2/convert/bulk.py index 775f914c63..272187d6ba 100644 --- a/src/calibre/gui2/convert/bulk.py +++ b/src/calibre/gui2/convert/bulk.py @@ -21,7 +21,7 @@ from calibre.ebooks.conversion.plumber import Plumber from calibre.ebooks.conversion.config import sort_formats_by_preference, get_output_formats from calibre.utils.config import prefs from calibre.utils.logging import Log -from polyglot.builtins import unicode_type, native_string_type +from polyglot.builtins import native_string_type class BulkConfig(Config): @@ -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((unicode_type(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/debug.py b/src/calibre/gui2/convert/debug.py index 35be0ab653..ff068da456 100644 --- a/src/calibre/gui2/convert/debug.py +++ b/src/calibre/gui2/convert/debug.py @@ -12,7 +12,6 @@ from calibre.gui2.convert.debug_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.gui2 import error_dialog, choose_dir from calibre.ebooks.conversion.config import OPTIONS -from polyglot.builtins import unicode_type class DebugWidget(Widget, Ui_Form): @@ -35,7 +34,7 @@ class DebugWidget(Widget, Ui_Form): def pre_commit_check(self): try: - x = unicode_type(self.opt_debug_pipeline.text()).strip() + x = str(self.opt_debug_pipeline.text()).strip() if not x: return True x = os.path.abspath(x) @@ -49,7 +48,7 @@ class DebugWidget(Widget, Ui_Form): import traceback det_msg = traceback.format_exc() error_dialog(self, _('Invalid debug folder'), - _('Failed to create debug folder')+': '+ unicode_type(self.opt_debug_pipeline.text()), + _('Failed to create debug folder')+': '+ str(self.opt_debug_pipeline.text()), det_msg=det_msg, show=True) return False return True diff --git a/src/calibre/gui2/convert/font_key.py b/src/calibre/gui2/convert/font_key.py index 168a44a709..6e615c5fb7 100644 --- a/src/calibre/gui2/convert/font_key.py +++ b/src/calibre/gui2/convert/font_key.py @@ -10,7 +10,6 @@ from qt.core import QDialog, QDialogButtonBox from calibre.gui2.convert.font_key_ui import Ui_Dialog from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import unicode_type class FontKeyChooser(QDialog, Ui_Dialog): @@ -67,7 +66,7 @@ class FontKeyChooser(QDialog, Ui_Dialog): @property def fsizes(self): - key = unicode_type(self.font_size_key.text()).strip() + key = str(self.font_size_key.text()).strip() return [float(x.strip()) for x in key.split(',' if ',' in key else ' ') if x.strip()] @property diff --git a/src/calibre/gui2/convert/heuristics.py b/src/calibre/gui2/convert/heuristics.py index 93186b2e73..d299d43592 100644 --- a/src/calibre/gui2/convert/heuristics.py +++ b/src/calibre/gui2/convert/heuristics.py @@ -12,7 +12,6 @@ from calibre.gui2.convert.heuristics_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.utils.localization import localize_user_manual_link from calibre.ebooks.conversion.config import OPTIONS -from polyglot.builtins import unicode_type, range class HeuristicsWidget(Widget, Ui_Form): @@ -75,7 +74,7 @@ class HeuristicsWidget(Widget, Ui_Form): return True def load_histories(self): - val = unicode_type(self.opt_replace_scene_breaks.currentText()) + val = str(self.opt_replace_scene_breaks.currentText()) self.opt_replace_scene_breaks.clear() self.opt_replace_scene_breaks.lineEdit().setText('') @@ -92,7 +91,7 @@ class HeuristicsWidget(Widget, Ui_Form): def save_histories(self): rssb_history = [] - history_pats = [unicode_type(self.opt_replace_scene_breaks.lineEdit().text())] + [unicode_type(self.opt_replace_scene_breaks.itemText(i)) + history_pats = [str(self.opt_replace_scene_breaks.lineEdit().text())] + [str(self.opt_replace_scene_breaks.itemText(i)) for i in range(self.opt_replace_scene_breaks.count())] for p in history_pats[:10]: # Ensure we don't have duplicate items. diff --git a/src/calibre/gui2/convert/look_and_feel.py b/src/calibre/gui2/convert/look_and_feel.py index 0174dd4341..516cdde411 100644 --- a/src/calibre/gui2/convert/look_and_feel.py +++ b/src/calibre/gui2/convert/look_and_feel.py @@ -13,7 +13,7 @@ from qt.core import Qt, QDialog from calibre.gui2.convert.look_and_feel_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.ebooks.conversion.config import OPTIONS -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class LookAndFeelWidget(Widget, Ui_Form): @@ -55,7 +55,7 @@ class LookAndFeelWidget(Widget, Ui_Form): def get_value_handler(self, g): if g is self.opt_change_justification: - ans = unicode_type(g.itemData(g.currentIndex()) or '') + ans = str(g.itemData(g.currentIndex()) or '') return ans if g is self.opt_filter_css: ans = set() @@ -64,10 +64,10 @@ class LookAndFeelWidget(Widget, Ui_Form): if w.isChecked(): ans = ans.union(item) ans = ans.union({x.strip().lower() for x in - unicode_type(self.filter_css_others.text()).split(',')}) + str(self.filter_css_others.text()).split(',')}) return ','.join(ans) if ans else None if g is self.opt_font_size_mapping: - val = unicode_type(g.text()).strip() + val = str(g.text()).strip() val = [x.strip() for x in val.split(',' if ',' in val else ' ') if x.strip()] return ', '.join(val) or None if g is self.opt_transform_css_rules: @@ -77,7 +77,7 @@ class LookAndFeelWidget(Widget, Ui_Form): def set_value_handler(self, g, val): if g is self.opt_change_justification: for i in range(g.count()): - c = unicode_type(g.itemData(i) or '') + c = str(g.itemData(i) or '') if val == c: g.setCurrentIndex(i) break @@ -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: @@ -114,7 +114,7 @@ class LookAndFeelWidget(Widget, Ui_Form): def font_key_wizard(self): from calibre.gui2.convert.font_key import FontKeyChooser d = FontKeyChooser(self, self.opt_base_font_size.value(), - unicode_type(self.opt_font_size_mapping.text()).strip()) + str(self.opt_font_size_mapping.text()).strip()) if d.exec_() == QDialog.DialogCode.Accepted: self.opt_font_size_mapping.setText(', '.join(['%.1f'%x for x in d.fsizes])) diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index 1567e02f0d..0d4336e8bf 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -21,7 +21,6 @@ from calibre.utils.icu import sort_key from calibre.library.comments import comments_to_html from calibre.utils.config import tweaks from calibre.ebooks.conversion.config import OPTIONS -from polyglot.builtins import unicode_type def create_opf_file(db, book_id, opf_file=None): @@ -75,7 +74,7 @@ class MetadataWidget(Widget, Ui_Form): self.cover_data = data def deduce_author_sort(self, *args): - au = unicode_type(self.author.currentText()) + au = str(self.author.currentText()) au = re.sub(r'\s+et al\.$', '', au) authors = string_to_authors(au) self.author_sort.setText(self.db.author_sort_from_authors(authors)) @@ -159,30 +158,30 @@ class MetadataWidget(Widget, Ui_Form): self.publisher.update_items_cache(self.db.new_api.all_field_names('publisher')) def get_title_and_authors(self): - title = unicode_type(self.title.text()).strip() + title = str(self.title.text()).strip() if not title: title = _('Unknown') - authors = unicode_type(self.author.text()).strip() + authors = str(self.author.text()).strip() authors = string_to_authors(authors) if authors else [_('Unknown')] return title, authors def get_metadata(self): title, authors = self.get_title_and_authors() mi = MetaInformation(title, authors) - publisher = unicode_type(self.publisher.text()).strip() + publisher = str(self.publisher.text()).strip() if publisher: mi.publisher = publisher - author_sort = unicode_type(self.author_sort.text()).strip() + author_sort = str(self.author_sort.text()).strip() if author_sort: mi.author_sort = author_sort comments = self.comment.html if comments: mi.comments = comments mi.series_index = float(self.series_index.value()) - series = unicode_type(self.series.currentText()).strip() + series = str(self.series.currentText()).strip() if series: mi.series = series - tags = [t.strip() for t in unicode_type(self.tags.text()).strip().split(',')] + tags = [t.strip() for t in str(self.tags.text()).strip().split(',')] if tags: mi.tags = tags @@ -190,7 +189,7 @@ class MetadataWidget(Widget, Ui_Form): def select_cover(self): files = choose_images(self, 'change cover dialog', - _('Choose cover for ') + unicode_type(self.title.text())) + _('Choose cover for ') + str(self.title.text())) if not files: return _file = files[0] @@ -205,9 +204,9 @@ 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 + "


"+unicode_type(e)) + _("

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


"+str(e)) d.exec_() if cover: pix = QPixmap() @@ -245,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/page_setup.py b/src/calibre/gui2/convert/page_setup.py index f59b77cf7a..feabdcaa27 100644 --- a/src/calibre/gui2/convert/page_setup.py +++ b/src/calibre/gui2/convert/page_setup.py @@ -12,7 +12,6 @@ from calibre.gui2.convert.page_setup_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.customize.ui import input_profiles, output_profiles from calibre.ebooks.conversion.config import OPTIONS -from polyglot.builtins import unicode_type class ProfileModel(QAbstractListModel): @@ -67,7 +66,7 @@ class PageSetupWidget(Widget, Ui_Form): self.opt_output_profile.setToolTip('') def show_desc(self, index): - desc = unicode_type(index.model().data(index, Qt.ItemDataRole.StatusTipRole) or '') + desc = str(index.model().data(index, Qt.ItemDataRole.StatusTipRole) or '') self.profile_description.setText(desc) def connect_gui_obj_handler(self, g, slot): diff --git a/src/calibre/gui2/convert/regex_builder.py b/src/calibre/gui2/convert/regex_builder.py index 5a692e508f..34bae0dc4f 100644 --- a/src/calibre/gui2/convert/regex_builder.py +++ b/src/calibre/gui2/convert/regex_builder.py @@ -18,7 +18,7 @@ from calibre.gui2.dialogs.choose_format import ChooseFormatDialog from calibre.ptempfile import TemporaryFile from calibre.utils.icu import utf16_length from calibre.utils.ipc.simple_worker import WorkerError, fork_job -from polyglot.builtins import native_string_type, range, unicode_type +from polyglot.builtins import native_string_type class RegexBuilder(QDialog, Ui_RegexBuilder): @@ -60,7 +60,7 @@ class RegexBuilder(QDialog, Ui_RegexBuilder): gprefs['regex_builder_geometry'] = geom def regex_valid(self): - regex = unicode_type(self.regex.text()) + regex = str(self.regex.text()) if regex: try: compile_regular_expression(regex) @@ -88,8 +88,8 @@ class RegexBuilder(QDialog, Ui_RegexBuilder): qt: int = 0 if self.regex_valid(): - text = unicode_type(self.preview.toPlainText()) - regex = unicode_type(self.regex.text()) + text = str(self.preview.toPlainText()) + regex = str(self.regex.text()) cursor = QTextCursor(self.preview.document()) extsel = QTextEdit.ExtraSelection() extsel.cursor = cursor @@ -110,7 +110,7 @@ class RegexBuilder(QDialog, Ui_RegexBuilder): if self.match_locs: self.next.setEnabled(True) self.previous.setEnabled(True) - self.occurrences.setText(unicode_type(len(self.match_locs))) + self.occurrences.setText(str(len(self.match_locs))) def goto_previous(self): pos = self.preview.textCursor().position() @@ -209,12 +209,12 @@ class RegexBuilder(QDialog, Ui_RegexBuilder): self.open_book(files[0]) def doc(self): - return unicode_type(self.preview.toPlainText()) + return str(self.preview.toPlainText()) class RegexEdit(QWidget, Ui_Edit): - doc_update = pyqtSignal(unicode_type) + doc_update = pyqtSignal(str) def __init__(self, parent=None): QWidget.__init__(self, parent) @@ -246,7 +246,7 @@ class RegexEdit(QWidget, Ui_Edit): def setObjectName(self, *args): QWidget.setObjectName(self, *args) if hasattr(self, 'edit'): - self.edit.initialize('regex_edit_'+unicode_type(self.objectName())) + self.edit.initialize('regex_edit_'+str(self.objectName())) def set_msg(self, msg): self.msg.setText(msg) @@ -268,7 +268,7 @@ class RegexEdit(QWidget, Ui_Edit): @property def text(self): - return unicode_type(self.edit.text()) + return str(self.edit.text()) @property def regex(self): diff --git a/src/calibre/gui2/convert/search_and_replace.py b/src/calibre/gui2/convert/search_and_replace.py index cb0a32e5de..577507aa97 100644 --- a/src/calibre/gui2/convert/search_and_replace.py +++ b/src/calibre/gui2/convert/search_and_replace.py @@ -17,7 +17,6 @@ from calibre import as_unicode from calibre.utils.localization import localize_user_manual_link from calibre.ebooks.conversion.search_replace import compile_regular_expression from calibre.ebooks.conversion.config import OPTIONS -from polyglot.builtins import unicode_type, range class SearchAndReplaceWidget(Widget, Ui_Form): @@ -193,7 +192,7 @@ class SearchAndReplaceWidget(Widget, Ui_Form): edit_search = self.sr_search.regex if edit_search: - edit_replace = unicode_type(self.sr_replace.text()) + edit_replace = str(self.sr_replace.text()) found = False for search, replace in definitions: if search == edit_search and replace == edit_replace: @@ -234,7 +233,7 @@ class SearchAndReplaceWidget(Widget, Ui_Form): for row in range(0, self.search_replace.rowCount()): colItems = [] for col in range(0, self.search_replace.columnCount()): - colItems.append(unicode_type(self.search_replace.item(row, col).text())) + colItems.append(str(self.search_replace.item(row, col).text())) ans.append(colItems) return ans @@ -281,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 641a90d688..981d080d25 100644 --- a/src/calibre/gui2/convert/single.py +++ b/src/calibre/gui2/convert/single.py @@ -28,7 +28,7 @@ from calibre.gui2.convert.search_and_replace import SearchAndReplaceWidget from calibre.gui2.convert.structure_detection import StructureDetectionWidget from calibre.gui2.convert.toc import TOCWidget from calibre.utils.config import prefs -from polyglot.builtins import native_string_type, unicode_type +from polyglot.builtins import native_string_type class GroupModel(QAbstractListModel): @@ -190,11 +190,11 @@ class Config(QDialog): @property def input_format(self): - return unicode_type(self.input_formats.currentText()).lower() + return str(self.input_formats.currentText()).lower() @property def output_format(self): - return unicode_type(self.output_formats.currentText()).lower() + return str(self.output_formats.currentText()).lower() @property def manually_fine_tune_toc(self): @@ -213,7 +213,7 @@ class Config(QDialog): self.plumber.get_option_help, self.db, self.book_id) self.mw = widget_factory(MetadataWidget) - self.setWindowTitle(_('Convert')+ ' ' + unicode_type(self.mw.title.text())) + self.setWindowTitle(_('Convert')+ ' ' + str(self.mw.title.text())) lf = widget_factory(LookAndFeelWidget) hw = widget_factory(HeuristicsWidget) sr = widget_factory(SearchAndReplaceWidget) @@ -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((unicode_type(x.upper()) for x in input_formats)) - self.output_formats.addItems((unicode_type(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/convert/txt_input.py b/src/calibre/gui2/convert/txt_input.py index 07d28c1612..106af84fd1 100644 --- a/src/calibre/gui2/convert/txt_input.py +++ b/src/calibre/gui2/convert/txt_input.py @@ -11,7 +11,7 @@ from calibre.gui2.convert.txt_input_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.ebooks.conversion.plugins.txt_input import MD_EXTENSIONS from calibre.ebooks.conversion.config import OPTIONS -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues class PluginWidget(Widget, Ui_Form): @@ -50,7 +50,7 @@ class PluginWidget(Widget, Ui_Form): def get_value_handler(self, g): if g is not self.opt_markdown_extensions: return Widget.get_value_handler(self, g) - return ', '.join(unicode_type(i.data(Qt.ItemDataRole.UserRole) or '') for i in itervalues(self.md_map) if i.checkState()) + return ', '.join(str(i.data(Qt.ItemDataRole.UserRole) or '') for i in itervalues(self.md_map) if i.checkState()) def connect_gui_obj_handler(self, g, f): if g is not self.opt_markdown_extensions: diff --git a/src/calibre/gui2/convert/xpath_wizard.py b/src/calibre/gui2/convert/xpath_wizard.py index 95bfb403b4..81bd317e1c 100644 --- a/src/calibre/gui2/convert/xpath_wizard.py +++ b/src/calibre/gui2/convert/xpath_wizard.py @@ -11,7 +11,6 @@ from qt.core import QDialog, QWidget, Qt, QDialogButtonBox, QVBoxLayout from calibre.gui2.convert.xpath_wizard_ui import Ui_Form from calibre.gui2.convert.xexp_edit_ui import Ui_Form as Ui_Edit from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import unicode_type, map class WizardWidget(QWidget, Ui_Form): @@ -27,10 +26,10 @@ class WizardWidget(QWidget, Ui_Form): @property def xpath(self): - tag = unicode_type(self.tag.currentText()).strip() + tag = str(self.tag.currentText()).strip() if tag != '*': tag = 'h:'+tag - attr, val = map(unicode_type, (self.attribute.text(), self.value.text())) + attr, val = map(str, (self.attribute.text(), self.value.text())) attr, val = attr.strip(), val.strip() q = '' if attr: @@ -81,14 +80,14 @@ class XPathEdit(QWidget, Ui_Edit): def setObjectName(self, *args): QWidget.setObjectName(self, *args) if hasattr(self, 'edit'): - self.edit.initialize('xpath_edit_'+unicode_type(self.objectName())) + self.edit.initialize('xpath_edit_'+str(self.objectName())) def set_msg(self, msg): self.msg.setText(msg) @property def text(self): - return unicode_type(self.edit.text()) + return str(self.edit.text()) @property def xpath(self): diff --git a/src/calibre/gui2/css_transform_rules.py b/src/calibre/gui2/css_transform_rules.py index 195977a9e9..c928cabed9 100644 --- a/src/calibre/gui2/css_transform_rules.py +++ b/src/calibre/gui2/css_transform_rules.py @@ -17,7 +17,7 @@ from calibre.gui2.tag_mapper import ( from calibre.gui2.widgets2 import Dialog from calibre.utils.config import JSONConfig from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class RuleEdit(QWidget): # {{{ @@ -132,14 +132,14 @@ class RuleEdit(QWidget): # {{{ def rule(self, rule): def sc(name): c = getattr(self, name) - idx = c.findData(unicode_type(rule.get(name, ''))) + idx = c.findData(str(rule.get(name, ''))) if idx < 0: idx = 0 c.setCurrentIndex(idx) sc('action'), sc('match_type') - self.property.setText(unicode_type(rule.get('property', '')).strip()) - self.query.setText(unicode_type(rule.get('query', '')).strip()) - self.action_data.setText(unicode_type(rule.get('action_data', '')).strip()) + self.property.setText(str(rule.get('property', '')).strip()) + self.query.setText(str(rule.get('query', '')).strip()) + self.action_data.setText(str(rule.get('action_data', '')).strip()) self.update_state() def validate(self): diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index 81c10c54bf..a4ce10aaf4 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -24,7 +24,6 @@ from calibre.utils.icu import sort_key from calibre.library.comments import comments_to_html from calibre.gui2.library.delegates import ClearingDoubleSpinBox, ClearingSpinBox from calibre.gui2.widgets2 import RatingEditor, DateTimeEdit as DateTimeEditBase -from polyglot.builtins import unicode_type class EditWithComplete(EWC): @@ -55,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() @@ -144,7 +143,7 @@ class SimpleText(Base): self.editor.setClearButtonEnabled(True) def setter(self, val): - self.editor.setText(unicode_type(val or '')) + self.editor.setText(str(val or '')) def getter(self): return self.editor.text().strip() @@ -167,7 +166,7 @@ class LongText(Base): self.widgets = [self._box] def setter(self, val): - self._tb.setPlainText(unicode_type(val or '')) + self._tb.setPlainText(str(val or '')) def getter(self): return self._tb.toPlainText() @@ -417,7 +416,7 @@ class Comments(Base): self._tb.wyswyg_dirtied() def getter(self): - val = unicode_type(self._tb.html).strip() + val = str(self._tb.html).strip() if not val: val = None return val @@ -545,12 +544,12 @@ class Text(Base): def getter(self): if self.col_metadata['is_multiple']: - val = unicode_type(self.editor.text()).strip() + val = str(self.editor.text()).strip() ans = [x.strip() for x in val.split(self.sep['ui_to_list']) if x.strip()] if not ans: ans = None return ans - val = unicode_type(self.editor.currentText()).strip() + val = str(self.editor.currentText()).strip() if not val: val = None return val @@ -634,7 +633,7 @@ class Series(Base): self.initial_val, self.initial_index = self.current_val def getter(self): - n = unicode_type(self.name_widget.currentText()).strip() + n = str(self.name_widget.currentText()).strip() i = self.idx_widget.value() return n, i @@ -705,7 +704,7 @@ class Enumeration(Base): self.editor.setCurrentIndex(self.editor.findText(val)) def getter(self): - return unicode_type(self.editor.currentText()) + return str(self.editor.currentText()) def normalize_db_val(self, val): if val is None: @@ -860,7 +859,7 @@ def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, pa wij.setSizePolicy(QSizePolicy.Policy.Maximum, QSizePolicy.Policy.Preferred) l.setColumnMinimumWidth(0, label_width) wij.setAlignment(Qt.AlignmentFlag.AlignRight|Qt.AlignmentFlag.AlignVCenter) - t = unicode_type(wij.text()) + t = str(wij.text()) if t: if do_elision: wij.setText(elided_text(t, font=font_metrics, @@ -1269,7 +1268,7 @@ class BulkSeries(BulkBase): self.a_c_checkbox.setChecked(False) def getter(self): - n = unicode_type(self.main_widget.currentText()).strip() + n = str(self.main_widget.currentText()).strip() autonumber = self.idx_widget.checkState() force = self.force_number.checkState() start = self.series_start_number.value() @@ -1343,7 +1342,7 @@ class BulkEnumeration(BulkBase, Enumeration): self.main_widget.setCurrentIndex(0) def getter(self): - return unicode_type(self.main_widget.currentText()) + return str(self.main_widget.currentText()) def setter(self, val): if val is None: @@ -1471,10 +1470,10 @@ class BulkText(BulkBase): if self.col_metadata['is_multiple']: if not self.col_metadata['display'].get('is_names', False): return self.removing_widget.checkbox.isChecked(), \ - unicode_type(self.adding_widget.text()), \ - unicode_type(self.removing_widget.tags_box.text()) - return unicode_type(self.adding_widget.text()) - val = unicode_type(self.main_widget.currentText()).strip() + str(self.adding_widget.text()), \ + str(self.removing_widget.tags_box.text()) + return str(self.adding_widget.text()) + val = str(self.main_widget.currentText()).strip() if not val: val = None return val diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 7a9664ea2e..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 ' @@ -35,7 +33,7 @@ from calibre.utils.config import tweaks, device_prefs from calibre.utils.img import scale_image from calibre.library.save_to_disk import find_plugboard from calibre.ptempfile import PersistentTemporaryFile, force_unicode as filename_to_unicode -from polyglot.builtins import unicode_type, string_or_unicode +from polyglot.builtins import string_or_unicode from polyglot import queue # }}} @@ -107,7 +105,7 @@ class DeviceJob(BaseJob): # {{{ call_job_done = True self._aborted = True self.failed = True - self._details = unicode_type(err) + self._details = str(err) self.exception = err if call_job_done: self.job_done() @@ -209,7 +207,7 @@ class DeviceManager(Thread): # {{{ tb = traceback.format_exc() if DEBUG or tb not in self.reported_errors: self.reported_errors.add(tb) - prints('Unable to open device', unicode_type(dev)) + prints('Unable to open device', str(dev)) prints(tb) continue self.after_device_connect(dev, device_kind) @@ -566,7 +564,7 @@ class DeviceManager(Thread): # {{{ self.connected_device.set_plugboards(plugboards, find_plugboard) if metadata and files and len(metadata) == len(files): for f, mi in zip(files, metadata): - if isinstance(f, unicode_type): + if isinstance(f, str): ext = f.rpartition('.')[-1].lower() cpb = find_plugboard( device_name_for_plugboards(self.connected_device), @@ -935,7 +933,7 @@ class DeviceMixin: # {{{ d.show() def auto_convert_question(self, msg, autos): - autos = '\n'.join(map(unicode_type, map(force_unicode, autos))) + autos = '\n'.join(map(str, map(force_unicode, autos))) return self.ask_a_yes_no_question( _('No suitable formats'), msg, ans_when_user_unavailable=True, @@ -1033,7 +1031,7 @@ class DeviceMixin: # {{{ try: if 'Could not read 32 bytes on the control bus.' in \ - unicode_type(job.details): + str(job.details): error_dialog(self, _('Error talking to device'), _('There was a temporary error talking to the ' 'device. Please unplug and reconnect the device ' @@ -1361,7 +1359,7 @@ class DeviceMixin: # {{{ names = [] for book_id, mi in zip(ids, metadata): prefix = ascii_filename(mi.title) - if not isinstance(prefix, unicode_type): + if not isinstance(prefix, str): prefix = prefix.decode(preferred_encoding, 'replace') prefix = ascii_filename(prefix) names.append('%s_%d%s'%(prefix, book_id, @@ -1439,7 +1437,7 @@ class DeviceMixin: # {{{ names = [] for book_id, mi in zip(ids, metadata): prefix = ascii_filename(mi.title) - if not isinstance(prefix, unicode_type): + if not isinstance(prefix, str): prefix = prefix.decode(preferred_encoding, 'replace') prefix = ascii_filename(prefix) names.append('%s_%d%s'%(prefix, book_id, @@ -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 @@ -1518,7 +1516,7 @@ class DeviceMixin: # {{{ if not a: a = _('Unknown') prefix = ascii_filename(t+' - '+a) - if not isinstance(prefix, unicode_type): + if not isinstance(prefix, str): prefix = prefix.decode(preferred_encoding, 'replace') prefix = ascii_filename(prefix) names.append('%s_%d%s'%(prefix, id, os.path.splitext(f)[1])) @@ -1639,7 +1637,7 @@ class DeviceMixin: # {{{ if job.exception is not None: if isinstance(job.exception, FreeSpaceError): - where = 'in main memory.' if 'memory' in unicode_type(job.exception) \ + where = 'in main memory.' if 'memory' in str(job.exception) \ else 'on the storage card.' titles = '\n'.join(['
  • '+mi.title+'
  • ' for mi in metadata]) @@ -1650,7 +1648,7 @@ class DeviceMixin: # {{{ d.exec_() elif isinstance(job.exception, WrongDestinationError): error_dialog(self, _('Incorrect destination'), - unicode_type(job.exception), show=True) + str(job.exception), show=True) else: self.device_job_exception(job) return diff --git a/src/calibre/gui2/device_drivers/configwidget.py b/src/calibre/gui2/device_drivers/configwidget.py index 36d4d28889..fc9398a0a5 100644 --- a/src/calibre/gui2/device_drivers/configwidget.py +++ b/src/calibre/gui2/device_drivers/configwidget.py @@ -14,7 +14,6 @@ from calibre.gui2 import error_dialog, question_dialog from calibre.gui2.device_drivers.configwidget_ui import Ui_ConfigWidget from calibre.utils.formatter import validation_formatter from calibre.ebooks import BOOK_EXTENSIONS -from polyglot.builtins import unicode_type class ConfigWidget(QWidget, Ui_ConfigWidget): @@ -138,7 +137,7 @@ class ConfigWidget(QWidget, Ui_ConfigWidget): def format_map(self): formats = [ - unicode_type(self.columns.item(i).data(Qt.ItemDataRole.UserRole) or '') + str(self.columns.item(i).data(Qt.ItemDataRole.UserRole) or '') for i in range(self.columns.count()) if self.columns.item(i).checkState()==Qt.CheckState.Checked ] @@ -157,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.' @@ -166,13 +165,13 @@ class ConfigWidget(QWidget, Ui_ConfigWidget): (', '.join(fmts)), self.device_name)): return False - tmpl = unicode_type(self.opt_save_template.text()) + tmpl = str(self.opt_save_template.text()) try: validation_formatter.validate(tmpl) return True except Exception as err: error_dialog(self, _('Invalid template'), '

    '+_('The template %s is invalid:')%tmpl + - '
    '+unicode_type(err), show=True) + '
    '+str(err), show=True) return False diff --git a/src/calibre/gui2/device_drivers/mtp_config.py b/src/calibre/gui2/device_drivers/mtp_config.py index 9a0fc04f8a..2e067f9af4 100644 --- a/src/calibre/gui2/device_drivers/mtp_config.py +++ b/src/calibre/gui2/device_drivers/mtp_config.py @@ -19,7 +19,7 @@ from calibre.gui2 import error_dialog from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.utils.date import parse_date from calibre.gui2.device_drivers.mtp_folder_browser import Browser, IgnoredFolders -from polyglot.builtins import iteritems, unicode_type, range +from polyglot.builtins import iteritems class FormatsConfig(QWidget): # {{{ @@ -50,7 +50,7 @@ class FormatsConfig(QWidget): # {{{ @property def format_map(self): - return [unicode_type(self.f.item(i).data(Qt.ItemDataRole.UserRole) or '') for i in + return [str(self.f.item(i).data(Qt.ItemDataRole.UserRole) or '') for i in range(self.f.count()) if self.f.item(i).checkState()==Qt.CheckState.Checked] def validate(self): @@ -97,7 +97,7 @@ class TemplateConfig(QWidget): # {{{ @property def template(self): - return unicode_type(self.t.text()).strip() + return str(self.t.text()).strip() def edit_template(self): t = TemplateDialog(self, self.template) @@ -114,7 +114,7 @@ class TemplateConfig(QWidget): # {{{ except Exception as err: error_dialog(self, _('Invalid template'), '

    '+_('The template %s is invalid:')%tmpl + - '
    '+unicode_type(err), show=True) + '
    '+str(err), show=True) return False # }}} @@ -155,7 +155,7 @@ class SendToConfig(QWidget): # {{{ @property def value(self): - ans = [x.strip() for x in unicode_type(self.t.text()).strip().split(',')] + ans = [x.strip() for x in str(self.t.text()).strip().split(',')] return [x for x in ans if x] # }}} @@ -187,13 +187,13 @@ class IgnoredDevices(QWidget): # {{{ @property def blacklist(self): - return [unicode_type(self.f.item(i).data(Qt.ItemDataRole.UserRole) or '') for i in + return [str(self.f.item(i).data(Qt.ItemDataRole.UserRole) or '') for i in range(self.f.count()) if self.f.item(i).checkState()==Qt.CheckState.Checked] def ignore_device(self, snum): for i in range(self.f.count()): i = self.f.item(i) - c = unicode_type(i.data(Qt.ItemDataRole.UserRole) or '') + c = str(i.data(Qt.ItemDataRole.UserRole) or '') if c == snum: i.setCheckState(Qt.CheckState.Checked) break @@ -264,10 +264,10 @@ class Rule(QWidget): @property def rule(self): - folder = unicode_type(self.folder.text()).strip() + folder = str(self.folder.text()).strip() if folder: return ( - unicode_type(self.fmt.itemData(self.fmt.currentIndex()) or ''), + str(self.fmt.itemData(self.fmt.currentIndex()) or ''), folder ) return None diff --git a/src/calibre/gui2/device_drivers/mtp_folder_browser.py b/src/calibre/gui2/device_drivers/mtp_folder_browser.py index 9a92437b18..8389ec40d0 100644 --- a/src/calibre/gui2/device_drivers/mtp_folder_browser.py +++ b/src/calibre/gui2/device_drivers/mtp_folder_browser.py @@ -12,7 +12,6 @@ from qt.core import (QTabWidget, QTreeWidget, QTreeWidgetItem, Qt, QDialog, QDialogButtonBox, QVBoxLayout, QSize, pyqtSignal, QIcon, QLabel) from calibre.gui2 import file_icon_provider -from polyglot.builtins import unicode_type, range def browser_item(f, parent): @@ -167,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 @@ -200,11 +198,11 @@ class IgnoredFolders(QDialog): for node in self.iterchildren(w.invisibleRootItem()): if node.checkState(0) == Qt.CheckState.Checked: continue - path = unicode_type(node.data(0, Qt.ItemDataRole.UserRole) or '') + path = str(node.data(0, Qt.ItemDataRole.UserRole) or '') parent = path.rpartition('/')[0] if '/' not in path or icu_lower(parent) not in folders: folders.add(icu_lower(path)) - ans[unicode_type(w.storage.storage_id)] = list(folders) + ans[str(w.storage.storage_id)] = list(folders) return ans diff --git a/src/calibre/gui2/device_drivers/tabbed_device_config.py b/src/calibre/gui2/device_drivers/tabbed_device_config.py index 106543faeb..b467f8294a 100644 --- a/src/calibre/gui2/device_drivers/tabbed_device_config.py +++ b/src/calibre/gui2/device_drivers/tabbed_device_config.py @@ -15,7 +15,6 @@ from qt.core import ( from calibre.ebooks import BOOK_EXTENSIONS from calibre.gui2.device_drivers.mtp_config import (FormatsConfig, TemplateConfig) from calibre.devices.usbms.driver import debug_print -from polyglot.builtins import unicode_type, range def wrap_msg(msg): @@ -154,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) @@ -236,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: @@ -249,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) @@ -339,11 +338,11 @@ class ExtraCustomization(DeviceConfigTab): # {{{ if hasattr(self.opt_extra_customization[i], 'isChecked'): ec.append(self.opt_extra_customization[i].isChecked()) elif hasattr(self.opt_extra_customization[i], 'currentText'): - ec.append(unicode_type(self.opt_extra_customization[i].currentText()).strip()) + ec.append(str(self.opt_extra_customization[i].currentText()).strip()) else: - ec.append(unicode_type(self.opt_extra_customization[i].text()).strip()) + ec.append(str(self.opt_extra_customization[i].text()).strip()) else: - ec = unicode_type(self.opt_extra_customization.text()).strip() + ec = str(self.opt_extra_customization.text()).strip() if not ec: ec = None 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/add_empty_book.py b/src/calibre/gui2/dialogs/add_empty_book.py index 6323ee1f83..2b60a73cc0 100644 --- a/src/calibre/gui2/dialogs/add_empty_book.py +++ b/src/calibre/gui2/dialogs/add_empty_book.py @@ -13,7 +13,6 @@ from calibre.ebooks.metadata import string_to_authors from calibre.gui2.complete2 import EditWithComplete from calibre.utils.config import tweaks from calibre.gui2 import gprefs -from polyglot.builtins import unicode_type class AddEmptyBookDialog(QDialog): @@ -164,11 +163,11 @@ class AddEmptyBookDialog(QDialog): @property def selected_authors(self): - return string_to_authors(unicode_type(self.authors_combo.text())) + return string_to_authors(str(self.authors_combo.text())) @property def selected_series(self): - return unicode_type(self.series_combo.text()) + return str(self.series_combo.text()) @property def selected_title(self): diff --git a/src/calibre/gui2/dialogs/add_from_isbn.py b/src/calibre/gui2/dialogs/add_from_isbn.py index 349c1a2561..8eb6f716ea 100644 --- a/src/calibre/gui2/dialogs/add_from_isbn.py +++ b/src/calibre/gui2/dialogs/add_from_isbn.py @@ -15,7 +15,6 @@ from qt.core import ( from calibre.constants import iswindows from calibre.ebooks.metadata import check_isbn from calibre.gui2 import error_dialog, gprefs, question_dialog -from polyglot.builtins import filter, unicode_type class AddFromISBN(QDialog): @@ -26,7 +25,7 @@ class AddFromISBN(QDialog): path = 'C:\\Users\\kovid\\e-books\\some_book.epub' if iswindows else \ '/Users/kovid/e-books/some_book.epub' - self.label.setText(unicode_type(self.label.text())%path) + self.label.setText(str(self.label.text())%path) self.isbns = [] self.books = [] @@ -75,9 +74,9 @@ class AddFromISBN(QDialog): def paste(self, *args): app = QApplication.instance() c = app.clipboard() - txt = unicode_type(c.text()).strip() + txt = str(c.text()).strip() if txt: - old = unicode_type(self.isbn_box.toPlainText()).strip() + old = str(self.isbn_box.toPlainText()).strip() new = old + '\n' + txt self.isbn_box.setPlainText(new) @@ -86,13 +85,13 @@ class AddFromISBN(QDialog): return self._check_for_existing.isChecked() def accept(self, *args): - tags = unicode_type(self.add_tags.text()).strip().split(',') + tags = str(self.add_tags.text()).strip().split(',') tags = list(filter(None, [x.strip() for x in tags])) gprefs['add from ISBN tags'] = tags gprefs['add from ISBN dup check'] = self.check_for_existing self.set_tags = tags bad = set() - for line in unicode_type(self.isbn_box.toPlainText()).strip().splitlines(): + for line in str(self.isbn_box.toPlainText()).strip().splitlines(): line = line.strip() if not line: continue diff --git a/src/calibre/gui2/dialogs/authors_edit.py b/src/calibre/gui2/dialogs/authors_edit.py index c5930023f0..bb6bf89ef0 100644 --- a/src/calibre/gui2/dialogs/authors_edit.py +++ b/src/calibre/gui2/dialogs/authors_edit.py @@ -15,7 +15,6 @@ from calibre.utils.config_base import tweaks from calibre.gui2 import gprefs from calibre.gui2.complete2 import EditWithComplete from calibre.ebooks.metadata import string_to_authors -from polyglot.builtins import unicode_type, range class ItemDelegate(QStyledItemDelegate): @@ -30,12 +29,12 @@ class ItemDelegate(QStyledItemDelegate): return QStyledItemDelegate.sizeHint(self, *args) + QSize(0, 15) def setEditorData(self, editor, index): - name = unicode_type(index.data(Qt.ItemDataRole.DisplayRole) or '') + name = str(index.data(Qt.ItemDataRole.DisplayRole) or '') editor.setText(name) editor.lineEdit().selectAll() def setModelData(self, editor, model, index): - authors = string_to_authors(unicode_type(editor.text())) + authors = string_to_authors(str(editor.text())) model.setData(index, authors[0]) self.edited.emit(index.row()) @@ -89,10 +88,10 @@ class List(QListWidget): def edited(self, i): item = self.item(i) - q = unicode_type(item.text()) + q = str(item.text()) remove = [] for j in range(self.count()): - if i != j and unicode_type(self.item(j).text()) == q: + if i != j and str(self.item(j).text()) == q: remove.append(j) for x in sorted(remove, reverse=True): self.takeItem(x) @@ -177,7 +176,7 @@ class AuthorsEdit(QDialog): def authors(self): ans = [] for i in range(self.al.count()): - ans.append(unicode_type(self.al.item(i).text())) + ans.append(str(self.al.item(i).text())) return ans or [_('Unknown')] def add_author(self): diff --git a/src/calibre/gui2/dialogs/book_info.py b/src/calibre/gui2/dialogs/book_info.py index a6674498a9..2d078cc5c3 100644 --- a/src/calibre/gui2/dialogs/book_info.py +++ b/src/calibre/gui2/dialogs/book_info.py @@ -19,7 +19,6 @@ from calibre.gui2.book_details import ( from calibre.gui2.ui import get_gui from calibre.gui2.widgets import CoverView from calibre.gui2.widgets2 import Dialog, HTMLDisplay -from polyglot.builtins import unicode_type class Cover(CoverView): @@ -195,9 +194,9 @@ class BookInfo(QDialog): self.ps = QShortcut(QKeySequence('Alt+Left'), self) self.ps.activated.connect(self.previous) self.next_button.setToolTip(_('Next [%s]')% - unicode_type(self.ns.key().toString(QKeySequence.SequenceFormat.NativeText))) + str(self.ns.key().toString(QKeySequence.SequenceFormat.NativeText))) self.previous_button.setToolTip(_('Previous [%s]')% - unicode_type(self.ps.key().toString(QKeySequence.SequenceFormat.NativeText))) + str(self.ps.key().toString(QKeySequence.SequenceFormat.NativeText))) geom = QCoreApplication.instance().desktop().availableGeometry(self) screen_height = geom.height() - 100 @@ -231,7 +230,7 @@ class BookInfo(QDialog): self.refresh(self.current_row, mi=mi) def on_link_clicked(self, qurl): - link = unicode_type(qurl.toString(NO_URL_FORMATTING)) + link = str(qurl.toString(NO_URL_FORMATTING)) self.link_delegate(link) def done(self, r): diff --git a/src/calibre/gui2/dialogs/catalog.py b/src/calibre/gui2/dialogs/catalog.py index 84166111e2..a3741f2c3f 100644 --- a/src/calibre/gui2/dialogs/catalog.py +++ b/src/calibre/gui2/dialogs/catalog.py @@ -18,7 +18,6 @@ from calibre.customize import PluginInstallationType from calibre.customize.ui import catalog_plugins, config from calibre.gui2 import dynamic, info_dialog from calibre.gui2.dialogs.catalog_ui import Ui_Dialog -from polyglot.builtins import unicode_type class Catalog(QDialog, Ui_Dialog): @@ -36,7 +35,7 @@ class Catalog(QDialog, Ui_Dialog): self.dbspec, self.ids = dbspec, ids # Display the number of books we've been passed - self.count.setText(unicode_type(self.count.text()).format(len(ids))) + self.count.setText(str(self.count.text()).format(len(ids))) # Display the last-used title self.title.setText(dynamic.get('catalog_last_used_title', @@ -103,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: @@ -158,7 +157,7 @@ class Catalog(QDialog, Ui_Dialog): return ans def show_plugin_tab(self, idx): - cf = unicode_type(self.format.currentText()).lower() + cf = str(self.format.currentText()).lower() while self.tabs.count() > 1: self.tabs.removeTab(1) for pw in self.widgets: @@ -176,7 +175,7 @@ class Catalog(QDialog, Ui_Dialog): self.buttonBox.button(QDialogButtonBox.StandardButton.Help).setVisible(False) def format_changed(self, idx): - cf = unicode_type(self.format.currentText()) + cf = str(self.format.currentText()) if cf in self.sync_enabled_formats: self.sync.setEnabled(True) else: @@ -187,7 +186,7 @@ class Catalog(QDialog, Ui_Dialog): ''' When title/format change, invalidate Preset in E-book options tab ''' - cf = unicode_type(self.format.currentText()).lower() + cf = str(self.format.currentText()).lower() if cf in ('azw3', 'epub', 'mobi') and hasattr(self.options_widget, 'settings_changed'): self.options_widget.settings_changed("title/format") @@ -200,9 +199,9 @@ class Catalog(QDialog, Ui_Dialog): return ans def save_catalog_settings(self): - self.catalog_format = unicode_type(self.format.currentText()) + self.catalog_format = str(self.format.currentText()) dynamic.set('catalog_preferred_format', self.catalog_format) - self.catalog_title = unicode_type(self.title.text()) + self.catalog_title = str(self.title.text()) dynamic.set('catalog_last_used_title', self.catalog_title) self.catalog_sync = bool(self.sync.isChecked()) dynamic.set('catalog_sync_to_device', self.catalog_sync) diff --git a/src/calibre/gui2/dialogs/check_library.py b/src/calibre/gui2/dialogs/check_library.py index 589913666c..e843e31a08 100644 --- a/src/calibre/gui2/dialogs/check_library.py +++ b/src/calibre/gui2/dialogs/check_library.py @@ -17,7 +17,6 @@ from calibre.gui2.dialogs.confirm_delete import confirm from calibre.library.check_library import CheckLibrary, CHECKS from calibre.utils.recycle_bin import delete_file, delete_tree from calibre import prints, as_unicode -from polyglot.builtins import unicode_type class DBCheck(QDialog): # {{{ @@ -238,8 +237,8 @@ class CheckLibraryDialog(QDialog): return True def accept(self): - self.db.new_api.set_pref('check_library_ignore_extensions', unicode_type(self.ext_ignores.text())) - self.db.new_api.set_pref('check_library_ignore_names', unicode_type(self.name_ignores.text())) + self.db.new_api.set_pref('check_library_ignore_extensions', str(self.ext_ignores.text())) + self.db.new_api.set_pref('check_library_ignore_names', str(self.name_ignores.text())) QDialog.accept(self) def box_to_list(self, txt): @@ -247,8 +246,8 @@ class CheckLibraryDialog(QDialog): def run_the_check(self): checker = CheckLibrary(self.db.library_path, self.db) - checker.scan_library(self.box_to_list(unicode_type(self.name_ignores.text())), - self.box_to_list(unicode_type(self.ext_ignores.text()))) + checker.scan_library(self.box_to_list(str(self.name_ignores.text())), + self.box_to_list(str(self.ext_ignores.text()))) plaintext = [] @@ -409,7 +408,7 @@ class CheckLibraryDialog(QDialog): for it in items: if it.checkState(2) == Qt.CheckState.Checked: try: - p = os.path.join(self.db.library_path, unicode_type(it.text(2))) + p = os.path.join(self.db.library_path, str(it.text(2))) if os.path.isdir(p): delete_tree(p) else: @@ -417,7 +416,7 @@ class CheckLibraryDialog(QDialog): except: prints('failed to delete', os.path.join(self.db.library_path, - unicode_type(it.text(2)))) + str(it.text(2)))) self.run_the_check() def fix_missing_formats(self): 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 a0b586b465..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 ' @@ -7,7 +5,6 @@ from qt.core import QDialog, QTreeWidgetItem, QIcon, QModelIndex from calibre.gui2 import file_icon_provider from calibre.gui2.dialogs.choose_format_device_ui import Ui_ChooseFormatDeviceDialog -from polyglot.builtins import unicode_type class ChooseFormatDeviceDialog(QDialog, Ui_ChooseFormatDeviceDialog): @@ -51,5 +48,5 @@ class ChooseFormatDeviceDialog(QDialog, Ui_ChooseFormatDeviceDialog): return self._format def accept(self): - self._format = unicode_type(self.formats.currentItem().text(0)) + self._format = str(self.formats.currentItem().text(0)) return QDialog.accept(self) diff --git a/src/calibre/gui2/dialogs/choose_library.py b/src/calibre/gui2/dialogs/choose_library.py index 1976496eb7..aadd5d13c4 100644 --- a/src/calibre/gui2/dialogs/choose_library.py +++ b/src/calibre/gui2/dialogs/choose_library.py @@ -17,7 +17,6 @@ from calibre.gui2 import error_dialog, choose_dir from calibre.constants import (filesystem_encoding, iswindows, get_portable_base) from calibre import isbytestring, patheq, force_unicode -from polyglot.builtins import unicode_type class ProgressDialog(PD): @@ -55,7 +54,7 @@ class ChooseLibrary(QDialog, Ui_Dialog): lp = db.library_path if isbytestring(lp): lp = lp.decode(filesystem_encoding) - loc = unicode_type(self.old_location.text()).format(lp) + loc = str(self.old_location.text()).format(lp) self.old_location.setText(loc) self.browse_button.clicked.connect(self.choose_loc) self.empty_library.toggled.connect(self.empty_library_toggled) @@ -169,7 +168,7 @@ class ChooseLibrary(QDialog, Ui_Dialog): action = 'existing' elif self.empty_library.isChecked(): action = 'new' - text = unicode_type(self.location.text()).strip() + text = str(self.location.text()).strip() if not text: return error_dialog(self, _('No location'), _('No location selected'), show=True) @@ -177,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/custom_recipes.py b/src/calibre/gui2/dialogs/custom_recipes.py index 597ea8843c..0242d5c4d0 100644 --- a/src/calibre/gui2/dialogs/custom_recipes.py +++ b/src/calibre/gui2/dialogs/custom_recipes.py @@ -20,7 +20,7 @@ from calibre.web.feeds.recipes import custom_recipes, compile_recipe from calibre.gui2.tweak_book.editor.text import TextEdit from calibre.web.feeds.recipes.collection import get_builtin_recipe_by_id from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import iteritems, unicode_type, range, as_unicode +from polyglot.builtins import iteritems, as_unicode from calibre.gui2.search_box import SearchBox2 from polyglot.builtins import as_bytes @@ -125,14 +125,14 @@ def py3_repr(x): ans = repr(x) if isinstance(x, bytes) and not ans.startswith('b'): ans = 'b' + ans - if isinstance(x, unicode_type) and ans.startswith('u'): + if isinstance(x, str) and ans.startswith('u'): ans = ans[1:] return ans def options_to_recipe_source(title, oldest_article, max_articles_per_feed, feeds): classname = 'BasicUserRecipe%d' % int(time.time()) - title = unicode_type(title).strip() or classname + title = str(title).strip() or classname indent = ' ' * 8 if feeds: if len(feeds[0]) == 1: diff --git a/src/calibre/gui2/dialogs/delete_matching_from_device.py b/src/calibre/gui2/dialogs/delete_matching_from_device.py index 672bf6ce75..2a0cc07bd1 100644 --- a/src/calibre/gui2/dialogs/delete_matching_from_device.py +++ b/src/calibre/gui2/dialogs/delete_matching_from_device.py @@ -13,7 +13,6 @@ from calibre.ebooks.metadata import authors_to_string, authors_to_sort_string, \ from calibre.gui2.dialogs.delete_matching_from_device_ui import \ Ui_DeleteMatchingFromDeviceDialog from calibre.utils.date import UNDEFINED_DATE -from polyglot.builtins import unicode_type class tableItem(QTableWidgetItem): @@ -119,6 +118,6 @@ class DeleteMatchingFromDeviceDialog(QDialog, Ui_DeleteMatchingFromDeviceDialog) if self.table.item(row, 0).checkState() == Qt.CheckState.Unchecked: continue (model, id, path) = self.table.item(row, 0).data(Qt.ItemDataRole.UserRole) - path = unicode_type(path) + path = str(path) self.result.append((model, id, path)) return diff --git a/src/calibre/gui2/dialogs/device_category_editor.py b/src/calibre/gui2/dialogs/device_category_editor.py index 1a816c6e95..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 ' @@ -7,7 +5,6 @@ from qt.core import Qt, QDialog, QListWidgetItem from calibre.gui2.dialogs.device_category_editor_ui import Ui_DeviceCategoryEditor from calibre.gui2 import question_dialog, error_dialog -from polyglot.builtins import unicode_type class ListWidgetItem(QListWidgetItem): @@ -93,7 +90,7 @@ class DeviceCategoryEditor(QDialog, Ui_DeviceCategoryEditor): return if item.text() != item.initial_text(): id_ = int(item.data(Qt.ItemDataRole.UserRole)) - self.to_rename[id_] = unicode_type(item.text()) + self.to_rename[id_] = str(item.text()) def rename_tag(self): item = self.available_tags.currentItem() @@ -112,7 +109,7 @@ class DeviceCategoryEditor(QDialog, Ui_DeviceCategoryEditor): error_dialog(self, _('No items selected'), _('You must select at least one item from the list.')).exec_() return - ct = ', '.join([unicode_type(item.text()) for item in deletes]) + ct = ', '.join([str(item.text()) for item in deletes]) if not question_dialog(self, _('Are you sure?'), '

    '+_('Are you sure you want to delete the following items?')+'
    '+ct): return diff --git a/src/calibre/gui2/dialogs/duplicates.py b/src/calibre/gui2/dialogs/duplicates.py index e21bb6fb7c..961926cdb8 100644 --- a/src/calibre/gui2/dialogs/duplicates.py +++ b/src/calibre/gui2/dialogs/duplicates.py @@ -15,7 +15,6 @@ from qt.core import ( from calibre.gui2 import gprefs from calibre.ebooks.metadata import authors_to_string from calibre.utils.icu import primary_sort_key -from polyglot.builtins import unicode_type, range class DuplicatesQuestion(QDialog): @@ -126,7 +125,7 @@ class DuplicatesQuestion(QDialog): index_is_id=True) or '').split(',')]) def key(x): - return primary_sort_key(unicode_type(author_text[x])) + return primary_sort_key(str(author_text[x])) for book_id in sorted(matching_books, key=key): add_child(ta%dict( @@ -151,10 +150,10 @@ class DuplicatesQuestion(QDialog): for i in range(self.dup_list.topLevelItemCount()): x = self.dup_list.topLevelItem(i) check = '✓' if x.checkState(0) == Qt.CheckState.Checked else '✗' - title = '%s %s' % (check, unicode_type(x.text(0))) + title = '%s %s' % (check, str(x.text(0))) dups = [] for child in (x.child(j) for j in range(x.childCount())): - dups.append('\t' + unicode_type(child.text(0))) + dups.append('\t' + str(child.text(0))) entries.append(title + '\n' + '\n'.join(dups)) return '\n\n'.join(entries) diff --git a/src/calibre/gui2/dialogs/edit_authors_dialog.py b/src/calibre/gui2/dialogs/edit_authors_dialog.py index 100bbeb2dd..acd1d3de0f 100644 --- a/src/calibre/gui2/dialogs/edit_authors_dialog.py +++ b/src/calibre/gui2/dialogs/edit_authors_dialog.py @@ -17,7 +17,6 @@ from calibre.gui2.dialogs.edit_authors_dialog_ui import Ui_EditAuthorsDialog from calibre.utils.config import prefs from calibre.utils.config_base import tweaks from calibre.utils.icu import sort_key, primary_contains, contains, primary_startswith -from polyglot.builtins import unicode_type QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction' @@ -26,14 +25,14 @@ class tableItem(QTableWidgetItem): def __init__(self, txt): QTableWidgetItem.__init__(self, txt) - self.sort_key = sort_key(unicode_type(txt)) + self.sort_key = sort_key(str(txt)) def setText(self, txt): - self.sort_key = sort_key(unicode_type(txt)) + self.sort_key = sort_key(str(txt)) QTableWidgetItem.setText(self, txt) def set_sort_key(self): - self.sort_key = sort_key(unicode_type(self.text())) + self.sort_key = sort_key(str(self.text())) def __ge__(self, other): return self.sort_key >= other.sort_key @@ -184,7 +183,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): def show_table(self, id_to_select, select_sort, select_link, is_first_letter): auts_to_show = {t[0] for t in self.find_aut_func(use_virtual_library=self.apply_vl_checkbox.isChecked())} - filter_text = icu_lower(unicode_type(self.filter_box.text())) + filter_text = icu_lower(str(self.filter_box.text())) if filter_text: auts_to_show = {id_ for id_ in auts_to_show if self.string_contains(filter_text, icu_lower(self.authors[id_]['name']))} @@ -234,7 +233,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): use_as = tweaks['categories_use_field_for_author_name'] == 'author_sort' for row in range(0, len(auts_to_show)): if is_first_letter: - item_txt = unicode_type(self.table.item(row, 1).text() if use_as + item_txt = str(self.table.item(row, 1).text() if use_as else self.table.item(row, 0).text()) if primary_startswith(item_txt, id_to_select): select_item = self.table.item(row, 1 if use_as else 0) @@ -340,32 +339,32 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): from calibre.gui2.ui import get_gui row = self.context_item.row() get_gui().search.set_search_string('authors:="%s"' % - unicode_type(self.table.item(row, 0).text()).replace(r'"', r'\"')) + str(self.table.item(row, 0).text()).replace(r'"', r'\"')) def copy_to_clipboard(self): cb = QApplication.clipboard() - cb.setText(unicode_type(self.context_item.text())) + cb.setText(str(self.context_item.text())) def paste_from_clipboard(self): cb = QApplication.clipboard() self.context_item.setText(cb.text()) def upper_case(self): - self.context_item.setText(icu_upper(unicode_type(self.context_item.text()))) + self.context_item.setText(icu_upper(str(self.context_item.text()))) def lower_case(self): - self.context_item.setText(icu_lower(unicode_type(self.context_item.text()))) + self.context_item.setText(icu_lower(str(self.context_item.text()))) def swap_case(self): - self.context_item.setText(unicode_type(self.context_item.text()).swapcase()) + self.context_item.setText(str(self.context_item.text()).swapcase()) def title_case(self): from calibre.utils.titlecase import titlecase - self.context_item.setText(titlecase(unicode_type(self.context_item.text()))) + self.context_item.setText(titlecase(str(self.context_item.text()))) def capitalize(self): from calibre.utils.icu import capitalize - self.context_item.setText(capitalize(unicode_type(self.context_item.text()))) + self.context_item.setText(capitalize(str(self.context_item.text()))) def copy_aus_to_au(self): row = self.context_item.row() @@ -397,7 +396,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(False) self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setAutoDefault(False) - st = icu_lower(unicode_type(self.find_box.currentText())) + st = icu_lower(str(self.find_box.currentText())) if not st: return for _ in range(0, self.table.rowCount()*2): @@ -405,7 +404,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): r = (self.start_find_pos//2) % self.table.rowCount() c = self.start_find_pos % 2 item = self.table.item(r, c) - text = icu_lower(unicode_type(item.text())) + text = icu_lower(str(item.text())) if st in text: self.table.setCurrentItem(item) self.table.setFocus(True) @@ -445,10 +444,10 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): for row in range(0,self.table.rowCount()): item_aut = self.table.item(row, 0) id_ = int(item_aut.data(Qt.ItemDataRole.UserRole)) - aut = unicode_type(item_aut.text()).strip() + aut = str(item_aut.text()).strip() item_aus = self.table.item(row, 1) # Sometimes trailing commas are left by changing between copy algs - aus = unicode_type(author_to_author_sort(aut)).rstrip(',') + aus = str(author_to_author_sort(aut)).rstrip(',') item_aus.setText(aus) self.authors[id_]['sort'] = aus self.set_icon(item_aus, id_) @@ -458,7 +457,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): def do_auth_sort_to_author(self): self.table.cellChanged.disconnect() for row in range(0,self.table.rowCount()): - aus = unicode_type(self.table.item(row, 1).text()).strip() + aus = str(self.table.item(row, 1).text()).strip() item_aut = self.table.item(row, 0) id_ = int(item_aut.data(Qt.ItemDataRole.UserRole)) item_aut.setText(aus) @@ -469,7 +468,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): def set_icon(self, item, id_): col_name = self.get_column_name(item.column()) - if unicode_type(item.text()) != self.original_authors[id_][col_name]: + if str(item.text()) != self.original_authors[id_][col_name]: item.setIcon(self.edited_icon) else: item.setIcon(self.empty_icon) @@ -478,7 +477,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): id_ = int(self.table.item(row, 0).data(Qt.ItemDataRole.UserRole)) if col == 0: item = self.table.item(row, 0) - aut = unicode_type(item.text()).strip() + aut = str(item.text()).strip() aut_list = string_to_authors(aut) if len(aut_list) != 1: error_dialog(self.parent(), _('Invalid author name'), @@ -497,6 +496,6 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): item = self.table.item(row, col) item.set_sort_key() self.set_icon(item, id_) - self.authors[id_][self.get_column_name(col)] = unicode_type(item.text()) + self.authors[id_][self.get_column_name(col)] = str(item.text()) self.table.setCurrentItem(item) self.table.scrollToItem(item) diff --git a/src/calibre/gui2/dialogs/enum_values_edit.py b/src/calibre/gui2/dialogs/enum_values_edit.py index 682ffebb31..700e169edd 100644 --- a/src/calibre/gui2/dialogs/enum_values_edit.py +++ b/src/calibre/gui2/dialogs/enum_values_edit.py @@ -8,7 +8,6 @@ from qt.core import (QDialog, QColor, QDialogButtonBox, QHeaderView, QAbstractItemView, QComboBox) from calibre.gui2 import error_dialog, gprefs -from polyglot.builtins import unicode_type class EnumValuesEdit(QDialog): @@ -44,7 +43,7 @@ class EnumValuesEdit(QDialog): self.del_button.clicked.connect(self.del_line) - self.all_colors = {unicode_type(s) for s in list(QColor.colorNames())} + self.all_colors = {str(s) for s in list(QColor.colorNames())} tl = QVBoxLayout() l.addItem(tl, 0, 1) @@ -153,13 +152,13 @@ class EnumValuesEdit(QDialog): values = [] colors = [] for i in range(0, self.table.rowCount()): - v = unicode_type(self.table.item(i, 0).text()) + v = str(self.table.item(i, 0).text()) if not v: error_dialog(self, _('Empty value'), _('Empty values are not allowed'), show=True) return values.append(v) - c = unicode_type(self.table.cellWidget(i, 1).currentText()) + c = str(self.table.cellWidget(i, 1).currentText()) if c: colors.append(c) diff --git a/src/calibre/gui2/dialogs/exim.py b/src/calibre/gui2/dialogs/exim.py index 1e4d6356e2..836443adf6 100644 --- a/src/calibre/gui2/dialogs/exim.py +++ b/src/calibre/gui2/dialogs/exim.py @@ -20,7 +20,6 @@ from calibre.gui2 import choose_dir, error_dialog, question_dialog from calibre.gui2.widgets2 import Dialog from calibre.utils.exim import all_known_libraries, export, Importer, import_data from calibre.utils.icu import numeric_sort_key -from polyglot.builtins import range def disk_usage(path_to_dir, abort=None): @@ -37,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/match_books.py b/src/calibre/gui2/dialogs/match_books.py index a6c8b42c08..713bb70e5a 100644 --- a/src/calibre/gui2/dialogs/match_books.py +++ b/src/calibre/gui2/dialogs/match_books.py @@ -13,7 +13,6 @@ from qt.core import (Qt, QDialog, QAbstractItemView, QTableWidgetItem, from calibre.gui2 import gprefs, error_dialog from calibre.gui2.dialogs.match_books_ui import Ui_MatchBooks from calibre.utils.icu import sort_key -from polyglot.builtins import unicode_type class TableItem(QTableWidgetItem): @@ -126,7 +125,7 @@ class MatchBooks(QDialog, Ui_MatchBooks): QDialog.keyPressEvent(self, e) def do_search(self): - query = unicode_type(self.search_text.text()) + query = str(self.search_text.text()) if not query: d = error_dialog(self.gui, _('Match books'), _('You must enter a search expression into the search field')) diff --git a/src/calibre/gui2/dialogs/message_box.py b/src/calibre/gui2/dialogs/message_box.py index 64a6e164c2..5b3f9ce89f 100644 --- a/src/calibre/gui2/dialogs/message_box.py +++ b/src/calibre/gui2/dialogs/message_box.py @@ -15,7 +15,6 @@ from qt.core import ( from calibre.constants import __version__, isfrozen from calibre.gui2 import gprefs -from polyglot.builtins import unicode_type class Icon(QWidget): @@ -434,13 +433,13 @@ class JobError(QDialog): # {{{ QApplication.clipboard().setText( 'calibre, version %s (%s, embedded-python: %s)\n%s: %s\n\n%s' % (__version__, sys.platform, isfrozen, - unicode_type(self.windowTitle()), unicode_type(d.toPlainText()), - unicode_type(self.det_msg.toPlainText()))) + str(self.windowTitle()), str(d.toPlainText()), + str(self.det_msg.toPlainText()))) if hasattr(self, 'ctc_button'): self.ctc_button.setText(_('Copied')) def toggle_det_msg(self, *args): - vis = unicode_type(self.det_msg_toggle.text()) == self.hide_det_msg + vis = str(self.det_msg_toggle.text()) == self.hide_det_msg self.det_msg_toggle.setText(self.show_det_msg if vis else self.hide_det_msg) self.det_msg.setVisible(not vis) diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index 0a053774f2..50454e567b 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -33,9 +33,7 @@ from calibre.utils.config import JSONConfig, dynamic, prefs, tweaks from calibre.utils.date import internal_iso_format_string, qt_to_dt from calibre.utils.icu import capitalize, sort_key from calibre.utils.titlecase import titlecase -from polyglot.builtins import ( - error_message, filter, iteritems, itervalues, native_string_type, unicode_type -) +from polyglot.builtins import error_message, iteritems, itervalues, native_string_type Settings = namedtuple('Settings', 'remove_all remove add au aus do_aus rating pub do_series do_autonumber ' @@ -175,7 +173,7 @@ class MyBlockingBusy(QDialog): # {{{ except Exception as err: import traceback try: - err = unicode_type(err) + err = str(err) except: err = repr(err) self.error = (err, traceback.format_exc()) @@ -500,7 +498,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): self.refresh_book_list.toggled.connect(self.save_refresh_booklist) self.ids = [self.db.id(r) for r in rows] self.first_title = self.db.title(self.ids[0], index_is_id=True) - self.cover_clone.setToolTip(unicode_type(self.cover_clone.toolTip()) + ' (%s)' % self.first_title) + self.cover_clone.setToolTip(str(self.cover_clone.toolTip()) + ' (%s)' % self.first_title) self.setWindowTitle(ngettext( 'Editing metadata for one book', 'Editing metadata for {} books', len(rows)).format(len(rows))) @@ -598,8 +596,8 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): self.comments = d.textbox.html b = self.comments_button b.setStyleSheet('QPushButton { font-weight: bold }') - if unicode_type(b.text())[-1] != '*': - b.setText(unicode_type(b.text()) + ' *') + if str(b.text())[-1] != '*': + b.setText(str(b.text()) + ' *') def save_refresh_booklist(self, *args): gprefs['refresh_book_list_on_bulk_edit'] = bool(self.refresh_book_list.isChecked()) @@ -769,18 +767,18 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): def s_r_sf_itemdata(self, idx): if idx is None: idx = self.search_field.currentIndex() - return unicode_type(self.search_field.itemData(idx) or '') + return str(self.search_field.itemData(idx) or '') def s_r_df_itemdata(self, idx): if idx is None: idx = self.destination_field.currentIndex() - return unicode_type(self.destination_field.itemData(idx) or '') + return str(self.destination_field.itemData(idx) or '') def s_r_get_field(self, mi, field): if field: if field == '{template}': v = SafeFormat().safe_format( - unicode_type(self.s_r_template.text()), mi, _('S/R TEMPLATE ERROR'), mi) + str(self.s_r_template.text()), mi, _('S/R TEMPLATE ERROR'), mi) return [v] fm = self.db.metadata_for_field(field) if field == 'sort': @@ -790,10 +788,10 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): else: val = mi.get(field, None) if isinstance(val, (numbers.Number, bool)): - val = unicode_type(val) + val = str(val) elif fm['is_csp']: # convert the csp dict into a list - id_type = unicode_type(self.s_r_src_ident.currentText()) + id_type = str(self.s_r_src_ident.currentText()) if id_type: val = [val.get(id_type, '')] else: @@ -842,7 +840,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): if len(t) > 1: t = t[self.starting_from.value()-1: self.starting_from.value()-1 + self.results_count.value()] - w.setText(unicode_type(self.multiple_separator.text()).join(t)) + w.setText(str(self.multiple_separator.text()).join(t)) if self.search_mode.currentIndex() == 0: self.destination_field.setCurrentIndex(idx) @@ -907,8 +905,8 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): getattr(self, 'book_%d_result'%(i+1)).setText('') def s_r_func(self, match): - rfunc = self.s_r_functions[unicode_type(self.replace_func.currentText())] - rtext = unicode_type(self.replace_with.text()) + rfunc = self.s_r_functions[str(self.replace_func.currentText())] + rtext = str(self.replace_with.text()) rtext = match.expand(rtext) return rfunc(rtext) @@ -916,7 +914,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): src_field = self.s_r_sf_itemdata(None) src = self.s_r_get_field(mi, src_field) result = [] - rfunc = self.s_r_functions[unicode_type(self.replace_func.currentText())] + rfunc = self.s_r_functions[str(self.replace_func.currentText())] for s in src: t = self.s_r_obj.sub(self.s_r_func, s) if self.search_mode.currentIndex() == 0: @@ -950,7 +948,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): dest_mode = self.replace_mode.currentIndex() if self.destination_field_fm['is_csp']: - dest_ident = unicode_type(self.s_r_dst_ident.text()) + dest_ident = str(self.s_r_dst_ident.text()) if not dest_ident or (src == 'identifiers' and dest_ident == '*'): raise Exception(_('You must specify a destination identifier type')) @@ -967,7 +965,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): if dest_mode != 0: dest_val = mi.get(dest, '') if self.db.metadata_for_field(dest)['is_csp']: - dst_id_type = unicode_type(self.s_r_dst_ident.text()) + dst_id_type = str(self.s_r_dst_ident.text()) if dst_id_type: dest_val = [dest_val.get(dst_id_type, '')] else: @@ -1000,7 +998,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): flags |= regex.IGNORECASE try: - stext = unicode_type(self.search_for.text()) + stext = str(self.search_for.text()) if not stext: raise Exception(_('You must specify a search expression in the "Search for" field')) if self.search_mode.currentIndex() == 0: @@ -1036,7 +1034,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): if len(t) > 1 and self.destination_field_fm['is_multiple']: t = t[self.starting_from.value()-1: self.starting_from.value()-1 + self.results_count.value()] - t = unicode_type(self.multiple_separator.text()).join(t) + t = str(self.multiple_separator.text()).join(t) else: t = self.s_r_replace_mode_separator().join(t) wr.setText(t) @@ -1060,7 +1058,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): if dfm['is_csp']: # convert the colon-separated pair strings back into a dict, # which is what set_identifiers wants - dst_id_type = unicode_type(self.s_r_dst_ident.text()) + dst_id_type = str(self.s_r_dst_ident.text()) if dst_id_type and dst_id_type != '*': v = ''.join(val) ids = mi.get(dest) @@ -1188,19 +1186,19 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): remove_all = self.remove_all_tags.isChecked() remove = [] if not remove_all: - remove = unicode_type(self.remove_tags.text()).strip().split(',') - add = unicode_type(self.tags.text()).strip().split(',') - au = unicode_type(self.authors.text()) - aus = unicode_type(self.author_sort.text()) + remove = str(self.remove_tags.text()).strip().split(',') + add = str(self.tags.text()).strip().split(',') + au = str(self.authors.text()) + aus = str(self.author_sort.text()) do_aus = self.author_sort.isEnabled() rating = self.rating.rating_value if not self.apply_rating.isChecked(): rating = -1 - pub = unicode_type(self.publisher.text()) + pub = str(self.publisher.text()) do_series = self.write_series clear_series = self.clear_series.isChecked() clear_pub = self.clear_pub.isChecked() - series = unicode_type(self.series.currentText()).strip() + series = str(self.series.currentText()).strip() do_autonumber = self.autonumber_series.isChecked() do_series_restart = self.series_numbering_restarts.isChecked() series_start_value = self.series_start_number.value() @@ -1280,7 +1278,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): return QDialog.accept(self) def series_changed(self, *args): - self.write_series = bool(unicode_type(self.series.currentText()).strip()) + self.write_series = bool(str(self.series.currentText()).strip()) self.autonumber_series.setEnabled(True) def s_r_remove_query(self, *args): @@ -1293,7 +1291,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): return item_id = self.query_field.currentIndex() - item_name = unicode_type(self.query_field.currentText()) + item_name = str(self.query_field.currentText()) self.query_field.blockSignals(True) self.query_field.removeItem(item_id) @@ -1321,7 +1319,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): error_dialog(self, _("Save search/replace"), _("You must provide a name."), show=True) new = True - name = unicode_type(name) + name = str(name) if name in list(self.queries.keys()): if not question_dialog(self, _("Save search/replace"), _("That saved search/replace already exists and will be overwritten. " @@ -1331,21 +1329,21 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): query = {} query['name'] = name - query['search_field'] = unicode_type(self.search_field.currentText()) - query['search_mode'] = unicode_type(self.search_mode.currentText()) - query['s_r_template'] = unicode_type(self.s_r_template.text()) - query['s_r_src_ident'] = unicode_type(self.s_r_src_ident.currentText()) - query['search_for'] = unicode_type(self.search_for.text()) + query['search_field'] = str(self.search_field.currentText()) + query['search_mode'] = str(self.search_mode.currentText()) + query['s_r_template'] = str(self.s_r_template.text()) + query['s_r_src_ident'] = str(self.s_r_src_ident.currentText()) + query['search_for'] = str(self.search_for.text()) query['case_sensitive'] = self.case_sensitive.isChecked() - query['replace_with'] = unicode_type(self.replace_with.text()) - query['replace_func'] = unicode_type(self.replace_func.currentText()) - query['destination_field'] = unicode_type(self.destination_field.currentText()) - query['s_r_dst_ident'] = unicode_type(self.s_r_dst_ident.text()) - query['replace_mode'] = unicode_type(self.replace_mode.currentText()) + query['replace_with'] = str(self.replace_with.text()) + query['replace_func'] = str(self.replace_func.currentText()) + query['destination_field'] = str(self.destination_field.currentText()) + query['s_r_dst_ident'] = str(self.s_r_dst_ident.text()) + query['replace_mode'] = str(self.replace_mode.currentText()) query['comma_separated'] = self.comma_separated.isChecked() query['results_count'] = self.results_count.value() query['starting_from'] = self.starting_from.value() - query['multiple_separator'] = unicode_type(self.multiple_separator.text()) + query['multiple_separator'] = str(self.multiple_separator.text()) self.queries[name] = query self.queries.commit() @@ -1364,7 +1362,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog): self.s_r_reset_query_fields() self.saved_search_name = '' return - item = self.queries.get(unicode_type(item_name), None) + item = self.queries.get(str(item_name), None) if item is None: self.s_r_reset_query_fields() return diff --git a/src/calibre/gui2/dialogs/opml.py b/src/calibre/gui2/dialogs/opml.py index 23996fbc90..558c2e5b3c 100644 --- a/src/calibre/gui2/dialogs/opml.py +++ b/src/calibre/gui2/dialogs/opml.py @@ -17,7 +17,6 @@ from lxml import etree from calibre.gui2 import choose_files, error_dialog from calibre.utils.xml_parse import safe_xml_fromstring from calibre.utils.icu import sort_key -from polyglot.builtins import unicode_type Group = namedtuple('Group', 'title feeds') @@ -126,7 +125,7 @@ class ImportOPML(QDialog): self.path.setText(opml_files[0]) def accept(self): - path = unicode_type(self.path.text()) + path = str(self.path.text()) if not path: return error_dialog(self, _('Path not specified'), _( 'You must specify the path to the OPML file to import'), show=True) diff --git a/src/calibre/gui2/dialogs/password.py b/src/calibre/gui2/dialogs/password.py index 134ec669cf..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 ' @@ -8,7 +6,6 @@ from qt.core import QDialog, QLineEdit, Qt from calibre.gui2.dialogs.password_ui import Ui_Dialog from calibre.gui2 import dynamic -from polyglot.builtins import unicode_type class PasswordDialog(QDialog, Ui_Dialog): @@ -38,12 +35,12 @@ class PasswordDialog(QDialog, Ui_Dialog): self.gui_password.setEchoMode(QLineEdit.EchoMode.Normal) def username(self): - return unicode_type(self.gui_username.text()) + return str(self.gui_username.text()) def password(self): - return unicode_type(self.gui_password.text()) + return str(self.gui_password.text()) def accept(self): - dynamic.set(self.cfg_key+'__un', unicode_type(self.gui_username.text())) - dynamic.set(self.cfg_key+'__pw', unicode_type(self.gui_password.text())) + dynamic.set(self.cfg_key+'__un', str(self.gui_username.text())) + dynamic.set(self.cfg_key+'__pw', str(self.gui_password.text())) QDialog.accept(self) diff --git a/src/calibre/gui2/dialogs/plugin_updater.py b/src/calibre/gui2/dialogs/plugin_updater.py index 95175298b0..1b37b619fb 100644 --- a/src/calibre/gui2/dialogs/plugin_updater.py +++ b/src/calibre/gui2/dialogs/plugin_updater.py @@ -29,7 +29,7 @@ from calibre.gui2 import error_dialog, gprefs, info_dialog, open_url, question_d from calibre.gui2.preferences.plugins import ConfigWidget from calibre.utils.date import UNDEFINED_DATE, format_date from calibre.utils.https import get_https_resource_securely -from polyglot.builtins import filter, itervalues, map, unicode_type +from polyglot.builtins import itervalues SERVER = 'https://code.calibre-ebook.com/plugins/' INDEX_URL = '%splugins.json.bz2' % SERVER @@ -258,7 +258,7 @@ class DisplayPluginSortFilterModel(QSortFilterProxyModel): self.invalidateFilter() def set_filter_text(self, filter_text_value): - self.filter_text = icu_lower(unicode_type(filter_text_value)) + self.filter_text = icu_lower(str(filter_text_value)) self.invalidateFilter() @@ -267,7 +267,7 @@ class DisplayPluginModel(QAbstractTableModel): def __init__(self, display_plugins): QAbstractTableModel.__init__(self) self.display_plugins = display_plugins - self.headers = list(map(unicode_type, [_('Plugin name'), _('Donate'), _('Status'), _('Installed'), + self.headers = list(map(str, [_('Plugin name'), _('Donate'), _('Status'), _('Installed'), _('Available'), _('Released'), _('calibre'), _('Author')])) def rowCount(self, *args): @@ -348,7 +348,7 @@ class DisplayPluginModel(QAbstractTableModel): def _get_display_version(self, version): if version is None: return '' - return '.'.join([unicode_type(v) for v in list(version)]) + return '.'.join([str(v) for v in list(version)]) def _get_status(self, display_plugin): if not display_plugin.is_valid_platform(): @@ -713,7 +713,7 @@ class PluginUpdaterDialog(SizePersistedDialog): plugin = add_plugin(zip_path) except NameConflict as e: return error_dialog(self.gui, _('Already exists'), - unicode_type(e), show=True) + str(e), show=True) # Check for any toolbars to add to. widget = ConfigWidget(self.gui) widget.gui = self.gui diff --git a/src/calibre/gui2/dialogs/progress.py b/src/calibre/gui2/dialogs/progress.py index 778795336c..9aed79ec4d 100644 --- a/src/calibre/gui2/dialogs/progress.py +++ b/src/calibre/gui2/dialogs/progress.py @@ -11,7 +11,6 @@ from qt.core import ( from calibre.gui2 import elided_text from calibre.gui2.progress_indicator import ProgressIndicator -from polyglot.builtins import unicode_type class ProgressDialog(QDialog): @@ -102,7 +101,7 @@ class ProgressDialog(QDialog): @title.setter def title(self, val): - self.title_label.setText(unicode_type(val or '')) + self.title_label.setText(str(val or '')) @property def msg(self): @@ -110,7 +109,7 @@ class ProgressDialog(QDialog): @msg.setter def msg(self, val): - val = unicode_type(val or '') + val = str(val or '') self.message.setText(elided_text(val, self.font(), self.message.minimumWidth()-10)) def _canceled(self, *args): diff --git a/src/calibre/gui2/dialogs/quickview.py b/src/calibre/gui2/dialogs/quickview.py index 84a455c327..b02258ae69 100644 --- a/src/calibre/gui2/dialogs/quickview.py +++ b/src/calibre/gui2/dialogs/quickview.py @@ -20,7 +20,6 @@ from calibre.gui2.dialogs.quickview_ui import Ui_Quickview from calibre.utils.date import timestampfromdt from calibre.utils.icu import sort_key from calibre.utils.iso8601 import UNDEFINED_DATE -from polyglot.builtins import unicode_type class TableItem(QTableWidgetItem): @@ -51,7 +50,7 @@ class TableItem(QTableWidgetItem): # self is not None and other is None therefore self >= other return True - if isinstance(self.sort, (bytes, unicode_type)): + if isinstance(self.sort, (bytes, str)): l = sort_key(self.sort) r = sort_key(other.sort) else: @@ -76,7 +75,7 @@ class TableItem(QTableWidgetItem): # self is not None therefore self > other return False - if isinstance(self.sort, (bytes, unicode_type)): + if isinstance(self.sort, (bytes, str)): l = sort_key(self.sort) r = sort_key(other.sort) else: @@ -483,7 +482,7 @@ class Quickview(QDialog, Ui_Quickview): def item_selected(self, txt): if self.no_valid_items: return - self.fill_in_books_box(unicode_type(txt)) + self.fill_in_books_box(str(txt)) self.set_search_text(self.current_key + ':"=' + txt.replace('"', '\\"') + '"') def vl_box_changed(self): @@ -569,9 +568,9 @@ class Quickview(QDialog, Ui_Quickview): self.no_valid_items = False if self.fm[key]['datatype'] == 'rating': if self.fm[key]['display'].get('allow_half_stars', False): - vals = unicode_type(vals/2.0) + vals = str(vals/2.0) else: - vals = unicode_type(vals//2) + vals = str(vals//2) if not isinstance(vals, list): vals = [vals] vals.sort(key=sort_key) @@ -858,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 ba7c274cba..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' @@ -27,7 +25,7 @@ from calibre.utils.date import utcnow from calibre.utils.network import internet_connected from calibre import force_unicode from calibre.utils.localization import get_lang, canonicalize_lang -from polyglot.builtins import iteritems, unicode_type, range, map +from polyglot.builtins import iteritems def convert_day_time_schedule(val): @@ -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)) @@ -160,7 +158,7 @@ class DaysOfMonth(Base): @property def schedule(self): - parts = [x.strip() for x in unicode_type(self.days.text()).split(',') if + parts = [x.strip() for x in str(self.days.text()).split(',') if x.strip()] try: days_of_month = tuple(map(int, parts)) @@ -456,7 +454,7 @@ class SchedulerDialog(QDialog): return True if self.account.isVisible(): - un, pw = map(unicode_type, (self.username.text(), self.password.text())) + un, pw = map(str, (self.username.text(), self.password.text())) un, pw = un.strip(), pw.strip() if not un and not pw and self.schedule.isChecked(): if not getattr(self, 'subscription_optional', False): @@ -479,8 +477,8 @@ class SchedulerDialog(QDialog): add_title_tag = self.add_title_tag.isChecked() keep_issues = '0' if self.keep_issues.isEnabled(): - keep_issues = unicode_type(self.keep_issues.value()) - custom_tags = unicode_type(self.custom_tags.text()).strip() + keep_issues = str(self.keep_issues.value()) + custom_tags = str(self.custom_tags.text()).strip() custom_tags = [x.strip() for x in custom_tags.split(',')] self.recipe_model.customize_recipe(urn, add_title_tag, custom_tags, keep_issues) return True diff --git a/src/calibre/gui2/dialogs/search.py b/src/calibre/gui2/dialogs/search.py index d02f14dede..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 ' @@ -20,7 +18,6 @@ from calibre.utils.icu import sort_key from calibre.utils.config import tweaks from calibre.utils.date import now from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import unicode_type, range, map box_values = {} last_matchkind = CONTAINS_MATCH @@ -39,7 +36,7 @@ def init_dateop(cb): def current_dateop(cb): - return unicode_type(cb.itemData(cb.currentIndex()) or '') + return str(cb.itemData(cb.currentIndex()) or '') def create_msg_label(self): @@ -332,11 +329,11 @@ class SearchDialog(QDialog): gprefs.set('advanced_search_simple_tab_focused_field', fw.objectName()) elif self.tab_widget.currentIndex() == 3: gprefs.set('advanced_search_template_tab_program_field', - unicode_type(self.template_program_box.text())) + str(self.template_program_box.text())) gprefs.set('advanced_search_template_tab_value_field', - unicode_type(self.template_value_box.text())) + str(self.template_value_box.text())) gprefs.set('advanced_search_template_tab_test_field', - unicode_type(self.template_test_type_box.currentIndex())) + str(self.template_test_type_box.currentIndex())) def accept(self): self.save_state() @@ -374,17 +371,17 @@ class SearchDialog(QDialog): self.date_search_string, self.template_search_string)[i]() def template_search_string(self): - template = unicode_type(self.template_program_box.text()) - value = unicode_type(self.template_value_box.text()).replace('"', '\\"') + template = str(self.template_program_box.text()) + value = str(self.template_value_box.text()).replace('"', '\\"') if template and value: cb = self.template_test_type_box - op = unicode_type(cb.itemData(cb.currentIndex())) - l = '{0}#@#:{1}:{2}'.format(template, op, value) + op = str(cb.itemData(cb.currentIndex())) + l = '{}#@#:{}:{}'.format(template, op, value) return 'template:"' + l + '"' return '' def date_search_string(self): - field = unicode_type(self.date_field.itemData(self.date_field.currentIndex()) or '') + field = str(self.date_field.itemData(self.date_field.currentIndex()) or '') op = current_dateop(self.dateop_date) prefix = '%s:%s' % (field, op) if self.sel_date.isChecked(): @@ -400,7 +397,7 @@ class SearchDialog(QDialog): val = self.date_daysago.value() val *= {0:1, 1:7, 2:30, 3:365}[self.date_ago_type.currentIndex()] return '%s%sdaysago' % (prefix, val) - return '%s%s' % (prefix, unicode_type(self.date_human.itemData(self.date_human.currentIndex()) or '')) + return '%s%s' % (prefix, str(self.date_human.itemData(self.date_human.currentIndex()) or '')) def adv_search_string(self): mk = self.matchkind.currentIndex() @@ -410,7 +407,7 @@ class SearchDialog(QDialog): self.mc = '=' else: self.mc = '~' - all, any, phrase, none = map(lambda x: unicode_type(x.text()), + all, any, phrase, none = map(lambda x: str(x.text()), (self.all, self.any, self.phrase, self.none)) all, any, none = map(self.tokens, (all, any, none)) phrase = phrase.strip() @@ -432,11 +429,11 @@ class SearchDialog(QDialog): return ans def token(self): - txt = unicode_type(self.text.text()).strip() + txt = str(self.text.text()).strip() if txt: if self.negate.isChecked(): txt = '!'+txt - tok = self.FIELDS[unicode_type(self.field.currentText())]+txt + tok = self.FIELDS[str(self.field.currentText())]+txt if re.search(r'\s', tok): tok = '"%s"'%tok return tok @@ -452,35 +449,35 @@ class SearchDialog(QDialog): ans = [] self.box_last_values = {} - title = unicode_type(self.title_box.text()).strip() + title = str(self.title_box.text()).strip() self.box_last_values['title_box'] = title if title: ans.append('title:"' + self.mc + title + '"') - author = unicode_type(self.authors_box.text()).strip() + author = str(self.authors_box.text()).strip() self.box_last_values['authors_box'] = author if author: ans.append('author:"' + self.mc + author + '"') - series = unicode_type(self.series_box.text()).strip() + series = str(self.series_box.text()).strip() self.box_last_values['series_box'] = series if series: ans.append('series:"' + self.mc + series + '"') - tags = unicode_type(self.tags_box.text()) + tags = str(self.tags_box.text()) self.box_last_values['tags_box'] = tags tags = [t.strip() for t in tags.split(',') if t.strip()] if tags: tags = ['tags:"' + self.mc + t + '"' for t in tags] ans.append('(' + ' or '.join(tags) + ')') - general = unicode_type(self.general_box.text()) + general = str(self.general_box.text()) self.box_last_values['general_box'] = general - general_index = unicode_type(self.general_combo.currentText()) + general_index = str(self.general_combo.currentText()) self.box_last_values['general_index'] = general_index global box_values global last_matchkind box_values = copy.deepcopy(self.box_last_values) last_matchkind = mk if general: - ans.append(unicode_type(self.general_combo.currentText()) + ':"' + + ans.append(str(self.general_combo.currentText()) + ':"' + self.mc + general + '"') if ans: return ' and '.join(ans) diff --git a/src/calibre/gui2/dialogs/smartdevice.py b/src/calibre/gui2/dialogs/smartdevice.py index 6dc518f055..aa15fb96ba 100644 --- a/src/calibre/gui2/dialogs/smartdevice.py +++ b/src/calibre/gui2/dialogs/smartdevice.py @@ -9,7 +9,7 @@ from qt.core import (QDialog, QLineEdit, Qt) from calibre.gui2 import error_dialog from calibre.gui2.dialogs.smartdevice_ui import Ui_Dialog from calibre.utils.mdns import get_all_ips -from polyglot.builtins import itervalues, unicode_type, map +from polyglot.builtins import itervalues def ipaddr_sort_key(ipaddr): @@ -107,7 +107,7 @@ class SmartdeviceDialog(QDialog, Ui_Dialog): Qt.CheckState.Unchecked else QLineEdit.EchoMode.Normal) def accept(self): - port = unicode_type(self.fixed_port.text()) + port = str(self.fixed_port.text()) if not port: error_dialog(self, _('Invalid port number'), _('You must provide a port number.'), show=True) @@ -125,13 +125,13 @@ class SmartdeviceDialog(QDialog, Ui_Dialog): return self.device_manager.set_option('smartdevice', 'password', - unicode_type(self.password_box.text())) + str(self.password_box.text())) self.device_manager.set_option('smartdevice', 'autostart', self.autostart_box.isChecked()) self.device_manager.set_option('smartdevice', 'use_fixed_port', self.use_fixed_port.isChecked()) self.device_manager.set_option('smartdevice', 'port_number', - unicode_type(self.fixed_port.text())) + str(self.fixed_port.text())) message = self.device_manager.start_plugin('smartdevice') diff --git a/src/calibre/gui2/dialogs/tag_categories.py b/src/calibre/gui2/dialogs/tag_categories.py index 2efd5c269b..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 ' @@ -11,7 +9,7 @@ from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2 import error_dialog, warning_dialog from calibre.constants import islinux from calibre.utils.icu import sort_key, strcmp, primary_contains -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class Item: @@ -230,7 +228,7 @@ class TagCategories(QDialog, Ui_TagCategories): def add_category(self): self.save_category() - cat_name = unicode_type(self.input_box.text()).strip() + cat_name = str(self.input_box.text()).strip() if cat_name == '': return False comps = [c.strip() for c in cat_name.split('.') if c.strip()] @@ -259,7 +257,7 @@ class TagCategories(QDialog, Ui_TagCategories): def rename_category(self): self.save_category() - cat_name = unicode_type(self.input_box.text()).strip() + cat_name = str(self.input_box.text()).strip() if cat_name == '': return False if not self.current_cat_name: @@ -300,7 +298,7 @@ class TagCategories(QDialog, Ui_TagCategories): self.save_category() s = self.category_box.itemText(idx) if s: - self.current_cat_name = unicode_type(s) + self.current_cat_name = str(s) else: self.current_cat_name = None self.fill_applied_items() diff --git a/src/calibre/gui2/dialogs/tag_editor.py b/src/calibre/gui2/dialogs/tag_editor.py index e36df92a74..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 ' @@ -10,7 +8,6 @@ from calibre.gui2.dialogs.tag_editor_ui import Ui_TagEditor from calibre.gui2 import question_dialog, error_dialog, gprefs from calibre.constants import islinux from calibre.utils.icu import sort_key, primary_contains -from polyglot.builtins import unicode_type, range class TagEditor(QDialog, Ui_TagEditor): @@ -125,15 +122,15 @@ class TagEditor(QDialog, Ui_TagEditor): return pos = self.available_tags.verticalScrollBar().value() for item in items: - used = self.db.is_tag_used(unicode_type(item.text())) \ + used = self.db.is_tag_used(str(item.text())) \ if self.key is None else \ - self.db.is_item_used_in_multiple(unicode_type(item.text()), label=self.key) + self.db.is_item_used_in_multiple(str(item.text()), label=self.key) if used: confirms.append(item) else: deletes.append(item) if confirms: - ct = ', '.join([unicode_type(item.text()) for item in confirms]) + ct = ', '.join([str(item.text()) for item in confirms]) if question_dialog(self, _('Are your sure?'), '

    '+_('The following tags are used by one or more books. ' 'Are you certain you want to delete them?')+'
    '+ct): @@ -141,9 +138,9 @@ class TagEditor(QDialog, Ui_TagEditor): for item in deletes: if self.key is None: - self.db.delete_tag(unicode_type(item.text())) + self.db.delete_tag(str(item.text())) else: - bks = self.db.delete_item_from_multiple(unicode_type(item.text()), + bks = self.db.delete_item_from_multiple(str(item.text()), label=self.key) self.db.refresh_ids(bks) self.available_tags.takeItem(self.available_tags.row(item)) @@ -161,7 +158,7 @@ class TagEditor(QDialog, Ui_TagEditor): row = max(rows) tags = self._get_applied_tags_box_contents() for item in items: - tag = unicode_type(item.text()) + tag = str(item.text()) tags.append(tag) self.available_tags.takeItem(self.available_tags.row(item)) @@ -184,14 +181,14 @@ class TagEditor(QDialog, Ui_TagEditor): def _get_applied_tags_box_contents(self): tags = [] for i in range(0, self.applied_tags.count()): - tags.append(unicode_type(self.applied_tags.item(i).text())) + tags.append(str(self.applied_tags.item(i).text())) return tags def unapply_tags(self, item=None): tags = self._get_applied_tags_box_contents() items = self.applied_tags.selectedItems() if item is None else [item] for item in items: - tag = unicode_type(item.text()) + tag = str(item.text()) tags.remove(tag) self.available_tags.addItem(tag) @@ -201,7 +198,7 @@ class TagEditor(QDialog, Ui_TagEditor): for tag in tags: self.applied_tags.addItem(tag) - items = [unicode_type(self.available_tags.item(x).text()) for x in + items = [str(self.available_tags.item(x).text()) for x in range(self.available_tags.count())] items.sort(key=sort_key) self.available_tags.clear() @@ -213,7 +210,7 @@ class TagEditor(QDialog, Ui_TagEditor): self.filter_tags(self.available_filter_input.text()) def add_tag(self): - tags = unicode_type(self.add_tag_input.text()).split(self.sep) + tags = str(self.add_tag_input.text()).split(self.sep) tags_in_box = self._get_applied_tags_box_contents() for tag in tags: tag = tag.strip() @@ -237,10 +234,10 @@ class TagEditor(QDialog, Ui_TagEditor): # filter tags def filter_tags(self, filter_value, which='available_tags'): collection = getattr(self, which) - q = icu_lower(unicode_type(filter_value)) + q = icu_lower(str(filter_value)) for i in range(collection.count()): # on every available tag item = collection.item(i) - item.setHidden(bool(q and not primary_contains(q, unicode_type(item.text())))) + item.setHidden(bool(q and not primary_contains(q, str(item.text())))) def accept(self): self.tags = self._get_applied_tags_box_contents() diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index 9ee9f9fbdb..1908e6d272 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -18,7 +18,6 @@ from calibre.gui2 import question_dialog, error_dialog, gprefs from calibre.utils.config import prefs from calibre.utils.icu import contains, primary_contains, primary_startswith, capitalize from calibre.utils.titlecase import titlecase -from polyglot.builtins import unicode_type QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction' @@ -84,18 +83,18 @@ class NameTableWidgetItem(QTableWidgetItem): self.setText(self.text_before_placeholder) def __ge__(self, other): - return (self.sort_key(unicode_type(self.text())) >= - self.sort_key(unicode_type(other.text()))) + return (self.sort_key(str(self.text())) >= + self.sort_key(str(other.text()))) def __lt__(self, other): - return (self.sort_key(unicode_type(self.text())) < - self.sort_key(unicode_type(other.text()))) + return (self.sort_key(str(self.text())) < + self.sort_key(str(other.text()))) class CountTableWidgetItem(QTableWidgetItem): def __init__(self, count): - QTableWidgetItem.__init__(self, unicode_type(count)) + QTableWidgetItem.__init__(self, str(count)) self._count = count def __ge__(self, other): @@ -295,11 +294,11 @@ class TagListEditor(QDialog, Ui_TagListEditor): ca = m.addAction(_('Delete')) ca.setIcon(QIcon(I('trash.png'))) ca.triggered.connect(self.delete_tags) - item_name = unicode_type(item.text()) + item_name = str(item.text()) ca = m.addAction(_('Search for {}').format(item_name)) ca.setIcon(QIcon(I('search.png'))) ca.triggered.connect(partial(self.set_search_text, item_name)) - item_name = unicode_type(item.text()) + item_name = str(item.text()) ca = m.addAction(_('Filter by {}').format(item_name)) ca.setIcon(QIcon(I('filter.png'))) ca.triggered.connect(partial(self.set_filter_text, item_name)) @@ -328,8 +327,8 @@ 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, - unicode_type(item.text()).replace(r'"', r'\"'))) + get_gui().search.set_search_string('{}:"={}"'.format(self.category, + str(item.text()).replace(r'"', r'\"'))) qv = get_quickview_action_plugin() if qv: @@ -343,7 +342,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): def copy_to_clipboard(self, item): cb = QApplication.clipboard() - cb.setText(unicode_type(item.text())) + cb.setText(str(item.text())) def paste_from_clipboard(self, item): cb = QApplication.clipboard() @@ -359,7 +358,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): # block signals to avoid the "edit one changes all" behavior self.table.blockSignals(True) for item in items: - item.setText(func(unicode_type(item.text()))) + item.setText(func(str(item.text()))) self.table.blockSignals(False) def swap_case(self, txt): @@ -371,7 +370,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): def do_search(self): self.not_found_label.setVisible(False) - find_text = unicode_type(self.search_box.currentText()) + find_text = str(self.search_box.currentText()) if not find_text: return for _ in range(0, self.table.rowCount()): @@ -398,7 +397,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): def fill_in_table(self, tags, tag_to_match, ttm_is_first_letter): data = self.get_book_ids(self.apply_vl_checkbox.isChecked()) self.all_tags = {} - filter_text = icu_lower(unicode_type(self.filter_box.text())) + filter_text = icu_lower(str(self.filter_box.text())) for k,v,count in data: if not filter_text or self.string_contains(filter_text, icu_lower(v)): self.all_tags[v] = {'key': k, 'count': count, 'cur_name': v, @@ -435,7 +434,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): item.setText(self.to_rename[_id]) else: item.setText(tag) - if self.is_enumerated and unicode_type(item.text()) not in self.enum_permitted_values: + if self.is_enumerated and str(item.text()) not in self.enum_permitted_values: item.setBackground(QColor('#FF2400')) item.setToolTip( '

    ' + @@ -540,7 +539,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): edited_item.setText(self.text_before_editing) self.table.blockSignals(False) return - new_text = unicode_type(edited_item.text()) + new_text = str(edited_item.text()) if self.is_enumerated and new_text not in self.enum_permitted_values: error_dialog(self, _('Item is not a permitted value'), '

    ' + _( "This column has a fixed set of permitted values. The entered " @@ -626,7 +625,7 @@ class TagListEditor(QDialog, Ui_TagListEditor): to_del.append(item) if to_del: - ct = ', '.join([unicode_type(item.text()) for item in to_del]) + ct = ', '.join([str(item.text()) for item in to_del]) if not confirm( '

    '+_('Are you sure you want to delete the following items?')+'
    '+ct, 'tag_list_editor_delete'): 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 38af32245c..a5237ddda7 100644 --- a/src/calibre/gui2/dialogs/template_dialog.py +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -6,7 +6,6 @@ __docformat__ = 'restructuredtext en' __license__ = 'GPL v3' import json, os, traceback -from polyglot.builtins import unicode_type from qt.core import (Qt, QDialog, QDialogButtonBox, QSyntaxHighlighter, QFont, QRegExp, QApplication, QTextCharFormat, QColor, QCursor, @@ -51,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() @@ -142,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 @@ -159,7 +158,7 @@ class TemplateHighlighter(QSyntaxHighlighter): i = regex.indexIn(text, i + length) if self.generate_paren_positions: - t = unicode_type(text) + t = str(text) i = 0 foundQuote = False while i < len(t): @@ -507,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): @@ -518,7 +517,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): ]) if filename: with open(filename, 'w') as f: - f.write(unicode_type(self.textbox.toPlainText())) + f.write(str(self.textbox.toPlainText())) def get_current_font(self): font_name = gprefs.get('gpm_template_editor_font', None) @@ -547,14 +546,14 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): self.font_box.setWritingSystem(QFontDatabase.Latin) self.font_box.setCurrentFont(font) self.font_box.setEditable(False) - gprefs['gpm_template_editor_font'] = unicode_type(font.family()) + gprefs['gpm_template_editor_font'] = str(font.family()) self.font_size_box.setValue(font.pointSize()) self.font_box.currentFontChanged.connect(self.font_changed) self.font_size_box.valueChanged.connect(self.font_size_changed) def font_changed(self, font): fi = QFontInfo(font) - gprefs['gpm_template_editor_font'] = unicode_type(fi.family()) + gprefs['gpm_template_editor_font'] = str(fi.family()) self.set_editor_font() def font_size_changed(self, toWhat): @@ -570,10 +569,10 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): self.breakpoint_line_box.setEnabled(new_state != 0) self.breakpoint_line_box_label.setEnabled(new_state != 0) if new_state == 0: - self.display_values(unicode_type(self.textbox.toPlainText())) + self.display_values(str(self.textbox.toPlainText())) def go_button_pressed(self): - self.display_values(unicode_type(self.textbox.toPlainText())) + self.display_values(str(self.textbox.toPlainText())) def remove_all_button_pressed(self): self.textbox.set_clicked_line_numbers(set()) @@ -646,15 +645,15 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): def color_to_clipboard(self): app = QApplication.instance() c = app.clipboard() - c.setText(unicode_type(self.color_name.color)) + c.setText(str(self.color_name.color)) def icon_to_clipboard(self): app = QApplication.instance() c = app.clipboard() - c.setText(unicode_type(self.icon_files.currentText())) + c.setText(str(self.icon_files.currentText())) def textbox_changed(self): - cur_text = unicode_type(self.textbox.toPlainText()) + cur_text = str(self.textbox.toPlainText()) if self.last_text != cur_text: self.last_text = cur_text self.highlighter.regenerate_paren_positions() @@ -681,7 +680,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): def text_cursor_changed(self): cursor = self.textbox.textCursor() position = cursor.position() - t = unicode_type(self.textbox.toPlainText()) + t = str(self.textbox.toPlainText()) if position > 0 and position <= len(t): block_number = cursor.blockNumber() pos_in_block = cursor.positionInBlock() - 1 @@ -699,7 +698,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): return (_('Stored user defined template') if longform else _('Stored template')) def function_changed(self, toWhat): - name = unicode_type(self.function.itemData(toWhat)) + name = str(self.function.itemData(toWhat)) self.source_code.clear() self.documentation.clear() self.func_type.clear() @@ -721,7 +720,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): gprefs['template_editor_dialog_geometry'] = bytearray(self.saveGeometry()) def accept(self): - txt = unicode_type(self.textbox.toPlainText()).rstrip() + txt = str(self.textbox.toPlainText()).rstrip() if (self.coloring or self.iconing or self.embleming) and not txt: error_dialog(self, _('No template provided'), _('The template box cannot be empty'), show=True) @@ -731,16 +730,16 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): error_dialog(self, _('No column chosen'), _('You must specify a column to be colored'), show=True) return - self.rule = (unicode_type(self.colored_field.itemData( + self.rule = (str(self.colored_field.itemData( self.colored_field.currentIndex()) or ''), txt) elif self.iconing: if self.icon_field.currentIndex() == -1: error_dialog(self, _('No column chosen'), _('You must specify the column where the icons are applied'), show=True) return - rt = unicode_type(self.icon_kind.itemData(self.icon_kind.currentIndex()) or '') + rt = str(self.icon_kind.itemData(self.icon_kind.currentIndex()) or '') self.rule = (rt, - unicode_type(self.icon_field.itemData( + str(self.icon_field.itemData( self.icon_field.currentIndex()) or ''), txt) elif self.embleming: diff --git a/src/calibre/gui2/dialogs/template_dialog_code_widget.py b/src/calibre/gui2/dialogs/template_dialog_code_widget.py index f5ea1b225f..407857ba65 100644 --- a/src/calibre/gui2/dialogs/template_dialog_code_widget.py +++ b/src/calibre/gui2/dialogs/template_dialog_code_widget.py @@ -14,7 +14,6 @@ from qt.core import ( from calibre.gui2.tweak_book.editor.text import LineNumbers from calibre.gui2.tweak_book.editor.themes import get_theme, theme_color -from polyglot.builtins import unicode_type class LineNumberArea(LineNumbers): @@ -63,7 +62,7 @@ class CodeEditor(QPlainTextEdit): def line_number_area_width(self): # get largest width of digits w = self.fontMetrics() - self.number_width = max(map(lambda x:w.width(unicode_type(x)), range(10))) + self.number_width = max(map(lambda x:w.width(str(x)), range(10))) digits = 1 limit = max(1, self.blockCount()) while limit >= 10: @@ -131,7 +130,7 @@ class CodeEditor(QPlainTextEdit): else: painter.setFont(self.font()) painter.drawText(0, top, self.line_number_area.width() - 5, self.fontMetrics().height(), - Qt.AlignmentFlag.AlignRight, unicode_type(num + 1)) + Qt.AlignmentFlag.AlignRight, str(num + 1)) painter.restore() block = block.next() top = bottom diff --git a/src/calibre/gui2/dnd.py b/src/calibre/gui2/dnd.py index 56efc683bf..4c1f2fa746 100644 --- a/src/calibre/gui2/dnd.py +++ b/src/calibre/gui2/dnd.py @@ -22,7 +22,6 @@ from calibre.gui2 import error_dialog from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.filenames import make_long_path_useable from calibre.utils.imghdr import what -from polyglot.builtins import unicode_type from polyglot.queue import Empty, Queue from polyglot.urllib import unquote, urlparse @@ -198,7 +197,7 @@ def dnd_has_extension(md, extensions, allow_all_extensions=False, allow_remote=F if DEBUG: prints('\nDebugging DND event') for f in md.formats(): - f = unicode_type(f) + f = str(f) raw = data_as_string(f, md) prints(f, len(raw), repr(raw[:300]), '\n') print() @@ -221,7 +220,7 @@ def dnd_has_extension(md, extensions, allow_all_extensions=False, allow_remote=F def dnd_get_local_image_and_pixmap(md, image_exts=None): if md.hasImage(): for x in md.formats(): - x = unicode_type(x) + x = str(x) if x.startswith('image/'): cdata = bytes(md.data(x)) pmap = QPixmap() @@ -347,7 +346,7 @@ def _get_firefox_pair(md, exts, url, fname): def get_firefox_rurl(md, exts): - formats = frozenset([unicode_type(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 b6b8f20668..bf3d910d96 100644 --- a/src/calibre/gui2/email.py +++ b/src/calibre/gui2/email.py @@ -26,7 +26,7 @@ from calibre.library.save_to_disk import get_components from calibre.utils.config import tweaks, prefs from calibre.utils.icu import primary_sort_key from calibre.gui2.threaded_jobs import ThreadedJob -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues from polyglot.binary import from_hex_unicode @@ -210,7 +210,7 @@ class SelectRecipients(QDialog): # {{{ for i, name in enumerate(('address', 'alias', 'formats', 'subject')): c = i % 2 row = l.rowCount() - c - self.labels[i].setText(unicode_type(self.labels[i].text()) + ':') + self.labels[i].setText(str(self.labels[i].text()) + ':') l.addWidget(self.labels[i], row, (2*c)) le = QLineEdit(self) le.setToolTip(tooltips[i]) @@ -232,11 +232,11 @@ class SelectRecipients(QDialog): # {{{ self.init_list() def add_recipient(self): - to = unicode_type(self.address.text()).strip() + to = str(self.address.text()).strip() if not to: return error_dialog( self, _('Need address'), _('You must specify an address'), show=True) - formats = ','.join([x.strip().upper() for x in unicode_type(self.formats.text()).strip().split(',') if x.strip()]) + formats = ','.join([x.strip().upper() for x in str(self.formats.text()).strip().split(',') if x.strip()]) if not formats: return error_dialog( self, _('Need formats'), _('You must specify at least one format to send'), show=True) @@ -248,11 +248,11 @@ class SelectRecipients(QDialog): # {{{ acc[to] = [formats, False, False] c = email_config() c.set('accounts', acc) - alias = unicode_type(self.alias.text()).strip() + alias = str(self.alias.text()).strip() if alias: opts.aliases[to] = alias c.set('aliases', opts.aliases) - subject = unicode_type(self.subject.text()).strip() + subject = str(self.subject.text()).strip() if subject: opts.subjects[to] = subject c.set('subjects', opts.subjects) @@ -287,7 +287,7 @@ class SelectRecipients(QDialog): # {{{ ans = [] for i in self.items: if i.checkState() == Qt.CheckState.Checked: - to = unicode_type(i.data(Qt.ItemDataRole.UserRole) or '') + to = str(i.data(Qt.ItemDataRole.UserRole) or '') fmts = tuple(x.strip().upper() for x in (opts.accounts[to][0] or '').split(',')) subject = opts.subjects.get(to, '') ans.append((to, fmts, subject)) @@ -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 @@ -408,7 +408,7 @@ class EmailMixin: # {{{ from calibre.utils.html2text import html2text texts[-1] += '\n\n' + _('About this book:') + '\n\n' + textwrap.fill(html2text(mi.comments)) prefix = f'{t} - {a}' - if not isinstance(prefix, unicode_type): + if not isinstance(prefix, str): prefix = prefix.decode(preferred_encoding, 'replace') attachment_names.append(prefix + os.path.splitext(f)[1]) remove = remove_ids if delete_from_library else [] diff --git a/src/calibre/gui2/font_family_chooser.py b/src/calibre/gui2/font_family_chooser.py index 9b2b00fdf1..338612a594 100644 --- a/src/calibre/gui2/font_family_chooser.py +++ b/src/calibre/gui2/font_family_chooser.py @@ -16,7 +16,6 @@ from qt.core import (QFontInfo, QFontMetrics, Qt, QFont, QFontDatabase, QPen, from calibre.constants import config_dir from calibre.gui2 import choose_files, error_dialog, info_dialog, empty_index -from polyglot.builtins import unicode_type, range def add_fonts(parent): @@ -112,7 +111,7 @@ class FontFamilyDelegate(QStyledItemDelegate): painter.restore() def do_paint(self, painter, option, index): - text = unicode_type(index.data(Qt.ItemDataRole.DisplayRole) or '') + text = str(index.data(Qt.ItemDataRole.DisplayRole) or '') font = QFont(option.font) font.setPointSize(QFontInfo(font).pointSize() * 1.5) font2 = QFont(font) @@ -264,7 +263,7 @@ class FontFamilyDialog(QDialog): i = self.view.currentIndex().row() if i < 0: i = 0 - q = icu_lower(unicode_type(self.search.text())).strip() + q = icu_lower(str(self.search.text())).strip() if not q: return r = (range(i-1, -1, -1) if backwards else range(i+1, diff --git a/src/calibre/gui2/icon_theme.py b/src/calibre/gui2/icon_theme.py index 1d2a9ed299..a8201d9c4b 100644 --- a/src/calibre/gui2/icon_theme.py +++ b/src/calibre/gui2/icon_theme.py @@ -33,7 +33,7 @@ from calibre.utils.icu import numeric_sort_key as sort_key from calibre.utils.img import image_from_data, Canvas, optimize_png, optimize_jpeg from calibre.utils.zipfile import ZipFile, ZIP_STORED from calibre.utils.filenames import atomic_rename -from polyglot.builtins import iteritems, map, range, reraise, filter, as_bytes, unicode_type +from polyglot.builtins import iteritems, reraise, as_bytes from polyglot import http_client from polyglot.queue import Queue, Empty @@ -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'' @@ -619,7 +619,7 @@ class ChooseTheme(Dialog): w.l = l = QGridLayout(w) def add_row(x, y=None): - if isinstance(x, unicode_type): + if isinstance(x, str): x = QLabel(x) row = l.rowCount() if y is None: @@ -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 9d2f11a606..ec78866a13 100644 --- a/src/calibre/gui2/image_popup.py +++ b/src/calibre/gui2/image_popup.py @@ -16,7 +16,6 @@ from calibre import fit_image from calibre.gui2 import ( NO_URL_FORMATTING, choose_save_file, gprefs, max_available_height ) -from polyglot.builtins import unicode_type def render_svg(widget, path): @@ -222,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() @@ -248,7 +247,7 @@ class ImageView(QDialog): if geom is not None: QApplication.instance().safe_restore_geometry(self, geom) try: - self.current_image_name = unicode_type(self.current_url.toString(NO_URL_FORMATTING)).rpartition('/')[-1] + self.current_image_name = str(self.current_url.toString(NO_URL_FORMATTING)).rpartition('/')[-1] except AttributeError: self.current_image_name = self.current_url reso = '' diff --git a/src/calibre/gui2/init.py b/src/calibre/gui2/init.py index 6de1bb2dc7..8f1789d223 100644 --- a/src/calibre/gui2/init.py +++ b/src/calibre/gui2/init.py @@ -28,7 +28,6 @@ from calibre.gui2.widgets import LayoutButton, Splitter from calibre.utils.config import prefs from calibre.utils.icu import sort_key from calibre.utils.localization import localize_website_link -from polyglot.builtins import unicode_type _keep_refs = [] @@ -338,7 +337,7 @@ class GridViewButton(LayoutButton): # {{{ self.set_state_to_show() self.action_toggle = QAction(self.icon(), _('Toggle') + ' ' + self.label, self) gui.addAction(self.action_toggle) - gui.keyboard.register_shortcut('grid view toggle' + self.label, unicode_type(self.action_toggle.text()), + gui.keyboard.register_shortcut('grid view toggle' + self.label, str(self.action_toggle.text()), default_keys=(sc,), action=self.action_toggle) self.action_toggle.triggered.connect(self.toggle) self.action_toggle.changed.connect(self.update_shortcut) @@ -368,7 +367,7 @@ class SearchBarButton(LayoutButton): # {{{ self.set_state_to_hide() self.action_toggle = QAction(self.icon(), _('Toggle') + ' ' + self.label, self) gui.addAction(self.action_toggle) - gui.keyboard.register_shortcut('search bar toggle' + self.label, unicode_type(self.action_toggle.text()), + gui.keyboard.register_shortcut('search bar toggle' + self.label, str(self.action_toggle.text()), default_keys=(sc,), action=self.action_toggle) self.action_toggle.triggered.connect(self.toggle) self.action_toggle.changed.connect(self.update_shortcut) @@ -453,14 +452,14 @@ class VLTabs(QTabBar): # {{{ def tab_changed(self, idx): if self.ignore_tab_changed: return - vl = unicode_type(self.tabData(idx) or '').strip() or None + vl = str(self.tabData(idx) or '').strip() or None self.gui.apply_virtual_library(vl, update_tabs=False) def tab_moved(self, from_, to): - self.current_db.new_api.set_pref('virt_libs_order', [unicode_type(self.tabData(i) or '') for i in range(self.count())]) + self.current_db.new_api.set_pref('virt_libs_order', [str(self.tabData(i) or '') for i in range(self.count())]) def tab_close(self, index): - vl = unicode_type(self.tabData(index) or '') + vl = str(self.tabData(index) or '') if vl: # Dont allow closing the All Books tab self.current_db.new_api.set_pref('virt_libs_hidden', list( self.current_db.new_api.pref('virt_libs_hidden', ())) + [vl]) @@ -536,7 +535,7 @@ class VLTabs(QTabBar): # {{{ m.addAction(_('Unlock Virtual library tabs'), self.unlock_tab) i = self.tabAt(ev.pos()) if i > -1: - vl = unicode_type(self.tabData(i) or '') + vl = str(self.tabData(i) or '') if vl: m.addSeparator() m.addAction(_('Edit "%s"') % vl, partial(self.gui.do_create_edit, name=vl)) @@ -600,7 +599,7 @@ class LayoutMixin: # {{{ self.qv = self.qv.actual_plugin_ self.status_bar = StatusBar(self) - stylename = unicode_type(self.style().objectName()) + stylename = str(self.style().objectName()) self.grid_view_button = GridViewButton(self) self.search_bar_button = SearchBarButton(self) self.grid_view_button.toggled.connect(self.toggle_grid_view) diff --git a/src/calibre/gui2/job_indicator.py b/src/calibre/gui2/job_indicator.py index 6152b36d9a..c311125802 100644 --- a/src/calibre/gui2/job_indicator.py +++ b/src/calibre/gui2/job_indicator.py @@ -12,7 +12,6 @@ from qt.core import ( ) from calibre.gui2 import config -from polyglot.builtins import range class Pointer(QWidget): diff --git a/src/calibre/gui2/jobs.py b/src/calibre/gui2/jobs.py index c9f4766888..bcf8a1c093 100644 --- a/src/calibre/gui2/jobs.py +++ b/src/calibre/gui2/jobs.py @@ -31,7 +31,6 @@ from calibre.gui2.threaded_jobs import ThreadedJobServer, ThreadedJob from calibre.gui2.widgets2 import Dialog from calibre.utils.search_query_parser import SearchQueryParser, ParseException from calibre.utils.icu import lower -from polyglot.builtins import range from polyglot.queue import Empty, Queue diff --git a/src/calibre/gui2/keyboard.py b/src/calibre/gui2/keyboard.py index 34b6913b9a..27643cc25a 100644 --- a/src/calibre/gui2/keyboard.py +++ b/src/calibre/gui2/keyboard.py @@ -21,7 +21,7 @@ from calibre.utils.icu import sort_key, lower from calibre.gui2 import error_dialog, info_dialog from calibre.utils.search_query_parser import SearchQueryParser, ParseException from calibre.gui2.search_box import SearchBox2 -from polyglot.builtins import iteritems, itervalues, unicode_type, range +from polyglot.builtins import iteritems, itervalues ROOT = QModelIndex() @@ -66,7 +66,7 @@ def finalize(shortcuts, custom_keys_map={}): # {{{ keys = [] for x in candidates: ks = QKeySequence(x, QKeySequence.SequenceFormat.PortableText) - x = unicode_type(ks.toString(QKeySequence.SequenceFormat.PortableText)) + x = str(ks.toString(QKeySequence.SequenceFormat.PortableText)) if x in seen: if DEBUG: prints('Key %r for shortcut %s is already used by' @@ -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() @@ -299,7 +297,7 @@ class ConfigModel(SearchQueryParser, QAbstractItemModel): if sc['persist_shortcut']: options_map[un] = options_map.get(un, {}) options_map[un]['persist_shortcut'] = sc['persist_shortcut'] - keys = [unicode_type(k.toString(QKeySequence.SequenceFormat.PortableText)) for k in sc['keys']] + keys = [str(k.toString(QKeySequence.SequenceFormat.PortableText)) for k in sc['keys']] kmap[un] = keys with self.keyboard.config: self.keyboard.config['map'] = kmap @@ -447,11 +445,11 @@ class Editor(QFrame): # {{{ self.default_keys = [QKeySequence(k, QKeySequence.SequenceFormat.PortableText) for k in shortcut['default_keys']] self.current_keys = list(shortcut['keys']) - default = ', '.join([unicode_type(k.toString(QKeySequence.SequenceFormat.NativeText)) for k in + default = ', '.join([str(k.toString(QKeySequence.SequenceFormat.NativeText)) for k in self.default_keys]) if not default: default = _('None') - current = ', '.join([unicode_type(k.toString(QKeySequence.SequenceFormat.NativeText)) for k in + current = ', '.join([str(k.toString(QKeySequence.SequenceFormat.NativeText)) for k in self.current_keys]) if not current: current = _('None') @@ -509,7 +507,7 @@ class Editor(QFrame): # {{{ dup_desc = self.dup_check(sequence) if dup_desc is not None: error_dialog(self, _('Already assigned'), - unicode_type(sequence.toString(QKeySequence.SequenceFormat.NativeText)) + ' ' + _( + str(sequence.toString(QKeySequence.SequenceFormat.NativeText)) + ' ' + _( 'already assigned to') + ' ' + dup_desc, show=True) self.clear_clicked(which=which) @@ -528,7 +526,7 @@ class Editor(QFrame): # {{{ ans = [] for which in (1, 2): button = getattr(self, 'button%d'%which) - t = unicode_type(button.text()) + t = str(button.text()) if t == _('None'): continue ks = QKeySequence(t, QKeySequence.SequenceFormat.NativeText) @@ -555,7 +553,7 @@ class Delegate(QStyledItemDelegate): # {{{ elif data.is_shortcut: shortcut = data.data # Shortcut - keys = [unicode_type(k.toString(QKeySequence.SequenceFormat.NativeText)) for k in shortcut['keys']] + keys = [str(k.toString(QKeySequence.SequenceFormat.NativeText)) for k in shortcut['keys']] if not keys: keys = _('None') else: @@ -733,7 +731,7 @@ class ShortcutConfig(QWidget): # {{{ if not idx.isValid(): idx = self._model.index(0, 0) idx = self._model.find_next(idx, - unicode_type(self.search.currentText())) + str(self.search.currentText())) self.highlight_index(idx) def find_previous(self, *args): @@ -741,7 +739,7 @@ class ShortcutConfig(QWidget): # {{{ if not idx.isValid(): idx = self._model.index(0, 0) idx = self._model.find_next(idx, - unicode_type(self.search.currentText()), backwards=True) + str(self.search.currentText()), backwards=True) self.highlight_index(idx) def highlight_group(self, group_name): diff --git a/src/calibre/gui2/languages.py b/src/calibre/gui2/languages.py index 9a878b4149..e79e4fab66 100644 --- a/src/calibre/gui2/languages.py +++ b/src/calibre/gui2/languages.py @@ -11,7 +11,7 @@ from calibre.gui2 import gui_prefs from calibre.gui2.complete2 import EditWithComplete from calibre.utils.localization import lang_map_for_ui from calibre.utils.icu import sort_key, lower -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues class LanguagesEdit(EditWithComplete): @@ -54,7 +54,7 @@ class LanguagesEdit(EditWithComplete): @property def vals(self): - raw = unicode_type(self.lineEdit().text()) + raw = str(self.lineEdit().text()) for k, v in iteritems(self.comma_map): raw = raw.replace(k, v) parts = [x.strip() for x in raw.split(',')] diff --git a/src/calibre/gui2/layout.py b/src/calibre/gui2/layout.py index fdcea95bcc..9f08dba1c1 100644 --- a/src/calibre/gui2/layout.py +++ b/src/calibre/gui2/layout.py @@ -18,7 +18,6 @@ from calibre.gui2.bars import BarsManager from calibre.gui2.search_box import SavedSearchBox, SearchBox2 from calibre.gui2.widgets2 import RightClickButton from calibre.utils.config_base import tweaks -from polyglot.builtins import unicode_type class LocationManager(QObject): # {{{ @@ -129,7 +128,7 @@ class LocationManager(QObject): # {{{ had_device = self.has_device if cp is None: cp = (None, None) - if isinstance(cp, (bytes, unicode_type)): + if isinstance(cp, (bytes, str)): cp = (cp, None) if len(fs) < 3: fs = list(fs) + [0] diff --git a/src/calibre/gui2/library/alternate_views.py b/src/calibre/gui2/library/alternate_views.py index 757fd92e61..575fec0261 100644 --- a/src/calibre/gui2/library/alternate_views.py +++ b/src/calibre/gui2/library/alternate_views.py @@ -31,7 +31,7 @@ from calibre.gui2.library.caches import CoverCache, ThumbnailCache from calibre.gui2.pin_columns import PinContainer from calibre.utils import join_with_timeout from calibre.utils.config import prefs, tweaks -from polyglot.builtins import itervalues, range, unicode_type +from polyglot.builtins import itervalues from polyglot.queue import LifoQueue CM_TO_INCH = 0.393701 @@ -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) @@ -470,7 +470,7 @@ class CoverDelegate(QStyledItemDelegate): if fm and fm['datatype'] == 'rating': ans = rating_to_stars(val, fm['display'].get('allow_half_stars', False)) is_stars = True - return ('' if ans is None else unicode_type(ans)), is_stars + return ('' if ans is None else str(ans)), is_stars except Exception: if DEBUG: import traceback @@ -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/delegates.py b/src/calibre/gui2/library/delegates.py index 2d30b4c5b8..f4db5a37cf 100644 --- a/src/calibre/gui2/library/delegates.py +++ b/src/calibre/gui2/library/delegates.py @@ -27,7 +27,6 @@ from calibre.gui2.dialogs.comments_dialog import CommentsDialog, PlainTextDialog from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.gui2.languages import LanguagesEdit -from polyglot.builtins import unicode_type class UpdateEditorGeometry: @@ -169,7 +168,7 @@ def get_val_for_textlike_columns(index_): ct = '' else: ct = index_.data(Qt.ItemDataRole.DisplayRole) or '' - return unicode_type(ct) + return str(ct) # }}} @@ -610,7 +609,7 @@ class CcEnumDelegate(QStyledItemDelegate, UpdateEditorGeometry): # {{{ return editor def setModelData(self, editor, model, index): - val = unicode_type(editor.currentText()) + val = str(editor.currentText()) if not val: val = None model.setData(index, (val), Qt.ItemDataRole.EditRole) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index 92d07c7921..18c6d81719 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -41,9 +41,7 @@ from calibre.utils.date import ( from calibre.utils.icu import sort_key from calibre.utils.localization import calibre_langcode_to_name from calibre.utils.search_query_parser import ParseException, SearchQueryParser -from polyglot.builtins import ( - iteritems, itervalues, map, range, string_or_bytes, unicode_type -) +from polyglot.builtins import iteritems, itervalues, string_or_bytes Counts = namedtuple('Counts', 'library_total total current') @@ -78,7 +76,7 @@ class ColumnColor: # {{{ self.formatter = formatter def __call__(self, id_, key, fmt, db, color_cache, template_cache): - key += unicode_type(hash(fmt)) + key += str(hash(fmt)) if id_ in color_cache and key in color_cache[id_]: self.mi = None color = color_cache[id_][key] @@ -119,7 +117,7 @@ class ColumnIcon: # {{{ icons = [] for dex, (kind, fmt) in enumerate(fmts): rule_icons = self.formatter.safe_format(fmt, self.mi, '', self.mi, - column_name=cache_index+unicode_type(dex), + column_name=cache_index+str(dex), template_cache=template_cache) if not rule_icons: continue @@ -892,7 +890,7 @@ class BooksModel(QAbstractTableModel): # {{{ def stars_tooltip(func, allow_half=True): def f(idx): ans = val = int(func(idx)) - ans = unicode_type(val // 2) + ans = str(val // 2) if allow_half and val % 2: ans += '.5' return _('%s stars') % ans @@ -957,7 +955,7 @@ class BooksModel(QAbstractTableModel): # {{{ cc = self.custom_columns[self.column_map[col]]['display'] colors = cc.get('enum_colors', []) values = cc.get('enum_values', []) - txt = unicode_type(index.data(Qt.ItemDataRole.DisplayRole) or '') + txt = str(index.data(Qt.ItemDataRole.DisplayRole) or '') if len(colors) > 0 and txt in values: try: color = QColor(colors[values.index(txt)]) @@ -1077,10 +1075,10 @@ class BooksModel(QAbstractTableModel): # {{{ label=self.db.field_metadata.key_to_label(colhead) s_index = None if typ in ('text', 'comments'): - val = unicode_type(value or '').strip() + val = str(value or '').strip() val = val if val else None elif typ == 'enumeration': - val = unicode_type(value or '').strip() + val = str(value or '').strip() if not val: val = None elif typ == 'bool': @@ -1091,7 +1089,7 @@ class BooksModel(QAbstractTableModel): # {{{ if value == 0: val = '0' else: - val = unicode_type(value or '').strip() + val = str(value or '').strip() if not val: val = None elif typ == 'datetime': @@ -1103,7 +1101,7 @@ class BooksModel(QAbstractTableModel): # {{{ return False val = qt_to_dt(val, as_utc=False) elif typ == 'series': - val = unicode_type(value or '').strip() + val = str(value or '').strip() if val: pat = re.compile(r'\[([.0-9]+)\]') match = pat.search(val) @@ -1117,7 +1115,7 @@ class BooksModel(QAbstractTableModel): # {{{ s_index = self.db.get_next_cc_series_num_for(val, label=label, num=None) elif typ == 'composite': - tmpl = unicode_type(value or '').strip() + tmpl = str(value or '').strip() disp = cc['display'] disp['composite_template'] = tmpl self.db.set_custom_column_metadata(cc['colnum'], display=disp, @@ -1141,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) @@ -1173,7 +1171,7 @@ class BooksModel(QAbstractTableModel): # {{{ return False val = (int(value) if column == 'rating' else value if column in ('timestamp', 'pubdate') - else re.sub(r'\s', ' ', unicode_type(value or '').strip())) + else re.sub(r'\s', ' ', str(value or '').strip())) id = self.db.id(row) books_to_refresh = {id} if column == 'rating': @@ -1741,7 +1739,7 @@ class DeviceBooksModel(BooksModel): # {{{ cname = self.column_map[col] if cname in ('size', 'timestamp', 'inlibrary'): return False - val = unicode_type(value or '').strip() + val = str(value or '').strip() idx = self.map[row] if cname == 'collections': tags = [i.strip() for i in val.split(',')] diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py index 84af133d67..79c4969d1e 100644 --- a/src/calibre/gui2/library/views.py +++ b/src/calibre/gui2/library/views.py @@ -30,7 +30,7 @@ from calibre.gui2.library import DEFAULT_SORT from calibre.constants import filesystem_encoding from calibre import force_unicode from calibre.utils.icu import primary_sort_key -from polyglot.builtins import iteritems, map, range, unicode_type +from polyglot.builtins import iteritems def restrict_column_width(self, col, old_size, new_size): @@ -74,7 +74,7 @@ class HeaderView(QHeaderView): # {{{ opt.orientation = self.orientation() opt.fontMetrics = self.fm model = self.parent().model() - opt.text = unicode_type(model.headerData(logical_index, opt.orientation, Qt.ItemDataRole.DisplayRole) or '') + opt.text = str(model.headerData(logical_index, opt.orientation, Qt.ItemDataRole.DisplayRole) or '') if opt.orientation == Qt.Orientation.Vertical: try: val = model.headerData(logical_index, opt.orientation, Qt.ItemDataRole.DecorationRole) @@ -102,7 +102,7 @@ class HeaderView(QHeaderView): # {{{ opt.sortIndicator = QStyleOptionHeader.SortIndicator.SortDown if \ self.sortIndicatorOrder() == Qt.SortOrder.AscendingOrder else QStyleOptionHeader.SortIndicator.SortUp margin += style.pixelMetric(QStyle.PixelMetric.PM_HeaderMarkSize, None, self) - opt.text = unicode_type(model.headerData(logical_index, opt.orientation, Qt.ItemDataRole.DisplayRole) or '') + opt.text = str(model.headerData(logical_index, opt.orientation, Qt.ItemDataRole.DisplayRole) or '') if self.textElideMode() != Qt.TextElideMode.ElideNone: opt.text = opt.fontMetrics.elidedText(opt.text, Qt.TextElideMode.ElideRight, rect.width() - margin) if self.isEnabled(): @@ -480,7 +480,7 @@ class BooksView(QTableView): # {{{ ans.addSeparator() if hidden_cols: m = ans.addMenu(_('Show column')) - hcols = [(hcol, unicode_type(self.model().headerData(hidx, Qt.Orientation.Horizontal, Qt.ItemDataRole.DisplayRole) or '')) + hcols = [(hcol, str(self.model().headerData(hidx, Qt.Orientation.Horizontal, Qt.ItemDataRole.DisplayRole) or '')) for hcol, hidx in iteritems(hidden_cols)] hcols.sort(key=lambda x: primary_sort_key(x[1])) for hcol, hname in hcols: @@ -516,7 +516,7 @@ class BooksView(QTableView): # {{{ col = None if idx > -1 and idx < len(self.column_map): col = self.column_map[idx] - name = unicode_type(self.model().headerData(idx, Qt.Orientation.Horizontal, Qt.ItemDataRole.DisplayRole) or '') + name = str(self.model().headerData(idx, Qt.Orientation.Horizontal, Qt.ItemDataRole.DisplayRole) or '') view.column_header_context_menu = self.create_context_menu(col, name, view) has_context_menu = hasattr(view, 'column_header_context_menu') if self.is_library_view and has_context_menu: @@ -674,7 +674,7 @@ class BooksView(QTableView): # {{{ def write_state(self, state): db = getattr(self.model(), 'db', None) - name = unicode_type(self.objectName()) + name = str(self.objectName()) if name and db is not None: db.new_api.set_pref(name + ' books view state', state) @@ -789,7 +789,7 @@ class BooksView(QTableView): # {{{ def get_old_state(self): ans = None - name = unicode_type(self.objectName()) + name = str(self.objectName()) if name: name += ' books view state' db = getattr(self.model(), 'db', None) @@ -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()): @@ -1428,14 +1428,14 @@ class DeviceBooksView(BooksView): # {{{ def get_old_state(self): ans = None - name = unicode_type(self.objectName()) + name = str(self.objectName()) if name: name += ' books view state' ans = gprefs.get(name, None) return ans def write_state(self, state): - name = unicode_type(self.objectName()) + name = str(self.objectName()) if name: gprefs.set(name + ' books view state', state) diff --git a/src/calibre/gui2/linux_file_dialogs.py b/src/calibre/gui2/linux_file_dialogs.py index e1dd5b71f6..5ac7c66213 100644 --- a/src/calibre/gui2/linux_file_dialogs.py +++ b/src/calibre/gui2/linux_file_dialogs.py @@ -14,7 +14,7 @@ from qt.core import QEventLoop from calibre import force_unicode from calibre.constants import DEBUG, filesystem_encoding, preferred_encoding from calibre.utils.config import dynamic -from polyglot.builtins import getenv, reraise, string_or_bytes, unicode_type +from polyglot.builtins import reraise, string_or_bytes def dialog_name(name, title): @@ -27,20 +27,20 @@ def get_winid(widget=None): def detect_desktop_environment(): - de = getenv('XDG_CURRENT_DESKTOP') + de = os.getenv('XDG_CURRENT_DESKTOP') if de: return de.upper().split(':', 1)[0] - if getenv('KDE_FULL_SESSION') == 'true': + if os.getenv('KDE_FULL_SESSION') == 'true': return 'KDE' - if getenv('GNOME_DESKTOP_SESSION_ID'): + if os.getenv('GNOME_DESKTOP_SESSION_ID'): return 'GNOME' - ds = getenv('DESKTOP_SESSION') + ds = os.getenv('DESKTOP_SESSION') if ds and ds.upper() in {'GNOME', 'XFCE'}: return ds.upper() def is_executable_present(name): - PATH = getenv('PATH') or '' + PATH = os.getenv('PATH') or '' for path in PATH.split(os.pathsep): if os.access(os.path.join(path, name), os.X_OK): return True @@ -82,7 +82,7 @@ def save_initial_dir(name, title, ans, no_save_dir, is_file=False): def encode_arg(title): - if isinstance(title, unicode_type): + if isinstance(title, str): try: title = title.encode(preferred_encoding) except UnicodeEncodeError: @@ -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 @@ -136,7 +136,7 @@ def kde_cmd(window, title, *rest): ans += ['--desktopfile', 'calibre-gui'] winid = get_winid(window) if winid is not None: - ans += ['--attach', unicode_type(int(winid))] + ans += ['--attach', str(int(winid))] return ans + list(rest) 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 749f35e1d9..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 ' @@ -12,7 +10,6 @@ from qt.core import ( from calibre.gui2.lrf_renderer.text import TextBlock, FontLoader, COLOR, PixmapItem from calibre.ebooks.lrf.objects import RuledLine as _RuledLine from calibre.ebooks.lrf.objects import Canvas as __Canvas -from polyglot.builtins import unicode_type class Color(QColor): @@ -418,7 +415,7 @@ class Document(QGraphicsScene): fdata = QByteArray(lrf.font_map[font].data) id = QFontDatabase.addApplicationFontFromData(fdata) if id != -1: - font_map[font] = [unicode_type(i) for i in QFontDatabase.applicationFontFamilies(id)][0] + font_map[font] = [str(i) for i in QFontDatabase.applicationFontFamilies(id)][0] if load_substitutions: base = P('fonts/liberation/*.ttf') 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 c9bcff1cea..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 ' @@ -11,7 +9,7 @@ from qt.core import ( from calibre.ebooks.lrf.fonts import LIBERATION_FONT_MAP from calibre.ebooks.hyphenate import hyphenate_word -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes WEIGHT_MAP = lambda wt : int((wt/10)-1) NULL = lambda a, b: a @@ -156,7 +154,7 @@ class ParSkip: self.height = parskip def __str__(self): - return 'Parskip: '+unicode_type(self.height) + return 'Parskip: '+str(self.height) class TextBlock: @@ -291,7 +289,7 @@ class TextBlock: self.current_style.linespace, self.opts.visual_debug) if self.height > self.max_y+10: - raise TextBlock.HeightExceeded(unicode_type(self.current_line)) + raise TextBlock.HeightExceeded(str(self.current_line)) self.lines.append(self.current_line) self.current_line = None @@ -321,13 +319,12 @@ class TextBlock: break def __iter__(self): - for line in self.lines: - yield line + yield from self.lines def __str__(self): s = '' for line in self: - s += unicode_type(line) + '\n' + s += str(line) + '\n' return s @@ -542,12 +539,12 @@ class Line(QGraphicsItem): while True: word = next(words) word.highlight = False - if tokens[0] in unicode_type(word.string).lower(): + if tokens[0] in str(word.string).lower(): matches.append(word) for c in range(1, len(tokens)): word = next(words) print(tokens[c], word.string) - if tokens[c] not in unicode_type(word.string): + if tokens[c] not in str(word.string): return None matches.append(word) for w in matches: @@ -570,11 +567,11 @@ class Line(QGraphicsItem): if isinstance(tok, numbers.Number): s += ' ' elif isinstance(tok, Word): - s += unicode_type(tok.string) + s += str(tok.string) return s def __str__(self): - return unicode_type(self).encode('utf-8') + return str(self).encode('utf-8') class Word: diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 3bf14b552e..45feca9b6a 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -27,7 +27,7 @@ from calibre.gui2.splash_screen import SplashScreen from calibre.utils.config import dynamic, prefs from calibre.utils.lock import SingleInstance from calibre.utils.monotonic import monotonic -from polyglot.builtins import as_bytes, environ_item, range, unicode_type +from polyglot.builtins import as_bytes, environ_item after_quit_actions = {'debug_on_restart': False, 'restart_after_quit': False, 'no_plugins_on_restart': False} if iswindows: @@ -141,7 +141,7 @@ def get_default_library_path(): fname = _('Calibre Library') if iswindows: fname = 'Calibre Library' - if isinstance(fname, unicode_type): + if isinstance(fname, str): try: fname.encode(filesystem_encoding) except Exception: @@ -170,7 +170,7 @@ def get_library_path(gui_runner): base = os.path.expanduser('~') if not base or not os.path.exists(base): from qt.core import QDir - base = unicode_type(QDir.homePath()).replace('/', os.sep) + base = str(QDir.homePath()).replace('/', os.sep) candidate = gui_runner.choose_dir(base) if not candidate: candidate = os.path.join(base, 'Calibre Library') @@ -562,6 +562,6 @@ if __name__ == '__main__': log = f.read().decode('utf-8', 'ignore') d = QErrorMessage() d.showMessage(('Error:%s
    Traceback:
    ' - '%sLog:
    %s')%(unicode_type(err), - unicode_type(tb).replace('\n', '
    '), + '%sLog:
    %s')%(str(err), + str(tb).replace('\n', '
    '), log.replace('\n', '
    '))) 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 83da23d1a0..54203f8204 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -50,7 +50,7 @@ from calibre.utils.date import ( ) from calibre.utils.filenames import make_long_path_useable from calibre.utils.icu import sort_key, strcmp -from polyglot.builtins import iteritems, range, unicode_type +from polyglot.builtins import iteritems def show_locked_file_error(parent, err): @@ -241,7 +241,7 @@ class TitleEdit(EnLineEdit, ToMetadataMixin): @property def current_val(self): - title = clean_text(unicode_type(self.text())) + title = clean_text(str(self.text())) if not title: title = self.get_default() return title.strip() @@ -434,7 +434,7 @@ class AuthorsEdit(EditWithComplete, ToMetadataMixin): @property def current_val(self): - au = clean_text(unicode_type(self.text())) + au = clean_text(str(self.text())) if not au: au = self.get_default() return string_to_authors(au) @@ -501,7 +501,7 @@ class AuthorSortEdit(EnLineEdit, ToMetadataMixin): @property def current_val(self): - return clean_text(unicode_type(self.text())) + return clean_text(str(self.text())) @current_val.setter def current_val(self, val): @@ -522,7 +522,7 @@ class AuthorSortEdit(EnLineEdit, ToMetadataMixin): return self.db.new_api.author_sort_from_authors(authors, key_func=lambda x: x) def update_state(self, *args): - au = unicode_type(self.authors_edit.text()) + au = str(self.authors_edit.text()) au = re.sub(r'\s+et al\.$', '', au) au = self.author_sort_from_authors(string_to_authors(au)) @@ -548,13 +548,13 @@ class AuthorSortEdit(EnLineEdit, ToMetadataMixin): self.authors_edit.set_value(ans) def auto_generate(self, *args): - au = unicode_type(self.authors_edit.text()) + au = str(self.authors_edit.text()) au = re.sub(r'\s+et al\.$', '', au).strip() authors = string_to_authors(au) self.set_value(self.author_sort_from_authors(authors)) def author_to_sort(self, *args): - au = unicode_type(self.authors_edit.text()) + au = str(self.authors_edit.text()) au = re.sub(r'\s+et al\.$', '', au).strip() if au: self.set_value(au) @@ -627,7 +627,7 @@ class SeriesEdit(EditWithComplete, ToMetadataMixin): @property def current_val(self): - return clean_text(unicode_type(self.currentText())) + return clean_text(str(self.currentText())) @current_val.setter def current_val(self, val): @@ -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,10 +1195,10 @@ 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 + "


    "+unicode_type(e)) + _("

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


    "+str(e)) d.exec_() if cover: orig = self.current_val @@ -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) @@ -1406,7 +1406,7 @@ class TagsEdit(EditWithComplete, ToMetadataMixin): # {{{ @property def current_val(self): - return [clean_text(x) for x in unicode_type(self.text()).split(',')] + return [clean_text(x) for x in str(self.text()).split(',')] @current_val.setter def current_val(self, val): @@ -1594,7 +1594,7 @@ class IdentifiersEdit(QLineEdit, ToMetadataMixin): @property def current_val(self): - raw = unicode_type(self.text()).strip() + raw = str(self.text()).strip() parts = [clean_text(x) for x in raw.split(',')] ans = {} for x in parts: @@ -1658,7 +1658,7 @@ class IdentifiersEdit(QLineEdit, ToMetadataMixin): identifier_found = self.parse_clipboard_for_identifier() if identifier_found: return - text = unicode_type(QApplication.clipboard().text()).strip() + text = str(QApplication.clipboard().text()).strip() if text.startswith('http://') or text.startswith('https://'): return self.paste_prefix('url') try: @@ -1671,14 +1671,14 @@ class IdentifiersEdit(QLineEdit, ToMetadataMixin): if prefix == 'isbn': self.paste_isbn() else: - text = unicode_type(QApplication.clipboard().text()).strip() + text = str(QApplication.clipboard().text()).strip() if text: vals = self.current_val vals[prefix] = text self.current_val = vals def paste_isbn(self): - text = unicode_type(QApplication.clipboard().text()).strip() + text = str(QApplication.clipboard().text()).strip() if not text or not check_isbn(text): d = ISBNDialog(self, text) if not d.exec_(): @@ -1698,7 +1698,7 @@ class IdentifiersEdit(QLineEdit, ToMetadataMixin): def parse_clipboard_for_identifier(self): from calibre.ebooks.metadata.sources.prefs import msprefs from calibre.utils.formatter import EvalFormatter - text = unicode_type(QApplication.clipboard().text()).strip() + text = str(QApplication.clipboard().text()).strip() if not text: return False @@ -1768,7 +1768,7 @@ class ISBNDialog(QDialog): # {{{ self.resize(sz) def accept(self): - isbn = unicode_type(self.line_edit.text()) + isbn = str(self.line_edit.text()) if not check_isbn(isbn): return error_dialog(self, _('Invalid ISBN'), _('The ISBN you entered is not valid. Try again.'), @@ -1776,7 +1776,7 @@ class ISBNDialog(QDialog): # {{{ QDialog.accept(self) def checkText(self, txt): - isbn = unicode_type(txt) + isbn = str(txt) if not isbn: sheet = '' extra = '' @@ -1790,7 +1790,7 @@ class ISBNDialog(QDialog): # {{{ self.line_edit.setStyleSheet(sheet) def text(self): - return check_isbn(unicode_type(self.line_edit.text())) + return check_isbn(str(self.line_edit.text())) # }}} @@ -1816,7 +1816,7 @@ class PublisherEdit(EditWithComplete, ToMetadataMixin): # {{{ @property def current_val(self): - return clean_text(unicode_type(self.currentText())) + return clean_text(str(self.currentText())) @current_val.setter def current_val(self, val): @@ -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 7e4cf35932..53a5f36b0d 100644 --- a/src/calibre/gui2/metadata/config.py +++ b/src/calibre/gui2/metadata/config.py @@ -15,7 +15,7 @@ from qt.core import ( from calibre.gui2.preferences.metadata_sources import FieldsModel as FM from calibre.utils.icu import sort_key -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class FieldsModel(FM): # {{{ @@ -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)) @@ -134,10 +134,10 @@ class ConfigWidget(QWidget): if isinstance(w, (QSpinBox, QDoubleSpinBox)): val = w.value() elif isinstance(w, QLineEdit): - val = unicode_type(w.text()) + val = str(w.text()) elif isinstance(w, QCheckBox): val = w.isChecked() elif isinstance(w, QComboBox): idx = w.currentIndex() - val = unicode_type(w.itemData(idx) or '') + val = str(w.itemData(idx) or '') self.plugin.prefs[w.opt.name] = val diff --git a/src/calibre/gui2/metadata/diff.py b/src/calibre/gui2/metadata/diff.py index 6a69337e6a..e819148813 100644 --- a/src/calibre/gui2/metadata/diff.py +++ b/src/calibre/gui2/metadata/diff.py @@ -27,7 +27,7 @@ from calibre.gui2.metadata.basic_widgets import PubdateEdit, RatingEdit from calibre.gui2.widgets2 import RightClickButton from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.date import UNDEFINED_DATE -from polyglot.builtins import iteritems, itervalues, map, range, unicode_type, zip +from polyglot.builtins import iteritems, itervalues Widgets = namedtuple('Widgets', 'new old label button') @@ -52,7 +52,7 @@ class LineEdit(EditWithComplete): @property def value(self): - val = unicode_type(self.text()).strip() + val = str(self.text()).strip() ism = self.metadata['is_multiple'] if ism: if not val: @@ -87,7 +87,7 @@ class LineEdit(EditWithComplete): @property def current_val(self): - return unicode_type(self.text()) + return str(self.text()) @current_val.setter def current_val(self, val): @@ -221,7 +221,7 @@ class SeriesEdit(LineEdit): self.setCursorPosition(0) def to_mi(self, mi): - val = unicode_type(self.text()).strip() + val = str(self.text()).strip() try: series_index = float(val.rpartition('[')[-1].rstrip(']').strip()) except: @@ -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 16d17e2782..93c875cb21 100644 --- a/src/calibre/gui2/metadata/pdf_covers.py +++ b/src/calibre/gui2/metadata/pdf_covers.py @@ -20,7 +20,6 @@ from calibre.ebooks.metadata.pdf import page_images from calibre.gui2 import error_dialog, file_icon_provider from calibre.ptempfile import PersistentTemporaryDirectory from calibre.gui2.progress_indicator import WaitLayout -from polyglot.builtins import unicode_type class CoverDelegate(QStyledItemDelegate): @@ -84,18 +83,18 @@ class PDFCovers(QDialog): @property def cover_path(self): for item in self.covers.selectedItems(): - return unicode_type(item.data(Qt.ItemDataRole.UserRole) or '') + return str(item.data(Qt.ItemDataRole.UserRole) or '') if self.covers.count() > 0: - return unicode_type(self.covers.item(0).data(Qt.ItemDataRole.UserRole) or '') + return str(self.covers.item(0).data(Qt.ItemDataRole.UserRole) or '') def cleanup(self): try: shutil.rmtree(self.tdir) - except EnvironmentError: + except OSError: pass def render(self): - self.current_tdir = os.path.join(self.tdir, unicode_type(self.first)) + self.current_tdir = os.path.join(self.tdir, str(self.first)) self.error = None try: os.mkdir(self.current_tdir) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 6d407bc512..c232a52598 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -34,7 +34,7 @@ from calibre.library.comments import merge_comments as merge_two_comments from calibre.utils.config import tweaks from calibre.utils.date import local_tz from calibre.utils.localization import canonicalize_lang -from polyglot.builtins import filter, iteritems, unicode_type +from polyglot.builtins import iteritems BASE_TITLE = _('Edit metadata') fetched_fields = ('title', 'title_sort', 'authors', 'author_sort', 'series', @@ -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]) @@ -317,7 +317,7 @@ class MetadataSingleDialogBase(QDialog): def edit_prefix_list(self): prefixes, ok = QInputDialog.getMultiLineText( self, _('Edit prefixes'), _('Enter prefixes, one on a line. The first prefix becomes the default.'), - '\n'.join(list(map(unicode_type, gprefs['paste_isbn_prefixes'])))) + '\n'.join(list(map(str, gprefs['paste_isbn_prefixes'])))) if ok: gprefs['paste_isbn_prefixes'] = list(filter(None, (x.strip() for x in prefixes.splitlines()))) or gprefs.defaults['paste_isbn_prefixes'] self.update_paste_identifiers_menu() @@ -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 dc8a082df5..00a4d54403 100644 --- a/src/calibre/gui2/metadata/single_download.py +++ b/src/calibre/gui2/metadata/single_download.py @@ -37,7 +37,7 @@ from calibre.library.comments import comments_to_html from calibre import force_unicode from calibre.utils.ipc.simple_worker import fork_job, WorkerError from calibre.ptempfile import TemporaryDirectory -from polyglot.builtins import iteritems, itervalues, unicode_type, range, getcwd +from polyglot.builtins import iteritems, itervalues from polyglot.queue import Queue, Empty # }}} @@ -144,7 +144,7 @@ class ResultsModel(QAbstractTableModel): # {{{ def data_as_text(self, book, col): if col == 0: - return unicode_type(book.gui_rank+1) + return str(book.gui_rank+1) if col == 1: t = book.title if book.title else _('Unknown') a = authors_to_string(book.authors) if book.authors else '' @@ -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 @@ -341,7 +341,7 @@ class Comments(HTMLDisplay): # {{{ if col.isValid(): col = col.toRgb() if col.isValid(): - ans = unicode_type(col.name()) + ans = str(col.name()) return ans c = color_to_string(QApplication.palette().color(QPalette.ColorGroup.Normal, @@ -408,7 +408,7 @@ class IdentifyWorker(Thread): # {{{ 'single_identify', (self.title, self.authors, self.identifiers), no_output=True, abort=self.abort) self.results, covers, caches, log_dump = res['result'] - self.results = [OPF(BytesIO(r), basedir=getcwd(), + self.results = [OPF(BytesIO(r), basedir=os.getcwd(), populate_spine=False).to_book_metadata() for r in self.results] for r, cov in zip(self.results, covers): r.has_cached_cover_url = cov @@ -492,7 +492,7 @@ class IdentifyWidget(QWidget): # {{{ if 'isbn' in identifiers: simple_desc += 'ISBN: %s' % identifiers['isbn'] self.query.setText(simple_desc) - self.log(unicode_type(self.query.text())) + self.log(str(self.query.text())) self.worker = IdentifyWorker(self.log, self.abort, title, authors, identifiers, self.caches) @@ -831,7 +831,7 @@ class CoversView(QListView): # {{{ pmap = self.model().cc if pmap is not None: from calibre.gui2.image_popup import ImageView - d = ImageView(self, pmap, unicode_type(idx.data(Qt.ItemDataRole.DisplayRole) or ''), geom_name='metadata_download_cover_popup_geom') + d = ImageView(self, pmap, str(idx.data(Qt.ItemDataRole.DisplayRole) or ''), geom_name='metadata_download_cover_popup_geom') d(use_exec=True) def copy_cover(self): diff --git a/src/calibre/gui2/notify.py b/src/calibre/gui2/notify.py index 85c5bcf760..17e11a19e2 100644 --- a/src/calibre/gui2/notify.py +++ b/src/calibre/gui2/notify.py @@ -12,7 +12,6 @@ from contextlib import suppress from functools import lru_cache from calibre.constants import DEBUG, __appname__, get_osx_version, islinux, ismacos -from polyglot.builtins import unicode_type class Notifier: @@ -164,7 +163,7 @@ class QtNotifier(Notifier): try: hide = False try: - if not isinstance(body, unicode_type): + if not isinstance(body, str): body = body.decode('utf-8') if ismacos and not self.systray.isVisible(): self.systray.show() diff --git a/src/calibre/gui2/open_with.py b/src/calibre/gui2/open_with.py index d2e9218442..eb026d00e3 100644 --- a/src/calibre/gui2/open_with.py +++ b/src/calibre/gui2/open_with.py @@ -26,7 +26,7 @@ from calibre.gui2.progress_indicator import ProgressIndicator from calibre.gui2.widgets2 import Dialog from calibre.utils.config import JSONConfig from calibre.utils.icu import numeric_sort_key as sort_key -from polyglot.builtins import iteritems, range, string_or_bytes, unicode_type +from polyglot.builtins import iteritems, string_or_bytes ENTRY_ROLE = Qt.ItemDataRole.UserRole @@ -362,7 +362,7 @@ def choose_program(file_type='jpeg', parent=None, prefs=oprefs): entry = choose_manually(file_type, parent) if d.select_manually else d.selected_entry if entry is not None: entry = finalize_entry(entry) - entry['uuid'] = unicode_type(uuid.uuid4()) + entry['uuid'] = str(uuid.uuid4()) entries = oprefs['entries'] if oft not in entries: entries[oft] = [] diff --git a/src/calibre/gui2/pin_columns.py b/src/calibre/gui2/pin_columns.py index 029bd46fc4..b19e034794 100644 --- a/src/calibre/gui2/pin_columns.py +++ b/src/calibre/gui2/pin_columns.py @@ -7,7 +7,6 @@ from qt.core import QSplitter, QTableView from calibre.gui2.library import DEFAULT_SORT from calibre.gui2 import gprefs -from polyglot.builtins import range class PinTableView(QTableView): diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index f9005d30a0..2e77dbd2ae 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -16,7 +16,7 @@ from calibre.customize.ui import preferences_plugins from calibre.utils.config import ConfigProxy from calibre.gui2.complete2 import EditWithComplete from calibre.gui2.widgets import HistoryLineEdit -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes class AbortCommit(Exception): @@ -128,15 +128,15 @@ class Setting: raise ValueError('Unknown data type %s' % self.gui_obj.__class__) if isinstance(self.config_obj, ConfigProxy) and \ - not unicode_type(self.gui_obj.toolTip()): + not str(self.gui_obj.toolTip()): h = self.config_obj.help(self.name) if h: self.gui_obj.setToolTip(h) - tt = unicode_type(self.gui_obj.toolTip()) + tt = str(self.gui_obj.toolTip()) if tt: - if not unicode_type(self.gui_obj.whatsThis()): + if not str(self.gui_obj.whatsThis()): self.gui_obj.setWhatsThis(tt) - if not unicode_type(self.gui_obj.statusTip()): + if not str(self.gui_obj.statusTip()): self.gui_obj.setStatusTip(tt) tt = '\n'.join(textwrap.wrap(tt, 70)) self.gui_obj.setToolTip(tt) @@ -204,17 +204,17 @@ class Setting: elif self.datatype == 'number': val = self.gui_obj.value() elif self.datatype == 'string': - val = unicode_type(self.gui_obj.text()).strip() + val = str(self.gui_obj.text()).strip() if self.empty_string_is_None and not val: val = None elif self.datatype == 'choice': if isinstance(self.gui_obj, EditWithComplete): - val = unicode_type(self.gui_obj.text()) + val = str(self.gui_obj.text()) else: idx = self.gui_obj.currentIndex() if idx < 0: idx = 0 - val = unicode_type(self.gui_obj.itemData(idx) or '') + val = str(self.gui_obj.itemData(idx) or '') return val @@ -227,7 +227,7 @@ class CommaSeparatedList(Setting): self.gui_obj.setText(x) def get_gui_val(self): - val = unicode_type(self.gui_obj.text()).strip() + val = str(self.gui_obj.text()).strip() ans = [] if val: ans = [x.strip() for x in val.split(',')] diff --git a/src/calibre/gui2/preferences/adding.py b/src/calibre/gui2/preferences/adding.py index 9d7b0e8253..c970630a73 100644 --- a/src/calibre/gui2/preferences/adding.py +++ b/src/calibre/gui2/preferences/adding.py @@ -17,7 +17,6 @@ from calibre.utils.config import prefs from calibre.gui2.widgets import FilenamePattern from calibre.gui2.auto_add import AUTO_ADDED from calibre.gui2 import gprefs, choose_dir, error_dialog, question_dialog -from polyglot.builtins import unicode_type class ConfigWidget(ConfigWidgetBase, Ui_Form): @@ -134,7 +133,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): viewer = self.opt_blocked_auto_formats for i in range(viewer.count()): if viewer.item(i).checkState() == Qt.CheckState.Checked: - fmts.append(unicode_type(viewer.item(i).text())) + fmts.append(str(viewer.item(i).text())) return fmts # }}} @@ -147,7 +146,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.add_filter_rules = [] def commit(self): - path = unicode_type(self.opt_auto_add_path.text()).strip() + path = str(self.opt_auto_add_path.text()).strip() if path != gprefs['auto_add_path']: if path: path = os.path.abspath(path) diff --git a/src/calibre/gui2/preferences/behavior.py b/src/calibre/gui2/preferences/behavior.py index 460d1daf94..2c3caf0d4c 100644 --- a/src/calibre/gui2/preferences/behavior.py +++ b/src/calibre/gui2/preferences/behavior.py @@ -21,7 +21,6 @@ from calibre.ebooks import BOOK_EXTENSIONS from calibre.ebooks.oeb.iterator import is_supported from calibre.constants import iswindows from calibre.utils.icu import sort_key -from polyglot.builtins import unicode_type, range def input_order_drop_event(self, ev): @@ -95,7 +94,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def commit(self): input_map = prefs['input_format_order'] - input_cols = [unicode_type(self.opt_input_order.item(i).data(Qt.ItemDataRole.UserRole) or '') for + input_cols = [str(self.opt_input_order.item(i).data(Qt.ItemDataRole.UserRole) or '') for i in range(self.opt_input_order.count())] if input_map != input_cols: prefs['input_format_order'] = input_cols @@ -143,7 +142,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): viewer = self.opt_internally_viewed_formats for i in range(viewer.count()): if viewer.item(i).checkState() == Qt.CheckState.Checked: - fmts.append(unicode_type(viewer.item(i).text())) + fmts.append(str(viewer.item(i).text())) return fmts # }}} diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py index 11905ae8c2..77c02be1af 100644 --- a/src/calibre/gui2/preferences/coloring.py +++ b/src/calibre/gui2/preferences/coloring.py @@ -34,7 +34,7 @@ from calibre.library.coloring import ( ) from calibre.utils.icu import lower, sort_key from calibre.utils.localization import lang_map -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems all_columns_string = _('All columns') @@ -172,12 +172,12 @@ class ConditionEditor(QWidget): # {{{ @property def current_col(self): idx = self.column_box.currentIndex() - return unicode_type(self.column_box.itemData(idx) or '') + return str(self.column_box.itemData(idx) or '') @current_col.setter def current_col(self, val): for idx in range(self.column_box.count()): - c = unicode_type(self.column_box.itemData(idx) or '') + c = str(self.column_box.itemData(idx) or '') if c == val: self.column_box.setCurrentIndex(idx) return @@ -186,12 +186,12 @@ class ConditionEditor(QWidget): # {{{ @property def current_action(self): idx = self.action_box.currentIndex() - return unicode_type(self.action_box.itemData(idx) or '') + return str(self.action_box.itemData(idx) or '') @current_action.setter def current_action(self, val): for idx in range(self.action_box.count()): - c = unicode_type(self.action_box.itemData(idx) or '') + c = str(self.action_box.itemData(idx) or '') if c == val: self.action_box.setCurrentIndex(idx) return @@ -199,7 +199,7 @@ class ConditionEditor(QWidget): # {{{ @property def current_val(self): - ans = unicode_type(self.value_box.text()).strip() + ans = str(self.value_box.text()).strip() if self.current_col == 'languages': rmap = {lower(v):k for k, v in iteritems(lang_map())} ans = rmap.get(lower(ans), ans) @@ -528,8 +528,8 @@ class RuleEditor(QDialog): # {{{ def update_color_label(self): pal = QApplication.palette() - bg1 = unicode_type(pal.color(QPalette.ColorRole.Base).name()) - bg2 = unicode_type(pal.color(QPalette.ColorRole.AlternateBase).name()) + bg1 = str(pal.color(QPalette.ColorRole.Base).name()) + bg2 = str(pal.color(QPalette.ColorRole.AlternateBase).name()) c = self.color_box.color self.color_label.setText('''  {st}  @@ -585,10 +585,10 @@ class RuleEditor(QDialog): # {{{ for i in range(1, model.rowCount()): item = model.item(i, 0) if item.checkState() == Qt.CheckState.Checked: - fnames.append(lower(unicode_type(item.text()))) + fnames.append(lower(str(item.text()))) fname = ' : '.join(fnames) else: - fname = lower(unicode_type(self.filename_box.currentText())) + fname = lower(str(self.filename_box.currentText())) return fname def update_icon_filenames_in_box(self): @@ -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() @@ -647,7 +647,7 @@ class RuleEditor(QDialog): # {{{ self.update_icon_filenames_in_box() for i in range(self.column_box.count()): - c = unicode_type(self.column_box.itemData(i) or '') + c = str(self.column_box.itemData(i) or '') if col == c: self.column_box.setCurrentIndex(i) break @@ -701,13 +701,13 @@ class RuleEditor(QDialog): # {{{ else: r.color = self.color_box.color idx = self.column_box.currentIndex() - col = unicode_type(self.column_box.itemData(idx) or '') + col = str(self.column_box.itemData(idx) or '') for c in self.conditions: condition = c.condition if condition is not None: r.add_condition(*condition) if self.rule_kind == 'icon': - kind = unicode_type(self.kind_box.itemData( + kind = str(self.kind_box.itemData( self.kind_box.currentIndex()) or '') else: kind = self.rule_kind diff --git a/src/calibre/gui2/preferences/columns.py b/src/calibre/gui2/preferences/columns.py index a90def0e62..11bcb52605 100644 --- a/src/calibre/gui2/preferences/columns.py +++ b/src/calibre/gui2/preferences/columns.py @@ -15,7 +15,6 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget from calibre.gui2.preferences.columns_ui import Ui_Form from calibre.gui2.preferences.create_custom_column import CreateCustomColumn from calibre.gui2 import error_dialog, question_dialog, ALL_COLUMNS -from polyglot.builtins import unicode_type, range, map class ConfigWidget(ConfigWidgetBase, Ui_Form): @@ -142,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) @@ -194,7 +193,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if idx < 0: return error_dialog(self, '', _('You must select a column to delete it'), show=True) - col = unicode_type(self.opt_columns.item(idx, 0).data(Qt.ItemDataRole.UserRole) or '') + col = str(self.opt_columns.item(idx, 0).data(Qt.ItemDataRole.UserRole) or '') if col not in self.custcols: return error_dialog(self, '', _('The selected column is not a custom column'), show=True) @@ -223,7 +222,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): model = self.gui.library_view.model() row = self.opt_columns.currentRow() try: - key = unicode_type(self.opt_columns.item(row, 0).data(Qt.ItemDataRole.UserRole)) + key = str(self.opt_columns.item(row, 0).data(Qt.ItemDataRole.UserRole)) except: key = '' CreateCustomColumn(self, row, key, model.orig_headers, ALL_COLUMNS) @@ -236,12 +235,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def apply_custom_column_changes(self): model = self.gui.library_view.model() db = model.db - config_cols = [unicode_type(self.opt_columns.item(i, 0).data(Qt.ItemDataRole.UserRole) or '') + config_cols = [str(self.opt_columns.item(i, 0).data(Qt.ItemDataRole.UserRole) or '') for i in range(self.opt_columns.rowCount())] if not config_cols: config_cols = ['title'] removed_cols = set(model.column_map) - set(config_cols) - hidden_cols = {unicode_type(self.opt_columns.item(i, 0).data(Qt.ItemDataRole.UserRole) or '') + hidden_cols = {str(self.opt_columns.item(i, 0).data(Qt.ItemDataRole.UserRole) or '') for i in range(self.opt_columns.rowCount()) if self.opt_columns.item(i, 0).checkState()==Qt.CheckState.Unchecked} hidden_cols = hidden_cols.union(removed_cols) # Hide removed cols @@ -252,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/conversion.py b/src/calibre/gui2/preferences/conversion.py index 10274cc4b7..3cb74cf380 100644 --- a/src/calibre/gui2/preferences/conversion.py +++ b/src/calibre/gui2/preferences/conversion.py @@ -23,7 +23,6 @@ from calibre.gui2.convert.structure_detection import StructureDetectionWidget from calibre.gui2.convert.toc import TOCWidget from calibre.customize.ui import input_format_plugins, output_format_plugins from calibre.gui2.convert import config_widget_for_input_plugin -from polyglot.builtins import unicode_type class Model(QStringListModel): @@ -93,7 +92,7 @@ class Base(ConfigWidgetBase): if rec.option == name: ans = getattr(rec, 'help', None) if ans is not None: - return ans.replace('%default', unicode_type(rec.recommended_value)) + return ans.replace('%default', str(rec.recommended_value)) return cls(self, self.plumber.get_option_by_name, hfunc, None, None) self.load_conversion_widgets() diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index 31502795be..cb30a17544 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -19,7 +19,7 @@ from qt.core import ( from calibre.gui2 import error_dialog from calibre.gui2.dialogs.template_line_editor import TemplateLineEditor from calibre.utils.date import parse_date, UNDEFINED_DATE -from polyglot.builtins import iteritems, unicode_type, range, map +from polyglot.builtins import iteritems class CreateCustomColumn(QDialog): @@ -185,11 +185,11 @@ class CreateCustomColumn(QDialog): self.default_value.setText(_('Now') if dv == 'now' else dv) elif ct == 'rating': if self.allow_half_stars.isChecked(): - self.default_value.setText(unicode_type(dv/2)) + self.default_value.setText(str(dv/2)) else: - self.default_value.setText(unicode_type(dv//2)) + self.default_value.setText(str(dv//2)) elif ct in ('int', 'float'): - self.default_value.setText(unicode_type(dv)) + self.default_value.setText(str(dv)) elif ct not in ('composite', '*composite'): self.default_value.setText(dv) @@ -200,12 +200,12 @@ class CreateCustomColumn(QDialog): self.is_names.setChecked(c['display'].get('is_names', False)) self.description_box.setText(c['display'].get('description', '')) - all_colors = [unicode_type(s) for s in list(QColor.colorNames())] + all_colors = [str(s) for s in list(QColor.colorNames())] self.enum_colors_label.setToolTip('

    ' + ', '.join(all_colors) + '

    ') self.exec_() def shortcut_activated(self, url): # {{{ - which = unicode_type(url).split(':')[-1] + which = str(url).split(':')[-1] self.column_type_box.setCurrentIndex({ 'yesno': self.column_types_map['bool'], 'tags' : self.column_types_map['*text'], @@ -489,7 +489,7 @@ class CreateCustomColumn(QDialog): self.allow_half_stars.setVisible(col_type == 'rating') def accept(self): - col = unicode_type(self.column_name_box.text()).strip() + col = str(self.column_name_box.text()).strip() if not col: return self.simple_error('', _('No lookup name was provided')) if col.startswith('#'): @@ -500,7 +500,7 @@ class CreateCustomColumn(QDialog): if col.endswith('_index'): return self.simple_error('', _('Lookup names cannot end with _index, ' 'because these names are reserved for the index of a series column.')) - col_heading = unicode_type(self.column_heading_box.text()).strip() + col_heading = str(self.column_heading_box.text()).strip() coldef = self.column_types[self.column_type_box.currentIndex()] col_type = coldef['datatype'] if col_type[0] == '*': @@ -535,12 +535,12 @@ class CreateCustomColumn(QDialog): display_dict = {} - default_val = (unicode_type(self.default_value.text()).strip() + default_val = (str(self.default_value.text()).strip() if col_type != 'composite' else None) if col_type == 'datetime': - if unicode_type(self.format_box.text()).strip(): - display_dict = {'date_format':unicode_type(self.format_box.text()).strip()} + if str(self.format_box.text()).strip(): + display_dict = {'date_format':str(self.format_box.text()).strip()} else: display_dict = {'date_format': None} if default_val: @@ -556,28 +556,28 @@ class CreateCustomColumn(QDialog): _('The default value must be "Now" or a date')) display_dict['default_value'] = default_val elif col_type == 'composite': - if not unicode_type(self.composite_box.text()).strip(): + if not str(self.composite_box.text()).strip(): return self.simple_error('', _('You must enter a template for ' 'composite columns')) - display_dict = {'composite_template':unicode_type(self.composite_box.text()).strip(), + display_dict = {'composite_template':str(self.composite_box.text()).strip(), 'composite_sort': ['text', 'number', 'date', 'bool'] [self.composite_sort_by.currentIndex()], 'make_category': self.composite_make_category.isChecked(), 'contains_html': self.composite_contains_html.isChecked(), } elif col_type == 'enumeration': - if not unicode_type(self.enum_box.text()).strip(): + if not str(self.enum_box.text()).strip(): return self.simple_error('', _('You must enter at least one ' 'value for enumeration columns')) - l = [v.strip() for v in unicode_type(self.enum_box.text()).split(',') if v.strip()] + l = [v.strip() for v in str(self.enum_box.text()).split(',') if v.strip()] l_lower = [v.lower() for v in l] for i,v in enumerate(l_lower): if v in l_lower[i+1:]: return self.simple_error('', _('The value "{0}" is in the ' 'list more than once, perhaps with different case').format(l[i])) - c = unicode_type(self.enum_colors.text()) + c = str(self.enum_colors.text()) if c: - c = [v.strip() for v in unicode_type(self.enum_colors.text()).split(',')] + c = [v.strip() for v in str(self.enum_colors.text()).split(',')] else: c = [] if len(c) != 0 and len(c) != len(l): @@ -595,8 +595,8 @@ class CreateCustomColumn(QDialog): elif col_type == 'text' and is_multiple: display_dict = {'is_names': self.is_names.isChecked()} elif col_type in ['int', 'float']: - if unicode_type(self.format_box.text()).strip(): - display_dict = {'number_format':unicode_type(self.format_box.text()).strip()} + if str(self.format_box.text()).strip(): + display_dict = {'number_format':str(self.format_box.text()).strip()} else: display_dict = {'number_format': None} if default_val: @@ -612,8 +612,8 @@ class CreateCustomColumn(QDialog): except: return self.simple_error(_('Invalid default value'), msg) elif col_type == 'comments': - display_dict['heading_position'] = unicode_type(self.comments_heading_position.currentData()) - display_dict['interpret_as'] = unicode_type(self.comments_type.currentData()) + display_dict['heading_position'] = str(self.comments_heading_position.currentData()) + display_dict['interpret_as'] = str(self.comments_type.currentData()) elif col_type == 'rating': half_stars = bool(self.allow_half_stars.isChecked()) display_dict['allow_half_stars'] = half_stars diff --git a/src/calibre/gui2/preferences/emailp.py b/src/calibre/gui2/preferences/emailp.py index 77506c9eb6..977bda5d10 100644 --- a/src/calibre/gui2/preferences/emailp.py +++ b/src/calibre/gui2/preferences/emailp.py @@ -14,7 +14,7 @@ from calibre.gui2.preferences.email_ui import Ui_Form from calibre.utils.config import ConfigProxy from calibre.utils.icu import numeric_sort_key from calibre.utils.smtp import config as smtp_prefs -from polyglot.builtins import unicode_type, map, as_unicode +from polyglot.builtins import as_unicode class EmailAccounts(QAbstractTableModel): # {{{ @@ -177,7 +177,7 @@ class EmailAccounts(QAbstractTableModel): # {{{ c = 0 while y in self.accounts: c += 1 - y = x + unicode_type(c) + y = x + str(c) auto_send = len(self.accounts) < 1 self.beginResetModel() self.accounts[y] = ['MOBI, EPUB', auto_send, diff --git a/src/calibre/gui2/preferences/history.py b/src/calibre/gui2/preferences/history.py index 5d677fe0e1..8d38dd0f88 100644 --- a/src/calibre/gui2/preferences/history.py +++ b/src/calibre/gui2/preferences/history.py @@ -11,7 +11,6 @@ import textwrap from qt.core import QComboBox, Qt from calibre.gui2 import config as gui_conf -from polyglot.builtins import unicode_type class HistoryBox(QComboBox): @@ -38,11 +37,11 @@ class HistoryBox(QComboBox): self.setCurrentIndex(self.findText(val, Qt.MatchFlag.MatchFixedString)) def save_history(self, opt_name): - history = [unicode_type(self.itemText(i)) for i in range(self.count())] + history = [str(self.itemText(i)) for i in range(self.count())] ct = self.text() if ct not in history: history = [ct] + history gui_conf[opt_name] = history[:10] def text(self): - return unicode_type(self.currentText()).strip() + return str(self.currentText()).strip() diff --git a/src/calibre/gui2/preferences/ignored_devices.py b/src/calibre/gui2/preferences/ignored_devices.py index 04a6d9a48c..8ec8090cc3 100644 --- a/src/calibre/gui2/preferences/ignored_devices.py +++ b/src/calibre/gui2/preferences/ignored_devices.py @@ -12,7 +12,7 @@ from qt.core import ( from calibre.customize.ui import enable_plugin from calibre.gui2 import gprefs from calibre.gui2.preferences import ConfigWidgetBase, test_widget -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems class ConfigWidget(ConfigWidgetBase): diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 62903ca70e..4f1ef44478 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -38,7 +38,7 @@ from calibre.gui2.library.alternate_views import auto_height, CM_TO_INCH from calibre.gui2.widgets2 import Dialog from calibre.gui2.actions.show_quickview import get_quickview_action_plugin from calibre.utils.resources import set_data -from polyglot.builtins import iteritems, unicode_type, map +from polyglot.builtins import iteritems class BusyCursor: @@ -555,7 +555,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.SequenceFormat.PortableText), QKeySequence( 'Ctrl+Shift+F', QKeySequence.SequenceFormat.PortableText)] - keys = [unicode_type(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in keys] + keys = [str(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in keys] self.fs_help_msg.setText(self.fs_help_msg.text()%( QKeySequence(QKeySequence.StandardKey.FullScreen).toString(QKeySequence.SequenceFormat.NativeText))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.ConnectionType.QueuedConnection) @@ -751,7 +751,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) - name = unicode_type(fi.family()) + name = str(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + ' [%dpt]'%fi.pointSize()) @@ -761,7 +761,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if fd.exec_() == QDialog.DialogCode.Accepted: font = fd.selectedFont() fi = QFontInfo(font) - self.current_font = [unicode_type(fi.family()), fi.pointSize(), + self.current_font = [str(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch()] self.update_font_display() self.changed_signal.emit() diff --git a/src/calibre/gui2/preferences/main.py b/src/calibre/gui2/preferences/main.py index 10a2b5b295..e116f0f51e 100644 --- a/src/calibre/gui2/preferences/main.py +++ b/src/calibre/gui2/preferences/main.py @@ -26,7 +26,6 @@ from calibre.gui2.dialogs.message_box import Icon from calibre.gui2.preferences import ( AbortCommit, AbortInitialize, get_plugin, init_gui ) -from polyglot.builtins import unicode_type ICON_SIZE = 32 @@ -301,8 +300,8 @@ class Preferences(QDialog): if isinstance(g, QLabel): buddy = g.buddy() if buddy is not None and hasattr(buddy, 'toolTip'): - htext = unicode_type(buddy.toolTip()).strip() - etext = unicode_type(g.toolTip()).strip() + htext = str(buddy.toolTip()).strip() + etext = str(g.toolTip()).strip() if htext and not etext: g.setToolTip(htext) g.setWhatsThis(htext) 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/plugboard.py b/src/calibre/gui2/preferences/plugboard.py index ce7e95e26f..88f0b7a1e2 100644 --- a/src/calibre/gui2/preferences/plugboard.py +++ b/src/calibre/gui2/preferences/plugboard.py @@ -24,7 +24,7 @@ from calibre.library.save_to_disk import plugboard_any_format_value, \ from calibre.srv.content import plugboard_content_server_value, plugboard_content_server_formats from calibre.gui2.email import plugboard_email_value, plugboard_email_formats from calibre.utils.formatter import validation_formatter -from polyglot.builtins import native_string_type, unicode_type +from polyglot.builtins import native_string_type class ConfigWidget(ConfigWidgetBase, Ui_Form): @@ -143,7 +143,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.clear_fields(new_boxes=False) return self.clear_fields(new_boxes=True) - self.current_device = unicode_type(txt) + self.current_device = str(txt) fpb = self.current_plugboards.get(self.current_format, None) if fpb is None: print('edit_device_changed: none format!') @@ -166,7 +166,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.clear_fields(new_boxes=False) return self.clear_fields(new_boxes=True) - txt = unicode_type(txt) + txt = str(txt) fpb = self.current_plugboards.get(txt, None) if fpb is None: print('edit_format_changed: none editable format!') @@ -198,7 +198,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.clear_fields(edit_boxes=False) return self.clear_fields(edit_boxes=True) - self.current_device = unicode_type(txt) + self.current_device = str(txt) if self.current_format in self.current_plugboards and \ self.current_device in self.current_plugboards[self.current_format]: @@ -282,7 +282,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.new_device.setCurrentIndex(0) if txt: self.clear_fields(edit_boxes=True) - self.current_format = unicode_type(txt) + self.current_format = str(txt) self.check_if_writer_disabled(self.current_format) else: self.clear_fields(edit_boxes=False) @@ -291,7 +291,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): pb = [] comments_in_dests = False for i in range(0, len(self.source_widgets)): - s = unicode_type(self.source_widgets[i].text()) + s = str(self.source_widgets[i].text()) if s: d = self.dest_widgets[i].currentIndex() if d != 0: @@ -300,7 +300,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): except Exception as err: error_dialog(self, _('Invalid template'), '

    '+_('The template %s is invalid:')%s + - '
    '+unicode_type(err), show=True) + '
    '+str(err), show=True) return pb.append((s, self.dest_fields[d])) comments_in_dests = comments_in_dests or self.dest_fields[d] == 'comments' diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py index 5827788f16..1baefbc577 100644 --- a/src/calibre/gui2/preferences/plugins.py +++ b/src/calibre/gui2/preferences/plugins.py @@ -24,7 +24,7 @@ from calibre.gui2.dialogs.confirm_delete import confirm from calibre.utils.search_query_parser import SearchQueryParser from calibre.utils.icu import lower from calibre.constants import iswindows -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues class AdaptSQP(SearchQueryParser): @@ -204,7 +204,7 @@ class PluginModel(QAbstractItemModel, AdaptSQP): # {{{ plugin = self.index_to_plugin(index) disabled = is_disabled(plugin) if role == Qt.ItemDataRole.DisplayRole: - ver = '.'.join(map(unicode_type, plugin.version)) + ver = '.'.join(map(str, plugin.version)) desc = '\n'.join(textwrap.wrap(plugin.description, 100)) ans='%s (%s) %s %s\n%s'%(plugin.name, ver, _('by'), plugin.author, desc) c = plugin_customization(plugin) @@ -281,7 +281,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if not idx.isValid(): idx = self._plugin_model.index(0, 0) idx = self._plugin_model.find_next(idx, - unicode_type(self.search.currentText())) + str(self.search.currentText())) self.highlight_index(idx) def find_previous(self, *args): @@ -289,7 +289,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if not idx.isValid(): idx = self._plugin_model.index(0, 0) idx = self._plugin_model.find_next(idx, - unicode_type(self.search.currentText()), backwards=True) + str(self.search.currentText()), backwards=True) self.highlight_index(idx) def toggle_plugin(self, *args): @@ -327,7 +327,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): plugin = add_plugin(path) except NameConflict as e: return error_dialog(self, _('Already exists'), - unicode_type(e), show=True) + str(e), show=True) self._plugin_model.beginResetModel() self._plugin_model.populate() self._plugin_model.endResetModel() @@ -349,7 +349,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): index = self.plugin_view.currentIndex() if index.isValid(): if not index.parent().isValid(): - name = unicode_type(index.data() or '') + name = str(index.data() or '') return error_dialog(self, _('Error'), '

    '+ _('Select an actual plugin under %s to customize')%name, show=True, show_copy_button=False) @@ -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/save_template.py b/src/calibre/gui2/preferences/save_template.py index 09f116804b..d83e95c889 100644 --- a/src/calibre/gui2/preferences/save_template.py +++ b/src/calibre/gui2/preferences/save_template.py @@ -13,7 +13,6 @@ from calibre.gui2.preferences.save_template_ui import Ui_Form from calibre.library.save_to_disk import FORMAT_ARG_DESCS, preprocess_template from calibre.utils.formatter import validation_formatter from calibre.gui2.dialogs.template_dialog import TemplateDialog -from polyglot.builtins import unicode_type class SaveTemplate(QWidget, Ui_Form): @@ -75,7 +74,7 @@ class SaveTemplate(QWidget, Ui_Form): except Exception as err: error_dialog(self, _('Invalid template'), '

    '+_('The template %s is invalid:')%tmpl + - '
    '+unicode_type(err), show=True) + '
    '+str(err), show=True) return False return True @@ -83,6 +82,6 @@ class SaveTemplate(QWidget, Ui_Form): self.opt_template.set_value(val) def save_settings(self, config, name): - val = unicode_type(self.opt_template.text()) + val = str(self.opt_template.text()) config.set(name, val) self.opt_template.save_history(self.option_name+'_template_history') diff --git a/src/calibre/gui2/preferences/search.py b/src/calibre/gui2/preferences/search.py index 71ce6ba422..1aa497a40f 100644 --- a/src/calibre/gui2/preferences/search.py +++ b/src/calibre/gui2/preferences/search.py @@ -16,7 +16,7 @@ from calibre.gui2 import config, error_dialog, gprefs from calibre.utils.config import prefs from calibre.utils.icu import sort_key from calibre.library.caches import set_use_primary_find_in_search -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class ConfigWidget(ConfigWidgetBase, Ui_Form): @@ -139,13 +139,13 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def gst_save_clicked(self): idx = self.gst_names.currentIndex() - name = icu_lower(unicode_type(self.gst_names.currentText())) + name = icu_lower(str(self.gst_names.currentText())) if not name: return error_dialog(self.gui, _('Grouped search terms'), _('The search term cannot be blank'), show=True) if idx != 0: - orig_name = unicode_type(self.gst_names.itemData(idx) or '') + orig_name = str(self.gst_names.itemData(idx) or '') else: orig_name = '' if name != orig_name: @@ -159,7 +159,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): _('That name is already used for User category'), show=True) - val = [v.strip() for v in unicode_type(self.gst_value.text()).split(',') if v.strip()] + val = [v.strip() for v in str(self.gst_value.text()).split(',') if v.strip()] if not val: return error_dialog(self.gui, _('Grouped search terms'), _('The value box cannot be empty'), show=True) @@ -176,7 +176,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if self.gst_names.currentIndex() == 0: return error_dialog(self.gui, _('Grouped search terms'), _('The empty grouped search term cannot be deleted'), show=True) - name = unicode_type(self.gst_names.currentText()) + name = str(self.gst_names.currentText()) if name in self.gst: del self.gst[name] self.fill_gst_box(select='') @@ -211,7 +211,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if idx == 0: self.gst_value.setText('') else: - name = unicode_type(self.gst_names.itemData(idx) or '') + name = str(self.gst_names.itemData(idx) or '') self.gst_value.setText(','.join(self.gst[name])) self.gst_value.blockSignals(False) @@ -225,13 +225,13 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.db.new_api.set_pref('grouped_search_terms', self.gst) self.db.field_metadata.add_grouped_search_terms(self.gst) self.db.new_api.set_pref('similar_authors_search_key', - unicode_type(self.similar_authors_search_key.currentText())) + str(self.similar_authors_search_key.currentText())) self.db.new_api.set_pref('similar_tags_search_key', - unicode_type(self.similar_tags_search_key.currentText())) + str(self.similar_tags_search_key.currentText())) self.db.new_api.set_pref('similar_series_search_key', - unicode_type(self.similar_series_search_key.currentText())) + str(self.similar_series_search_key.currentText())) self.db.new_api.set_pref('similar_publisher_search_key', - unicode_type(self.similar_publisher_search_key.currentText())) + str(self.similar_publisher_search_key.currentText())) return ConfigWidgetBase.commit(self) def refresh_gui(self, gui): diff --git a/src/calibre/gui2/preferences/server.py b/src/calibre/gui2/preferences/server.py index 208cbe0f43..7a361f35fd 100644 --- a/src/calibre/gui2/preferences/server.py +++ b/src/calibre/gui2/preferences/server.py @@ -35,7 +35,7 @@ from calibre.srv.users import ( ) from calibre.utils.icu import primary_sort_key from calibre.utils.shared_file import share_open -from polyglot.builtins import as_bytes, unicode_type +from polyglot.builtins import as_bytes if iswindows and not isportable: @@ -169,7 +169,7 @@ class Text(QLineEdit): return self.text().strip() or None def set(self, val): - self.setText(unicode_type(val or '')) + self.setText(str(val or '')) class Path(QWidget): @@ -199,7 +199,7 @@ class Path(QWidget): return self.text.text().strip() or None def set(self, val): - self.text.setText(unicode_type(val or '')) + self.text.setText(str(val or '')) def choose(self): ans = choose_files(self, 'choose_path_srv_opts_' + self.dname, _('Choose a file'), select_only_single_file=True) @@ -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 5bcaa1ef34..7532c7e83d 100644 --- a/src/calibre/gui2/preferences/template_functions.py +++ b/src/calibre/gui2/preferences/template_functions.py @@ -16,7 +16,7 @@ from calibre.utils.formatter_functions import ( compile_user_function, compile_user_template_functions, formatter_functions, function_pref_is_python, function_pref_name, load_user_template_functions ) -from polyglot.builtins import iteritems, native_string_type, unicode_type +from polyglot.builtins import iteritems, native_string_type class ConfigWidget(ConfigWidgetBase, Ui_Form): @@ -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() @@ -245,7 +245,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.delete_button.setEnabled(True) def delete_button_clicked(self): - name = unicode_type(self.function_name.currentText()) + name = str(self.function_name.currentText()) if name in self.builtins: error_dialog(self.gui, _('Template functions'), _('You cannot delete a built-in function'), show=True) @@ -262,7 +262,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def create_button_clicked(self, use_name=None): self.changed_signal.emit() - name = use_name if use_name else unicode_type(self.function_name.currentText()) + name = use_name if use_name else str(self.function_name.currentText()) if name in self.funcs: error_dialog(self.gui, _('Template functions'), _('Name %s already used')%(name,), show=True) @@ -284,8 +284,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if not box.exec_(): return try: - prog = unicode_type(self.program.toPlainText()) - cls = compile_user_function(name, unicode_type(self.documentation.toPlainText()), + prog = str(self.program.toPlainText()) + cls = compile_user_function(name, str(self.documentation.toPlainText()), self.argument_count.value(), prog) self.funcs[name] = cls self.build_function_names_box(scroll_to=name) @@ -302,7 +302,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.program.setReadOnly(False) def function_index_changed(self, txt): - txt = unicode_type(txt) + txt = str(txt) self.create_button.setEnabled(False) if not txt: self.argument_count.clear() @@ -331,7 +331,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.replace_button.setEnabled(False) def replace_button_clicked(self): - name = unicode_type(self.function_name.currentText()) + name = str(self.function_name.currentText()) self.delete_button_clicked() self.create_button_clicked(use_name=name) @@ -379,7 +379,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.te_name.setCurrentIndex(idx) def st_delete_button_clicked(self): - name = unicode_type(self.te_name.currentText()) + name = str(self.te_name.currentText()) if name in self.st_funcs: del self.st_funcs[name] self.changed_signal.emit() @@ -394,18 +394,18 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def st_create_button_clicked(self, use_name=None): self.changed_signal.emit() - name = use_name if use_name else unicode_type(self.te_name.currentText()) + name = use_name if use_name else str(self.te_name.currentText()) for k,v in formatter_functions().get_functions().items(): if k == name and v.is_python: error_dialog(self.gui, _('Stored templates'), _('The name {} is already used for template function').format(name), show=True) try: - prog = unicode_type(self.te_textbox.toPlainText()) + prog = str(self.te_textbox.toPlainText()) if not prog.startswith('program:'): error_dialog(self.gui, _('Stored templates'), _('The stored template must begin with "program:"'), show=True) - cls = compile_user_function(name, unicode_type(self.template_editor.new_doc.toPlainText()), + cls = compile_user_function(name, str(self.template_editor.new_doc.toPlainText()), 0, prog) self.st_funcs[name] = cls self.st_build_function_names_box(scroll_to=name) @@ -423,7 +423,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.te_textbox.setReadOnly(False) def st_function_index_changed(self, txt): - txt = unicode_type(txt) + txt = str(txt) if self.st_current_program_name: if self.st_current_program_text != self.te_textbox.toPlainText(): box = warning_dialog(self.gui, _('Template functions'), @@ -451,7 +451,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.st_template_name_edited(txt) def st_replace_button_clicked(self): - name = unicode_type(self.te_name.currentText()) + name = str(self.te_name.currentText()) self.st_current_program_text = self.te_textbox.toPlainText() self.st_delete_button_clicked() self.st_create_button_clicked(use_name=name) diff --git a/src/calibre/gui2/preferences/texture_chooser.py b/src/calibre/gui2/preferences/texture_chooser.py index 171848ca56..f472daa233 100644 --- a/src/calibre/gui2/preferences/texture_chooser.py +++ b/src/calibre/gui2/preferences/texture_chooser.py @@ -14,7 +14,6 @@ from qt.core import ( from calibre.constants import config_dir from calibre.gui2 import choose_files, error_dialog from calibre.utils.icu import sort_key -from polyglot.builtins import unicode_type, range def texture_dir(): @@ -86,7 +85,7 @@ class TextureChooser(QDialog): self.update_remove_state() if initial: - existing = {unicode_type(i.data(Qt.ItemDataRole.UserRole) or ''):i for i in (self.images.item(c) for c in range(self.images.count()))} + existing = {str(i.data(Qt.ItemDataRole.UserRole) or ''):i for i in (self.images.item(c) for c in range(self.images.count()))} item = existing.get(initial, None) if item is not None: item.setSelected(True) @@ -117,7 +116,7 @@ class TextureChooser(QDialog): path = path[0] fname = os.path.basename(path) name = fname.rpartition('.')[0] - existing = {unicode_type(i.data(Qt.ItemDataRole.UserRole) or ''):i for i in (self.images.item(c) for c in range(self.images.count()))} + existing = {str(i.data(Qt.ItemDataRole.UserRole) or ''):i for i in (self.images.item(c) for c in range(self.images.count()))} dest = os.path.join(self.tdir, fname) with open(path, 'rb') as s, open(dest, 'wb') as f: shutil.copyfileobj(s, f) @@ -136,7 +135,7 @@ class TextureChooser(QDialog): @property def selected_fname(self): try: - return unicode_type(self.selected_item.data(Qt.ItemDataRole.UserRole) or '') + return str(self.selected_item.data(Qt.ItemDataRole.UserRole) or '') except (AttributeError, TypeError): pass @@ -146,7 +145,7 @@ class TextureChooser(QDialog): if self.selected_fname.startswith(':'): return error_dialog(self, _('Cannot remove'), _('Cannot remove builtin textures'), show=True) - os.remove(unicode_type(self.selected_item.data(Qt.ItemDataRole.UserRole+1) or '')) + os.remove(str(self.selected_item.data(Qt.ItemDataRole.UserRole+1) or '')) self.images.takeItem(self.images.row(self.selected_item)) diff --git a/src/calibre/gui2/preferences/toolbar.py b/src/calibre/gui2/preferences/toolbar.py index a2c4ea4830..4e70bda08d 100644 --- a/src/calibre/gui2/preferences/toolbar.py +++ b/src/calibre/gui2/preferences/toolbar.py @@ -13,7 +13,6 @@ from calibre.gui2.preferences.toolbar_ui import Ui_Form from calibre.gui2 import gprefs, warning_dialog, error_dialog from calibre.gui2.preferences import ConfigWidgetBase, test_widget, AbortCommit from calibre.utils.icu import primary_sort_key -from polyglot.builtins import unicode_type def sort_key_for_action(ac): @@ -291,7 +290,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.help_text.setText(tt) def what_changed(self, idx): - key = unicode_type(self.what.itemData(idx) or '') + key = str(self.what.itemData(idx) or '') if key == 'blank': self.actions_widget.setVisible(False) self.spacer_widget.setVisible(True) diff --git a/src/calibre/gui2/preferences/tweaks.py b/src/calibre/gui2/preferences/tweaks.py index 22d79e3c28..f3439b1b61 100644 --- a/src/calibre/gui2/preferences/tweaks.py +++ b/src/calibre/gui2/preferences/tweaks.py @@ -26,7 +26,7 @@ from calibre.utils.config_base import ( ) from calibre.utils.icu import lower from calibre.utils.search_query_parser import ParseException, SearchQueryParser -from polyglot.builtins import iteritems, range, unicode_type +from polyglot.builtins import iteritems ROOT = QModelIndex() @@ -263,7 +263,7 @@ class Tweaks(QAbstractListModel, AdaptSQP): # {{{ ' edit it unless you know what you are doing.', '', ] for tweak in self.tweaks: - ans.extend(['', unicode_type(tweak), '']) + ans.extend(['', str(tweak), '']) if self.plugin_tweaks: ans.extend(['', '', @@ -495,7 +495,7 @@ class ConfigWidget(ConfigWidgetBase): if d.exec_() == QDialog.DialogCode.Accepted: g, l = {}, {} try: - exec(unicode_type(d.edit.toPlainText()), g, l) + exec(str(d.edit.toPlainText()), g, l) except: import traceback return error_dialog(self, _('Failed'), @@ -536,7 +536,7 @@ class ConfigWidget(ConfigWidgetBase): if idx.isValid(): l, g = {}, {} try: - exec(unicode_type(self.edit_tweak.toPlainText()), g, l) + exec(str(self.edit_tweak.toPlainText()), g, l) except: import traceback error_dialog(self.gui, _('Failed'), @@ -593,7 +593,7 @@ class ConfigWidget(ConfigWidgetBase): if not idx.isValid(): idx = self._model.index(0) idx = self._model.find_next(idx, - unicode_type(self.search.currentText())) + str(self.search.currentText())) self.highlight_index(idx) def find_previous(self, *args): @@ -601,7 +601,7 @@ class ConfigWidget(ConfigWidgetBase): if not idx.isValid(): idx = self._model.index(0) idx = self._model.find_next(idx, - unicode_type(self.search.currentText()), backwards=True) + str(self.search.currentText()), backwards=True) self.highlight_index(idx) diff --git a/src/calibre/gui2/proceed.py b/src/calibre/gui2/proceed.py index dd7de9774c..6154b9315a 100644 --- a/src/calibre/gui2/proceed.py +++ b/src/calibre/gui2/proceed.py @@ -15,7 +15,6 @@ from qt.core import ( from calibre.constants import __version__ from calibre.gui2.dialogs.message_box import ViewLog -from polyglot.builtins import unicode_type Question = namedtuple('Question', 'payload callback cancel_callback ' 'title msg html_log log_viewer_title log_is_file det_msg ' @@ -171,9 +170,9 @@ class ProceedQuestion(QWidget): def copy_to_clipboard(self, *args): QApplication.clipboard().setText( 'calibre, version %s\n%s: %s\n\n%s' % - (__version__, unicode_type(self.windowTitle()), - unicode_type(self.msg_label.text()), - unicode_type(self.det_msg.toPlainText()))) + (__version__, str(self.windowTitle()), + str(self.msg_label.text()), + str(self.det_msg.toPlainText()))) self.copy_button.setText(_('Copied')) def action_clicked(self): @@ -211,7 +210,7 @@ class ProceedQuestion(QWidget): self.show_question() def toggle_det_msg(self, *args): - vis = unicode_type(self.det_msg_toggle.text()) == self.hide_det_msg + vis = str(self.det_msg_toggle.text()) == self.hide_det_msg self.det_msg_toggle.setText(self.show_det_msg if vis else self.hide_det_msg) self.det_msg.setVisible(not vis) diff --git a/src/calibre/gui2/qt_file_dialogs.py b/src/calibre/gui2/qt_file_dialogs.py index dbd45da63a..6026fcb1a0 100644 --- a/src/calibre/gui2/qt_file_dialogs.py +++ b/src/calibre/gui2/qt_file_dialogs.py @@ -8,7 +8,7 @@ import os from qt.core import QFileDialog, QObject from calibre.gui2.linux_file_dialogs import dialog_name, image_extensions -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes from polyglot.urllib import unquote @@ -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) @@ -117,7 +117,7 @@ class FileDialog(QObject): ftext, "", opts) if fs and fs[0]: for f in fs[0]: - f = unicode_type(f) + f = str(f) if not f: continue if not os.path.exists(f): @@ -130,11 +130,11 @@ class FileDialog(QObject): if mode == QFileDialog.FileMode.Directory: opts |= QFileDialog.Option.ShowDirsOnly with adapt_menubar: - f = unicode_type(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) + f = str(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) if self.selected_files: - self.selected_files = [unicode_type(q) for q in self.selected_files] + self.selected_files = [str(q) for q in self.selected_files] saved_loc = self.selected_files[0] if os.path.isfile(saved_loc): saved_loc = os.path.dirname(saved_loc) @@ -144,7 +144,7 @@ class FileDialog(QObject): def get_files(self): if self.selected_files is None: - return tuple(os.path.abspath(unicode_type(i)) for i in self.fd.selectedFiles()) + return tuple(os.path.abspath(str(i)) for i in self.fd.selectedFiles()) return tuple(self.selected_files) @@ -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 667724b7f5..18c7c15f15 100644 --- a/src/calibre/gui2/save.py +++ b/src/calibre/gui2/save.py @@ -22,7 +22,7 @@ from calibre.gui2.dialogs.progress import ProgressDialog from calibre.utils.formatter_functions import load_user_template_functions from calibre.utils.ipc.pool import Pool, Failure from calibre.library.save_to_disk import sanitize_args, get_path_components, find_plugboard, plugboard_save_to_disk_value -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues from polyglot.queue import Empty BookId = namedtuple('BookId', 'title authors') @@ -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 @@ -267,7 +267,7 @@ class Saver(QObject): except Failure as err: error_dialog(self.pd, _('Critical failure'), _( 'Could not save books to disk, click "Show details" for more information'), - det_msg=unicode_type(err.failure_message) + '\n' + unicode_type(err.details), show=True) + det_msg=str(err.failure_message) + '\n' + str(err.details), show=True) self.pd.canceled = True else: self.pd.value += 1 @@ -301,7 +301,7 @@ class Saver(QObject): except Failure as err: error_dialog(self.pd, _('Critical failure'), _( 'Could not save books to disk, click "Show details" for more information'), - det_msg=unicode_type(err.failure_message) + '\n' + unicode_type(err.details), show=True) + det_msg=str(err.failure_message) + '\n' + str(err.details), show=True) self.pd.canceled = True except RuntimeError: pass # tasks not completed diff --git a/src/calibre/gui2/search_box.py b/src/calibre/gui2/search_box.py index 762bf0344a..e1388191e2 100644 --- a/src/calibre/gui2/search_box.py +++ b/src/calibre/gui2/search_box.py @@ -20,13 +20,13 @@ from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.saved_search_editor import SavedSearchEditor from calibre.gui2.dialogs.search import SearchDialog from calibre.utils.icu import primary_sort_key -from polyglot.builtins import native_string_type, unicode_type, string_or_bytes, map, range +from polyglot.builtins import native_string_type, string_or_bytes -class AsYouType(unicode_type): +class AsYouType(str): def __new__(cls, text): - self = unicode_type.__new__(cls, text) + self = str.__new__(cls, text) self.as_you_type = True return self @@ -196,7 +196,7 @@ class SearchBox2(QComboBox): # {{{ if isinstance(ok, string_or_bytes): self.setToolTip(ok) ok = False - if not unicode_type(self.currentText()).strip(): + if not str(self.currentText()).strip(): self.clear(emit_search=False) return self._in_a_search = ok @@ -219,7 +219,7 @@ class SearchBox2(QComboBox): # {{{ if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter): self.do_search() self.focus_to_library.emit() - elif self.as_you_type and unicode_type(event.text()): + elif self.as_you_type and str(event.text()): self.timer.start(1500) # Comes from the combobox itself @@ -251,7 +251,7 @@ class SearchBox2(QComboBox): # {{{ def _do_search(self, store_in_history=True, as_you_type=False): self.hide_completer_popup() - text = unicode_type(self.currentText()).strip() + text = str(self.currentText()).strip() if not text: return self.clear() if as_you_type: @@ -269,7 +269,7 @@ class SearchBox2(QComboBox): # {{{ self.insertItem(0, t) self.setCurrentIndex(0) self.block_signals(False) - history = [unicode_type(self.itemText(i)) for i in + history = [str(self.itemText(i)) for i in range(self.count())] config[self.opt_name] = history @@ -312,7 +312,7 @@ class SearchBox2(QComboBox): # {{{ @property def current_text(self): - return unicode_type(self.lineEdit().text()) + return str(self.lineEdit().text()) # }}} @@ -376,7 +376,7 @@ class SavedSearchBox(QComboBox): # {{{ def saved_search_selected(self, qname): from calibre.gui2.ui import get_gui db = get_gui().current_db - qname = unicode_type(qname) + qname = str(qname) if qname is None or not qname.strip(): self.search_box.clear() return @@ -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)) @@ -403,9 +403,9 @@ class SavedSearchBox(QComboBox): # {{{ def save_search_button_clicked(self): from calibre.gui2.ui import get_gui db = get_gui().current_db - name = unicode_type(self.currentText()) + name = str(self.currentText()) if not name.strip(): - name = unicode_type(self.search_box.text()).replace('"', '') + name = str(self.search_box.text()).replace('"', '') name = name.replace('\\', '') if not name: error_dialog(self, _('Create saved search'), @@ -417,7 +417,7 @@ class SavedSearchBox(QComboBox): # {{{ _('There is no search to save'), show=True) return db.saved_search_delete(name) - db.saved_search_add(name, unicode_type(self.search_box.text())) + db.saved_search_add(name, str(self.search_box.text())) # now go through an initialization cycle to ensure that the combobox has # the new search in it, that it is selected, and that the search box # references the new search instead of the text in the search. @@ -438,10 +438,10 @@ class SavedSearchBox(QComboBox): # {{{ 'permanently deleted. Are you sure?') + '

    ', 'saved_search_delete', self): return - ss = db.saved_search_lookup(unicode_type(self.currentText())) + ss = db.saved_search_lookup(str(self.currentText())) if ss is None: return - db.saved_search_delete(unicode_type(self.currentText())) + db.saved_search_delete(str(self.currentText())) self.clear() self.search_box.clear() self.changed.emit() @@ -453,7 +453,7 @@ class SavedSearchBox(QComboBox): # {{{ idx = self.currentIndex() if idx < 0: return - self.search_box.set_search_string(db.saved_search_lookup(unicode_type(self.currentText()))) + self.search_box.set_search_string(db.saved_search_lookup(str(self.currentText()))) # }}} @@ -477,7 +477,7 @@ class SearchBoxMixin: # {{{ self.search.setMaximumWidth(self.width()-150) self.action_focus_search = QAction(self) shortcuts = list( - map(lambda x:unicode_type(x.toString(QKeySequence.SequenceFormat.PortableText)), + map(lambda x:str(x.toString(QKeySequence.SequenceFormat.PortableText)), QKeySequence.keyBindings(QKeySequence.StandardKey.Find))) shortcuts += ['/', 'Alt+S'] self.keyboard.register_shortcut('start search', _('Start search'), @@ -485,7 +485,7 @@ class SearchBoxMixin: # {{{ self.action_focus_search.triggered.connect(self.focus_search_box) self.addAction(self.action_focus_search) self.search.setStatusTip(re.sub(r'<\w+>', ' ', - unicode_type(self.search.toolTip()))) + str(self.search.toolTip()))) self.set_highlight_only_button_icon() self.highlight_only_button.clicked.connect(self.highlight_only_clicked) tt = _('Enable or disable search highlighting.') + '

    ' diff --git a/src/calibre/gui2/search_restriction_mixin.py b/src/calibre/gui2/search_restriction_mixin.py index 5b3142c33d..785d6310f0 100644 --- a/src/calibre/gui2/search_restriction_mixin.py +++ b/src/calibre/gui2/search_restriction_mixin.py @@ -17,7 +17,6 @@ from calibre.gui2.widgets import ComboBoxWithHelp from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import ParseException from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import unicode_type class SelectNames(QDialog): # {{{ @@ -51,7 +50,7 @@ class SelectNames(QDialog): # {{{ @property def names(self): for item in self._names.selectedItems(): - yield unicode_type(item.data(Qt.ItemDataRole.DisplayRole) or '') + yield str(item.data(Qt.ItemDataRole.DisplayRole) or '') @property def match_type(self): @@ -187,7 +186,7 @@ class CreateVirtualLibrary(QDialog): # {{{ def search_text_changed(self, txt): db = self.gui.current_db searches = [_('Saved searches recognized in the expression:')] - txt = unicode_type(txt) + txt = str(txt) while txt: p = txt.partition('search:') if p[1]: # found 'search:' @@ -218,7 +217,7 @@ class CreateVirtualLibrary(QDialog): # {{{ self.saved_searches_label.setPlainText('\n'.join(searches)) def name_text_edited(self, new_name): - self.new_name = unicode_type(new_name) + self.new_name = str(new_name) def name_index_changed(self, dex): if self.editing and (self.vl_text.text() != self.original_search or @@ -234,12 +233,12 @@ class CreateVirtualLibrary(QDialog): # {{{ return self.new_name = self.editing = self.vl_name.currentText() self.original_index = dex - self.original_search = unicode_type(self.vl_name.itemData(dex) or '') + self.original_search = str(self.vl_name.itemData(dex) or '') self.vl_text.setText(self.original_search) def link_activated(self, url): db = self.gui.current_db - f, txt = unicode_type(url).partition('.')[0::2] + f, txt = str(url).partition('.')[0::2] if f == 'search': names = db.saved_search_names() else: @@ -259,7 +258,7 @@ class CreateVirtualLibrary(QDialog): # {{{ self.vl_text.setCursorPosition(0) def accept(self): - n = unicode_type(self.vl_name.currentText()).strip() + n = str(self.vl_name.currentText()).strip() if not n: error_dialog(self.gui, _('No name'), _('You must provide a name for the new Virtual library'), @@ -279,7 +278,7 @@ class CreateVirtualLibrary(QDialog): # {{{ default_yes=False): return - v = unicode_type(self.vl_text.text()).strip() + v = str(self.vl_text.text()).strip() if not v: error_dialog(self.gui, _('No search string'), _('You must provide a search to define the new Virtual library'), @@ -545,7 +544,7 @@ class SearchRestrictionMixin: current_restriction_text = None if self.search_restriction.count() > 1: - txt = unicode_type(self.search_restriction.itemText(2)) + txt = str(self.search_restriction.itemText(2)) if txt.startswith('*'): current_restriction_text = txt self.search_restriction.clear() @@ -593,14 +592,14 @@ class SearchRestrictionMixin: def apply_text_search_restriction(self, search): if not self.search_restriction_list_built: self.build_search_restriction_list() - search = unicode_type(search) + search = str(search) if not search: self.search_restriction.setCurrentIndex(0) self._apply_search_restriction('', '') else: s = '*' + search if self.search_restriction.count() > 1: - txt = unicode_type(self.search_restriction.itemText(2)) + txt = str(self.search_restriction.itemText(2)) if txt.startswith('*'): self.search_restriction.setItemText(2, s) else: @@ -614,12 +613,12 @@ class SearchRestrictionMixin: if not self.search_restriction_list_built: self.build_search_restriction_list() if i == 1: - self.apply_text_search_restriction(unicode_type(self.search.currentText())) - elif i == 2 and unicode_type(self.search_restriction.currentText()).startswith('*'): + self.apply_text_search_restriction(str(self.search.currentText())) + elif i == 2 and str(self.search_restriction.currentText()).startswith('*'): self.apply_text_search_restriction( - unicode_type(self.search_restriction.currentText())[1:]) + str(self.search_restriction.currentText())[1:]) else: - r = unicode_type(self.search_restriction.currentText()) + r = str(self.search_restriction.currentText()) if r is not None and r != '': restriction = 'search:"%s"'%(r) else: @@ -656,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/shortcuts.py b/src/calibre/gui2/shortcuts.py index 14f49d1045..2a61f14afd 100644 --- a/src/calibre/gui2/shortcuts.py +++ b/src/calibre/gui2/shortcuts.py @@ -17,7 +17,6 @@ from qt.core import ( from calibre.gui2 import error_dialog from calibre.utils.config import XMLConfig from calibre.utils.icu import sort_key -from polyglot.builtins import unicode_type DEFAULTS = Qt.ItemDataRole.UserRole DESCRIPTION = Qt.ItemDataRole.UserRole + 1 @@ -119,7 +118,7 @@ class Customize(QFrame): dup_desc = self.dup_check(sequence, self.key) if dup_desc is not None: error_dialog(self, _('Already assigned'), - unicode_type(sequence.toString(QKeySequence.SequenceFormat.NativeText)) + ' ' + + str(sequence.toString(QKeySequence.SequenceFormat.NativeText)) + ' ' + _('already assigned to') + ' ' + dup_desc, show=True) self.clear_clicked(which=which) @@ -170,12 +169,12 @@ class Delegate(QStyledItemDelegate): def setEditorData(self, editor, index): defs = index.data(DEFAULTS) - defs = _(' or ').join([unicode_type(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in defs]) - editor.key = unicode_type(index.data(KEY)) + defs = _(' or ').join([str(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in defs]) + editor.key = str(index.data(KEY)) editor.default_shortcuts.setText(_('&Default') + ': %s' % defs) editor.default_shortcuts.setChecked(True) editor.header.setText('%s: %s'%(_('Customize shortcuts for'), - unicode_type(index.data(DESCRIPTION)))) + str(index.data(DESCRIPTION)))) custom = index.data(CUSTOM) if custom: editor.custom.setChecked(True) @@ -251,7 +250,7 @@ class Shortcuts(QAbstractListModel): return self.descriptions[key] def get_shortcuts(self, key): - return [unicode_type(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in + return [str(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in self.get_sequences(key)] def data(self, index, role): @@ -280,7 +279,7 @@ class Shortcuts(QAbstractListModel): def set_data(self, index, custom): key = self.order[index.row()] if custom: - self.custom[key] = [unicode_type(x.toString(QKeySequence.SequenceFormat.PortableText)) for x in custom] + self.custom[key] = [str(x.toString(QKeySequence.SequenceFormat.PortableText)) for x in custom] elif key in self.custom: del self.custom[key] diff --git a/src/calibre/gui2/splash_screen.py b/src/calibre/gui2/splash_screen.py index 2487978135..1c17122710 100644 --- a/src/calibre/gui2/splash_screen.py +++ b/src/calibre/gui2/splash_screen.py @@ -10,7 +10,6 @@ from qt.core import ( from calibre.constants import __appname__, numeric_version from calibre.utils.monotonic import monotonic -from polyglot.builtins import unicode_type class SplashScreen(QSplashScreen): @@ -36,7 +35,7 @@ class SplashScreen(QSplashScreen): f.setPixelSize(self.total_height) f.setItalic(True), f.setBold(True) f = QFontMetrics(f) - self.num_ch = unicode_type(max(3, numeric_version[0])) + self.num_ch = str(max(3, numeric_version[0])) self.footer_font = f = QFont() f.setPointSize(self.FOOTER_SIZE) f.setItalic(True) diff --git a/src/calibre/gui2/store/basic_config.py b/src/calibre/gui2/store/basic_config.py index 3212f35f91..40390e69e4 100644 --- a/src/calibre/gui2/store/basic_config.py +++ b/src/calibre/gui2/store/basic_config.py @@ -8,7 +8,6 @@ __docformat__ = 'restructuredtext en' from qt.core import QWidget from calibre.gui2.store.basic_config_widget_ui import Ui_Form -from polyglot.builtins import unicode_type class BasicStoreConfigWidget(QWidget, Ui_Form): @@ -38,5 +37,5 @@ class BasicStoreConfig: def save_settings(self, config_widget): self.config['open_external'] = config_widget.open_external.isChecked() - tags = unicode_type(config_widget.tags.text()) + tags = str(config_widget.tags.text()) self.config['tags'] = tags diff --git a/src/calibre/gui2/store/config/chooser/adv_search_builder.py b/src/calibre/gui2/store/config/chooser/adv_search_builder.py index 36e7922706..76de44a3ab 100644 --- a/src/calibre/gui2/store/config/chooser/adv_search_builder.py +++ b/src/calibre/gui2/store/config/chooser/adv_search_builder.py @@ -12,7 +12,6 @@ from qt.core import (QDialog, QDialogButtonBox) from calibre.gui2.store.config.chooser.adv_search_builder_ui import Ui_Dialog from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import unicode_type, map class AdvSearchBuilderDialog(QDialog, Ui_Dialog): @@ -77,7 +76,7 @@ class AdvSearchBuilderDialog(QDialog, Ui_Dialog): self.mc = '=' else: self.mc = '~' - all, any, phrase, none = map(lambda x: unicode_type(x.text()), + all, any, phrase, none = map(lambda x: str(x.text()), (self.all, self.any, self.phrase, self.none)) all, any, none = map(self.tokens, (all, any, none)) phrase = phrase.strip() @@ -96,11 +95,11 @@ class AdvSearchBuilderDialog(QDialog, Ui_Dialog): return ans def token(self): - txt = unicode_type(self.text.text()).strip() + txt = str(self.text.text()).strip() if txt: if self.negate.isChecked(): txt = '!'+txt - tok = self.FIELDS[unicode_type(self.field.currentText())]+txt + tok = self.FIELDS[str(self.field.currentText())]+txt if re.search(r'\s', tok): tok = '"%s"'%tok return tok @@ -116,25 +115,25 @@ class AdvSearchBuilderDialog(QDialog, Ui_Dialog): ans = [] self.box_last_values = {} - name = unicode_type(self.name_box.text()).strip() + name = str(self.name_box.text()).strip() if name: ans.append('name:"' + self.mc + name + '"') - description = unicode_type(self.description_box.text()).strip() + description = str(self.description_box.text()).strip() if description: ans.append('description:"' + self.mc + description + '"') - headquarters = unicode_type(self.headquarters_box.text()).strip() + headquarters = str(self.headquarters_box.text()).strip() if headquarters: ans.append('headquarters:"' + self.mc + headquarters + '"') - format = unicode_type(self.format_box.text()).strip() + format = str(self.format_box.text()).strip() if format: ans.append('format:"' + self.mc + format + '"') - enabled = unicode_type(self.enabled_combo.currentText()).strip() + enabled = str(self.enabled_combo.currentText()).strip() if enabled: ans.append('enabled:' + enabled) - drm = unicode_type(self.drm_combo.currentText()).strip() + drm = str(self.drm_combo.currentText()).strip() if drm: ans.append('drm:' + drm) - affiliate = unicode_type(self.affiliate_combo.currentText()).strip() + affiliate = str(self.affiliate_combo.currentText()).strip() if affiliate: ans.append('affiliate:' + affiliate) if ans: diff --git a/src/calibre/gui2/store/config/chooser/chooser_widget.py b/src/calibre/gui2/store/config/chooser/chooser_widget.py index 14d40cf42d..3bbcb805cb 100644 --- a/src/calibre/gui2/store/config/chooser/chooser_widget.py +++ b/src/calibre/gui2/store/config/chooser/chooser_widget.py @@ -9,7 +9,6 @@ from qt.core import QWidget, QIcon, QDialog, QComboBox, QLineEdit from calibre.gui2.store.config.chooser.adv_search_builder import AdvSearchBuilderDialog from calibre.gui2.store.config.chooser.chooser_widget_ui import Ui_Form -from polyglot.builtins import unicode_type class StoreChooserWidget(QWidget, Ui_Form): @@ -31,7 +30,7 @@ class StoreChooserWidget(QWidget, Ui_Form): self.results_view.activated.connect(self.results_view.model().toggle_plugin) def do_search(self): - self.results_view.model().search(unicode_type(self.query.text())) + self.results_view.model().search(str(self.query.text())) def build_adv_search(self): adv = AdvSearchBuilderDialog(self) diff --git a/src/calibre/gui2/store/config/chooser/models.py b/src/calibre/gui2/store/config/chooser/models.py index f07362e877..3a190099ff 100644 --- a/src/calibre/gui2/store/config/chooser/models.py +++ b/src/calibre/gui2/store/config/chooser/models.py @@ -16,7 +16,6 @@ from calibre.db.search import CONTAINS_MATCH, EQUALS_MATCH, REGEXP_MATCH, _match from calibre.utils.config_base import prefs from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import SearchQueryParser -from polyglot.builtins import range, unicode_type class Delegate(QStyledItemDelegate): @@ -209,7 +208,7 @@ class Matches(QAbstractItemModel): if not self.matches: return descending = order == Qt.SortOrder.DescendingOrder - self.matches.sort(key=lambda x: sort_key(unicode_type(self.data_as_text(x, col))), reverse=descending) + self.matches.sort(key=lambda x: sort_key(str(self.data_as_text(x, col))), reverse=descending) if reset: self.beginResetModel(), self.endResetModel() diff --git a/src/calibre/gui2/store/config/chooser/results_view.py b/src/calibre/gui2/store/config/chooser/results_view.py index 1e53f3d66c..a1b4c0ee8c 100644 --- a/src/calibre/gui2/store/config/chooser/results_view.py +++ b/src/calibre/gui2/store/config/chooser/results_view.py @@ -12,7 +12,6 @@ from qt.core import (Qt, QTreeView, QSize, QMenu) from calibre.customize.ui import store_plugins from calibre.gui2.metadata.single_download import RichTextDelegate from calibre.gui2.store.config.chooser.models import Matches, Delegate -from polyglot.builtins import range class ResultsView(QTreeView): diff --git a/src/calibre/gui2/store/loader.py b/src/calibre/gui2/store/loader.py index a8dd3f147b..2b01dc5405 100644 --- a/src/calibre/gui2/store/loader.py +++ b/src/calibre/gui2/store/loader.py @@ -16,7 +16,7 @@ from calibre.constants import numeric_version, DEBUG from calibre.gui2.store import StorePlugin from calibre.utils.config import JSONConfig from polyglot.urllib import urlencode -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues class VersionMismatch(ValueError): @@ -28,7 +28,7 @@ class VersionMismatch(ValueError): def download_updates(ver_map={}, server='https://code.calibre-ebook.com'): from calibre.utils.https import get_https_resource_securely - data = {k:unicode_type(v) for k, v in iteritems(ver_map)} + data = {k:str(v) for k, v in iteritems(ver_map)} data['ver'] = '1' url = '%s/stores?%s'%(server, urlencode(data)) # We use a timeout here to ensure the non-daemonic update thread does not @@ -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/adv_search_builder.py b/src/calibre/gui2/store/search/adv_search_builder.py index 60b1e44e9d..4412895f74 100644 --- a/src/calibre/gui2/store/search/adv_search_builder.py +++ b/src/calibre/gui2/store/search/adv_search_builder.py @@ -12,7 +12,6 @@ from qt.core import (QDialog, QDialogButtonBox) from calibre.gui2.store.search.adv_search_builder_ui import Ui_Dialog from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import unicode_type class AdvSearchBuilderDialog(QDialog, Ui_Dialog): @@ -84,7 +83,7 @@ class AdvSearchBuilderDialog(QDialog, Ui_Dialog): self.mc = '=' else: self.mc = '~' - all, any, phrase, none = list(map(lambda x: unicode_type(x.text()), + all, any, phrase, none = list(map(lambda x: str(x.text()), (self.all, self.any, self.phrase, self.none))) all, any, none = list(map(self.tokens, (all, any, none))) phrase = phrase.strip() @@ -103,11 +102,11 @@ class AdvSearchBuilderDialog(QDialog, Ui_Dialog): return ans def token(self): - txt = unicode_type(self.text.text()).strip() + txt = str(self.text.text()).strip() if txt: if self.negate.isChecked(): txt = '!'+txt - tok = self.FIELDS[unicode_type(self.field.currentText())]+txt + tok = self.FIELDS[str(self.field.currentText())]+txt if re.search(r'\s', tok): tok = '"%s"'%tok return tok @@ -123,16 +122,16 @@ class AdvSearchBuilderDialog(QDialog, Ui_Dialog): ans = [] self.box_last_values = {} - title = unicode_type(self.title_box.text()).strip() + title = str(self.title_box.text()).strip() if title: ans.append('title:"' + self.mc + title + '"') - author = unicode_type(self.author_box.text()).strip() + author = str(self.author_box.text()).strip() if author: ans.append('author:"' + self.mc + author + '"') - price = unicode_type(self.price_box.text()).strip() + price = str(self.price_box.text()).strip() if price: ans.append('price:"' + self.mc + price + '"') - format = unicode_type(self.format_box.text()).strip() + format = str(self.format_box.text()).strip() if format: ans.append('format:"' + self.mc + format + '"') drm = '' if self.drm_combo.currentIndex() == 0 else 'true' if self.drm_combo.currentIndex() == 1 else 'false' diff --git a/src/calibre/gui2/store/search/download_thread.py b/src/calibre/gui2/store/search/download_thread.py index 9ce8cb1dfa..d10e1e1610 100644 --- a/src/calibre/gui2/store/search/download_thread.py +++ b/src/calibre/gui2/store/search/download_thread.py @@ -12,7 +12,6 @@ from threading import Thread from calibre import browser from calibre.constants import DEBUG from calibre.utils.img import scale_image -from polyglot.builtins import range from polyglot.queue import Queue from polyglot.binary import from_base64_bytes diff --git a/src/calibre/gui2/store/search/models.py b/src/calibre/gui2/store/search/models.py index a4ca73b51f..7e4cbc8fec 100644 --- a/src/calibre/gui2/store/search/models.py +++ b/src/calibre/gui2/store/search/models.py @@ -18,7 +18,6 @@ from calibre.gui2.store.search.download_thread import DetailsThreadPool, \ CoverThreadPool from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import SearchQueryParser -from polyglot.builtins import unicode_type def comparable_price(text): @@ -30,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 @@ -291,7 +290,7 @@ class Matches(QAbstractItemModel): return descending = order == Qt.SortOrder.DescendingOrder self.all_matches.sort( - key=lambda x: sort_key(unicode_type(self.data_as_text(x, col))), + key=lambda x: sort_key(str(self.data_as_text(x, col))), reverse=descending) self.reorder_matches() if reset: diff --git a/src/calibre/gui2/store/search/search.py b/src/calibre/gui2/store/search/search.py index a656ffcfe6..20a013ba18 100644 --- a/src/calibre/gui2/store/search/search.py +++ b/src/calibre/gui2/store/search/search.py @@ -22,7 +22,6 @@ from calibre.gui2.store.search.download_thread import SearchThreadPool, \ CacheUpdateThreadPool from calibre.gui2.store.search.search_ui import Ui_Dialog from calibre.utils.filenames import ascii_filename -from polyglot.builtins import unicode_type class SearchDialog(QDialog, Ui_Dialog): @@ -68,7 +67,7 @@ class SearchDialog(QDialog, Ui_Dialog): self.setup_store_checks() # Set the search query - if isinstance(query, (bytes, unicode_type)): + if isinstance(query, (bytes, str)): self.search_edit.setText(query) elif isinstance(query, dict): if 'author' in query: @@ -186,11 +185,11 @@ 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"' % unicode_type(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"' % unicode_type(self.search_author.text()).replace('"', ' ')) + query.append('author2:"%s"' % str(self.search_author.text()).replace('"', ' ')) if self.search_edit.text(): - query.append(unicode_type(self.search_edit.text())) + query.append(str(self.search_edit.text())) query = " ".join(query) if not query.strip(): error_dialog(self, _('No query'), @@ -412,7 +411,7 @@ class SearchDialog(QDialog, Ui_Dialog): self.searching = False else: self.searching = True - if unicode_type(self.search.text()) != self.STOP_TEXT: + if str(self.search.text()) != self.STOP_TEXT: self.search.setText(self.STOP_TEXT) if not self.pi.isAnimated(): self.pi.startAnimation() @@ -436,7 +435,7 @@ class SearchDialog(QDialog, Ui_Dialog): self.save_state() def exec_(self): - if unicode_type(self.search_edit.text()).strip() or unicode_type(self.search_title.text()).strip() or unicode_type(self.search_author.text()).strip(): + if str(self.search_edit.text()).strip() or str(self.search_title.text()).strip() or str(self.search_author.text()).strip(): self.do_search() return QDialog.exec_(self) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index 5475239e25..210331f707 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -28,7 +28,7 @@ from calibre.utils.icu import ( strcmp ) from calibre.utils.serialize import json_dumps, json_loads -from polyglot.builtins import iteritems, itervalues, map, range, unicode_type +from polyglot.builtins import iteritems, itervalues TAG_SEARCH_STATES = {'clear': 0, 'mark_plus': 1, 'mark_plusplus': 2, 'mark_minus': 3, 'mark_minusminus': 4} @@ -199,7 +199,7 @@ class TagTreeItem: # {{{ else: name = tag.name if role == Qt.ItemDataRole.DisplayRole: - return unicode_type(name) + return str(name) if role == Qt.ItemDataRole.EditRole: return (tag.original_name) if role == Qt.ItemDataRole.DecorationRole: @@ -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 @@ -841,7 +841,7 @@ class TagsModel(QAbstractItemModel): # {{{ return ans def dropMimeData(self, md, action, row, column, parent): - fmts = {unicode_type(x) for x in md.formats()} + fmts = {str(x) for x in md.formats()} if not fmts.intersection(set(self.mimeTypes())): return False if "application/calibre+from_library" in fmts: @@ -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' @@ -1230,7 +1230,7 @@ class TagsModel(QAbstractItemModel): # {{{ # set up to reposition at the same item. We can do this except if # working with the last item and that item is deleted, in which case # we position at the parent label - val = unicode_type(value or '').strip() + val = str(value or '').strip() if not val: return self.show_error_after_event_loop_tick(_('Item is blank'), _('An item cannot be set to nothing. Delete it instead.')) @@ -1291,7 +1291,7 @@ class TagsModel(QAbstractItemModel): # {{{ return self.show_error_after_event_loop_tick( _('Duplicate search name'), _('The saved search name %s is already used.')%val) self.use_position_based_index_on_next_recount = True - self.db.saved_search_rename(unicode_type(item.data(role) or ''), val) + self.db.saved_search_rename(str(item.data(role) or ''), val) item.tag.name = val self.search_item_renamed.emit() # Does a refresh else: diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py index 8670121000..6c6b65b2f5 100644 --- a/src/calibre/gui2/tag_browser/ui.py +++ b/src/calibre/gui2/tag_browser/ui.py @@ -22,7 +22,7 @@ from calibre.ebooks.metadata import title_sort from calibre.gui2.dialogs.tag_categories import TagCategories from calibre.gui2.dialogs.tag_list_editor import TagListEditor from calibre.gui2.dialogs.edit_authors_dialog import EditAuthorsDialog -from polyglot.builtins import unicode_type, iteritems +from polyglot.builtins import iteritems class TagBrowserMixin: # {{{ @@ -125,7 +125,7 @@ class TagBrowserMixin: # {{{ if new_cat not in user_cats: break i += 1 - n = new_name + unicode_type(i) + n = new_name + str(i) # Add the new category user_cats[new_cat] = [] db.new_api.set_pref('user_categories', user_cats) @@ -282,7 +282,7 @@ class TagBrowserMixin: # {{{ m.delete_item_from_all_user_categories(orig_name[item], category) for old_id in to_rename: m.rename_item_in_all_user_categories(orig_name[old_id], - category, unicode_type(to_rename[old_id])) + category, str(to_rename[old_id])) db.new_api.remove_items(category, to_delete) db.new_api.rename_items(category, to_rename, change_index=False) @@ -791,7 +791,7 @@ class TagBrowserWidget(QFrame): # {{{ @property def find_text(self): - return unicode_type(self.item_search.currentText()).strip() + return str(self.item_search.currentText()).strip() def reset_find(self): model = self.tags_view.model() diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index ecbe116d69..4ecd29ed14 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -26,7 +26,6 @@ from calibre.gui2 import (config, gprefs, choose_files, pixmap_to_data, rating_font, empty_index, question_dialog) from calibre.utils.icu import sort_key from calibre.utils.serialize import json_loads -from polyglot.builtins import unicode_type, range, zip class TagDelegate(QStyledItemDelegate): # {{{ @@ -81,7 +80,7 @@ class TagDelegate(QStyledItemDelegate): # {{{ is_search = (True if item.type == TagTreeItem.TAG and item.tag.category == 'search' else False) if not is_search and (hover or gprefs['tag_browser_show_counts']): - count = unicode_type(index.data(COUNT_ROLE)) + count = str(index.data(COUNT_ROLE)) width = painter.fontMetrics().boundingRect(count).width() r = QRect(tr) r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4) @@ -244,7 +243,7 @@ class TagsView(QTreeView): # {{{ border: 1px solid #bfcde4; border-radius: 6px; } - '''.replace('PAD', unicode_type(gprefs['tag_browser_item_padding'])) + ( + '''.replace('PAD', str(gprefs['tag_browser_item_padding'])) + ( '' if gprefs['tag_browser_old_look'] else stylish_tb)) def set_look_and_feel(self, first=False): @@ -526,7 +525,7 @@ class TagsView(QTreeView): # {{{ with open(os.path.join(d, 'icon_' + sanitize_file_name(key)+'.png'), 'wb') as f: f.write(pixmap_to_data(p, format='PNG')) path = os.path.basename(f.name) - self._model.set_custom_category_icon(key, unicode_type(path)) + self._model.set_custom_category_icon(key, str(path)) self.recount() except: traceback.print_exc() @@ -726,7 +725,7 @@ class TagsView(QTreeView): # {{{ if not item.category_key.startswith('@'): while item.parent != self._model.root_item: item = item.parent - category = unicode_type(item.name or '') + category = str(item.name or '') key = item.category_key # Verify that we are working with a field that we know something about if key not in self.db.field_metadata: diff --git a/src/calibre/gui2/tag_mapper.py b/src/calibre/gui2/tag_mapper.py index f589124e7c..5d35351c53 100644 --- a/src/calibre/gui2/tag_mapper.py +++ b/src/calibre/gui2/tag_mapper.py @@ -18,7 +18,7 @@ from calibre.gui2.ui import get_gui from calibre.gui2.widgets2 import Dialog from calibre.utils.config import JSONConfig from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import iteritems, unicode_type, range, filter +from polyglot.builtins import iteritems tag_maps = JSONConfig('tag-map-rules') @@ -171,14 +171,14 @@ class RuleEdit(QWidget): def rule(self, rule): def sc(name): c = getattr(self, name) - idx = c.findData(unicode_type(rule.get(name, ''))) + idx = c.findData(str(rule.get(name, ''))) if idx < 0: idx = 0 c.setCurrentIndex(idx) sc('action'), sc('match_type') ac = self.action.currentData() - self.query.setText(intelligent_strip(ac, unicode_type(rule.get('query', '')))) - self.replace.setText(intelligent_strip(ac, unicode_type(rule.get('replace', '')))) + self.query.setText(intelligent_strip(ac, str(rule.get('query', '')))) + self.replace.setText(intelligent_strip(ac, str(rule.get('replace', '')))) def validate(self): rule = self.rule diff --git a/src/calibre/gui2/toc/location.py b/src/calibre/gui2/toc/location.py index 91e880e481..a8076443d8 100644 --- a/src/calibre/gui2/toc/location.py +++ b/src/calibre/gui2/toc/location.py @@ -15,7 +15,6 @@ from calibre.gui2.palette import dark_color, dark_link_color, dark_text_color from calibre.gui2.webengine import secure_webengine from calibre.utils.logging import default_log from calibre.utils.short_uuid import uuid4 -from polyglot.builtins import range, unicode_type class Page(QWebEnginePage): # {{{ @@ -26,7 +25,7 @@ class Page(QWebEnginePage): # {{{ def __init__(self, prefs): self.log = default_log self.current_frag = None - self.com_id = unicode_type(uuid4()) + self.com_id = str(uuid4()) QWebEnginePage.__init__(self) secure_webengine(self.settings(), for_viewer=True) self.titleChanged.connect(self.title_changed) @@ -57,10 +56,10 @@ class Page(QWebEnginePage): # {{{ self.scripts().insert(s) def javaScriptConsoleMessage(self, level, msg, lineno, msgid): - self.log('JS:', unicode_type(msg)) + self.log('JS:', str(msg)) def javaScriptAlert(self, origin, msg): - self.log(unicode_type(msg)) + self.log(str(msg)) def title_changed(self, title): parts = title.split('-', 1) @@ -81,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) @@ -207,10 +206,10 @@ 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 = unicode_type(self.search_text.text()).strip() + text = str(self.search_text.text()).strip() flags = QWebEnginePage.FindFlags(0) if forwards else QWebEnginePage.FindFlag.FindBackward self.find_data = text, flags, forwards self.view.findText(text, flags, self.find_callback) @@ -224,9 +223,9 @@ class ItemEdit(QWidget): _('No match found for: %s')%text, show=True) delta = 1 if forwards else -1 - current = unicode_type(d.currentItem().data(Qt.ItemDataRole.DisplayRole) or '') + current = str(d.currentItem().data(Qt.ItemDataRole.DisplayRole) or '') next_index = (d.currentRow() + delta)%d.count() - next = unicode_type(d.item(next_index).data(Qt.ItemDataRole.DisplayRole) or '') + next = str(d.item(next_index).data(Qt.ItemDataRole.DisplayRole) or '') msg = '

    '+_('No matches for %(text)s found in the current file [%(current)s].' ' Do you want to search in the %(which)s file [%(next)s]?') msg = msg%dict(text=text, current=current, next=next, @@ -249,7 +248,7 @@ class ItemEdit(QWidget): self.dest_list.addItems(spine_names) def current_changed(self, item): - name = self.current_name = unicode_type(item.data(Qt.ItemDataRole.DisplayRole) or '') + name = self.current_name = str(item.data(Qt.ItemDataRole.DisplayRole) or '') path = self.container.name_to_abspath(name) # Ensure encoding map is populated root = self.container.parsed(name) @@ -281,7 +280,7 @@ class ItemEdit(QWidget): if toc.dest: for i in range(self.dest_list.count()): litem = self.dest_list.item(i) - if unicode_type(litem.data(Qt.ItemDataRole.DisplayRole) or '') == toc.dest: + if str(litem.data(Qt.ItemDataRole.DisplayRole) or '') == toc.dest: dest_index = i frag = toc.frag break diff --git a/src/calibre/gui2/toc/main.py b/src/calibre/gui2/toc/main.py index 980f8ec635..55b4d7d348 100644 --- a/src/calibre/gui2/toc/main.py +++ b/src/calibre/gui2/toc/main.py @@ -33,7 +33,6 @@ from calibre.ptempfile import reset_base_dir from calibre.utils.config import JSONConfig from calibre.utils.filenames import atomic_rename from calibre.utils.logging import GUILog -from polyglot.builtins import map, range, unicode_type ICON_SIZE = 24 @@ -86,11 +85,11 @@ class XPathDialog(QDialog): # {{{ name, ok = QInputDialog.getText(self, _('Choose name'), _('Choose a name for these settings')) if ok: - name = unicode_type(name).strip() + name = str(name).strip() if name: saved = self.prefs.get('xpath_toc_settings', {}) # in JSON all keys have to be strings - saved[name] = {unicode_type(i):x for i, x in enumerate(xpaths)} + saved[name] = {str(i):x for i, x in enumerate(xpaths)} self.prefs.set('xpath_toc_settings', saved) self.setup_load_button() @@ -113,7 +112,7 @@ class XPathDialog(QDialog): # {{{ def load_settings(self, name): saved = self.prefs.get('xpath_toc_settings', {}).get(name, {}) for i, w in enumerate(self.widgets): - txt = saved.get(unicode_type(i), '') + txt = saved.get(str(i), '') w.edit.setText(txt) def check(self): @@ -128,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): @@ -357,7 +356,7 @@ class ItemView(QStackedWidget): # {{{ def populate_item_pane(self): item = self.current_item - name = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + name = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') self.item_pane.heading.setText('

    %s

    '%name) self.icon_label.setPixmap(item.data(0, Qt.ItemDataRole.DecorationRole ).pixmap(32, 32)) @@ -424,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) @@ -476,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 @@ -601,33 +599,33 @@ class TreeWidget(QTreeWidget): # {{{ self.push_history() from calibre.utils.titlecase import titlecase for item in self.selectedItems(): - t = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + t = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') item.setData(0, Qt.ItemDataRole.DisplayRole, titlecase(t)) def upper_case(self): self.push_history() for item in self.selectedItems(): - t = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + t = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') item.setData(0, Qt.ItemDataRole.DisplayRole, icu_upper(t)) def lower_case(self): self.push_history() for item in self.selectedItems(): - t = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + t = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') item.setData(0, Qt.ItemDataRole.DisplayRole, icu_lower(t)) def swap_case(self): self.push_history() from calibre.utils.icu import swapcase for item in self.selectedItems(): - t = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + t = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') item.setData(0, Qt.ItemDataRole.DisplayRole, swapcase(t)) def capitalize(self): self.push_history() from calibre.utils.icu import capitalize for item in self.selectedItems(): - t = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + t = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') item.setData(0, Qt.ItemDataRole.DisplayRole, capitalize(t)) def bulk_rename(self): @@ -659,13 +657,13 @@ 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() def key(k): - sc = unicode_type(QKeySequence(k | Qt.Modifier.CTRL).toString(QKeySequence.SequenceFormat.NativeText)) + sc = str(QKeySequence(k | Qt.Modifier.CTRL).toString(QKeySequence.SequenceFormat.NativeText)) return ' [%s]'%sc if item is not None: @@ -674,7 +672,7 @@ class TreeWidget(QTreeWidget): # {{{ m.addAction(QIcon(I('modified.png')), _('Bulk rename all selected items'), self.bulk_rename) m.addAction(QIcon(I('trash.png')), _('Remove all selected items'), self.del_items) m.addSeparator() - ci = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + ci = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') p = item.parent() or self.invisibleRootItem() idx = p.indexOfChild(item) if idx > 0: @@ -775,12 +773,12 @@ class TOCView(QWidget): # {{{ def event(self, e): if e.type() == QEvent.Type.StatusTip: - txt = unicode_type(e.tip()) or self.default_msg + 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 unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '') + return str(item.data(0, Qt.ItemDataRole.DisplayRole) or '') def del_items(self): self.tocw.del_items() @@ -793,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() @@ -835,7 +832,7 @@ class TOCView(QWidget): # {{{ def data_changed(self, top_left, bottom_right): for r in range(top_left.row(), bottom_right.row()+1): idx = self.tocw.model().index(r, 0, top_left.parent()) - new_title = unicode_type(idx.data(Qt.ItemDataRole.DisplayRole) or '').strip() + new_title = str(idx.data(Qt.ItemDataRole.DisplayRole) or '').strip() toc = idx.data(Qt.ItemDataRole.UserRole) if toc is not None: toc.title = new_title or _('(Untitled)') @@ -927,7 +924,7 @@ class TOCView(QWidget): # {{{ def process_node(parent, toc_parent): for i in range(parent.childCount()): item = parent.child(i) - title = unicode_type(item.data(0, Qt.ItemDataRole.DisplayRole) or '').strip() + title = str(item.data(0, Qt.ItemDataRole.DisplayRole) or '').strip() toc = item.data(0, Qt.ItemDataRole.UserRole) dest, frag = toc.dest, toc.frag toc = toc_parent.add(title, dest, frag) @@ -1076,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(): @@ -1094,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/tools.py b/src/calibre/gui2/tools.py index d2874a0cea..3612b70f07 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -24,7 +24,7 @@ from calibre.ebooks.conversion.config import ( GuiRecommendations, load_defaults, load_specifics, save_specifics, get_input_format_for_book, NoSupportedInputFormats) from calibre.gui2.convert import bulk_defaults_for_input_format -from polyglot.builtins import unicode_type, as_bytes +from polyglot.builtins import as_bytes def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{ @@ -67,7 +67,7 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{ temp_files = [in_file] try: - dtitle = unicode_type(mi.title) + dtitle = str(mi.title) except: dtitle = repr(mi.title) desc = _('Convert book %(num)d of %(total)d (%(title)s)') % \ @@ -228,7 +228,7 @@ class QueueBulk(QProgressDialog): if x[0] == 'debug_pipeline': lrecs.remove(x) try: - dtitle = unicode_type(mi.title) + dtitle = str(mi.title) except: dtitle = repr(mi.title) if len(dtitle) > 50: diff --git a/src/calibre/gui2/tweak_book/__init__.py b/src/calibre/gui2/tweak_book/__init__.py index 02839b60b6..e9f833c3d8 100644 --- a/src/calibre/gui2/tweak_book/__init__.py +++ b/src/calibre/gui2/tweak_book/__init__.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' import string -from polyglot.builtins import iteritems, map +from polyglot.builtins import iteritems from calibre.utils.config import JSONConfig from calibre.spell.dictionary import Dictionaries, parse_lang_code diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index df4eec4b7d..8992901a44 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -69,9 +69,7 @@ from calibre.utils.config import JSONConfig from calibre.utils.icu import numeric_sort_key from calibre.utils.imghdr import identify from calibre.utils.tdir_in_cache import tdir_in_cache -from polyglot.builtins import ( - as_bytes, iteritems, itervalues, map, string_or_bytes, unicode_type -) +from polyglot.builtins import as_bytes, iteritems, itervalues, string_or_bytes from polyglot.urllib import urlparse _diff_dialogs = [] @@ -390,7 +388,7 @@ class Boss(QObject): import traceback traceback.print_exc() if ef: - if isinstance(ef, unicode_type): + if isinstance(ef, str): ef = [ef] tuple(map(self.gui.file_list.request_edit, ef)) else: @@ -1445,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/char_select.py b/src/calibre/gui2/tweak_book/char_select.py index 8210a7a012..3cfebad1f2 100644 --- a/src/calibre/gui2/tweak_book/char_select.py +++ b/src/calibre/gui2/tweak_book/char_select.py @@ -22,7 +22,6 @@ from calibre.gui2.widgets2 import HistoryLineEdit2 from calibre.utils.icu import safe_chr as codepoint_to_chr from calibre.utils.unicode_names import character_name_from_code, points_for_word from calibre_extensions.progress_indicator import set_no_activate_on_click -from polyglot.builtins import map, range, unicode_type ROOT = QModelIndex() @@ -519,7 +518,7 @@ class CharModel(QAbstractListModel): return ['application/calibre_charcode_indices'] def mimeData(self, indexes): - data = ','.join(unicode_type(i.row()) for i in indexes) + data = ','.join(str(i.row()) for i in indexes) md = QMimeData() md.setData('application/calibre_charcode_indices', data.encode('utf-8')) return md @@ -763,7 +762,7 @@ class CharSelect(Dialog): self.char_view.setFocus(Qt.FocusReason.OtherFocusReason) def do_search(self): - text = unicode_type(self.search.text()).strip() + text = str(self.search.text()).strip() if not text: return self.clear_search() with BusyCursor(): diff --git a/src/calibre/gui2/tweak_book/check.py b/src/calibre/gui2/tweak_book/check.py index 1821af5fff..eef84f7768 100644 --- a/src/calibre/gui2/tweak_book/check.py +++ b/src/calibre/gui2/tweak_book/check.py @@ -17,7 +17,6 @@ from calibre.ebooks.oeb.polish.check.main import run_checks, fix_errors from calibre.gui2 import NO_URL_FORMATTING, safe_open_url from calibre.gui2.tweak_book import tprefs from calibre.gui2.tweak_book.widgets import BusyCursor -from polyglot.builtins import unicode_type, range def icon_for_level(level): @@ -49,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) @@ -101,7 +100,7 @@ class Check(QSplitter): def copy_to_clipboard(self): items = [] for item in (self.items.item(i) for i in range(self.items.count())): - msg = unicode_type(item.text()) + msg = str(item.text()) msg = prefix_for_level(item.data(Qt.ItemDataRole.UserRole).level) + msg items.append(msg) if items: @@ -117,7 +116,7 @@ class Check(QSplitter): msg, _('Click to run a check on the book'), _('Run check'))) def link_clicked(self, url): - url = unicode_type(url.toString(NO_URL_FORMATTING)) + url = str(url.toString(NO_URL_FORMATTING)) if url == 'activate:item': self.current_item_activated() elif url == 'run:check': @@ -245,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/completion/basic.py b/src/calibre/gui2/tweak_book/completion/basic.py index a0df293ee9..953e041179 100644 --- a/src/calibre/gui2/tweak_book/completion/basic.py +++ b/src/calibre/gui2/tweak_book/completion/basic.py @@ -20,7 +20,7 @@ from calibre.gui2.tweak_book.completion.utils import control, data, DataError from calibre.utils.ipc import eintr_retry_call from calibre.utils.matcher import Matcher from calibre.utils.icu import numeric_sort_key -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues Request = namedtuple('Request', 'id type data query') @@ -66,10 +66,10 @@ def get_data(data_conn, data_type, data=None): return result -class Name(unicode_type): +class Name(str): def __new__(self, name, mime_type, spine_names): - ans = unicode_type.__new__(self, name) + ans = str.__new__(self, name) ans.mime_type = mime_type ans.in_spine = name in spine_names return ans @@ -112,7 +112,7 @@ def create_anchor_map(root): def complete_anchor(name, data_conn): if name not in file_cache: data = raw = get_data(data_conn, 'file_data', name) - if isinstance(raw, unicode_type): + if isinstance(raw, str): try: root = parse(raw, decoder=lambda x:x.decode('utf-8')) except Exception: diff --git a/src/calibre/gui2/tweak_book/completion/utils.py b/src/calibre/gui2/tweak_book/completion/utils.py index 6270a5a6a5..d071fb8fb4 100644 --- a/src/calibre/gui2/tweak_book/completion/utils.py +++ b/src/calibre/gui2/tweak_book/completion/utils.py @@ -2,7 +2,6 @@ # vim:fileencoding=utf-8 -from polyglot.builtins import unicode_type __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' @@ -25,4 +24,4 @@ class DataError(Exception): self.tb = tb def traceback(self): - return unicode_type(self) + '\n' + self.tb + return str(self) + '\n' + self.tb diff --git a/src/calibre/gui2/tweak_book/diff/highlight.py b/src/calibre/gui2/tweak_book/diff/highlight.py index bd4ea28e28..b3cd49051b 100644 --- a/src/calibre/gui2/tweak_book/diff/highlight.py +++ b/src/calibre/gui2/tweak_book/diff/highlight.py @@ -13,7 +13,7 @@ from calibre.gui2.tweak_book import tprefs from calibre.gui2.tweak_book.editor.text import get_highlighter as calibre_highlighter, SyntaxHighlighter from calibre.gui2.tweak_book.editor.themes import get_theme, highlight_to_char_format from calibre.gui2.tweak_book.editor.syntax.utils import format_for_pygments_token, NULL_FMT -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems class QtHighlighter(QTextDocument): diff --git a/src/calibre/gui2/tweak_book/diff/main.py b/src/calibre/gui2/tweak_book/diff/main.py index 437eb98e39..5d6ae1a223 100644 --- a/src/calibre/gui2/tweak_book/diff/main.py +++ b/src/calibre/gui2/tweak_book/diff/main.py @@ -23,7 +23,7 @@ from calibre.gui2.tweak_book.widgets import Dialog from calibre.gui2.widgets2 import HistoryLineEdit2 from calibre.utils.filenames import samefile from calibre.utils.icu import numeric_sort_key -from polyglot.builtins import iteritems, unicode_type, map +from polyglot.builtins import iteritems class BusyWidget(QWidget): # {{{ @@ -131,7 +131,7 @@ def get_decoded_raw(name): def string_diff(left, right, left_syntax=None, right_syntax=None, left_name='left', right_name='right'): - left, right = unicode_type(left), unicode_type(right) + left, right = str(left), str(right) cache = Cache() cache.set_left(left_name, left), cache.set_right(right_name, right) changed_names = {} if left == right else {left_name:right_name} @@ -324,7 +324,7 @@ class Diff(Dialog): pass def do_search(self, reverse): - text = unicode_type(self.search.text()) + text = str(self.search.text()) if not text.strip(): return v = self.view.view.left if self.lb.isChecked() else self.view.view.right diff --git a/src/calibre/gui2/tweak_book/diff/view.py b/src/calibre/gui2/tweak_book/diff/view.py index 723fc724ed..007e843830 100644 --- a/src/calibre/gui2/tweak_book/diff/view.py +++ b/src/calibre/gui2/tweak_book/diff/view.py @@ -28,7 +28,7 @@ from calibre.gui2.tweak_book.editor.text import ( from calibre.gui2.tweak_book.editor.themes import get_theme, theme_color from calibre.utils.icu import utf16_length from calibre.utils.xml_parse import safe_xml_fromstring -from polyglot.builtins import as_bytes, iteritems, map, range, unicode_type, zip +from polyglot.builtins import as_bytes, iteritems Change = namedtuple('Change', 'ltop lbot rtop rbot kind') @@ -81,7 +81,7 @@ class LineNumberMap(dict): # {{{ return self def __setitem__(self, k, v): - v = unicode_type(v) + v = str(v) dict.__setitem__(self, k, v) self.max_width = max(self.max_width, len(v)) @@ -162,13 +162,13 @@ class TextBrowser(PlainTextEdit): # {{{ def calculate_metrics(self): w = self.fontMetrics() - self.number_width = max(map(lambda x:w.width(unicode_type(x)), range(10))) + self.number_width = max(map(lambda x:w.width(str(x)), range(10))) self.space_width = w.width(' ') def show_context_menu(self, pos): m = QMenu(self) a = m.addAction - i = unicode_type(self.textCursor().selectedText()).rstrip('\0') + i = str(self.textCursor().selectedText()).rstrip('\0') if i: a(QIcon(I('edit-copy.png')), _('Copy to clipboard'), self.copy).setShortcut(QKeySequence.StandardKey.Copy) @@ -217,7 +217,7 @@ class TextBrowser(PlainTextEdit): # {{{ headers = dict(self.headers) if lnum in headers: cpos = self.search_header_pos - lines = unicode_type(self.toPlainText()).splitlines() + lines = str(self.toPlainText()).splitlines() for hn, text in self.headers: lines[hn] = text prefix, postfix = lines[lnum][:cpos], lines[lnum][cpos:] @@ -308,7 +308,7 @@ class TextBrowser(PlainTextEdit): # {{{ while block.isValid() and top <= ev.rect().bottom(): r = ev.rect() if block.isVisible() and bottom >= r.top(): - text = unicode_type(self.line_number_map.get(num, '')) + text = str(self.line_number_map.get(num, '')) is_start = text != '-' and num in change_starts if is_start: painter.save() @@ -531,7 +531,7 @@ class DiffSplit(QSplitter): # {{{ def add_diff(self, left_name, right_name, left_text, right_text, context=None, syntax=None, beautify=False): left_text, right_text = left_text or '', right_text or '' is_identical = len(left_text) == len(right_text) and left_text == right_text and left_name == right_name - is_text = isinstance(left_text, unicode_type) and isinstance(right_text, unicode_type) + is_text = isinstance(left_text, str) and isinstance(right_text, str) left_name = left_name or '[%s]'%_('This file was added') right_name = right_name or '[%s]'%_('This file was removed') self.left.headers.append((self.left.blockCount() - 1, left_name)) diff --git a/src/calibre/gui2/tweak_book/download.py b/src/calibre/gui2/tweak_book/download.py index e326bc9c3c..6b0c8e17fe 100644 --- a/src/calibre/gui2/tweak_book/download.py +++ b/src/calibre/gui2/tweak_book/download.py @@ -14,7 +14,7 @@ from calibre.gui2.tweak_book import current_container from calibre.gui2.tweak_book.widgets import Dialog from calibre.gui2.progress_indicator import WaitStack from calibre.ebooks.oeb.polish.download import get_external_resources, download_external_resources, replace_resources -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems class ChooseResources(QWidget): 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 6901b1aee8..2c6762d425 100644 --- a/src/calibre/gui2/tweak_book/editor/insert_resource.py +++ b/src/calibre/gui2/tweak_book/editor/insert_resource.py @@ -27,7 +27,6 @@ from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.icu import numeric_sort_key from calibre.utils.localization import canonicalize_lang, get_lang from calibre_extensions.progress_indicator import set_no_activate_on_click -from polyglot.builtins import unicode_type class ChooseName(Dialog): # {{{ @@ -59,16 +58,16 @@ class ChooseName(Dialog): # {{{ return False def verify(self): - return name_is_ok(unicode_type(self.name_edit.text()), self.show_error) + return name_is_ok(str(self.name_edit.text()), self.show_error) def accept(self): if not self.verify(): return error_dialog(self, _('No name specified'), _( 'You must specify a file name for the new file, with an extension.'), show=True) - n = unicode_type(self.name_edit.text()).replace('\\', '/') + 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 {{{ @@ -79,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() @@ -111,7 +110,7 @@ class ImageDelegate(QStyledItemDelegate): def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, empty_index) # draw the hover and selection highlights - name = unicode_type(index.data(Qt.ItemDataRole.DisplayRole) or '') + name = str(index.data(Qt.ItemDataRole.DisplayRole) or '') cover = self.cover_cache.get(name, None) if cover is None: cover = self.cover_cache[name] = QPixmap() @@ -338,16 +337,16 @@ class InsertImage(Dialog): def activated(self, index): if self.for_browsing: - return self.image_activated.emit(unicode_type(index.data() or '')) + return self.image_activated.emit(str(index.data() or '')) self.chosen_image_is_external = False self.accept() def accept(self): - self.chosen_image = unicode_type(self.view.currentIndex().data() or '') - super(InsertImage, self).accept() + self.chosen_image = str(self.view.currentIndex().data() or '') + super().accept() def filter_changed(self, *args): - f = unicode_type(self.filter.text()) + f = str(self.filter.text()) self.fm.setFilterFixedString(f) # }}} @@ -416,8 +415,8 @@ class ChooseFolder(Dialog): # {{{ def create_folder(self, item): text, ok = QInputDialog.getText(self, _('Folder name'), _('Enter a name for the new folder')) - if ok and unicode_type(text): - c = QTreeWidgetItem(item, (unicode_type(text),)) + if ok and str(text): + c = QTreeWidgetItem(item, (str(text),)) c.setIcon(0, QIcon(I('mimetypes/dir.png'))) for item in self.folders.selectedItems(): item.setSelected(False) @@ -427,7 +426,7 @@ class ChooseFolder(Dialog): # {{{ def folder_path(self, item): ans = [] while item is not self.root: - ans.append(unicode_type(item.text(0))) + ans.append(str(item.text(0))) item = item.parent() return tuple(reversed(ans)) @@ -476,15 +475,15 @@ class NewBook(Dialog): # {{{ def accept(self): with tprefs: - tprefs.set('previous_new_book_authors', unicode_type(self.authors.text())) + 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): - mi = Metadata(unicode_type(self.title.text()).strip() or _('Unknown')) - mi.authors = string_to_authors(unicode_type(self.authors.text()).strip()) or [_('Unknown')] + mi = Metadata(str(self.title.text()).strip() or _('Unknown')) + mi.authors = string_to_authors(str(self.authors.text()).strip()) or [_('Unknown')] mi.languages = self.languages.lang_codes or [get_lang()] return mi diff --git a/src/calibre/gui2/tweak_book/editor/smarts/html.py b/src/calibre/gui2/tweak_book/editor/smarts/html.py index a5f72dd05f..0be8661bf1 100644 --- a/src/calibre/gui2/tweak_book/editor/smarts/html.py +++ b/src/calibre/gui2/tweak_book/editor/smarts/html.py @@ -27,7 +27,6 @@ from calibre.gui2.tweak_book.editor.syntax.html import ( ATTR_END, ATTR_NAME, ATTR_START, ATTR_VALUE ) from calibre.utils.icu import utf16_length -from polyglot.builtins import unicode_type get_offset = itemgetter(0) PARAGRAPH_SEPARATOR = '\u2029' @@ -354,10 +353,10 @@ class Smarts(NullSmarts): a = QTextEdit.ExtraSelection() a.cursor, a.format = editor.textCursor(), editor.match_paren_format a.cursor.setPosition(tag.start_block.position()), a.cursor.movePosition(QTextCursor.MoveOperation.EndOfBlock, QTextCursor.MoveMode.KeepAnchor) - text = unicode_type(a.cursor.selectedText()) + text = str(a.cursor.selectedText()) start_pos = utf16_length(text[:tag.start_offset]) a.cursor.setPosition(tag.end_block.position()), a.cursor.movePosition(QTextCursor.MoveOperation.EndOfBlock, QTextCursor.MoveMode.KeepAnchor) - text = unicode_type(a.cursor.selectedText()) + text = str(a.cursor.selectedText()) end_pos = utf16_length(text[:tag.end_offset + 1]) a.cursor.setPosition(tag.start_block.position() + start_pos) a.cursor.setPosition(tag.end_block.position() + end_pos, QTextCursor.MoveMode.KeepAnchor) @@ -503,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/snippets.py b/src/calibre/gui2/tweak_book/editor/snippets.py index d23030b755..b008fb0298 100644 --- a/src/calibre/gui2/tweak_book/editor/snippets.py +++ b/src/calibre/gui2/tweak_book/editor/snippets.py @@ -25,11 +25,9 @@ from calibre.gui2.tweak_book.widgets import Dialog, PlainTextEdit from calibre.utils.config import JSONConfig from calibre.utils.icu import string_length as strlen from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import ( - codepoint_to_chr, iteritems, itervalues, range, unicode_type -) +from polyglot.builtins import codepoint_to_chr, iteritems, itervalues -string_length = lambda x: strlen(unicode_type(x)) # Needed on narrow python builds, as subclasses of unicode dont work +string_length = lambda x: strlen(str(x)) # Needed on narrow python builds, as subclasses of unicode dont work KEY = Qt.Key.Key_J MODIFIER = Qt.Modifier.META if ismacos else Qt.Modifier.CTRL @@ -107,7 +105,7 @@ def escape_funcs(): return escape, unescape -class TabStop(unicode_type): +class TabStop(str): def __new__(self, raw, start_offset, tab_stops, is_toplevel=True): if raw.endswith('}'): @@ -118,7 +116,7 @@ class TabStop(unicode_type): for c in child_stops: c.parent = self tab_stops.extend(child_stops) - self = unicode_type.__new__(self, uraw) + self = str.__new__(self, uraw) if num.endswith('*'): self.takes_selection = True num = num[:-1] @@ -126,7 +124,7 @@ class TabStop(unicode_type): self.takes_selection = False self.num = int(num) else: - self = unicode_type.__new__(self, '') + self = str.__new__(self, '') self.num = int(raw[1:]) self.takes_selection = False self.start = start_offset @@ -138,7 +136,7 @@ class TabStop(unicode_type): def __repr__(self): return 'TabStop(text=%s num=%d start=%d is_mirror=%s takes_selection=%s is_toplevel=%s)' % ( - unicode_type.__repr__(self), self.num, self.start, self.is_mirror, self.takes_selection, self.is_toplevel) + str.__repr__(self), self.num, self.start, self.is_mirror, self.takes_selection, self.is_toplevel) def parse_template(template, start_offset=0, is_toplevel=True, grouped=True): @@ -177,7 +175,7 @@ def snippets(refresh=False): if _snippets is None or refresh: _snippets = copy.deepcopy(builtin_snippets) for snip in user_snippets.get('snippets', []): - if snip['trigger'] and isinstance(snip['trigger'], unicode_type): + if snip['trigger'] and isinstance(snip['trigger'], str): key = snip_key(snip['trigger'], *snip['syntaxes']) _snippets[key] = {'template':snip['template'], 'description':snip['description']} _snippets = sorted(iteritems(_snippets), key=(lambda key_snip:string_length(key_snip[0].trigger)), reverse=True) diff --git a/src/calibre/gui2/tweak_book/editor/syntax/base.py b/src/calibre/gui2/tweak_book/editor/syntax/base.py index ea83678d06..ce0edd6711 100644 --- a/src/calibre/gui2/tweak_book/editor/syntax/base.py +++ b/src/calibre/gui2/tweak_book/editor/syntax/base.py @@ -11,7 +11,7 @@ from qt.core import QTextCursor, QTextBlockUserData, QTextLayout, QTimer from ..themes import highlight_to_char_format from calibre.gui2.tweak_book.widgets import BusyCursor from calibre.utils.icu import utf16_length -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def run_loop(user_data, state_map, formats, text): @@ -215,7 +215,7 @@ class SyntaxHighlighter: start_state = self.user_data_factory().state ud.clear(state=start_state, doc_name=self.doc_name) # Ensure no stale user data lingers formats = [] - for i, num, fmt in run_loop(ud, self.state_map, self.formats, unicode_type(block.text())): + for i, num, fmt in run_loop(ud, self.state_map, self.formats, str(block.text())): if fmt is not None: r = QTextLayout.FormatRange() r.start, r.length, r.format = i, num, fmt 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 d7b9caa812..0e9bac6920 100644 --- a/src/calibre/gui2/tweak_book/editor/text.py +++ b/src/calibre/gui2/tweak_book/editor/text.py @@ -40,7 +40,7 @@ from calibre.utils.icu import ( ) from calibre.utils.img import image_to_data from calibre.utils.titlecase import titlecase -from polyglot.builtins import as_unicode, map, range, unicode_type +from polyglot.builtins import as_unicode def get_highlighter(syntax): @@ -67,7 +67,7 @@ _dff = None def default_font_family(): global _dff if _dff is None: - families = set(map(unicode_type, QFontDatabase().families())) + families = set(map(str, QFontDatabase().families())) for x in ('Ubuntu Mono', 'Consolas', 'Liberation Mono'): if x in families: _dff = x @@ -260,7 +260,7 @@ class TextEdit(PlainTextEdit): self.setFont(font) self.highlighter.apply_theme(theme) w = self.fontMetrics() - self.number_width = max(map(lambda x:w.width(unicode_type(x)), range(10))) + self.number_width = max(map(lambda x:w.width(str(x)), range(10))) self.size_hint = QSize(self.expected_geometry[0] * w.averageCharWidth(), self.expected_geometry[1] * w.height()) self.highlight_color = theme_color(theme, 'HighlightRegion', 'bg') self.highlight_cursor_line() @@ -280,7 +280,7 @@ class TextEdit(PlainTextEdit): self.setTabStopWidth(self.tw * self.space_width) if isinstance(text, bytes): text = text.decode('utf-8', 'replace') - self.setPlainText(unicodedata.normalize('NFC', unicode_type(text))) + self.setPlainText(unicodedata.normalize('NFC', str(text))) if process_template and QPlainTextEdit.find(self, '%CURSOR%'): c = self.textCursor() c.insertText('') @@ -314,7 +314,7 @@ class TextEdit(PlainTextEdit): c.movePosition(QTextCursor.MoveOperation.NextBlock, n=lnum - 1) c.movePosition(QTextCursor.MoveOperation.StartOfLine) c.movePosition(QTextCursor.MoveOperation.EndOfLine, QTextCursor.MoveMode.KeepAnchor) - text = unicode_type(c.selectedText()).rstrip('\0') + text = str(c.selectedText()).rstrip('\0') if col is None: c.movePosition(QTextCursor.MoveOperation.StartOfLine) lt = text.lstrip() @@ -373,7 +373,7 @@ class TextEdit(PlainTextEdit): if wrap: pos = m_end if reverse else m_start c.setPosition(pos, QTextCursor.MoveMode.KeepAnchor) - raw = unicode_type(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') + raw = str(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') m = pat.search(raw) if m is None: return False @@ -406,7 +406,7 @@ class TextEdit(PlainTextEdit): if self.current_search_mark is None: return 0 c = self.current_search_mark.cursor - raw = unicode_type(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') + raw = str(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') if template is None: count = len(pat.findall(raw)) else: @@ -420,7 +420,7 @@ class TextEdit(PlainTextEdit): if getattr(template.func, 'append_final_output_to_marked', False): retval = template.end() if retval: - raw += unicode_type(retval) + raw += str(retval) else: template.end() show_function_debug_output(template) @@ -443,7 +443,7 @@ class TextEdit(PlainTextEdit): c = self.textCursor() c.beginEditBlock() c.movePosition(QTextCursor.MoveOperation.Start), c.movePosition(QTextCursor.MoveOperation.End, QTextCursor.MoveMode.KeepAnchor) - text = unicode_type(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') + text = str(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') from calibre.ebooks.oeb.polish.css import sort_sheet text = css_text(sort_sheet(current_container(), text)) c.insertText(text) @@ -464,7 +464,7 @@ class TextEdit(PlainTextEdit): if wrap and not complete: pos = QTextCursor.MoveOperation.End if reverse else QTextCursor.MoveOperation.Start c.movePosition(pos, QTextCursor.MoveMode.KeepAnchor) - raw = unicode_type(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') + raw = str(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') m = pat.search(raw) if m is None: return False @@ -509,7 +509,7 @@ class TextEdit(PlainTextEdit): if not found: return False else: - raw = unicode_type(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') + raw = str(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') m = pat.search(raw) if m is None: return False @@ -542,7 +542,7 @@ class TextEdit(PlainTextEdit): return match_pos, match_word while True: - text = unicode_type(c.selectedText()).rstrip('\0') + text = str(c.selectedText()).rstrip('\0') idx, word = find_first_word(text) if idx == -1: return False @@ -579,7 +579,7 @@ class TextEdit(PlainTextEdit): def replace(self, pat, template, saved_match='gui'): c = self.textCursor() - raw = unicode_type(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') + raw = str(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0') m = pat.fullmatch(raw) if m is None: # This can happen if either the user changed the selected text or @@ -606,7 +606,7 @@ class TextEdit(PlainTextEdit): self.setTextCursor(c) return True base = r'''%%s\s*=\s*['"]{0,1}%s''' % regex.escape(anchor) - raw = unicode_type(self.toPlainText()) + raw = str(self.toPlainText()) m = regex.search(base % 'id', raw) if m is None: m = regex.search(base % 'name', raw) @@ -685,7 +685,7 @@ class TextEdit(PlainTextEdit): painter.setFont(f) self.last_current_lnum = (top, bottom - top) painter.drawText(0, top, self.line_number_area.width() - 5, self.fontMetrics().height(), - Qt.AlignmentFlag.AlignRight, unicode_type(num + 1)) + Qt.AlignmentFlag.AlignRight, str(num + 1)) if current == num: painter.restore() block = block.next() @@ -751,7 +751,7 @@ class TextEdit(PlainTextEdit): fmt_range = self.syntax_range_for_cursor(c) fmt = getattr(fmt_range, 'format', None) if fmt is not None: - tt = unicode_type(fmt.toolTip()) + tt = str(fmt.toolTip()) if tt: QToolTip.setFont(self.tooltip_font) QToolTip.setPalette(self.tooltip_palette) @@ -830,7 +830,7 @@ class TextEdit(PlainTextEdit): right = max(c.anchor(), c.position()) # For speed we use QPlainTextEdit's toPlainText as we dont care about # spaces in this context - raw = unicode_type(QPlainTextEdit.toPlainText(self)) + raw = str(QPlainTextEdit.toPlainText(self)) # Make sure the left edge is not within a <> gtpos = raw.find('>', left) ltpos = raw.find('<', left) @@ -876,7 +876,7 @@ class TextEdit(PlainTextEdit): c = self.textCursor() c.setPosition(left) c.setPosition(right, QTextCursor.MoveMode.KeepAnchor) - prev_text = unicode_type(c.selectedText()).rstrip('\0') + prev_text = str(c.selectedText()).rstrip('\0') c.insertText(prefix + prev_text + suffix) if prev_text: right = c.position() @@ -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: @@ -983,10 +983,10 @@ version="1.1" width="100%%" height="100%%" viewBox="0 0 {w} {h}" preserveAspectR c = self.textCursor() has_selection = c.hasSelection() if has_selection: - text = unicode_type(c.selectedText()).rstrip('\0') + text = str(c.selectedText()).rstrip('\0') else: c.setPosition(c.position() - min(c.positionInBlock(), 6), QTextCursor.MoveMode.KeepAnchor) - text = unicode_type(c.selectedText()).rstrip('\0') + text = str(c.selectedText()).rstrip('\0') m = re.search(r'[a-fA-F0-9]{2,6}$', text) if m is None: return False @@ -1032,7 +1032,7 @@ version="1.1" width="100%%" height="100%%" viewBox="0 0 {w} {h}" preserveAspectR from calibre.gui2.tweak_book.editor.smarts.css import find_rule block = None if self.syntax == 'css': - raw = unicode_type(self.toPlainText()) + raw = str(self.toPlainText()) line, col = find_rule(raw, rule_address) if line is not None: block = self.document().findBlockByNumber(line - 1) diff --git a/src/calibre/gui2/tweak_book/editor/themes.py b/src/calibre/gui2/tweak_book/editor/themes.py index 0ad80ca500..0cf752f088 100644 --- a/src/calibre/gui2/tweak_book/editor/themes.py +++ b/src/calibre/gui2/tweak_book/editor/themes.py @@ -17,7 +17,7 @@ from calibre.gui2 import error_dialog from calibre.gui2.tweak_book import tprefs from calibre.gui2.tweak_book.editor import syntax_text_char_format from calibre.gui2.tweak_book.widgets import Dialog -from polyglot.builtins import iteritems, unicode_type, range, map +from polyglot.builtins import iteritems underline_styles = {'single', 'dash', 'dot', 'dash_dot', 'dash_dot_dot', 'wave', 'spell'} @@ -346,7 +346,7 @@ class CreateNewTheme(Dialog): @property def theme_name(self): - return unicode_type(self._name.text()).strip() + return str(self._name.text()).strip() def accept(self): if not self.theme_name: @@ -475,7 +475,7 @@ class Property(QWidget): l.addStretch(1) def us_changed(self): - self.data['underline'] = unicode_type(self.underline.currentText()) or None + self.data['underline'] = str(self.underline.currentText()) or None self.changed.emit() # Help text {{{ @@ -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) @@ -619,7 +619,7 @@ class ThemeEditor(Dialog): data[k] = dict(THEMES[default_theme()][k]._asdict()) for nk, nv in iteritems(data[k]): if isinstance(nv, QBrush): - data[k][nk] = unicode_type(nv.color().name()) + data[k][nk] = str(nv.color().name()) if extra or missing: tprefs['custom_themes'][name] = data return data @@ -633,7 +633,7 @@ class ThemeEditor(Dialog): c.setParent(None) c.deleteLater() self.properties = [] - name = unicode_type(self.theme.currentText()) + name = str(self.theme.currentText()) if not name: return data = self.update_theme(name) @@ -650,7 +650,7 @@ class ThemeEditor(Dialog): @property def theme_name(self): - return unicode_type(self.theme.currentText()) + return str(self.theme.currentText()) def changed(self): name = self.theme_name @@ -661,7 +661,7 @@ class ThemeEditor(Dialog): d = CreateNewTheme(self) if d.exec_() == QDialog.DialogCode.Accepted: name = '*' + d.theme_name - base = unicode_type(d.base.currentText()) + base = str(d.base.currentText()) theme = {} for key, val in iteritems(THEMES[base]): theme[key] = {k:col_to_string(v.color()) if isinstance(v, QBrush) else v for k, v in iteritems(val._asdict())} diff --git a/src/calibre/gui2/tweak_book/editor/widget.py b/src/calibre/gui2/tweak_book/editor/widget.py index 417e8de43b..ed027ef013 100644 --- a/src/calibre/gui2/tweak_book/editor/widget.py +++ b/src/calibre/gui2/tweak_book/editor/widget.py @@ -29,7 +29,7 @@ from calibre.gui2.tweak_book.editor import ( from calibre.gui2.tweak_book.editor.help import help_url from calibre.gui2.tweak_book.editor.text import TextEdit from calibre.utils.icu import utf16_length -from polyglot.builtins import itervalues, string_or_bytes, unicode_type +from polyglot.builtins import itervalues, string_or_bytes def create_icon(text, palette=None, sz=None, divider=2, fill='white'): @@ -224,7 +224,7 @@ class Editor(QMainWindow): def get_raw_data(self): # The EPUB spec requires NFC normalization, see section 1.3.6 of # http://www.idpf.org/epub/20/spec/OPS_2.0.1_draft.htm - return unicodedata.normalize('NFC', unicode_type(self.editor.toPlainText()).rstrip('\0')) + return unicodedata.normalize('NFC', str(self.editor.toPlainText()).rstrip('\0')) def replace_data(self, raw, only_if_different=True): if isinstance(raw, bytes): @@ -485,7 +485,7 @@ class Editor(QMainWindow): if not c.atStart(): c.clearSelection() c.movePosition(QTextCursor.MoveOperation.PreviousCharacter, QTextCursor.MoveMode.KeepAnchor) - char = unicode_type(c.selectedText()).rstrip('\0') + char = str(c.selectedText()).rstrip('\0') return (c.blockNumber() + 1, col, char) def cut(self): @@ -509,7 +509,7 @@ class Editor(QMainWindow): def fix_html(self): if self.syntax == 'html': from calibre.ebooks.oeb.polish.pretty import fix_html - self.editor.replace_text(fix_html(current_container(), unicode_type(self.editor.toPlainText())).decode('utf-8')) + self.editor.replace_text(fix_html(current_container(), str(self.editor.toPlainText())).decode('utf-8')) return True return False @@ -519,7 +519,7 @@ class Editor(QMainWindow): ) if self.syntax in {'css', 'html', 'xml'}: func = {'css':pretty_css, 'xml':pretty_xml}.get(self.syntax, pretty_html) - original_text = unicode_type(self.editor.toPlainText()) + original_text = str(self.editor.toPlainText()) prettied_text = func(current_container(), name, original_text).decode('utf-8') if original_text != prettied_text: self.editor.replace_text(prettied_text) diff --git a/src/calibre/gui2/tweak_book/file_list.py b/src/calibre/gui2/tweak_book/file_list.py index e2f4b5d4d3..cff4731669 100644 --- a/src/calibre/gui2/tweak_book/file_list.py +++ b/src/calibre/gui2/tweak_book/file_list.py @@ -40,7 +40,7 @@ from calibre.utils.fonts.utils import get_font_names from calibre.utils.icu import numeric_sort_key from calibre_extensions.progress_indicator import set_no_activate_on_click from polyglot.binary import as_hex_unicode -from polyglot.builtins import filter, iteritems, map, range, unicode_type +from polyglot.builtins import iteritems FILE_COPY_MIME = 'application/calibre-edit-book-files' @@ -107,14 +107,14 @@ def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_na ans = {'prefix': None, 'start': None} if d.exec_() == QDialog.DialogCode.Accepted: - prefix = sanitize(unicode_type(d.prefix.text())) + prefix = sanitize(str(d.prefix.text())) previous[category] = prefix tprefs.set('file-list-bulk-rename-prefix', previous) num = d.num.value() fmt = '%d' if leading_zeros: largest = num + number - 1 - fmt = '%0{0}d'.format(len(unicode_type(largest))) + fmt = '%0{}d'.format(len(str(largest))) ans['prefix'] = prefix + fmt ans['start'] = num if allow_spine_order: @@ -128,7 +128,7 @@ class ItemDelegate(QStyledItemDelegate): # {{{ rename_requested = pyqtSignal(object, object) def setEditorData(self, editor, index): - name = unicode_type(index.data(NAME_ROLE) or '') + name = str(index.data(NAME_ROLE) or '') # We do this because Qt calls selectAll() unconditionally on the # editor, and we want only a part of the file name to be selected QTimer.singleShot(0, partial(self.set_editor_data, name, editor)) @@ -147,8 +147,8 @@ class ItemDelegate(QStyledItemDelegate): # {{{ editor.selectAll() def setModelData(self, editor, model, index): - newname = unicode_type(editor.text()) - oldname = unicode_type(index.data(NAME_ROLE) or '') + newname = str(editor.text()) + oldname = str(index.data(NAME_ROLE) or '') if newname != oldname: self.rename_requested.emit(oldname, newname) @@ -296,13 +296,13 @@ class FileList(QTreeWidget, OpenWithHandler): def current_name(self): ci = self.currentItem() if ci is not None: - return unicode_type(ci.data(0, NAME_ROLE) or '') + return str(ci.data(0, NAME_ROLE) or '') return '' def get_state(self): s = {'pos':self.verticalScrollBar().value()} s['expanded'] = {c for c, item in iteritems(self.categories) if item.isExpanded()} - s['selected'] = {unicode_type(i.data(0, NAME_ROLE) or '') for i in self.selectedItems()} + s['selected'] = {str(i.data(0, NAME_ROLE) or '') for i in self.selectedItems()} return s def set_state(self, state): @@ -311,21 +311,21 @@ class FileList(QTreeWidget, OpenWithHandler): self.verticalScrollBar().setValue(state['pos']) for parent in self.categories.values(): for c in (parent.child(i) for i in range(parent.childCount())): - name = unicode_type(c.data(0, NAME_ROLE) or '') + name = str(c.data(0, NAME_ROLE) or '') if name in state['selected']: c.setSelected(True) def item_from_name(self, name): for parent in self.categories.values(): for c in (parent.child(i) for i in range(parent.childCount())): - q = unicode_type(c.data(0, NAME_ROLE) or '') + q = str(c.data(0, NAME_ROLE) or '') if q == name: return c def select_name(self, name, set_as_current_index=False): for parent in self.categories.values(): for c in (parent.child(i) for i in range(parent.childCount())): - q = unicode_type(c.data(0, NAME_ROLE) or '') + q = str(c.data(0, NAME_ROLE) or '') c.setSelected(q == name) if q == name: self.scrollToItem(c) @@ -335,7 +335,7 @@ class FileList(QTreeWidget, OpenWithHandler): def select_names(self, names, current_name=None): for parent in self.categories.values(): for c in (parent.child(i) for i in range(parent.childCount())): - q = unicode_type(c.data(0, NAME_ROLE) or '') + q = str(c.data(0, NAME_ROLE) or '') c.setSelected(q in names) if q == current_name: self.scrollToItem(c) @@ -592,9 +592,9 @@ class FileList(QTreeWidget, OpenWithHandler): container = current_container() ci = self.currentItem() if ci is not None: - cn = unicode_type(ci.data(0, NAME_ROLE) or '') - mt = unicode_type(ci.data(0, MIME_ROLE) or '') - cat = unicode_type(ci.data(0, CATEGORY_ROLE) or '') + cn = str(ci.data(0, NAME_ROLE) or '') + mt = str(ci.data(0, MIME_ROLE) or '') + cat = str(ci.data(0, CATEGORY_ROLE) or '') n = elided_text(cn.rpartition('/')[-1]) m.addAction(QIcon(I('save.png')), _('Export %s') % n, partial(self.export, cn)) if cn not in container.names_that_must_not_be_changed and cn not in container.names_that_must_not_be_removed and mt not in OEB_FONTS: @@ -630,7 +630,7 @@ class FileList(QTreeWidget, OpenWithHandler): selected_map = defaultdict(list) for item in sel: - selected_map[unicode_type(item.data(0, CATEGORY_ROLE) or '')].append(unicode_type(item.data(0, NAME_ROLE) or '')) + selected_map[str(item.data(0, CATEGORY_ROLE) or '')].append(str(item.data(0, NAME_ROLE) or '')) for items in selected_map.values(): items.sort(key=self.index_of_name) @@ -657,7 +657,7 @@ class FileList(QTreeWidget, OpenWithHandler): for category, parent in iteritems(self.categories): for i in range(parent.childCount()): item = parent.child(i) - if unicode_type(item.data(0, NAME_ROLE) or '') == name: + if str(item.data(0, NAME_ROLE) or '') == name: return (category, i) return (None, -1) @@ -680,7 +680,7 @@ class FileList(QTreeWidget, OpenWithHandler): self.mark_requested.emit(name, 'cover') def mark_as_titlepage(self, name): - first = unicode_type(self.categories['text'].child(0).data(0, NAME_ROLE) or '') == name + first = str(self.categories['text'].child(0).data(0, NAME_ROLE) or '') == name move_to_start = False if not first: move_to_start = question_dialog(self, _('Not first item'), _( @@ -706,7 +706,7 @@ class FileList(QTreeWidget, OpenWithHandler): ' internally. The filenames you see are automatically generated from the' ' internal structures of the original file.') % current_container().book_type.upper(), show=True) return - names = {unicode_type(item.data(0, NAME_ROLE) or '') for item in self.selectedItems()} + names = {str(item.data(0, NAME_ROLE) or '') for item in self.selectedItems()} bad = names & current_container().names_that_must_not_be_changed if bad: error_dialog(self, _('Cannot rename'), @@ -718,7 +718,7 @@ class FileList(QTreeWidget, OpenWithHandler): def request_bulk_rename(self): names = self.request_rename_common() if names is not None: - categories = Counter(unicode_type(item.data(0, CATEGORY_ROLE) or '') for item in self.selectedItems()) + categories = Counter(str(item.data(0, CATEGORY_ROLE) or '') for item in self.selectedItems()) settings = get_bulk_rename_settings(self, len(names), category=categories.most_common(1)[0][0], allow_spine_order=True) fmt, num = settings['prefix'], settings['start'] if fmt is not None: @@ -753,7 +753,7 @@ class FileList(QTreeWidget, OpenWithHandler): @property def selected_names(self): - ans = {unicode_type(item.data(0, NAME_ROLE) or '') for item in self.selectedItems()} + ans = {str(item.data(0, NAME_ROLE) or '') for item in self.selectedItems()} ans.discard('') return ans @@ -772,9 +772,9 @@ class FileList(QTreeWidget, OpenWithHandler): text = self.categories['text'] children = (text.child(i) for i in range(text.childCount())) - spine_removals = [(unicode_type(item.data(0, NAME_ROLE) or ''), item.isSelected()) for item in children] - other_removals = {unicode_type(item.data(0, NAME_ROLE) or '') for item in self.selectedItems() - if unicode_type(item.data(0, CATEGORY_ROLE) or '') != 'text'} + spine_removals = [(str(item.data(0, NAME_ROLE) or ''), item.isSelected()) for item in children] + other_removals = {str(item.data(0, NAME_ROLE) or '') for item in self.selectedItems() + if str(item.data(0, CATEGORY_ROLE) or '') != 'text'} self.delete_requested.emit(spine_removals, other_removals) def delete_done(self, spine_removals, other_removals): @@ -786,7 +786,7 @@ class FileList(QTreeWidget, OpenWithHandler): if category != 'text': for i in range(parent.childCount()): child = parent.child(i) - if unicode_type(child.data(0, NAME_ROLE) or '') in other_removals: + if str(child.data(0, NAME_ROLE) or '') in other_removals: removals.append(child) # The sorting by index is necessary otherwise Qt crashes with recursive @@ -818,12 +818,12 @@ 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 = [] for child in (text.child(i) for i in range(text.childCount())): - name = unicode_type(child.data(0, NAME_ROLE) or '') + name = str(child.data(0, NAME_ROLE) or '') linear = bool(child.data(0, LINEAR_ROLE)) order.append([name, linear]) # Ensure that all non-linear items are at the end, any non-linear @@ -834,14 +834,14 @@ class FileList(QTreeWidget, OpenWithHandler): self.reorder_spine.emit(order) def item_double_clicked(self, item, column): - category = unicode_type(item.data(0, CATEGORY_ROLE) or '') + category = str(item.data(0, CATEGORY_ROLE) or '') if category: self._request_edit(item) def _request_edit(self, item): - category = unicode_type(item.data(0, CATEGORY_ROLE) or '') - mime = unicode_type(item.data(0, MIME_ROLE) or '') - name = unicode_type(item.data(0, NAME_ROLE) or '') + category = str(item.data(0, CATEGORY_ROLE) or '') + mime = str(item.data(0, MIME_ROLE) or '') + name = str(item.data(0, NAME_ROLE) or '') syntax = {'text':'html', 'styles':'css'}.get(category, None) self.edit_file.emit(name, syntax, mime) @@ -860,7 +860,7 @@ class FileList(QTreeWidget, OpenWithHandler): if backwards: items = reversed(tuple(items)) for item in items: - name = unicode_type(item.data(0, NAME_ROLE) or '') + name = str(item.data(0, NAME_ROLE) or '') if seen_current: self._request_edit(item) return True @@ -876,9 +876,9 @@ class FileList(QTreeWidget, OpenWithHandler): def searchable_names(self): ans = {'text':OrderedDict(), 'styles':OrderedDict(), 'selected':OrderedDict(), 'open':OrderedDict()} for item in self.all_files: - category = unicode_type(item.data(0, CATEGORY_ROLE) or '') - mime = unicode_type(item.data(0, MIME_ROLE) or '') - name = unicode_type(item.data(0, NAME_ROLE) or '') + category = str(item.data(0, CATEGORY_ROLE) or '') + mime = str(item.data(0, MIME_ROLE) or '') + name = str(item.data(0, NAME_ROLE) or '') ok = category in {'text', 'styles'} if ok: ans[category][name] = syntax_from_mime(name, mime) @@ -938,7 +938,7 @@ class FileList(QTreeWidget, OpenWithHandler): def link_stylesheets(self, names): s = self.categories['styles'] - sheets = [unicode_type(s.child(i).data(0, NAME_ROLE) or '') for i in range(s.childCount())] + sheets = [str(s.child(i).data(0, NAME_ROLE) or '') for i in range(s.childCount())] if not sheets: return error_dialog(self, _('No stylesheets'), _( 'This book currently has no stylesheets. You must first create a stylesheet' @@ -971,7 +971,7 @@ class FileList(QTreeWidget, OpenWithHandler): l.addWidget(bb) if d.exec_() == QDialog.DialogCode.Accepted: tprefs['remove_existing_links_when_linking_sheets'] = r.isChecked() - sheets = [unicode_type(s.item(il).text()) for il in range(s.count()) if s.item(il).checkState() == Qt.CheckState.Checked] + sheets = [str(s.item(il).text()) for il in range(s.count()) if s.item(il).checkState() == Qt.CheckState.Checked] if sheets: self.link_stylesheets_requested.emit(names, sheets, r.isChecked()) @@ -1037,7 +1037,7 @@ class NewFileDialog(QDialog): # {{{ @property def name_is_ok(self): - return name_is_ok(unicode_type(self.name.text()), self.show_error) + return name_is_ok(str(self.name.text()), self.show_error) def update_ok(self, *args): self.ok_button.setEnabled(self.name_is_ok) @@ -1047,7 +1047,7 @@ class NewFileDialog(QDialog): # {{{ return error_dialog(self, _('No name specified'), _( 'You must specify a name for the new file, with an extension, for example, chapter1.html'), show=True) tprefs['auto_link_stylesheets'] = self.link_css.isChecked() - name = unicode_type(self.name.text()) + name = str(self.name.text()) name, ext = name.rpartition('.')[0::2] name = (name + '.' + ext.lower()).replace('\\', '/') mt = guess_type(name) diff --git a/src/calibre/gui2/tweak_book/function_replace.py b/src/calibre/gui2/tweak_book/function_replace.py index ae5229ac18..7997ed892c 100644 --- a/src/calibre/gui2/tweak_book/function_replace.py +++ b/src/calibre/gui2/tweak_book/function_replace.py @@ -21,14 +21,14 @@ from calibre.utils.config import JSONConfig from calibre.utils.icu import capitalize, upper, lower, swapcase from calibre.utils.titlecase import titlecase from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems from polyglot.io import PolyglotStringIO user_functions = JSONConfig('editor-search-replace-functions') def compile_code(src, name=''): - if not isinstance(src, unicode_type): + if not isinstance(src, str): match = re.search(br'coding[:=]\s*([-\w.]+)', src[:200]) enc = match.group(1).decode('utf-8') if match else 'utf-8' src = src.decode(enc) diff --git a/src/calibre/gui2/tweak_book/manage_fonts.py b/src/calibre/gui2/tweak_book/manage_fonts.py index a962f00279..cfbdd201ae 100644 --- a/src/calibre/gui2/tweak_book/manage_fonts.py +++ b/src/calibre/gui2/tweak_book/manage_fonts.py @@ -21,7 +21,7 @@ from calibre.gui2.tweak_book.widgets import Dialog, BusyCursor from calibre.utils.icu import primary_sort_key as sort_key from calibre.utils.fonts.scanner import font_scanner, NoFonts from calibre.utils.fonts.metadata import FontMetadata, UnsupportedFont -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def rule_for_font(font_file, added_name): @@ -84,11 +84,11 @@ class EmbeddingData(Dialog): text.append('
  • ' + '' + face['path'] + '') name = face.get('full_name') or face.get('family_name') or face.get('subfamily_name') if name: - text.append('
    ' + _('Name:') + '\xa0' + unicode_type(name) + '') + text.append('
    ' + _('Name:') + '\xa0' + str(name) + '') if 'font-weight' in face: - text.append('
    ' + 'font-weight:\xa0' + unicode_type(face['font-weight'])) + text.append('
    ' + 'font-weight:\xa0' + str(face['font-weight'])) if 'font-style' in face: - text.append('
    ' + 'font-style:\xa0' + unicode_type(face['font-style'])) + text.append('
    ' + 'font-style:\xa0' + str(face['font-style'])) self.text.setHtml('\n'.join(text)) @@ -197,7 +197,7 @@ class ChangeFontFamily(Dialog): @property def family(self): - return unicode_type(self._family.text()) + return str(self._family.text()) @property def normalized_family(self): diff --git a/src/calibre/gui2/tweak_book/plugin.py b/src/calibre/gui2/tweak_book/plugin.py index 07ab63dd31..d6841aa2ea 100644 --- a/src/calibre/gui2/tweak_book/plugin.py +++ b/src/calibre/gui2/tweak_book/plugin.py @@ -14,7 +14,7 @@ from calibre.customize import PluginInstallationType from calibre.customize.ui import all_edit_book_tool_plugins from calibre.gui2.tweak_book import current_container, tprefs from calibre.gui2.tweak_book.boss import get_boss -from polyglot.builtins import itervalues, unicode_type +from polyglot.builtins import itervalues class Tool: @@ -81,7 +81,7 @@ class Tool: :param description: An optional longer description of this action, it will be used in the preferences entry for this shortcut. ''' - short_text = short_text or unicode_type(qaction.text()).replace('&&', '\0').replace('&', '').replace('\0', '&') + short_text = short_text or str(qaction.text()).replace('&&', '\0').replace('&', '').replace('\0', '&') self.gui.keyboard.register_shortcut( self.name + '_' + unique_name, short_text, default_keys=default_keys, action=qaction, description=description or '', group=_('Plugins')) diff --git a/src/calibre/gui2/tweak_book/preferences.py b/src/calibre/gui2/tweak_book/preferences.py index 6cfaf64403..153f33ed95 100644 --- a/src/calibre/gui2/tweak_book/preferences.py +++ b/src/calibre/gui2/tweak_book/preferences.py @@ -9,8 +9,7 @@ import numbers from operator import attrgetter, methodcaller from functools import partial from collections import namedtuple -from polyglot.builtins import ( - iteritems, itervalues, map, unicode_type, range) +from polyglot.builtins import iteritems, itervalues from itertools import product from copy import copy, deepcopy @@ -78,7 +77,7 @@ class BasicSettings(QWidget): # {{{ widget.addItem(human or key, key) def getter(w): - ans = unicode_type(w.itemData(w.currentIndex()) or '') + ans = str(w.itemData(w.currentIndex()) or '') return {none_val:None}.get(ans, ans) def setter(w, val): @@ -105,7 +104,7 @@ class BasicSettings(QWidget): # {{{ widget.defaults = prefs.defaults[name] def getter(w): - return list(map(unicode_type, (w.item(i).text() for i in range(w.count())))) + return list(map(str, (w.item(i).text() for i in range(w.count())))) def setter(w, val): order_map = {x:i for i, x in enumerate(val)} @@ -354,7 +353,7 @@ class PreviewSettings(BasicSettings): # {{{ return s.fontFamily(which) def family_getter(which, w): - ans = unicode_type(w.currentFont().family()) + ans = str(w.currentFont().family()) if ans == default_font(which): ans = None return ans @@ -520,13 +519,13 @@ class ToolbarSettings(QWidget): prefs = prefs or tprefs val = self.original_settings = {} for i in range(1, self.bars.count()): - name = unicode_type(self.bars.itemData(i) or '') + name = str(self.bars.itemData(i) or '') val[name] = copy(prefs[name]) self.current_settings = deepcopy(val) @property def current_name(self): - return unicode_type(self.bars.itemData(self.bars.currentIndex()) or '') + return str(self.bars.itemData(self.bars.currentIndex()) or '') def build_lists(self): from calibre.gui2.tweak_book.plugin import plugin_toolbar_actions @@ -550,12 +549,12 @@ class ToolbarSettings(QWidget): ic = ac.icon() if not ic or ic.isNull(): ic = blank - ans = QListWidgetItem(ic, unicode_type(ac.text()).replace('&', ''), parent) + ans = QListWidgetItem(ic, str(ac.text()).replace('&', ''), parent) ans.setData(Qt.ItemDataRole.UserRole, key) ans.setToolTip(ac.toolTip()) return ans - for key, ac in sorted(iteritems(all_items), key=lambda k_ac: unicode_type(k_ac[1].text())): + for key, ac in sorted(iteritems(all_items), key=lambda k_ac: str(k_ac[1].text())): if key not in applied: to_item(key, ac, self.available) if name == 'global_book_toolbar' and 'donate' not in applied: @@ -612,7 +611,7 @@ class ToolbarSettings(QWidget): s = self.current_settings[self.current_name] except KeyError: return - names = [unicode_type(i.data(Qt.ItemDataRole.UserRole) or '') for i in items] + names = [str(i.data(Qt.ItemDataRole.UserRole) or '') for i in items] if not names: return for n in names: @@ -683,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) @@ -706,7 +705,7 @@ class TemplatesDialog(Dialog): # {{{ @property def current_syntax(self): - return unicode_type(self.syntaxes.currentText()) + return str(self.syntaxes.currentText()) def show_template(self): from calibre.gui2.tweak_book.templates import raw_template_for @@ -724,7 +723,7 @@ class TemplatesDialog(Dialog): # {{{ def _save_syntax(self): custom = tprefs['templates'] - custom[self.current_syntax] = unicode_type(self.editor.toPlainText()) + custom[self.current_syntax] = str(self.editor.toPlainText()) tprefs['templates'] = custom def restore_defaults(self): diff --git a/src/calibre/gui2/tweak_book/preview.py b/src/calibre/gui2/tweak_book/preview.py index 39ce779954..9433f071bc 100644 --- a/src/calibre/gui2/tweak_book/preview.py +++ b/src/calibre/gui2/tweak_book/preview.py @@ -39,7 +39,7 @@ from calibre.gui2.webengine import ( ) from calibre.gui2.widgets2 import HistoryLineEdit2 from calibre.utils.ipc.simple_worker import offload_worker -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems from polyglot.queue import Empty, Queue from polyglot.urllib import urlparse @@ -195,7 +195,7 @@ class UrlSchemeHandler(QWebEngineUrlSchemeHandler): QTimer.singleShot(0, self.check_for_parse) else: data = get_data(name) - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') mime_type = { # Prevent warning in console about mimetype of fonts @@ -461,7 +461,7 @@ class WebView(RestartingWebEngineView, OpenWithHandler): menu = QMenu(self) data = self._page.contextMenuData() url = data.linkUrl() - url = unicode_type(url.toString(NO_URL_FORMATTING)).strip() + url = str(url.toString(NO_URL_FORMATTING)).strip() text = data.selectedText() if text: ca = self.pageAction(QWebEnginePage.WebAction.Copy) @@ -590,7 +590,7 @@ class Preview(QWidget): self.view._page.findText('') def find(self, direction): - text = unicode_type(self.search.text()) + text = str(self.search.text()) self.view._page.findText(text, ( QWebEnginePage.FindFlag.FindBackward if direction == 'prev' else QWebEnginePage.FindFlags(0))) diff --git a/src/calibre/gui2/tweak_book/reports.py b/src/calibre/gui2/tweak_book/reports.py index 7ed7489519..39227b11be 100644 --- a/src/calibre/gui2/tweak_book/reports.py +++ b/src/calibre/gui2/tweak_book/reports.py @@ -36,7 +36,7 @@ from calibre.gui2.progress_indicator import ProgressIndicator from calibre.utils.icu import primary_contains, numeric_sort_key from calibre.utils.unicode_names import character_name_from_code from calibre.utils.localization import calibre_langcode_to_name, canonicalize_lang -from polyglot.builtins import filter, iteritems, map, range, unicode_type, as_bytes +from polyglot.builtins import iteritems, as_bytes # Utils {{{ @@ -459,9 +459,9 @@ class ImagesModel(FileCollection): return entry.basename if col == 1: sz = entry.size / 1024. - return ('%.2f' % sz if int(sz) != sz else unicode_type(sz)) + return ('%.2f' % sz if int(sz) != sz else str(sz)) if col == 2: - return unicode_type(len(entry.usage)) + return str(len(entry.usage)) if col == 3: return '%d x %d' % (entry.width, entry.height) elif role == Qt.ItemDataRole.UserRole: @@ -732,7 +732,7 @@ class WordsModel(FileCollection): ans += ' (%s)' % entry.locale.countrycode return ans if col == 2: - return unicode_type(len(entry.usage)) + return str(len(entry.usage)) elif role == Qt.ItemDataRole.UserRole: try: return self.files[index.row()] @@ -824,7 +824,7 @@ class CharsModel(FileCollection): if col == 2: return ('U+%04X' if entry.codepoint < 0x10000 else 'U+%06X') % entry.codepoint if col == 3: - return unicode_type(entry.count) + return str(entry.count) elif role == Qt.ItemDataRole.UserRole: try: return self.files[index.row()] @@ -1005,7 +1005,7 @@ class CSSRulesModel(QAbstractItemModel): self.rules = data['css'] self.num_unused = sum(1 for r in self.rules if r.count == 0) try: - self.num_size = len(unicode_type(max(r.count for r in self.rules))) + self.num_size = len(str(max(r.count for r in self.rules))) except ValueError: self.num_size = 1 self.build_maps() @@ -1229,7 +1229,7 @@ class ClassesModel(CSSRulesModel): self.rules = self.classes = tuple(data['classes']) self.num_unused = sum(1 for ce in self.classes if ce.num_of_matches == 0) try: - self.num_size = len(unicode_type(max(r.num_of_matches for r in self.classes))) + self.num_size = len(str(max(r.num_of_matches for r in self.classes))) except ValueError: self.num_size = 1 self.build_maps() 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/search.py b/src/calibre/gui2/tweak_book/search.py index 0472cad525..fe41480459 100644 --- a/src/calibre/gui2/tweak_book/search.py +++ b/src/calibre/gui2/tweak_book/search.py @@ -37,9 +37,7 @@ from calibre.gui2.tweak_book.function_replace import ( from calibre.gui2.tweak_book.widgets import BusyCursor from calibre.gui2.widgets2 import FlowLayout, HistoryComboBox from calibre.utils.icu import primary_contains -from polyglot.builtins import ( - error_message, filter, iteritems, map, range, unicode_type -) +from polyglot.builtins import error_message, iteritems # The search panel {{{ @@ -370,7 +368,7 @@ class SearchWidget(QWidget): @property def find(self): - return unicode_type(self.find_text.text()) + return str(self.find_text.text()) @find.setter def find(self, val): @@ -380,7 +378,7 @@ class SearchWidget(QWidget): def replace(self): if self.mode == 'function': return self.functions.text() - return unicode_type(self.replace_text.text()) + return str(self.replace_text.text()) @replace.setter def replace(self, val): @@ -621,7 +619,7 @@ class SearchesModel(QAbstractListModel): return None def do_filter(self, text): - text = unicode_type(text) + text = str(text) self.beginResetModel() self.filtered_searches = [] for i, search in enumerate(self.searches): @@ -806,7 +804,7 @@ class EditSearch(QFrame): # {{{ @property def current_search(self): search = self.search.copy() - f = unicode_type(self.find.toPlainText()) + f = str(self.find.toPlainText()) search['find'] = f search['dot_all'] = bool(self.dot_all.isChecked()) search['case_sensitive'] = bool(self.case_sensitive.isChecked()) @@ -814,7 +812,7 @@ class EditSearch(QFrame): # {{{ if search['mode'] == 'function': r = self.function.text() else: - r = unicode_type(self.replace.toPlainText()) + r = str(self.replace.toPlainText()) search['replace'] = r return search @@ -833,7 +831,7 @@ class EditSearch(QFrame): # {{{ search = self.search search['name'] = n - f = unicode_type(self.find.toPlainText()) + f = str(self.find.toPlainText()) if not f: error_dialog(self, _('Must specify find'), _( 'You must specify a find expression'), show=True) @@ -848,7 +846,7 @@ class EditSearch(QFrame): # {{{ 'You must specify a function name in Function-Regex mode'), show=True) return False else: - r = unicode_type(self.replace.toPlainText()) + r = str(self.replace.toPlainText()) search['replace'] = r search['dot_all'] = bool(self.dot_all.isChecked()) diff --git a/src/calibre/gui2/tweak_book/spell.py b/src/calibre/gui2/tweak_book/spell.py index ee3ae3aa62..fcb39a5548 100644 --- a/src/calibre/gui2/tweak_book/spell.py +++ b/src/calibre/gui2/tweak_book/spell.py @@ -46,7 +46,7 @@ from calibre.utils.localization import ( calibre_langcode_to_name, canonicalize_lang, get_lang, get_language ) from calibre_extensions.progress_indicator import set_no_activate_on_click -from polyglot.builtins import filter, iteritems, range, unicode_type +from polyglot.builtins import iteritems LANG = 0 COUNTRY = 1 @@ -117,7 +117,7 @@ class AddDictionary(QDialog): # {{{ @property def nickname(self): - return unicode_type(self.nick.text()).strip() + return str(self.nick.text()).strip() def accept(self): nick = self.nickname @@ -127,7 +127,7 @@ class AddDictionary(QDialog): # {{{ if nick in {d.name for d in custom_dictionaries()}: return error_dialog(self, _('Nickname already used'), _( 'A dictionary with the nick name "%s" already exists.') % nick, show=True) - oxt = unicode_type(self.path.text()) + oxt = str(self.path.text()) try: num = import_from_oxt(oxt, nick) except: @@ -253,7 +253,7 @@ class ManageUserDictionaries(Dialog): name, ok = QInputDialog.getText(self, _('New dictionary'), _( 'Name of the new dictionary')) if ok: - name = unicode_type(name) + name = str(name) if name in {d.name for d in dictionaries.all_user_dictionaries}: return error_dialog(self, _('Already used'), _( 'A dictionary with the name %s already exists') % name, show=True) @@ -278,7 +278,7 @@ class ManageUserDictionaries(Dialog): name, ok = QInputDialog.getText(self, _('New name'), _( 'New name for the dictionary')) if ok: - name = unicode_type(name) + name = str(name) if name == d.name: return if name in {d.name for d in dictionaries.all_user_dictionaries}: @@ -334,7 +334,7 @@ class ManageUserDictionaries(Dialog): if d.exec_() != QDialog.DialogCode.Accepted: return d.loc.update_recently_used() - word = unicode_type(w.text()) + word = str(w.text()) lang = (loc.lang_codes or [canonicalize_lang(get_lang())])[0] if not word: return @@ -375,7 +375,7 @@ class ManageUserDictionaries(Dialog): if not lc: return error_dialog(self, _('Must specify language'), _( 'You must specify a language to import words'), show=True) - words = set(filter(None, [x.strip() for x in unicode_type(w.toPlainText()).splitlines()])) + words = set(filter(None, [x.strip() for x in str(w.toPlainText()).splitlines()])) lang = lc[0] words = {(w, lang) for w in words} - self.current_dictionary.words if dictionaries.add_to_user_dictionary(self.current_dictionary.name, words, DictionaryLocale(lang, None)): @@ -475,8 +475,8 @@ class ManageDictionaries(Dialog): # {{{ def data_changed(self, item, column): if column == 0 and item.type() == DICTIONARY: d = item.data(0, Qt.ItemDataRole.UserRole) - if not d.builtin and unicode_type(item.text(0)) != d.name: - rename_dictionary(d, unicode_type(item.text(0))) + if not d.builtin and str(item.text(0)) != d.name: + rename_dictionary(d, str(item.text(0))) def build_dictionaries(self, reread=False): all_dictionaries = builtin_dictionaries() | custom_dictionaries(reread=reread) @@ -559,7 +559,7 @@ class ManageDictionaries(Dialog): # {{{ pc.setText((_( 'This is already the preferred variant for the {1} language') if preferred else _( 'Use this as the preferred variant for the {1} language')).format( - unicode_type(item.text(0)), unicode_type(item.parent().text(0)))) + str(item.text(0)), str(item.parent().text(0)))) pc.setEnabled(not preferred) def set_preferred_country(self): @@ -568,18 +568,18 @@ class ManageDictionaries(Dialog): # {{{ bf.setBold(True) for x in (item.parent().child(i) for i in range(item.parent().childCount())): x.setData(0, Qt.ItemDataRole.FontRole, bf if x is item else None) - lc = unicode_type(item.parent().data(0, Qt.ItemDataRole.UserRole)) + lc = str(item.parent().data(0, Qt.ItemDataRole.UserRole)) pl = dprefs['preferred_locales'] - pl[lc] = '%s-%s' % (lc, unicode_type(item.data(0, Qt.ItemDataRole.UserRole))) + pl[lc] = '%s-%s' % (lc, str(item.data(0, Qt.ItemDataRole.UserRole))) dprefs['preferred_locales'] = pl def init_dictionary(self, item): 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) @@ -589,8 +589,8 @@ class ManageDictionaries(Dialog): # {{{ bf.setItalic(True) for x in (item.parent().child(i) for i in range(item.parent().childCount())): x.setData(0, Qt.ItemDataRole.FontRole, bf if x is item else None) - cc = unicode_type(item.parent().data(0, Qt.ItemDataRole.UserRole)) - lc = unicode_type(item.parent().parent().data(0, Qt.ItemDataRole.UserRole)) + cc = str(item.parent().data(0, Qt.ItemDataRole.UserRole)) + lc = str(item.parent().parent().data(0, Qt.ItemDataRole.UserRole)) d = item.data(0, Qt.ItemDataRole.UserRole) locale = '%s-%s' % (lc, cc) pl = dprefs['preferred_dictionaries'] @@ -997,7 +997,7 @@ class SpellCheck(Dialog): m.show_only_misspelt = hh.isSectionHidden(3) self.ignore_button = b = QPushButton(_('&Ignore')) - b.ign_text, b.unign_text = unicode_type(b.text()), _('Un&ignore') + b.ign_text, b.unign_text = str(b.text()), _('Un&ignore') b.ign_tt = _('Ignore the current word for the rest of this session') b.unign_tt = _('Stop ignoring the current word') b.clicked.connect(self.toggle_ignore) @@ -1006,7 +1006,7 @@ class SpellCheck(Dialog): h.setStretch(0, 1) l.addWidget(b), l.addSpacing(20) self.add_button = b = QPushButton(_('Add word to &dictionary:')) - b.add_text, b.remove_text = unicode_type(b.text()), _('Remove from &dictionaries') + b.add_text, b.remove_text = str(b.text()), _('Remove from &dictionaries') b.add_tt = _('Add the current word to the specified user dictionary') b.remove_tt = _('Remove the current word from all active user dictionaries') b.clicked.connect(self.add_remove) @@ -1071,7 +1071,7 @@ class SpellCheck(Dialog): def search_type_changed(self): tprefs['spell_check_case_sensitive_search'] = bool(self.case_sensitive_search.isChecked()) - if unicode_type(self.filter_text.text()).strip(): + if str(self.filter_text.text()).strip(): self.do_filter() def show_next_occurrence(self): @@ -1084,7 +1084,7 @@ class SpellCheck(Dialog): self.find_word.emit(w, self.words_model.words[w]) def initialize_user_dictionaries(self): - ct = unicode_type(self.user_dictionaries.currentText()) + ct = str(self.user_dictionaries.currentText()) self.user_dictionaries.clear() self.user_dictionaries.addItems([d.name for d in dictionaries.active_user_dictionaries]) if ct: @@ -1159,7 +1159,7 @@ class SpellCheck(Dialog): w = self.words_model.word_for_row(row) if w is None: return - new_word = unicode_type(self.suggested_word.text()) + new_word = str(self.suggested_word.text()) self.change_requested.emit(w, new_word) def change_word_after_update(self, w, new_word): @@ -1215,7 +1215,7 @@ class SpellCheck(Dialog): current = self.words_view.currentIndex() if current.isValid(): if self.user_dictionaries.isVisible(): # add - udname = unicode_type(self.user_dictionaries.currentText()) + udname = str(self.user_dictionaries.currentText()) self.words_model.add_word(current.row(), udname) else: self.words_model.remove_word(current.row()) @@ -1237,7 +1237,7 @@ class SpellCheck(Dialog): self.__current_word = None def do_filter(self): - text = unicode_type(self.filter_text.text()).strip() + text = str(self.filter_text.text()).strip() with self: self.words_model.filter(text) diff --git a/src/calibre/gui2/tweak_book/toc.py b/src/calibre/gui2/tweak_book/toc.py index e697e74d06..61dcd6048e 100644 --- a/src/calibre/gui2/tweak_book/toc.py +++ b/src/calibre/gui2/tweak_book/toc.py @@ -17,7 +17,6 @@ from calibre.gui2 import error_dialog, make_view_use_window_background from calibre.gui2.toc.main import ItemEdit, TOCView from calibre.gui2.tweak_book import TOP, actions, current_container, tprefs from calibre_extensions.progress_indicator import set_no_activate_on_click -from polyglot.builtins import range, unicode_type class TOCEditor(QDialog): @@ -76,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()) @@ -84,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(): @@ -100,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()) @@ -193,14 +192,13 @@ 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() if item is not None: - dest = unicode_type(item.data(0, DEST_ROLE) or '') - frag = unicode_type(item.data(0, FRAG_ROLE) or '') + dest = str(item.data(0, DEST_ROLE) or '') + frag = str(item.data(0, FRAG_ROLE) or '') if not frag: frag = TOP self.navigate_requested.emit(dest, frag) @@ -230,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 eb54946c9b..a1dff8a4dc 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -52,7 +52,7 @@ from calibre.utils.localization import ( localize_user_manual_link, localize_website_link ) from calibre.utils.unicode_names import character_name_from_code -from polyglot.builtins import iteritems, itervalues, map, range, unicode_type +from polyglot.builtins import iteritems, itervalues def open_donate(): @@ -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) @@ -369,7 +369,7 @@ class Main(MainWindow): self.cursor_position_widget = CursorPositionWidget(self) self.status_bar.addPermanentWidget(self.cursor_position_widget) self.status_bar_default_msg = la = QLabel(' ' + _('{0} {1} created by {2}').format(__appname__, get_version(), 'Kovid Goyal')) - la.base_template = unicode_type(la.text()) + la.base_template = str(la.text()) self.status_bar.addWidget(la) self.boss(self) @@ -414,10 +414,10 @@ class Main(MainWindow): toolbar_actions[sid] = ac if target is not None: ac.triggered.connect(target) - if isinstance(keys, unicode_type): + if isinstance(keys, str): keys = (keys,) self.keyboard.register_shortcut( - sid, unicode_type(ac.text()).replace('&', ''), default_keys=keys, description=description, action=ac, group=group) + sid, str(ac.text()).replace('&', ''), default_keys=keys, description=description, action=ac, group=group) self.addAction(ac) return ac @@ -718,7 +718,7 @@ class Main(MainWindow): if self.plugin_menu_actions: e = b.addMenu(_('&Plugins')) - for ac in sorted(self.plugin_menu_actions, key=lambda x:sort_key(unicode_type(x.text()))): + for ac in sorted(self.plugin_menu_actions, key=lambda x:sort_key(str(x.text()))): e.addAction(ac) e = b.addMenu(_('&Help')) @@ -770,7 +770,7 @@ class Main(MainWindow): bar.addAction(actions[ac]) except KeyError: if DEBUG: - prints('Unknown action for toolbar %r: %r' % (unicode_type(bar.objectName()), ac)) + prints('Unknown action for toolbar %r: %r' % (str(bar.objectName()), ac)) for x in tprefs['global_book_toolbar']: add(self.global_bar, x) @@ -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 d95adbe2b0..28a578bcd6 100644 --- a/src/calibre/gui2/tweak_book/widgets.py +++ b/src/calibre/gui2/tweak_book/widgets.py @@ -26,10 +26,9 @@ from calibre.gui2.widgets2 import Dialog as BaseDialog, HistoryComboBox, to_plai from calibre.utils.icu import primary_sort_key, sort_key, primary_contains, numeric_sort_key from calibre.utils.matcher import get_char, Matcher, DEFAULT_LEVEL1, DEFAULT_LEVEL2, DEFAULT_LEVEL3 from calibre.gui2.complete2 import EditWithComplete -from polyglot.builtins import iteritems, unicode_type, zip, getcwd, filter as ignore_me +from polyglot.builtins import iteritems ROOT = QModelIndex() -ignore_me class BusyCursor: @@ -70,7 +69,7 @@ class InsertTag(Dialog): # {{{ @property def tag(self): - return unicode_type(self.tag_input.text()).strip() + return str(self.tag_input.text()).strip() @classmethod def test(cls): @@ -131,7 +130,7 @@ class RationalizeFolders(Dialog): # {{{ def folder_map(self): ans = {} for typ, x in self.TYPE_MAP: - val = unicode_type(getattr(self, '%s_folder' % typ).text()).strip().strip('/') + val = str(getattr(self, '%s_folder' % typ).text()).strip().strip('/') ans[typ] = val return ans @@ -243,15 +242,15 @@ class ImportForeign(Dialog): # {{{ self.dest.setText(path) def accept(self): - if not unicode_type(self.src.text()): + if not str(self.src.text()): return error_dialog(self, _('Need document'), _( 'You must specify the source file that will be imported.'), show=True) Dialog.accept(self) @property def data(self): - src = unicode_type(self.src.text()).strip() - dest = unicode_type(self.dest.text()).strip() + src = str(self.src.text()).strip() + dest = str(self.dest.text()).strip() if not dest: dest = src.rpartition('.')[0] + '.epub' return src, dest @@ -348,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: @@ -458,7 +457,7 @@ class QuickOpen(Dialog): l.addWidget(self.bb, alignment=Qt.AlignmentFlag.AlignBottom) def update_matches(self, text): - text = unicode_type(text).strip() + text = str(text).strip() self.help_label.setVisible(False) self.results.setVisible(True) matches = self.matcher(text, limit=100) @@ -479,7 +478,7 @@ class QuickOpen(Dialog): @classmethod def test(cls): from calibre.utils.matcher import get_items_from_dir - items = get_items_from_dir(getcwd(), lambda x:not x.endswith('.pyc')) + items = get_items_from_dir(os.getcwd(), lambda x:not x.endswith('.pyc')) d = cls(items) d.exec_() print(d.selected_result) @@ -553,7 +552,7 @@ class NamesModel(QAbstractListModel): return '\xa0' * 20 def filter(self, query): - query = unicode_type(query or '') + query = str(query or '') self.beginResetModel() if not query: self.items = tuple((text, None) for text in self.names) @@ -618,7 +617,7 @@ class AnchorsModel(QAbstractListModel): self.filter('') def filter(self, query): - query = unicode_type(query or '') + query = str(query or '') self.beginResetModel() self.items = [x for x in self.names if primary_contains(query, x[0]) or primary_contains(query, x[1])] self.endResetModel() @@ -746,11 +745,11 @@ class InsertLink(Dialog): @property def href(self): - return unicode_type(self.target.text()).strip() + return str(self.target.text()).strip() @property def text(self): - return unicode_type(self.text_edit.text()).strip() + return str(self.text_edit.text()).strip() @property def template(self): @@ -890,7 +889,7 @@ class InsertSemantics(Dialog): d.exec_() def semantic_type_changed(self): - item_type = unicode_type(self.semantic_type.itemData(self.semantic_type.currentIndex()) or '') + item_type = str(self.semantic_type.itemData(self.semantic_type.currentIndex()) or '') name, frag = self.final_type_map.get(item_type, (None, None)) self.show_type(name, frag) @@ -915,8 +914,8 @@ class InsertSemantics(Dialog): self.target.blockSignals(False) def target_text_changed(self): - name, frag = unicode_type(self.target.text()).partition('#')[::2] - item_type = unicode_type(self.semantic_type.itemData(self.semantic_type.currentIndex()) or '') + name, frag = str(self.target.text()).partition('#')[::2] + item_type = str(self.semantic_type.itemData(self.semantic_type.currentIndex()) or '') self.final_type_map[item_type] = (name, frag or None) def selected_file_changed(self, *args): @@ -1034,7 +1033,7 @@ class FilterCSS(Dialog): # {{{ a('float'), a('clear') if self.opt_colors.isChecked(): a('color'), a('background-color') - for x in unicode_type(self.others.text()).split(','): + for x in str(self.others.text()).split(','): x = x.strip() if x: a(x) @@ -1166,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): @@ -1210,7 +1209,7 @@ class PlainTextEdit(QPlainTextEdit): # {{{ return to_plain_text(self) def selected_text_from_cursor(self, cursor): - return unicodedata.normalize('NFC', unicode_type(cursor.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0')) + return unicodedata.normalize('NFC', str(cursor.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0')) @property def selected_text(self): diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 255369b964..1d55ce1d02 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -60,7 +60,7 @@ from calibre.library import current_library_name from calibre.srv.library_broker import GuiLibraryBroker, db_matches from calibre.utils.config import dynamic, prefs from calibre.utils.ipc.pool import Pool -from polyglot.builtins import string_or_bytes, unicode_type +from polyglot.builtins import string_or_bytes from polyglot.queue import Empty, Queue @@ -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.' @@ -606,7 +606,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ if self.content_server is not None and \ self.content_server.exception is not None: error_dialog(self, _('Failed to start Content server'), - unicode_type(self.content_server.exception)).exec_() + str(self.content_server.exception)).exec_() @property def current_db(self): @@ -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) @@ -1043,7 +1043,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ pass if not minz: self.job_error_dialog.show_error(dialog_title, - _('Failed')+': '+unicode_type(job.description), + _('Failed')+': '+str(job.description), det_msg=job.details, retry_func=retry_func) def read_settings(self): diff --git a/src/calibre/gui2/update.py b/src/calibre/gui2/update.py index 77d46f01de..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 ' @@ -19,7 +17,6 @@ from calibre.gui2 import config, dynamic, open_url from calibre.gui2.dialogs.plugin_updater import get_plugin_updates_available from calibre.utils.serialize import msgpack_dumps, msgpack_loads from polyglot.binary import as_hex_unicode, from_hex_bytes -from polyglot.builtins import map, unicode_type URL = 'https://code.calibre-ebook.com/latest' # URL = 'http://localhost:8000/latest' @@ -60,7 +57,7 @@ def get_newest_version(): except UnicodeDecodeError: version = '' ans = NO_CALIBRE_UPDATE - m = re.match(unicode_type(r'(\d+)\.(\d+).(\d+)$'), version) + m = re.match(r'(\d+)\.(\d+).(\d+)$', version) if m is not None: ans = tuple(map(int, (m.group(1), m.group(2), m.group(3)))) return ans @@ -139,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!')) @@ -213,7 +210,7 @@ class UpdateMixin: has_plugin_updates = number_of_plugin_updates > 0 self.plugin_update_found(number_of_plugin_updates) version_url = as_hex_unicode(msgpack_dumps((calibre_version, number_of_plugin_updates))) - calibre_version = '.'.join(map(unicode_type, calibre_version)) + calibre_version = '.'.join(map(str, calibre_version)) if not has_calibre_update and not has_plugin_updates: self.status_bar.update_label.setVisible(False) @@ -264,7 +261,7 @@ class UpdateMixin: plugin.qaction.setToolTip(_('Install and configure user plugins')) def update_link_clicked(self, url): - url = unicode_type(url) + url = str(url) if url.startswith('update:'): calibre_version, number_of_plugin_updates = msgpack_loads(from_hex_bytes(url[len('update:'):])) self.update_found(calibre_version, number_of_plugin_updates, force=True) 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/bookmarks.py b/src/calibre/gui2/viewer/bookmarks.py index 49c1a4e905..13529f63d3 100644 --- a/src/calibre/gui2/viewer/bookmarks.py +++ b/src/calibre/gui2/viewer/bookmarks.py @@ -17,7 +17,6 @@ from calibre.gui2.viewer.shortcuts import get_shortcut_for from calibre.gui2.viewer.web_view import vprefs from calibre.utils.date import EPOCH, utcnow from calibre.utils.icu import primary_sort_key -from polyglot.builtins import range, unicode_type class BookmarksList(QListWidget): @@ -241,7 +240,7 @@ class BookmarkManager(QWidget): def item_changed(self, item): self.bookmarks_list.blockSignals(True) - title = unicode_type(item.data(Qt.ItemDataRole.DisplayRole)) or _('Unknown') + title = str(item.data(Qt.ItemDataRole.DisplayRole)) or _('Unknown') title = self.uniqify_bookmark_title(title) item.setData(Qt.ItemDataRole.DisplayRole, title) item.setData(Qt.ItemDataRole.ToolTipRole, title) @@ -352,7 +351,7 @@ class BookmarkManager(QWidget): title, ok = QInputDialog.getText(self, _('Add bookmark'), _('Enter title for bookmark:'), text=pos_data.get('selected_text') or default_title) - title = unicode_type(title).strip() + title = str(title).strip() if not ok or not title: return title = self.uniqify_bookmark_title(title) 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/highlights.py b/src/calibre/gui2/viewer/highlights.py index 98f1beea30..ef62783eee 100644 --- a/src/calibre/gui2/viewer/highlights.py +++ b/src/calibre/gui2/viewer/highlights.py @@ -29,7 +29,6 @@ from calibre.gui2.viewer.search import SearchInput from calibre.gui2.viewer.shortcuts import get_shortcut_for, index_to_key_sequence from calibre.gui2.widgets2 import Dialog from calibre_extensions.progress_indicator import set_no_activate_on_click -from polyglot.builtins import range decoration_cache = {} 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 59986fa80d..99662af029 100644 --- a/src/calibre/gui2/viewer/search.py +++ b/src/calibre/gui2/viewer/search.py @@ -18,7 +18,7 @@ from calibre.gui2.progress_indicator import ProgressIndicator from calibre.gui2.viewer.config import vprefs from calibre.gui2.viewer.web_view import get_data, get_manifest from calibre.gui2.viewer.widgets import ResultsDelegate, SearchBox -from polyglot.builtins import iteritems, map, unicode_type +from polyglot.builtins import iteritems from polyglot.functools import lru_cache from polyglot.queue import Queue @@ -178,7 +178,7 @@ def searchable_text_for_name(name): anchor_offset_map = OrderedDict() while stack: node = stack.pop() - if isinstance(node, unicode_type): + if isinstance(node, str): ans.append(node) text_pos += len(node) continue @@ -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 7eb9953bf9..719514882b 100644 --- a/src/calibre/gui2/viewer/web_view.py +++ b/src/calibre/gui2/viewer/web_view.py @@ -38,7 +38,7 @@ from calibre.gui2.webengine import ( from calibre.srv.code import get_translations_data from calibre.utils.serialize import json_loads from calibre.utils.shared_file import share_open -from polyglot.builtins import as_bytes, iteritems, unicode_type +from polyglot.builtins import as_bytes, iteritems from polyglot.functools import lru_cache SANDBOX_HOST = FAKE_HOST.rpartition('.')[0] + '.sandbox' @@ -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): @@ -681,7 +681,7 @@ class WebView(RestartingWebEngineView): vprefs['local_storage'] = sd def do_callback(self, func_name, callback): - cid = unicode_type(next(self.callback_id_counter)) + cid = str(next(self.callback_id_counter)) self.callback_map[cid] = callback self.execute_when_ready('get_current_cfi', cid) diff --git a/src/calibre/gui2/webengine.py b/src/calibre/gui2/webengine.py index b55c8b62e2..9ae40ba56e 100644 --- a/src/calibre/gui2/webengine.py +++ b/src/calibre/gui2/webengine.py @@ -11,7 +11,7 @@ from qt.webengine import QWebEnginePage, QWebEngineScript, QWebEngineView, QWebE from calibre import prints from calibre.utils.monotonic import monotonic from calibre.utils.rapydscript import special_title -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems def secure_webengine(view_or_page_or_settings, for_viewer=False): @@ -60,7 +60,7 @@ def create_script( from_js = pyqtSignal -class to_js(unicode_type): +class to_js(str): def __call__(self, *a): prints('WARNING: Calling {}() before the javascript bridge is ready'.format(self.name)) diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index 5911ee6ae4..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 ' ''' @@ -25,7 +23,7 @@ from calibre.gui2.progress_indicator import ProgressIndicator as _ProgressIndica from calibre.gui2.dnd import (dnd_has_image, dnd_get_image, dnd_get_files, image_extensions, dnd_has_extension, dnd_get_local_image_and_pixmap, DownloadDialog) from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import native_string_type, unicode_type, range +from polyglot.builtins import native_string_type history = XMLConfig('history') @@ -86,7 +84,7 @@ class FilenamePattern(QWidget, Ui_Form): # {{{ # Get all items in the combobox. If we are resetting # to defaults we don't want to lose what the user # has added. - val_hist = [unicode_type(self.re.lineEdit().text())] + [unicode_type(self.re.itemText(i)) for i in range(self.re.count())] + val_hist = [str(self.re.lineEdit().text())] + [str(self.re.itemText(i)) for i in range(self.re.count())] self.re.clear() if defaults: @@ -109,7 +107,7 @@ class FilenamePattern(QWidget, Ui_Form): # {{{ def do_test(self): from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata.meta import metadata_from_filename - fname = unicode_type(self.filename.text()) + fname = str(self.filename.text()) ext = os.path.splitext(fname)[1][1:].lower() if ext not in BOOK_EXTENSIONS: return warning_dialog(self, _('Test file name invalid'), @@ -139,7 +137,7 @@ class FilenamePattern(QWidget, Ui_Form): # {{{ self.series.setText(_('No match')) if mi.series_index is not None: - self.series_index.setText(unicode_type(mi.series_index)) + self.series_index.setText(str(mi.series_index)) else: self.series_index.setText(_('No match')) @@ -153,11 +151,11 @@ class FilenamePattern(QWidget, Ui_Form): # {{{ else: self.pubdate.setText(_('No match')) - self.isbn.setText(_('No match') if mi.isbn is None else unicode_type(mi.isbn)) + self.isbn.setText(_('No match') if mi.isbn is None else str(mi.isbn)) self.comments.setText(mi.comments if mi.comments else _('No match')) def pattern(self): - pat = unicode_type(self.re.lineEdit().text()) + pat = str(self.re.lineEdit().text()) return re.compile(pat) def commit(self): @@ -165,7 +163,7 @@ class FilenamePattern(QWidget, Ui_Form): # {{{ prefs['filename_pattern'] = pat history = [] - history_pats = [unicode_type(self.re.lineEdit().text())] + [unicode_type(self.re.itemText(i)) for i in range(self.re.count())] + history_pats = [str(self.re.lineEdit().text())] + [str(self.re.itemText(i)) for i in range(self.re.count())] for p in history_pats[:24]: # Ensure we don't have duplicate items. if p and p not in history: @@ -496,23 +494,23 @@ class LineEditECM: # {{{ def upper_case(self): from calibre.utils.icu import upper - self.setText(upper(unicode_type(self.text()))) + self.setText(upper(str(self.text()))) def lower_case(self): from calibre.utils.icu import lower - self.setText(lower(unicode_type(self.text()))) + self.setText(lower(str(self.text()))) def swap_case(self): from calibre.utils.icu import swapcase - self.setText(swapcase(unicode_type(self.text()))) + self.setText(swapcase(str(self.text()))) def title_case(self): from calibre.utils.titlecase import titlecase - self.setText(titlecase(unicode_type(self.text()))) + self.setText(titlecase(str(self.text()))) def capitalize(self): from calibre.utils.icu import capitalize - self.setText(capitalize(unicode_type(self.text()))) + self.setText(capitalize(str(self.text()))) # }}} @@ -595,13 +593,13 @@ class CompleteLineEdit(EnLineEdit): # {{{ self.space_before_sep = space_before def text_changed(self, text): - all_text = unicode_type(text) + all_text = str(text) text = all_text[:self.cursorPosition()] prefix = text.split(self.separator)[-1].strip() text_items = [] for t in all_text.split(self.separator): - t1 = unicode_type(t).strip() + t1 = str(t).strip() if t1: text_items.append(t) text_items = list(set(text_items)) @@ -609,8 +607,8 @@ class CompleteLineEdit(EnLineEdit): # {{{ def complete_text(self, text): cursor_pos = self.cursorPosition() - before_text = unicode_type(self.text())[:cursor_pos] - after_text = unicode_type(self.text())[cursor_pos:] + before_text = str(self.text())[:cursor_pos] + after_text = str(self.text())[cursor_pos:] prefix_len = len(before_text.split(self.separator)[-1].lstrip()) if self.space_before_sep: complete_text_pat = '%s%s %s %s' @@ -639,7 +637,7 @@ class EnComboBox(QComboBox): # {{{ self.setMinimumContentsLength(20) def text(self): - return unicode_type(self.currentText()) + return str(self.currentText()) def setText(self, text): idx = self.findText(text, Qt.MatchFlag.MatchFixedString|Qt.MatchFlag.MatchCaseSensitive) @@ -696,11 +694,11 @@ class HistoryLineEdit(QComboBox): # {{{ def save_history(self): items = [] - ct = unicode_type(self.currentText()) + ct = str(self.currentText()) if ct: items.append(ct) for i in range(self.count()): - item = unicode_type(self.itemText(i)) + item = str(self.itemText(i)) if item not in items: items.append(item) self.blockSignals(True) @@ -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() @@ -1098,7 +1096,7 @@ class Splitter(QSplitter): parent.addAction(self.action_toggle) if hasattr(parent, 'keyboard'): parent.keyboard.register_shortcut('splitter %s %s'%(name, - label), unicode_type(self.action_toggle.text()), + label), str(self.action_toggle.text()), default_keys=(shortcut,), action=self.action_toggle) else: self.action_toggle.setShortcut(shortcut) diff --git a/src/calibre/gui2/widgets2.py b/src/calibre/gui2/widgets2.py index a8b81b8ed3..e2cf387760 100644 --- a/src/calibre/gui2/widgets2.py +++ b/src/calibre/gui2/widgets2.py @@ -19,7 +19,6 @@ from calibre.gui2.complete2 import EditWithComplete, LineEdit from calibre.gui2.widgets import history from calibre.utils.config_base import tweaks from calibre.utils.date import UNDEFINED_DATE -from polyglot.builtins import unicode_type from polyglot.functools import lru_cache @@ -50,7 +49,7 @@ class HistoryMixin: return history.get(self.store_name, []) def save_history(self): - ct = unicode_type(self.text()) + ct = str(self.text()) if len(ct) >= self.min_history_entry_length: try: self.history.remove(ct) @@ -104,7 +103,7 @@ class ColorButton(QPushButton): @color.setter def color(self, val): - val = unicode_type(val or '') + val = str(val or '') col = QColor(val) orig = self._color if col.isValid(): @@ -123,7 +122,7 @@ class ColorButton(QPushButton): def choose_color(self): col = QColorDialog.getColor(QColor(self._color or Qt.GlobalColor.white), self, _('Choose a color')) if col.isValid(): - self.color = unicode_type(col.name()) + self.color = str(col.name()) def access_key(k): @@ -540,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 729751c28e..9340f67ead 100644 --- a/src/calibre/gui2/win_file_dialogs.py +++ b/src/calibre/gui2/win_file_dialogs.py @@ -12,7 +12,7 @@ from uuid import uuid4 from contextlib import suppress -from polyglot.builtins import filter, string_or_bytes, unicode_type +from polyglot.builtins import string_or_bytes is64bit = sys.maxsize > (1 << 32) base = sys.extensions_location if hasattr(sys, 'new_app_layout') else os.path.dirname(sys.executable) @@ -61,7 +61,7 @@ def serialize_binary(key, val): def serialize_string(key, val): key = key.encode('ascii') if not isinstance(key, bytes) else key - val = unicode_type(val).encode('utf-8') + val = str(val).encode('utf-8') if len(val) > 2**16 - 1: raise ValueError('%s is too long' % key) return struct.pack('=B%dsH%ds' % (len(key), len(val)), len(key), key, len(val), val) @@ -205,7 +205,7 @@ def run_file_dialog( from calibre import prints from calibre.constants import DEBUG if DEBUG: - prints('stdout+stderr from file dialog helper:', unicode_type([h.stdoutdata, h.stderrdata])) + prints('stdout+stderr from file dialog helper:', str([h.stdoutdata, h.stderrdata])) if h.rc != 0: raise Exception('File dialog failed (return code %s): %s' % (h.rc, get_errors())) @@ -218,7 +218,7 @@ def run_file_dialog( return () parts = list(filter(None, server.data.split(b'\0'))) if DEBUG: - prints('piped data from file dialog helper:', unicode_type(parts)) + prints('piped data from file dialog helper:', str(parts)) if len(parts) < 2: return () if parts[0] != secret: @@ -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 21622601f0..8ce45d1e73 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -26,7 +26,7 @@ from calibre.gui2.wizard.send_email import smtp_prefs from calibre.gui2.wizard.stanza_ui import Ui_WizardPage as StanzaUI from calibre.utils.config import dynamic, prefs from calibre.utils.localization import localize_user_manual_link -from polyglot.builtins import iteritems, map, unicode_type +from polyglot.builtins import iteritems # Devices {{{ @@ -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() @@ -537,14 +537,14 @@ class KindlePage(QWizardPage, KindleUI): self.to_address.setText(accs[0][0]) def x(): - t = unicode_type(self.to_address.text()) + t = str(self.to_address.text()) if t.strip(): return t.strip() self.send_email_widget.initialize(x) def commit(self): - x = unicode_type(self.to_address.text()).strip() + x = str(self.to_address.text()).strip() parts = x.split('@') if (len(parts) >= 2 and parts[0] and self.send_email_widget.set_email_settings(True)): @@ -605,8 +605,8 @@ class StanzaPage(QWizardPage, StanzaUI): for p in range(8080, 8100): try: s.bind(('0.0.0.0', p)) - t = unicode_type(self.instructions.text()) - t = re.sub(r':\d+', ':'+unicode_type(p), t) + t = str(self.instructions.text()) + t = re.sub(r':\d+', ':'+str(p), t) self.instructions.setText(t) return p except: @@ -733,10 +733,10 @@ class LibraryPage(QWizardPage, LibraryUI): for item in items: self.language.addItem(item[1], (item[0])) self.language.blockSignals(False) - prefs['language'] = unicode_type(self.language.itemData(self.language.currentIndex()) or '') + prefs['language'] = str(self.language.itemData(self.language.currentIndex()) or '') def change_language(self, idx): - prefs['language'] = unicode_type(self.language.itemData(self.language.currentIndex()) or '') + prefs['language'] = str(self.language.itemData(self.language.currentIndex()) or '') from polyglot.builtins import builtins builtins.__dict__['_'] = lambda x: x from calibre.ebooks.metadata.book.base import reset_field_metadata @@ -774,7 +774,7 @@ class LibraryPage(QWizardPage, LibraryUI): return False def validatePage(self): - newloc = unicode_type(self.location.text()) + newloc = str(self.location.text()) if not self.is_library_dir_suitable(newloc): self.show_library_dir_error(newloc) return False @@ -804,11 +804,11 @@ class LibraryPage(QWizardPage, LibraryUI): self.show_library_dir_error(x) def show_library_dir_error(self, x): - if not isinstance(x, unicode_type): + if not isinstance(x, str): try: x = x.decode(filesystem_encoding) except: - x = unicode_type(repr(x)) + x = str(repr(x)) error_dialog(self, _('Bad location'), _('You must choose an empty folder for ' 'the calibre library. %s is not empty.')%x, show=True) @@ -846,7 +846,7 @@ class LibraryPage(QWizardPage, LibraryUI): def isComplete(self): try: - lp = unicode_type(self.location.text()) + lp = str(self.location.text()) ans = bool(lp) and os.path.exists(lp) and os.path.isdir(lp) and os.access(lp, os.W_OK) except: @@ -854,7 +854,7 @@ class LibraryPage(QWizardPage, LibraryUI): return ans def commit(self): - newloc = unicode_type(self.location.text()) + newloc = str(self.location.text()) try: dln = self.default_library_name if (dln and os.path.exists(dln) and not os.listdir(dln) and newloc != dln): @@ -949,8 +949,8 @@ class Wizard(QWizard): QWizard.accept(self) def set_finish_text(self, *args): - bt = unicode_type("" + self.buttonText(QWizard.WizardButton.FinishButton) + "").replace('&', '') - t = unicode_type(self.finish_page.finish_text.text()) + bt = str("" + self.buttonText(QWizard.WizardButton.FinishButton) + "").replace('&', '') + t = str(self.finish_page.finish_text.text()) if '%s' in t: self.finish_page.finish_text.setText(t%bt) diff --git a/src/calibre/gui2/wizard/send_email.py b/src/calibre/gui2/wizard/send_email.py index 9ea2f0c60e..131a46db3d 100644 --- a/src/calibre/gui2/wizard/send_email.py +++ b/src/calibre/gui2/wizard/send_email.py @@ -19,7 +19,6 @@ from calibre import prints from calibre.gui2.wizard.send_email_ui import Ui_Form from calibre.utils.smtp import config as smtp_prefs from calibre.gui2 import error_dialog, question_dialog -from polyglot.builtins import unicode_type from polyglot.binary import as_hex_unicode, from_hex_unicode from polyglot.io import PolyglotStringIO @@ -70,7 +69,7 @@ class TestEmail(QDialog): def run_test(self): try: - tb = self.test_func(unicode_type(self.to.text())) or _('Email successfully sent') + tb = self.test_func(str(self.to.text())) or _('Email successfully sent') except Exception: import traceback tb = traceback.format_exc() @@ -132,7 +131,7 @@ class RelaySetup(QDialog): self.service = service def accept(self): - un = unicode_type(self.username.text()) + un = str(self.username.text()) if self.service.get('at_in_username', False) and '@' not in un: return error_dialog(self, _('Incorrect username'), _('%s needs the full email address as your username') % @@ -267,14 +266,14 @@ class SendEmail(QWidget, Ui_Form): self.relay_tls.setChecked(True) def set_email_settings(self, to_set): - from_ = unicode_type(self.email_from.text()).strip() + from_ = str(self.email_from.text()).strip() if to_set and not from_: error_dialog(self, _('Bad configuration'), _('You must set the From email address')).exec_() return False - username = unicode_type(self.relay_username.text()).strip() - password = unicode_type(self.relay_password.text()).strip() - host = unicode_type(self.relay_host.text()).strip() + username = str(self.relay_username.text()).strip() + password = str(self.relay_password.text()).strip() + host = str(self.relay_host.text()).strip() enc_method = ('TLS' if self.relay_tls.isChecked() else 'SSL' if self.relay_ssl.isChecked() else 'NONE') if host: diff --git a/src/calibre/library/__init__.py b/src/calibre/library/__init__.py index c70078bd93..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 ' @@ -7,7 +5,6 @@ __copyright__ = '2008, Kovid Goyal ' import os -from polyglot.builtins import range def db(path=None, read_only=False): 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 9ce4ae694f..206fdee456 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -20,8 +20,7 @@ from calibre.db.search import CONTAINS_MATCH, EQUALS_MATCH, REGEXP_MATCH, _match from calibre.ebooks.metadata import title_sort, author_to_author_sort from calibre.ebooks.metadata.opf2 import metadata_to_opf from calibre import prints, force_unicode -from polyglot.builtins import (iteritems, itervalues, map, - unicode_type, string_or_bytes, zip, cmp) +from polyglot.builtins import iteritems, itervalues, string_or_bytes, cmp class MetadataBackup(Thread): # {{{ @@ -138,7 +137,7 @@ del y, c, n, u def force_to_bool(val): - if isinstance(val, (bytes, unicode_type)): + if isinstance(val, (bytes, str)): if isinstance(val, bytes): val = force_unicode(val) try: @@ -360,7 +359,7 @@ class ResultCache(SearchQueryParser): # {{{ if item is None: continue v = item[loc] - if isinstance(v, (bytes, unicode_type)): + if isinstance(v, (bytes, str)): v = parse_date(v) if v is None or v <= UNDEFINED_DATE: matches.add(item[0]) @@ -371,7 +370,7 @@ class ResultCache(SearchQueryParser): # {{{ if item is None: continue v = item[loc] - if isinstance(v, (bytes, unicode_type)): + if isinstance(v, (bytes, str)): v = parse_date(v) if v is not None and v > UNDEFINED_DATE: matches.add(item[0]) @@ -415,7 +414,7 @@ class ResultCache(SearchQueryParser): # {{{ if item is None or item[loc] is None: continue v = item[loc] - if isinstance(v, (bytes, unicode_type)): + if isinstance(v, (bytes, str)): v = parse_date(v) if relop(v, qd, field_count): matches.add(item[0]) @@ -742,7 +741,7 @@ class ResultCache(SearchQueryParser): # {{{ # everything else, or 'all' matches matchkind, query = self._matchkind(query) - if not isinstance(query, unicode_type): + if not isinstance(query, str): query = query.decode('utf-8') db_col = {} @@ -906,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 @@ -927,7 +926,7 @@ class ResultCache(SearchQueryParser): # {{{ self.marked_ids_dict = dict.fromkeys(id_dict, 'true') else: # Ensure that all the items in the dict are text - self.marked_ids_dict = dict(zip(iter(id_dict), map(unicode_type, + self.marked_ids_dict = dict(zip(iter(id_dict), map(str, itervalues(id_dict)))) # Set the values in the cache diff --git a/src/calibre/library/catalogs/bibtex.py b/src/calibre/library/catalogs/bibtex.py index 6ef4a65bda..885bfa783a 100644 --- a/src/calibre/library/catalogs/bibtex.py +++ b/src/calibre/library/catalogs/bibtex.py @@ -14,7 +14,7 @@ from calibre.customize import CatalogPlugin from calibre.library.catalogs import FIELDS, TEMPLATE_ALLOWED_FIELDS from calibre.customize.conversion import DummyReporter from calibre.ebooks.metadata import format_isbn -from polyglot.builtins import filter, string_or_bytes, unicode_type +from polyglot.builtins import string_or_bytes class BIBTEX(CatalogPlugin): @@ -248,7 +248,7 @@ class BIBTEX(CatalogPlugin): elif tpl_field in ['tags', 'authors'] : tpl_field =entry[tpl_field][0] elif tpl_field in ['id', 'series_index'] : - tpl_field = unicode_type(entry[tpl_field]) + tpl_field = str(entry[tpl_field]) else : tpl_field = entry[tpl_field] return ascii_text(tpl_field) @@ -267,7 +267,7 @@ class BIBTEX(CatalogPlugin): template_citation = '%s' % re.sub(r'[\D]','', entry["isbn"]) else : - template_citation = '%s' % unicode_type(entry["id"]) + template_citation = '%s' % str(entry["id"]) return bibtexclass.ValidateCitationKey(template_citation) diff --git a/src/calibre/library/catalogs/csv_xml.py b/src/calibre/library/catalogs/csv_xml.py index e7fa53df53..4abec9afcd 100644 --- a/src/calibre/library/catalogs/csv_xml.py +++ b/src/calibre/library/catalogs/csv_xml.py @@ -12,7 +12,6 @@ from collections import namedtuple from calibre.customize import CatalogPlugin from calibre.library.catalogs import FIELDS from calibre.customize.conversion import DummyReporter -from polyglot.builtins import unicode_type class CSV_XML(CatalogPlugin): @@ -155,14 +154,14 @@ class CSV_XML(CatalogPlugin): item = '%.2g' % (item / 2) # Convert HTML to markdown text - if isinstance(item, unicode_type): + if isinstance(item, str): opening_tag = re.search(r'<(\w+)( |>)', item) if opening_tag: closing_tag = re.search(r'<\/%s>$' % opening_tag.group(1), item) if closing_tag: item = html2text(item) - outstr.append('"%s"' % unicode_type(item).replace('"', '""')) + outstr.append('"%s"' % str(item).replace('"', '""')) outfile.write(','.join(outstr) + '\n') outfile.close() @@ -181,8 +180,8 @@ class CSV_XML(CatalogPlugin): for field in fields: if field.startswith('#'): val = db.get_field(r['id'], field, index_is_id=True) - if not isinstance(val, unicode_type): - val = unicode_type(val) + if not isinstance(val, str): + val = str(val) item = getattr(E, field.replace('#', '_'))(val) record.append(item) @@ -192,11 +191,11 @@ class CSV_XML(CatalogPlugin): val = r[field] if not val: continue - if not isinstance(val, (bytes, unicode_type)): + if not isinstance(val, (bytes, str)): if (fm.get(field, {}).get('datatype', None) == 'rating' and val): val = '%.2g' % (val / 2) - val = unicode_type(val) + val = str(val) item = getattr(E, field)(val) record.append(item) @@ -225,7 +224,7 @@ class CSV_XML(CatalogPlugin): if 'series' in fields and r['series']: record.append(E.series(r['series'], - index=unicode_type(r['series_index']))) + index=str(r['series_index']))) if 'languages' in fields and r['languages']: record.append(E.languages(r['languages'])) diff --git a/src/calibre/library/catalogs/epub_mobi.py b/src/calibre/library/catalogs/epub_mobi.py index ff259eac4a..ea94a41227 100644 --- a/src/calibre/library/catalogs/epub_mobi.py +++ b/src/calibre/library/catalogs/epub_mobi.py @@ -16,7 +16,6 @@ from calibre.library import current_library_name from calibre.library.catalogs import AuthorSortMismatchException, EmptyCatalogException from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.localization import calibre_langcode_to_name, canonicalize_lang, get_lang -from polyglot.builtins import unicode_type Option = namedtuple('Option', 'option, default, dest, action, help') @@ -398,7 +397,7 @@ class EPUB_MOBI(CatalogPlugin): if opts.verbose: log.info(" Begin catalog source generation (%s)" % - unicode_type(datetime.timedelta(seconds=int(time.time() - opts.start_time)))) + str(datetime.timedelta(seconds=int(time.time() - opts.start_time)))) # Launch the Catalog builder catalog = CatalogBuilder(db, opts, self, report_progress=notification) @@ -407,7 +406,7 @@ class EPUB_MOBI(CatalogPlugin): catalog.build_sources() if opts.verbose: log.info(" Completed catalog source generation (%s)\n" % - unicode_type(datetime.timedelta(seconds=int(time.time() - opts.start_time)))) + str(datetime.timedelta(seconds=int(time.time() - opts.start_time)))) except (AuthorSortMismatchException, EmptyCatalogException) as e: log.error(" *** Terminated catalog generation: %s ***" % e) except: @@ -500,7 +499,7 @@ class EPUB_MOBI(CatalogPlugin): if opts.verbose: log.info(" Catalog creation complete (%s)\n" % - unicode_type(datetime.timedelta(seconds=int(time.time() - opts.start_time)))) + str(datetime.timedelta(seconds=int(time.time() - opts.start_time)))) # returns to gui2.actions.catalog:catalog_generated() return catalog.error diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index e80b2c0798..0a74b3f250 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -43,7 +43,7 @@ from calibre.utils.icu import capitalize, collation_order, sort_key from calibre.utils.img import scale_image from calibre.utils.localization import get_lang, lang_as_iso639_1 from calibre.utils.zipfile import ZipFile -from polyglot.builtins import iteritems, map, unicode_type, zip +from polyglot.builtins import iteritems NBSP = '\u00a0' @@ -52,7 +52,7 @@ def makeelement(tag_name, parent, **attrs): ans = parent.makeelement(tag_name) for k, v in attrs.items(): k = k.replace('_', '-').rstrip('-') - ans.set(k, unicode_type(v)) + ans.set(k, str(v)) parent.append(ans) ans.tail = '\n' return ans @@ -252,7 +252,7 @@ class CatalogBuilder: index = book['series_index'] integer = int(index) fraction = index - integer - series_index = '%04d%s' % (integer, unicode_type('%0.4f' % fraction).lstrip('0')) + series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0')) key = '%s ~%s %s' % (self._kf_author_to_author_sort(book['author']), self.generate_sort_title(book['series']), series_index) @@ -278,7 +278,7 @@ class CatalogBuilder: index = book['series_index'] integer = int(index) fraction = index - integer - series_index = '%04d%s' % (integer, unicode_type('%0.4f' % fraction).lstrip('0')) + series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0')) fs = '{:<%d}~{!s}{!s}' % longest_author_sort key = fs.format(capitalize(book['author_sort']), self.generate_sort_title(book['series']), @@ -289,7 +289,7 @@ class CatalogBuilder: index = book['series_index'] integer = int(index) fraction = index - integer - series_index = '%04d%s' % (integer, unicode_type('%0.4f' % fraction).lstrip('0')) + series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0')) key = '%s %s' % (self.generate_sort_title(book['series']), series_index) return key @@ -613,7 +613,7 @@ class CatalogBuilder: for rule in self.prefix_rules: # Literal comparison for Tags field if rule['field'].lower() == 'tags' or rule['field'] == _('Tags'): - if rule['pattern'].lower() in tuple(map(unicode_type.lower, record['tags'])): + if rule['pattern'].lower() in tuple(map(str.lower, record['tags'])): if self.DEBUG and self.opts.verbose: self.opts.log.info(" %s '%s' by %s (%s: Tags includes '%s')" % (rule['prefix'], record['title'], @@ -643,7 +643,7 @@ class CatalogBuilder: # locale version field_contents = _(repr(field_contents)) try: - if re.search(rule['pattern'], unicode_type(field_contents), + if re.search(rule['pattern'], str(field_contents), re.IGNORECASE) is not None: if self.DEBUG: _log_prefix_rule_match_info(rule, record, field_contents) @@ -715,14 +715,14 @@ class CatalogBuilder: if icu_upper(c[0]) != last_c: last_c = icu_upper(c[0]) if last_c in exceptions.keys(): - last_c = exceptions[unicode_type(last_c)] + last_c = exceptions[str(last_c)] last_ordnum = ordnum cl_list[idx] = last_c else: if last_ordnum != ordnum: last_c = icu_upper(c[0:ordlen]) if last_c in exceptions.keys(): - last_c = exceptions[unicode_type(last_c)] + last_c = exceptions[str(last_c)] last_ordnum = ordnum else: last_c = cl_list[idx-1] @@ -732,7 +732,7 @@ class CatalogBuilder: if last_ordnum != ordnum: last_c = icu_upper(c[0:ordlen]) if last_c in exceptions.keys(): - last_c = exceptions[unicode_type(last_c)] + last_c = exceptions[str(last_c)] last_ordnum = ordnum else: last_c = cl_list[idx-1] @@ -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") @@ -1355,7 +1355,7 @@ class CatalogBuilder: """ # Kindle TOC descriptions won't render certain characters # Fix up - massaged = xml_replace_entities(unicode_type(description)) + massaged = xml_replace_entities(str(description)) # Replace '&' with '&' # massaged = re.sub("&", "&", massaged) @@ -1422,7 +1422,7 @@ class CatalogBuilder: Return: (dict): formatted args for templating """ - series_index = unicode_type(book['series_index']) + series_index = str(book['series_index']) if series_index.endswith('.0'): series_index = series_index[:-2] args = dict( @@ -2701,7 +2701,7 @@ class CatalogBuilder: series_index = '' if book['series']: series = book['series'] - series_index = unicode_type(book['series_index']) + series_index = str(book['series_index']) if series_index.endswith('.0'): series_index = series_index[:-2] @@ -3078,7 +3078,7 @@ class CatalogBuilder: for book in self.books_by_description: sec_id = "book%dID" % int(book['id']) if book['series']: - series_index = unicode_type(book['series_index']) + series_index = str(book['series_index']) if series_index.endswith('.0'): series_index = series_index[:-2] if self.generate_for_kindle_mobi: @@ -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]) @@ -4029,7 +4029,7 @@ class CatalogBuilder: Return: (str): legal XHTML anchor string of unicode character name """ - fullname = ''.join(unicodedata.name(unicode_type(cc)) for cc in c) + fullname = ''.join(unicodedata.name(str(cc)) for cc in c) terms = fullname.split() return "_".join(terms) @@ -4061,7 +4061,7 @@ class CatalogBuilder: matched = list(set(record['tags']) & set(excluded_tags)) if matched: for rule in self.opts.exclusion_rules: - if rule[1] == _('Tags') and rule[2] == unicode_type(matched[0]): + if rule[1] == _('Tags') and rule[2] == str(matched[0]): self.opts.log.info(" - '%s' by %s (Exclusion rule '%s')" % (record['title'], record['authors'][0], rule[0])) @@ -4261,7 +4261,7 @@ class CatalogBuilder: # locale version field_contents = _(repr(field_contents)) - matched = re.search(pat, unicode_type(field_contents), + matched = re.search(pat, str(field_contents), re.IGNORECASE) if matched is not None: if self.opts.verbose: @@ -4350,10 +4350,10 @@ class CatalogBuilder: if self.opts.cli_environment: log_msg = "%3.0f%% %s" % (self.progress_int * 100, self.progress_string) if self.opts.verbose: - log_msg += " (%s)" % unicode_type(datetime.timedelta(seconds=int(time.time() - self.opts.start_time))) + log_msg += " (%s)" % str(datetime.timedelta(seconds=int(time.time() - self.opts.start_time))) else: log_msg = ("%s (%s)" % (self.progress_string, - unicode_type(datetime.timedelta(seconds=int(time.time() - self.opts.start_time))))) + str(datetime.timedelta(seconds=int(time.time() - self.opts.start_time))))) self.opts.log(log_msg) def update_progress_micro_step(self, description, micro_step_pct): diff --git a/src/calibre/library/check_library.py b/src/calibre/library/check_library.py index 4a0112af26..76c5749d36 100644 --- a/src/calibre/library/check_library.py +++ b/src/calibre/library/check_library.py @@ -11,7 +11,7 @@ import re, os, traceback, fnmatch from calibre import isbytestring from calibre.constants import filesystem_encoding from calibre.ebooks import BOOK_EXTENSIONS -from polyglot.builtins import iteritems, filter +from polyglot.builtins import iteritems EBOOK_EXTENSIONS = frozenset(BOOK_EXTENSIONS) NORMALS = frozenset(['metadata.opf', 'cover.jpg']) @@ -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 755192343f..545393d7ce 100644 --- a/src/calibre/library/coloring.py +++ b/src/calibre/library/coloring.py @@ -8,7 +8,6 @@ import re from textwrap import dedent from polyglot.binary import as_hex_unicode, from_hex_bytes -from polyglot.builtins import map color_row_key = '*row' @@ -177,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 f98008147b..d002904233 100644 --- a/src/calibre/library/comments.py +++ b/src/calibre/library/comments.py @@ -12,7 +12,6 @@ from calibre.ebooks.BeautifulSoup import ( ProcessingInstruction ) from calibre.utils.html2text import html2text -from polyglot.builtins import unicode_type # Hackish - ignoring sentences ending or beginning in numbers to avoid # confusion with decimal points. @@ -48,8 +47,8 @@ def comments_to_html(comments): ''' if not comments: - return u'

      ' - if not isinstance(comments, unicode_type): + return '

      ' + if not isinstance(comments, str): comments = comments.decode(preferred_encoding, 'replace') if comments.lstrip().startswith('<'): @@ -58,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) @@ -68,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('.', @@ -79,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 12882df61c..42a50e2791 100644 --- a/src/calibre/library/custom_columns.py +++ b/src/calibre/library/custom_columns.py @@ -14,7 +14,7 @@ from calibre.constants import preferred_encoding from calibre.library.field_metadata import FieldMetadata from calibre.utils.date import parse_date from calibre.utils.config import tweaks -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes class CustomColumns: @@ -131,23 +131,23 @@ class CustomColumns: if d['is_multiple']: if x is None: return [] - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): x = x.split(d['multiple_seps']['ui_to_list']) x = [y.strip() for y in x if y.strip()] x = [y.decode(preferred_encoding, 'replace') if not isinstance(y, - unicode_type) else y for y in x] + str) else y for y in x] return [' '.join(y.split()) for y in x] else: - return x if x is None or isinstance(x, unicode_type) else \ + return x if x is None or isinstance(x, str) else \ x.decode(preferred_encoding, 'replace') def adapt_datetime(x, d): - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): x = parse_date(x, assume_utc=False, as_utc=False) return x def adapt_bool(x, d): - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): if isinstance(x, bytes): x = force_unicode(x) x = x.lower() @@ -170,7 +170,7 @@ class CustomColumns: def adapt_number(x, d): if x is None: return None - if isinstance(x, (unicode_type, bytes)): + if isinstance(x, (str, bytes)): if isinstance(x, bytes): x = force_unicode(x) if x.lower() == 'none': @@ -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 d0ee2f88a3..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 ' @@ -15,7 +13,6 @@ from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.metadata import string_to_authors from calibre.utils.serialize import pickle_loads, pickle_dumps from calibre import isbytestring -from polyglot.builtins import unicode_type, filter, map class Concatenate: @@ -55,7 +52,7 @@ class Connection(sqlite.Connection): def _connect(path): - if isinstance(path, unicode_type): + if isinstance(path, str): path = path.encode('utf-8') conn = sqlite.connect(path, factory=Connection, detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES) conn.row_factory = lambda cursor, row : list(row) @@ -1384,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 2209fc8333..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' @@ -49,7 +47,7 @@ from calibre.db.lazy import FormatMetadata, FormatsList from calibre.db.categories import Tag, CATEGORY_SORTS from calibre.utils.localization import (canonicalize_lang, calibre_langcode_to_name) -from polyglot.builtins import iteritems, unicode_type, string_or_bytes, map +from polyglot.builtins import iteritems, string_or_bytes copyfile = os.link if hasattr(os, 'link') else shutil.copyfile SPOOL_SIZE = 30*1024*1024 @@ -93,7 +91,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if self._library_id_ is None: ans = self.conn.get('SELECT uuid FROM library_id', all=False) if ans is None: - ans = unicode_type(uuid.uuid4()) + ans = str(uuid.uuid4()) self.library_id = ans else: self._library_id_ = ans @@ -101,7 +99,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): @library_id.setter def library_id(self, val): - self._library_id_ = unicode_type(val) + self._library_id_ = str(val) self.conn.executescript(''' DELETE FROM library_id; INSERT INTO library_id (uuid) VALUES ("%s"); @@ -258,11 +256,11 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): from calibre.library.coloring import migrate_old_rule old_rules = [] for i in range(1, 6): - col = self.prefs.get('column_color_name_'+unicode_type(i), None) - templ = self.prefs.get('column_color_template_'+unicode_type(i), None) + col = self.prefs.get('column_color_name_'+str(i), None) + templ = self.prefs.get('column_color_template_'+str(i), None) if col and templ: try: - del self.prefs['column_color_name_'+unicode_type(i)] + del self.prefs['column_color_name_'+str(i)] rules = migrate_old_rule(self.field_metadata, templ) for templ in rules: old_rules.append((col, templ)) @@ -328,10 +326,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): prints('found user category case overlap', catmap[uc]) cat = catmap[uc][0] suffix = 1 - while icu_lower((cat + unicode_type(suffix))) in catmap: + while icu_lower(cat + str(suffix)) in catmap: suffix += 1 - prints('Renaming user category %s to %s'%(cat, cat+unicode_type(suffix))) - user_cats[cat + unicode_type(suffix)] = user_cats[cat] + prints('Renaming user category %s to %s'%(cat, cat+str(suffix))) + user_cats[cat + str(suffix)] = user_cats[cat] del user_cats[cat] cats_changed = True if cats_changed: @@ -452,7 +450,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): # account for the series index column. Field_metadata knows that # the series index is one larger than the series. If you change # it here, be sure to change it there as well. - self.FIELD_MAP[unicode_type(col)+'_index'] = base = base+1 + self.FIELD_MAP[str(col)+'_index'] = base = base+1 self.field_metadata.set_field_record_index( self.custom_column_num_map[col]['label']+'_index', base, @@ -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: @@ -1086,7 +1084,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): def has_book(self, mi): title = mi.title if title: - if not isinstance(title, unicode_type): + if not isinstance(title, str): title = title.decode(preferred_encoding, 'replace') return bool(self.conn.get('SELECT id FROM books where title=?', (title,), all=False)) return False @@ -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 @@ -1762,8 +1760,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if len(comps) == 0: i = 1 while True: - if unicode_type(i) not in user_cats: - new_cats[unicode_type(i)] = user_cats[k] + if str(i) not in user_cats: + new_cats[str(i)] = user_cats[k] break i += 1 else: @@ -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: @@ -1989,7 +1987,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): formatter = calibre_langcode_to_name items = [v for v in tcategories[category].values() if v.c > 0] else: - formatter = (lambda x:unicode_type(x)) + formatter = (lambda x:str(x)) items = [v for v in tcategories[category].values() if v.c > 0] # sort the list @@ -2460,7 +2458,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if not a: continue a = a.strip().replace(',', '|') - if not isinstance(a, unicode_type): + if not isinstance(a, str): a = a.decode(preferred_encoding, 'replace') aus = self.conn.get('SELECT id, name, sort FROM authors WHERE name=?', (a,)) if aus: @@ -2619,7 +2617,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): def set_timestamp(self, id, dt, notify=True, commit=True): if dt: - if isinstance(dt, (unicode_type, bytes)): + if isinstance(dt, (str, bytes)): dt = parse_date(dt, as_utc=True, assume_utc=False) self.conn.execute('UPDATE books SET timestamp=? WHERE id=?', (dt, id)) self.data.set(id, self.FIELD_MAP['timestamp'], dt, row_is_id=True) @@ -2648,7 +2646,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): books_to_refresh = {id} if publisher: case_change = False - if not isinstance(publisher, unicode_type): + if not isinstance(publisher, str): publisher = publisher.decode(preferred_encoding, 'replace') pubx = self.conn.get('''SELECT id,name from publishers WHERE name=?''', (publisher,)) @@ -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: @@ -3093,7 +3091,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): tag = tag.strip() if not tag: continue - if not isinstance(tag, unicode_type): + if not isinstance(tag, str): tag = tag.decode(preferred_encoding, 'replace') existing_tags = self.all_tags() lt = [t.lower() for t in existing_tags] @@ -3174,7 +3172,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): books_to_refresh = {id} if series: case_change = False - if not isinstance(series, unicode_type): + if not isinstance(series, str): series = series.decode(preferred_encoding, 'replace') series = series.strip() series = ' '.join(series.split()) @@ -3545,7 +3543,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): aus = mi.author_sort if mi.author_sort else self.author_sort_from_authors(mi.authors) if isinstance(aus, bytes): aus = aus.decode(preferred_encoding, 'replace') - title = mi.title if isinstance(mi.title, unicode_type) else \ + title = mi.title if isinstance(mi.title, str) else \ mi.title.decode(preferred_encoding, 'replace') obj = self.conn.execute('INSERT INTO books(title, series_index, author_sort) VALUES (?, ?, ?)', (title, series_index, aus)) @@ -3615,7 +3613,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): os.remove(dest) shutil.copyfile(src, dest) x = path_map[x] - if not isinstance(x, unicode_type): + if not isinstance(x, str): x = x.decode(filesystem_encoding, 'replace') progress(x) 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/prefs.py b/src/calibre/library/prefs.py index 9e1556eb98..4ef2cc8795 100644 --- a/src/calibre/library/prefs.py +++ b/src/calibre/library/prefs.py @@ -11,7 +11,7 @@ import json, os from calibre.constants import preferred_encoding from calibre.utils.config import to_json, from_json from calibre import prints -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class DBPrefs(dict): @@ -30,7 +30,7 @@ class DBPrefs(dict): dict.__setitem__(self, key, val) def raw_to_object(self, raw): - if not isinstance(raw, unicode_type): + if not isinstance(raw, str): raw = raw.decode(preferred_encoding) return json.loads(raw, object_hook=from_json) diff --git a/src/calibre/library/restore.py b/src/calibre/library/restore.py index 9648f94097..f0b2d8ee6d 100644 --- a/src/calibre/library/restore.py +++ b/src/calibre/library/restore.py @@ -17,7 +17,7 @@ from calibre.library.prefs import DBPrefs from calibre.constants import filesystem_encoding from calibre.utils.date import utcfromtimestamp from calibre import isbytestring -from polyglot.builtins import iteritems, filter +from polyglot.builtins import iteritems NON_EBOOK_EXTENSIONS = frozenset([ 'jpg', 'jpeg', 'gif', 'png', 'bmp', @@ -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 6872a3672f..afa58c8c7f 100644 --- a/src/calibre/library/save_to_disk.py +++ b/src/calibre/library/save_to_disk.py @@ -19,7 +19,6 @@ from calibre.ebooks.metadata import title_sort from calibre.utils.date import as_local_time from calibre import strftime, prints, sanitize_file_name from calibre.db.lazy import FormatsList -from polyglot.builtins import unicode_type plugboard_any_device_value = 'any device' plugboard_any_format_value = 'any format' @@ -132,7 +131,7 @@ def preprocess_template(template): template = template.replace('//', '/') template = template.replace('{author}', '{authors}') template = template.replace('{tag}', '{tags}') - if not isinstance(template, unicode_type): + if not isinstance(template, str): template = template.decode(preferred_encoding, 'replace') return template @@ -215,7 +214,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250, if hasattr(mi, 'last_modified') and hasattr(mi.last_modified, 'timetuple'): format_args['last_modified'] = strftime(timefmt, mi.last_modified.timetuple()) - format_args['id'] = unicode_type(id) + format_args['id'] = str(id) # Now format the custom fields custom_metadata = mi.get_all_user_metadata(make_copy=False) for key in custom_metadata: @@ -234,7 +233,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250, divide_by=2.0) elif cm['datatype'] in ['int', 'float']: if format_args[key] != 0: - format_args[key] = unicode_type(format_args[key]) + format_args[key] = str(format_args[key]) else: format_args[key] = '' if safe_format: @@ -245,7 +244,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250, components = [x.strip() for x in components.split('/')] components = [sanitize_func(x) for x in components if x] if not components: - components = [unicode_type(id)] + components = [str(id)] if to_lowercase: components = [x.lower() for x in components] if replace_whitespace: @@ -334,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 @@ -358,7 +357,7 @@ def do_save_book_to_disk(db, book_id, mi, plugboards, return not formats_written, book_id, mi.title for fmt in formats: - fmt_path = base_path+'.'+unicode_type(fmt) + fmt_path = base_path+'.'+str(fmt) try: db.copy_format_to(book_id, fmt, fmt_path) formats_written = True diff --git a/src/calibre/library/schema_upgrades.py b/src/calibre/library/schema_upgrades.py index b11d9dc161..d71c90fd5c 100644 --- a/src/calibre/library/schema_upgrades.py +++ b/src/calibre/library/schema_upgrades.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import os from calibre.utils.date import isoformat, DEFAULT_DATE -from polyglot.builtins import itervalues, unicode_type +from polyglot.builtins import itervalues class SchemaUpgrade: @@ -593,10 +593,10 @@ class SchemaUpgrade: existing = frozenset(map(int, custom_recipes)) if id_ in existing: id_ = max(existing) + 1000 - id_ = unicode_type(id_) + id_ = str(id_) fname = custom_recipe_filename(id_, title) custom_recipes[id_] = (title, fname) - if isinstance(script, unicode_type): + if isinstance(script, str): script = script.encode('utf-8') with open(os.path.join(bdir, fname), 'wb') as f: f.write(script) diff --git a/src/calibre/library/sqlite.py b/src/calibre/library/sqlite.py index c2a901d7ad..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' @@ -23,7 +21,7 @@ from calibre.constants import iswindows, DEBUG, plugins_loc from calibre.utils.icu import sort_key from calibre_extensions import speedup as _c_speedup from calibre import prints -from polyglot.builtins import cmp, native_string_type, unicode_type +from polyglot.builtins import cmp, native_string_type from polyglot import reprlib from polyglot.queue import Queue @@ -268,7 +266,7 @@ def do_connect(path, row_factory=None): conn.create_function('title_sort', 1, title_sort) conn.create_function('author_to_author_sort', 1, _author_to_author_sort) - conn.create_function('uuid4', 0, lambda : unicode_type(uuid.uuid4())) + conn.create_function('uuid4', 0, lambda : str(uuid.uuid4())) # Dummy functions for dynamically created filters conn.create_function('books_list_filter', 1, lambda x: 1) conn.create_collation(native_string_type('icucollate'), icu_collator) @@ -321,7 +319,7 @@ class DBThread(Thread): break except OperationalError as err: # Retry if unable to open db file - e = unicode_type(err) + e = str(err) if 'unable to open' not in e or i == 2: if 'unable to open' in e: prints('Unable to open database for func', @@ -341,7 +339,7 @@ class DatabaseException(Exception): def __init__(self, err, tb): tb = '\n\t'.join(('\tRemote'+tb).splitlines()) try: - msg = unicode_type(err) +'\n' + tb + msg = str(err) +'\n' + tb except: msg = repr(err) + '\n' + tb Exception.__init__(self, msg) @@ -362,7 +360,7 @@ def proxy(fn): ok, res = self.proxy.results.get() if not ok: if isinstance(res[0], IntegrityError): - raise IntegrityError(unicode_type(res[0])) + raise IntegrityError(str(res[0])) raise DatabaseException(*res) return res return run diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 1037c3dd0a..8a4e6e0adb 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -13,7 +13,7 @@ from calibre.constants import islinux, isbsd from calibre.customize.ui import all_input_formats from calibre.ptempfile import TemporaryDirectory from calibre import CurrentDir -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems entry_points = { @@ -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 # }}} @@ -276,7 +276,7 @@ class ZshCompleter: # {{{ h = opt.help or '' h = h.replace('"', "'").replace('[', '(').replace( ']', ')').replace('\n', ' ').replace(':', '\\:').replace('`', "'") - h = h.replace('%default', unicode_type(opt.default)) + h = h.replace('%default', str(opt.default)) arg = '' if opt.takes_value(): arg = ':"%s":'%h @@ -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') @@ -434,12 +434,12 @@ class ZshCompleter: # {{{ h = opt.help or '' h = h.replace('"', "'").replace('[', '(').replace( ']', ')').replace('\n', ' ').replace(':', '\\:').replace('`', "'") - h = h.replace('%default', unicode_type(opt.default)) + h = h.replace('%default', str(opt.default)) help_txt = '"[%s]"'%h 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): @@ -831,11 +831,11 @@ class PostInstall: self.info('Installing bash completion to:', bash_comp_dest+os.sep) write_completion(self, bash_comp_dest, zsh) except TypeError as err: - if 'resolve_entities' in unicode_type(err): + if 'resolve_entities' in str(err): 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: @@ -879,11 +879,11 @@ class PostInstall: def install_single_icon(iconsrc, basename, size, context, is_last_icon=False): filename = '%s-%s.png' % (basename, size) render_img(iconsrc, filename, width=int(size), height=int(size)) - cmd = ['xdg-icon-resource', 'install', '--noupdate', '--context', context, '--size', unicode_type(size), filename, basename] + cmd = ['xdg-icon-resource', 'install', '--noupdate', '--context', context, '--size', str(size), filename, basename] if is_last_icon: del cmd[2] cc(cmd) - self.icon_resources.append((context, basename, unicode_type(size))) + self.icon_resources.append((context, basename, str(size))) def install_icons(iconsrc, basename, context, is_last_icon=False): sizes = (16, 32, 48, 64, 128, 256) @@ -1252,7 +1252,7 @@ def write_appdata(key, entry, base, translators): fpath = os.path.join(base, '%s.metainfo.xml' % key) screenshots = E.screenshots() for w, h, url in entry['screenshots']: - s = E.screenshot(E.image(url, width=unicode_type(w), height=unicode_type(h))) + s = E.screenshot(E.image(url, width=str(w), height=str(h))) screenshots.append(s) screenshots[0].set('type', 'default') description = E.description() diff --git a/src/calibre/ptempfile.py b/src/calibre/ptempfile.py index bb6e3461d1..c0588dbb64 100644 --- a/src/calibre/ptempfile.py +++ b/src/calibre/ptempfile.py @@ -1,4 +1,3 @@ - __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' """ @@ -6,7 +5,6 @@ Provides platform independent temporary files that persist even after being closed. """ import tempfile, os, atexit -from polyglot.builtins import map, getenv from calibre.constants import (__version__, __appname__, filesystem_encoding, iswindows, get_windows_temp_path, ismacos) @@ -102,7 +100,7 @@ def base_dir(): else: base = os.environ.get('CALIBRE_TEMP_DIR', None) if base is not None and iswindows: - base = getenv('CALIBRE_TEMP_DIR') + base = os.getenv('CALIBRE_TEMP_DIR') prefix = app_prefix('tmp_') if base is None: if iswindows: 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/spell/dictionary.py b/src/calibre/spell/dictionary.py index 963f50d7ed..b1b7f73d04 100644 --- a/src/calibre/spell/dictionary.py +++ b/src/calibre/spell/dictionary.py @@ -19,7 +19,7 @@ from calibre.spell import parse_lang_code from calibre.utils.config import JSONConfig from calibre.utils.icu import capitalize from calibre.utils.localization import get_lang, get_system_locale -from polyglot.builtins import filter, iteritems, itervalues, map, unicode_type +from polyglot.builtins import iteritems, itervalues Dictionary = namedtuple('Dictionary', 'primary_locale locales dicpath affpath builtin name id') LoadedDictionary = namedtuple('Dictionary', 'primary_locale locales obj builtin name id') @@ -397,7 +397,7 @@ class Dictionaries: if d is not None: try: - ans = d.obj.suggest(unicode_type(word).replace('\u2010', '-')) + ans = d.obj.suggest(str(word).replace('\u2010', '-')) except ValueError: pass else: diff --git a/src/calibre/srv/ajax.py b/src/calibre/srv/ajax.py index 74507f7f19..0215e49118 100644 --- a/src/calibre/srv/ajax.py +++ b/src/calibre/srv/ajax.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2015, Kovid Goyal ' from functools import partial -from polyglot.builtins import iteritems, itervalues, unicode_type, zip, string_or_bytes, map +from polyglot.builtins import iteritems, itervalues, string_or_bytes from itertools import cycle from calibre import force_unicode @@ -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: @@ -115,7 +115,7 @@ def book_to_json(ctx, rd, db, book_id, dbtags[category] = ctx.url_for( books_in, encoded_category=encode_name(tag.category if tag.category else key), - encoded_item=encode_name(tag.original_name if tag.id is None else unicode_type(tag.id)), + encoded_item=encode_name(tag.original_name if tag.id is None else str(tag.id)), library_id=db.server_library_id ) break @@ -134,7 +134,7 @@ def book_to_json(ctx, rd, db, book_id, for device_class in device_plugins(): if device_class.__class__.__name__ == device_for_template: template = device_class.save_template() - data['_filename_'] = create_upload_path(mi, unicode_type(book_id), + data['_filename_'] = create_upload_path(mi, str(book_id), template, sanitize, path_type=posixpath) break @@ -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] @@ -445,7 +445,7 @@ def category(ctx, rd, encoded_name, library_id): 'average_rating': x.avg_rating, 'count': x.count, 'url': ctx.url_for(books_in, encoded_category=encode_name(x.category if x.category else toplevel), - encoded_item=encode_name(x.original_name if x.id is None else unicode_type(x.id)), + encoded_item=encode_name(x.original_name if x.id is None else str(x.id)), library_id=db.server_library_id ), 'has_children': x.original_name in children, @@ -551,7 +551,7 @@ def search_result(ctx, rd, db, query, num, offset, sort, sort_order, vl=''): 'vl': vl, } if parse_error is not None: - ans['bad_restriction'] = unicode_type(parse_error) + ans['bad_restriction'] = str(parse_error) return ans 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 a0e3a7b487..955c669374 100644 --- a/src/calibre/srv/books.py +++ b/src/calibre/srv/books.py @@ -21,7 +21,7 @@ from calibre.srv.routes import endpoint, json from calibre.srv.utils import get_db, get_library_data from calibre.utils.filenames import rmtree from calibre.utils.serialize import json_dumps -from polyglot.builtins import as_unicode, itervalues, map +from polyglot.builtins import as_unicode, itervalues cache_lock = RLock() queued_jobs = {} @@ -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/changes.py b/src/calibre/srv/changes.py index fcde249177..9d9e29b233 100644 --- a/src/calibre/srv/changes.py +++ b/src/calibre/srv/changes.py @@ -3,9 +3,6 @@ # License: GPLv3 Copyright: 2017, Kovid Goyal -from polyglot.builtins import map - - class ChangeEvent: def __init__(self): 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 3e2826873b..6254bbec1f 100644 --- a/src/calibre/srv/content.py +++ b/src/calibre/srv/content.py @@ -9,7 +9,6 @@ import os, errno from io import BytesIO from threading import Lock from contextlib import suppress -from polyglot.builtins import map, unicode_type from functools import partial from calibre import fit_image, sanitize_file_name @@ -48,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') @@ -103,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) @@ -165,7 +164,7 @@ def book_filename(rd, book_id, mi, fmt, as_encoded_unicode=False): if as_encoded_unicode: # See https://tools.ietf.org/html/rfc6266 fname = sanitize_file_name(fname).encode('utf-8') - fname = unicode_type(quote(fname)) + fname = str(quote(fname)) else: fname = ascii_filename(fname).replace('"', '_') if ext == 'kepub' and 'Kobo Touch' in rd.inheaders.get('User-Agent', ''): @@ -227,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() @@ -266,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/handler.py b/src/calibre/srv/handler.py index 6842d30faa..c2ce1fdcdd 100644 --- a/src/calibre/srv/handler.py +++ b/src/calibre/srv/handler.py @@ -15,7 +15,7 @@ from calibre.srv.routes import Router from calibre.srv.users import UserManager from calibre.utils.date import utcnow from calibre.utils.search_query_parser import ParseException -from polyglot.builtins import itervalues, filter, unicode_type +from polyglot.builtins import itervalues class Context: @@ -148,7 +148,7 @@ class Context: if old is None or old[0] <= db.last_modified(): categories = db.get_categories(book_ids=restrict_to_ids, sort=opts.sort_by, first_letter_sort=opts.collapse_model == 'first letter') data = json.dumps(render(db, categories), ensure_ascii=False) - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') cache[key] = old = (utcnow(), data) if len(cache) > self.CATEGORY_CACHE_SIZE: diff --git a/src/calibre/srv/http_request.py b/src/calibre/srv/http_request.py index 394fc2e0cf..a27ecaff92 100644 --- a/src/calibre/srv/http_request.py +++ b/src/calibre/srv/http_request.py @@ -15,7 +15,7 @@ from calibre.srv.loop import Connection, READ, WRITE from calibre.srv.utils import MultiDict, HTTP1, HTTP11, Accumulator from polyglot import http_client, reprlib from polyglot.urllib import unquote -from polyglot.builtins import error_message, filter +from polyglot.builtins import error_message protocol_map = {(1, 0):HTTP1, (1, 1):HTTP11} quoted_slash = re.compile(br'%2[fF]') diff --git a/src/calibre/srv/http_response.py b/src/calibre/srv/http_response.py index b180af31b6..a20b2fc6d0 100644 --- a/src/calibre/srv/http_response.py +++ b/src/calibre/srv/http_response.py @@ -29,8 +29,7 @@ from calibre.utils.monotonic import monotonic from calibre.utils.speedups import ReadOnlyFileBuffer from polyglot import http_client, reprlib from polyglot.builtins import ( - error_message, iteritems, itervalues, map, reraise, string_or_bytes, - unicode_type + error_message, iteritems, itervalues, reraise, string_or_bytes ) Range = namedtuple('Range', 'start stop size') @@ -131,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 @@ -255,7 +254,7 @@ class RequestData: # {{{ def filesystem_file_with_custom_etag(self, output, *etag_parts): etag = hashlib.sha1() - tuple(map(lambda x:etag.update(unicode_type(x).encode('utf-8')), etag_parts)) + tuple(map(lambda x:etag.update(str(x).encode('utf-8')), etag_parts)) return ETaggedFile(output, etag.hexdigest()) def filesystem_file_with_constant_etag(self, output, etag_as_hexencoded_string): @@ -321,8 +320,8 @@ def filesystem_file_output(output, outheaders, stat_result): if etag is None: oname = output.name or '' if not isinstance(oname, string_or_bytes): - oname = unicode_type(oname) - etag = hashlib.sha1((unicode_type(stat_result.st_mtime) + force_unicode(oname)).encode('utf-8')).hexdigest() + oname = str(oname) + etag = hashlib.sha1((str(stat_result.st_mtime) + force_unicode(oname)).encode('utf-8')).hexdigest() else: output = output.output etag = '"%s"' % etag @@ -366,7 +365,7 @@ class GeneratedOutput: class StaticOutput: def __init__(self, data): - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') self.data = data self.etag = '"%s"' % hashlib.sha1(data).hexdigest() @@ -403,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) @@ -659,7 +658,7 @@ class HTTPConnection(HTTPRequest): if 'Content-Type' not in outheaders: output_name = output.name if not isinstance(output_name, string_or_bytes): - output_name = unicode_type(output_name) + output_name = str(output_name) mt = guess_type(output_name)[0] if mt: if mt in {'text/plain', 'text/html', 'application/javascript', 'text/css'}: 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 c3a782e668..307c705e95 100644 --- a/src/calibre/srv/legacy.py +++ b/src/calibre/srv/legacy.py @@ -18,7 +18,7 @@ from calibre.srv.routes import endpoint from calibre.srv.utils import get_library_data, http_date from calibre.utils.cleantext import clean_xml_chars from calibre.utils.date import dt_as_local, is_date_undefined, timestampfromdt -from polyglot.builtins import iteritems, string_or_bytes, filter, as_bytes, unicode_type +from polyglot.builtins import iteritems, string_or_bytes, as_bytes from polyglot.urllib import urlencode # /mobile {{{ @@ -62,10 +62,10 @@ def build_search_box(num, search, sort, order, ctx, field_metadata, library_id): num_select = E.select(name='num') for option in (5, 10, 25, 100): - kwargs = {'value':unicode_type(option)} + kwargs = {'value':str(option)} if option == num: kwargs['SELECTED'] = 'SELECTED' - num_select.append(E.option(unicode_type(option), **kwargs)) + num_select.append(E.option(str(option), **kwargs)) num_select.tail = ' books matching ' form.append(num_select) @@ -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 70c18092dc..18bf483da2 100644 --- a/src/calibre/srv/loop.py +++ b/src/calibre/srv/loop.py @@ -30,7 +30,7 @@ from calibre.utils.logging import ThreadSafeLog from calibre.utils.mdns import get_external_ip from calibre.utils.monotonic import monotonic from calibre.utils.socket_inheritance import set_socket_inherit -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems from polyglot.queue import Empty, Full READ, WRITE, RDWR, WAIT = 'READ', 'WRITE', 'RDWR', 'WAIT' @@ -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() @@ -503,7 +503,7 @@ class ServerLoop: self.socket.listen(min(socket.SOMAXCONN, 128)) self.bound_address = ba = self.socket.getsockname() if isinstance(ba, tuple): - ba = ':'.join(map(unicode_type, ba)) + ba = ':'.join(map(str, ba)) self.pool.start() with TemporaryDirectory(prefix='srv-') as tdir: self.tdir = tdir @@ -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/manage_users_cli.py b/src/calibre/srv/manage_users_cli.py index d00a99be54..16fce3d214 100644 --- a/src/calibre/srv/manage_users_cli.py +++ b/src/calibre/srv/manage_users_cli.py @@ -8,7 +8,7 @@ from functools import partial from calibre import prints from calibre.constants import preferred_encoding, iswindows from calibre.utils.config import OptionParser -from polyglot.builtins import iteritems, raw_input, filter, unicode_type +from polyglot.builtins import iteritems def create_subcommand_parser(name, usage): @@ -102,7 +102,7 @@ def manage_users_cli(path=None, args=()): def get_input(prompt): prints(prompt, end=' ') - ans = raw_input() + ans = input() if isinstance(ans, bytes): ans = ans.decode(enc) if iswindows: @@ -123,7 +123,7 @@ def manage_users_cli(path=None, args=()): len(choices), _('default'), default + 1) reply = get_input(prompt) if not reply and default is not None: - reply = unicode_type(default + 1) + reply = str(default + 1) if not reply: prints(_('No choice selected, exiting...')) raise SystemExit(0) diff --git a/src/calibre/srv/metadata.py b/src/calibre/srv/metadata.py index eb6cc56875..51e72b54c1 100644 --- a/src/calibre/srv/metadata.py +++ b/src/calibre/srv/metadata.py @@ -21,7 +21,7 @@ from calibre.utils.icu import collation_order from calibre.utils.localization import calibre_langcode_to_name from calibre.library.comments import comments_to_html, markdown from calibre.library.field_metadata import category_icon_map -from polyglot.builtins import iteritems, itervalues, range, filter, unicode_type +from polyglot.builtins import iteritems, itervalues from polyglot.urllib import quote IGNORED_FIELDS = frozenset('cover ondevice path marked au_map'.split()) @@ -116,7 +116,7 @@ def category_as_json(items, category, display_name, count, tooltip=None, parent= ans['is_user_category'] = True if is_first_letter: ans['is_first_letter'] = True - item_id = 'c' + unicode_type(len(items)) + item_id = 'c' + str(len(items)) items[item_id] = ans return item_id @@ -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/opds.py b/src/calibre/srv/opds.py index 0d442cdeb8..f19dd164cf 100644 --- a/src/calibre/srv/opds.py +++ b/src/calibre/srv/opds.py @@ -28,7 +28,7 @@ from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import ParseException from calibre.utils.xml_parse import safe_xml_fromstring from polyglot.binary import as_hex_unicode, from_hex_unicode -from polyglot.builtins import as_bytes, filter, iteritems, unicode_type +from polyglot.builtins import as_bytes, iteritems from polyglot.urllib import unquote_plus, urlencode @@ -37,7 +37,7 @@ def atom(ctx, rd, endpoint, output): rd.outheaders.set('Calibre-Instance-Id', force_unicode(prefs['installation_uuid'], 'utf-8'), replace_all=True) if isinstance(output, bytes): ans = output # Assume output is already UTF-8 XML - elif isinstance(output, unicode_type): + elif isinstance(output, str): ans = output.encode('utf-8') else: ans = etree.tostring(output, encoding='utf-8', xml_declaration=True, pretty_print=True) @@ -144,7 +144,7 @@ def CATALOG_ENTRY(item, item_kind, request_context, updated, catalog_name, id_ = 'calibre:category:'+item.name iid = 'N' + item.name if item.id is not None: - iid = 'I' + unicode_type(item.id) + iid = 'I' + str(item.id) iid += ':'+item_kind href = request_context.url_for('/opds/category', category=as_hex_unicode(catalog_name), which=as_hex_unicode(iid)) link = NAVLINK(href=href) @@ -203,9 +203,9 @@ def ACQUISITION_ENTRY(book_id, updated, request_context): fm['is_multiple']['ui_to_list'], joinval=fm['is_multiple']['list_to_ui'])))) elif datatype == 'comments' or (fm['datatype'] == 'composite' and fm['display'].get('contains_html', False)): - extra.append('%s: %s
      '%(xml(name), comments_to_html(unicode_type(val)))) + extra.append('%s: %s
      '%(xml(name), comments_to_html(str(val)))) else: - extra.append('%s: %s
      '%(xml(name), xml(unicode_type(val)))) + extra.append('%s: %s
      '%(xml(name), xml(str(val)))) if mi.comments: comments = comments_to_html(mi.comments) extra.append(comments) @@ -228,7 +228,7 @@ def ACQUISITION_ENTRY(book_id, updated, request_context): link = E.link(type=mt, href=get(what=fmt), rel="http://opds-spec.org/acquisition") ffm = fm.get(fmt.upper()) if ffm: - link.set('length', unicode_type(ffm['size'])) + link.set('length', str(ffm['size'])) link.set('mtime', ffm['mtime'].isoformat()) ans.append(link) ans.append(E.link(type='image/jpeg', href=get(what='cover'), rel="http://opds-spec.org/cover")) @@ -571,7 +571,7 @@ def opds_category(ctx, rd, category, which): ids = rc.db.get_books_for_category(q, which) & rc.allowed_book_ids() sort_by = 'series' if category == 'series' else 'title' - return get_acquisition_feed(rc, ids, offset, page_url, up_url, 'calibre-category:'+category+':'+unicode_type(which), sort_by=sort_by) + return get_acquisition_feed(rc, ids, offset, page_url, up_url, 'calibre-category:'+category+':'+str(which), sort_by=sort_by) @endpoint('/opds/categorygroup/{category}/{which}', postprocess=atom) 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/pool.py b/src/calibre/srv/pool.py index b7ce2e2d06..53ceedfcaa 100644 --- a/src/calibre/srv/pool.py +++ b/src/calibre/srv/pool.py @@ -9,7 +9,6 @@ import sys from threading import Thread from calibre.utils.monotonic import monotonic -from polyglot.builtins import range from polyglot.queue import Queue, Full 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 6c82ad375c..b9fb136466 100644 --- a/src/calibre/srv/render_book.py +++ b/src/calibre/srv/render_book.py @@ -47,7 +47,7 @@ from polyglot.binary import ( as_base64_unicode as encode_component, from_base64_bytes, from_base64_unicode as decode_component ) -from polyglot.builtins import as_bytes, iteritems, map, unicode_type +from polyglot.builtins import as_bytes, iteritems from polyglot.urllib import quote, urlparse RENDER_VERSION = 1 @@ -108,7 +108,7 @@ def create_link_replacer(container, link_uid, changed): frag = urlunquote(frag) url = resource_template.format(encode_url(name, frag)) else: - if isinstance(name, unicode_type): + if isinstance(name, str): name = name.encode('utf-8') url = 'missing:' + force_unicode(quote(name), 'utf-8') changed.add(base) @@ -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,13 +764,12 @@ 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 for bm in parse_bookmarks(raw): - if bm['type'] == 'cfi' and isinstance(bm['pos'], unicode_type): + if bm['type'] == 'cfi' and isinstance(bm['pos'], str): spine_index = (1 + bm['spine']) * 2 epubcfi = 'epubcfi(/{}/{})'.format(spine_index, bm['pos'].lstrip('/')) title = bm.get('title') diff --git a/src/calibre/srv/routes.py b/src/calibre/srv/routes.py index 052fdd86f0..6feb8c1d73 100644 --- a/src/calibre/srv/routes.py +++ b/src/calibre/srv/routes.py @@ -11,7 +11,7 @@ from operator import attrgetter from calibre.srv.errors import HTTPSimpleResponse, HTTPNotFound, RouteError from calibre.srv.utils import http_date from calibre.utils.serialize import msgpack_dumps, json_dumps, MSGPACK_MIME -from polyglot.builtins import iteritems, itervalues, unicode_type, range, zip, filter +from polyglot.builtins import iteritems, itervalues from polyglot import http_client from polyglot.urllib import quote as urlquote @@ -142,7 +142,7 @@ class Route: default = self.defaults[name] = eval(default) if isinstance(default, numbers.Number): self.type_checkers[name] = type(default) - if is_sponge and not isinstance(default, unicode_type): + if is_sponge and not isinstance(default, str): raise route_error('Soak up path component must have a default value of string type') else: if found_optional_part is not False: @@ -201,9 +201,9 @@ class Route: raise RouteError('The variable(s) %s are not part of the route: %s' % (','.join(unknown), self.endpoint.route)) def quoted(x): - if not isinstance(x, (unicode_type, bytes)): - x = unicode_type(x) - if isinstance(x, unicode_type): + if not isinstance(x, (str, bytes)): + x = str(x) + if isinstance(x, str): x = x.encode('utf-8') return urlquote(x, '') args = {k:'' for k in self.defaults} diff --git a/src/calibre/srv/standalone.py b/src/calibre/srv/standalone.py index ef4e2063d6..695f064996 100644 --- a/src/calibre/srv/standalone.py +++ b/src/calibre/srv/standalone.py @@ -24,7 +24,7 @@ from calibre.srv.utils import HandleInterrupt, RotatingLog from calibre.utils.config import prefs from calibre.utils.localization import localize_user_manual_link from calibre.utils.lock import singleinstance -from polyglot.builtins import error_message, unicode_type +from polyglot.builtins import error_message from calibre_extensions import speedup @@ -236,7 +236,7 @@ def main(args=sys.argv): daemonize() if opts.pidfile: with lopen(opts.pidfile, 'wb') as f: - f.write(unicode_type(os.getpid()).encode('ascii')) + f.write(str(os.getpid()).encode('ascii')) signal.signal(signal.SIGTERM, lambda s, f: server.stop()) if not getattr(opts, 'daemonize', False) and not iswindows: signal.signal(signal.SIGHUP, lambda s, f: server.stop()) 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/auth.py b/src/calibre/srv/tests/auth.py index ec9c955fab..4ed05922a5 100644 --- a/src/calibre/srv/tests/auth.py +++ b/src/calibre/srv/tests/auth.py @@ -16,7 +16,7 @@ from calibre.ptempfile import TemporaryDirectory from calibre.srv.errors import HTTPForbidden from calibre.srv.tests.base import BaseTest, TestServer from calibre.srv.routes import endpoint, Router -from polyglot.builtins import iteritems, itervalues, map +from polyglot.builtins import iteritems, itervalues from polyglot import http_client from polyglot.http_cookie import CookieJar from polyglot.urllib import (build_opener, HTTPBasicAuthHandler, 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 2fb59521ca..348890c66e 100644 --- a/src/calibre/srv/tests/http.py +++ b/src/calibre/srv/tests/http.py @@ -13,7 +13,7 @@ from calibre import guess_type from calibre.srv.tests.base import BaseTest, TestServer from calibre.srv.utils import eintr_retry_call from calibre.utils.monotonic import monotonic -from polyglot.builtins import iteritems, range, unicode_type +from polyglot.builtins import iteritems from polyglot import http_client is_ci = os.environ.get('CI', '').lower() == 'true' @@ -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', @@ -186,7 +186,7 @@ class TestHTTP(BaseTest): r = conn.getresponse() self.ae(r.status, http_client.NOT_FOUND) self.assertIsNotNone(r.getheader('Date', None)) - self.ae(r.getheader('Content-Length'), unicode_type(len(body))) + self.ae(r.getheader('Content-Length'), str(len(body))) self.ae(r.getheader('Content-Type'), 'text/plain; charset=UTF-8') self.ae(len(r.getheaders()), 3) self.ae(r.read(), b'') @@ -331,7 +331,7 @@ class TestHTTP(BaseTest): conn = server.connect() conn.request('GET', '/an_etagged_path', headers={'Accept-Encoding':'gzip'}) r = conn.getresponse() - self.ae(unicode_type(len(raw)), r.getheader('Calibre-Uncompressed-Length')) + self.ae(str(len(raw)), r.getheader('Calibre-Uncompressed-Length')) self.ae(r.status, http_client.OK), self.ae(zlib.decompress(r.read(), 16+zlib.MAX_WBITS), raw) # Test dynamic etagged content @@ -361,25 +361,25 @@ class TestHTTP(BaseTest): conn = server.connect() conn.request('GET', '/test') r = conn.getresponse() - etag = unicode_type(r.getheader('ETag')) + etag = str(r.getheader('ETag')) self.assertTrue(etag) self.ae(r.getheader('Content-Type'), guess_type(f.name)[0]) - self.ae(unicode_type(r.getheader('Accept-Ranges')), 'bytes') + self.ae(str(r.getheader('Accept-Ranges')), 'bytes') self.ae(int(r.getheader('Content-Length')), len(fdata)) self.ae(r.status, http_client.OK), self.ae(r.read(), fdata) conn.request('GET', '/test', headers={'Range':'bytes=2-25'}) r = conn.getresponse() self.ae(r.status, http_client.PARTIAL_CONTENT) - self.ae(unicode_type(r.getheader('Accept-Ranges')), 'bytes') - self.ae(unicode_type(r.getheader('Content-Range')), 'bytes 2-25/%d' % len(fdata)) + self.ae(str(r.getheader('Accept-Ranges')), 'bytes') + self.ae(str(r.getheader('Content-Range')), 'bytes 2-25/%d' % len(fdata)) self.ae(int(r.getheader('Content-Length')), 24) self.ae(r.read(), fdata[2:26]) conn.request('GET', '/test', headers={'Range':'bytes=100000-'}) r = conn.getresponse() self.ae(r.status, http_client.REQUESTED_RANGE_NOT_SATISFIABLE) - self.ae(unicode_type(r.getheader('Content-Range')), 'bytes */%d' % len(fdata)) + self.ae(str(r.getheader('Content-Range')), 'bytes */%d' % len(fdata)) conn.request('GET', '/test', headers={'Range':'bytes=25-50', 'If-Range':etag}) r = conn.getresponse() diff --git a/src/calibre/srv/tests/loop.py b/src/calibre/srv/tests/loop.py index 18a965547b..109af82981 100644 --- a/src/calibre/srv/tests/loop.py +++ b/src/calibre/srv/tests/loop.py @@ -16,7 +16,6 @@ from calibre.srv.tests.base import BaseTest, TestServer from calibre.ptempfile import TemporaryDirectory from calibre.utils.certgen import create_server_cert from calibre.utils.monotonic import monotonic -from polyglot.builtins import range, unicode_type, map from polyglot import http_client is_ci = os.environ.get('CI', '').lower() == 'true' @@ -218,7 +217,7 @@ class LoopTest(BaseTest): s.bind(('localhost', 0)) port = s.getsockname()[1] self.ae(s.fileno(), 3) - os.environ['LISTEN_PID'] = unicode_type(os.getpid()) + os.environ['LISTEN_PID'] = str(os.getpid()) os.environ['LISTEN_FDS'] = '1' with TestServer(lambda data:(data.path[0].encode('utf-8') + data.read()), allow_socket_preallocation=True) as server: conn = server.connect() diff --git a/src/calibre/srv/tests/routes.py b/src/calibre/srv/tests/routes.py index c611468148..c1cbaeccc4 100644 --- a/src/calibre/srv/tests/routes.py +++ b/src/calibre/srv/tests/routes.py @@ -7,7 +7,7 @@ __copyright__ = '2015, Kovid Goyal ' import os from calibre.srv.tests.base import BaseTest -from polyglot.builtins import itervalues, filter +from polyglot.builtins import itervalues from tempfile import TemporaryDirectory diff --git a/src/calibre/srv/tests/web_sockets.py b/src/calibre/srv/tests/web_sockets.py index 8dbb2271b4..a8577ec09d 100644 --- a/src/calibre/srv/tests/web_sockets.py +++ b/src/calibre/srv/tests/web_sockets.py @@ -14,7 +14,6 @@ from calibre.srv.web_socket import ( PING, PONG, PROTOCOL_ERROR, CONTINUATION, INCONSISTENT_DATA, CONTROL_CODES) from calibre.utils.monotonic import monotonic from calibre.utils.socket_inheritance import set_socket_inherit -from polyglot.builtins import range, unicode_type from polyglot.binary import as_base64_unicode HANDSHAKE_STR = '''\ @@ -77,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'' @@ -132,7 +131,7 @@ class WSClient: def write_message(self, msg, chunk_size=None): if isinstance(msg, tuple): opcode, msg = msg - if isinstance(msg, unicode_type): + if isinstance(msg, str): msg = msg.encode('utf-8') return self.write_frame(1, opcode, msg) w = MessageWriter(msg, self.mask, chunk_size) @@ -147,7 +146,7 @@ class WSClient: self.socket.sendall(frame) def write_close(self, code, reason=b''): - if isinstance(reason, unicode_type): + if isinstance(reason, str): reason = reason.encode('utf-8') self.write_frame(1, CLOSE, struct.pack(b'!H', code) + reason) @@ -183,7 +182,7 @@ class WebSocketTest(BaseTest): expected_messages, expected_controls = [], [] for ex in expected: - if isinstance(ex, unicode_type): + if isinstance(ex, str): ex = TEXT, ex elif isinstance(ex, bytes): ex = BINARY, ex @@ -292,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 d384114dee..74ba63e307 100644 --- a/src/calibre/srv/utils.py +++ b/src/calibre/srv/utils.py @@ -16,10 +16,10 @@ from calibre.utils.localization import get_translator from calibre.utils.socket_inheritance import set_socket_inherit from calibre.utils.logging import ThreadSafeLog from calibre.utils.shared_file import share_open -from polyglot.builtins import iteritems, map, range +from polyglot.builtins import iteritems from polyglot import reprlib from polyglot.http_cookie import SimpleCookie -from polyglot.builtins import unicode_type, as_unicode +from polyglot.builtins import as_unicode from polyglot.urllib import parse_qs, quote as urlquote from polyglot.binary import as_hex_unicode as encode_name, from_hex_unicode as decode_name @@ -30,7 +30,7 @@ encode_name, decode_name def http_date(timeval=None): - return unicode_type(formatdate(timeval=timeval, usegmt=True)) + return str(formatdate(timeval=timeval, usegmt=True)) class MultiDict(dict): # {{{ @@ -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/srv/web_socket.py b/src/calibre/srv/web_socket.py index bddc294529..1f8d6c84a4 100644 --- a/src/calibre/srv/web_socket.py +++ b/src/calibre/srv/web_socket.py @@ -21,7 +21,6 @@ from calibre.srv.utils import DESIRED_SEND_BUFFER_SIZE from calibre.utils.speedups import ReadOnlyFileBuffer from polyglot import http_client from polyglot.binary import as_base64_unicode -from polyglot.builtins import unicode_type from polyglot.queue import Empty, Queue HANDSHAKE_STR = ( @@ -178,7 +177,7 @@ class ReadFrame: # {{{ def create_frame(fin, opcode, payload, mask=None, rsv=0): - if isinstance(payload, unicode_type): + if isinstance(payload, str): payload = payload.encode('utf-8') l = len(payload) header_len = 2 + (0 if l < 126 else 2 if 126 <= l <= 65535 else 8) + (0 if mask is None else 4) @@ -207,7 +206,7 @@ class MessageWriter: def __init__(self, buf, mask=None, chunk_size=None): self.buf, self.data_type, self.mask = buf, BINARY, mask - if isinstance(buf, unicode_type): + if isinstance(buf, str): self.buf, self.data_type = ReadOnlyFileBuffer(buf.encode('utf-8')), TEXT elif isinstance(buf, bytes): self.buf = ReadOnlyFileBuffer(buf) @@ -422,7 +421,7 @@ class WebSocketConnection(HTTPConnection): self.set_ws_state() def websocket_close(self, code=NORMAL_CLOSE, reason=b''): - if isinstance(reason, unicode_type): + if isinstance(reason, str): reason = reason.encode('utf-8') self.stop_reading = True reason = reason[:123] @@ -487,7 +486,7 @@ class WebSocketConnection(HTTPConnection): ''' Useful for streaming handlers that want to break up messages into frames themselves. Note that these frames will be interleaved with control frames, so they should not be too large. ''' - opcode = (TEXT if isinstance(data, unicode_type) else BINARY) if is_first else CONTINUATION + opcode = (TEXT if isinstance(data, str) else BINARY) if is_first else CONTINUATION fin = 1 if is_last else 0 frame = create_frame(fin, opcode, data) with self.cf_lock: @@ -496,7 +495,7 @@ class WebSocketConnection(HTTPConnection): def send_websocket_ping(self, data=b''): ''' Send a PING to the remote client, it should reply with a PONG which will be sent to the handle_websocket_pong callback in your handler. ''' - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') frame = create_frame(True, PING, data) with self.cf_lock: diff --git a/src/calibre/startup.py b/src/calibre/startup.py index 751c984eca..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' @@ -10,7 +9,7 @@ Perform various initialization tasks. import locale, sys, os # Default translation is NOOP -from polyglot.builtins import builtins, unicode_type +from polyglot.builtins import builtins builtins.__dict__['_'] = lambda s: s # For strings which belong in the translation tables, but which shouldn't be @@ -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. # @@ -162,7 +161,7 @@ def initialize_calibre(): if name == 'Thread': name = self.name if name: - if isinstance(name, unicode_type): + if isinstance(name, str): name = name.encode('ascii', 'replace').decode('ascii') speedup.set_thread_name(name[:15]) except Exception: diff --git a/src/calibre/test_build.py b/src/calibre/test_build.py index 1de72c4fcf..5aef0cb0b8 100644 --- a/src/calibre/test_build.py +++ b/src/calibre/test_build.py @@ -13,7 +13,7 @@ Test a binary calibre build to ensure that all needed binary images/libraries ha import os, ctypes, sys, unittest, time, shutil from calibre.constants import iswindows, islinux, ismacos, plugins_loc -from polyglot.builtins import iteritems, map, unicode_type, getenv +from polyglot.builtins import iteritems is_ci = os.environ.get('CI', '').lower() == 'true' is_sanitized = 'libasan' in os.environ.get('LD_PRELOAD', '') @@ -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) @@ -147,7 +147,7 @@ class BuildTest(unittest.TestCase): s = msgpack_dumps(obj) self.assertEqual(obj, msgpack_loads(s)) self.assertEqual(type(msgpack_loads(msgpack_dumps(b'b'))), bytes) - self.assertEqual(type(msgpack_loads(msgpack_dumps('b'))), unicode_type) + self.assertEqual(type(msgpack_loads(msgpack_dumps('b'))), str) large = b'x' * (100 * 1024 * 1024) msgpack_loads(msgpack_dumps(large)) @@ -168,7 +168,7 @@ class BuildTest(unittest.TestCase): def au(x, name): self.assertTrue( - isinstance(x, unicode_type), + isinstance(x, str), '%s() did not return a unicode string, instead returning: %r' % (name, x)) for x in 'username temp_path locale_name'.split(): au(getattr(winutil, x)(), x) @@ -178,11 +178,11 @@ class BuildTest(unittest.TestCase): for k, v in iteritems(d): au(v, k) os.environ['XXXTEST'] = 'YYY' - self.assertEqual(getenv('XXXTEST'), 'YYY') + self.assertEqual(os.getenv('XXXTEST'), 'YYY') del os.environ['XXXTEST'] - self.assertIsNone(getenv('XXXTEST')) + self.assertIsNone(os.getenv('XXXTEST')) for k in os.environ: - v = getenv(k) + v = os.getenv(k) if v is not None: au(v, 'getenv-' + k) t = time.localtime() 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/certgen.py b/src/calibre/utils/certgen.py index e180ddbc72..2b767154ef 100644 --- a/src/calibre/utils/certgen.py +++ b/src/calibre/utils/certgen.py @@ -6,7 +6,6 @@ __license__ = 'GPL v3' __copyright__ = '2015, Kovid Goyal ' import socket -from polyglot.builtins import unicode_type from calibre_extensions import certgen @@ -20,7 +19,7 @@ def create_cert_request( organizational_unit=None, email_address=None, alt_names=(), basic_constraints=None ): def enc(x): - if isinstance(x, unicode_type): + if isinstance(x, str): x = x.encode('ascii') return x or None @@ -83,7 +82,7 @@ def create_server_cert( def export(dest, obj, func, *args): if dest is not None: data = func(obj, *args) - if isinstance(data, unicode_type): + if isinstance(data, str): data = data.encode('utf-8') if hasattr(dest, 'write'): dest.write(data) diff --git a/src/calibre/utils/cleantext.py b/src/calibre/utils/cleantext.py index 5a0583ef6c..cd66ec6eaa 100644 --- a/src/calibre/utils/cleantext.py +++ b/src/calibre/utils/cleantext.py @@ -7,7 +7,7 @@ import re from calibre.constants import preferred_encoding from calibre_extensions.speedup import clean_xml_chars as _ncxc -from polyglot.builtins import codepoint_to_chr, filter, map, range +from polyglot.builtins import codepoint_to_chr from polyglot.html_entities import name2codepoint 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 cd2e19118a..4e1bc6bd7c 100644 --- a/src/calibre/utils/config_base.py +++ b/src/calibre/utils/config_base.py @@ -12,7 +12,7 @@ from copy import deepcopy from calibre.utils.lock import ExclusiveFile from calibre.constants import config_dir, CONFIG_DIR_MODE, preferred_encoding, filesystem_encoding, iswindows -from polyglot.builtins import unicode_type, iteritems, map +from polyglot.builtins import iteritems plugin_dir = os.path.join(config_dir, 'plugins') @@ -21,7 +21,7 @@ def parse_old_style(src): import pickle as cPickle options = {'cPickle':cPickle} try: - if not isinstance(src, unicode_type): + if not isinstance(src, str): src = src.decode('utf-8') src = src.replace('PyQt%d.QtCore' % 4, 'PyQt5.QtCore') src = re.sub(r'cPickle\.loads\(([\'"])', r'cPickle.loads(b\1', src) @@ -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, unicode_type) 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: @@ -399,7 +399,7 @@ class Config(ConfigInterface): src = self.option_set.serialize(opts) f.seek(0) f.truncate() - if isinstance(src, unicode_type): + if isinstance(src, str): src = src.encode('utf-8') f.write(src) @@ -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 ' @@ -550,7 +550,7 @@ def create_global_prefs(conf_obj=None): prefs = ConfigProxy(create_global_prefs()) if prefs['installation_uuid'] is None: import uuid - prefs['installation_uuid'] = unicode_type(uuid.uuid4()) + prefs['installation_uuid'] = str(uuid.uuid4()) # Read tweaks diff --git a/src/calibre/utils/date.py b/src/calibre/utils/date.py index 8b7492e8f5..951386849e 100644 --- a/src/calibre/utils/date.py +++ b/src/calibre/utils/date.py @@ -14,7 +14,7 @@ from calibre import strftime from calibre.constants import iswindows, ismacos, preferred_encoding from calibre.utils.iso8601 import utc_tz, local_tz, UNDEFINED_DATE from calibre.utils.localization import lcdata -from polyglot.builtins import unicode_type, native_string_type +from polyglot.builtins import native_string_type _utc_tz = utc_tz _local_tz = local_tz @@ -192,13 +192,13 @@ def fromordinal(day, as_utc=True): def isoformat(date_time, assume_utc=False, as_utc=True, sep='T'): if not hasattr(date_time, 'tzinfo'): - return unicode_type(date_time.isoformat()) + return str(date_time.isoformat()) if date_time.tzinfo is None: date_time = date_time.replace(tzinfo=_utc_tz if assume_utc else _local_tz) date_time = date_time.astimezone(_utc_tz if as_utc else _local_tz) # native_string_type(sep) because isoformat barfs with unicode sep on python 2.x - return unicode_type(date_time.isoformat(native_string_type(sep))) + return str(date_time.isoformat(native_string_type(sep))) def internal_iso_format_string(): @@ -211,7 +211,7 @@ def w3cdtf(date_time, assume_utc=False): date_time = date_time.replace(tzinfo=_utc_tz if assume_utc else _local_tz) date_time = date_time.astimezone(_utc_tz if as_utc else _local_tz) - return unicode_type(date_time.strftime('%Y-%m-%dT%H:%M:%SZ')) + return str(date_time.strftime('%Y-%m-%dT%H:%M:%SZ')) def as_local_time(date_time, assume_utc=True): diff --git a/src/calibre/utils/exim.py b/src/calibre/utils/exim.py index cf07c6ffff..97a4ba8c62 100644 --- a/src/calibre/utils/exim.py +++ b/src/calibre/utils/exim.py @@ -11,7 +11,7 @@ from calibre.constants import config_dir, iswindows, filesystem_encoding from calibre.utils.config_base import prefs, StringConfig, create_global_prefs from calibre.utils.config import JSONConfig from calibre.utils.filenames import samefile -from polyglot.builtins import iteritems, raw_input, error_message, unicode_type +from polyglot.builtins import iteritems, error_message from polyglot.binary import as_hex_unicode @@ -25,7 +25,7 @@ def send_file(from_obj, to_obj, chunksize=1<<20): break m.update(raw) to_obj.write(raw) - return unicode_type(m.hexdigest()) + return str(m.hexdigest()) class FileDest: @@ -55,7 +55,7 @@ class FileDest: def close(self): if not self._discard: size = self.exporter.f.tell() - self.start_pos - digest = unicode_type(self.hasher.hexdigest()) + digest = str(self.hasher.hexdigest()) self.exporter.file_metadata[self.key] = (len(self.exporter.parts), self.start_pos, size, digest, self.mtime) del self.exporter, self.hasher @@ -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,14 +299,14 @@ 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] except Exception: lpath = None c = create_global_prefs(StringConfig(raw, 'calibre wide preferences')) - c.set('installation_uuid', unicode_type(uuid.uuid4())) + c.set('installation_uuid', str(uuid.uuid4())) c.set('library_path', lpath) raw = c.src if not isinstance(raw, bytes): @@ -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,12 +384,12 @@ 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 def input_unicode(prompt): - ans = raw_input(prompt) + ans = input(prompt) if isinstance(ans, bytes): ans = ans.decode(sys.stdin.encoding) return ans diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index a3c590ab18..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. @@ -16,7 +15,7 @@ from calibre.constants import ( filesystem_encoding, iswindows, preferred_encoding, ismacos ) from calibre.utils.localization import get_udc -from polyglot.builtins import iteritems, itervalues, unicode_type, range +from polyglot.builtins import iteritems, itervalues def ascii_text(orig): @@ -24,7 +23,7 @@ def ascii_text(orig): try: ascii = udc.decode(orig) except Exception: - if isinstance(orig, unicode_type): + if isinstance(orig, str): orig = orig.encode('ascii', 'replace') ascii = orig.decode(preferred_encoding, 'replace') if isinstance(ascii, bytes): @@ -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/free_type.py b/src/calibre/utils/fonts/free_type.py index 03a80ba3cc..9c85a9fb5e 100644 --- a/src/calibre/utils/fonts/free_type.py +++ b/src/calibre/utils/fonts/free_type.py @@ -10,7 +10,6 @@ import threading from functools import wraps from calibre_extensions.freetype import FreeType as _FreeType -from polyglot.builtins import map, unicode_type class ThreadingViolation(Exception): @@ -48,7 +47,7 @@ class Face: ''' Returns True if all the characters in text have glyphs in this font. ''' - if not isinstance(text, unicode_type): + if not isinstance(text, str): raise TypeError('%r is not a unicode object'%text) if has_non_printable_chars: from calibre.utils.fonts.utils import get_printable_characters @@ -58,7 +57,7 @@ class Face: @same_thread def glyph_ids(self, text): - if not isinstance(text, unicode_type): + if not isinstance(text, str): raise TypeError('%r is not a unicode object'%text) for char in text: yield self.face.glyph_id(ord(char)) diff --git a/src/calibre/utils/fonts/metadata.py b/src/calibre/utils/fonts/metadata.py index f9cd47dd3c..b818206183 100644 --- a/src/calibre/utils/fonts/metadata.py +++ b/src/calibre/utils/fonts/metadata.py @@ -11,7 +11,6 @@ from struct import calcsize, unpack, unpack_from from collections import namedtuple from calibre.utils.fonts.utils import get_font_names2, get_font_characteristics -from polyglot.builtins import range, unicode_type class UnsupportedFont(ValueError): @@ -48,7 +47,7 @@ class FontMetadata: elif wt == 700: wt = 'bold' else: - wt = unicode_type(wt) + wt = str(wt) self.font_weight = wt self.font_stretch = ('ultra-condensed', 'extra-condensed', diff --git a/src/calibre/utils/fonts/scanner.py b/src/calibre/utils/fonts/scanner.py index 98b367b8f8..2d967bfbbe 100644 --- a/src/calibre/utils/fonts/scanner.py +++ b/src/calibre/utils/fonts/scanner.py @@ -15,7 +15,7 @@ from calibre.constants import (config_dir, iswindows, ismacos, DEBUG, isworker, filesystem_encoding) from calibre.utils.fonts.metadata import FontMetadata, UnsupportedFont from calibre.utils.icu import sort_key -from polyglot.builtins import itervalues, unicode_type, filter +from polyglot.builtins import itervalues class NoFonts(ValueError): @@ -270,8 +270,8 @@ class FontScanner(Thread): ''' from calibre.utils.fonts.utils import (supports_text, panose_to_css_generic_family, get_printable_characters) - if not isinstance(text, unicode_type): - raise TypeError(u'%r is not unicode'%text) + if not isinstance(text, str): + 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/dict_data.py b/src/calibre/utils/fonts/sfnt/cff/dict_data.py index 47d1457e55..d58d12a391 100644 --- a/src/calibre/utils/fonts/sfnt/cff/dict_data.py +++ b/src/calibre/utils/fonts/sfnt/cff/dict_data.py @@ -7,7 +7,6 @@ __copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>' __docformat__ = 'restructuredtext en' from struct import pack, unpack_from -from polyglot.builtins import range, unicode_type t1_operand_encoding = [None] * 256 t1_operand_encoding[0:32] = (32) * ["do_operator"] @@ -71,7 +70,7 @@ class ByteCode(dict): return float(number), index def write_float(self, f, encoding='ignored'): - s = unicode_type(f).upper() + s = str(f).upper() if s[:2] == "0.": s = s[1:] elif s[:3] == "-0.": diff --git a/src/calibre/utils/fonts/sfnt/cff/table.py b/src/calibre/utils/fonts/sfnt/cff/table.py index 02c5a9838c..943b5e6eca 100644 --- a/src/calibre/utils/fonts/sfnt/cff/table.py +++ b/src/calibre/utils/fonts/sfnt/cff/table.py @@ -14,7 +14,7 @@ from calibre.utils.fonts.sfnt.errors import UnsupportedFont, NoGlyphs from calibre.utils.fonts.sfnt.cff.dict_data import TopDict, PrivateDict from calibre.utils.fonts.sfnt.cff.constants import (cff_standard_strings, STANDARD_CHARSETS) -from polyglot.builtins import iteritems, itervalues, range +from polyglot.builtins import iteritems, itervalues # Useful links # http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf @@ -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/cff/writer.py b/src/calibre/utils/fonts/sfnt/cff/writer.py index b556abd5fa..7a74fa3114 100644 --- a/src/calibre/utils/fonts/sfnt/cff/writer.py +++ b/src/calibre/utils/fonts/sfnt/cff/writer.py @@ -10,7 +10,6 @@ from struct import pack from collections import OrderedDict from calibre.utils.fonts.sfnt.cff.constants import cff_standard_strings -from polyglot.builtins import range class Index(list): diff --git a/src/calibre/utils/fonts/sfnt/cmap.py b/src/calibre/utils/fonts/sfnt/cmap.py index 322a658518..7caae73d9d 100644 --- a/src/calibre/utils/fonts/sfnt/cmap.py +++ b/src/calibre/utils/fonts/sfnt/cmap.py @@ -15,7 +15,6 @@ from collections import OrderedDict from calibre.utils.fonts.utils import read_bmp_prefix from calibre.utils.fonts.sfnt import UnknownTable, max_power_of_two from calibre.utils.fonts.sfnt.errors import UnsupportedFont -from polyglot.builtins import range def split_range(start_code, end_code, cmap): # {{{ @@ -171,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/common.py b/src/calibre/utils/fonts/sfnt/common.py index 3e778fecf7..5f98e736fa 100644 --- a/src/calibre/utils/fonts/sfnt/common.py +++ b/src/calibre/utils/fonts/sfnt/common.py @@ -10,7 +10,7 @@ from struct import unpack_from, calcsize from collections import OrderedDict, namedtuple from calibre.utils.fonts.sfnt.errors import UnsupportedFont -from polyglot.builtins import range, iteritems +from polyglot.builtins import iteritems class Unpackable: 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 2c9d52645e..b4c57e6961 100644 --- a/src/calibre/utils/fonts/sfnt/head.py +++ b/src/calibre/utils/fonts/sfnt/head.py @@ -12,7 +12,6 @@ from struct import unpack_from, pack, calcsize from calibre.utils.fonts.sfnt import UnknownTable, DateTimeProperty, FixedProperty from calibre.utils.fonts.sfnt.errors import UnsupportedFont from calibre.utils.fonts.sfnt.loca import read_array -from polyglot.builtins import zip class HeadTable(UnknownTable): @@ -23,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 983e49beb3..5e94caf729 100644 --- a/src/calibre/utils/fonts/sfnt/kern.py +++ b/src/calibre/utils/fonts/sfnt/kern.py @@ -11,7 +11,6 @@ from struct import unpack_from, calcsize, pack, error as struct_error from calibre.utils.fonts.sfnt import (UnknownTable, FixedProperty, max_power_of_two) from calibre.utils.fonts.sfnt.errors import UnsupportedFont -from polyglot.builtins import range class KernTable(UnknownTable): @@ -19,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/loca.py b/src/calibre/utils/fonts/sfnt/loca.py index 7cc16444bb..710ac6cea9 100644 --- a/src/calibre/utils/fonts/sfnt/loca.py +++ b/src/calibre/utils/fonts/sfnt/loca.py @@ -11,7 +11,7 @@ from operator import itemgetter from itertools import repeat from calibre.utils.fonts.sfnt import UnknownTable -from polyglot.builtins import iteritems, range +from polyglot.builtins import iteritems def four_byte_type_code(): diff --git a/src/calibre/utils/fonts/sfnt/maxp.py b/src/calibre/utils/fonts/sfnt/maxp.py index 9d5b69d94b..3067976728 100644 --- a/src/calibre/utils/fonts/sfnt/maxp.py +++ b/src/calibre/utils/fonts/sfnt/maxp.py @@ -10,7 +10,6 @@ from struct import unpack_from, pack from calibre.utils.fonts.sfnt import UnknownTable, FixedProperty from calibre.utils.fonts.sfnt.errors import UnsupportedFont -from polyglot.builtins import zip class MaxpTable(UnknownTable): @@ -18,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/metrics.py b/src/calibre/utils/fonts/sfnt/metrics.py index 976a0233de..d68cd52a0d 100644 --- a/src/calibre/utils/fonts/sfnt/metrics.py +++ b/src/calibre/utils/fonts/sfnt/metrics.py @@ -6,7 +6,6 @@ __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>' __docformat__ = 'restructuredtext en' -from polyglot.builtins import map, unicode_type from calibre.utils.fonts.utils import get_all_font_names from calibre.utils.fonts.sfnt.container import UnsupportedFont @@ -94,7 +93,7 @@ class FontMetrics: Return the advance widths (in pixels) for all glyphs corresponding to the characters in string at the specified pixel_size and stretch factor. ''' - if not isinstance(string, unicode_type): + if not isinstance(string, str): raise ValueError('Must supply a unicode object') chars = tuple(map(ord, string)) cmap = self.cmap.get_character_map(chars) diff --git a/src/calibre/utils/fonts/sfnt/subset.py b/src/calibre/utils/fonts/sfnt/subset.py index 6652fe4c96..9a037cbc23 100644 --- a/src/calibre/utils/fonts/sfnt/subset.py +++ b/src/calibre/utils/fonts/sfnt/subset.py @@ -14,7 +14,7 @@ from functools import partial from calibre.utils.icu import safe_chr, ord_string from calibre.utils.fonts.sfnt.container import Sfnt from calibre.utils.fonts.sfnt.errors import UnsupportedFont, NoGlyphs -from polyglot.builtins import unicode_type, range, iteritems, itervalues, map +from polyglot.builtins import iteritems, itervalues # TrueType outlines {{{ @@ -109,7 +109,7 @@ def pdf_subset(sfnt, glyphs): def safe_ord(x): - return ord_string(unicode_type(x))[0] + return ord_string(str(x))[0] def subset(raw, individual_chars, ranges=(), warnings=None): @@ -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 @@ -351,12 +351,12 @@ def all(): print('No glyphs!') continue except UnsupportedFont as e: - unsupported.append((font['full_name'], font['path'], unicode_type(e))) + unsupported.append((font['full_name'], font['path'], str(e))) print('Unsupported!') continue except Exception as e: print('Failed!') - failed.append((font['full_name'], font['path'], unicode_type(e))) + failed.append((font['full_name'], font['path'], str(e))) else: averages.append(sum(itervalues(new_stats))/sum(itervalues(old_stats)) * 100) print('Reduced to:', '%.1f'%averages[-1] , '%') diff --git a/src/calibre/utils/fonts/utils.py b/src/calibre/utils/fonts/utils.py index 8a281f1722..e74b8d9ce1 100644 --- a/src/calibre/utils/fonts/utils.py +++ b/src/calibre/utils/fonts/utils.py @@ -10,7 +10,7 @@ import struct from io import BytesIO from collections import defaultdict -from polyglot.builtins import iteritems, itervalues, unicode_type, range, as_bytes +from polyglot.builtins import iteritems, itervalues, as_bytes class UnsupportedFont(ValueError): @@ -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'}) @@ -397,7 +397,7 @@ def get_bmp_glyph_ids(table, bmp, codes): def get_glyph_ids(raw, text, raw_is_table=False): - if not isinstance(text, unicode_type): + if not isinstance(text, str): raise TypeError('%r is not a unicode object'%text) if raw_is_table: table = raw @@ -418,12 +418,11 @@ 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): - if not isinstance(text, unicode_type): + if not isinstance(text, str): raise TypeError('%r is not a unicode object'%text) if not has_only_printable_chars: text = get_printable_characters(text) @@ -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/fonts/win_fonts.py b/src/calibre/utils/fonts/win_fonts.py index f90aeb88ca..3ad658a7f5 100644 --- a/src/calibre/utils/fonts/win_fonts.py +++ b/src/calibre/utils/fonts/win_fonts.py @@ -13,7 +13,7 @@ from calibre import prints, isbytestring from calibre.constants import filesystem_encoding from calibre.utils.fonts.utils import (is_truetype_font, get_font_names, get_font_characteristics) -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class WinFonts: @@ -58,7 +58,7 @@ class WinFonts: return ft def fonts_for_family(self, family, normalize=True): - family = unicode_type(family) + family = str(family) ans = {} for weight, is_italic in product((self.w.FW_NORMAL, self.w.FW_BOLD), (False, True)): if family in self.app_font_families: diff --git a/src/calibre/utils/formatter.py b/src/calibre/utils/formatter.py index bfe34c7e7e..c9773e793a 100644 --- a/src/calibre/utils/formatter.py +++ b/src/calibre/utils/formatter.py @@ -1,4 +1,3 @@ - ''' Created on 23 Sep 2010 @@ -18,7 +17,7 @@ from calibre.constants import DEBUG from calibre.ebooks.metadata.book.base import field_metadata from calibre.utils.formatter_functions import formatter_functions from calibre.utils.icu import strcmp -from polyglot.builtins import unicode_type, error_message +from polyglot.builtins import error_message class Node: @@ -906,9 +905,9 @@ class _Interpreter: else: res = fm['is_multiple']['list_to_ui'].join(res) else: - res = unicode_type(res) + res = str(res) else: - res = unicode_type(res) # Should be the string "None" + res = str(res) # Should be the string "None" if (self.break_reporter): self.break_reporter(prog.node_name, res, prog.line_number) return res @@ -1044,7 +1043,7 @@ class _Interpreter: try: answer = self.ARITHMETIC_BINARY_OPS[prog.operator](float(self.expr(prog.left)), float(self.expr(prog.right))) - res = unicode_type(answer if modf(answer)[0] != 0 else int(answer)) + res = str(answer if modf(answer)[0] != 0 else int(answer)) if (self.break_reporter): self.break_reporter(prog.node_name, res, prog.line_number) return res @@ -1062,7 +1061,7 @@ class _Interpreter: def do_node_unary_arithop(self, prog): try: expr = self.ARITHMETIC_UNARY_OPS[prog.operator](float(self.expr(prog.expr))) - res = unicode_type(expr if modf(expr)[0] != 0 else int(expr)) + res = str(expr if modf(expr)[0] != 0 else int(expr)) if (self.break_reporter): self.break_reporter(prog.node_name, res, prog.line_number) return res @@ -1187,7 +1186,7 @@ class TemplateFormatter(string.Formatter): except: raise ValueError( _('format: type {0} requires a decimal (float) value, got {1}').format(typ, val)) - return unicode_type(('{0:'+fmt+'}').format(val)) + return str(('{0:'+fmt+'}').format(val)) def _explode_format_string(self, fmt): try: @@ -1261,7 +1260,7 @@ class TemplateFormatter(string.Formatter): # ensure we are dealing with a string. if isinstance(val, numbers.Number): if val: - val = unicode_type(val) + val = str(val) else: val = '' # Handle conditional text diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 368b40d4ab..a625e4905e 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -25,7 +25,7 @@ from calibre.utils.titlecase import titlecase from calibre.utils.icu import capitalize, strcmp, sort_key from calibre.utils.date import parse_date, format_date, now, UNDEFINED_DATE from calibre.utils.localization import calibre_langcode_to_name, canonicalize_lang -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues class FormatterFunctions: @@ -135,12 +135,12 @@ class FormatterFunction: def eval_(self, formatter, kwargs, mi, locals, *args): ret = self.evaluate(formatter, kwargs, mi, locals, *args) - if isinstance(ret, (bytes, unicode_type)): + if isinstance(ret, (bytes, str)): return ret if isinstance(ret, list): return ','.join(ret) if isinstance(ret, (numbers.Number, bool)): - return unicode_type(ret) + return str(ret) class BuiltinFormatterFunction(FormatterFunction): @@ -258,7 +258,7 @@ class BuiltinAdd(BuiltinFormatterFunction): for v in args: v = float(v if v and v != 'None' else 0) res += v - return unicode_type(res) + return str(res) class BuiltinSubtract(BuiltinFormatterFunction): @@ -272,7 +272,7 @@ class BuiltinSubtract(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, x, y): x = float(x if x and x != 'None' else 0) y = float(y if y and y != 'None' else 0) - return unicode_type(x - y) + return str(x - y) class BuiltinMultiply(BuiltinFormatterFunction): @@ -288,7 +288,7 @@ class BuiltinMultiply(BuiltinFormatterFunction): for v in args: v = float(v if v and v != 'None' else 0) res *= v - return unicode_type(res) + return str(res) class BuiltinDivide(BuiltinFormatterFunction): @@ -302,7 +302,7 @@ class BuiltinDivide(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, x, y): x = float(x if x and x != 'None' else 0) y = float(y if y and y != 'None' else 0) - return unicode_type(x / y) + return str(x / y) class BuiltinCeiling(BuiltinFormatterFunction): @@ -315,7 +315,7 @@ class BuiltinCeiling(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, x): x = float(x if x and x != 'None' else 0) - return unicode_type(int(ceil(x))) + return str(int(ceil(x))) class BuiltinFloor(BuiltinFormatterFunction): @@ -328,7 +328,7 @@ class BuiltinFloor(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, x): x = float(x if x and x != 'None' else 0) - return unicode_type(int(floor(x))) + return str(int(floor(x))) class BuiltinRound(BuiltinFormatterFunction): @@ -340,7 +340,7 @@ class BuiltinRound(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, x): x = float(x if x and x != 'None' else 0) - return unicode_type(int(round(x))) + return str(int(round(x))) class BuiltinMod(BuiltinFormatterFunction): @@ -353,7 +353,7 @@ class BuiltinMod(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, x, y): x = float(x if x and x != 'None' else 0) y = float(y if y and y != 'None' else 0) - return unicode_type(int(x % y)) + return str(int(x % y)) class BuiltinFractionalPart(BuiltinFormatterFunction): @@ -366,7 +366,7 @@ class BuiltinFractionalPart(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals, x): x = float(x if x and x != 'None' else 0) - return unicode_type(modf(x)[0]) + return str(modf(x)[0]) class BuiltinTemplate(BuiltinFormatterFunction): @@ -438,7 +438,7 @@ class BuiltinListSplit(BuiltinFormatterFunction): l = [v.strip() for v in list_val.split(sep)] res = '' for i,v in enumerate(l): - res = locals[id_prefix+'_'+unicode_type(i)] = v + res = locals[id_prefix+'_'+str(i)] = v return res @@ -483,7 +483,7 @@ class BuiltinRawField(BuiltinFormatterFunction): if fm is None: return ', '.join(res) return fm['is_multiple']['list_to_ui'].join(res) - return unicode_type(res) + return str(res) class BuiltinRawList(BuiltinFormatterFunction): @@ -838,7 +838,7 @@ class BuiltinCount(BuiltinFormatterFunction): 'Aliases: count(), list_count()') def evaluate(self, formatter, kwargs, mi, locals, val, sep): - return unicode_type(len([v for v in val.split(sep) if v])) + return str(len([v for v in val.split(sep) if v])) class BuiltinListCountMatching(BuiltinFormatterFunction): @@ -857,7 +857,7 @@ class BuiltinListCountMatching(BuiltinFormatterFunction): for v in [x.strip() for x in list_.split(sep) if x.strip()]: if re.search(pattern, v, flags=re.I): res += 1 - return unicode_type(res) + return str(res) class BuiltinListitem(BuiltinFormatterFunction): @@ -970,7 +970,7 @@ class BuiltinFormatsSizes(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals): fmt_data = mi.get('format_metadata', {}) try: - return ','.join(k.upper()+':'+unicode_type(v['size']) for k,v in iteritems(fmt_data)) + return ','.join(k.upper()+':'+str(v['size']) for k,v in iteritems(fmt_data)) except: return '' @@ -989,7 +989,7 @@ class BuiltinFormatsPaths(BuiltinFormatterFunction): def evaluate(self, formatter, kwargs, mi, locals): fmt_data = mi.get('format_metadata', {}) try: - return ','.join(k.upper()+':'+unicode_type(v['path']) for k,v in iteritems(fmt_data)) + return ','.join(k.upper()+':'+str(v['path']) for k,v in iteritems(fmt_data)) except: return '' @@ -1231,7 +1231,7 @@ class BuiltinBooksize(BuiltinFormatterFunction): try: v = mi._proxy_metadata.book_size if v is not None: - return unicode_type(mi._proxy_metadata.book_size) + return str(mi._proxy_metadata.book_size) return '' except: pass @@ -1270,7 +1270,7 @@ class BuiltinAnnotationCount(BuiltinFormatterFunction): with suppress(Exception): from calibre.gui2.ui import get_gui c = get_gui().current_db.new_api.annotation_count_for_book(mi.id) - return '' if c == 0 else unicode_type(c) + return '' if c == 0 else str(c) return _('This function can be used only in the GUI') @@ -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/hyphenate.py b/src/calibre/utils/hyphenation/hyphenate.py index ba1efbe460..87835425e5 100644 --- a/src/calibre/utils/hyphenation/hyphenate.py +++ b/src/calibre/utils/hyphenation/hyphenate.py @@ -10,7 +10,6 @@ import regex from calibre.utils.hyphenation.dictionaries import ( dictionary_name_for_locale, path_to_dictionary ) -from polyglot.builtins import unicode_type from polyglot.functools import lru_cache REGEX_FLAGS = regex.VERSION1 | regex.WORD | regex.FULLCASE | regex.UNICODE @@ -27,7 +26,7 @@ def dictionary_for_locale(locale): def add_soft_hyphens(word, dictionary, hyphen_char='\u00ad'): - word = unicode_type(word) + word = str(word) if len(word) > 99 or '=' in word: return word q = word 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.py b/src/calibre/utils/icu.py index ff1e516ace..1a52db161a 100644 --- a/src/calibre/utils/icu.py +++ b/src/calibre/utils/icu.py @@ -11,7 +11,7 @@ import sys from calibre.utils.config_base import tweaks from calibre_extensions import icu as _icu -from polyglot.builtins import cmp, filter, unicode_type +from polyglot.builtins import cmp _locale = _collator = _primary_collator = _sort_collator = _numeric_collator = _case_sensitive_collator = None cmp @@ -224,7 +224,7 @@ ord_string = _icu.ord_string def character_name(string): try: - return _icu.character_name(unicode_type(string)) or None + return _icu.character_name(str(string)) or None except (TypeError, ValueError, KeyError): pass @@ -241,7 +241,7 @@ def normalize(text, mode='NFC'): # that unless you have very good reasons not too. Also, it's speed # decreases on wide python builds, where conversion to/from ICU's string # representation is slower. - return _icu.normalize(_nmodes[mode], unicode_type(text)) + return _icu.normalize(_nmodes[mode], str(text)) def contractions(col=None): diff --git a/src/calibre/utils/icu_test.py b/src/calibre/utils/icu_test.py index 85d259df12..e628cb5725 100644 --- a/src/calibre/utils/icu_test.py +++ b/src/calibre/utils/icu_test.py @@ -9,7 +9,7 @@ import unittest, sys from contextlib import contextmanager import calibre.utils.icu as icu -from polyglot.builtins import iteritems, unicode_type, cmp +from polyglot.builtins import iteritems, cmp @contextmanager @@ -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(unicode_type(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(str(q)), ['one', 'two', 'three'], 'Failed to split: %r' % q) + 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 ca73002aca..0652b55fad 100644 --- a/src/calibre/utils/img.py +++ b/src/calibre/utils/img.py @@ -23,7 +23,7 @@ from calibre.utils.config_base import tweaks from calibre.utils.filenames import atomic_rename from calibre.utils.imghdr import what from calibre_extensions import imageops -from polyglot.builtins import string_or_bytes, unicode_type +from polyglot.builtins import string_or_bytes # Utilities {{{ @@ -133,7 +133,7 @@ def image_from_path(path): def image_from_x(x): ' Create an image from a bytestring or a path or a file like object. ' - if isinstance(x, unicode_type): + if isinstance(x, str): return image_from_path(x) if hasattr(x, 'read'): return image_from_data(x.read()) @@ -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 @@ -606,7 +606,7 @@ def encode_jpeg(file_path, quality=80): from calibre.utils.speedups import ReadOnlyFileBuffer quality = max(0, min(100, int(quality))) exe = get_exe_path('cjpeg') - cmd = [exe] + '-optimize -progressive -maxmemory 100M -quality'.split() + [unicode_type(quality)] + cmd = [exe] + '-optimize -progressive -maxmemory 100M -quality'.split() + [str(quality)] img = QImage() if not img.load(file_path): raise ValueError('%s is not a valid image file' % file_path) diff --git a/src/calibre/utils/imghdr.py b/src/calibre/utils/imghdr.py index 2b806a60a9..d3aed07480 100644 --- a/src/calibre/utils/imghdr.py +++ b/src/calibre/utils/imghdr.py @@ -6,7 +6,7 @@ from struct import unpack, error import os from calibre.utils.speedups import ReadOnlyFileBuffer -from polyglot.builtins import string_or_bytes, unicode_type +from polyglot.builtins import string_or_bytes """ Recognize image file formats and sizes based on their first few bytes.""" @@ -42,7 +42,7 @@ def identify(src): recognized. ''' needs_close = False - if isinstance(src, unicode_type): + if isinstance(src, str): stream = lopen(src, 'rb') needs_close = True elif isinstance(src, bytes): 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 9619e7966a..6d970bfb08 100644 --- a/src/calibre/utils/ipc/launch.py +++ b/src/calibre/utils/ipc/launch.py @@ -11,7 +11,7 @@ from calibre.constants import iswindows, ismacos, isfrozen from calibre.utils.config import prefs from calibre.ptempfile import PersistentTemporaryFile, base_dir from calibre.utils.serialize import msgpack_dumps -from polyglot.builtins import string_or_bytes, environ_item, native_string_type, getcwd +from polyglot.builtins import string_or_bytes, environ_item, native_string_type from polyglot.binary import as_hex_unicode if iswindows: @@ -152,8 +152,8 @@ class Worker: exe = self.gui_executable if self.gui else self.executable env = self.env try: - origwd = cwd or os.path.abspath(getcwd()) - except EnvironmentError: + origwd = cwd or os.path.abspath(os.getcwd()) + 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 c44facfa0e..e834da9498 100644 --- a/src/calibre/utils/ipc/simple_worker.py +++ b/src/calibre/utils/ipc/simple_worker.py @@ -17,7 +17,7 @@ from calibre.constants import iswindows from calibre.utils.ipc import eintr_retry_call from calibre.utils.ipc.launch import Worker from calibre.utils.monotonic import monotonic -from polyglot.builtins import environ_item, string_or_bytes, unicode_type +from polyglot.builtins import environ_item, string_or_bytes if iswindows: from multiprocessing.connection import PipeConnection as Connection @@ -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 @@ -268,7 +268,7 @@ def offload_worker(env={}, priority='normal', cwd=None): def compile_code(src): import io import re - if not isinstance(src, unicode_type): + if not isinstance(src, str): match = re.search(br'coding[:=]\s*([-\w.]+)', src[:200]) enc = match.group(1).decode('utf-8') if match else 'utf-8' src = src.decode(enc) 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/linux_trash.py b/src/calibre/utils/linux_trash.py index 13bf248b80..7ff880ba3f 100644 --- a/src/calibre/utils/linux_trash.py +++ b/src/calibre/utils/linux_trash.py @@ -23,7 +23,6 @@ import os.path as op from datetime import datetime import shutil -from polyglot.builtins import unicode_type from polyglot.urllib import quote FILES_DIR = 'files' @@ -40,9 +39,9 @@ TOPDIR_FALLBACK = '.Trash-%s'%uid def uniquote(raw): - if isinstance(raw, unicode_type): + if isinstance(raw, str): raw = raw.encode('utf-8') - return unicode_type(quote(raw)) + return str(quote(raw)) def is_parent(parent, path): @@ -120,7 +119,7 @@ def find_ext_volume_global_trash(volume_root): if not op.isdir(trash_dir) or op.islink(trash_dir) or not (mode & stat.S_ISVTX): return None - trash_dir = op.join(trash_dir, unicode_type(uid)) + trash_dir = op.join(trash_dir, str(uid)) try: check_create(trash_dir) except OSError: diff --git a/src/calibre/utils/localization.py b/src/calibre/utils/localization.py index e59ba0994b..e005c45eb7 100644 --- a/src/calibre/utils/localization.py +++ b/src/calibre/utils/localization.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import os, locale, re, io from gettext import GNUTranslations, NullTranslations -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems _available_translations = None @@ -430,7 +430,7 @@ def calibre_langcode_to_name(lc, localize=True): def canonicalize_lang(raw): if not raw: return None - if not isinstance(raw, unicode_type): + if not isinstance(raw, str): raw = raw.decode('utf-8', 'ignore') raw = raw.lower().strip() if not raw: @@ -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 8a6abedaf9..7c8d2280ae 100644 --- a/src/calibre/utils/localunzip.py +++ b/src/calibre/utils/localunzip.py @@ -18,7 +18,7 @@ from struct import calcsize, unpack, pack from collections import namedtuple, OrderedDict from calibre.ptempfile import SpooledTemporaryFile -from polyglot.builtins import itervalues, getcwd +from polyglot.builtins import itervalues HEADER_SIG = 0x04034b50 HEADER_BYTE_SIG = pack(b'<L', HEADER_SIG) @@ -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))) @@ -247,7 +247,7 @@ def extractall(path_or_stream, path=None): f = open(f, 'rb') close_at_end = True if path is None: - path = getcwd() + path = os.getcwd() pos = f.tell() try: _extractall(f, path) @@ -294,7 +294,7 @@ class LocalZipFile: def extractall(self, path=None): self.stream.seek(0) - _extractall(self.stream, path=(path or getcwd())) + _extractall(self.stream, path=(path or os.getcwd())) def close(self): pass 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/magick/__init__.py b/src/calibre/utils/magick/__init__.py index dcf0f69273..1f52c56bcf 100644 --- a/src/calibre/utils/magick/__init__.py +++ b/src/calibre/utils/magick/__init__.py @@ -7,7 +7,6 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>' __docformat__ = 'restructuredtext en' from calibre.utils.magick.legacy import Image, PixelWand -from polyglot.builtins import unicode_type if False: PixelWand @@ -15,5 +14,5 @@ if False: def create_canvas(width, height, bgcolor='#ffffff'): canvas = Image() - canvas.create_canvas(int(width), int(height), unicode_type(bgcolor)) + canvas.create_canvas(int(width), int(height), str(bgcolor)) return canvas diff --git a/src/calibre/utils/matcher.py b/src/calibre/utils/matcher.py index 2d77b40059..b78f63b7d0 100644 --- a/src/calibre/utils/matcher.py +++ b/src/calibre/utils/matcher.py @@ -16,7 +16,7 @@ from itertools import islice from calibre import detect_ncpus as cpu_count, as_unicode from calibre.constants import filesystem_encoding from calibre.utils.icu import primary_sort_key, primary_find, primary_collator -from polyglot.builtins import iteritems, itervalues, map, unicode_type, range, zip, raw_input, filter, getcwd +from polyglot.builtins import iteritems, itervalues from polyglot.queue import Queue DEFAULT_LEVEL1 = '/' @@ -95,7 +95,7 @@ class Matcher: w = [Worker(requests, results) for i in range(max(1, cpu_count()))] [x.start() for x in w] workers.extend(w) - items = map(lambda x: normalize('NFC', unicode_type(x)), filter(None, items)) + items = map(lambda x: normalize('NFC', str(x)), filter(None, items)) self.items = items = tuple(items) tasks = split(items, len(workers)) self.task_maps = [{j: i for j, (i, _) in enumerate(task)} for task in tasks] @@ -106,7 +106,7 @@ class Matcher: self.sort_keys = None def __call__(self, query, limit=None): - query = normalize('NFC', unicode_type(query)) + query = normalize('NFC', str(query)) with wlock: for i, scorer in enumerate(self.scorers): workers[0].requests.put((i, scorer, query)) @@ -259,13 +259,12 @@ class CScorer: self.m = Matcher( items, primary_collator().capsule, - unicode_type(level1), unicode_type(level2), unicode_type(level3) + str(level1), str(level2), str(level3) ) 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): @@ -292,12 +291,12 @@ def test(return_tests=False): start = memory() for i in range(10): - doit(unicode_type(i)) + doit(str(i)) gc.collect() used10 = memory() - start start = memory() for i in range(100): - doit(unicode_type(i)) + doit(str(i)) gc.collect() used100 = memory() - start if used100 > 0 and used10 > 0: @@ -328,7 +327,7 @@ def get_char(string, pos): def input_unicode(prompt): - ans = raw_input(prompt) + ans = input(prompt) if isinstance(ans, bytes): ans = ans.decode(sys.stdin.encoding) return ans @@ -339,8 +338,8 @@ def main(basedir=None, query=None): from calibre.utils.terminal import ColoredStream if basedir is None: try: - basedir = input_unicode('Enter directory to scan [%s]: ' % getcwd() - ).strip() or getcwd() + basedir = input_unicode('Enter directory to scan [%s]: ' % os.getcwd() + ).strip() or os.getcwd() except (EOFError, KeyboardInterrupt): return m = FilesystemMatcher(basedir) 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/open_with/windows.py b/src/calibre/utils/open_with/windows.py index b63a45a9f9..086cad30c7 100644 --- a/src/calibre/utils/open_with/windows.py +++ b/src/calibre/utils/open_with/windows.py @@ -12,7 +12,6 @@ from qt.core import QBuffer, QByteArray, QPixmap, Qt, QtWin, QIODevice from calibre.gui2 import must_use_qt from calibre.utils.winreg.default_programs import split_commandline from calibre_extensions import winutil -from polyglot.builtins import filter ICON_SIZE = 256 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/podofo/__init__.py b/src/calibre/utils/podofo/__init__.py index 306a53eca3..9250796b6b 100644 --- a/src/calibre/utils/podofo/__init__.py +++ b/src/calibre/utils/podofo/__init__.py @@ -11,7 +11,6 @@ from calibre.constants import preferred_encoding from calibre.ebooks.metadata import authors_to_string from calibre.ptempfile import TemporaryDirectory from calibre.utils.ipc.simple_worker import WorkerError, fork_job -from polyglot.builtins import unicode_type def get_podofo(): @@ -22,7 +21,7 @@ def get_podofo(): def prep(val): if not val: return '' - if not isinstance(val, unicode_type): + if not isinstance(val, str): val = val.decode(preferred_encoding, 'replace') return val.strip() diff --git a/src/calibre/utils/rapydscript.py b/src/calibre/utils/rapydscript.py index a7f0451724..d7299be32a 100644 --- a/src/calibre/utils/rapydscript.py +++ b/src/calibre/utils/rapydscript.py @@ -17,7 +17,7 @@ from calibre.constants import ( ) from calibre.ptempfile import TemporaryDirectory from calibre.utils.filenames import atomic_rename -from polyglot.builtins import as_bytes, as_unicode, exec_path, unicode_type, zip +from polyglot.builtins import as_bytes, as_unicode, exec_path COMPILER_PATH = 'rapydscript/compiler.js.xz' special_title = '__webengine_messages_pending__' @@ -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 @@ -475,7 +475,7 @@ def compile_srv(): rapydscript_dir = os.path.join(base, 'src', 'pyj') rb = os.path.join(base, 'src', 'calibre', 'srv', 'render_book.py') with lopen(rb, 'rb') as f: - rv = unicode_type(int(re.search(br'^RENDER_VERSION\s+=\s+(\d+)', f.read(), re.M).group(1))) + rv = str(int(re.search(br'^RENDER_VERSION\s+=\s+(\d+)', f.read(), re.M).group(1))) mathjax_version = json.loads(P('mathjax/manifest.json', data=True, allow_user_override=False))['etag'] base = os.path.join(base, 'resources', 'content-server') fname = os.path.join(rapydscript_dir, 'srv.pyj') diff --git a/src/calibre/utils/recycle_bin.py b/src/calibre/utils/recycle_bin.py index ed28767b18..caaece8adf 100644 --- a/src/calibre/utils/recycle_bin.py +++ b/src/calibre/utils/recycle_bin.py @@ -11,7 +11,6 @@ import os, shutil, time, sys from calibre import isbytestring from calibre.constants import (iswindows, ismacos, filesystem_encoding, islinux) -from polyglot.builtins import unicode_type recycle = None @@ -29,7 +28,7 @@ if iswindows: recycler = start_pipe_worker('from calibre.utils.recycle_bin import recycler_main; recycler_main()') def recycle_path(path): - winutil.move_to_trash(unicode_type(path)) + winutil.move_to_trash(str(path)) def recycler_main(): stdin = getattr(sys.stdin, 'buffer', sys.stdin) 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.py b/src/calibre/utils/search_query_parser.py index 890f71049d..56e8cdb014 100644 --- a/src/calibre/utils/search_query_parser.py +++ b/src/calibre/utils/search_query_parser.py @@ -23,7 +23,7 @@ import weakref, re from calibre.constants import preferred_encoding from calibre.utils.icu import sort_key from calibre import prints -from polyglot.builtins import codepoint_to_chr, unicode_type +from polyglot.builtins import codepoint_to_chr ''' @@ -57,7 +57,7 @@ class SavedSearchQueries: db.set_pref(self.opt_name, self.queries) def force_unicode(self, x): - if not isinstance(x, unicode_type): + if not isinstance(x, str): x = x.decode(preferred_encoding, 'replace') return x @@ -154,8 +154,8 @@ class Parser: # Had to translate named constants to numeric values lex_scanner = re.Scanner([ (r'[()]', lambda x,t: (Parser.OPCODE, t)), - (r'@.+?:[^")\s]+', lambda x,t: (Parser.WORD, unicode_type(t))), - (r'[^"()\s]+', lambda x,t: (Parser.WORD, unicode_type(t))), + (r'@.+?:[^")\s]+', lambda x,t: (Parser.WORD, str(t))), + (r'[^"()\s]+', lambda x,t: (Parser.WORD, str(t))), (r'".*?((?<!\\)")', lambda x,t: (Parser.QUOTED_WORD, t[1:-1])), (r'\s+', None) ], flags=re.DOTALL) 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/serialize.py b/src/calibre/utils/serialize.py index 3de30016fa..fd4260860e 100644 --- a/src/calibre/utils/serialize.py +++ b/src/calibre/utils/serialize.py @@ -2,8 +2,6 @@ # vim:fileencoding=utf-8 # License: GPLv3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net> -from polyglot.builtins import unicode_type - MSGPACK_MIME = 'application/x-msgpack' CANARY = 'jPoAv3zOyHvQ5JFNYg4hJ9' @@ -24,7 +22,7 @@ def create_encoder(for_json=False): def encoder(obj): if isinstance(obj, datetime): - return encoded(0, unicode_type(obj.isoformat()), ExtType) + return encoded(0, str(obj.isoformat()), ExtType) if isinstance(obj, (set, frozenset)): return encoded(1, tuple(obj), ExtType) if getattr(obj, '__calibre_serializable__', False): diff --git a/src/calibre/utils/short_uuid.py b/src/calibre/utils/short_uuid.py index d7b3a2ca0b..63b1e0fe16 100644 --- a/src/calibre/utils/short_uuid.py +++ b/src/calibre/utils/short_uuid.py @@ -9,8 +9,6 @@ Generate UUID encoded using a user specified alphabet. import string, math, uuid as _uuid -from polyglot.builtins import unicode_type - def num_to_string(number, alphabet, alphabet_len, pad_to_length=None): ans = [] @@ -36,7 +34,7 @@ class ShortUUID: # We do not include zero and one in the default alphabet as they can be # confused with the letters O and I in some fonts. And removing them # does not change the uuid_pad_len. - self.alphabet = tuple(sorted(unicode_type(alphabet or (string.digits + string.ascii_letters)[2:]))) + self.alphabet = tuple(sorted(str(alphabet or (string.digits + string.ascii_letters)[2:]))) self.alphabet_len = len(self.alphabet) self.alphabet_map = {c:i for i, c in enumerate(self.alphabet)} self.uuid_pad_len = int(math.ceil(math.log(1 << 128, self.alphabet_len))) diff --git a/src/calibre/utils/smtp.py b/src/calibre/utils/smtp.py index db11b5a523..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' @@ -13,7 +11,7 @@ This module implements a simple commandline SMTP client that supports: import sys, traceback, os, socket, encodings.idna as idna from calibre import isbytestring from calibre.constants import iswindows -from polyglot.builtins import unicode_type, as_unicode, native_string_type +from polyglot.builtins import as_unicode, native_string_type def decode_fqdn(fqdn): @@ -112,7 +110,7 @@ def get_mx(host, verbose=0): print('Find mail exchanger for', host) answers = list(dns.resolver.query(host, 'MX')) answers.sort(key=lambda x: int(getattr(x, 'preference', sys.maxsize))) - return [unicode_type(x.exchange) for x in answers if hasattr(x, 'exchange')] + return [str(x.exchange) for x in answers if hasattr(x, 'exchange')] def sendmail_direct(from_, to, msg, timeout, localhost, verbose, @@ -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 437519b8ac..cc8ccffe7f 100644 --- a/src/calibre/utils/smtplib.py +++ b/src/calibre/utils/smtplib.py @@ -52,7 +52,7 @@ from email.base64mime import body_encode as encode_base64 from sys import stderr from functools import partial -from polyglot.builtins import unicode_type, string_or_bytes +from polyglot.builtins import string_or_bytes __all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException", "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError", @@ -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 == '': @@ -590,7 +590,7 @@ class SMTP: def encode_cram_md5(challenge, user, password): challenge = base64.decodestring(challenge) - if isinstance(password, unicode_type): # Added by Kovid, see http://bugs.python.org/issue5285 + if isinstance(password, str): # Added by Kovid, see http://bugs.python.org/issue5285 password = password.encode('utf-8') response = user + " " + hmac.HMAC(password, challenge).hexdigest() return encode_base64(response, eol="") @@ -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 fb3351083b..75d632de92 100644 --- a/src/calibre/utils/terminal.py +++ b/src/calibre/utils/terminal.py @@ -9,7 +9,7 @@ import os, sys, re from calibre.prints import is_binary from calibre.constants import iswindows -from polyglot.builtins import iteritems, range, zip +from polyglot.builtins import iteritems if iswindows: import ctypes.wintypes @@ -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 84f6a55b6d..b565e057a1 100644 --- a/src/calibre/utils/test_lock.py +++ b/src/calibre/utils/test_lock.py @@ -18,7 +18,7 @@ from calibre.utils.tdir_in_cache import ( clean_tdirs_in, is_tdir_locked, retry_lock_tdir, tdir_in_cache, tdirs_in, unlock_file ) -from polyglot.builtins import iteritems, getcwd, native_string_type +from polyglot.builtins import iteritems, native_string_type def FastFailEF(name): @@ -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(): @@ -186,13 +186,13 @@ def other3(): def other4(): - cache_dir.ans = getcwd() + cache_dir.ans = os.getcwd() tdir_in_cache('t') time.sleep(30) def other5(): - cache_dir.ans = getcwd() + cache_dir.ans = os.getcwd() if not os.path.isdir(tdir_in_cache('t')): raise SystemExit(1) 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/titlecase.py b/src/calibre/utils/titlecase.py index 04544a4dcd..fe76280d26 100644 --- a/src/calibre/utils/titlecase.py +++ b/src/calibre/utils/titlecase.py @@ -12,7 +12,6 @@ License: http://www.opensource.org/licenses/mit-license.php import re from calibre.utils.icu import capitalize, upper -from polyglot.builtins import unicode_type __all__ = ['titlecase'] __version__ = '0.5' @@ -23,7 +22,7 @@ PUNCT = r"""!"#$%&'‘’()*+,\-‒–—―./:;?@[\\\]_`{|}~""" SMALL_WORDS = re.compile(r'^(%s)$' % SMALL, re.I) INLINE_PERIOD = re.compile(r'[a-z][.][a-z]', re.I) UC_ELSEWHERE = re.compile(r'[%s]*?[a-zA-Z]+[A-Z]+?' % PUNCT) -CAPFIRST = re.compile(unicode_type(r"^[%s]*?(\w)" % PUNCT), flags=re.UNICODE) +CAPFIRST = re.compile(str(r"^[%s]*?(\w)" % PUNCT), flags=re.UNICODE) SMALL_FIRST = re.compile(r'^([%s]*)(%s)\b' % (PUNCT, SMALL), re.I|re.U) SMALL_LAST = re.compile(r'\b(%s)[%s]?$' % (SMALL, PUNCT), re.I|re.U) SMALL_AFTER_NUM = re.compile(r'(\d+\s+)(a|an|the)\b', re.I|re.U) 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/windows/wintest.py b/src/calibre/utils/windows/wintest.py index 8562fb67c7..e3735739fb 100644 --- a/src/calibre/utils/windows/wintest.py +++ b/src/calibre/utils/windows/wintest.py @@ -5,7 +5,6 @@ import os import unittest -from polyglot.builtins import unicode_type class TestWinutil(unittest.TestCase): @@ -18,7 +17,7 @@ class TestWinutil(unittest.TestCase): del self.winutil def test_add_to_recent_docs(self): - path = unicode_type(os.path.abspath(__file__)) + path = str(os.path.abspath(__file__)) self.winutil.add_to_recent_docs(path, None) self.winutil.add_to_recent_docs(path, 'some-app-uid') 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/winreg/lib.py b/src/calibre/utils/winreg/lib.py index 4c9b808160..53a30a7fa0 100644 --- a/src/calibre/utils/winreg/lib.py +++ b/src/calibre/utils/winreg/lib.py @@ -7,7 +7,6 @@ __copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>' import ctypes, ctypes.wintypes as types, struct, datetime, numbers -from polyglot.builtins import unicode_type from calibre_extensions import winutil try: @@ -113,11 +112,11 @@ def expand_environment_strings(src): def convert_to_registry_data(value, has_expansions=False): if value is None: return None, winreg.REG_NONE, 0 - if isinstance(value, (unicode_type, bytes)): + if isinstance(value, (str, bytes)): buf = ctypes.create_unicode_buffer(value) return buf, (winreg.REG_EXPAND_SZ if has_expansions else winreg.REG_SZ), len(buf) * 2 if isinstance(value, (list, tuple)): - buf = ctypes.create_unicode_buffer('\0'.join(map(unicode_type, value)) + '\0\0') + buf = ctypes.create_unicode_buffer('\0'.join(map(str, value)) + '\0\0') return buf, winreg.REG_MULTI_SZ, len(buf) * 2 if isinstance(value, numbers.Integral): try: diff --git a/src/calibre/utils/zipfile.py b/src/calibre/utils/zipfile.py index b9f10a8c4c..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. @@ -18,7 +17,7 @@ from calibre import sanitize_file_name from calibre.constants import filesystem_encoding from calibre.ebooks.chardet import detect from calibre.ptempfile import SpooledTemporaryFile -from polyglot.builtins import getcwd, map, string_or_bytes, unicode_type, as_bytes +from polyglot.builtins import string_or_bytes, as_bytes try: import zlib # We may need its compression method @@ -155,7 +154,7 @@ _CD64_OFFSET_START_CENTDIR = 9 def decode_arcname(name): - if not isinstance(name, unicode_type): + if not isinstance(name, str): try: name = name.decode('utf-8') except Exception: @@ -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": @@ -407,7 +406,7 @@ class ZipInfo : return header + filename + extra def _encodeFilenameFlags(self): - if isinstance(self.filename, unicode_type): + if isinstance(self.filename, str): return self.filename.encode('utf-8'), self.flag_bits | 0x800 else: return self.filename, self.flag_bits @@ -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") @@ -1093,7 +1092,7 @@ class ZipFile: member = self.getinfo(member) if path is None: - path = getcwd() + path = os.getcwd() return self._extract_member(member, path, pwd) @@ -1224,7 +1223,7 @@ class ZipFile: arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) while arcname[0] in (os.sep, os.altsep): arcname = arcname[1:] - if not isinstance(arcname, unicode_type): + if not isinstance(arcname, str): arcname = arcname.decode(filesystem_encoding) if isdir and not arcname.endswith('/'): arcname += '/' @@ -1302,7 +1301,7 @@ class ZipFile: if not isinstance(byts, bytes): byts = byts.encode('utf-8') if not isinstance(zinfo_or_arcname, ZipInfo): - if not isinstance(zinfo_or_arcname, unicode_type): + if not isinstance(zinfo_or_arcname, str): zinfo_or_arcname = zinfo_or_arcname.decode(filesystem_encoding) zinfo = ZipInfo(filename=zinfo_or_arcname, date_time=time.localtime(time.time())[:6]) @@ -1506,7 +1505,7 @@ def safe_replace(zipstream, name, datastream, extra_replacements={}, with SpooledTemporaryFile(max_size=100*1024*1024) as temp: ztemp = ZipFile(temp, 'w') for obj in z.infolist(): - if isinstance(obj.filename, unicode_type): + if isinstance(obj.filename, str): obj.flag_bits |= 0x16 # Set isUTF-8 bit if obj.filename in names: ztemp.writestr(obj, rbytes(obj.filename)) 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 741eee146b..14d3951a9c 100644 --- a/src/calibre/web/feeds/__init__.py +++ b/src/calibre/web/feeds/__init__.py @@ -12,7 +12,7 @@ from calibre.utils.logging import default_log from calibre import entity_to_unicode, strftime, force_unicode from calibre.utils.date import dt_factory, utcnow, local_tz from calibre.utils.cleantext import clean_ascii_chars, clean_xml_chars -from polyglot.builtins import unicode_type, string_or_bytes, map +from polyglot.builtins import string_or_bytes class Article: @@ -35,9 +35,9 @@ class Article: self.author = author self.toc_thumbnail = None self.internal_toc_entries = () - if author and not isinstance(author, unicode_type): + if author and not isinstance(author, str): author = author.decode('utf-8', 'replace') - if summary and not isinstance(summary, unicode_type): + if summary and not isinstance(summary, str): summary = summary.decode('utf-8', 'replace') summary = clean_xml_chars(summary) if summary else summary self.summary = summary @@ -68,13 +68,13 @@ class Article: @formatted_date.setter def formatted_date(self, val): - if isinstance(val, unicode_type): + if isinstance(val, str): self._formatted_date = val @property def title(self): t = self._title - if not isinstance(t, unicode_type) and hasattr(t, 'decode'): + if not isinstance(t, str) and hasattr(t, 'decode'): t = t.decode('utf-8', 'replace') return t @@ -142,7 +142,7 @@ class Feed: def populate_from_preparsed_feed(self, title, articles, oldest_article=7, max_articles_per_feed=100): - self.title = unicode_type(title if title else _('Unknown feed')) + self.title = str(title if title else _('Unknown feed')) self.description = '' self.image_url = None self.articles = [] @@ -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 @@ -209,7 +209,7 @@ class Feed: author = item.get('author', None) content = [i.value for i in item.get('content', []) if i.value] - content = [i if isinstance(i, unicode_type) else i.decode('utf-8', 'replace') + content = [i if isinstance(i, str) else i.decode('utf-8', 'replace') for i in content] content = '\n'.join(content) if not content.strip(): @@ -225,7 +225,7 @@ class Feed: self.logger.debug('Skipping article %s (%s) from feed %s as it is too old.'% (title, article.localtime.strftime('%a, %d %b, %Y %H:%M'), self.title)) except UnicodeDecodeError: - if not isinstance(title, unicode_type): + if not isinstance(title, str): title = title.decode('utf-8', 'replace') self.logger.debug('Skipping article %s as it is too old'%title) diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 595783724b..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>' ''' @@ -38,7 +37,7 @@ from calibre.web.fetch.simple import ( AbortArticle, RecursiveFetcher, option_parser as web2disk_option_parser ) from calibre.web.fetch.utils import prepare_masthead_image -from polyglot.builtins import getcwd, string_or_bytes, unicode_type +from polyglot.builtins import string_or_bytes def classes(classes): @@ -712,7 +711,7 @@ class BasicNewsRecipe(Recipe): _raw = url_or_raw if raw: return _raw - if not isinstance(_raw, unicode_type) and self.encoding: + if not isinstance(_raw, str) and self.encoding: if callable(self.encoding): _raw = self.encoding(_raw) else: @@ -721,7 +720,7 @@ class BasicNewsRecipe(Recipe): strip_encoding_declarations, xml_to_unicode ) from calibre.utils.cleantext import clean_xml_chars - if isinstance(_raw, unicode_type): + if isinstance(_raw, str): _raw = strip_encoding_declarations(_raw) else: _raw = xml_to_unicode(_raw, strip_encoding_pats=True, resolve_entities=True)[0] @@ -898,11 +897,11 @@ class BasicNewsRecipe(Recipe): :param progress_reporter: A Callable that takes two arguments: progress (a number between 0 and 1) and a string message. The message should be optional. ''' self.log = ThreadSafeWrapper(log) - if not isinstance(self.title, unicode_type): - self.title = unicode_type(self.title, 'utf-8', 'replace') + if not isinstance(self.title, str): + self.title = str(self.title, 'utf-8', 'replace') self.debug = options.verbose > 1 - self.output_dir = os.path.abspath(getcwd()) + self.output_dir = os.path.abspath(os.getcwd()) self.verbose = options.verbose self.test = options.test if self.test and not isinstance(self.test, tuple): @@ -934,9 +933,9 @@ class BasicNewsRecipe(Recipe): self.css_map = {} web2disk_cmdline = ['web2disk', - '--timeout', unicode_type(self.timeout), - '--max-recursions', unicode_type(self.recursions), - '--delay', unicode_type(self.delay), + '--timeout', str(self.timeout), + '--max-recursions', str(self.recursions), + '--delay', str(self.delay), ] if self.verbose: @@ -1429,7 +1428,7 @@ class BasicNewsRecipe(Recipe): ''' try: from calibre.ebooks.covers import create_cover - title = self.title if isinstance(self.title, unicode_type) else \ + title = self.title if isinstance(self.title, str) else \ self.title.decode(preferred_encoding, 'replace') date = strftime(self.timefmt).replace('[', '').replace(']', '') img_data = create_cover(title, [date]) @@ -1478,7 +1477,7 @@ class BasicNewsRecipe(Recipe): article_titles.append(force_unicode(a.title, 'utf-8')) desc = self.description - if not isinstance(desc, unicode_type): + if not isinstance(desc, str): desc = desc.decode('utf-8', 'replace') mi.comments = (_('Articles in this issue:' ) + '\n\n' + '\n\n'.join(article_titles)) + '\n\n' + desc @@ -1495,7 +1494,7 @@ class BasicNewsRecipe(Recipe): mp = getattr(self, 'masthead_path', None) if mp is not None and os.access(mp, os.R_OK): from calibre.ebooks.metadata.opf2 import Guide - ref = Guide.Reference(os.path.basename(self.masthead_path), getcwd()) + ref = Guide.Reference(os.path.basename(self.masthead_path), os.getcwd()) ref.type = 'masthead' ref.title = 'Masthead Image' opf.guide.append(ref) @@ -1589,7 +1588,7 @@ class BasicNewsRecipe(Recipe): elem = BeautifulSoup(templ.render(doctype='xhtml').decode('utf-8')).find('div') body.insert(len(body.contents), elem) with open(last, 'wb') as fi: - fi.write(unicode_type(soup).encode('utf-8')) + fi.write(str(soup).encode('utf-8')) if len(feeds) == 0: raise Exception('All feeds are empty, aborting.') diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index 7c765d6b21..5e16423832 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -10,7 +10,7 @@ from calibre.web.feeds.news import (BasicNewsRecipe, CustomIndexRecipe, AutomaticNewsRecipe, CalibrePeriodical) from calibre.ebooks.BeautifulSoup import BeautifulSoup from calibre.utils.config import JSONConfig -from polyglot.builtins import itervalues, unicode_type, codepoint_to_chr, range +from polyglot.builtins import itervalues, codepoint_to_chr basic_recipes = (BasicNewsRecipe, AutomaticNewsRecipe, CustomIndexRecipe, CalibrePeriodical) @@ -32,7 +32,7 @@ def compile_recipe(src): :return: Recipe class or None, if no such class was found in src ''' - if not isinstance(src, unicode_type): + if not isinstance(src, str): match = re.search(br'coding[:=]\s*([-\w.]+)', src[:200]) enc = match.group(1).decode('utf-8') if match else 'utf-8' src = src.decode(enc) @@ -46,7 +46,7 @@ def compile_recipe(src): 'AutomaticNewsRecipe':AutomaticNewsRecipe, 'time':time, 're':re, 'BeautifulSoup':BeautifulSoup, - 'unicode': unicode_type, + 'unicode': str, 'unichr': codepoint_to_chr, 'xrange': range, } diff --git a/src/calibre/web/feeds/recipes/collection.py b/src/calibre/web/feeds/recipes/collection.py index c9716b7d3d..53f7efee3b 100644 --- a/src/calibre/web/feeds/recipes/collection.py +++ b/src/calibre/web/feeds/recipes/collection.py @@ -19,7 +19,7 @@ from calibre.constants import numeric_version from calibre.utils.iso8601 import parse_iso8601 from calibre.utils.date import now as nowf, utcnow, local_tz, isoformat, EPOCH, UNDEFINED_DATE from calibre.utils.recycle_bin import delete_file -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems NS = 'http://calibre-ebook.com/recipe_collection' E = ElementMaker(namespace=NS, nsmap={None:NS}) @@ -54,7 +54,7 @@ def serialize_recipe(urn, recipe_class): if ns is True: ns = 'yes' return E.recipe({ - 'id' : unicode_type(urn), + 'id' : str(urn), 'title' : attr('title', _('Unknown')), 'author' : attr('__author__', default_author), 'language' : attr('language', 'und'), @@ -81,7 +81,7 @@ def serialize_collection(mapping_of_recipe_classes): traceback.print_exc() continue collection.append(recipe) - collection.set('count', unicode_type(len(collection))) + collection.set('count', str(len(collection))) return etree.tostring(collection, encoding='utf-8', xml_declaration=True, pretty_print=True) @@ -139,14 +139,14 @@ def update_custom_recipes(script_ids): bdir = os.path.dirname(custom_recipes.file_path) for id_, title, script in script_ids: - id_ = unicode_type(int(id_)) + id_ = str(int(id_)) existing = custom_recipes.get(id_, None) if existing is None: fname = custom_recipe_filename(id_, title) else: fname = existing[1] - if isinstance(script, unicode_type): + if isinstance(script, str): script = script.encode('utf-8') custom_recipes[id_] = (title, fname) @@ -172,10 +172,10 @@ def add_custom_recipes(script_map): bdir = os.path.dirname(custom_recipes.file_path) with custom_recipes: for title, script in iteritems(script_map): - fid = unicode_type(id_) + fid = str(id_) fname = custom_recipe_filename(fid, title) - if isinstance(script, unicode_type): + if isinstance(script, str): script = script.encode('utf-8') custom_recipes[fid] = (title, fname) @@ -190,7 +190,7 @@ def add_custom_recipes(script_map): def remove_custom_recipe(id_): from calibre.web.feeds.recipes import custom_recipes - id_ = unicode_type(int(id_)) + id_ = str(int(id_)) existing = custom_recipes.get(id_, None) if existing is not None: bdir = os.path.dirname(custom_recipes.file_path) @@ -204,7 +204,7 @@ def remove_custom_recipe(id_): def get_custom_recipe(id_): from calibre.web.feeds.recipes import custom_recipes - id_ = unicode_type(int(id_)) + id_ = str(int(id_)) existing = custom_recipes.get(id_, None) if existing is not None: bdir = os.path.dirname(custom_recipes.file_path) @@ -403,7 +403,7 @@ class SchedulerConfig: elif typ == 'day/time': text = '%d:%d:%d'%schedule elif typ in ('days_of_week', 'days_of_month'): - dw = ','.join(map(unicode_type, map(int, schedule[0]))) + dw = ','.join(map(str, map(int, schedule[0]))) text = '%s:%d:%d'%(dw, schedule[1], schedule[2]) else: raise ValueError('Unknown schedule type: %r'%typ) @@ -552,8 +552,8 @@ class SchedulerConfig: username, password = c[k] except: username = password = '' - self.set_account_info(urn, unicode_type(username), - unicode_type(password)) + self.set_account_info(urn, str(username), + str(password)) except: continue del c diff --git a/src/calibre/web/feeds/recipes/model.py b/src/calibre/web/feeds/recipes/model.py index a5e7a801a5..979513b7ba 100644 --- a/src/calibre/web/feeds/recipes/model.py +++ b/src/calibre/web/feeds/recipes/model.py @@ -20,7 +20,7 @@ from calibre.web.feeds.recipes.collection import ( get_custom_recipe_collection, remove_custom_recipe, update_custom_recipe, update_custom_recipes ) -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems class NewsTreeItem: @@ -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() @@ -309,7 +309,7 @@ class RecipeModel(QAbstractItemModel, AdaptSQP): def search(self, query): results = [] try: - query = unicode_type(query).strip() + query = str(query).strip() if query: results = self.parse(query) if not results: diff --git a/src/calibre/web/feeds/templates.py b/src/calibre/web/feeds/templates.py index 6995216c22..961582bd15 100644 --- a/src/calibre/web/feeds/templates.py +++ b/src/calibre/web/feeds/templates.py @@ -13,13 +13,12 @@ from lxml.html.builder import HTML, HEAD, TITLE, STYLE, DIV, BODY, \ TABLE, TD, TR from calibre import strftime, isbytestring -from polyglot.builtins import unicode_type def attrs(*args, **kw): rescale = kw.pop('rescale', None) if rescale is not None: - kw['data-calibre-rescale'] = unicode_type(rescale) + kw['data-calibre-rescale'] = str(rescale) if args: kw['class'] = ' '.join(args) return kw @@ -79,7 +78,7 @@ class EmbeddedContent(Template): self.root = HTML(head, BODY(H2(article.title), DIV())) div = self.root.find('body').find('div') - if elements and isinstance(elements[0], unicode_type): + if elements and isinstance(elements[0], str): div.text = elements[0] elements = list(elements)[1:] for elem in elements: 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 3a3168e190..b66e2d6889 100644 --- a/src/calibre/web/fetch/simple.py +++ b/src/calibre/web/fetch/simple.py @@ -29,7 +29,6 @@ from calibre.utils.img import image_from_data, image_to_data from calibre.utils.imghdr import what from calibre.utils.logging import Log from calibre.web.fetch.utils import rescale_image -from polyglot.builtins import unicode_type from polyglot.http_client import responses from polyglot.urllib import ( URLError, quote, url2pathname, urljoin, urlparse, urlsplit, urlunparse, @@ -108,7 +107,7 @@ def save_soup(soup, target): if path and os.path.isfile(path) and os.path.exists(path) and os.path.isabs(path): tag[key] = unicode_path(relpath(path, selfdir).replace(os.sep, '/')) - html = unicode_type(soup) + html = str(soup) with open(target, 'wb') as f: f.write(html.encode('utf-8')) @@ -116,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 @@ -138,7 +137,7 @@ class RecursiveFetcher: def __init__(self, options, log, image_map={}, css_map={}, job_info=None): bd = options.dir - if not isinstance(bd, unicode_type): + if not isinstance(bd, str): bd = bd.decode(filesystem_encoding) self.base_dir = os.path.abspath(os.path.expanduser(bd)) @@ -356,7 +355,7 @@ class RecursiveFetcher: except Exception: self.log.exception('Could not fetch stylesheet ', iurl) continue - stylepath = os.path.join(diskpath, 'style'+unicode_type(c)+'.css') + stylepath = os.path.join(diskpath, 'style'+str(c)+'.css') with self.stylemap_lock: self.stylemap[iurl] = stylepath with open(stylepath, 'wb') as x: @@ -364,7 +363,7 @@ class RecursiveFetcher: tag['href'] = stylepath else: for ns in tag.findAll(text=True): - src = unicode_type(ns) + src = str(ns) m = self.__class__.CSS_IMPORT_PATTERN.search(src) if m: iurl = m.group(1) @@ -383,7 +382,7 @@ class RecursiveFetcher: self.log.exception('Could not fetch stylesheet ', iurl) continue c += 1 - stylepath = os.path.join(diskpath, 'style'+unicode_type(c)+'.css') + stylepath = os.path.join(diskpath, 'style'+str(c)+'.css') with self.stylemap_lock: self.stylemap[iurl] = stylepath with open(stylepath, 'wb') as x: @@ -427,7 +426,7 @@ class RecursiveFetcher: self.log.exception('Could not fetch image ', iurl) continue c += 1 - fname = ascii_filename('img'+unicode_type(c)) + fname = ascii_filename('img'+str(c)) data = self.preprocess_image_ext(data, iurl) if self.preprocess_image_ext is not None else data if data is None: continue @@ -523,7 +522,7 @@ class RecursiveFetcher: continue if self.files > self.max_files: return res - linkdir = 'link'+unicode_type(c) if into_dir else '' + linkdir = 'link'+str(c) if into_dir else '' linkdiskpath = os.path.join(diskpath, linkdir) if not os.path.exists(linkdiskpath): os.mkdir(linkdiskpath) @@ -554,7 +553,7 @@ class RecursiveFetcher: self.process_stylesheets(soup, newbaseurl) _fname = basename(iurl) - if not isinstance(_fname, unicode_type): + if not isinstance(_fname, str): _fname.decode('latin1', 'replace') _fname = _fname.replace('%', '').replace(os.sep, '') _fname = ascii_filename(_fname) diff --git a/src/css_selectors/parser.py b/src/css_selectors/parser.py index 5b575badbe..2a8be8f31b 100644 --- a/src/css_selectors/parser.py +++ b/src/css_selectors/parser.py @@ -15,7 +15,7 @@ import operator import string from css_selectors.errors import SelectorSyntaxError, ExpressionError -from polyglot.builtins import unicode_type, codepoint_to_chr, range +from polyglot.builtins import unicode_type, codepoint_to_chr utab = {c:c+32 for c in range(ord(u'A'), ord(u'Z')+1)} diff --git a/src/tinycss/fonts3.py b/src/tinycss/fonts3.py index 3e62907b45..f592a66730 100644 --- a/src/tinycss/fonts3.py +++ b/src/tinycss/fonts3.py @@ -7,7 +7,6 @@ __copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>' import re -from polyglot.builtins import map from tinycss.css21 import CSS21Parser, ParseError from .tokenizer import tokenize_grouped