From c2d25ac2519fa4edb21f2c8e155495963ad8a27d Mon Sep 17 00:00:00 2001 From: Noorhteen Raja NJ Date: Tue, 7 Dec 2021 01:12:26 +0530 Subject: [PATCH] pre-commit hook for pyupgrade (#4583) * chore: add pyupgrade * refactor: upgrade code to py3.7+ ran `pre-commit run pyupgrade -a` while excluding changes to ply * fix: flake errors --- .pre-commit-config.yaml | 6 ++ amalgamate.py | 14 ++--- docs/conf.py | 11 ++-- setup.py | 21 +++---- tests/prompt/test_vc.py | 4 +- tests/test_aliases.py | 2 - tests/test_base_shell.py | 1 - tests/test_dirstack.py | 4 +- tests/test_dirstack_unc.py | 3 +- tests/test_environ.py | 2 - tests/test_execer.py | 1 - tests/test_foreign_shells.py | 4 +- tests/test_history_dummy.py | 1 - tests/test_history_json.py | 8 +-- tests/test_history_sqlite.py | 6 +- tests/test_imphooks.py | 3 +- tests/test_integrations.py | 2 +- tests/test_jsonutils.py | 1 - tests/test_lazyjson.py | 2 - tests/test_lexer.py | 12 ++-- tests/test_main.py | 2 - tests/test_man.py | 1 - tests/test_news.py | 7 +-- tests/test_parser.py | 83 ++++++++++---------------- tests/test_ptk_highlight.py | 19 +++--- tests/test_ptk_multiline.py | 1 - tests/test_ptk_shell.py | 1 - tests/test_shell.py | 1 - tests/test_tools.py | 91 ++++++++++++++--------------- tests/test_tracer.py | 2 +- tests/test_wizard.py | 4 +- tests/test_xonfig.py | 5 +- tests/tools.py | 14 ++--- xonsh/aliases.py | 15 +++-- xonsh/ansi_colors.py | 8 +-- xonsh/ast.py | 7 +-- xonsh/base_shell.py | 3 +- xonsh/built_ins.py | 5 +- xonsh/codecache.py | 4 +- xonsh/color_tools.py | 4 +- xonsh/commands_cache.py | 1 - xonsh/completer.py | 3 +- xonsh/completers/bash_completion.py | 6 +- xonsh/completers/python.py | 2 +- xonsh/contexts.py | 4 +- xonsh/diff_history.py | 11 ++-- xonsh/dirstack.py | 15 +++-- xonsh/environ.py | 25 ++++---- xonsh/execer.py | 3 +- xonsh/foreign_shells.py | 7 +-- xonsh/history/base.py | 1 - xonsh/history/dummy.py | 1 - xonsh/history/json.py | 13 ++--- xonsh/history/main.py | 13 ++--- xonsh/history/sqlite.py | 5 +- xonsh/imphooks.py | 5 +- xonsh/inspectors.py | 8 +-- xonsh/jobs.py | 11 ++-- xonsh/jupyter_kernel.py | 17 +++--- xonsh/lazyasd.py | 4 +- xonsh/lazyjson.py | 3 +- xonsh/lexer.py | 7 +-- xonsh/lib/collections.py | 4 +- xonsh/main.py | 7 +-- xonsh/openpy.py | 6 +- xonsh/parser.py | 1 - xonsh/parsers/base.py | 23 ++++---- xonsh/parsers/completion_context.py | 2 +- xonsh/parsers/context_check.py | 6 +- xonsh/parsers/fstring_adaptor.py | 1 - xonsh/parsers/v36.py | 1 - xonsh/parsers/v38.py | 1 - xonsh/parsers/v39.py | 2 +- xonsh/platform.py | 4 +- xonsh/pretty.py | 9 ++- xonsh/procs/posix.py | 4 +- xonsh/procs/proxies.py | 20 +++---- xonsh/procs/specs.py | 12 ++-- xonsh/prompt/base.py | 5 +- xonsh/prompt/cwd.py | 1 - xonsh/prompt/env.py | 1 - xonsh/prompt/gitstatus.py | 5 +- xonsh/prompt/job.py | 1 - xonsh/prompt/times.py | 1 - xonsh/prompt/vc.py | 3 +- xonsh/ptk_shell/completer.py | 1 - xonsh/ptk_shell/history.py | 1 - xonsh/ptk_shell/key_bindings.py | 1 - xonsh/ptk_shell/shell.py | 1 - xonsh/pyghooks.py | 7 +-- xonsh/pygments_cache.py | 2 +- xonsh/pytest_plugin.py | 5 +- xonsh/readline_shell.py | 7 +-- xonsh/shell.py | 5 +- xonsh/timings.py | 13 ++--- xonsh/tokenize.py | 14 ++--- xonsh/tools.py | 49 +++++++--------- xonsh/tracer.py | 4 +- xonsh/webconfig/main.py | 11 ++-- xonsh/wizard.py | 52 ++++++++--------- xonsh/xonfig.py | 16 ++--- xonsh/xontribs.py | 4 +- xonsh/xoreutils/ulimit.py | 4 +- xonsh/xoreutils/umask.py | 3 +- xonsh/xoreutils/which.py | 4 +- xontrib/bashisms.py | 12 ++-- xontrib/jedi.py | 2 +- xontrib/prompt_ret_code.py | 2 +- xontrib/vox.py | 4 +- 109 files changed, 381 insertions(+), 513 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c9da75218..7db173427 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,3 +32,9 @@ repos: - id: debug-statements - id: check-added-large-files + + - repo: https://github.com/asottile/pyupgrade + rev: v2.29.1 + hooks: + - id: pyupgrade + args: [--py37-plus] diff --git a/amalgamate.py b/amalgamate.py index c710692be..2f2a55869 100755 --- a/amalgamate.py +++ b/amalgamate.py @@ -54,7 +54,7 @@ class SourceCache(Mapping): SOURCES = SourceCache() -class GlobalNames(object): +class GlobalNames: """Stores globally defined names that have been seen on ast nodes.""" impnodes = frozenset(["import", "importfrom"]) @@ -74,7 +74,7 @@ class GlobalNames(object): val = sorted(val) if all([val[0][0] == x[0] for x in val[1:]]): continue - s += "WARNING: {0!r} defined in multiple locations:\n".format(key) + s += f"WARNING: {key!r} defined in multiple locations:\n" for loc in val: s += " {}:{} ({})\n".format(*loc) if len(s) > 0: @@ -92,7 +92,7 @@ class GlobalNames(object): return self.cache[name].add(e) else: - self.cache[name] = set([e]) + self.cache[name] = {e} def add(self, node, istopnode=False): """Adds the names from the node to the cache.""" @@ -266,7 +266,7 @@ def depsort(graph): nodeps = {m for m in remaining if len(graph[m].pkgdeps - solved) == 0} if len(nodeps) == 0: msg = ( - "\nsolved order = {0}\nremaining = {1}\nCycle detected in " + "\nsolved order = {}\nremaining = {}\nCycle detected in " "module graph!" ).format(pprint.pformat(seder), pprint.pformat(remaining)) raise RuntimeError(msg) @@ -457,7 +457,7 @@ def sorted_futures(graph): def amalgamate(order, graph, pkg): """Create amalgamated source.""" src = ( - '"""Amalgamation of {0} package, made up of the following ' + '"""Amalgamation of {} package, made up of the following ' "modules, in order:\n\n* " ).format(pkg) src += "\n* ".join(order) @@ -552,13 +552,13 @@ def main(args=None): continue print("Amalgamating " + pkg) exclude = read_exclude(pkg) - print(" excluding {}".format(pprint.pformat(exclude or None))) + print(f" excluding {pprint.pformat(exclude or None)}") graph = make_graph(pkg, exclude=exclude) order = depsort(graph) src = amalgamate(order, graph, pkg) write_amalgam(src, pkg) rewrite_init(pkg, order, debug=debug) - print(" collapsed {} modules".format(len(order))) + print(f" collapsed {len(order)} modules") if __name__ == "__main__": diff --git a/docs/conf.py b/docs/conf.py index 5bbf6757f..5ae987d76 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # This file is execfile()d with the current directory set to its containing dir. # @@ -78,8 +77,8 @@ source_suffix = ".rst" master_doc = "contents" # General information about the project. -project = u"xonsh" -copyright = u"2015, Anthony Scopatz" +project = "xonsh" +copyright = "2015, Anthony Scopatz" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -251,7 +250,7 @@ htmlhelp_basename = "xonshdoc" # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ("index", "xonsh.tex", u"xonsh documentation", u"Anthony Scopatz", "manual") + ("index", "xonsh.tex", "xonsh documentation", "Anthony Scopatz", "manual") ] # The name of an image file (relative to this directory) to place at the top of @@ -376,7 +375,7 @@ def make_xontribs(): else: pkg = d.package.name if d.package.url: - pkg = "`{0} website <{1}>`_".format(pkg, d.package.url) + pkg = f"`{pkg} website <{d.package.url}>`_" if d.package.license: pkg = pkg + ", " + d.package.license inst = "" @@ -397,7 +396,7 @@ def make_xontribs(): "on startup.)\n\n" ".. code-block:: xonsh\n\n" ) - usage += " xontrib load {}\n\n".format(name) + usage += f" xontrib load {name}\n\n" s += sec.format( low=name.lower(), title=title, diff --git a/setup.py b/setup.py index 2ab97f39f..cadf2c0d2 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: ascii -*- """The xonsh installer.""" # Note: Do not embed any non-ASCII characters in this file until pip has been # fixed. See https://github.com/xonsh/xonsh/issues/487. @@ -111,7 +110,7 @@ def dirty_version(): _date = "" print("failed to get commit date", file=sys.stderr) with open("xonsh/dev.githash", "w") as f: - f.write("{}|{}".format(sha, _date)) + f.write(f"{sha}|{_date}") print("wrote git version: " + sha, file=sys.stderr) return True @@ -122,13 +121,13 @@ ORIGINAL_VERSION_LINE = None def replace_version(N): """Replace version in `__init__.py` with devN suffix""" global ORIGINAL_VERSION_LINE - with open("xonsh/__init__.py", "r") as f: + with open("xonsh/__init__.py") as f: raw = f.read() lines = raw.splitlines() msg_assert = "__version__ must be the first line of the __init__.py" assert "__version__" in lines[0], msg_assert ORIGINAL_VERSION_LINE = lines[0] - lines[0] = lines[0].rstrip(' "') + '.dev{}"'.format(N) + lines[0] = lines[0].rstrip(' "') + f'.dev{N}"' upd = "\n".join(lines) + "\n" with open("xonsh/__init__.py", "w") as f: f.write(upd) @@ -138,7 +137,7 @@ def restore_version(): """If we touch the version in __init__.py discard changes after install.""" if ORIGINAL_VERSION_LINE is None: return - with open("xonsh/__init__.py", "r") as f: + with open("xonsh/__init__.py") as f: raw = f.read() lines = raw.splitlines() lines[0] = ORIGINAL_VERSION_LINE @@ -225,12 +224,10 @@ class install_scripts_rewrite(install_scripts): bs_cmd = self.get_finalized_command("build_scripts") exec_param = getattr(bs_cmd, "executable", None) - with open(file, "r") as f: + with open(file) as f: content = f.read() - processed = content.replace( - " python3 ", ' "{}" '.format(exec_param) - ) + processed = content.replace(" python3 ", f' "{exec_param}" ') with open(file, "w") as f: f.write(processed) @@ -262,9 +259,7 @@ class xdevelop(develop): def install_script(self, dist, script_name, script_text, dev_path=None): if script_name == "xon.sh": # change default python3 to the concrete python binary used to install/develop inside xon.sh script - script_text = script_text.replace( - " python3 ", ' "{}" '.format(sys.executable) - ) + script_text = script_text.replace(" python3 ", f' "{sys.executable}" ') super().install_script(dist, script_name, script_text, dev_path) @@ -278,7 +273,7 @@ def main(): print(logo) except UnicodeEncodeError: pass - with open(os.path.join(os.path.dirname(__file__), "README.rst"), "r") as f: + with open(os.path.join(os.path.dirname(__file__), "README.rst")) as f: readme = f.read() scripts = ["scripts/xon.sh"] skw = dict( diff --git a/tests/prompt/test_vc.py b/tests/prompt/test_vc.py index b5403af00..b5c5bed32 100644 --- a/tests/prompt/test_vc.py +++ b/tests/prompt/test_vc.py @@ -23,7 +23,7 @@ def repo(request, tmpdir_factory): try: sp.call([vc, "init"]) except FileNotFoundError: - pytest.skip("cannot find {} executable".format(vc)) + pytest.skip(f"cannot find {vc} executable") if vc == "git": git_config = temp_dir / ".git/config" git_config.write_text( @@ -88,7 +88,7 @@ current = yellow reverse branch = getattr(vc, get_branch)() assert branch in VC_BRANCH[repo["vc"]] - assert not branch.startswith(u"\u001b[") + assert not branch.startswith("\u001b[") def test_current_branch_calls_locate_binary_for_empty_cmds_cache(xession, monkeypatch): diff --git a/tests/test_aliases.py b/tests/test_aliases.py index 4bd7db0b1..28a779cd1 100644 --- a/tests/test_aliases.py +++ b/tests/test_aliases.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Testing built_ins.Aliases""" -from __future__ import unicode_literals, print_function import os diff --git a/tests/test_base_shell.py b/tests/test_base_shell.py index 7c67a5601..80bdc9b3f 100644 --- a/tests/test_base_shell.py +++ b/tests/test_base_shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """(A down payment on) Testing for ``xonsh.base_shell.BaseShell`` and associated classes""" import os diff --git a/tests/test_dirstack.py b/tests/test_dirstack.py index e6a2f490f..e19816c43 100644 --- a/tests/test_dirstack.py +++ b/tests/test_dirstack.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Testing dirstack""" -from __future__ import unicode_literals, print_function from contextlib import contextmanager import os @@ -62,7 +60,7 @@ def test_cdpath_expansion(xession): os.mkdir(d) assert os.path.exists( dirstack._try_cdpath(d) - ), "dirstack._try_cdpath: could not resolve {0}".format(d) + ), f"dirstack._try_cdpath: could not resolve {d}" finally: for d in test_dirs: if os.path.exists(d): diff --git a/tests/test_dirstack_unc.py b/tests/test_dirstack_unc.py index 25ffa1ac2..64ae519dd 100644 --- a/tests/test_dirstack_unc.py +++ b/tests/test_dirstack_unc.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Testing dirstack""" # from __future__ import unicode_literals, print_function @@ -19,7 +18,7 @@ PARENT = os.path.dirname(HERE) def drive_in_use(letter): - return ON_WINDOWS and os.system("vol {}: 2>nul>nul".format(letter)) == 0 + return ON_WINDOWS and os.system(f"vol {letter}: 2>nul>nul") == 0 MAX_TEMP_DRIVES = 4 diff --git a/tests/test_environ.py b/tests/test_environ.py index 2cc62744f..752a15b1b 100644 --- a/tests/test_environ.py +++ b/tests/test_environ.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Tests the xonsh environment.""" -from __future__ import unicode_literals, print_function import os import re import pathlib diff --git a/tests/test_execer.py b/tests/test_execer.py index 6566f6721..d3db78a9e 100644 --- a/tests/test_execer.py +++ b/tests/test_execer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests the xonsh lexer.""" import os diff --git a/tests/test_foreign_shells.py b/tests/test_foreign_shells.py index d75d5b0e5..91777b2b1 100644 --- a/tests/test_foreign_shells.py +++ b/tests/test_foreign_shells.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Tests foreign shells.""" -from __future__ import unicode_literals, print_function import os import subprocess @@ -89,7 +87,7 @@ def test_foreign_bash_data(): def test_foreign_cmd_data(): env = (("ENV_TO_BE_REMOVED", "test"),) batchfile = os.path.join(os.path.dirname(__file__), "batch.bat") - source_cmd = 'call "{}"\necho off'.format(batchfile) + source_cmd = f'call "{batchfile}"\necho off' try: obsenv, _ = foreign_shell_data( "cmd", diff --git a/tests/test_history_dummy.py b/tests/test_history_dummy.py index d0b1aa6c4..292e3bb93 100644 --- a/tests/test_history_dummy.py +++ b/tests/test_history_dummy.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests the dummy history backend.""" # pylint: disable=protected-access diff --git a/tests/test_history_json.py b/tests/test_history_json.py index 3fb1f9950..537d0066a 100644 --- a/tests/test_history_json.py +++ b/tests/test_history_json.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests the json history backend.""" # pylint: disable=protected-access @@ -170,10 +169,7 @@ def test_show_cmd_numerate(inp, commands, offset, hist, xession, capsys): for ts, cmd in enumerate(CMDS): # populate the shell history hist.append({"inp": cmd, "rtn": 0, "ts": (ts + 1, ts + 1.5)}) - exp = ( - "{}: {}".format(base_idx + idx * step, cmd) - for idx, cmd in enumerate(list(commands)) - ) + exp = (f"{base_idx + idx * step}: {cmd}" for idx, cmd in enumerate(list(commands))) exp = "\n".join(exp) history_main(["show", "-n"] + shlex.split(inp)) @@ -196,7 +192,7 @@ def test_history_diff(tmpdir, xession, monkeypatch, capsys): # make sure that flush is complete time.sleep(0.1) - left, right = [str(f) for f in files] + left, right = (str(f) for f in files) history_main(["diff", left, right]) out, err = capsys.readouterr() # make sure it is called diff --git a/tests/test_history_sqlite.py b/tests/test_history_sqlite.py index a3b0ad797..bae99ca02 100644 --- a/tests/test_history_sqlite.py +++ b/tests/test_history_sqlite.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests the xonsh history.""" # pylint: disable=protected-access import os @@ -81,10 +80,7 @@ def test_show_cmd_numerate(inp, commands, offset, hist, xession, capsys): for ts, cmd in enumerate(CMDS): # populate the shell history hist.append({"inp": cmd, "rtn": 0, "ts": (ts + 1, ts + 1.5)}) - exp = ( - "{}: {}".format(base_idx + idx * step, cmd) - for idx, cmd in enumerate(list(commands)) - ) + exp = (f"{base_idx + idx * step}: {cmd}" for idx, cmd in enumerate(list(commands))) exp = "\n".join(exp) history_main(["show", "-n"] + shlex.split(inp)) diff --git a/tests/test_imphooks.py b/tests/test_imphooks.py index c192767bc..bcbc11bb7 100644 --- a/tests/test_imphooks.py +++ b/tests/test_imphooks.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Testing xonsh import hooks""" import os from importlib import import_module @@ -67,5 +66,5 @@ def test_get_source(): mod = import_module("sample") loader = mod.__loader__ source = loader.get_source("sample") - with open(os.path.join(TEST_DIR, "sample.xsh"), "rt") as srcfile: + with open(os.path.join(TEST_DIR, "sample.xsh")) as srcfile: assert source == srcfile.read() diff --git a/tests/test_integrations.py b/tests/test_integrations.py index 0a4552adf..63f37ed22 100644 --- a/tests/test_integrations.py +++ b/tests/test_integrations.py @@ -701,7 +701,7 @@ def test_subshells(cmd, fmt, exp): @pytest.mark.parametrize("cmd, exp", [("pwd", lambda: os.getcwd() + "\n")]) def test_redirect_out_to_file(cmd, exp, tmpdir): outfile = tmpdir.mkdir("xonsh_test_dir").join("xonsh_test_file") - command = "{} > {}\n".format(cmd, outfile) + command = f"{cmd} > {outfile}\n" out, _, _ = run_xonsh(command) content = outfile.read() if callable(exp): diff --git a/tests/test_jsonutils.py b/tests/test_jsonutils.py index 338920d28..6ac421572 100644 --- a/tests/test_jsonutils.py +++ b/tests/test_jsonutils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Testing xonsh json hooks""" import json diff --git a/tests/test_lazyjson.py b/tests/test_lazyjson.py index ef9e21cc4..c40e10393 100644 --- a/tests/test_lazyjson.py +++ b/tests/test_lazyjson.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Tests lazy json functionality.""" -from __future__ import unicode_literals, print_function from io import StringIO from xonsh.lazyjson import index, ljdump, LazyJSON, LJNode diff --git a/tests/test_lexer.py b/tests/test_lexer.py index e0966b170..e57694b62 100644 --- a/tests/test_lexer.py +++ b/tests/test_lexer.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Tests the xonsh lexer.""" -from __future__ import unicode_literals, print_function import os import sys from collections.abc import Sequence @@ -28,7 +26,7 @@ def ensure_tuple(x): elif isinstance(x, Sequence): x = tuple(x) else: - raise TypeError("{0} is not a sequence".format(x)) + raise TypeError(f"{x} is not a sequence") return x @@ -42,7 +40,7 @@ def tokens_equal(x, y): def assert_token_equal(x, y): """Asserts that two tokens are equal.""" if not tokens_equal(x, y): - msg = "The tokens differ: {0!r} != {1!r}".format(x, y) + msg = f"The tokens differ: {x!r} != {y!r}" pytest.fail(msg) return True @@ -84,7 +82,7 @@ def check_tokens(inp, exp): def check_tokens_subproc(inp, exp, stop=-1): - obs = lex_input("$[{}]".format(inp))[1:stop] + obs = lex_input(f"$[{inp}]")[1:stop] return assert_tokens_equal(exp, obs) @@ -395,7 +393,7 @@ def test_path_fstring_literal(): def test_regex_globs(): for i in (".*", r"\d*", ".*#{1,2}"): for p in ("", "r", "g", "@somethingelse", "p", "pg"): - c = "{}`{}`".format(p, i) + c = f"{p}`{i}`" assert check_token(c, ["SEARCHPATH", c, 0]) @@ -427,7 +425,7 @@ def test_ioredir(case): @pytest.mark.parametrize("case", [">", ">>", "<", "e>", "> ", ">> ", "< ", "e> "]) def test_redir_whitespace(case): - inp = "![{}/path/to/file]".format(case) + inp = f"![{case}/path/to/file]" obs = lex_input(inp) assert obs[2].type == "WS" diff --git a/tests/test_main.py b/tests/test_main.py index 1077bc4bd..b197c0528 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Tests the xonsh main function.""" -from __future__ import unicode_literals, print_function from contextlib import contextmanager import builtins diff --git a/tests/test_man.py b/tests/test_man.py index 154664e13..eb3767205 100644 --- a/tests/test_man.py +++ b/tests/test_man.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os import pytest # noqa F401 from xonsh.completers.man import complete_from_man diff --git a/tests/test_news.py b/tests/test_news.py index 6eda761df..04bb9b873 100644 --- a/tests/test_news.py +++ b/tests/test_news.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Testing that news entries are well formed.""" import os import re @@ -24,7 +23,7 @@ def check_news_file(fname): errors = restructuredtext_lint.lint(content) if errors: - err_msgs = os.linesep.join((err.message for err in errors)) + err_msgs = os.linesep.join(err.message for err in errors) pytest.fail(f"{fname}: Invalid ReST\n{err_msgs}") form = "" @@ -50,14 +49,14 @@ def check_news_file(fname): elif l.strip() == "": form += "0" else: - pytest.fail("{}:{}: invalid rst".format(name, i + 1), pytrace=True) + pytest.fail(f"{name}:{i + 1}: invalid rst", pytrace=True) # The file should have: # empty lines around categories # at least one content line in a non null category reg = re.compile(r"^(3(0|$)|20(1|4)(1|0|4)*0|204$)+$") if not reg.match(form): print(form) - pytest.fail("{}: invalid rst".format(name), pytrace=True) + pytest.fail(f"{name}: invalid rst", pytrace=True) @pytest.fixture(params=list(os.scandir(NEWSDIR))) diff --git a/tests/test_parser.py b/tests/test_parser.py index ee99fb40d..e1b9f718b 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests the xonsh parser.""" import ast import textwrap @@ -2624,35 +2623,23 @@ def test_redirect_abspath(case): @pytest.mark.parametrize("case", ["", "o", "out", "1"]) def test_redirect_output(case): - assert check_xonsh_ast({}, '$[echo "test" {}> test.txt]'.format(case), False) - assert check_xonsh_ast( - {}, '$[< input.txt echo "test" {}> test.txt]'.format(case), False - ) - assert check_xonsh_ast( - {}, '$[echo "test" {}> test.txt < input.txt]'.format(case), False - ) + assert check_xonsh_ast({}, f'$[echo "test" {case}> test.txt]', False) + assert check_xonsh_ast({}, f'$[< input.txt echo "test" {case}> test.txt]', False) + assert check_xonsh_ast({}, f'$[echo "test" {case}> test.txt < input.txt]', False) @pytest.mark.parametrize("case", ["e", "err", "2"]) def test_redirect_error(case): - assert check_xonsh_ast({}, '$[echo "test" {}> test.txt]'.format(case), False) - assert check_xonsh_ast( - {}, '$[< input.txt echo "test" {}> test.txt]'.format(case), False - ) - assert check_xonsh_ast( - {}, '$[echo "test" {}> test.txt < input.txt]'.format(case), False - ) + assert check_xonsh_ast({}, f'$[echo "test" {case}> test.txt]', False) + assert check_xonsh_ast({}, f'$[< input.txt echo "test" {case}> test.txt]', False) + assert check_xonsh_ast({}, f'$[echo "test" {case}> test.txt < input.txt]', False) @pytest.mark.parametrize("case", ["a", "all", "&"]) def test_redirect_all(case): - assert check_xonsh_ast({}, '$[echo "test" {}> test.txt]'.format(case), False) - assert check_xonsh_ast( - {}, '$[< input.txt echo "test" {}> test.txt]'.format(case), False - ) - assert check_xonsh_ast( - {}, '$[echo "test" {}> test.txt < input.txt]'.format(case), False - ) + assert check_xonsh_ast({}, f'$[echo "test" {case}> test.txt]', False) + assert check_xonsh_ast({}, f'$[< input.txt echo "test" {case}> test.txt]', False) + assert check_xonsh_ast({}, f'$[echo "test" {case}> test.txt < input.txt]', False) @pytest.mark.parametrize( @@ -2673,13 +2660,9 @@ def test_redirect_all(case): ) @pytest.mark.parametrize("o", ["", "o", "out", "1"]) def test_redirect_error_to_output(r, o): - assert check_xonsh_ast({}, '$[echo "test" {} {}> test.txt]'.format(r, o), False) - assert check_xonsh_ast( - {}, '$[< input.txt echo "test" {} {}> test.txt]'.format(r, o), False - ) - assert check_xonsh_ast( - {}, '$[echo "test" {} {}> test.txt < input.txt]'.format(r, o), False - ) + assert check_xonsh_ast({}, f'$[echo "test" {r} {o}> test.txt]', False) + assert check_xonsh_ast({}, f'$[< input.txt echo "test" {r} {o}> test.txt]', False) + assert check_xonsh_ast({}, f'$[echo "test" {r} {o}> test.txt < input.txt]', False) @pytest.mark.parametrize( @@ -2700,13 +2683,9 @@ def test_redirect_error_to_output(r, o): ) @pytest.mark.parametrize("e", ["e", "err", "2"]) def test_redirect_output_to_error(r, e): - assert check_xonsh_ast({}, '$[echo "test" {} {}> test.txt]'.format(r, e), False) - assert check_xonsh_ast( - {}, '$[< input.txt echo "test" {} {}> test.txt]'.format(r, e), False - ) - assert check_xonsh_ast( - {}, '$[echo "test" {} {}> test.txt < input.txt]'.format(r, e), False - ) + assert check_xonsh_ast({}, f'$[echo "test" {r} {e}> test.txt]', False) + assert check_xonsh_ast({}, f'$[< input.txt echo "test" {r} {e}> test.txt]', False) + assert check_xonsh_ast({}, f'$[echo "test" {r} {e}> test.txt < input.txt]', False) def test_macro_call_empty(): @@ -2748,7 +2727,7 @@ MACRO_ARGS = [ @pytest.mark.parametrize("s", MACRO_ARGS) def test_macro_call_one_arg(s): - f = "f!({})".format(s) + f = f"f!({s})" tree = check_xonsh_ast({}, f, False, return_obs=True) assert isinstance(tree, AST) args = tree.body.args[1].elts @@ -2758,7 +2737,7 @@ def test_macro_call_one_arg(s): @pytest.mark.parametrize("s,t", itertools.product(MACRO_ARGS[::2], MACRO_ARGS[1::2])) def test_macro_call_two_args(s, t): - f = "f!({}, {})".format(s, t) + f = f"f!({s}, {t})" tree = check_xonsh_ast({}, f, False, return_obs=True) assert isinstance(tree, AST) args = tree.body.args[1].elts @@ -2771,7 +2750,7 @@ def test_macro_call_two_args(s, t): "s,t,u", itertools.product(MACRO_ARGS[::3], MACRO_ARGS[1::3], MACRO_ARGS[2::3]) ) def test_macro_call_three_args(s, t, u): - f = "f!({}, {}, {})".format(s, t, u) + f = f"f!({s}, {t}, {u})" tree = check_xonsh_ast({}, f, False, return_obs=True) assert isinstance(tree, AST) args = tree.body.args[1].elts @@ -2783,7 +2762,7 @@ def test_macro_call_three_args(s, t, u): @pytest.mark.parametrize("s", MACRO_ARGS) def test_macro_call_one_trailing(s): - f = "f!({0},)".format(s) + f = f"f!({s},)" tree = check_xonsh_ast({}, f, False, return_obs=True) assert isinstance(tree, AST) args = tree.body.args[1].elts @@ -2793,7 +2772,7 @@ def test_macro_call_one_trailing(s): @pytest.mark.parametrize("s", MACRO_ARGS) def test_macro_call_one_trailing_space(s): - f = "f!( {0}, )".format(s) + f = f"f!( {s}, )" tree = check_xonsh_ast({}, f, False, return_obs=True) assert isinstance(tree, AST) args = tree.body.args[1].elts @@ -2963,7 +2942,7 @@ WITH_BANG_RAWSIMPLE = [ @pytest.mark.parametrize("body", WITH_BANG_RAWSIMPLE) def test_withbang_single_simple(body): - code = "with! x: {}\n".format(body) + code = f"with! x: {body}\n" tree = check_xonsh_ast({}, code, False, return_obs=True, mode="exec") assert isinstance(tree, AST) wither = tree.body[0] @@ -2978,7 +2957,7 @@ def test_withbang_single_simple(body): @pytest.mark.parametrize("body", WITH_BANG_RAWSIMPLE) def test_withbang_single_simple_opt(body): - code = "with! x as y: {}\n".format(body) + code = f"with! x as y: {body}\n" tree = check_xonsh_ast({}, code, False, return_obs=True, mode="exec") assert isinstance(tree, AST) wither = tree.body[0] @@ -3068,19 +3047,19 @@ def test_syntax_error_del_ifexp(): ) def test_syntax_error_del_comps(exp): with pytest.raises(SyntaxError): - PARSER.parse("del {}".format(exp)) + PARSER.parse(f"del {exp}") @pytest.mark.parametrize("exp", ["x + y", "x and y", "-x"]) def test_syntax_error_del_ops(exp): with pytest.raises(SyntaxError): - PARSER.parse("del {}".format(exp)) + PARSER.parse(f"del {exp}") @pytest.mark.parametrize("exp", ["x > y", "x > y == z"]) def test_syntax_error_del_cmp(exp): with pytest.raises(SyntaxError): - PARSER.parse("del {}".format(exp)) + PARSER.parse(f"del {exp}") def test_syntax_error_lonely_del(): @@ -3129,19 +3108,19 @@ def test_syntax_error_assign_ifexp(): ) def test_syntax_error_assign_comps(exp): with pytest.raises(SyntaxError): - PARSER.parse("{} = z".format(exp)) + PARSER.parse(f"{exp} = z") @pytest.mark.parametrize("exp", ["x + y", "x and y", "-x"]) def test_syntax_error_assign_ops(exp): with pytest.raises(SyntaxError): - PARSER.parse("{} = z".format(exp)) + PARSER.parse(f"{exp} = z") @pytest.mark.parametrize("exp", ["x > y", "x > y == z"]) def test_syntax_error_assign_cmp(exp): with pytest.raises(SyntaxError): - PARSER.parse("{} = a".format(exp)) + PARSER.parse(f"{exp} = a") def test_syntax_error_augassign_literal(): @@ -3185,19 +3164,19 @@ def test_syntax_error_augassign_ifexp(): ) def test_syntax_error_augassign_comps(exp): with pytest.raises(SyntaxError): - PARSER.parse("{} += z".format(exp)) + PARSER.parse(f"{exp} += z") @pytest.mark.parametrize("exp", ["x + y", "x and y", "-x"]) def test_syntax_error_augassign_ops(exp): with pytest.raises(SyntaxError): - PARSER.parse("{} += z".format(exp)) + PARSER.parse(f"{exp} += z") @pytest.mark.parametrize("exp", ["x > y", "x > y +=+= z"]) def test_syntax_error_augassign_cmp(exp): with pytest.raises(SyntaxError): - PARSER.parse("{} += a".format(exp)) + PARSER.parse(f"{exp} += a") def test_syntax_error_bar_kwonlyargs(): diff --git a/tests/test_ptk_highlight.py b/tests/test_ptk_highlight.py index a150ade6e..d4352edba 100644 --- a/tests/test_ptk_highlight.py +++ b/tests/test_ptk_highlight.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Test XonshLexer for pygments""" import gc @@ -46,7 +45,7 @@ def check_token(code, tokens): break tks = tks[1:] else: - msg = "Token {!r} missing: {!r}".format(tk, list(lx.get_tokens(code))) + msg = f"Token {tk!r} missing: {list(lx.get_tokens(code))!r}" pytest.fail(msg) break @@ -164,14 +163,12 @@ def xonsh_builtins_ls_colors(xession, events_fxt): def test_path(tmpdir, xonsh_builtins_ls_colors): test_dir = str(tmpdir.mkdir("xonsh-test-highlight-path")) + check_token(f"cd {test_dir}", [(Name.Builtin, "cd"), (Color.BOLD_BLUE, test_dir)]) check_token( - "cd {}".format(test_dir), [(Name.Builtin, "cd"), (Color.BOLD_BLUE, test_dir)] + f"cd {test_dir}-xxx", + [(Name.Builtin, "cd"), (Text, f"{test_dir}-xxx")], ) - check_token( - "cd {}-xxx".format(test_dir), - [(Name.Builtin, "cd"), (Text, "{}-xxx".format(test_dir))], - ) - check_token("cd X={}".format(test_dir), [(Color.BOLD_BLUE, test_dir)]) + check_token(f"cd X={test_dir}", [(Color.BOLD_BLUE, test_dir)]) with xonsh_builtins_ls_colors.env.swap(AUTO_CD=True): check_token(test_dir, [(Name.Constant, test_dir)]) @@ -186,13 +183,11 @@ def test_color_on_lscolors_change(tmpdir, xonsh_builtins_ls_colors): lsc["di"] = ("GREEN",) - check_token( - "cd {}".format(test_dir), [(Name.Builtin, "cd"), (Color.GREEN, test_dir)] - ) + check_token(f"cd {test_dir}", [(Name.Builtin, "cd"), (Color.GREEN, test_dir)]) del lsc["di"] - check_token("cd {}".format(test_dir), [(Name.Builtin, "cd"), (Text, test_dir)]) + check_token(f"cd {test_dir}", [(Name.Builtin, "cd"), (Text, test_dir)]) @skip_if_on_windows diff --git a/tests/test_ptk_multiline.py b/tests/test_ptk_multiline.py index 7f25ac6d8..6b3eb31f8 100644 --- a/tests/test_ptk_multiline.py +++ b/tests/test_ptk_multiline.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests sample inputs to PTK multiline and checks parser response""" from collections import namedtuple from unittest.mock import MagicMock, patch diff --git a/tests/test_ptk_shell.py b/tests/test_ptk_shell.py index ebbd422f5..296920046 100644 --- a/tests/test_ptk_shell.py +++ b/tests/test_ptk_shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Test initialization of prompt_toolkit shell""" import sys diff --git a/tests/test_shell.py b/tests/test_shell.py index 147c5e393..524ce755f 100644 --- a/tests/test_shell.py +++ b/tests/test_shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Testing for ``xonsh.shell.Shell``""" import os diff --git a/tests/test_tools.py b/tests/test_tools.py index 2d9a5c57c..be63bfd36 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests xonsh tools.""" import datetime as dt import os @@ -128,49 +127,49 @@ def test_subproc_toks_ls_l(): def test_subproc_toks_git(): s = 'git commit -am "hello doc"' - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_git_semi(): s = 'git commit -am "hello doc"' - exp = "![{0}];".format(s) + exp = f"![{s}];" obs = subproc_toks(s + ";", lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_git_nl(): s = 'git commit -am "hello doc"' - exp = "![{0}]\n".format(s) + exp = f"![{s}]\n" obs = subproc_toks(s + "\n", lexer=LEXER, returnline=True) assert exp == obs def test_bash_macro(): s = "bash -c ! export var=42; echo $var" - exp = "![{0}]\n".format(s) + exp = f"![{s}]\n" obs = subproc_toks(s + "\n", lexer=LEXER, returnline=True) assert exp == obs def test_python_macro(): s = 'python -c ! import os; print(os.path.abspath("/"))' - exp = "![{0}]\n".format(s) + exp = f"![{s}]\n" obs = subproc_toks(s + "\n", lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_indent_ls(): s = "ls -l" - exp = INDENT + "![{0}]".format(s) + exp = INDENT + f"![{s}]" obs = subproc_toks(INDENT + s, mincol=len(INDENT), lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_indent_ls_nl(): s = "ls -l" - exp = INDENT + "![{0}]\n".format(s) + exp = INDENT + f"![{s}]\n" obs = subproc_toks( INDENT + s + "\n", mincol=len(INDENT), lexer=LEXER, returnline=True ) @@ -179,28 +178,28 @@ def test_subproc_toks_indent_ls_nl(): def test_subproc_toks_indent_ls_no_min(): s = "ls -l" - exp = INDENT + "![{0}]".format(s) + exp = INDENT + f"![{s}]" obs = subproc_toks(INDENT + s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_indent_ls_no_min_nl(): s = "ls -l" - exp = INDENT + "![{0}]\n".format(s) + exp = INDENT + f"![{s}]\n" obs = subproc_toks(INDENT + s + "\n", lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_indent_ls_no_min_semi(): s = "ls" - exp = INDENT + "![{0}];".format(s) + exp = INDENT + f"![{s}];" obs = subproc_toks(INDENT + s + ";", lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_indent_ls_no_min_semi_nl(): s = "ls" - exp = INDENT + "![{0}];\n".format(s) + exp = INDENT + f"![{s}];\n" obs = subproc_toks(INDENT + s + ";\n", lexer=LEXER, returnline=True) assert exp == obs @@ -208,7 +207,7 @@ def test_subproc_toks_indent_ls_no_min_semi_nl(): def test_subproc_toks_ls_comment(): s = "ls -l" com = " # lets list" - exp = "![{0}]{1}".format(s, com) + exp = f"![{s}]{com}" obs = subproc_toks(s + com, lexer=LEXER, returnline=True) assert exp == obs @@ -216,7 +215,7 @@ def test_subproc_toks_ls_comment(): def test_subproc_toks_ls_42_comment(): s = "ls 42" com = " # lets list" - exp = "![{0}]{1}".format(s, com) + exp = f"![{s}]{com}" obs = subproc_toks(s + com, lexer=LEXER, returnline=True) assert exp == obs @@ -224,7 +223,7 @@ def test_subproc_toks_ls_42_comment(): def test_subproc_toks_ls_str_comment(): s = 'ls "wakka"' com = " # lets list" - exp = "![{0}]{1}".format(s, com) + exp = f"![{s}]{com}" obs = subproc_toks(s + com, lexer=LEXER, returnline=True) assert exp == obs @@ -233,7 +232,7 @@ def test_subproc_toks_indent_ls_comment(): ind = " " s = "ls -l" com = " # lets list" - exp = "{0}![{1}]{2}".format(ind, s, com) + exp = f"{ind}![{s}]{com}" obs = subproc_toks(ind + s + com, lexer=LEXER, returnline=True) assert exp == obs @@ -242,7 +241,7 @@ def test_subproc_toks_indent_ls_str(): ind = " " s = 'ls "wakka"' com = " # lets list" - exp = "{0}![{1}]{2}".format(ind, s, com) + exp = f"{ind}![{s}]{com}" obs = subproc_toks(ind + s + com, lexer=LEXER, returnline=True) assert exp == obs @@ -250,8 +249,8 @@ def test_subproc_toks_indent_ls_str(): def test_subproc_toks_ls_l_semi_ls_first(): lsdl = "ls -l" ls = "ls" - s = "{0}; {1}".format(lsdl, ls) - exp = "![{0}]; {1}".format(lsdl, ls) + s = f"{lsdl}; {ls}" + exp = f"![{lsdl}]; {ls}" obs = subproc_toks(s, lexer=LEXER, maxcol=6, returnline=True) assert exp == obs @@ -259,8 +258,8 @@ def test_subproc_toks_ls_l_semi_ls_first(): def test_subproc_toks_ls_l_semi_ls_second(): lsdl = "ls -l" ls = "ls" - s = "{0}; {1}".format(lsdl, ls) - exp = "{0}; ![{1}]".format(lsdl, ls) + s = f"{lsdl}; {ls}" + exp = f"{lsdl}; ![{ls}]" obs = subproc_toks(s, lexer=LEXER, mincol=7, returnline=True) assert exp == obs @@ -268,8 +267,8 @@ def test_subproc_toks_ls_l_semi_ls_second(): def test_subproc_toks_hello_mom_first(): fst = "echo 'hello'" sec = "echo 'mom'" - s = "{0}; {1}".format(fst, sec) - exp = "![{0}]; {1}".format(fst, sec) + s = f"{fst}; {sec}" + exp = f"![{fst}]; {sec}" obs = subproc_toks(s, lexer=LEXER, maxcol=len(fst) + 1, returnline=True) assert exp == obs @@ -277,8 +276,8 @@ def test_subproc_toks_hello_mom_first(): def test_subproc_toks_hello_mom_second(): fst = "echo 'hello'" sec = "echo 'mom'" - s = "{0}; {1}".format(fst, sec) - exp = "{0}; ![{1}]".format(fst, sec) + s = f"{fst}; {sec}" + exp = f"{fst}; ![{sec}]" obs = subproc_toks(s, lexer=LEXER, mincol=len(fst), returnline=True) assert exp == obs @@ -305,7 +304,7 @@ def test_subproc_toks_hello_bad_trailing_triple_quotes(): def test_subproc_toks_hello_mom_triple_quotes_nl(): s = 'echo """hello\nmom"""' - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs @@ -360,44 +359,44 @@ def test_subproc_toks_semicolon_only(): def test_subproc_toks_pyeval(): s = "echo @(1+1)" - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_pyeval_multiline_string(): s = 'echo @("""hello\nmom""")' - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_twopyeval(): s = "echo @(1+1) @(40 + 2)" - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_pyeval_parens(): s = "echo @(1+1)" - inp = "({0})".format(s) - exp = "(![{0}])".format(s) + inp = f"({s})" + exp = f"(![{s}])" obs = subproc_toks(inp, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_twopyeval_parens(): s = "echo @(1+1) @(40+2)" - inp = "({0})".format(s) - exp = "(![{0}])".format(s) + inp = f"({s})" + exp = f"(![{s}])" obs = subproc_toks(inp, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_pyeval_nested(): s = "echo @(min(1, 42))" - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs @@ -423,65 +422,65 @@ def test_subproc_toks_pyeval_nested(): ) def test_subproc_toks_and_or(phrase): s = "echo " + phrase - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_pyeval_nested_parens(): s = "echo @(min(1, 42))" - inp = "({0})".format(s) - exp = "(![{0}])".format(s) + inp = f"({s})" + exp = f"(![{s}])" obs = subproc_toks(inp, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_capstdout(): s = "echo $(echo bat)" - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_capproc(): s = "echo !(echo bat)" - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_pyeval_redirect(): s = 'echo @("foo") > bar' - inp = "{0}".format(s) - exp = "![{0}]".format(s) + inp = f"{s}" + exp = f"![{s}]" obs = subproc_toks(inp, lexer=LEXER, returnline=True) assert exp == obs def test_subproc_toks_greedy_parens(): s = "(sort)" - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True) assert exp == obs def test_subproc_toks_greedy_parens_inp(): s = "(sort) < input.txt" - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True) assert exp == obs def test_subproc_toks_greedy_parens_statements(): s = '(echo "abc"; sleep 1; echo "def")' - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True) assert exp == obs def test_subproc_toks_greedy_parens_statements_with_grep(): s = '(echo "abc"; sleep 1; echo "def") | grep' - exp = "![{0}]".format(s) + exp = f"![{s}]" obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True) assert exp == obs @@ -1572,7 +1571,7 @@ def test_executables_in(xession): with TemporaryDirectory() as test_path: for _type in types: for executable in executables: - fname = "%s_%s" % (_type, executable) + fname = f"{_type}_{executable}" if _type == "none": continue if _type == "file" and executable: diff --git a/tests/test_tracer.py b/tests/test_tracer.py index 9109f741e..7883015bf 100644 --- a/tests/test_tracer.py +++ b/tests/test_tracer.py @@ -15,5 +15,5 @@ def test_tracer_help(capsys, xsh_with_aliases): pat = re.compile(r"^usage:\s*trace[^\n]*{([\w,-]+)}", re.MULTILINE) m = pat.match(capout) assert m[1] - verbs = set(v.strip().lower() for v in m[1].split(",")) + verbs = {v.strip().lower() for v in m[1].split(",")} assert verbs == {"rm", "start", "add", "on", "off", "del", "color", "stop", "ls"} diff --git a/tests/test_wizard.py b/tests/test_wizard.py index c0cfbf95e..30820495d 100644 --- a/tests/test_wizard.py +++ b/tests/test_wizard.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Tests the xonsh lexer.""" -from __future__ import unicode_literals, print_function import os import pytest # noqa F401 @@ -69,7 +67,7 @@ def test_state_visitor_store(): def dump_xonfig_env_mock(path, value): name = os.path.basename(path.rstrip("/")) - return "${name} = {val!r}".format(name=name, val=value) + return f"${name} = {value!r}" def test_tuple_store_and_write(): diff --git a/tests/test_xonfig.py b/tests/test_xonfig.py index 7b95e748c..21c202561 100644 --- a/tests/test_xonfig.py +++ b/tests/test_xonfig.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tests the xonfig command. Actually, just a down payment on a full test. Currently exercises only these options: @@ -24,7 +23,7 @@ def test_xonfg_help(capsys, xonsh_builtins): pat = re.compile(r"^usage:\s*xonfig[^\n]*{([\w,-]+)}", re.MULTILINE) m = pat.match(capout) assert m[1] - verbs = set(v.strip().lower() for v in m[1].split(",")) + verbs = {v.strip().lower() for v in m[1].split(",")} assert verbs == { "jupyter-kernel", "info", @@ -101,7 +100,7 @@ def test_xonfig_kernel_with_jupyter(monkeypatch, capsys, fake_lib, xonsh_builtin nonlocal cap_spec cap_args = dict(args=args, kw=kwargs) spec_file = os.path.join(args[1], "kernel.json") - cap_spec = json.load(open(spec_file, "r")) + cap_spec = json.load(open(spec_file)) def mock_get_kernel_spec(*args, **kwargs): raise jupyter_client.kernelspec.NoSuchKernel diff --git a/tests/tools.py b/tests/tools.py index 38e0604e7..e24e61da5 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- """Tests the xonsh lexer.""" -from __future__ import unicode_literals, print_function import os import sys import ast @@ -200,27 +198,29 @@ def check_parse(input): def nodes_equal(x, y): __tracebackhide__ = True - assert type(x) == type(y), "Ast nodes do not have the same type: '%s' != '%s' " % ( + assert type(x) == type( + y + ), "Ast nodes do not have the same type: '{}' != '{}' ".format( type(x), type(y), ) if isinstance(x, (ast.Expr, ast.FunctionDef, ast.ClassDef)): assert ( x.lineno == y.lineno - ), "Ast nodes do not have the same line number : %s != %s" % ( + ), "Ast nodes do not have the same line number : {} != {}".format( x.lineno, y.lineno, ) assert ( x.col_offset == y.col_offset - ), "Ast nodes do not have the same column offset number : %s != %s" % ( + ), "Ast nodes do not have the same column offset number : {} != {}".format( x.col_offset, y.col_offset, ) for (xname, xval), (yname, yval) in zip(ast.iter_fields(x), ast.iter_fields(y)): assert ( xname == yname - ), "Ast nodes fields differ : %s (of type %s) != %s (of type %s)" % ( + ), "Ast nodes fields differ : {} (of type {}) != {} (of type {})".format( xname, type(xval), yname, @@ -228,7 +228,7 @@ def nodes_equal(x, y): ) assert type(xval) == type( yval - ), "Ast nodes fields differ : %s (of type %s) != %s (of type %s)" % ( + ), "Ast nodes fields differ : {} (of type {}) != {} (of type {})".format( xname, type(xval), yname, diff --git a/xonsh/aliases.py b/xonsh/aliases.py index 1d160ab38..d6e4e7483 100644 --- a/xonsh/aliases.py +++ b/xonsh/aliases.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Aliases for the xonsh shell.""" import functools import os @@ -183,7 +182,7 @@ class Aliases(cabc.MutableMapping): return str(self._raw) def __repr__(self): - return "{0}.{1}({2})".format( + return "{}.{}({})".format( self.__class__.__module__, self.__class__.__name__, self._raw ) @@ -222,7 +221,7 @@ class ExecAlias: ) def __repr__(self): - return "ExecAlias({0!r}, filename={1!r})".format(self.src, self.filename) + return f"ExecAlias({self.src!r}, filename={self.filename!r})" class PartialEvalAliasBase: @@ -478,7 +477,7 @@ def source_foreign_fn( if dryrun: return else: - msg = "xonsh: error: Source failed: {0!r}\n".format(prevcmd) + msg = f"xonsh: error: Source failed: {prevcmd!r}\n" msg += "xonsh: error: Possible reasons: File not found or syntax error\n" return (None, msg, 1) # apply results @@ -531,7 +530,7 @@ def source_alias(args, stdin=None): fpath = locate_binary(fname) if fpath is None: if env.get("XONSH_DEBUG"): - print("source: {}: No such file".format(fname), file=sys.stderr) + print(f"source: {fname}: No such file", file=sys.stderr) if i == 0: raise RuntimeError( "must source at least one file, " + fname + " does not exist." @@ -545,7 +544,7 @@ def source_alias(args, stdin=None): "then please use the appropriate source command. " "For example, source-bash script.sh" ) - with open(fpath, "r", encoding=encoding, errors=errors) as fp: + with open(fpath, encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith("\n"): src += "\n" @@ -617,7 +616,7 @@ def source_cmd_fn( fpath = locate_binary(args[0]) args[0] = fpath if fpath else args[0] if not os.path.isfile(args[0]): - return (None, "xonsh: error: File not found: {}\n".format(args[0]), 1) + return (None, f"xonsh: error: File not found: {args[0]}\n", 1) prevcmd = "call " prevcmd += " ".join([argvquote(arg, force=True) for arg in args]) prevcmd = escape_windows_cmd_string(prevcmd) @@ -695,7 +694,7 @@ def xexec_fn( if name: command[0] = name if login: - command[0] = "-{}".format(command[0]) + command[0] = f"-{command[0]}" denv = {} if not clean: diff --git a/xonsh/ansi_colors.py b/xonsh/ansi_colors.py index e251d2357..d3a24b9f5 100644 --- a/xonsh/ansi_colors.py +++ b/xonsh/ansi_colors.py @@ -83,7 +83,7 @@ def ansi_color_name_to_escape_code(name, style="default", cmap=None): return cmap[name] m = RE_XONSH_COLOR.match(name) if m is None: - raise ValueError("{!r} is not a color!".format(name)) + raise ValueError(f"{name!r} is not a color!") parts = m.groupdict() # convert regex match into actual ANSI colors if parts["reset"] is not None: @@ -205,7 +205,7 @@ def ansi_color_style(style="default"): if style in ANSI_STYLES: cmap = ANSI_STYLES[style] else: - msg = "Could not find color style {0!r}, using default.".format(style) + msg = f"Could not find color style {style!r}, using default." warnings.warn(msg, RuntimeWarning) cmap = ANSI_STYLES["default"] return cmap @@ -295,7 +295,7 @@ def ansi_color_escape_code_to_name(escape_code, style, reversed_style=None): # strip some actual escape codes, if needed. match = ANSI_ESCAPE_CODE_RE.match(escape_code) if not match: - msg = 'Invalid ANSI color sequence "{0}", using "RESET" instead.'.format( + msg = 'Invalid ANSI color sequence "{}", using "RESET" instead.'.format( escape_code ) warnings.warn(msg, RuntimeWarning) @@ -1150,7 +1150,7 @@ def ansi_style_by_name(name): if name in ANSI_STYLES: return ANSI_STYLES[name] elif not HAS_PYGMENTS: - raise KeyError("could not find style {0!r}".format(name)) + raise KeyError(f"could not find style {name!r}") from xonsh.pygments_cache import get_style_by_name from pygments.util import ClassNotFound diff --git a/xonsh/ast.py b/xonsh/ast.py index a8f5c6859..076073640 100644 --- a/xonsh/ast.py +++ b/xonsh/ast.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """The xonsh abstract syntax tree node.""" # These are imported into our module namespace for the benefit of parser.py. # pylint: disable=unused-import @@ -339,7 +338,7 @@ class CtxAwareTransformer(NodeTransformer): parser : xonsh.Parser A parse instance to try to parse subprocess statements with. """ - super(CtxAwareTransformer, self).__init__() + super().__init__() self.parser = parser self.input = None self.contexts = [] @@ -420,7 +419,7 @@ class CtxAwareTransformer(NodeTransformer): returnline=False, lexer=self.parser.lexer, ) - if spline is None or spline != "![{}]".format(line[mincol:maxcol].strip()): + if spline is None or spline != f"![{line[mincol:maxcol].strip()}]": # failed to get something consistent, try greedy wrap spline = subproc_toks( line, @@ -638,7 +637,7 @@ def pdump(s, **kwargs): lens = len(s) + 1 if lens == 1: return s - i = min([s.find(o) % lens for o in openers]) + i = min(s.find(o) % lens for o in openers) if i == lens - 1: return s closer = closers[openers.find(s[i])] diff --git a/xonsh/base_shell.py b/xonsh/base_shell.py index 72d9567dd..dd10f22ce 100644 --- a/xonsh/base_shell.py +++ b/xonsh/base_shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """The base class for xonsh shell""" import io import os @@ -554,7 +553,7 @@ class BaseShell: with open(1, "wb", closefd=False) as f: # prevent xonsh from answering interactive questions # on the next command by writing the title - f.write("\x1b]0;{0}\x07".format(t).encode()) + f.write(f"\x1b]0;{t}\x07".encode()) f.flush() @property diff --git a/xonsh/built_ins.py b/xonsh/built_ins.py index 1cdbd478e..ef0156069 100644 --- a/xonsh/built_ins.py +++ b/xonsh/built_ins.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """The xonsh built-ins. Note that this module is named 'built_ins' so as not to be confused with the @@ -294,7 +293,7 @@ def _convert_kind_flag(x): x = x.lower() kind = MACRO_FLAG_KINDS.get(x, None) if kind is None: - raise TypeError("{0!r} not a recognized macro type.".format(x)) + raise TypeError(f"{x!r} not a recognized macro type.") return kind @@ -455,7 +454,7 @@ def _eval_regular_args(raw_args, glbs, locs): else: argstr = "({},)".format(", ".join(arglist)) kwargstr = "dict({})".format(", ".join(kwarglist)) - both = "({}, {})".format(argstr, kwargstr) + both = f"({argstr}, {kwargstr})" args, kwargs = execer.eval(both, glbs=glbs, locs=locs) return args, kwargs diff --git a/xonsh/codecache.py b/xonsh/codecache.py index da7171ff8..a415639f4 100644 --- a/xonsh/codecache.py +++ b/xonsh/codecache.py @@ -31,7 +31,7 @@ def _cache_renamer(path, code=False): if not code: path = os.path.realpath(path) o = ["".join(_CHARACTER_MAP.get(i, i) for i in w) for w in _splitpath(path)] - o[-1] = "{}.{}".format(o[-1], sys.implementation.cache_tag) + o[-1] = f"{o[-1]}.{sys.implementation.cache_tag}" return o @@ -153,7 +153,7 @@ def run_script_with_cache(filename, execer, glb=None, loc=None, mode="exec"): if use_cache: run_cached, ccode = script_cache_check(filename, cachefname) if not run_cached: - with open(filename, "r", encoding="utf-8") as f: + with open(filename, encoding="utf-8") as f: code = f.read() ccode = compile_code(filename, code, execer, glb, loc, mode) update_cache(ccode, cachefname) diff --git a/xonsh/color_tools.py b/xonsh/color_tools.py index fa1398ec0..37f56f915 100644 --- a/xonsh/color_tools.py +++ b/xonsh/color_tools.py @@ -464,9 +464,9 @@ def RE_RGB6(): def rgb_to_ints(rgb): if len(rgb) == 6: - return tuple([int(h, 16) for h in RE_RGB6.split(rgb)[1:4]]) + return tuple(int(h, 16) for h in RE_RGB6.split(rgb)[1:4]) else: - return tuple([int(h * 2, 16) for h in RE_RGB3.split(rgb)[1:4]]) + return tuple(int(h * 2, 16) for h in RE_RGB3.split(rgb)[1:4]) def short_to_ints(short): diff --git a/xonsh/commands_cache.py b/xonsh/commands_cache.py index 3978180a0..fe040c339 100644 --- a/xonsh/commands_cache.py +++ b/xonsh/commands_cache.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Module for caching command & alias names as well as for predicting whether a command will be able to be run in the background. diff --git a/xonsh/completer.py b/xonsh/completer.py index 70e4bd4d3..3604c1cb5 100644 --- a/xonsh/completer.py +++ b/xonsh/completer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """A (tab-)completer for xonsh.""" import sys import typing as tp @@ -16,7 +15,7 @@ from xonsh.parsers.completion_context import CompletionContext, CompletionContex from xonsh.tools import print_exception -class Completer(object): +class Completer: """This provides a list of optional completions for the xonsh shell.""" def __init__(self): diff --git a/xonsh/completers/bash_completion.py b/xonsh/completers/bash_completion.py index ed3275b43..5b039cf12 100644 --- a/xonsh/completers/bash_completion.py +++ b/xonsh/completers/bash_completion.py @@ -110,7 +110,7 @@ def _get_bash_completions_source(paths=None): paths = _BASH_COMPLETIONS_PATHS_DEFAULT for path in map(pathlib.Path, paths): if path.is_file(): - return 'source "{}"'.format(path.as_posix()) + return f'source "{path.as_posix()}"' return None @@ -292,7 +292,7 @@ def bash_completions( opening_quote="", closing_quote="", arg_index=None, - **kwargs + **kwargs, ): """Completes based on results from BASH completion. @@ -418,7 +418,7 @@ def bash_completions( if "-o noquote" not in complete_stmt: out, need_quotes = quote_paths(out, opening_quote, closing_quote) if "-o nospace" in complete_stmt: - out = set([x.rstrip() for x in out]) + out = {x.rstrip() for x in out} return out, max(len(prefix) - strip_len, 0) diff --git a/xonsh/completers/python.py b/xonsh/completers/python.py index b0dcf8c3c..f546b3312 100644 --- a/xonsh/completers/python.py +++ b/xonsh/completers/python.py @@ -239,7 +239,7 @@ def attr_complete(prefix, ctx, filter_func): prelen = len(prefix) for opt in opts: # check whether these options actually work (e.g., disallow 7.imag) - _expr = "{0}.{1}".format(expr, opt) + _expr = f"{expr}.{opt}" _val_, _ctx_ = _safe_eval(_expr, _ctx) if _val_ is None and _ctx_ is None: continue diff --git a/xonsh/contexts.py b/xonsh/contexts.py index be0ddc7e0..2f31fcdc8 100644 --- a/xonsh/contexts.py +++ b/xonsh/contexts.py @@ -6,7 +6,7 @@ from collections.abc import Mapping from xonsh.built_ins import XSH -class Block(object): +class Block: """This is a context manager for obtaining a block of lines without actually executing the block. The lines are accessible as the 'lines' attribute. This must be used as a macro. @@ -80,7 +80,7 @@ class Functor(Block): super().__enter__() body = textwrap.indent(self.macro_block, " ") uid = hash(body) + sys.maxsize # should always be a positive int - name = "__xonsh_functor_{uid}__".format(uid=uid) + name = f"__xonsh_functor_{uid}__" # construct signature string sig = rtn = "" sig = ", ".join(self.args) diff --git a/xonsh/diff_history.py b/xonsh/diff_history.py index 293280235..90db687f5 100644 --- a/xonsh/diff_history.py +++ b/xonsh/diff_history.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tools for diff'ing two xonsh history files in a meaningful fashion.""" import difflib import datetime @@ -78,7 +77,7 @@ def highlighted_ndiff(a, b): return s -class HistoryDiffer(object): +class HistoryDiffer: """This class helps diff two xonsh history files.""" def __init__(self, afile, bfile, reopen=False, verbose=False): @@ -141,7 +140,7 @@ class HistoryDiffer(object): bval = benv[key] if aval == bval: continue - s += "{0!r} is in both, but differs\n".format(key) + s += f"{key!r} is in both, but differs\n" s += bold_str_diff(aval, bval, sm=sm) + "\n" return s @@ -150,12 +149,10 @@ class HistoryDiffer(object): if len(only_x) == 0: return "" if self.verbose: - xstr = ",\n".join( - [" {0!r}: {1!r}".format(key, xenv[key]) for key in only_x] - ) + xstr = ",\n".join([f" {key!r}: {xenv[key]!r}" for key in only_x]) xstr = "\n" + xstr else: - xstr = ", ".join(["{0!r}".format(key) for key in only_x]) + xstr = ", ".join([f"{key!r}" for key in only_x]) in_x = "These vars are only in {color}{xid}{reset}: {{{xstr}}}\n\n" return in_x.format(xid=xid, color=color, reset=COLORS.RESET, xstr=xstr) diff --git a/xonsh/dirstack.py b/xonsh/dirstack.py index 41dc46fd2..b73a1ac8e 100644 --- a/xonsh/dirstack.py +++ b/xonsh/dirstack.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Directory stack and associated utilities for the xonsh shell. https://www.gnu.org/software/bash/manual/html_node/Directory-Stack-Builtins.html """ @@ -221,11 +220,11 @@ def cd(args, stdin=None): try: num = int(d[1:]) except ValueError: - return "", "cd: Invalid destination: {0}\n".format(d), 1 + return "", f"cd: Invalid destination: {d}\n", 1 if num == 0: return None, None, 0 elif num < 0: - return "", "cd: Invalid destination: {0}\n".format(d), 1 + return "", f"cd: Invalid destination: {d}\n", 1 elif num > len(DIRSTACK): e = "cd: Too few elements in dirstack ({0} elements)\n" return "", e.format(len(DIRSTACK)), 1 @@ -237,18 +236,18 @@ def cd(args, stdin=None): return ( "", ( - "cd takes 0 or 1 arguments, not {0}. An additional `-P` " + "cd takes 0 or 1 arguments, not {}. An additional `-P` " "flag can be passed in first position to follow symlinks." "\n".format(len(args)) ), 1, ) if not os.path.exists(d): - return "", "cd: no such file or directory: {0}\n".format(d), 1 + return "", f"cd: no such file or directory: {d}\n", 1 if not os.path.isdir(d): - return "", "cd: {0} is not a directory\n".format(d), 1 + return "", f"cd: {d} is not a directory\n", 1 if not os.access(d, os.X_OK): - return "", "cd: permission denied: {0}\n".format(d), 1 + return "", f"cd: permission denied: {d}\n", 1 if ( ON_WINDOWS and _is_unc_path(d) @@ -511,7 +510,7 @@ def dirs_fn( pad = len(str(len(o) - 1)) for (ix, e) in enumerate(o): blanks = " " * (pad - len(str(ix))) - out += "\n{0}{1} {2}".format(blanks, ix, e) + out += f"\n{blanks}{ix} {e}" out = out[1:] elif print_long: out = "\n".join(o) diff --git a/xonsh/environ.py b/xonsh/environ.py index 3924cb84e..cb9eee039 100644 --- a/xonsh/environ.py +++ b/xonsh/environ.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Environment for the xonsh shell.""" import os import re @@ -180,7 +179,7 @@ def locale_convert(key): locale.setlocale(LOCALE_CATS[key], val) val = locale.setlocale(LOCALE_CATS[key]) except (locale.Error, KeyError): - msg = "Failed to set locale {0!r} to {1!r}".format(key, val) + msg = f"Failed to set locale {key!r} to {val!r}" warnings.warn(msg, RuntimeWarning) return val @@ -390,7 +389,7 @@ class LsColors(cabc.MutableMapping): return str(self._d) def __repr__(self): - return "{0}.{1}(...)".format(self.__class__.__module__, self.__class__.__name__) + return f"{self.__class__.__module__}.{self.__class__.__name__}(...)" _repr_pretty_ = to_repr_pretty_ @@ -1400,10 +1399,8 @@ class PromptSetting(Xettings): None, "Symbols for gitstatus prompt. Default values are: \n\n" + "\n".join( - ( - f"* ``XONSH_GITSTATUS_{fld.name}``: ``{fld.value}``" - for fld in GITSTATUS_FIELD_DEFS - ) + f"* ``XONSH_GITSTATUS_{fld.name}``: ``{fld.value}``" + for fld in GITSTATUS_FIELD_DEFS ), pattern="XONSH_GITSTATUS_*", ) @@ -1411,11 +1408,9 @@ class PromptSetting(Xettings): (), "Fields to hide in {gitstatus} prompt (all fields below are shown by default.) \n\n" + "\n".join( - ( - f"* ``{fld.name}``\n" - for fld in GITSTATUS_FIELD_DEFS - if not fld.name.startswith("HASH") - ) + f"* ``{fld.name}``\n" + for fld in GITSTATUS_FIELD_DEFS + if not fld.name.startswith("HASH") ), ) XONSH_HISTORY_MATCH_ANYWHERE = Var.with_default( @@ -2084,11 +2079,11 @@ class Env(cabc.MutableMapping): """ yield from ( set(self._d) - | set( + | { k for k in self._vars.keys() if self._vars[k].default is not DefaultNotGiven - ) + } ) def __iter__(self): @@ -2108,7 +2103,7 @@ class Env(cabc.MutableMapping): return str(self._d) def __repr__(self): - return "{0}.{1}(...)".format(self.__class__.__module__, self.__class__.__name__) + return f"{self.__class__.__module__}.{self.__class__.__name__}(...)" def __hash__(self) -> int: return hash(str(self._d)) diff --git a/xonsh/execer.py b/xonsh/execer.py index f40024fe8..ab70e1bd3 100644 --- a/xonsh/execer.py +++ b/xonsh/execer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements the xonsh executer.""" import sys import types @@ -20,7 +19,7 @@ from xonsh.tools import ( from xonsh.built_ins import XSH -class Execer(object): +class Execer: """Executes xonsh code in a context.""" def __init__( diff --git a/xonsh/foreign_shells.py b/xonsh/foreign_shells.py index a4cae8d2a..26c8ba000 100644 --- a/xonsh/foreign_shells.py +++ b/xonsh/foreign_shells.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tools to help interface with foreign shells, such as Bash.""" import os import re @@ -385,7 +384,7 @@ def parse_funcs(s, shell, sourcer=None, files=(), extra_args=()): return funcs -class ForeignShellBaseAlias(object): +class ForeignShellBaseAlias: """This class is responsible for calling foreign shell functions as if they were aliases. This does not currently support taking stdin. """ @@ -578,9 +577,9 @@ def ensure_shell(shell): if "currenv" in shell_keys and not isinstance(shell["currenv"], tuple): ce = shell["currenv"] if isinstance(ce, cabc.Mapping): - ce = tuple([(ensure_string(k), v) for k, v in ce.items()]) + ce = tuple((ensure_string(k), v) for k, v in ce.items()) elif isinstance(ce, cabc.Sequence): - ce = tuple([(ensure_string(k), v) for k, v in ce]) + ce = tuple((ensure_string(k), v) for k, v in ce) else: raise RuntimeError("unrecognized type for currenv") shell["currenv"] = ce diff --git a/xonsh/history/base.py b/xonsh/history/base.py index 710a4a305..238146fa3 100644 --- a/xonsh/history/base.py +++ b/xonsh/history/base.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Base class of Xonsh History backends.""" import types import uuid diff --git a/xonsh/history/dummy.py b/xonsh/history/dummy.py index a38912f90..dc587fc6e 100644 --- a/xonsh/history/dummy.py +++ b/xonsh/history/dummy.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements the xonsh history backend.""" import collections from xonsh.history.base import History diff --git a/xonsh/history/json.py b/xonsh/history/json.py index 575129154..0c9e0ac30 100644 --- a/xonsh/history/json.py +++ b/xonsh/history/json.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements JSON version of xonsh history backend.""" import os import sys @@ -165,7 +164,7 @@ class JsonHistoryGC(threading.Thread): files = self.files(only_unlocked=True) rmfiles_fn = self.gc_units_to_rmfiles.get(units) if rmfiles_fn is None: - raise ValueError("Units type {0!r} not understood".format(units)) + raise ValueError(f"Units type {units!r} not understood") size_over, rm_files = rmfiles_fn(hsize, files) hist = getattr(XSH, "history", None) @@ -256,7 +255,7 @@ class JsonHistoryFlusher(threading.Thread): self, filename, buffer, queue, cond, at_exit=False, skip=None, *args, **kwargs ): """Thread for flushing history.""" - super(JsonHistoryFlusher, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.filename = filename self.buffer = buffer self.queue = queue @@ -299,7 +298,7 @@ class JsonHistoryFlusher(threading.Thread): cmds.append(cmd) last_inp = cmd["inp"] - with open(self.filename, "r", newline="\n") as f: + with open(self.filename, newline="\n") as f: hist = xlj.LazyJSON(f).load() load_hist_len = len(hist["cmds"]) hist["cmds"].extend(cmds) @@ -360,7 +359,7 @@ class JsonCommandField(cabc.Sequence): queue.append(self) with self.hist._cond: self.hist._cond.wait_for(self.i_am_at_the_front) - with open(self.hist.filename, "r", newline="\n") as f: + with open(self.hist.filename, newline="\n") as f: lj = xlj.LazyJSON(f, reopen=False) rtn = lj["cmds"][key].get(self.field, self.default) if isinstance(rtn, xlj.LJNode): @@ -411,9 +410,7 @@ class JsonHistory(History): if filename is None: # pylint: disable=no-member data_dir = _xhj_get_data_dir() - self.filename = os.path.join( - data_dir, "xonsh-{0}.json".format(self.sessionid) - ) + self.filename = os.path.join(data_dir, f"xonsh-{self.sessionid}.json") else: self.filename = filename diff --git a/xonsh/history/main.py b/xonsh/history/main.py index a1d521426..0df52da63 100644 --- a/xonsh/history/main.py +++ b/xonsh/history/main.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Main entry points of the xonsh history.""" import datetime import json @@ -31,7 +30,7 @@ def construct_history(**kwargs): return backend else: print( - "Unknown history backend: {}. Using JSON version".format(backend), + f"Unknown history backend: {backend}. Using JSON version", file=sys.stderr, ) kls_history = JsonHistory @@ -60,7 +59,7 @@ def _xh_find_histfile_var(file_list, default=None): f = xt.expanduser_abs_path(f) if not os.path.isfile(f): continue - with open(f, "r") as rc_file: + with open(f) as rc_file: for line in rc_file: if line.startswith("HISTFILE="): hist_file = line.split("=", 1)[1].strip("'\"\n") @@ -82,7 +81,7 @@ def _xh_bash_hist_parser(location=None, **kwargs): os.path.join("~", ".bash_history"), ) if location: - with open(location, "r", errors="backslashreplace") as bash_hist: + with open(location, errors="backslashreplace") as bash_hist: for ind, line in enumerate(bash_hist): yield {"inp": line.rstrip(), "ts": 0.0, "ind": ind} else: @@ -97,7 +96,7 @@ def _xh_zsh_hist_parser(location=None, **kwargs): os.path.join("~", ".zsh_history"), ) if location: - with open(location, "r", errors="backslashreplace") as zsh_hist: + with open(location, errors="backslashreplace") as zsh_hist: for ind, line in enumerate(zsh_hist): if line.startswith(":"): try: @@ -131,7 +130,7 @@ def _xh_get_history( datetime_format=None, start_time=None, end_time=None, - location=None + location=None, ): """Get the requested portion of shell history. @@ -339,7 +338,7 @@ class HistoryAlias(xcli.ArgParserAlias): s = json.dumps(data) print(s, file=_stdout) else: - lines = ["{0}: {1}".format(k, v) for k, v in data.items()] + lines = [f"{k}: {v}" for k, v in data.items()] print("\n".join(lines), file=_stdout) @staticmethod diff --git a/xonsh/history/sqlite.py b/xonsh/history/sqlite.py index 62c752238..7ba59f33d 100644 --- a/xonsh/history/sqlite.py +++ b/xonsh/history/sqlite.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements the xonsh history backend via sqlite3.""" import collections import json @@ -90,14 +89,14 @@ ON {XH_SQLITE_TABLE_NAME}(inp);""" def _xh_sqlite_get_frequency(cursor, input): # type: (sqlite3.Cursor, str) -> int - sql = "SELECT sum(frequency) FROM {} WHERE inp=?".format(XH_SQLITE_TABLE_NAME) + sql = f"SELECT sum(frequency) FROM {XH_SQLITE_TABLE_NAME} WHERE inp=?" cursor.execute(sql, (input,)) return cursor.fetchone()[0] or 0 def _xh_sqlite_erase_dups(cursor, input): freq = _xh_sqlite_get_frequency(cursor, input) - sql = "DELETE FROM {} WHERE inp=?".format(XH_SQLITE_TABLE_NAME) + sql = f"DELETE FROM {XH_SQLITE_TABLE_NAME} WHERE inp=?" cursor.execute(sql, (input,)) return freq diff --git a/xonsh/imphooks.py b/xonsh/imphooks.py index d1496acae..7f96f2581 100644 --- a/xonsh/imphooks.py +++ b/xonsh/imphooks.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Import hooks for importing xonsh source files. This module registers the hooks it defines when it is imported. @@ -51,7 +50,7 @@ class XonshImportHook(MetaPathFinder, SourceLoader): """Implements the import hook for xonsh source files.""" def __init__(self, *args, **kwargs): - super(XonshImportHook, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._filenames = {} self._execer = None @@ -114,7 +113,7 @@ class XonshImportHook(MetaPathFinder, SourceLoader): """Gets the code object for a xonsh file.""" filename = self.get_filename(fullname) if filename is None: - msg = "xonsh file {0!r} could not be found".format(fullname) + msg = f"xonsh file {fullname!r} could not be found" raise ImportError(msg) src = self.get_source(fullname) execer = self.execer diff --git a/xonsh/inspectors.py b/xonsh/inspectors.py index 1ac5d815b..91c390d54 100644 --- a/xonsh/inspectors.py +++ b/xonsh/inspectors.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tools for inspecting Python objects. This file was forked from the IPython project: @@ -9,7 +8,6 @@ This file was forked from the IPython project: * Copyright (c) 2001, Nathaniel Gray """ import os -import io import sys import types import inspect @@ -104,7 +102,7 @@ def get_encoding(obj): # Print only text files, not extension binaries. Note that # getsourcelines returns lineno with 1-offset and page() uses # 0-offset, so we must adjust. - with io.open(ofile, "rb") as buf: # Tweaked to use io.open for Python 2 + with open(ofile, "rb") as buf: # Tweaked to use io.open for Python 2 encoding, _ = detect_encoding(buf.readline) return encoding @@ -325,7 +323,7 @@ def find_source_lines(obj): return lineno -class Inspector(object): +class Inspector: """Inspects objects.""" def __init__(self, str_detail_level=0): @@ -604,7 +602,7 @@ class Inspector(object): if isalias: if not callable(obj): if len(obj) >= 2 and isinstance(obj[1], str): - ds = "Alias to the system command:\n {0}".format(obj[1]) + ds = f"Alias to the system command:\n {obj[1]}" else: ds = "Alias: " + str(obj) else: diff --git a/xonsh/jobs.py b/xonsh/jobs.py index 4e0eccfc0..793d02281 100644 --- a/xonsh/jobs.py +++ b/xonsh/jobs.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Job control for the xonsh shell.""" import os import sys @@ -284,7 +283,7 @@ def format_job_string(num: int) -> str: cmd = " ".join([" ".join(i) if isinstance(i, list) else i for i in job["cmds"]]) pid = job["pids"][-1] bg = " &" if job["bg"] else "" - return "[{}]{} {}: {}{} ({})".format(num, pos, status, cmd, bg, pid) + return f"[{num}]{pos} {status}: {cmd}{bg} ({pid})" def print_one_job(num, outfile=sys.stdout): @@ -350,7 +349,7 @@ def clean_jobs(): # The Ctrl+D binding for prompt_toolkit already inserts a # newline print() - print("xonsh: {}".format(msg), file=sys.stderr) + print(f"xonsh: {msg}", file=sys.stderr) print("-" * 5, file=sys.stderr) jobs([], stdout=sys.stderr) print("-" * 5, file=sys.stderr) @@ -406,12 +405,12 @@ def resume_job(args, wording): else: tid = int(args[0]) except (ValueError, IndexError): - return "", "Invalid job: {}\n".format(args[0]) + return "", f"Invalid job: {args[0]}\n" if tid not in XSH.all_jobs: - return "", "Invalid job: {}\n".format(args[0]) + return "", f"Invalid job: {args[0]}\n" else: - return "", "{} expects 0 or 1 arguments, not {}\n".format(wording, len(args)) + return "", f"{wording} expects 0 or 1 arguments, not {len(args)}\n" # Put this one on top of the queue tasks.remove(tid) diff --git a/xonsh/jupyter_kernel.py b/xonsh/jupyter_kernel.py index efa02028b..7c68c4eb7 100644 --- a/xonsh/jupyter_kernel.py +++ b/xonsh/jupyter_kernel.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Hooks for Jupyter Xonsh Kernel.""" import sys import json @@ -41,7 +40,7 @@ def bind(socket, connection, port): if port <= 0: return socket.bind_to_random_port(connection) else: - socket.bind("{}:{}".format(connection, port)) + socket.bind(f"{connection}:{port}") return port @@ -112,7 +111,7 @@ class XonshKernel: } else: self.dprint(1, "Loading simple_kernel with args:", sys.argv) - self.dprint(1, "Reading config file {!r}...".format(ns.config_file)) + self.dprint(1, f"Reading config file {ns.config_file!r}...") with open(ns.config_file) as f: config = json.load(f) return config @@ -260,25 +259,25 @@ class XonshKernel: def run_thread(self, loop, name): """Run main thread""" - self.dprint(2, "Starting loop for {name!r}...".format(name=name)) + self.dprint(2, f"Starting loop for {name!r}...") while not self.exiting: - self.dprint(2, "{} Loop!".format(name)) + self.dprint(2, f"{name} Loop!") try: loop.start() except ZMQError as e: - self.dprint(1, "{} ZMQError!\n {}".format(name, e)) + self.dprint(1, f"{name} ZMQError!\n {e}") if e.errno == errno.EINTR: continue else: raise except Exception: - self.dprint(2, "{} Exception!".format(name)) + self.dprint(2, f"{name} Exception!") if self.exiting: break else: raise else: - self.dprint(2, "{} Break!".format(name)) + self.dprint(2, f"{name} Break!") break def heartbeat_loop(self): @@ -352,7 +351,7 @@ class XonshKernel: user_expressions=None, allow_stdin=False, parent_header=None, - **kwargs + **kwargs, ): """Execute user code.""" if len(code.strip()) == 0: diff --git a/xonsh/lazyasd.py b/xonsh/lazyasd.py index cb0c13044..e50bae87c 100644 --- a/xonsh/lazyasd.py +++ b/xonsh/lazyasd.py @@ -14,7 +14,7 @@ import typing as tp __version__ = "0.1.3" -class LazyObject(object): +class LazyObject: def __init__(self, load, ctx, name): """Lazily loads an object via the load function the first time an attribute is accessed. Once loaded it will replace itself in the @@ -200,7 +200,7 @@ def lazydict(f): return LazyDict(f, f.__globals__, f.__name__) -class LazyBool(object): +class LazyBool: def __init__(self, load, ctx, name): """Boolean like object that lazily computes it boolean value when it is first asked. Once loaded, this result will replace itself diff --git a/xonsh/lazyjson.py b/xonsh/lazyjson.py index b95d46082..ca7f54e0b 100644 --- a/xonsh/lazyjson.py +++ b/xonsh/lazyjson.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements a lazy JSON file class that wraps around json data.""" import io import weakref @@ -206,7 +205,7 @@ class LazyJSON(LJNode): self._f = f self.reopen = reopen if not reopen and isinstance(f, str): - self._f = open(f, "r", newline="\n") + self._f = open(f, newline="\n") self._load_index() self.root = weakref.proxy(self) self.is_mapping = isinstance(self.offsets, cabc.Mapping) diff --git a/xonsh/lexer.py b/xonsh/lexer.py index 004cf59dd..6f89abfaf 100644 --- a/xonsh/lexer.py +++ b/xonsh/lexer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Lexer for xonsh code. Written using a hybrid of ``tokenize`` and PLY. @@ -160,7 +159,7 @@ def _end_delimiter(state, token): e = '"{}" at {} ends "{}" at {} (expected "{}")' return e.format(s, (l, c), orig, pos, match) else: - return 'Unmatched "{}" at line {}, column {}'.format(s, l, c) + return f'Unmatched "{s}" at line {l}, column {c}' def handle_rparen(state, token): @@ -361,7 +360,7 @@ def handle_token(state, token): state["last"] = token yield _new_token(token_map[typ], st, token.start) else: - m = "Unexpected token: {0}".format(token) + m = f"Unexpected token: {token}" yield _new_token("ERRORTOKEN", m, token.start) @@ -408,7 +407,7 @@ def _new_token(type, value, pos): return o -class Lexer(object): +class Lexer: """Implements a lexer for the xonsh language.""" _tokens: tp.Optional[tp.Tuple[str, ...]] = None diff --git a/xonsh/lib/collections.py b/xonsh/lib/collections.py index 48332592e..11b7f413d 100644 --- a/xonsh/lib/collections.py +++ b/xonsh/lib/collections.py @@ -7,7 +7,7 @@ from collections.abc import MutableMapping, MutableSequence, MutableSet import typing as tp -class ChainDBDefaultType(object): +class ChainDBDefaultType: """Singleton for representing when no default value is given.""" __inst: tp.Optional["ChainDBDefaultType"] = None @@ -51,7 +51,7 @@ class ChainDB(ChainMap): for result in reversed(results): if result is not ChainDBDefault: return result - raise KeyError("{} is none of the current mappings".format(key)) + raise KeyError(f"{key} is none of the current mappings") return res def __setitem__(self, key, value): diff --git a/xonsh/main.py b/xonsh/main.py index e88273884..65bedef38 100644 --- a/xonsh/main.py +++ b/xonsh/main.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """The main xonsh script.""" import os import sys @@ -115,7 +114,7 @@ def path_argument(s): s = os.path.abspath(os.path.expanduser(s)) if not os.path.exists(s): - msg = "{0!r} must be a valid path to a file or directory".format(s) + msg = f"{s!r} must be a valid path to a file or directory" raise argparse.ArgumentTypeError(msg) return s @@ -422,7 +421,7 @@ def _failback_to_other_shells(args, err): if foreign_shell: traceback.print_exc() print("Xonsh encountered an issue during launch", file=sys.stderr) - print("Failback to {}".format(foreign_shell), file=sys.stderr) + print(f"Failback to {foreign_shell}", file=sys.stderr) os.execlp(foreign_shell, foreign_shell) else: raise err @@ -494,7 +493,7 @@ def main_xonsh(args): args.file, shell.execer, glb=shell.ctx, loc=None, mode="exec" ) else: - print("xonsh: {0}: No such file or directory.".format(args.file)) + print(f"xonsh: {args.file}: No such file or directory.") exit_code = 1 elif args.mode == XonshMode.script_from_stdin: # run a script given on stdin diff --git a/xonsh/openpy.py b/xonsh/openpy.py index b67eafa13..d672bcb30 100644 --- a/xonsh/openpy.py +++ b/xonsh/openpy.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Tools to open ``*.py`` files as Unicode. Uses the encoding specified within the file, as per PEP 263. @@ -48,7 +47,7 @@ def source_to_unicode(txt, errors="replace", skip_encoding_cookie=True): text = io.TextIOWrapper(buf, encoding, errors=errors, line_buffering=True) text.mode = "r" if skip_encoding_cookie: - return u"".join(strip_encoding_cookie(text)) + return "".join(strip_encoding_cookie(text)) else: return text.read() @@ -67,8 +66,7 @@ def strip_encoding_cookie(filelike): yield second except StopIteration: return - for line in it: - yield line + yield from it def read_py_file(filename, skip_encoding_cookie=True): diff --git a/xonsh/parser.py b/xonsh/parser.py index fcbb6f390..783da21a6 100644 --- a/xonsh/parser.py +++ b/xonsh/parser.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements the xonsh parser.""" from xonsh.lazyasd import lazyobject from xonsh.platform import PYTHON_VERSION_INFO diff --git a/xonsh/parsers/base.py b/xonsh/parsers/base.py index 528fbaf45..aa593ffee 100644 --- a/xonsh/parsers/base.py +++ b/xonsh/parsers/base.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements the base xonsh parser.""" import os import re @@ -27,7 +26,7 @@ RE_STRINGPREFIX = LazyObject( ) -class Location(object): +class Location: """Location in a file.""" def __init__(self, fname, lineno, column=None): @@ -37,9 +36,9 @@ class Location(object): self.column = column def __str__(self): - s = "{0}:{1}".format(self.fname, self.lineno) + s = f"{self.fname}:{self.lineno}" if self.column is not None: - s += ":{0}".format(self.column) + s += f":{self.column}" return s @@ -233,7 +232,7 @@ def raise_parse_error( err_line_pointer = "\n{}\n{: >{}}".format(err_line, "^", col) else: err_line_pointer = "" - err = SyntaxError("{0}: {1}{2}".format(loc, msg, err_line_pointer)) + err = SyntaxError(f"{loc}: {msg}{err_line_pointer}") err.loc = loc # type: ignore raise err @@ -252,7 +251,7 @@ class YaccLoader(Thread): self.parser.parser = yacc.yacc(**self.yacc_kwargs) -class BaseParser(object): +class BaseParser: """A base class that parses the xonsh language.""" def __init__( @@ -579,9 +578,9 @@ class BaseParser(object): elif t is not None and t.type == uprule: p[0] = t else: - raise TypeError("token for {0!r} not found.".format(rulename)) + raise TypeError(f"token for {rulename!r} not found.") - tokfunc.__doc__ = "{0}_tok : {1}".format(rulename, rulename.upper()) + tokfunc.__doc__ = f"{rulename}_tok : {rulename.upper()}" tokfunc.__name__ = "p_" + rulename + "_tok" setattr(self.__class__, tokfunc.__name__, tokfunc) @@ -1204,7 +1203,7 @@ class BaseParser(object): op = self._augassign_op[p2] if op is None: self._set_error( - "operation {0!r} not supported".format(p2), + f"operation {p2!r} not supported", self.currloc(lineno=p.lineno, column=p.lexpos), ) p[0] = ast.AugAssign( @@ -2152,7 +2151,7 @@ class BaseParser(object): op = self._term_binops[p1.value] if op is None: self._set_error( - "operation {0!r} not supported".format(p1), + f"operation {p1!r} not supported", self.currloc(lineno=p.lineno, column=p.lexpos), ) p[0] = [op(lineno=p1.lineno, col_offset=p1.lexpos), p[2]] @@ -3398,7 +3397,7 @@ class BaseParser(object): "ATDOLLAR_LPAREN", "AMPERSAND", } - ts = "\n | ".join(sorted([t.lower() + "_tok" for t in toks])) + ts = "\n | ".join(sorted(t.lower() + "_tok" for t in toks)) doc = "subproc_arg_part : " + ts + "\n" self.p_subproc_arg_part.__func__.__doc__ = doc @@ -3455,5 +3454,5 @@ class BaseParser(object): p.value, self.currloc(lineno=p.lineno, column=p.lexpos) ) else: - msg = ("code: {0}".format(p.value),) + msg = (f"code: {p.value}",) self._parse_error(msg, self.currloc(lineno=p.lineno, column=p.lexpos)) diff --git a/xonsh/parsers/completion_context.py b/xonsh/parsers/completion_context.py index 013848a96..5f65b0a6b 100644 --- a/xonsh/parsers/completion_context.py +++ b/xonsh/parsers/completion_context.py @@ -748,7 +748,7 @@ class CompletionContextParser: raise_parse_error("no further code") raise_parse_error( - "code: {0}".format(p.value), + f"code: {p.value}", Location("input", p.lineno, p.lexpos - self.line_indices[p.lineno - 1]), self.current_input, self.current_input.splitlines(keepends=True), diff --git a/xonsh/parsers/context_check.py b/xonsh/parsers/context_check.py index a3f34f7e9..5b5c775da 100644 --- a/xonsh/parsers/context_check.py +++ b/xonsh/parsers/context_check.py @@ -66,7 +66,7 @@ class ContextCheckingVisitor(ast.NodeVisitor): for i in node.targets: err = _not_assignable(i) if err is not None: - msg = "can't delete {}".format(err) + msg = f"can't delete {err}" self.error = msg, i.lineno, i.col_offset break @@ -74,12 +74,12 @@ class ContextCheckingVisitor(ast.NodeVisitor): for i in node.targets: err = _not_assignable(i) if err is not None: - msg = "can't assign to {}".format(err) + msg = f"can't assign to {err}" self.error = msg, i.lineno, i.col_offset break def visit_AugAssign(self, node): err = _not_assignable(node.target, True) if err is not None: - msg = "illegal target for augmented assignment: {}".format(err) + msg = f"illegal target for augmented assignment: {err}" self.error = msg, node.target.lineno, node.target.col_offset diff --git a/xonsh/parsers/fstring_adaptor.py b/xonsh/parsers/fstring_adaptor.py index 89fb2ab0f..df6cb1ced 100644 --- a/xonsh/parsers/fstring_adaptor.py +++ b/xonsh/parsers/fstring_adaptor.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements helper class for parsing Xonsh syntax within f-strings.""" import re from ast import parse as pyparse diff --git a/xonsh/parsers/v36.py b/xonsh/parsers/v36.py index 44f4ec19b..f00b49c7d 100644 --- a/xonsh/parsers/v36.py +++ b/xonsh/parsers/v36.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements the xonsh parser for Python v3.6.""" import xonsh.ast as ast from xonsh.parsers.base import store_ctx, lopen_loc, BaseParser diff --git a/xonsh/parsers/v38.py b/xonsh/parsers/v38.py index f022dd0f5..cd1358d2a 100644 --- a/xonsh/parsers/v38.py +++ b/xonsh/parsers/v38.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Implements the xonsh parser for Python v3.8.""" import xonsh.ast as ast from xonsh.parsers.v36 import Parser as ThreeSixParser diff --git a/xonsh/parsers/v39.py b/xonsh/parsers/v39.py index 4023a843d..ddf8b3d44 100644 --- a/xonsh/parsers/v39.py +++ b/xonsh/parsers/v39.py @@ -27,7 +27,7 @@ class Parser(ThreeEightParser): if isinstance(p1, Index): p1 = p1.value is_subscript = True - if any((isinstance(p, Index) for p in p2)): + if any(isinstance(p, Index) for p in p2): is_subscript = True after_comma = [p.value if isinstance(p, Index) else p for p in p2] diff --git a/xonsh/platform.py b/xonsh/platform.py index 398ee0114..782e91aa5 100644 --- a/xonsh/platform.py +++ b/xonsh/platform.py @@ -303,7 +303,7 @@ CC = 6 def githash(): """Returns a tuple contains two strings: the hash and the date.""" install_base = os.path.dirname(__file__) - githash_file = "{}/dev.githash".format(install_base) + githash_file = f"{install_base}/dev.githash" if not os.path.exists(githash_file): return None, None sha = None @@ -417,7 +417,7 @@ if ON_WINDOWS: def __init__(self): import nt - self._upperkeys = dict((k.upper(), k) for k in nt.environ) + self._upperkeys = {k.upper(): k for k in nt.environ} def _sync(self): """Ensure that the case sensitive map of the keys are diff --git a/xonsh/pretty.py b/xonsh/pretty.py index 64a71eb89..23013a9df 100644 --- a/xonsh/pretty.py +++ b/xonsh/pretty.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Python advanced pretty printer. This pretty printer is intended to replace the old `pprint` python module which does not allow developers @@ -146,7 +145,7 @@ def pretty_print( sys.stdout.flush() -class _PrettyPrinterBase(object): +class _PrettyPrinterBase: @contextlib.contextmanager def indent(self, indent): """with statement support for indenting/dedenting.""" @@ -421,7 +420,7 @@ class RepresentationPrinter(PrettyPrinter): return printer -class Printable(object): +class Printable: def output(self, stream, output_width): return output_width @@ -469,7 +468,7 @@ class Group(Printable): self.want_break = False -class GroupQueue(object): +class GroupQueue: def __init__(self, *groups): self.queue = [] for group in groups: @@ -753,7 +752,7 @@ def _exception_pprint(obj, p, cycle): """Base pprint for all exceptions.""" name = getattr(obj.__class__, "__qualname__", obj.__class__.__name__) if obj.__class__.__module__ not in ("exceptions", "builtins"): - name = "%s.%s" % (obj.__class__.__module__, name) + name = f"{obj.__class__.__module__}.{name}" step = len(name) + 1 p.begin_group(step, name + "(") for idx, arg in enumerate(getattr(obj, "args", ())): diff --git a/xonsh/procs/posix.py b/xonsh/procs/posix.py index b73e062fa..b21266ac9 100644 --- a/xonsh/procs/posix.py +++ b/xonsh/procs/posix.py @@ -28,12 +28,12 @@ MODE_NUMS = ("1049", "47", "1047") @xl.lazyobject def START_ALTERNATE_MODE(): - return frozenset("\x1b[?{0}h".format(i).encode() for i in MODE_NUMS) + return frozenset(f"\x1b[?{i}h".encode() for i in MODE_NUMS) @xl.lazyobject def END_ALTERNATE_MODE(): - return frozenset("\x1b[?{0}l".format(i).encode() for i in MODE_NUMS) + return frozenset(f"\x1b[?{i}l".encode() for i in MODE_NUMS) @xl.lazyobject diff --git a/xonsh/procs/proxies.py b/xonsh/procs/proxies.py index 2eb9a64e4..4e75ae873 100644 --- a/xonsh/procs/proxies.py +++ b/xonsh/procs/proxies.py @@ -426,21 +426,21 @@ class ProcProxyThread(threading.Thread): self.errread = xli.msvcrt.open_osfhandle(self.errread.Detach(), 0) if self.p2cwrite != -1: - self.stdin = io.open(self.p2cwrite, "wb", -1) + self.stdin = open(self.p2cwrite, "wb", -1) if universal_newlines: self.stdin = io.TextIOWrapper( self.stdin, write_through=True, line_buffering=False ) elif isinstance(stdin, int) and stdin != 0: - self.stdin = io.open(stdin, "wb", -1) + self.stdin = open(stdin, "wb", -1) if self.c2pread != -1: - self.stdout = io.open(self.c2pread, "rb", -1) + self.stdout = open(self.c2pread, "rb", -1) if universal_newlines: self.stdout = io.TextIOWrapper(self.stdout) if self.errread != -1: - self.stderr = io.open(self.errread, "rb", -1) + self.stderr = open(self.errread, "rb", -1) if universal_newlines: self.stderr = io.TextIOWrapper(self.stderr) @@ -487,14 +487,14 @@ class ProcProxyThread(threading.Thread): sp_stdin = None elif self.p2cread != -1: sp_stdin = io.TextIOWrapper( - io.open(self.p2cread, "rb", -1), encoding=enc, errors=err + open(self.p2cread, "rb", -1), encoding=enc, errors=err ) else: sp_stdin = sys.stdin # stdout if self.c2pwrite != -1: sp_stdout = io.TextIOWrapper( - io.open(self.c2pwrite, "wb", -1), encoding=enc, errors=err + open(self.c2pwrite, "wb", -1), encoding=enc, errors=err ) else: sp_stdout = sys.stdout @@ -503,7 +503,7 @@ class ProcProxyThread(threading.Thread): sp_stderr = sp_stdout elif self.errwrite != -1: sp_stderr = io.TextIOWrapper( - io.open(self.errwrite, "wb", -1), encoding=enc, errors=err + open(self.errwrite, "wb", -1), encoding=enc, errors=err ) else: sp_stderr = sys.stderr @@ -809,7 +809,7 @@ class ProcProxy: stdin = None else: if isinstance(self.stdin, int): - inbuf = io.open(self.stdin, "rb", -1) + inbuf = open(self.stdin, "rb", -1) else: inbuf = self.stdin stdin = io.TextIOWrapper(inbuf, encoding=enc, errors=err) @@ -835,9 +835,7 @@ class ProcProxy: if handle < 3: buf = sysbuf else: - buf = io.TextIOWrapper( - io.open(handle, "wb", -1), encoding=enc, errors=err - ) + buf = io.TextIOWrapper(open(handle, "wb", -1), encoding=enc, errors=err) elif hasattr(handle, "encoding"): # must be a text stream, no need to wrap. buf = handle diff --git a/xonsh/procs/specs.py b/xonsh/procs/specs.py index 6aa28e34a..f3909b075 100644 --- a/xonsh/procs/specs.py +++ b/xonsh/procs/specs.py @@ -164,16 +164,12 @@ def _REDIR_OUT(): @xl.lazyobject def _E2O_MAP(): - return frozenset( - {"{}>{}".format(e, o) for e in _REDIR_ERR for o in _REDIR_OUT if o != ""} - ) + return frozenset({f"{e}>{o}" for e in _REDIR_ERR for o in _REDIR_OUT if o != ""}) @xl.lazyobject def _O2E_MAP(): - return frozenset( - {"{}>{}".format(o, e) for e in _REDIR_ERR for o in _REDIR_OUT if o != ""} - ) + return frozenset({f"{o}>{e}" for e in _REDIR_ERR for o in _REDIR_OUT if o != ""}) def _is_redirect(x): @@ -184,7 +180,7 @@ def safe_open(fname, mode, buffering=-1): """Safely attempts to open a file in for xonsh subprocs.""" # file descriptors try: - return io.open(fname, mode, buffering=buffering) + return open(fname, mode, buffering=buffering) except PermissionError: raise xt.XonshError(f"xonsh: {fname}: permission denied") except FileNotFoundError: @@ -486,7 +482,7 @@ class SubprocSpec: return self.cls( ["man", cmd0.rstrip("?")], bufsize=bufsize, **kwargs ) - e = "xonsh: subprocess mode: command not found: {0}".format(cmd0) + e = f"xonsh: subprocess mode: command not found: {cmd0}" env = XSH.env sug = xt.suggest_commands(cmd0, env) if len(sug.strip()) > 0: diff --git a/xonsh/prompt/base.py b/xonsh/prompt/base.py index 87f66eecf..01c6f70ba 100644 --- a/xonsh/prompt/base.py +++ b/xonsh/prompt/base.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Base prompt, provides PROMPT_FIELDS and prompt related functions""" import itertools @@ -146,7 +145,7 @@ class PromptFormatter: except Exception: print("prompt: error: on field {!r}" "".format(field), file=sys.stderr) xt.print_exception() - value = "{{BACKGROUND_RED}}{{ERROR:{}}}{{RESET}}".format(field) + value = f"{{BACKGROUND_RED}}{{ERROR:{field}}}{{RESET}}" return value @@ -267,7 +266,7 @@ def is_template_string(template, PROMPT_FIELDS=None): """Returns whether or not the string is a valid template.""" template = template() if callable(template) else template try: - included_names = set(i[1] for i in xt.FORMATTER.parse(template)) + included_names = {i[1] for i in xt.FORMATTER.parse(template)} except ValueError: return False included_names.discard(None) diff --git a/xonsh/prompt/cwd.py b/xonsh/prompt/cwd.py index 32d1685bb..ad891b2be 100644 --- a/xonsh/prompt/cwd.py +++ b/xonsh/prompt/cwd.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """CWD related prompt formatter""" import os diff --git a/xonsh/prompt/env.py b/xonsh/prompt/env.py index 17f866eed..3d6d3473e 100644 --- a/xonsh/prompt/env.py +++ b/xonsh/prompt/env.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Prompt formatter for virtualenv and others""" import os diff --git a/xonsh/prompt/gitstatus.py b/xonsh/prompt/gitstatus.py index ee5dea35f..41f952f24 100644 --- a/xonsh/prompt/gitstatus.py +++ b/xonsh/prompt/gitstatus.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Informative git status prompt formatter""" import os import subprocess @@ -112,7 +111,7 @@ def _get_stash(gitdir): try: with open(os.path.join(gitdir, "logs/refs/stash")) as f: return sum(1 for _ in f) - except IOError: + except OSError: return 0 @@ -263,7 +262,7 @@ def gitstatus_prompt(): value = fields[fld] if symbol and value > 0: ret += symbol + str(value) + COLORS.RESET - if sum((fields.get(fld, 0) for fld in number_flds)) == 0 and not _is_hidden( + if sum(fields.get(fld, 0) for fld in number_flds) == 0 and not _is_hidden( _DEFS.CLEAN ): symbol = _get_def(_DEFS.CLEAN) diff --git a/xonsh/prompt/job.py b/xonsh/prompt/job.py index b4d1be4b6..97313e0ac 100644 --- a/xonsh/prompt/job.py +++ b/xonsh/prompt/job.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Prompt formatter for current jobs""" import xonsh.jobs as xj diff --git a/xonsh/prompt/times.py b/xonsh/prompt/times.py index eb5af8340..ff6ece84c 100644 --- a/xonsh/prompt/times.py +++ b/xonsh/prompt/times.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """date & time related prompt formatter""" import time diff --git a/xonsh/prompt/vc.py b/xonsh/prompt/vc.py index 9d4d5c520..5fe743086 100644 --- a/xonsh/prompt/vc.py +++ b/xonsh/prompt/vc.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Prompt formatter for simple version control branches""" # pylint:disable=no-member, invalid-name @@ -96,7 +95,7 @@ def get_hg_branch(root=None): # get branch name branch_path = root / ".hg" / "branch" if branch_path.exists(): - with open(branch_path, "r") as branch_file: + with open(branch_path) as branch_file: branch = branch_file.read().strip() else: branch = "default" diff --git a/xonsh/ptk_shell/completer.py b/xonsh/ptk_shell/completer.py index 287eb80a9..9ecca60bd 100644 --- a/xonsh/ptk_shell/completer.py +++ b/xonsh/ptk_shell/completer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Completer implementation to use with prompt_toolkit.""" import os diff --git a/xonsh/ptk_shell/history.py b/xonsh/ptk_shell/history.py index 965253ec1..182cf890a 100644 --- a/xonsh/ptk_shell/history.py +++ b/xonsh/ptk_shell/history.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """History object for use with prompt_toolkit.""" import prompt_toolkit.history diff --git a/xonsh/ptk_shell/key_bindings.py b/xonsh/ptk_shell/key_bindings.py index 0f40446a7..cc5c58c5f 100644 --- a/xonsh/ptk_shell/key_bindings.py +++ b/xonsh/ptk_shell/key_bindings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Key bindings for prompt_toolkit xonsh shell.""" from prompt_toolkit import search diff --git a/xonsh/ptk_shell/shell.py b/xonsh/ptk_shell/shell.py index 1c50420d8..27ff96598 100644 --- a/xonsh/ptk_shell/shell.py +++ b/xonsh/ptk_shell/shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """The prompt_toolkit based xonsh shell.""" import os import re diff --git a/xonsh/pyghooks.py b/xonsh/pyghooks.py index 33d82ba4d..0bb5e3cf0 100644 --- a/xonsh/pyghooks.py +++ b/xonsh/pyghooks.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Hooks for pygments syntax highlighting.""" import os import re @@ -170,7 +169,7 @@ def color_name_to_pygments_code(name, styles): return styles[token] m = RE_XONSH_COLOR.match(name) if m is None: - raise ValueError("{!r} is not a color!".format(name)) + raise ValueError(f"{name!r} is not a color!") parts = m.groupdict() # convert regex match into actual pygments colors if parts["reset"] is not None: @@ -390,7 +389,7 @@ class XonshStyle(Style): pygments_style_by_name(value) except Exception: print( - "Could not find style {0!r}, using default".format(value), + f"Could not find style {value!r}, using default", file=sys.stderr, ) value = "default" @@ -1738,7 +1737,7 @@ class XonshLexer(Python3Lexer): with root or subproc state""" start = 0 state = ("root",) - m = re.match(r"(\s*)({})".format(COMMAND_TOKEN_RE), text) + m = re.match(fr"(\s*)({COMMAND_TOKEN_RE})", text) if m is not None: yield m.start(1), Whitespace, m.group(1) start = m.end(1) diff --git a/xonsh/pygments_cache.py b/xonsh/pygments_cache.py index b41654dc6..9eb37ab83 100644 --- a/xonsh/pygments_cache.py +++ b/xonsh/pygments_cache.py @@ -28,7 +28,7 @@ def _print_duplicate_message(duplicates): import sys for filename, vals in sorted(duplicates.items()): - msg = "for {0} ambiquity between:\n ".format(filename) + msg = f"for {filename} ambiquity between:\n " vals = [m + ":" + c for m, c in vals] msg += "\n ".join(sorted(vals)) print(msg, file=sys.stderr) diff --git a/xonsh/pytest_plugin.py b/xonsh/pytest_plugin.py index 216d28608..c62c8e3be 100644 --- a/xonsh/pytest_plugin.py +++ b/xonsh/pytest_plugin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Pytest plugin for testing xsh files.""" import sys import importlib @@ -71,8 +70,8 @@ class XshFunction(pytest.Item): """called when self.runtest() raises an exception.""" formatted_tb = _limited_traceback(excinfo) formatted_tb.insert(0, "xonsh execution failed\n") - formatted_tb.append("{}: {}".format(excinfo.type.__name__, excinfo.value)) + formatted_tb.append(f"{excinfo.type.__name__}: {excinfo.value}") return "".join(formatted_tb) def reportinfo(self): - return self.fspath, 0, "xonsh test: {}".format(self.name) + return self.fspath, 0, f"xonsh test: {self.name}" diff --git a/xonsh/readline_shell.py b/xonsh/readline_shell.py index e63d54bf5..fe8a69891 100644 --- a/xonsh/readline_shell.py +++ b/xonsh/readline_shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """The readline based xonsh shell. Portions of this code related to initializing the readline library @@ -117,7 +116,7 @@ def setup_readline(): readline.parse_and_bind('"\\e[B": history-search-forward') readline.parse_and_bind('"\\e[A": history-search-backward') # Setup Shift-Tab to indent - readline.parse_and_bind('"\\e[Z": "{0}"'.format(env.get("INDENT"))) + readline.parse_and_bind('"\\e[Z": "{}"'.format(env.get("INDENT"))) # handle tab completion differences found in libedit readline compatibility # as discussed at http://stackoverflow.com/a/7116997 @@ -405,7 +404,7 @@ class ReadlineShell(BaseShell, cmd.Cmd): return 1 elif len(completions) <= XSH.env.get("COMPLETION_QUERY_LIMIT"): return 2 - msg = "\nDisplay all {} possibilities? ".format(len(completions)) + msg = f"\nDisplay all {len(completions)} possibilities? " msg += "({GREEN}y{RESET} or {RED}n{RESET})" self.print_color(msg, end="", flush=True, file=sys.stderr) yn = "x" @@ -701,7 +700,7 @@ class ReadlineHistoryAdder(threading.Thread): current readline instance. May wait for the history garbage collector to finish. """ - super(ReadlineHistoryAdder, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.daemon = True self.wait_for_gc = wait_for_gc self.start() diff --git a/xonsh/shell.py b/xonsh/shell.py index d7d72158d..e9ea0e077 100644 --- a/xonsh/shell.py +++ b/xonsh/shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """The xonsh shell""" import sys import time @@ -118,7 +117,7 @@ def transform_command(src, show_diff=True): return src -class Shell(object): +class Shell: """Main xonsh shell. Initializes execution environment and decides if prompt_toolkit or @@ -230,7 +229,7 @@ class Shell(object): elif shell_type == "dumb": from xonsh.dumb_shell import DumbShell as shell_class else: - raise XonshError("{} is not recognized as a shell type".format(shell_type)) + raise XonshError(f"{shell_type} is not recognized as a shell type") self.shell = shell_class(execer=self.execer, ctx=self.ctx, **kwargs) # allows history garbage collector to start running if hist.gc is not None: diff --git a/xonsh/timings.py b/xonsh/timings.py index fa95576fc..50a7e0fed 100644 --- a/xonsh/timings.py +++ b/xonsh/timings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Timing related functionality for the xonsh shell. The following time_it alias and Timer was forked from the IPython project: @@ -117,7 +116,7 @@ def format_time(timespan, precision=3): value = int(leftover / length) if value > 0: leftover = leftover % length - time.append("{0}{1}".format(str(value), suffix)) + time.append(f"{str(value)}{suffix}") if leftover < 1: break return " ".join(time) @@ -230,18 +229,18 @@ def timeit_alias(args, stdin=None): if worst > 4 * best and best > 0 and worst > 1e-5: print( ( - "The slowest run took {0:0.2f} times longer than the " + "The slowest run took {:0.2f} times longer than the " "fastest. This could mean that an intermediate result " "is being cached." ).format(worst / best) ) print( - "{0} loops, best of {1}: {2} per loop".format( + "{} loops, best of {}: {} per loop".format( number, repeat, format_time(best, precision) ) ) if tc > tc_min: - print("Compiler time: {0:.2f} s".format(tc)) + print(f"Compiler time: {tc:.2f} s") return @@ -327,8 +326,8 @@ def setup_timings(argv): times = list(_timings.items()) times = sorted(times, key=lambda x: x[1]) width = max(len(s) for s, _ in times) + 2 - header_format = "|{{:<{}}}|{{:^11}}|{{:^11}}|".format(width) - entry_format = "|{{:<{}}}|{{:^11.3f}}|{{:^11.3f}}|".format(width) + header_format = f"|{{:<{width}}}|{{:^11}}|{{:^11}}|" + entry_format = f"|{{:<{width}}}|{{:^11.3f}}|{{:^11.3f}}|" sepline = "|{}|{}|{}|".format("-" * width, "-" * 11, "-" * 11) # Print result table print(" Debug level: {}".format(os.getenv("XONSH_DEBUG", "Off"))) diff --git a/xonsh/tokenize.py b/xonsh/tokenize.py index ae7c874cd..feb1a2243 100644 --- a/xonsh/tokenize.py +++ b/xonsh/tokenize.py @@ -329,11 +329,11 @@ _redir_map = ( "o>2", "1>2", ) -IORedirect = group(group(*_redir_map), "{}>>?".format(group(*_redir_names))) +IORedirect = group(group(*_redir_map), f"{group(*_redir_names)}>>?") _redir_check_0 = set(_redir_map) -_redir_check_1 = {"{}>".format(i) for i in _redir_names}.union(_redir_check_0) -_redir_check_2 = {"{}>>".format(i) for i in _redir_names}.union(_redir_check_1) +_redir_check_1 = {f"{i}>" for i in _redir_names}.union(_redir_check_0) +_redir_check_2 = {f"{i}>>" for i in _redir_names}.union(_redir_check_1) _redir_check = frozenset(_redir_check_2) Operator = group( @@ -788,7 +788,7 @@ def detect_encoding(readline): except UnicodeDecodeError: msg = "invalid or missing encoding declaration" if filename is not None: - msg = "{} for {!r}".format(msg, filename) + msg = f"{msg} for {filename!r}" raise SyntaxError(msg) match = cookie_re.match(line_string) @@ -802,7 +802,7 @@ def detect_encoding(readline): if filename is None: msg = "unknown encoding: " + encoding else: - msg = "unknown encoding for {!r}: {}".format(filename, encoding) + msg = f"unknown encoding for {filename!r}: {encoding}" raise SyntaxError(msg) if bom_found: @@ -811,7 +811,7 @@ def detect_encoding(readline): if filename is None: msg = "encoding problem: utf-8" else: - msg = "encoding problem for {!r}: utf-8".format(filename) + msg = f"encoding problem for {filename!r}: utf-8" raise SyntaxError(msg) encoding += "-sig" return encoding @@ -1177,7 +1177,7 @@ def tokenize_main(): args = (filename,) + location + (message,) perror("%s:%d:%d: error: %s" % args) elif filename: - perror("%s: error: %s" % (filename, message)) + perror(f"{filename}: error: {message}") else: perror("error: %s" % message) sys.exit(1) diff --git a/xonsh/tools.py b/xonsh/tools.py index 4548ba674..43926da01 100644 --- a/xonsh/tools.py +++ b/xonsh/tools.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Misc. xonsh tools. The following implementations were forked from the IPython project: @@ -294,7 +293,7 @@ def FORMATTER(): return string.Formatter() -class DefaultNotGivenType(object): +class DefaultNotGivenType: """Singleton for representing when no default value is given.""" __inst: tp.Optional["DefaultNotGivenType"] = None @@ -904,7 +903,7 @@ def suggest_commands(cmd, env): for _cmd in xsh.commands_cache.all_commands: if _cmd not in suggested: if levenshtein(_cmd.lower(), cmd, thresh) < thresh: - suggested[_cmd] = "Command ({0})".format(_cmd) + suggested[_cmd] = f"Command ({_cmd})" suggested = collections.OrderedDict( sorted( @@ -917,13 +916,13 @@ def suggest_commands(cmd, env): rtn = command_not_found(cmd, env) else: oneof = "" if num == 1 else "one of " - tips = "Did you mean {}the following?".format(oneof) + tips = f"Did you mean {oneof}the following?" items = list(suggested.popitem(False) for _ in range(num)) length = max(len(key) for key, _ in items) + 2 alternatives = "\n".join( " {: <{}} {}".format(key + ":", length, val) for key, val in items ) - rtn = "{}\n{}".format(tips, alternatives) + rtn = f"{tips}\n{alternatives}" c = command_not_found(cmd, env) rtn += ("\n\n" + c) if len(c) > 0 else "" return rtn @@ -1448,12 +1447,12 @@ def ensure_slice(x): groups = (int(i) if i else None for i in m.groups()) s = slice(*groups) else: - raise ValueError("cannot convert {!r} to slice".format(x)) + raise ValueError(f"cannot convert {x!r} to slice") except TypeError: try: s = slice(*(int(i) for i in x)) except (TypeError, ValueError): - raise ValueError("cannot convert {!r} to slice".format(x)) + raise ValueError(f"cannot convert {x!r} to slice") return s @@ -1616,7 +1615,7 @@ def ptk2_color_depth_setter(x): elif x in {"", None}: x = "" else: - msg = '"{}" is not a valid value for $PROMPT_TOOLKIT_COLOR_DEPTH. '.format(x) + msg = f'"{x}" is not a valid value for $PROMPT_TOOLKIT_COLOR_DEPTH. ' warnings.warn(msg, RuntimeWarning) x = "" if x == "" and "PROMPT_TOOLKIT_COLOR_DEPTH" in os_environ: @@ -1641,7 +1640,7 @@ def to_completions_display_value(x): elif x in {"single", "readline"}: pass else: - msg = '"{}" is not a valid value for $COMPLETIONS_DISPLAY. '.format(x) + msg = f'"{x}" is not a valid value for $COMPLETIONS_DISPLAY. ' msg += 'Using "multi".' warnings.warn(msg, RuntimeWarning) x = "multi" @@ -1689,7 +1688,7 @@ def to_dict(x): try: x = ast.literal_eval(x) except (ValueError, SyntaxError): - msg = '"{}" can not be converted to Python dictionary.'.format(x) + msg = f'"{x}" can not be converted to Python dictionary.' warnings.warn(msg, RuntimeWarning) x = dict() return x @@ -1701,7 +1700,7 @@ def to_str_str_dict(x): return x x = to_dict(x) if not is_str_str_dict(x): - msg = '"{}" can not be converted to str:str dictionary.'.format(x) + msg = f'"{x}" can not be converted to str:str dictionary.' warnings.warn(msg, RuntimeWarning) x = dict() return x @@ -1862,7 +1861,7 @@ def to_history_tuple(x): def history_tuple_to_str(x): """Converts a valid history tuple to a canonical string.""" - return "{0} {1}".format(*x) + return "{} {}".format(*x) def all_permutations(iterable): @@ -2040,9 +2039,7 @@ def _win10_color_map(): "ansibrightyellow": (249, 241, 165), "ansiwhite": (242, 242, 242), } - return { - k: "#{0:02x}{1:02x}{2:02x}".format(r, g, b) for k, (r, g, b) in cmap.items() - } + return {k: f"#{r:02x}{g:02x}{b:02x}" for k, (r, g, b) in cmap.items()} WIN10_COLOR_MAP = LazyObject(_win10_color_map, globals(), "WIN10_COLOR_MAP") @@ -2373,7 +2370,7 @@ def backup_file(fname): base, ext = os.path.splitext(fname) timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S-%f") - newfname = "%s.%s%s" % (base, timestamp, ext) + newfname = f"{base}.{timestamp}{ext}" shutil.move(fname, newfname) @@ -2416,11 +2413,11 @@ def expand_case_matching(s): elif c.isalpha(): folded = c.casefold() if len(folded) == 1: - c = "[{0}{1}]".format(c.upper(), c.lower()) + c = f"[{c.upper()}{c.lower()}]" else: - newc = ["[{0}{1}]?".format(f.upper(), f.lower()) for f in folded[:-1]] + newc = [f"[{f.upper()}{f.lower()}]?" for f in folded[:-1]] newc = "".join(newc) - newc += "[{0}{1}{2}]".format(folded[-1].upper(), folded[-1].lower(), c) + newc += f"[{folded[-1].upper()}{folded[-1].lower()}{c}]" c = newc t.append(c) return "".join(t) @@ -2614,7 +2611,7 @@ def deprecated(deprecated_in=None, removed_in=None): message_suffix = "" def decorated(func): - warning_message = "{} has been deprecated".format(func.__name__) + warning_message = f"{func.__name__} has been deprecated" warning_message += message_suffix @functools.wraps(func) @@ -2624,7 +2621,7 @@ def deprecated(deprecated_in=None, removed_in=None): warnings.warn(warning_message, DeprecationWarning) wrapped.__doc__ = ( - "{}\n\n{}".format(wrapped.__doc__, warning_message) + f"{wrapped.__doc__}\n\n{warning_message}" if wrapped.__doc__ else warning_message ) @@ -2640,9 +2637,9 @@ def _deprecated_message_suffix(deprecated_in, removed_in): deprecated_in, removed_in ) elif deprecated_in and not removed_in: - message_suffix = " in version {}".format(deprecated_in) + message_suffix = f" in version {deprecated_in}" elif not deprecated_in and removed_in: - message_suffix = " and will be removed in version {}".format(removed_in) + message_suffix = f" and will be removed in version {removed_in}" else: message_suffix = None @@ -2655,13 +2652,11 @@ def _deprecated_error_on_expiration(name, removed_in): if not removed_in: return elif LooseVersion(__version__) >= LooseVersion(removed_in): - raise AssertionError( - "{} has passed its version {} expiry date!".format(name, removed_in) - ) + raise AssertionError(f"{name} has passed its version {removed_in} expiry date!") def to_repr_pretty_(inst, p, cycle): - name = "{0}.{1}".format(inst.__class__.__module__, inst.__class__.__name__) + name = f"{inst.__class__.__module__}.{inst.__class__.__name__}" with p.group(0, name + "(", ")"): if cycle: p.text("...") diff --git a/xonsh/tracer.py b/xonsh/tracer.py index 859ad090d..e22c19122 100644 --- a/xonsh/tracer.py +++ b/xonsh/tracer.py @@ -23,7 +23,7 @@ terminal = LazyObject( ) -class TracerType(object): +class TracerType: """Represents a xonsh tracer object, which keeps track of all tracing state. This is a singleton. """ @@ -33,7 +33,7 @@ class TracerType(object): def __new__(cls, *args, **kwargs): if cls._inst is None: - cls._inst = super(TracerType, cls).__new__(cls, *args, **kwargs) + cls._inst = super().__new__(cls, *args, **kwargs) return cls._inst def __init__(self): diff --git a/xonsh/webconfig/main.py b/xonsh/webconfig/main.py index f00cfdc90..15c80cd66 100644 --- a/xonsh/webconfig/main.py +++ b/xonsh/webconfig/main.py @@ -2,7 +2,6 @@ import os import sys import json -import socket import socketserver from http import server from pprint import pprint @@ -27,7 +26,7 @@ def colors(config): style = config["colors"] if style == "default": return [] - return ["$XONSH_COLOR_STYLE = {!r}".format(style)] + return [f"$XONSH_COLOR_STYLE = {style!r}"] @renderer @@ -59,7 +58,7 @@ def insert_into_xonshrc( # get current contents fname = os.path.expanduser(xonshrc) if os.path.isfile(fname): - with open(fname, "r") as f: + with open(fname) as f: s = f.read() before, _, s = s.partition(prefix) _, _, after = s.partition(suffix) @@ -120,15 +119,15 @@ def main(args=None): while port <= 9310: try: with socketserver.TCPServer(("", port), Handler) as httpd: - url = "http://localhost:{0}".format(port) - print("Web config started at '{0}'. Hit Crtl+C to stop.".format(url)) + url = f"http://localhost:{port}" + print(f"Web config started at '{url}'. Hit Crtl+C to stop.") if ns.browser: import webbrowser webbrowser.open(url) httpd.serve_forever() break - except socket.error: + except OSError: type, value = sys.exc_info()[:2] if "Address already in use" not in str(value): raise diff --git a/xonsh/wizard.py b/xonsh/wizard.py index 89c2b41db..0643f7d56 100644 --- a/xonsh/wizard.py +++ b/xonsh/wizard.py @@ -18,7 +18,7 @@ from xonsh.jsonutils import serialize_xonsh_json # # Nodes themselves # -class Node(object): +class Node: """Base type of all nodes.""" attrs: tp.Union[tp.Tuple[str, ...], str] = () @@ -289,7 +289,7 @@ class StateFile(Input): if val is None: self.prompt = "filename: " else: - self.prompt = "filename [default={0!r}]: ".format(val) + self.prompt = f"filename [default={val!r}]: " class SaveJSON(StateFile): @@ -443,7 +443,7 @@ def _lowername(cls): return cls.__name__.lower() -class Visitor(object): +class Visitor: """Super-class for all classes that should walk over a tree of nodes. This implements the visit() method. """ @@ -488,7 +488,7 @@ class PrettyFormatter(Visitor): for aname in node.attrs: a = getattr(node, aname) t.append(self.visit(a) if isinstance(a, Node) else pprint.pformat(a)) - t = ["{0}={1}".format(n, x) for n, x in zip(node.attrs, t)] + t = [f"{n}={x}" for n, x in zip(node.attrs, t)] s += textwrap.indent(",\n".join(t), self.indent) self.level -= 1 s += "\n)" @@ -500,7 +500,7 @@ class PrettyFormatter(Visitor): if node.path is None: return s + "])" else: - return s + "], path={0!r})".format(node.path) + return s + f"], path={node.path!r})" s += "\n" self.level += 1 s += textwrap.indent(",\n".join(map(self.visit, node.children)), self.indent) @@ -512,40 +512,40 @@ class PrettyFormatter(Visitor): return s def visit_message(self, node): - return "Message({0!r})".format(node.message) + return f"Message({node.message!r})" def visit_question(self, node): s = node.__class__.__name__ + "(\n" self.level += 1 - s += self.indent + "question={0!r},\n".format(node.question) + s += self.indent + f"question={node.question!r},\n" s += self.indent + "responses={" if len(node.responses) == 0: s += "}" else: s += "\n" t = sorted(node.responses.items()) - t = ["{0!r}: {1}".format(k, self.visit(v)) for k, v in t] + t = [f"{k!r}: {self.visit(v)}" for k, v in t] s += textwrap.indent(",\n".join(t), 2 * self.indent) s += "\n" + self.indent + "}" if node.converter is not None: - s += ",\n" + self.indent + "converter={0!r}".format(node.converter) + s += ",\n" + self.indent + f"converter={node.converter!r}" if node.path is not None: - s += ",\n" + self.indent + "path={0!r}".format(node.path) + s += ",\n" + self.indent + f"path={node.path!r}" self.level -= 1 s += "\n)" return s def visit_input(self, node): - s = "{0}(prompt={1!r}".format(node.__class__.__name__, node.prompt) + s = f"{node.__class__.__name__}(prompt={node.prompt!r}" if node.converter is None and node.path is None: return s + "\n)" if node.converter is not None: - s += ",\n" + self.indent + "converter={0!r}".format(node.converter) - s += ",\n" + self.indent + "show_conversion={0!r}".format(node.show_conversion) - s += ",\n" + self.indent + "confirm={0!r}".format(node.confirm) - s += ",\n" + self.indent + "retry={0!r}".format(node.retry) + s += ",\n" + self.indent + f"converter={node.converter!r}" + s += ",\n" + self.indent + f"show_conversion={node.show_conversion!r}" + s += ",\n" + self.indent + f"confirm={node.confirm!r}" + s += ",\n" + self.indent + f"retry={node.retry!r}" if node.path is not None: - s += ",\n" + self.indent + "path={0!r}".format(node.path) + s += ",\n" + self.indent + f"path={node.path!r}" s += "\n)" return s @@ -557,7 +557,7 @@ class PrettyFormatter(Visitor): return s def visit_while(self, node): - s = "{0}(cond={1!r}".format(node.__class__.__name__, node.cond) + s = f"{node.__class__.__name__}(cond={node.cond!r}" s += ",\n" + self.indent + "body=[" if len(node.body) > 0: s += "\n" @@ -566,10 +566,10 @@ class PrettyFormatter(Visitor): self.level -= 1 s += "\n" + self.indent s += "]" - s += ",\n" + self.indent + "idxname={0!r}".format(node.idxname) - s += ",\n" + self.indent + "beg={0!r}".format(node.beg) + s += ",\n" + self.indent + f"idxname={node.idxname!r}" + s += ",\n" + self.indent + f"beg={node.beg!r}" if node.path is not None: - s += ",\n" + self.indent + "path={0!r}".format(node.path) + s += ",\n" + self.indent + f"path={node.path!r}" s += "\n)" return s @@ -584,7 +584,7 @@ def ensure_str_or_int(x): except (ValueError, SyntaxError): pass if not isinstance(x, (int, str)): - msg = "{0!r} could not be converted to int or str".format(x) + msg = f"{x!r} could not be converted to int or str" raise ValueError(msg) return x @@ -604,7 +604,7 @@ def canon_path(path, indices=None): return tuple(map(ensure_str_or_int, path.split("/"))) -class UnstorableType(object): +class UnstorableType: """Represents an unstorable return value for when no input was given or such input was skipped. Typically represented by the Unstorable singleton. @@ -614,7 +614,7 @@ class UnstorableType(object): def __new__(cls, *args, **kwargs): if cls._inst is None: - cls._inst = super(UnstorableType, cls).__new__(cls, *args, **kwargs) + cls._inst = super().__new__(cls, *args, **kwargs) return cls._inst @@ -825,9 +825,9 @@ class PromptVisitor(StateVisitor): if fname is None or len(fname) == 0: fname = node.default_file if os.path.isfile(fname): - with open(fname, "r") as f: + with open(fname) as f: self.state = json.load(f) - print_color("{{GREEN}}{0!r} loaded.{{RESET}}".format(fname)) + print_color(f"{{GREEN}}{fname!r} loaded.{{RESET}}") else: print_color( ("{{RED}}{0!r} could not be found, " "continuing.{{RESET}}").format( @@ -855,7 +855,7 @@ class PromptVisitor(StateVisitor): if fname is None or len(fname) == 0: fname = node.default_file if os.path.isfile(fname): - with open(fname, "r") as f: + with open(fname) as f: s = f.read() before, _, s = s.partition(node.prefix) _, _, after = s.partition(node.suffix) diff --git a/xonsh/xonfig.py b/xonsh/xonfig.py index 960d88f9e..68f71dcbb 100644 --- a/xonsh/xonfig.py +++ b/xonsh/xonfig.py @@ -193,11 +193,11 @@ def _dump_xonfig_env(path, value): detyper = XSH.env.get_detyper(name) dval = str(value) if detyper is None else detyper(value) dval = str(value) if dval is None else dval - return "${name} = {val!r}".format(name=name, val=dval) + return f"${name} = {dval!r}" def _dump_xonfig_xontribs(path, value): - return "xontrib load {0}".format(" ".join(value)) + return "xontrib load {}".format(" ".join(value)) @lazyobject @@ -666,7 +666,7 @@ def _colors( if style is not None: if style not in color_style_names(): - print("Invalid style: {}".format(style)) + print(f"Invalid style: {style}") return XSH.env["XONSH_COLOR_STYLE"] = style @@ -752,7 +752,7 @@ def _jupyter_kernel( old_jup_kernel = ksm.get_kernel_spec(XONSH_JUPYTER_KERNEL) if not old_jup_kernel.resource_dir.startswith(prefix): print( - "Removing existing Jupyter kernel found at {0}".format( + "Removing existing Jupyter kernel found at {}".format( old_jup_kernel.resource_dir ) ) @@ -771,13 +771,13 @@ def _jupyter_kernel( json.dump(spec, f, sort_keys=True) print("Installing Jupyter kernel spec:") - print(" root: {0!r}".format(root)) + print(f" root: {root!r}") if user: - print(" as user: {0}".format(user)) + print(f" as user: {user}") elif root and prefix: - print(" combined prefix {0!r}".format(prefix)) + print(f" combined prefix {prefix!r}") else: - print(" prefix: {0!r}".format(prefix)) + print(f" prefix: {prefix!r}") ksm.install_kernel_spec( d, XONSH_JUPYTER_KERNEL, user=user, prefix=(None if user else prefix) ) diff --git a/xonsh/xontribs.py b/xonsh/xontribs.py index d7b305b5a..9522d9062 100644 --- a/xonsh/xontribs.py +++ b/xonsh/xontribs.py @@ -112,12 +112,12 @@ def xontribs_load( res = ExitCode.OK for name in names: if verbose: - print("loading xontrib {0!r}".format(name)) + print(f"loading xontrib {name!r}") try: update_context(name, ctx=ctx) except Exception: res = ExitCode.INIT_FAILED - print_exception("Failed to load xontrib {}.".format(name)) + print_exception(f"Failed to load xontrib {name}.") if hasattr(update_context, "bad_imports"): res = ExitCode.NOT_FOUND prompt_xontrib_install(update_context.bad_imports) # type: ignore diff --git a/xonsh/xoreutils/ulimit.py b/xonsh/xoreutils/ulimit.py index 7d06e6ebc..6ce020d98 100644 --- a/xonsh/xoreutils/ulimit.py +++ b/xonsh/xoreutils/ulimit.py @@ -275,10 +275,10 @@ Options:""", for k in _UL_RES: r = _UL_RES[k] - opts = "-{}, {}".format(k, r[1]) + opts = f"-{k}, {r[1]}" if r[0] is None: opts += " (unsupported)" - print("{}\n {}".format(opts, r[2]), file=file) + print(f"{opts}\n {r[2]}", file=file) print( """ diff --git a/xonsh/xoreutils/umask.py b/xonsh/xoreutils/umask.py index c28e8e4f2..9eec44c8b 100644 --- a/xonsh/xoreutils/umask.py +++ b/xonsh/xoreutils/umask.py @@ -68,8 +68,7 @@ def get_symbolic_rep_single(digit): def get_symbolic_rep(number): digits = get_oct_digits(number) return ",".join( - "{}={}".format(class_, get_symbolic_rep_single(digits[class_])) - for class_ in "ugo" + f"{class_}={get_symbolic_rep_single(digits[class_])}" for class_ in "ugo" ) diff --git a/xonsh/xoreutils/which.py b/xonsh/xoreutils/which.py index e49a4907d..99433f811 100644 --- a/xonsh/xoreutils/which.py +++ b/xonsh/xoreutils/which.py @@ -77,7 +77,7 @@ def _which_create_parser(): def print_global_object(arg, stdout): """Print the object.""" obj = XSH.ctx.get(arg) - print("global object of {}".format(type(obj)), file=stdout) + print(f"global object of {type(obj)}", file=stdout) def print_path(abs_name, from_where, stdout, verbose=False, captured=False): @@ -109,7 +109,7 @@ def print_alias(arg, stdout, verbose=False): print(alias, file=stdout) else: print( - "aliases['{}'] = {}".format(arg, alias), + f"aliases['{arg}'] = {alias}", flush=True, file=stdout, ) diff --git a/xontrib/bashisms.py b/xontrib/bashisms.py index d3a591f71..ef1ba8702 100644 --- a/xontrib/bashisms.py +++ b/xontrib/bashisms.py @@ -33,15 +33,15 @@ def bash_preproc(cmd, **kw): try: return bang_previous[arg](inputs[-1]) except IndexError: - print("xonsh: no history for '!{}'".format(arg)) + print(f"xonsh: no history for '!{arg}'") return "" # Look back in history for a matching command. else: try: - return next((x for x in reversed(inputs) if x.startswith(arg))) + return next(x for x in reversed(inputs) if x.startswith(arg)) except StopIteration: - print("xonsh: no previous commands match '!{}'".format(arg)) + print(f"xonsh: no previous commands match '!{arg}'") return "" return re.sub(r"!([!$^*]|[\w]+)", replace_bang, cmd) @@ -58,13 +58,13 @@ def alias(args, stdin=None): name, cmd = shlex.split(arg)[0].split("=", 1) XSH.aliases[name] = shlex.split(cmd) elif arg in XSH.aliases: - print("{}={}".format(arg, XSH.aliases[arg])) + print(f"{arg}={XSH.aliases[arg]}") else: - print("alias: {}: not found".format(arg), file=sys.stderr) + print(f"alias: {arg}: not found", file=sys.stderr) ret = 1 else: for alias, cmd in XSH.aliases.items(): - print("{}={}".format(alias, cmd)) + print(f"{alias}={cmd}") return ret diff --git a/xontrib/jedi.py b/xontrib/jedi.py index 49d991382..e34e39256 100644 --- a/xontrib/jedi.py +++ b/xontrib/jedi.py @@ -101,7 +101,7 @@ def complete_jedi(context: CompletionContext): except Exception: pass - res = set(create_completion(comp) for comp in script_comp if should_complete(comp)) + res = {create_completion(comp) for comp in script_comp if should_complete(comp)} if index > 0: last_char = source[index - 1] diff --git a/xontrib/prompt_ret_code.py b/xontrib/prompt_ret_code.py index e245d60c4..f60fce52d 100644 --- a/xontrib/prompt_ret_code.py +++ b/xontrib/prompt_ret_code.py @@ -23,7 +23,7 @@ def _ret_code(): if XSH.history.rtns: return_code = XSH.history.rtns[-1] if return_code != 0: - return "[{}]".format(return_code) + return f"[{return_code}]" return None diff --git a/xontrib/vox.py b/xontrib/vox.py index 334c44bb9..059763e62 100644 --- a/xontrib/vox.py +++ b/xontrib/vox.py @@ -458,9 +458,9 @@ class VoxHandler(xcli.ArgParserAlias): .decode() .splitlines() ) - pkgs = set(p for p in all_pkgs if len(p.split("==")) == 2) + pkgs = {p for p in all_pkgs if len(p.split("==")) == 2} ignored = sorted(all_pkgs - pkgs) - to_remove = set(p.split("==")[0] for p in pkgs) + to_remove = {p.split("==")[0] for p in pkgs} if to_remove: print("Ignoring:\n %s" % "\n ".join(ignored)) print("Uninstalling packages:\n %s" % "\n ".join(to_remove))