From b4e316f4badc2703cea566267886d8b094d0f569 Mon Sep 17 00:00:00 2001 From: Asher Foa Date: Sat, 17 Aug 2019 12:28:06 -0700 Subject: [PATCH] Use f-strings in util code (#8178) --- src/python/pants/util/collections.py | 2 +- src/python/pants/util/contextutil.py | 8 ++++---- src/python/pants/util/debug.py | 2 +- src/python/pants/util/netrc.py | 2 +- src/python/pants/util/objects.py | 10 +++++----- src/python/pants/util/retry.py | 2 +- src/python/pants/util/s3_log_aggregator.py | 6 +++--- src/python/pants/util/tarutil.py | 4 ++-- src/python/pants/util/xml_parser.py | 10 ++++------ 9 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/python/pants/util/collections.py b/src/python/pants/util/collections.py index b0ba38c512f..e026c44786e 100644 --- a/src/python/pants/util/collections.py +++ b/src/python/pants/util/collections.py @@ -61,4 +61,4 @@ def assert_single_element(iterable): except StopIteration: return first_item - raise ValueError("iterable {!r} has more than one element.".format(iterable)) + raise ValueError(f"iterable {iterable!r} has more than one element.") diff --git a/src/python/pants/util/contextutil.py b/src/python/pants/util/contextutil.py index f09b1b70938..9faa731eede 100644 --- a/src/python/pants/util/contextutil.py +++ b/src/python/pants/util/contextutil.py @@ -227,7 +227,7 @@ def safe_file(path, suffix=None, cleanup=True): :param str suffix: Use this suffix to create the copy. Otherwise use a random string. :param bool cleanup: Whether or not to clean up the copy. """ - safe_path = '{0}.{1}'.format(path, suffix or uuid.uuid4()) + safe_path = '{}.{}'.format(path, suffix or uuid.uuid4()) if os.path.exists(path): shutil.copy(path, safe_path) try: @@ -270,13 +270,13 @@ def open_zip(path_or_file, *args, **kwargs): :returns: `class 'contextlib.GeneratorContextManager`. """ if not path_or_file: - raise InvalidZipPath('Invalid zip location: {}'.format(path_or_file)) + raise InvalidZipPath(f'Invalid zip location: {path_or_file}') allowZip64 = kwargs.pop('allowZip64', True) try: zf = zipfile.ZipFile(path_or_file, *args, allowZip64=allowZip64, **kwargs) except zipfile.BadZipfile as bze: # Use the realpath in order to follow symlinks back to the problem source file. - raise zipfile.BadZipfile("Bad Zipfile {0}: {1}".format(os.path.realpath(path_or_file), bze)) + raise zipfile.BadZipfile("Bad Zipfile {}: {}".format(os.path.realpath(path_or_file), bze)) try: yield zf finally: @@ -362,7 +362,7 @@ def maybe_profiled(profile_path): view_cmd = green('gprof2dot -f pstats {path} | dot -Tpng -o {path}.png && open {path}.png' .format(path=profile_path)) logging.getLogger().info( - 'Dumped profile data to: {}\nUse e.g. {} to render and view.'.format(profile_path, view_cmd) + f'Dumped profile data to: {profile_path}\nUse e.g. {view_cmd} to render and view.' ) diff --git a/src/python/pants/util/debug.py b/src/python/pants/util/debug.py index 20151a42f46..f0129872216 100644 --- a/src/python/pants/util/debug.py +++ b/src/python/pants/util/debug.py @@ -43,7 +43,7 @@ def __getattr__(self, attr): def wrapped_method_call(*args, **kwargs): r = getattr(self.wrapped_object, attr)(*args, **kwargs) dlog( - '{}.{}(*{}, **{}) -> {}'.format(self.wrapped_object, attr, args, kwargs, r), + f'{self.wrapped_object}.{attr}(*{args}, **{kwargs}) -> {r}', self.log_path ) return r diff --git a/src/python/pants/util/netrc.py b/src/python/pants/util/netrc.py index 1203f576972..ee332209e75 100644 --- a/src/python/pants/util/netrc.py +++ b/src/python/pants/util/netrc.py @@ -44,4 +44,4 @@ def _ensure_loaded(self): if len(self._login) == 0: raise self.NetrcError('Found no usable authentication blocks in ~/.netrc') except NetrcParseError as e: - raise self.NetrcError('Problem parsing ~/.netrc: {}'.format(e)) + raise self.NetrcError(f'Problem parsing ~/.netrc: {e}') diff --git a/src/python/pants/util/objects.py b/src/python/pants/util/objects.py index f59056ae7a5..a45f08f28c3 100644 --- a/src/python/pants/util/objects.py +++ b/src/python/pants/util/objects.py @@ -18,7 +18,7 @@ class TypeCheckError(TypeError): # TODO: make some wrapper exception class to make this kind of # prefixing easy (maybe using a class field format string?). def __init__(self, type_name, msg, *args, **kwargs): - formatted_msg = "type check error in class {}: {}".format(type_name, msg) + formatted_msg = f"type check error in class {type_name}: {msg}" super().__init__(formatted_msg, *args, **kwargs) @@ -105,7 +105,7 @@ def __new__(cls, *args, **kwargs): this_object = super().__new__(cls, *args, **kwargs) except TypeError as e: raise cls.make_type_error( - "error in namedtuple() base constructor: {}".format(e)) + f"error in namedtuple() base constructor: {e}") # TODO: Make this kind of exception pattern (filter for errors then display them all at once) # more ergonomic. @@ -122,7 +122,7 @@ def __new__(cls, *args, **kwargs): field_constraint.validate_satisfied_by(field_value) except TypeConstraintError as e: type_failure_msgs.append( - "field '{}' was invalid: {}".format(field_name, e)) + f"field '{field_name}' was invalid: {e}") if type_failure_msgs: raise cls.make_type_error( '{} type checking constructor arguments:\n{}' @@ -203,7 +203,7 @@ def __repr__(self): args_formatted = [] for field_name in field_names: field_value = getattr(self, field_name) - args_formatted.append("{}={!r}".format(field_name, field_value)) + args_formatted.append(f"{field_name}={field_value!r}") return '{class_name}({args_joined})'.format( class_name=type(self).__name__, args_joined=', '.join(args_formatted)) @@ -464,7 +464,7 @@ def __init__(self, *types): if not types: raise ValueError('Must supply at least one type') if any(not isinstance(t, type) for t in types): - raise TypeError('Supplied types must be types. {!r}'.format(types)) + raise TypeError(f'Supplied types must be types. {types!r}') if len(types) == 1: type_list = types[0].__name__ diff --git a/src/python/pants/util/retry.py b/src/python/pants/util/retry.py index fdf515ad80a..9a945f1d8b1 100644 --- a/src/python/pants/util/retry.py +++ b/src/python/pants/util/retry.py @@ -25,6 +25,6 @@ def retry_on_exception(func, max_retries, exception_types, backoff_func=lambda n try: return func() except exception_types as e: - logger.debug('encountered exception on retry #{}: {!r}'.format(i, e)) + logger.debug(f'encountered exception on retry #{i}: {e!r}') if i == max_retries - 1: raise diff --git a/src/python/pants/util/s3_log_aggregator.py b/src/python/pants/util/s3_log_aggregator.py index b6f3ffe2ca9..f2af6a5b8c6 100644 --- a/src/python/pants/util/s3_log_aggregator.py +++ b/src/python/pants/util/s3_log_aggregator.py @@ -22,7 +22,7 @@ def __iadd__(self, other): return self -class S3LogAccumulator(object): +class S3LogAccumulator: """Aggregates total downloaded bytes per file from S3 logs. Helps us track which binaries our S3 bandwidth costs are being spent on. @@ -88,9 +88,9 @@ def _get(measures_map, sort_key): def _prettyprint_bytes(x): for unit in ['B', 'KB', 'MB', 'GB']: if abs(x) < 1024.0: - return '{:3.1f}{}'.format(x, unit) + return f'{x:3.1f}{unit}' x /= 1024.0 - return '{:.1f}TB'.format(x) + return f'{x:.1f}TB' diff --git a/src/python/pants/util/tarutil.py b/src/python/pants/util/tarutil.py index f76e8bc9135..81c3d0e88fa 100644 --- a/src/python/pants/util/tarutil.py +++ b/src/python/pants/util/tarutil.py @@ -48,12 +48,12 @@ def next(self): tarinfo = self.tarinfo.fromtarfile(self) except tarfile.EOFHeaderError as e: if self.ignore_zeros: - self._dbg(2, "0x%X: %s" % (self.offset, e)) + self._dbg(2, f"0x{self.offset:X}: {e}") self.offset += tarfile.BLOCKSIZE continue except tarfile.InvalidHeaderError as e: if self.ignore_zeros: - self._dbg(2, "0x%X: %s" % (self.offset, e)) + self._dbg(2, f"0x{self.offset:X}: {e}") self.offset += tarfile.BLOCKSIZE continue # Modify here, to raise exceptions if errorlevel is bigger than 0. diff --git a/src/python/pants/util/xml_parser.py b/src/python/pants/util/xml_parser.py index c6875358b0e..8cc4036db24 100644 --- a/src/python/pants/util/xml_parser.py +++ b/src/python/pants/util/xml_parser.py @@ -21,7 +21,7 @@ def _parse(cls, xml_path): parsed_xml = parse(xml_path) # Minidom is a frontend for various parsers, only Exception covers ill-formed .xml for them all. except Exception as e: - raise cls.XmlError('Error parsing xml file at {0}: {1}'.format(xml_path, e)) + raise cls.XmlError(f'Error parsing xml file at {xml_path}: {e!r}') return parsed_xml @classmethod @@ -30,7 +30,7 @@ def from_file(cls, xml_path): try: parsed_xml = cls._parse(xml_path) except OSError as e: - raise XmlParser.XmlError("Problem reading xml file at {}: {}".format(xml_path, e)) + raise XmlParser.XmlError(f"Problem reading xml file at {xml_path}: {e!r}") return cls(xml_path, parsed_xml) def __init__(self, xml_path, parsed_xml): @@ -52,12 +52,10 @@ def get_attribute(self, element, attribute): """ parsed_element = self.parsed.getElementsByTagName(element) if not parsed_element: - raise self.XmlError("There is no '{0}' element in " - "xml file at: {1}".format(element, self.xml_path)) + raise self.XmlError(f"There is no '{element}' element in xml file at: {self.xml_path}") parsed_attribute = parsed_element[0].getAttribute(attribute) if not parsed_attribute: - raise self.XmlError("There is no '{0}' attribute in " - "xml at: {1}".format(attribute, self.xml_path)) + raise self.XmlError(f"There is no '{attribute}' attribute in xml at: {self.xml_path}") return parsed_attribute def get_optional_attribute(self, element, attribute):