From 4987db4bd0557c396cc607c7d2761eee45c936b8 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Wed, 18 Jul 2018 18:36:36 -0700 Subject: [PATCH] Switch to f-string formatting in many places. --- etiquette/decorators.py | 4 +- etiquette/helpers.py | 20 ++++---- etiquette/objects.py | 47 +++++++++---------- etiquette/photodb.py | 5 +- etiquette/searchhelpers.py | 4 +- .../etiquette_flask/caching.py | 2 +- .../etiquette_flask/sessions.py | 5 +- 7 files changed, 44 insertions(+), 43 deletions(-) diff --git a/etiquette/decorators.py b/etiquette/decorators.py index 067587e..0f4b027 100644 --- a/etiquette/decorators.py +++ b/etiquette/decorators.py @@ -53,7 +53,7 @@ def not_implemented(function): ''' Decorator to remember what needs doing. ''' - warnings.warn('%s is not implemented' % function.__name__) + warnings.warn(f'{function.__name__} is not implemented') return function def time_me(function): @@ -66,7 +66,7 @@ def time_me(function): result = function(*args, **kwargs) end = time.time() duration = end - start - print('%s: %0.8f' % (function.__name__, duration)) + print(f'{function.__name__}: {duration:0.8f}') return result return timed_function diff --git a/etiquette/helpers.py b/etiquette/helpers.py index 3eed846..26a6651 100644 --- a/etiquette/helpers.py +++ b/etiquette/helpers.py @@ -25,9 +25,10 @@ def album_zip_directories(album, recursive=True): ''' directories = {} if album.title: - root_folder = 'album %s - %s' % (album.id, remove_path_badchars(album.title)) + title = remove_path_badchars(album.title) + root_folder = f'album {album.id} - {title}' else: - root_folder = 'album %s' % album.id + root_folder = f'album {album.id}' directories[album] = root_folder if recursive: @@ -54,7 +55,7 @@ def album_zip_filenames(album, recursive=True): filepath = photo.real_path.absolute_path if filepath in arcnames: continue - photo_name = '%s - %s' % (photo.id, photo.basename) + photo_name = f'{photo.id} - {photo.basename}' arcnames[filepath] = os.path.join(directory, photo_name) return arcnames @@ -128,10 +129,12 @@ def dict_to_params(d): ''' if not d: return '' - params = ['%s=%s' % (k, v) for (k, v) in d.items() if v] + + params = [f'{key}={value}' for (key, value) in d.items() if value] params = '&'.join(params) if params: params = '?' + params + return params def fit_into_bounds(image_width, image_height, frame_width, frame_height): @@ -348,7 +351,7 @@ def recursive_dict_keys(d): keys = set(d.keys()) for (key, value) in d.items(): if isinstance(value, dict): - subkeys = {'%s\\%s' % (key, subkey) for subkey in recursive_dict_keys(value)} + subkeys = {f'{key}\\{subkey}' for subkey in recursive_dict_keys(value)} keys.update(subkeys) return keys @@ -397,7 +400,7 @@ def seconds_to_hms(seconds): if minutes: parts.append(minutes) parts.append(seconds) - hms = ':'.join('%02d' % part for part in parts) + hms = ':'.join(f'{part:02d}' for part in parts) return hms def split_easybake_string(ebstring): @@ -450,7 +453,8 @@ def sql_listify(items): ['hi', 'ho', 'hey'] -> '("hi", "ho", "hey")' ''' - return '(%s)' % ', '.join('"%s"' % item for item in items) + items = ', '.join(f'"{item}"' for item in items) + return '(%s)' % items def truthystring(s): ''' @@ -466,7 +470,7 @@ def truthystring(s): return bool(s) if not isinstance(s, str): - raise TypeError('Unsupported type %s' % type(s)) + raise TypeError(f'Unsupported type {type(s)}') s = s.lower() if s in constants.TRUTHYSTRING_TRUE: diff --git a/etiquette/objects.py b/etiquette/objects.py index 552d453..20f6684 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -53,7 +53,7 @@ class ObjectBase: return None if not isinstance(author_id, str): - raise TypeError('author_id must be string, not %s' % type(author_id)) + raise TypeError(f'Author ID must be string, not {type(author_id)}.') author_id = author_id.strip() if author_id == '': @@ -167,7 +167,7 @@ class GroupableMixin: def get_children(self): child_rows = self.photodb.sql_select( - 'SELECT memberid FROM %s WHERE parentid == ?' % self.group_table, + f'SELECT memberid FROM {self.group_table} WHERE parentid == ?', [self.id] ) child_ids = [row[0] for row in child_rows] @@ -313,7 +313,7 @@ class Album(ObjectBase, GroupableMixin): ''' filepath = pathclass.Path(filepath) if not filepath.is_dir: - raise ValueError('%s is not a directory' % filepath) + raise ValueError(f'{filepath} is not a directory') try: existing = self.photodb.get_album_by_path(filepath) @@ -476,7 +476,7 @@ class Album(ObjectBase, GroupableMixin): def has_photo(self, photo): if not isinstance(photo, Photo): - raise TypeError('`photo` must be of type %s' % Photo) + raise TypeError(f'`photo` must be of type {Photo}, not {type(photo)}.') rel_row = self.photodb.sql_select_one( 'SELECT 1 FROM album_photo_rel WHERE albumid == ? AND photoid == ?', @@ -586,7 +586,7 @@ class Bookmark(ObjectBase): return '' if not isinstance(title, str): - raise TypeError('Title must be string, not %s' % type(title)) + raise TypeError(f'Title must be string, not {type(title)}') title = title.strip() for whitespace in string.whitespace: @@ -600,12 +600,12 @@ class Bookmark(ObjectBase): return '' if not isinstance(url, str): - raise TypeError('URL must be string, not %s' % type(url)) + raise TypeError(f'URL must be string, not {type(url)}') url = url.strip() if not url: - raise ValueError('Invalid URL "%s"' % url) + raise ValueError(f'Invalid URL "{url}"') return url @@ -721,15 +721,13 @@ class Photo(ObjectBase): # keep our current one. existing = self.has_tag(tag, check_children=True) if existing: - message = f'Preferring existing {existing} over {tag}' - self.photodb.log.debug(message) + self.photodb.log.debug(f'Preferring existing {existing} over {tag}') return existing # If the new tag is more specific, remove our current one for it. for parent in tag.walk_parents(): if self.has_tag(parent, check_children=False): - message = f'Preferring new {tag} over {parent}' - self.photodb.log.debug(message) + self.photodb.log.debug(f'Preferring new {tag} over {parent}') self.remove_tag(parent, commit=False) self.photodb.log.debug('Applying %s to %s', tag, self) @@ -898,7 +896,7 @@ class Photo(ObjectBase): tag_by_id = {t.id: t for t in tag_options} tag_option_ids = helpers.sql_listify(tag_by_id) rel_row = self.photodb.sql_select_one( - 'SELECT tagid FROM photo_tag_rel WHERE photoid == ? AND tagid IN %s' % tag_option_ids, + f'SELECT tagid FROM photo_tag_rel WHERE photoid == ? AND tagid IN {tag_option_ids}', [self.id] ) @@ -1123,7 +1121,7 @@ class Photo(ObjectBase): cleaned = helpers.remove_path_badchars(new_filename) cleaned = cleaned.strip() if not cleaned: - raise ValueError('"%s" is not valid.' % new_filename) + raise ValueError(f'"{new_filename}" is not valid.') new_filename = cleaned data = { @@ -1166,12 +1164,10 @@ class Tag(ObjectBase, GroupableMixin): return hash(self.name) def __repr__(self): - rep = f'Tag:{self.id}:{self.name}' - return rep + return f'Tag:{self.id}:{self.name}' def __str__(self): - rep = f'Tag:{self.name}' - return rep + return f'Tag:{self.name}' @staticmethod def normalize_description(description): @@ -1179,7 +1175,7 @@ class Tag(ObjectBase, GroupableMixin): return '' if not isinstance(description, str): - raise TypeError('Description must be string, not %s' % type(description)) + raise TypeError(f'Description must be string, not {type(description)}') description = description.strip() @@ -1290,12 +1286,12 @@ class Tag(ObjectBase, GroupableMixin): # For those photos that only had the syn, simply replace with master. if replace_photoids: - query = ''' + query = f''' UPDATE photo_tag_rel SET tagid = ? WHERE tagid == ? - AND photoid IN %s - ''' % helpers.sql_listify(replace_photoids) + AND photoid IN {helpers.sql_listify(replace_photoids)} + ''' bindings = [mastertag.id, self.id] self.photodb.sql_execute(query, bindings) @@ -1484,12 +1480,10 @@ class User(ObjectBase): self._display_name = self.normalize_display_name(db_row['display_name']) def __repr__(self): - rep = f'User:{self.id}:{self.username}' - return rep + return f'User:{self.id}:{self.username}' def __str__(self): - rep = f'User:{self.username}' - return rep + return f'User:{self.username}' @staticmethod def normalize_display_name(display_name, max_length=None): @@ -1497,7 +1491,7 @@ class User(ObjectBase): return None if not isinstance(display_name, str): - raise TypeError('Display Name must be string, not %s' % type(display_name)) + raise TypeError(f'Display name must be string, not {type(display_name)}.') display_name = display_name.strip() @@ -1536,6 +1530,7 @@ class User(ObjectBase): self.photodb.log.debug('Committing - set display name') self.photodb.commit() + class WarningBag: def __init__(self): self.warnings = set() diff --git a/etiquette/photodb.py b/etiquette/photodb.py index df913cc..3056aee 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -627,7 +627,7 @@ class PDBPhotoMixin: query = ' '.join(query) - query = '%s\n%s\n%s' % ('-' * 80, query, '-' * 80) + query = f'{"-" * 80}\n{query}\n{"-" * 80}' print(query, bindings) #explain = self.sql_execute('EXPLAIN QUERY PLAN ' + query, bindings) @@ -1474,7 +1474,8 @@ class PhotoDB( id_batch = ids_needed[:999] ids_needed = ids_needed[999:] - qmarks = '(%s)' % ','.join('?' * len(id_batch)) + qmarks = ','.join('?' * len(id_batch)) + qmarks = '(%s)' % qmarks query = 'SELECT * FROM %s WHERE id IN %s' % (thing_map['table'], qmarks) more_things = self.sql_select(query, id_batch) for thing_row in more_things: diff --git a/etiquette/searchhelpers.py b/etiquette/searchhelpers.py index 29c703f..7dafd92 100644 --- a/etiquette/searchhelpers.py +++ b/etiquette/searchhelpers.py @@ -340,7 +340,7 @@ def normalize_positive_integer(number): number = int(number) if number < 0: - raise ValueError('%d must be >= 0.' % number) + raise ValueError(f'{number} must be >= 0.') return number @@ -434,7 +434,7 @@ def tag_expression_tree_builder( except expressionmatch.NoTokens: return None except Exception as exc: - warning_bag.add('Bad expression "%s"' % tag_expression) + warning_bag.add(f'Bad expression "{tag_expression}"') return None for node in expression_tree.walk_leaves(): diff --git a/frontends/etiquette_flask/etiquette_flask/caching.py b/frontends/etiquette_flask/etiquette_flask/caching.py index 1515791..b1f685b 100644 --- a/frontends/etiquette_flask/etiquette_flask/caching.py +++ b/frontends/etiquette_flask/etiquette_flask/caching.py @@ -67,6 +67,6 @@ class CacheFile: def get_headers(self): headers = { 'ETag': self.get_etag(), - 'Cache-Control': 'max-age=%d' % self.max_age, + 'Cache-Control': f'max-age={self.max_age}', } return headers diff --git a/frontends/etiquette_flask/etiquette_flask/sessions.py b/frontends/etiquette_flask/etiquette_flask/sessions.py index 0090890..e4bebb3 100644 --- a/frontends/etiquette_flask/etiquette_flask/sessions.py +++ b/frontends/etiquette_flask/etiquette_flask/sessions.py @@ -8,6 +8,7 @@ import etiquette from voussoirkit import cacheclass + SESSION_MAX_AGE = 86400 REQUEST_TYPES = (flask.Request, werkzeug.wrappers.Request, werkzeug.local.LocalProxy) @@ -109,9 +110,9 @@ class Session: def __repr__(self): if self.user: - return 'Session %s for user %s' % (self.token, self.user) + return f'Session {self.token} for user {self.user}' else: - return 'Session %s for anonymous' % self.token + return f'Session {self.token} for anonymous' def expired(self): now = etiquette.helpers.now()