Skip to content
Open
9 changes: 8 additions & 1 deletion src/click/_termui_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,14 @@ def format_eta(self) -> str:
hours = t % 24
t //= 24
if t > 0:
return f"{t}d {hours:02}:{minutes:02}:{seconds:02}"
return "{d}{day_label} {h:02}:{m:02}:{s:02}".format(
d=t,
# TRANSLATORS: The 'd' stands for 'day'.
day_label=_("d"),
h=hours,
m=minutes,
s=seconds,
)
else:
return f"{hours:02}:{minutes:02}:{seconds:02}"
return ""
Expand Down
5 changes: 3 additions & 2 deletions src/click/_winconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from ctypes.wintypes import HANDLE
from ctypes.wintypes import LPCWSTR
from ctypes.wintypes import LPWSTR
from gettext import gettext as _

from ._compat import _NonClosingTextIOWrapper

Expand Down Expand Up @@ -152,7 +153,7 @@ def readinto(self, b: Buffer) -> int:
# wait for KeyboardInterrupt
time.sleep(0.1)
if not rv:
raise OSError(f"Windows error: {GetLastError()}")
raise OSError(_("Windows error: {error}").format(error=GetLastError()))

if buffer[0] == EOF:
return 0
Expand All @@ -169,7 +170,7 @@ def _get_error_message(errno: int) -> str:
return "ERROR_SUCCESS"
elif errno == ERROR_NOT_ENOUGH_MEMORY:
return "ERROR_NOT_ENOUGH_MEMORY"
return f"Windows error {errno}"
return _("Windows error: {error}").format(error=errno)

def write(self, b: Buffer) -> int:
bytes_to_be_written = len(b)
Expand Down
26 changes: 17 additions & 9 deletions src/click/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2902,7 +2902,7 @@ def _parse_decls(
for decl in decls:
if decl.isidentifier():
if name is not None:
raise TypeError(f"Name '{name}' defined twice")
raise TypeError(_("Name '{name}' defined twice").format(name=name))
name = decl
else:
split_char = ";" if decl[:1] == "/" else "/"
Expand All @@ -2917,8 +2917,10 @@ def _parse_decls(
secondary_opts.append(second.lstrip())
if first == second:
raise ValueError(
f"Boolean option {decl!r} cannot use the"
" same flag for true/false."
_(
"Boolean option {decl!r} cannot use the"
" same flag for true/false."
).format(decl=decl)
)
else:
possible_names.append(_split_opt(decl))
Expand All @@ -2934,14 +2936,18 @@ def _parse_decls(
if not expose_value:
return None, opts, secondary_opts
raise TypeError(
f"Could not determine name for option with declarations {decls!r}"
_(
"Could not determine name for option with declarations {decls!r}"
).format(decls=decls)
)

if not opts and not secondary_opts:
raise TypeError(
f"No options defined but a name was passed ({name})."
" Did you mean to declare an argument instead? Did"
f" you mean to pass '--{name}'?"
_(
"No options defined but a name was passed ({name})."
" Did you mean to declare an argument instead? Did"
" you mean to pass '--{name}'?"
).format(name=name)
)

return name, opts, secondary_opts
Expand Down Expand Up @@ -3379,8 +3385,10 @@ def _parse_decls(
name = name.replace("-", "_").lower()
else:
raise TypeError(
"Arguments take exactly one parameter declaration, got"
f" {len(decls)}: {decls}."
_(
"Arguments take exactly one parameter declaration, got"
" {length}: {decls}."
).format(length=len(decls), decls=decls)
)
return name, [arg], []

Expand Down
2 changes: 1 addition & 1 deletion src/click/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def new_func(*args: P.args, **kwargs: P.kwargs) -> R:
if doc_description is None:
doc_description = f"the {key!r} key from :attr:`click.Context.meta`"

decorator.__doc__ = (
decorator.__doc__ = _(
f"Decorator that passes {doc_description} as the first argument"
" to the decorated function."
)
Expand Down
2 changes: 1 addition & 1 deletion src/click/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def write_usage(self, prog: str, args: str = "", prefix: str | None = None) -> N
``"Usage: "``.
"""
if prefix is None:
prefix = f"{_('Usage:')} "
prefix = "{usage} ".format(usage=_("Usage:"))

usage_prefix = f"{prefix:>{self.current_indent}}{prog} "
text_width = self.width - self.current_indent
Expand Down
6 changes: 5 additions & 1 deletion src/click/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ def __init__(
for opt in opts:
prefix, value = _split_opt(opt)
if not prefix:
raise ValueError(f"Invalid start character for option ({opt})")
raise ValueError(
_("Invalid start character for option ({option})").format(
option=opt
)
)
self.prefixes.add(prefix[0])
if len(prefix) == 1 and len(value) == 1:
self._short_opts.append(opt)
Expand Down
4 changes: 2 additions & 2 deletions src/click/termui.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,13 +614,13 @@ def style(
try:
bits.append(f"\033[{_interpret_color(fg)}m")
except KeyError:
raise TypeError(f"Unknown color {fg!r}") from None
raise TypeError(_("Unknown color {colour!r}").format(colour=fg)) from None

if bg:
try:
bits.append(f"\033[{_interpret_color(bg, 10)}m")
except KeyError:
raise TypeError(f"Unknown color {bg!r}") from None
raise TypeError(_("Unknown color {colour!r}").format(colour=bg)) from None

if bold is not None:
bits.append(f"\033[{1 if bold else 22}m")
Expand Down
8 changes: 6 additions & 2 deletions src/click/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ def get_invalid_choice_message(self, value: t.Any, ctx: Context | None) -> str:
).format(value=value, choice=choices_str, choices=choices_str)

def __repr__(self) -> str:
return f"Choice({list(self.choices)})"
return _("Choice({choices})").format(choices=list(self.choices))

def shell_complete(
self, ctx: Context, param: Parameter, incomplete: str
Expand Down Expand Up @@ -853,7 +853,11 @@ def convert(

return f
except OSError as e:
self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx)
self.fail(
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reformatting from ruff 0.14.10's format command.

f"'{format_filename(value)}': {e.strerror}",
param,
ctx,
)

def shell_complete(
self, ctx: Context, param: Parameter, incomplete: str
Expand Down
5 changes: 3 additions & 2 deletions src/click/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import sys
import typing as t
from functools import update_wrapper
from gettext import gettext as _
from types import ModuleType
from types import TracebackType

Expand Down Expand Up @@ -330,7 +331,7 @@ def get_binary_stream(name: t.Literal["stdin", "stdout", "stderr"]) -> t.BinaryI
"""
opener = binary_streams.get(name)
if opener is None:
raise TypeError(f"Unknown standard stream '{name}'")
raise TypeError(_("Unknown standard stream '{name}'").format(name=name))
return opener()


Expand All @@ -351,7 +352,7 @@ def get_text_stream(
"""
opener = text_streams.get(name)
if opener is None:
raise TypeError(f"Unknown standard stream '{name}'")
raise TypeError(_("Unknown standard stream '{name}'").format(name=name))
return opener(encoding, errors)


Expand Down