diff --git a/glom/cli.py b/glom/cli.py index 4aa2bc3..7e87e85 100644 --- a/glom/cli.py +++ b/glom/cli.py @@ -64,7 +64,7 @@ def glom_cli(target, spec, indent, debug, inspect): try: result = glom.glom(target, spec) except GlomError as ge: - print('{}: {}'.format(ge.__class__.__name__, ge)) + print(f'{ge.__class__.__name__}: {ge}') return 1 if not indent: @@ -172,7 +172,7 @@ def mw_get_target(next_, posargs_, target_file, target_format, spec_file, spec_f with open(spec_file) as f: spec_text = f.read() except OSError as ose: - raise UsageError('could not read spec file {!r}, got: {}'.format(spec_file, ose)) + raise UsageError(f'could not read spec file {spec_file!r}, got: {ose}') if not spec_text: spec = Path() @@ -196,7 +196,7 @@ def mw_get_target(next_, posargs_, target_file, target_format, spec_file, spec_f try: target_text = open(target_file).read() except OSError as ose: - raise UsageError('could not read target file {!r}, got: {}'.format(target_file, ose)) + raise UsageError(f'could not read target file {target_file!r}, got: {ose}') elif not target_text and not isatty(sys.stdin): target_text = sys.stdin.read() @@ -217,7 +217,7 @@ def _from_glom_import_star(): def _eval_python_full_spec(py_text): name = '__cli_glom_spec__' - code_str = '{} = {}'.format(name, py_text) + code_str = f'{name} = {py_text}' env = _from_glom_import_star() spec = _compile_code(code_str, name=name, env=env) return spec diff --git a/glom/core.py b/glom/core.py index 3b023a7..e9b7446 100644 --- a/glom/core.py +++ b/glom/core.py @@ -232,7 +232,7 @@ def _format_trace_value(value, maxlen): s = bbrepr(value).replace("\\'", "'") if len(s) > maxlen: try: - suffix = '... (len=%s)' % len(value) + suffix = f'... (len={len(value)})' except Exception: suffix = '...' s = s[:maxlen - len(suffix)] + suffix @@ -351,7 +351,7 @@ def get_message(self): def __repr__(self): cn = self.__class__.__name__ - return '{}({!r}, {!r}, {!r})'.format(cn, self.exc, self.path, self.part_idx) + return f'{cn}({self.exc!r}, {self.path!r}, {self.part_idx!r})' class PathAssignError(GlomError): @@ -381,7 +381,7 @@ def get_message(self): def __repr__(self): cn = self.__class__.__name__ - return '{}({!r}, {!r}, {!r})'.format(cn, self.exc, self.path, self.dest_name) + return f'{cn}({self.exc!r}, {self.path!r}, {self.dest_name!r})' class CoalesceError(GlomError): @@ -422,22 +422,22 @@ def __init__(self, coal_obj, skipped, path): def __repr__(self): cn = self.__class__.__name__ - return '{}({!r}, {!r}, {!r})'.format(cn, self.coal_obj, self.skipped, self.path) + return f'{cn}({self.coal_obj!r}, {self.skipped!r}, {self.path!r})' def get_message(self): missed_specs = tuple(self.coal_obj.subspecs) skipped_vals = [v.__class__.__name__ if isinstance(v, self.coal_obj.skip_exc) - else '' % v.__class__.__name__ + else f'' for v in self.skipped] msg = ('no valid values found. Tried %r and got (%s)' % (missed_specs, ', '.join(skipped_vals))) if self.coal_obj.skip is not _MISSING: - msg += ', skip set to {!r}'.format(self.coal_obj.skip) + msg += f', skip set to {self.coal_obj.skip!r}' if self.coal_obj.skip_exc is not GlomError: - msg += ', skip_exc set to {!r}'.format(self.coal_obj.skip_exc) + msg += f', skip_exc set to {self.coal_obj.skip_exc!r}' if self.path is not None: - msg += ' (at path {!r})'.format(self.path) + msg += f' (at path {self.path!r})' return msg @@ -488,11 +488,11 @@ def get_message(self): return ("glom() called without registering any types for operation '%s'. see" " glom.register() or Glommer's constructor for details." % (self.op,)) reg_types = sorted([t.__name__ for t, h in self.type_map.items() if h]) - reg_types_str = '()' if not reg_types else ('(%s)' % ', '.join(reg_types)) + reg_types_str = '()' if not reg_types else (f"({', '.join(reg_types)})") msg = ("target type %r not registered for '%s', expected one of" " registered types: %s" % (self.target_type.__name__, self.op, reg_types_str)) if self.path: - msg += ' (at {!r})'.format(self.path) + msg += f' (at {self.path!r})' return msg @@ -557,21 +557,21 @@ def format_invocation(name='', args=(), kwargs=None, **kw): """ _repr = kw.pop('repr', bbrepr) if kw: - raise TypeError('unexpected keyword args: %r' % ', '.join(kw.keys())) + raise TypeError(f"unexpected keyword args: {', '.join(kw.keys())!r}") kwargs = kwargs or {} a_text = ', '.join([_repr(a) for a in args]) if isinstance(kwargs, dict): kwarg_items = [(k, kwargs[k]) for k in sorted(kwargs)] else: kwarg_items = kwargs - kw_text = ', '.join(['{}={}'.format(k, _repr(v)) for k, v in kwarg_items]) + kw_text = ', '.join([f'{k}={_repr(v)}' for k, v in kwarg_items]) all_args_text = a_text if all_args_text and kw_text: all_args_text += ', ' all_args_text += kw_text - return '{}({})'.format(name, all_args_text) + return f'{name}({all_args_text})' class Path: @@ -819,8 +819,8 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ if self.scope: - return '{}({}, scope={!r})'.format(cn, bbrepr(self.spec), self.scope) - return '{}({})'.format(cn, bbrepr(self.spec)) + return f'{cn}({bbrepr(self.spec)}, scope={self.scope!r})' + return f'{cn}({bbrepr(self.spec)})' class Coalesce: @@ -914,7 +914,7 @@ def __init__(self, *subspecs, **kwargs): self.skip_func = lambda v: v == self.skip self.skip_exc = kwargs.pop('skip_exc', GlomError) if kwargs: - raise TypeError('unexpected keyword args: {!r}'.format(sorted(kwargs.keys()))) + raise TypeError(f'unexpected keyword args: {sorted(kwargs.keys())!r}') def glomit(self, target, scope): skipped = [] @@ -996,13 +996,13 @@ def __init__(self, *a, **kw): if breakpoint is True: breakpoint = pdb.set_trace if breakpoint and not callable(breakpoint): - raise TypeError('breakpoint expected bool or callable, not: %r' % breakpoint) + raise TypeError(f'breakpoint expected bool or callable, not: {breakpoint!r}') self.breakpoint = breakpoint post_mortem = kw.pop('post_mortem', False) if post_mortem is True: post_mortem = pdb.post_mortem if post_mortem and not callable(post_mortem): - raise TypeError('post_mortem expected bool or callable, not: %r' % post_mortem) + raise TypeError(f'post_mortem expected bool or callable, not: {post_mortem!r}') self.post_mortem = post_mortem def __repr__(self): @@ -1096,7 +1096,7 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ - return '{}({}, args={!r}, kwargs={!r})'.format(cn, bbrepr(self.func), self.args, self.kwargs) + return f'{cn}({bbrepr(self.func)}, args={self.args!r}, kwargs={self.kwargs!r})' def _is_spec(obj, strict=False): @@ -1439,7 +1439,7 @@ def __getitem__(self, item): def __call__(self, *args, **kwargs): if self is S: if args: - raise TypeError('S() takes no positional arguments, got: {!r}'.format(args)) + raise TypeError(f'S() takes no positional arguments, got: {args!r}') if not kwargs: raise TypeError('S() expected at least one kwarg, got none') # TODO: typecheck kwarg vals? @@ -1733,7 +1733,7 @@ def _format_t(path, root=T): index = ", ".join([_format_slice(x) for x in arg]) else: index = _format_slice(arg) - prepr.append("[{}]".format(index)) + prepr.append(f"[{index}]") elif op == '(': args, kwargs = arg prepr.append(format_invocation(args=args, kwargs=kwargs, repr=bbrepr)) @@ -1788,7 +1788,7 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ - return '{}({})'.format(cn, bbrepr(self.value)) + return f'{cn}({bbrepr(self.value)})' Literal = Val # backwards compat for pre-20.7.0 @@ -1812,7 +1812,7 @@ def __iter__(self): return iter(self.__dict__.items()) def __repr__(self): - return "{}({})".format(self.__class__.__name__, bbrepr(self.__dict__)) + return f"{self.__class__.__name__}({bbrepr(self.__dict__)})" class Vars: @@ -1885,7 +1885,7 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ rpr = '' if self.spec is None else bbrepr(self.spec) - return '{}({})'.format(cn, rpr) + return f'{cn}({rpr})' class _AbstractIterable(_AbstractIterableBase): @@ -2093,7 +2093,7 @@ def _register_fuzzy_type(self, op, new_type, _type_tree=None): def register(self, target_type, **kwargs): if not isinstance(target_type, type): - raise TypeError('register expected a type, not an instance: {!r}'.format(target_type)) + raise TypeError(f'register expected a type, not an instance: {target_type!r}') exact = kwargs.pop('exact', None) new_op_map = dict(kwargs) @@ -2139,11 +2139,11 @@ def register_op(self, op_name, auto_func=None, exact=False): extensions. """ if not isinstance(op_name, basestring): - raise TypeError('expected op_name to be a text name, not: {!r}'.format(op_name)) + raise TypeError(f'expected op_name to be a text name, not: {op_name!r}') if auto_func is None: auto_func = lambda t: False elif not callable(auto_func): - raise TypeError('expected auto_func to be callable, not: {!r}'.format(auto_func)) + raise TypeError(f'expected auto_func to be callable, not: {auto_func!r}') # determine support for any previously known types known_types = set(sum([list(m.keys()) for m @@ -2268,7 +2268,7 @@ def glom(target, spec, **kwargs): scope.update(kwargs.pop('scope', {})) err = None if kwargs: - raise TypeError('unexpected keyword args: %r' % sorted(kwargs.keys())) + raise TypeError(f'unexpected keyword args: {sorted(kwargs.keys())!r}') try: try: ret = _glom(target, spec, scope) @@ -2537,7 +2537,7 @@ def fill(self, target): def __repr__(self): cn = self.__class__.__name__ rpr = '' if self.spec is None else bbrepr(self.spec) - return '{}({})'.format(cn, rpr) + return f'{cn}({rpr})' def FILL(target, spec, scope): diff --git a/glom/grouping.py b/glom/grouping.py index dba3d5b..12c2146 100644 --- a/glom/grouping.py +++ b/glom/grouping.py @@ -92,7 +92,7 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ - return '{}({!r})'.format(cn, self.spec) + return f'{cn}({self.spec!r})' def GROUP(target, spec, scope): @@ -171,7 +171,7 @@ def agg(self, target, tree): return STOP def __repr__(self): - return '%s()' % self.__class__.__name__ + return f'{self.__class__.__name__}()' class Avg: @@ -195,7 +195,7 @@ def agg(self, target, tree): return avg_acc[0] / avg_acc[1] def __repr__(self): - return '%s()' % self.__class__.__name__ + return f'{self.__class__.__name__}()' class Max: @@ -214,7 +214,7 @@ def agg(self, target, tree): return tree[self] def __repr__(self): - return '%s()' % self.__class__.__name__ + return f'{self.__class__.__name__}()' class Min: @@ -233,7 +233,7 @@ def agg(self, target, tree): return tree[self] def __repr__(self): - return '%s()' % self.__class__.__name__ + return f'{self.__class__.__name__}()' class Sample: @@ -270,7 +270,7 @@ def agg(self, target, tree): return sample def __repr__(self): - return '{}({!r})'.format(self.__class__.__name__, self.size) + return f'{self.__class__.__name__}({self.size!r})' @@ -313,4 +313,4 @@ def glomit(self, target, scope): return scope[glom](target, self.subspec, scope) def __repr__(self): - return '{}({!r}, {!r})'.format(self.__class__.__name__, self.n, self.subspec) + return f'{self.__class__.__name__}({self.n!r}, {self.subspec!r})' diff --git a/glom/matching.py b/glom/matching.py index ea9eb83..4c44f18 100644 --- a/glom/matching.py +++ b/glom/matching.py @@ -186,7 +186,7 @@ def matches(self, target): return True def __repr__(self): - return '{}({})'.format(self.__class__.__name__, bbrepr(self.spec)) + return f'{self.__class__.__name__}({bbrepr(self.spec)})' _RE_FULLMATCH = getattr(re, "fullmatch", None) @@ -264,11 +264,10 @@ class _Bool: def __init__(self, *children, **kw): self.children = children if not children: - raise ValueError("need at least one operand for {}".format( - self.__class__.__name__)) + raise ValueError(f"need at least one operand for {self.__class__.__name__}") self.default = kw.pop('default', _MISSING) if kw: - raise TypeError('got unexpected kwargs: %r' % list(kw.keys())) + raise TypeError(f'got unexpected kwargs: {list(kw.keys())!r}') def __and__(self, other): return And(self, other) @@ -412,7 +411,7 @@ def __le__(self, other): return _MExpr(self, 'l', other) def __repr__(self): - return 'M({})'.format(bbrepr(self.spec)) + return f'M({bbrepr(self.spec)})' def glomit(self, target, scope): match = scope[glom](target, self.spec, scope) @@ -523,7 +522,7 @@ def __call__(self, spec): if not isinstance(spec, type(T)): # TODO: open this up for other specs so we can do other # checks, like function calls - raise TypeError("M() only accepts T-style specs, not %s" % type(spec).__name__) + raise TypeError(f"M() only accepts T-style specs, not {type(spec).__name__}") return _MSubspec(spec) def __eq__(self, other): @@ -602,7 +601,7 @@ def glomit(self, target, scope): return target def __repr__(self): - return '{}({})'.format(self.__class__.__name__, bbrepr(self.key)) + return f'{self.__class__.__name__}({bbrepr(self.key)})' class Required: @@ -651,7 +650,7 @@ def __init__(self, key): self.key = key def __repr__(self): - return '{}({})'.format(self.__class__.__name__, bbrepr(self.key)) + return f'{self.__class__.__name__}({bbrepr(self.key)})' def _precedence(match): @@ -854,10 +853,10 @@ def glomit(self, target, scope): return scope[glom](target, valspec, chain_child(scope)) if self.default is not _MISSING: return arg_val(target, self.default, scope) - raise MatchError("no matches for target in %s" % self.__class__.__name__) + raise MatchError(f"no matches for target in {self.__class__.__name__}") def __repr__(self): - return '{}({})'.format(self.__class__.__name__, bbrepr(self.cases)) + return f'{self.__class__.__name__}({bbrepr(self.cases)})' RAISE = make_sentinel('RAISE') # flag object for "raise on check failure" @@ -926,7 +925,7 @@ def truthy(val): equal_to = kwargs.pop('equal_to', _MISSING) one_of = kwargs.pop('one_of', _MISSING) if kwargs: - raise TypeError('unexpected keyword arguments: %r' % kwargs.keys()) + raise TypeError(f'unexpected keyword arguments: {kwargs.keys()!r}') self.validators = _get_arg_val('validate', 'callable', callable, validate) self.instance_of = _get_arg_val('instance_of', 'a type', @@ -984,12 +983,12 @@ def glomit(self, target, scope): raise self._ValidationError except Exception as e: msg = ('expected %r check to validate target' - % getattr(validator, '__name__', None) or ('#%s' % i)) + % getattr(validator, '__name__', None) or (f'#{i}')) if type(e) is self._ValidationError: if self.default is not RAISE: return self.default else: - msg += ' (got exception: %r)' % e + msg += f' (got exception: {e!r})' errs.append(msg) if self.instance_of and not isinstance(target, self.instance_of): @@ -1040,15 +1039,15 @@ def __init__(self, msgs, check, path): self.path = path def get_message(self): - msg = 'target at path %s failed check,' % self.path + msg = f'target at path {self.path} failed check,' if self.check_obj.spec is not T: - msg += ' subtarget at {!r}'.format(self.check_obj.spec) + msg += f' subtarget at {self.check_obj.spec!r}' if len(self.msgs) == 1: - msg += ' got error: {!r}'.format(self.msgs[0]) + msg += f' got error: {self.msgs[0]!r}' else: - msg += ' got {} errors: {!r}'.format(len(self.msgs), self.msgs) + msg += f' got {len(self.msgs)} errors: {self.msgs!r}' return msg def __repr__(self): cn = self.__class__.__name__ - return '{}({!r}, {!r}, {!r})'.format(cn, self.msgs, self.check_obj, self.path) + return f'{cn}({self.msgs!r}, {self.check_obj!r}, {self.path!r})' diff --git a/glom/mutation.py b/glom/mutation.py index ee27888..c3fc322 100644 --- a/glom/mutation.py +++ b/glom/mutation.py @@ -146,7 +146,7 @@ def __init__(self, path, val, missing=None): if missing is not None: if not callable(missing): - raise TypeError('expected missing to be callable, not {!r}'.format(missing)) + raise TypeError(f'expected missing to be callable, not {missing!r}') self.missing = missing def glomit(self, target, scope): @@ -182,8 +182,8 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ if self.missing is None: - return '{}({!r}, {!r})'.format(cn, self._orig_path, self.val) - return '{}({!r}, {!r}, missing={})'.format(cn, self._orig_path, self.val, bbrepr(self.missing)) + return f'{cn}({self._orig_path!r}, {self.val!r})' + return f'{cn}({self._orig_path!r}, {self.val!r}, missing={bbrepr(self.missing)})' def assign(obj, path, val, missing=None): @@ -320,7 +320,7 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ - return '{}({!r})'.format(cn, self._orig_path) + return f'{cn}({self._orig_path!r})' def delete(obj, path, ignore_missing=False): diff --git a/glom/reduction.py b/glom/reduction.py index b400ce0..ca0d3bd 100644 --- a/glom/reduction.py +++ b/glom/reduction.py @@ -146,7 +146,7 @@ def __init__(self): subspec=T, init=int, op=lambda cur, val: cur + 1) def __repr__(self): - return '%s()' % self.__class__.__name__ + return f'{self.__class__.__name__}()' class Flatten(Fold): @@ -250,12 +250,12 @@ def flatten(target, **kwargs): init = kwargs.pop('init', list) levels = kwargs.pop('levels', 1) if kwargs: - raise TypeError('unexpected keyword args: %r' % sorted(kwargs.keys())) + raise TypeError(f'unexpected keyword args: {sorted(kwargs.keys())!r}') if levels == 0: return target if levels < 0: - raise ValueError('expected levels >= 0, not %r' % levels) + raise ValueError(f'expected levels >= 0, not {levels!r}') spec = (subspec,) spec += (Flatten(init="lazy"),) * (levels - 1) spec += (Flatten(init=init),) @@ -343,6 +343,6 @@ def merge(target, **kwargs): init = kwargs.pop('init', dict) op = kwargs.pop('op', None) if kwargs: - raise TypeError('unexpected keyword args: %r' % sorted(kwargs.keys())) + raise TypeError(f'unexpected keyword args: {sorted(kwargs.keys())!r}') spec = Merge(subspec, init, op) return glom(target, spec) diff --git a/glom/streaming.py b/glom/streaming.py index c2a6145..e446641 100644 --- a/glom/streaming.py +++ b/glom/streaming.py @@ -61,7 +61,7 @@ def __init__(self, subspec=T, **kwargs): self.sentinel = kwargs.pop('sentinel', STOP) if kwargs: - raise TypeError('unexpected keyword arguments: %r' % sorted(kwargs)) + raise TypeError(f'unexpected keyword arguments: {sorted(kwargs)!r}') return def __repr__(self): @@ -275,7 +275,7 @@ def slice(self, *args): try: islice([], *args) except TypeError: - raise TypeError('invalid slice arguments: {!r}'.format(args)) + raise TypeError(f'invalid slice arguments: {args!r}') return self._add_op('slice', args, lambda it, scope: islice(it, *args)) def limit(self, count): @@ -381,5 +381,5 @@ def glomit(self, target, scope): def __repr__(self): cn = self.__class__.__name__ if self._default is None: - return '{}({})'.format(cn, bbrepr(self._spec)) - return '{}({}, default={})'.format(cn, bbrepr(self._spec), bbrepr(self._default)) + return f'{cn}({bbrepr(self._spec)})' + return f'{cn}({bbrepr(self._spec)}, default={bbrepr(self._default)})' diff --git a/glom/test/test_error.py b/glom/test/test_error.py index 8149f3e..f232193 100644 --- a/glom/test/test_error.py +++ b/glom/test/test_error.py @@ -96,11 +96,11 @@ def _debug_some_str(value, *a, **kw): return str(value) except BaseException as be: # pragma: no cover try: - print(' !! failed to stringify {} object, got {}'.format(type(value).__name__, be)) + print(f' !! failed to stringify {type(value).__name__} object, got {be}') traceback.print_exc() except: print(' !! unable to print trace') - return ''.format(type(value).__name__, be) + return f'' traceback._some_str = _debug_some_str @@ -231,7 +231,7 @@ def test_long_target_repr(): class ObjectWithLongRepr: def __repr__(self): - return '<{} {}>'.format(self.__class__.__name__, 'w' + ('ooooo' * 250)) + return f"<{self.__class__.__name__} {'w' + 'ooooo' * 250}>" actual = _make_stack(target=ObjectWithLongRepr(), spec='badattr') assert '...' in actual diff --git a/glom/test/test_mutation.py b/glom/test/test_mutation.py index ec86b39..3291651 100644 --- a/glom/test/test_mutation.py +++ b/glom/test/test_mutation.py @@ -101,7 +101,7 @@ def test_sequence_assign(): def test_invalid_assign_op_target(): - target = {'afunc': lambda x: 'hi %s' % x} + target = {'afunc': lambda x: f'hi {x}'} spec = T['afunc'](x=1) with pytest.raises(ValueError): @@ -304,7 +304,7 @@ def test_sequence_delete(): def test_invalid_delete_op_target(): - target = {'afunc': lambda x: 'hi %s' % x} + target = {'afunc': lambda x: f'hi {x}'} spec = T['afunc'](x=1) with pytest.raises(ValueError):