summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/advanced.rst14
-rw-r--r--docs/arguments.rst2
-rw-r--r--docs/bashcomplete.rst6
-rw-r--r--docs/commands.rst10
-rw-r--r--docs/documentation.rst4
-rw-r--r--docs/index.rst2
-rw-r--r--docs/options.rst40
-rw-r--r--docs/quickstart.rst2
-rw-r--r--docs/testing.rst6
-rw-r--r--docs/utils.rst11
-rw-r--r--examples/aliases/aliases.py2
-rw-r--r--examples/bashcompletion/bashcompletion.py2
-rw-r--r--examples/complex/complex/commands/cmd_init.py2
-rw-r--r--examples/imagepipe/imagepipe.py5
-rw-r--r--examples/repo/repo.py2
-rw-r--r--examples/termui/termui.py2
-rw-r--r--examples/validation/validation.py3
-rw-r--r--src/click/_bashcomplete.py2
-rw-r--r--src/click/_compat.py4
-rw-r--r--src/click/_termui_impl.py21
-rw-r--r--src/click/_textwrap.py2
-rw-r--r--src/click/_unicodefun.py10
-rw-r--r--src/click/_winconsole.py4
-rw-r--r--src/click/core.py61
-rw-r--r--src/click/decorators.py5
-rw-r--r--src/click/exceptions.py17
-rw-r--r--src/click/formatting.py14
-rw-r--r--src/click/parser.py6
-rw-r--r--src/click/termui.py24
-rw-r--r--src/click/testing.py7
-rw-r--r--src/click/types.py65
-rw-r--r--src/click/utils.py2
-rw-r--r--tests/test_arguments.py12
-rw-r--r--tests/test_basic.py10
-rw-r--r--tests/test_chain.py5
-rw-r--r--tests/test_commands.py4
-rw-r--r--tests/test_defaults.py4
-rw-r--r--tests/test_options.py13
-rw-r--r--tests/test_termui.py4
-rw-r--r--tests/test_testing.py4
40 files changed, 188 insertions, 227 deletions
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 6278893..8003611 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -46,7 +46,7 @@ it would accept ``pus`` as an alias (so long as it was unique):
return None
elif len(matches) == 1:
return click.Group.get_command(self, ctx, matches[0])
- ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
+ ctx.fail(f"Too many matches: {', '.join(sorted(matches))}")
And it can then be used like this:
@@ -92,7 +92,7 @@ it's good to know that the system works this way.
@click.option('--url', callback=open_url)
def cli(url, fp=None):
if fp is not None:
- click.echo('%s: %s' % (url, fp.code))
+ click.echo(f"{url}: {fp.code}")
In this case the callback returns the URL unchanged but also passes a
second ``fp`` value to the callback. What's more recommended is to pass
@@ -116,7 +116,7 @@ the information in a wrapper however:
@click.option('--url', callback=open_url)
def cli(url):
if url is not None:
- click.echo('%s: %s' % (url.url, url.fp.code))
+ click.echo(f"{url.url}: {url.fp.code}")
Token Normalization
@@ -140,7 +140,7 @@ function that converts the token to lowercase:
@click.command(context_settings=CONTEXT_SETTINGS)
@click.option('--name', default='Pete')
def cli(name):
- click.echo('Name: %s' % name)
+ click.echo(f"Name: {name}")
And how it works on the command line:
@@ -171,7 +171,7 @@ Example:
@cli.command()
@click.option('--count', default=1)
def test(count):
- click.echo('Count: %d' % count)
+ click.echo(f'Count: {count}')
@cli.command()
@click.option('--count', default=1)
@@ -300,7 +300,7 @@ In the end you end up with something like this:
"""A fake wrapper around Python's timeit."""
cmdline = ['echo', 'python', '-mtimeit'] + list(timeit_args)
if verbose:
- click.echo('Invoking: %s' % ' '.join(cmdline))
+ click.echo(f"Invoking: {' '.join(cmdline)}")
call(cmdline)
And what it looks like:
@@ -396,7 +396,7 @@ method can be used to find this out.
@click.pass_context
def cli(ctx, port):
source = ctx.get_parameter_source("port")
- click.echo("Port came from {}".format(source))
+ click.echo(f"Port came from {source}")
.. click:run::
diff --git a/docs/arguments.rst b/docs/arguments.rst
index 6ae3538..e5765c9 100644
--- a/docs/arguments.rst
+++ b/docs/arguments.rst
@@ -55,7 +55,7 @@ Example:
def copy(src, dst):
"""Move file SRC to DST."""
for fn in src:
- click.echo('move %s to folder %s' % (fn, dst))
+ click.echo(f"move {fn} to folder {dst}")
And what it looks like:
diff --git a/docs/bashcomplete.rst b/docs/bashcomplete.rst
index b2bb1b6..bc0ba7d 100644
--- a/docs/bashcomplete.rst
+++ b/docs/bashcomplete.rst
@@ -50,8 +50,8 @@ suggestions:
@click.command()
@click.argument("envvar", type=click.STRING, autocompletion=get_env_vars)
def cmd1(envvar):
- click.echo('Environment variable: %s' % envvar)
- click.echo('Value: %s' % os.environ[envvar])
+ click.echo(f"Environment variable: {envvar}")
+ click.echo(f"Value: {os.environ[envvar]}")
Completion help strings
@@ -79,7 +79,7 @@ suggestions with help strings:
@click.command()
@click.argument("color", type=click.STRING, autocompletion=get_colors)
def cmd1(color):
- click.echo('Chosen color is %s' % color)
+ click.echo(f"Chosen color is {color}")
Activation
diff --git a/docs/commands.rst b/docs/commands.rst
index da26ac0..2bb9111 100644
--- a/docs/commands.rst
+++ b/docs/commands.rst
@@ -25,7 +25,7 @@ when an inner command runs:
@click.group()
@click.option('--debug/--no-debug', default=False)
def cli(debug):
- click.echo('Debug mode is %s' % ('on' if debug else 'off'))
+ click.echo(f"Debug mode is {'on' if debug else 'off'}")
@cli.command() # @cli, not @click!
def sync():
@@ -96,7 +96,7 @@ script like this:
@cli.command()
@click.pass_context
def sync(ctx):
- click.echo('Debug is %s' % (ctx.obj['DEBUG'] and 'on' or 'off'))
+ click.echo(f"Debug is {'on' if ctx.obj['DEBUG'] else 'off'}")
if __name__ == '__main__':
cli(obj={})
@@ -166,7 +166,7 @@ Example:
if ctx.invoked_subcommand is None:
click.echo('I was invoked without subcommand')
else:
- click.echo('I am about to invoke %s' % ctx.invoked_subcommand)
+ click.echo(f"I am about to invoke {ctx.invoked_subcommand}")
@cli.command()
def sync():
@@ -466,7 +466,7 @@ Example usage:
@cli.command()
@click.option('--port', default=8000)
def runserver(port):
- click.echo('Serving on http://127.0.0.1:%d/' % port)
+ click.echo(f"Serving on http://127.0.0.1:{port}/")
if __name__ == '__main__':
cli(default_map={
@@ -512,7 +512,7 @@ This example does the same as the previous example:
@cli.command()
@click.option('--port', default=8000)
def runserver(port):
- click.echo('Serving on http://127.0.0.1:%d/' % port)
+ click.echo(f"Serving on http://127.0.0.1:{port}/")
if __name__ == '__main__':
cli()
diff --git a/docs/documentation.rst b/docs/documentation.rst
index 982ad42..181c5b3 100644
--- a/docs/documentation.rst
+++ b/docs/documentation.rst
@@ -24,7 +24,7 @@ Simple example:
def hello(count, name):
"""This script prints hello NAME COUNT times."""
for x in range(count):
- click.echo('Hello %s!' % name)
+ click.echo(f"Hello {name}!")
And what it looks like:
@@ -173,7 +173,7 @@ desired. This can be customized at all levels:
def hello(count, name):
"""This script prints hello <name> <int> times."""
for x in range(count):
- click.echo('Hello %s!' % name)
+ click.echo(f"Hello {name}!")
Example:
diff --git a/docs/index.rst b/docs/index.rst
index 7fac849..683f1ef 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -36,7 +36,7 @@ What does it look like? Here is an example of a simple Click program:
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
- click.echo('Hello %s!' % name)
+ click.echo(f"Hello {name}!")
if __name__ == '__main__':
hello()
diff --git a/docs/options.rst b/docs/options.rst
index 4942c8a..41653aa 100644
--- a/docs/options.rst
+++ b/docs/options.rst
@@ -85,7 +85,7 @@ simply pass in `required=True` as an argument to the decorator.
@click.option('--from', '-f', 'from_')
@click.option('--to', '-t')
def reserved_param_name(from_, to):
- click.echo('from %s to %s' % (from_, to))
+ click.echo(f"from {from_} to {to}")
And on the command line:
@@ -121,7 +121,8 @@ the ``nargs`` parameter. The values are then stored as a tuple.
@click.command()
@click.option('--pos', nargs=2, type=float)
def findme(pos):
- click.echo('%s / %s' % pos)
+ a, b = pos
+ click.echo(f"{a} / {b}")
And on the command line:
@@ -146,7 +147,8 @@ the tuple. For this you can directly specify a tuple as type:
@click.command()
@click.option('--item', type=(str, int))
def putitem(item):
- click.echo('name=%s id=%d' % item)
+ name, id = item
+ click.echo(f"name={name} id={id}")
And on the command line:
@@ -163,7 +165,8 @@ used. The above example is thus equivalent to this:
@click.command()
@click.option('--item', nargs=2, type=click.Tuple([str, int]))
def putitem(item):
- click.echo('name=%s id=%d' % item)
+ name, id = item
+ click.echo(f"name={name} id={id}")
.. _multiple-options:
@@ -212,7 +215,7 @@ for instance:
@click.command()
@click.option('-v', '--verbose', count=True)
def log(verbose):
- click.echo('Verbosity: %s' % verbose)
+ click.echo(f"Verbosity: {verbose}")
And on the command line:
@@ -281,7 +284,7 @@ can alternatively split the parameters through ``;`` instead:
@click.command()
@click.option('/debug;/no-debug')
def log(debug):
- click.echo('debug=%s' % debug)
+ click.echo(f"debug={debug}")
if __name__ == '__main__':
log()
@@ -402,7 +405,7 @@ Example:
@click.command()
@click.option('--name', prompt=True)
def hello(name):
- click.echo('Hello %s!' % name)
+ click.echo(f"Hello {name}!")
And what it looks like:
@@ -419,7 +422,7 @@ a different one:
@click.command()
@click.option('--name', prompt='Your name please')
def hello(name):
- click.echo('Hello %s!' % name)
+ click.echo(f"Hello {name}!")
What it looks like:
@@ -443,7 +446,7 @@ useful for password input:
@click.option('--password', prompt=True, hide_input=True,
confirmation_prompt=True)
def encrypt(password):
- click.echo('Encrypting password to %s' % password.encode('rot13'))
+ click.echo(f"Encrypting password to {password.encode('rot13')}")
What it looks like:
@@ -459,7 +462,7 @@ replaced with the :func:`password_option` decorator:
@click.command()
@click.password_option()
def encrypt(password):
- click.echo('Encrypting password to %s' % password.encode('rot13'))
+ click.echo(f"Encrypting password to {password.encode('rot13')}")
Dynamic Defaults for Prompts
----------------------------
@@ -625,7 +628,7 @@ Example usage:
@click.command()
@click.option('--username')
def greet(username):
- click.echo('Hello %s!' % username)
+ click.echo(f'Hello {username}!')
if __name__ == '__main__':
greet(auto_envvar_prefix='GREETER')
@@ -650,12 +653,12 @@ Example:
@click.group()
@click.option('--debug/--no-debug')
def cli(debug):
- click.echo('Debug mode is %s' % ('on' if debug else 'off'))
+ click.echo(f"Debug mode is {'on' if debug else 'off'}")
@cli.command()
@click.option('--username')
def greet(username):
- click.echo('Hello %s!' % username)
+ click.echo(f"Hello {username}!")
if __name__ == '__main__':
cli(auto_envvar_prefix='GREETER')
@@ -677,7 +680,7 @@ Example usage:
@click.command()
@click.option('--username', envvar='USERNAME')
def greet(username):
- click.echo('Hello %s!' % username)
+ click.echo(f"Hello {username}!")
if __name__ == '__main__':
greet()
@@ -726,7 +729,7 @@ And from the command line:
.. click:run::
import os
- invoke(perform, env={'PATHS': './foo/bar%s./test' % os.path.pathsep})
+ invoke(perform, env={"PATHS": f"./foo/bar{os.path.pathsep}./test"})
Other Prefix Characters
-----------------------
@@ -742,7 +745,7 @@ POSIX semantics. However in certain situations this can be useful:
@click.command()
@click.option('+w/-w')
def chmod(w):
- click.echo('writable=%s' % w)
+ click.echo(f"writable={w}")
if __name__ == '__main__':
chmod()
@@ -762,7 +765,7 @@ boolean flag you need to separate it with ``;`` instead of ``/``:
@click.command()
@click.option('/debug;/no-debug')
def log(debug):
- click.echo('debug=%s' % debug)
+ click.echo(f"debug={debug}")
if __name__ == '__main__':
log()
@@ -834,7 +837,8 @@ Example:
@click.command()
@click.option('--rolls', callback=validate_rolls, default='1d6')
def roll(rolls):
- click.echo('Rolling a %d-sided dice %d time(s)' % rolls)
+ sides, times = rolls
+ click.echo(f"Rolling a {sides}-sided dice {times} time(s)")
if __name__ == '__main__':
roll()
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index c8cb2d9..51f7f22 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -240,7 +240,7 @@ To add parameters, use the :func:`option` and :func:`argument` decorators:
@click.argument('name')
def hello(count, name):
for x in range(count):
- click.echo('Hello %s!' % name)
+ click.echo(f"Hello {name}!")
What it looks like:
diff --git a/docs/testing.rst b/docs/testing.rst
index 52a888d..57acaf2 100644
--- a/docs/testing.rst
+++ b/docs/testing.rst
@@ -30,7 +30,7 @@ data, exit code, and optional exception attached:
@click.command()
@click.argument('name')
def hello(name):
- click.echo('Hello %s!' % name)
+ click.echo(f'Hello {name}!')
.. code-block:: python
:caption: test_hello.py
@@ -54,7 +54,7 @@ For subcommand testing, a subcommand name must be specified in the `args` parame
@click.group()
@click.option('--debug/--no-debug', default=False)
def cli(debug):
- click.echo('Debug mode is %s' % ('on' if debug else 'off'))
+ click.echo(f"Debug mode is {'on' if debug else 'off'}")
@cli.command()
def sync():
@@ -126,7 +126,7 @@ stream (stdin). This is very useful for testing prompts, for instance:
@click.command()
@click.option('--foo', prompt=True)
def prompt(foo):
- click.echo('foo=%s' % foo)
+ click.echo(f"foo={foo}")
.. code-block:: python
:caption: test_prompt.py
diff --git a/docs/utils.rst b/docs/utils.rst
index 902e5fd..7dd8dbb 100644
--- a/docs/utils.rst
+++ b/docs/utils.rst
@@ -112,15 +112,14 @@ Example:
@click.command()
def less():
- click.echo_via_pager('\n'.join('Line %d' % idx
- for idx in range(200)))
+ click.echo_via_pager("\n".join(f"Line {idx}" for idx in range(200)))
If you want to use the pager for a lot of text, especially if generating everything in advance would take a lot of time, you can pass a generator (or generator function) instead of a string:
.. click:example::
def _generate_output():
for idx in range(50000):
- yield "Line %d\n" % idx
+ yield f"Line {idx}\n"
@click.command()
def less():
@@ -264,7 +263,7 @@ context of a full Unicode string.
Example::
- click.echo('Path: %s' % click.format_filename(b'foo.txt'))
+ click.echo(f"Path: {click.format_filename(b'foo.txt')}")
Standard Streams
@@ -349,7 +348,7 @@ Example usage::
rv = {}
for section in parser.sections():
for key, value in parser.items(section):
- rv['%s.%s' % (section, key)] = value
+ rv[f"{section}.{key}"] = value
return rv
@@ -396,7 +395,7 @@ loop. So code like this will render correctly::
with click.progressbar([1, 2, 3]) as bar:
for x in bar:
- print('sleep({})...'.format(x))
+ print(f"sleep({x})...")
time.sleep(x)
Another useful feature is to associate a label with the progress bar which
diff --git a/examples/aliases/aliases.py b/examples/aliases/aliases.py
index c01672b..c3da657 100644
--- a/examples/aliases/aliases.py
+++ b/examples/aliases/aliases.py
@@ -65,7 +65,7 @@ class AliasedGroup(click.Group):
return None
elif len(matches) == 1:
return click.Group.get_command(self, ctx, matches[0])
- ctx.fail("Too many matches: {}".format(", ".join(sorted(matches))))
+ ctx.fail(f"Too many matches: {', '.join(sorted(matches))}")
def read_config(ctx, param, value):
diff --git a/examples/bashcompletion/bashcompletion.py b/examples/bashcompletion/bashcompletion.py
index 592bf19..3f8c9df 100644
--- a/examples/bashcompletion/bashcompletion.py
+++ b/examples/bashcompletion/bashcompletion.py
@@ -19,7 +19,7 @@ def get_env_vars(ctx, args, incomplete):
@click.argument("envvar", type=click.STRING, autocompletion=get_env_vars)
def cmd1(envvar):
click.echo(f"Environment variable: {envvar}")
- click.echo("Value: {}".format(os.environ[envvar]))
+ click.echo(f"Value: {os.environ[envvar]}")
@click.group(help="A group that holds a subcommand")
diff --git a/examples/complex/complex/commands/cmd_init.py b/examples/complex/complex/commands/cmd_init.py
index c2cf770..8802458 100644
--- a/examples/complex/complex/commands/cmd_init.py
+++ b/examples/complex/complex/commands/cmd_init.py
@@ -10,4 +10,4 @@ def cli(ctx, path):
"""Initializes a repository."""
if path is None:
path = ctx.home
- ctx.log("Initialized the repository in %s", click.format_filename(path))
+ ctx.log(f"Initialized the repository in {click.format_filename(path)}")
diff --git a/examples/imagepipe/imagepipe.py b/examples/imagepipe/imagepipe.py
index 95f5c42..57432fa 100644
--- a/examples/imagepipe/imagepipe.py
+++ b/examples/imagepipe/imagepipe.py
@@ -230,9 +230,8 @@ def smoothen_cmd(images, iterations):
"""Applies a smoothening filter."""
for image in images:
click.echo(
- "Smoothening '{}' {} time{}".format(
- image.filename, iterations, "s" if iterations != 1 else ""
- )
+ f"Smoothening {image.filename!r} {iterations}"
+ f" time{'s' if iterations != 1 else ''}"
)
for _ in range(iterations):
image = copy_filename(image.filter(ImageFilter.BLUR), image)
diff --git a/examples/repo/repo.py b/examples/repo/repo.py
index ff44d55..b773f3a 100644
--- a/examples/repo/repo.py
+++ b/examples/repo/repo.py
@@ -78,7 +78,7 @@ def clone(repo, src, dest, shallow, rev):
"""
if dest is None:
dest = posixpath.split(src)[-1] or "."
- click.echo("Cloning repo {} to {}".format(src, os.path.abspath(dest)))
+ click.echo(f"Cloning repo {src} to {os.path.basename(dest)}")
repo.home = dest
if shallow:
click.echo("Making shallow checkout")
diff --git a/examples/termui/termui.py b/examples/termui/termui.py
index b772f13..f4886b1 100644
--- a/examples/termui/termui.py
+++ b/examples/termui/termui.py
@@ -24,7 +24,7 @@ def pager():
"""Demonstrates using the pager."""
lines = []
for x in range(200):
- lines.append("{}. Hello World!".format(click.style(str(x), fg="green")))
+ lines.append(f"{click.style(str(x), fg='green')}. Hello World!")
click.echo_via_pager("\n".join(lines))
diff --git a/examples/validation/validation.py b/examples/validation/validation.py
index 6f87eb0..3f78df0 100644
--- a/examples/validation/validation.py
+++ b/examples/validation/validation.py
@@ -17,8 +17,7 @@ class URL(click.ParamType):
value = urlparse.urlparse(value)
if value.scheme not in ("http", "https"):
self.fail(
- "invalid URL scheme ({}). Only HTTP URLs are"
- " allowed".format(value.scheme),
+ f"invalid URL scheme ({value.scheme}). Only HTTP URLs are allowed",
param,
ctx,
)
diff --git a/src/click/_bashcomplete.py b/src/click/_bashcomplete.py
index 1c865f6..b9e4900 100644
--- a/src/click/_bashcomplete.py
+++ b/src/click/_bashcomplete.py
@@ -345,7 +345,7 @@ def do_complete_fish(cli, prog_name):
for item in get_choices(cli, prog_name, args, incomplete):
if item[1]:
- echo("{arg}\t{desc}".format(arg=item[0], desc=item[1]))
+ echo(f"{item[0]}\t{item[1]}")
else:
echo(item[0])
diff --git a/src/click/_compat.py b/src/click/_compat.py
index 96b0dd8..85568ca 100644
--- a/src/click/_compat.py
+++ b/src/click/_compat.py
@@ -64,7 +64,7 @@ class _NonClosingTextIOWrapper(io.TextIOWrapper):
errors,
force_readable=False,
force_writable=False,
- **extra
+ **extra,
):
self._stream = stream = _FixupStream(stream, force_readable, force_writable)
super().__init__(stream, encoding, errors, **extra)
@@ -415,7 +415,7 @@ def open_stream(filename, mode="r", encoding=None, errors="strict", atomic=False
while True:
tmp_filename = os.path.join(
os.path.dirname(filename),
- ".__atomic-write{:08x}".format(random.randrange(1 << 32)),
+ f".__atomic-write{random.randrange(1 << 32):08x}",
)
try:
fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm)
diff --git a/src/click/_termui_impl.py b/src/click/_termui_impl.py
index 84e3fc5..f03aa85 100644
--- a/src/click/_termui_impl.py
+++ b/src/click/_termui_impl.py
@@ -173,7 +173,7 @@ class ProgressBar:
return pos
def format_pct(self):
- return "{: 4}%".format(int(self.pct * 100))[1:]
+ return f"{int(self.pct * 100): 4}%"[1:]
def format_bar(self):
if self.length_known:
@@ -352,10 +352,7 @@ def pager(generator, color=None):
fd, filename = tempfile.mkstemp()
os.close(fd)
try:
- if (
- hasattr(os, "system")
- and os.system("more {}".format(shlex.quote(filename))) == 0
- ):
+ if hasattr(os, "system") and os.system(f"more {shlex.quote(filename)}") == 0:
return _pipepager(generator, "more", color)
return _nullpager(stdout, generator, color)
finally:
@@ -374,7 +371,7 @@ def _pipepager(generator, cmd, color):
# condition that
cmd_detail = cmd.rsplit("/", 1)[-1].split()
if color is None and cmd_detail[0] == "less":
- less_flags = "{}{}".format(os.environ.get("LESS", ""), " ".join(cmd_detail[1:]))
+ less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}"
if not less_flags:
env["LESS"] = "-R"
color = True
@@ -424,7 +421,7 @@ def _tempfilepager(generator, cmd, color):
with open_stream(filename, "wb")[0] as f:
f.write(text.encode(encoding))
try:
- os.system("{} {}".format(shlex.quote(cmd), shlex.quote(filename)))
+ os.system(f"{shlex.quote(cmd)} {shlex.quote(filename)}")
finally:
os.unlink(filename)
@@ -469,7 +466,7 @@ class Editor:
environ = None
try:
c = subprocess.Popen(
- "{} {}".format(shlex.quote(editor), shlex.quote(filename)),
+ f"{shlex.quote(editor)} {shlex.quote(filename)}",
env=environ,
shell=True,
)
@@ -546,16 +543,16 @@ def open_url(url, wait=False, locate=False):
elif WIN:
if locate:
url = _unquote_file(url)
- args = "explorer /select,{}".format(shlex.quote(url))
+ args = f"explorer /select,{shlex.quote(url)}"
else:
- args = 'start {} "" {}'.format("/WAIT" if wait else "", shlex.quote(url))
+ args = f"start {'/WAIT' if wait else ''} \"\" {shlex.quote(url)}"
return os.system(args)
elif CYGWIN:
if locate:
url = _unquote_file(url)
- args = "cygstart {}".format(shlex.quote(os.path.dirname(url)))
+ args = f"cygstart {shlex.quote(os.path.dirname(url))}"
else:
- args = "cygstart {} {}".format("-w" if wait else "", shlex.quote(url))
+ args = f"cygstart {'-w' if wait else ''} {shlex.quote(url)}"
return os.system(args)
try:
diff --git a/src/click/_textwrap.py b/src/click/_textwrap.py
index 6959087..7a052b7 100644
--- a/src/click/_textwrap.py
+++ b/src/click/_textwrap.py
@@ -33,5 +33,5 @@ class TextWrapper(textwrap.TextWrapper):
indent = self.initial_indent
if idx > 0:
indent = self.subsequent_indent
- rv.append(indent + line)
+ rv.append(f"{indent}{line}")
return "\n".join(rv)
diff --git a/src/click/_unicodefun.py b/src/click/_unicodefun.py
index 57545e0..7f3f234 100644
--- a/src/click/_unicodefun.py
+++ b/src/click/_unicodefun.py
@@ -55,9 +55,9 @@ def _verify_python3_env():
)
else:
extra += (
- "This system lists a couple of UTF-8 supporting locales"
- " that you can pick from. The following suitable"
- " locales were discovered: {}".format(", ".join(sorted(good_locales)))
+ "This system lists some UTF-8 supporting locales that"
+ " you can pick from. The following suitable locales"
+ f" were discovered: {', '.join(sorted(good_locales))}"
)
bad_locale = None
@@ -71,12 +71,12 @@ def _verify_python3_env():
"\n\nClick discovered that you exported a UTF-8 locale"
" but the locale system could not pick up from it"
" because it does not exist. The exported locale is"
- " '{}' but it is not supported".format(bad_locale)
+ f" {bad_locale!r} but it is not supported"
)
raise RuntimeError(
"Click will abort further execution because Python 3 was"
" configured to use ASCII as encoding for the environment."
" Consult https://click.palletsprojects.com/python3/ for"
- " mitigation steps.{}".format(extra)
+ f" mitigation steps.{extra}"
)
diff --git a/src/click/_winconsole.py b/src/click/_winconsole.py
index c46081f..923fdba 100644
--- a/src/click/_winconsole.py
+++ b/src/click/_winconsole.py
@@ -213,9 +213,7 @@ class ConsoleStream:
return self.buffer.isatty()
def __repr__(self):
- return "<ConsoleStream name={!r} encoding={!r}>".format(
- self.name, self.encoding
- )
+ return f"<ConsoleStream name={self.name!r} encoding={self.encoding!r}>"
class WindowsChunkedWriter:
diff --git a/src/click/core.py b/src/click/core.py
index 78b9ce4..e4061aa 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -36,12 +36,12 @@ SUBCOMMAND_METAVAR = "COMMAND [ARGS]..."
SUBCOMMANDS_METAVAR = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..."
DEPRECATED_HELP_NOTICE = " (DEPRECATED)"
-DEPRECATED_INVOKE_NOTICE = "DeprecationWarning: The command %(name)s is deprecated."
+DEPRECATED_INVOKE_NOTICE = "DeprecationWarning: The command {name} is deprecated."
def _maybe_show_deprecated_notice(cmd):
if cmd.deprecated:
- echo(style(DEPRECATED_INVOKE_NOTICE % {"name": cmd.name}, fg="red"), err=True)
+ echo(style(DEPRECATED_INVOKE_NOTICE.format(name=cmd.name), fg="red"), err=True)
def fast_exit(code):
@@ -56,7 +56,7 @@ def fast_exit(code):
def _bashcomplete(cmd, prog_name, complete_var=None):
"""Internal handler for the bash completion support."""
if complete_var is None:
- complete_var = "_{}_COMPLETE".format(prog_name.replace("-", "_").upper())
+ complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper()
complete_instr = os.environ.get(complete_var)
if not complete_instr:
return
@@ -81,17 +81,11 @@ def _check_multicommand(base_command, cmd_name, cmd, register=False):
" that is in chain mode. This is not supported."
)
raise RuntimeError(
- "{}. Command '{}' is set to chain and '{}' was added as"
- " subcommand but it in itself is a multi command. ('{}' is a {}"
- " within a chained {} named '{}').".format(
- hint,
- base_command.name,
- cmd_name,
- cmd_name,
- cmd.__class__.__name__,
- base_command.__class__.__name__,
- base_command.name,
- )
+ f"{hint}. Command {base_command.name!r} is set to chain and"
+ f" {cmd_name!r} was added as a subcommand but it in itself is a"
+ f" multi command. ({cmd_name!r} is a {type(cmd).__name__}"
+ f" within a chained {type(base_command).__name__} named"
+ f" {base_command.name!r})."
)
@@ -159,8 +153,8 @@ class ParameterSource:
"""
if value not in cls.VALUES:
raise ValueError(
- "Invalid ParameterSource value: '{}'. Valid "
- "values are: {}".format(value, ",".join(cls.VALUES))
+ f"Invalid ParameterSource value: {value!r}. Valid"
+ f" values are: {','.join(cls.VALUES)}"
)
@@ -381,8 +375,8 @@ class Context:
and parent.auto_envvar_prefix is not None
and self.info_name is not None
):
- auto_envvar_prefix = "{}_{}".format(
- parent.auto_envvar_prefix, self.info_name.upper()
+ auto_envvar_prefix = (
+ f"{parent.auto_envvar_prefix}_{self.info_name.upper()}"
)
else:
auto_envvar_prefix = auto_envvar_prefix.upper()
@@ -1088,9 +1082,9 @@ class Command(BaseCommand):
if args and not ctx.allow_extra_args and not ctx.resilient_parsing:
ctx.fail(
- "Got unexpected extra argument{} ({})".format(
- "s" if len(args) != 1 else "", " ".join(map(make_str, args))
- )
+ "Got unexpected extra"
+ f" argument{'s' if len(args) != 1 else ''}"
+ f" ({' '.join(map(make_str, args))})"
)
ctx.args = args
@@ -1598,8 +1592,8 @@ class Parameter:
if self.nargs <= 1:
raise TypeError(
"Attempted to invoke composite type but nargs has"
- " been set to {}. This is not supported; nargs"
- " needs to be set to a fixed value > 1.".format(self.nargs)
+ f" been set to {self.nargs}. This is not supported;"
+ " nargs needs to be set to a fixed value > 1."
)
if self.multiple:
return tuple(self.type(x or (), self, ctx) for x in value or ())
@@ -1863,8 +1857,9 @@ class Option(Parameter):
if not opts and not secondary_opts:
raise TypeError(
- "No options defined but a name was passed ({}). Did you"
- " mean to declare an argument instead of an option?".format(name)
+ f"No options defined but a name was passed ({name})."
+ " Did you mean to declare an argument instead of an"
+ " option?"
)
return name, opts, secondary_opts
@@ -1924,13 +1919,12 @@ class Option(Parameter):
if self.allow_from_autoenv and ctx.auto_envvar_prefix is not None:
envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}"
if envvar is not None:
- extra.append(
- "env var: {}".format(
- ", ".join(str(d) for d in envvar)
- if isinstance(envvar, (list, tuple))
- else envvar
- )
+ var_str = (
+ ", ".join(str(d) for d in envvar)
+ if isinstance(envvar, (list, tuple))
+ else envvar
)
+ extra.append(f"env var: {var_str}")
if self.default is not None and (self.show_default or ctx.show_default):
if isinstance(self.show_default, str):
default_string = f"({self.show_default})"
@@ -1945,7 +1939,8 @@ class Option(Parameter):
if self.required:
extra.append("required")
if extra:
- help = "{}[{}]".format(f"{help} " if help else "", "; ".join(extra))
+ extra_str = ";".join(extra)
+ help = f"{help} [{extra_str}]" if help else f"[{extra_str}]"
return ("; " if any_prefix_is_slash else " / ").join(rv), help
@@ -2061,7 +2056,7 @@ class Argument(Parameter):
else:
raise TypeError(
"Arguments take exactly one parameter declaration, got"
- " {}".format(len(decls))
+ f" {len(decls)}."
)
return name, [arg], []
diff --git a/src/click/decorators.py b/src/click/decorators.py
index e0596c8..3013305 100644
--- a/src/click/decorators.py
+++ b/src/click/decorators.py
@@ -66,7 +66,8 @@ def make_pass_decorator(object_type, ensure=False):
if obj is None:
raise RuntimeError(
"Managed to invoke callback without a context"
- " object of type '{}' existing".format(object_type.__name__)
+ f" object of type {object_type.__name__!r}"
+ " existing."
)
return ctx.invoke(f, obj, *args, **kwargs)
@@ -96,7 +97,7 @@ def _make_command(f, name, attrs, cls):
name=name or f.__name__.lower().replace("_", "-"),
callback=f,
params=params,
- **attrs
+ **attrs,
)
diff --git a/src/click/exceptions.py b/src/click/exceptions.py
index 2776a02..25b02bb 100644
--- a/src/click/exceptions.py
+++ b/src/click/exceptions.py
@@ -53,8 +53,9 @@ class UsageError(ClickException):
color = None
hint = ""
if self.cmd is not None and self.cmd.get_help_option(self.ctx) is not None:
- hint = "Try '{} {}' for help.\n".format(
- self.ctx.command_path, self.ctx.help_option_names[0]
+ hint = (
+ f"Try '{self.ctx.command_path}"
+ f" {self.ctx.help_option_names[0]}' for help.\n"
)
if self.ctx is not None:
color = self.ctx.color
@@ -137,12 +138,8 @@ class MissingParameter(BadParameter):
else:
msg = msg_extra
- return "Missing {}{}{}{}".format(
- param_type,
- f" {param_hint}" if param_hint else "",
- ". " if msg else ".",
- msg or "",
- )
+ hint_str = f" {param_hint}" if param_hint else ""
+ return f"Missing {param_type}{hint_str}.{' ' if msg else ''}{msg or ''}"
def __str__(self):
if self.message is None:
@@ -170,10 +167,10 @@ class NoSuchOption(UsageError):
bits = [self.message]
if self.possibilities:
if len(self.possibilities) == 1:
- bits.append("Did you mean {}?".format(self.possibilities[0]))
+ bits.append(f"Did you mean {self.possibilities[0]}?")
else:
possibilities = sorted(self.possibilities)
- bits.append("(Possible options: {})".format(", ".join(possibilities)))
+ bits.append(f"(Possible options: {', '.join(possibilities)})")
return " ".join(bits)
diff --git a/src/click/formatting.py b/src/click/formatting.py
index 5a8b81c..a298c2e 100644
--- a/src/click/formatting.py
+++ b/src/click/formatting.py
@@ -134,7 +134,7 @@ class HelpFormatter:
:param args: whitespace separated list of arguments.
:param prefix: the prefix for the first line.
"""
- usage_prefix = "{:>{w}}{} ".format(prefix, prog, w=self.current_indent)
+ usage_prefix = f"{prefix:>{self.current_indent}}{prog} "
text_width = self.width - self.current_indent
if text_width >= (term_len(usage_prefix) + 20):
@@ -163,7 +163,7 @@ class HelpFormatter:
def write_heading(self, heading):
"""Writes a heading into the buffer."""
- self.write("{:>{w}}{}:\n".format("", heading, w=self.current_indent))
+ self.write(f"{'':>{self.current_indent}}{heading}:\n")
def write_paragraph(self):
"""Writes a paragraph into the buffer."""
@@ -204,7 +204,7 @@ class HelpFormatter:
first_col = min(widths[0], col_max) + col_spacing
for first, second in iter_rows(rows, len(widths)):
- self.write("{:>{w}}{}".format("", first, w=self.current_indent))
+ self.write(f"{'':>{self.current_indent}}{first}")
if not second:
self.write("\n")
continue
@@ -219,14 +219,10 @@ class HelpFormatter:
lines = wrapped_text.splitlines()
if lines:
- self.write("{}\n".format(lines[0]))
+ self.write(f"{lines[0]}\n")
for line in lines[1:]:
- self.write(
- "{:>{w}}{}\n".format(
- "", line, w=first_col + self.current_indent
- )
- )
+ self.write(f"{'':>{first_col + self.current_indent}}{line}\n")
if len(lines) > 1:
# separate long help from next option
diff --git a/src/click/parser.py b/src/click/parser.py
index ae486d0..158abb0 100644
--- a/src/click/parser.py
+++ b/src/click/parser.py
@@ -100,7 +100,7 @@ def normalize_opt(opt, ctx):
if ctx is None or ctx.token_normalize_func is None:
return opt
prefix, opt = split_opt(opt)
- return prefix + ctx.token_normalize_func(opt)
+ return f"{prefix}{ctx.token_normalize_func(opt)}"
def split_arg_string(string):
@@ -361,7 +361,7 @@ class OptionParser:
unknown_options = []
for ch in arg[1:]:
- opt = normalize_opt(prefix + ch, self.ctx)
+ opt = normalize_opt(f"{prefix}{ch}", self.ctx)
option = self._short_opt.get(opt)
i += 1
@@ -399,7 +399,7 @@ class OptionParser:
# to the state as new larg. This way there is basic combinatorics
# that can be achieved while still ignoring unknown arguments.
if self.ignore_unknown_options and unknown_options:
- state.largs.append("{}{}".format(prefix, "".join(unknown_options)))
+ state.largs.append(f"{prefix}{''.join(unknown_options)}")
def _process_opts(self, arg, state):
explicit_value = None
diff --git a/src/click/termui.py b/src/click/termui.py
index b9c91c7..a1bdf2a 100644
--- a/src/click/termui.py
+++ b/src/click/termui.py
@@ -56,10 +56,10 @@ def _build_prompt(
):
prompt = text
if type is not None and show_choices and isinstance(type, Choice):
- prompt += " ({})".format(", ".join(map(str, type.choices)))
+ prompt += f" ({', '.join(map(str, type.choices))})"
if default is not None and show_default:
- prompt = "{} [{}]".format(prompt, _format_default(default))
- return prompt + suffix
+ prompt = f"{prompt} [{_format_default(default)}]"
+ return f"{prompt}{suffix}"
def _format_default(default):
@@ -502,24 +502,24 @@ def style(
bits = []
if fg:
try:
- bits.append("\033[{}m".format(_ansi_colors[fg]))
+ bits.append(f"\033[{_ansi_colors[fg]}m")
except KeyError:
- raise TypeError(f"Unknown color '{fg}'")
+ raise TypeError(f"Unknown color {fg!r}")
if bg:
try:
- bits.append("\033[{}m".format(_ansi_colors[bg] + 10))
+ bits.append(f"\033[{_ansi_colors[bg] + 10}m")
except KeyError:
- raise TypeError(f"Unknown color '{bg}'")
+ raise TypeError(f"Unknown color {bg!r}")
if bold is not None:
- bits.append("\033[{}m".format(1 if bold else 22))
+ bits.append(f"\033[{1 if bold else 22}m")
if dim is not None:
- bits.append("\033[{}m".format(2 if dim else 22))
+ bits.append(f"\033[{2 if dim else 22}m")
if underline is not None:
- bits.append("\033[{}m".format(4 if underline else 24))
+ bits.append(f"\033[{4 if underline else 24}m")
if blink is not None:
- bits.append("\033[{}m".format(5 if blink else 25))
+ bits.append(f"\033[{5 if blink else 25}m")
if reverse is not None:
- bits.append("\033[{}m".format(7 if reverse else 27))
+ bits.append(f"\033[{7 if reverse else 27}m")
bits.append(text)
if reset:
bits.append(_ansi_reset_all)
diff --git a/src/click/testing.py b/src/click/testing.py
index 717d2e4..fd6bf61 100644
--- a/src/click/testing.py
+++ b/src/click/testing.py
@@ -99,9 +99,8 @@ class Result:
)
def __repr__(self):
- return "<{} {}>".format(
- type(self).__name__, repr(self.exception) if self.exception else "okay"
- )
+ exc_str = repr(self.exception) if self.exception else "okay"
+ return f"<{type(self).__name__} {exc_str}>"
class CliRunner:
@@ -196,7 +195,7 @@ class CliRunner:
return val
def hidden_input(prompt=None):
- sys.stdout.write("{}\n".format(prompt or ""))
+ sys.stdout.write(f"{prompt or ''}\n")
sys.stdout.flush()
return input.readline().rstrip("\r\n")
diff --git a/src/click/types.py b/src/click/types.py
index 7aae2fe..93cf701 100644
--- a/src/click/types.py
+++ b/src/click/types.py
@@ -157,10 +157,11 @@ class Choice(ParamType):
self.case_sensitive = case_sensitive
def get_metavar(self, param):
- return "[{}]".format("|".join(self.choices))
+ return f"[{'|'.join(self.choices)}]"
def get_missing_message(self, param):
- return "Choose from:\n\t{}.".format(",\n\t".join(self.choices))
+ choice_str = ",\n\t".join(self.choices)
+ return f"Choose from:\n\t{choice_str}"
def convert(self, value, param, ctx):
# Match through normalization and case sensitivity
@@ -188,15 +189,13 @@ class Choice(ParamType):
return normed_choices[normed_value]
self.fail(
- "invalid choice: {}. (choose from {})".format(
- value, ", ".join(self.choices)
- ),
+ f"invalid choice: {value}. (choose from {', '.join(self.choices)})",
param,
ctx,
)
def __repr__(self):
- return "Choice('{}')".format(list(self.choices))
+ return f"Choice({list(self.choices)})"
class DateTime(ParamType):
@@ -226,7 +225,7 @@ class DateTime(ParamType):
self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"]
def get_metavar(self, param):
- return "[{}]".format("|".join(self.formats))
+ return f"[{'|'.join(self.formats)}]"
def _try_to_convert_date(self, value, format):
try:
@@ -242,9 +241,7 @@ class DateTime(ParamType):
return dtime
self.fail(
- "invalid datetime format: {}. (choose from {})".format(
- value, ", ".join(self.formats)
- )
+ f"invalid datetime format: {value}. (choose from {', '.join(self.formats)})"
)
def __repr__(self):
@@ -295,25 +292,19 @@ class IntRange(IntParamType):
):
if self.min is None:
self.fail(
- "{} is bigger than the maximum valid value {}.".format(
- rv, self.max
- ),
+ f"{rv} is bigger than the maximum valid value {self.max}.",
param,
ctx,
)
elif self.max is None:
self.fail(
- "{} is smaller than the minimum valid value {}.".format(
- rv, self.min
- ),
+ f"{rv} is smaller than the minimum valid value {self.min}.",
param,
ctx,
)
else:
self.fail(
- "{} is not in the valid range of {} to {}.".format(
- rv, self.min, self.max
- ),
+ f"{rv} is not in the valid range of {self.min} to {self.max}.",
param,
ctx,
)
@@ -367,25 +358,19 @@ class FloatRange(FloatParamType):
):
if self.min is None:
self.fail(
- "{} is bigger than the maximum valid value {}.".format(
- rv, self.max
- ),
+ f"{rv} is bigger than the maximum valid value {self.max}.",
param,
ctx,
)
elif self.max is None:
self.fail(
- "{} is smaller than the minimum valid value {}.".format(
- rv, self.min
- ),
+ f"{rv} is smaller than the minimum valid value {self.min}.",
param,
ctx,
)
else:
self.fail(
- "{} is not in the valid range of {} to {}.".format(
- rv, self.min, self.max
- ),
+ f"{rv} is not in the valid range of {self.min} to {self.max}.",
param,
ctx,
)
@@ -506,9 +491,7 @@ class File(ParamType):
return f
except OSError as e: # noqa: B014
self.fail(
- "Could not open file: {}: {}".format(
- filename_to_ui(value), get_strerror(e)
- ),
+ f"Could not open file: {filename_to_ui(value)}: {get_strerror(e)}",
param,
ctx,
)
@@ -600,40 +583,32 @@ class Path(ParamType):
if not self.exists:
return self.coerce_path_result(rv)
self.fail(
- "{} '{}' does not exist.".format(
- self.path_type, filename_to_ui(value)
- ),
+ f"{self.path_type} {filename_to_ui(value)!r} does not exist.",
param,
ctx,
)
if not self.file_okay and stat.S_ISREG(st.st_mode):
self.fail(
- "{} '{}' is a file.".format(self.path_type, filename_to_ui(value)),
+ f"{self.path_type} {filename_to_ui(value)!r} is a file.",
param,
ctx,
)
if not self.dir_okay and stat.S_ISDIR(st.st_mode):
self.fail(
- "{} '{}' is a directory.".format(
- self.path_type, filename_to_ui(value)
- ),
+ f"{self.path_type} {filename_to_ui(value)!r} is a directory.",
param,
ctx,
)
if self.writable and not os.access(value, os.W_OK):
self.fail(
- "{} '{}' is not writable.".format(
- self.path_type, filename_to_ui(value)
- ),
+ f"{self.path_type} {filename_to_ui(value)!r} is not writable.",
param,
ctx,
)
if self.readable and not os.access(value, os.R_OK):
self.fail(
- "{} '{}' is not readable.".format(
- self.path_type, filename_to_ui(value)
- ),
+ f"{self.path_type} {filename_to_ui(value)!r} is not readable.",
param,
ctx,
)
@@ -660,7 +635,7 @@ class Tuple(CompositeParamType):
@property
def name(self):
- return "<{}>".format(" ".join(ty.name for ty in self.types))
+ return f"<{' '.join(ty.name for ty in self.types)}>"
@property
def arity(self):
diff --git a/src/click/utils.py b/src/click/utils.py
index b18c83d..ffd26b3 100644
--- a/src/click/utils.py
+++ b/src/click/utils.py
@@ -408,7 +408,7 @@ def get_app_dir(app_name, roaming=True, force_posix=False):
folder = os.path.expanduser("~")
return os.path.join(folder, app_name)
if force_posix:
- return os.path.join(os.path.expanduser("~/.{}".format(_posixify(app_name))))
+ return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}"))
if sys.platform == "darwin":
return os.path.join(
os.path.expanduser("~/Library/Application Support"), app_name
diff --git a/tests/test_arguments.py b/tests/test_arguments.py
index 4970486..c5fee42 100644
--- a/tests/test_arguments.py
+++ b/tests/test_arguments.py
@@ -10,7 +10,7 @@ def test_nargs_star(runner):
@click.argument("src", nargs=-1)
@click.argument("dst")
def copy(src, dst):
- click.echo("src={}".format("|".join(src)))
+ click.echo(f"src={'|'.join(src)}")
click.echo(f"dst={dst}")
result = runner.invoke(copy, ["foo.txt", "bar.txt", "dir"])
@@ -33,7 +33,8 @@ def test_nargs_tup(runner):
@click.argument("point", nargs=2, type=click.INT)
def copy(name, point):
click.echo(f"name={name}")
- click.echo("point={0[0]}/{0[1]}".format(point))
+ x, y = point
+ click.echo(f"point={x}/{y}")
result = runner.invoke(copy, ["peter", "1", "2"])
assert not result.exception
@@ -53,7 +54,8 @@ def test_nargs_tup_composite(runner):
@click.command()
@click.argument("item", **opts)
def copy(item):
- click.echo("name={0[0]} id={0[1]:d}".format(item))
+ name, id = item
+ click.echo(f"name={name} id={id:d}")
result = runner.invoke(copy, ["peter", "1"])
assert not result.exception
@@ -187,7 +189,7 @@ def test_empty_nargs(runner):
@click.command()
@click.argument("arg", nargs=-1)
def cmd(arg):
- click.echo("arg:{}".format("|".join(arg)))
+ click.echo(f"arg:{'|'.join(arg)}")
result = runner.invoke(cmd, [])
assert result.exit_code == 0
@@ -196,7 +198,7 @@ def test_empty_nargs(runner):
@click.command()
@click.argument("arg", nargs=-1, required=True)
def cmd2(arg):
- click.echo("arg:{}".format("|".join(arg)))
+ click.echo(f"arg:{'|'.join(arg)}")
result = runner.invoke(cmd2, [])
assert result.exit_code == 2
diff --git a/tests/test_basic.py b/tests/test_basic.py
index 9f9d71e..c33e3a4 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -108,7 +108,7 @@ def test_int_option(runner):
@click.command()
@click.option("--foo", default=42)
def cli(foo):
- click.echo("FOO:[{}]".format(foo * 2))
+ click.echo(f"FOO:[{foo * 2}]")
result = runner.invoke(cli, [])
assert not result.exception
@@ -192,7 +192,7 @@ def test_boolean_option(runner):
result = runner.invoke(cli, ["--flag"])
assert not result.exception
- assert result.output == "{}\n".format(not default)
+ assert result.output == f"{not default}\n"
result = runner.invoke(cli, [])
assert not result.exception
assert result.output == f"{default}\n"
@@ -307,8 +307,8 @@ def test_path_option(runner):
@click.command()
@click.option("-f", type=click.Path(exists=True))
def showtype(f):
- click.echo("is_file={}".format(os.path.isfile(f)))
- click.echo("is_dir={}".format(os.path.isdir(f)))
+ click.echo(f"is_file={os.path.isfile(f)}")
+ click.echo(f"is_dir={os.path.isdir(f)}")
with runner.isolated_filesystem():
result = runner.invoke(showtype, ["-f", "xxx"])
@@ -321,7 +321,7 @@ def test_path_option(runner):
@click.command()
@click.option("-f", type=click.Path())
def exists(f):
- click.echo("exists={}".format(os.path.exists(f)))
+ click.echo(f"exists={os.path.exists(f)}")
with runner.isolated_filesystem():
result = runner.invoke(exists, ["-f", "xxx"])
diff --git a/tests/test_chain.py b/tests/test_chain.py
index cf9b198..0462779 100644
--- a/tests/test_chain.py
+++ b/tests/test_chain.py
@@ -7,9 +7,8 @@ import click
def debug():
click.echo(
- "{}={}".format(
- sys._getframe(1).f_code.co_name, "|".join(click.get_current_context().args)
- )
+ f"{sys._getframe(1).f_code.co_name}"
+ f"={'|'.join(click.get_current_context().args)}"
)
diff --git a/tests/test_commands.py b/tests/test_commands.py
index 1e19746..eace114 100644
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -210,7 +210,7 @@ def test_object_propagation(runner):
@cli.command()
@click.pass_context
def sync(ctx):
- click.echo("Debug is {}".format("on" if ctx.obj["DEBUG"] else "off"))
+ click.echo(f"Debug is {'on' if ctx.obj['DEBUG'] else 'off'}")
result = runner.invoke(cli, ["sync"])
assert result.exception is None
@@ -264,7 +264,7 @@ def test_unprocessed_options(runner):
@click.option("--verbose", "-v", count=True)
def cli(verbose, args):
click.echo(f"Verbosity: {verbose}")
- click.echo("Args: {}".format("|".join(args)))
+ click.echo(f"Args: {'|'.join(args)}")
result = runner.invoke(cli, ["-foo", "-vvvvx", "--muhaha", "x", "y", "-x"])
assert not result.exception
diff --git a/tests/test_defaults.py b/tests/test_defaults.py
index d55b1f4..0e438eb 100644
--- a/tests/test_defaults.py
+++ b/tests/test_defaults.py
@@ -32,8 +32,8 @@ def test_nargs_plus_multiple(runner):
"--arg", default=((1, 2), (3, 4)), nargs=2, multiple=True, type=click.INT
)
def cli(arg):
- for item in arg:
- click.echo("<{0[0]:d}|{0[1]:d}>".format(item))
+ for a, b in arg:
+ click.echo(f"<{a:d}|{b:d}>")
result = runner.invoke(cli, [])
assert not result.exception
diff --git a/tests/test_options.py b/tests/test_options.py
index 95cdad5..1b9b27e 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -44,8 +44,8 @@ def test_nargs_tup_composite_mult(runner):
@click.command()
@click.option("--item", type=(str, int), multiple=True)
def copy(item):
- for item in item:
- click.echo("name={0[0]} id={0[1]:d}".format(item))
+ for name, id in item:
+ click.echo(f"name={name} id={id:d}")
result = runner.invoke(copy, ["--item", "peter", "1", "--item", "max", "2"])
assert not result.exception
@@ -421,12 +421,13 @@ def test_option_help_preserve_paragraphs(runner):
result = runner.invoke(cmd, ["--help"],)
assert result.exit_code == 0
+ i = " " * 21
assert (
" -C, --config PATH Configuration file to use.\n"
- "{i}\n"
- "{i}If not given, the environment variable CONFIG_FILE is\n"
- "{i}consulted and used if set. If neither are given, a default\n"
- "{i}configuration file is loaded.".format(i=" " * 21)
+ f"{i}\n"
+ f"{i}If not given, the environment variable CONFIG_FILE is\n"
+ f"{i}consulted and used if set. If neither are given, a default\n"
+ f"{i}configuration file is loaded."
) in result.output
diff --git a/tests/test_termui.py b/tests/test_termui.py
index 616ab7d..7165023 100644
--- a/tests/test_termui.py
+++ b/tests/test_termui.py
@@ -247,7 +247,7 @@ def test_file_prompt_default_format(runner, file_kwargs):
click.echo(f.name)
result = runner.invoke(cli)
- assert result.output == "file [{0}]: \n{0}\n".format(__file__)
+ assert result.output == f"file [{__file__}]: \n{__file__}\n"
def test_secho(runner):
@@ -354,7 +354,7 @@ def test_getchar_special_key_windows(runner, monkeypatch, special_key_char, key_
click._termui_impl.msvcrt, "getwch", lambda: ordered_inputs.pop()
)
monkeypatch.setattr(click.termui, "_getchar", None)
- assert click.getchar() == special_key_char + key_char
+ assert click.getchar() == f"{special_key_char}{key_char}"
@pytest.mark.parametrize(
diff --git a/tests/test_testing.py b/tests/test_testing.py
index 5b2c813..7360473 100644
--- a/tests/test_testing.py
+++ b/tests/test_testing.py
@@ -125,7 +125,7 @@ def test_with_color():
assert not result.exception
result = runner.invoke(cli, color=True)
- assert result.output == "{}\n".format(click.style("hello world", fg="blue"))
+ assert result.output == f"{click.style('hello world', fg='blue')}\n"
assert not result.exception
@@ -213,7 +213,7 @@ def test_exit_code_and_output_from_sys_exit():
def test_env():
@click.command()
def cli_env():
- click.echo("ENV={}".format(os.environ["TEST_CLICK_ENV"]))
+ click.echo(f"ENV={os.environ['TEST_CLICK_ENV']}")
runner = CliRunner()