Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/click/exceptions.py: 33%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3import collections.abc as cabc
4import typing as t
5from gettext import gettext as _
6from gettext import ngettext
8from ._compat import get_text_stderr
9from .globals import resolve_color_default
10from .utils import echo
11from .utils import format_filename
13if t.TYPE_CHECKING:
14 from .core import Command
15 from .core import Context
16 from .core import Parameter
19def _join_param_hints(param_hint: cabc.Sequence[str] | str | None) -> str | None:
20 if param_hint is not None and not isinstance(param_hint, str):
21 return " / ".join(repr(x) for x in param_hint)
23 return param_hint
26class ClickException(Exception):
27 """An exception that Click can handle and show to the user."""
29 #: The exit code for this exception.
30 exit_code = 1
32 def __init__(self, message: str) -> None:
33 super().__init__(message)
34 # The context will be removed by the time we print the message, so cache
35 # the color settings here to be used later on (in `show`)
36 self.show_color: bool | None = resolve_color_default()
37 self.message = message
39 def format_message(self) -> str:
40 return self.message
42 def __str__(self) -> str:
43 return self.message
45 def show(self, file: t.IO[t.Any] | None = None) -> None:
46 if file is None:
47 file = get_text_stderr()
49 echo(
50 _("Error: {message}").format(message=self.format_message()),
51 file=file,
52 color=self.show_color,
53 )
56class UsageError(ClickException):
57 """An internal exception that signals a usage error. This typically
58 aborts any further handling.
60 :param message: the error message to display.
61 :param ctx: optionally the context that caused this error. Click will
62 fill in the context automatically in some situations.
63 """
65 exit_code = 2
67 def __init__(self, message: str, ctx: Context | None = None) -> None:
68 super().__init__(message)
69 self.ctx = ctx
70 self.cmd: Command | None = self.ctx.command if self.ctx else None
72 def show(self, file: t.IO[t.Any] | None = None) -> None:
73 if file is None:
74 file = get_text_stderr()
75 color = None
76 hint = ""
77 if (
78 self.ctx is not None
79 and self.ctx.command.get_help_option(self.ctx) is not None
80 ):
81 hint = _("Try '{command} {option}' for help.").format(
82 command=self.ctx.command_path, option=self.ctx.help_option_names[0]
83 )
84 hint = f"{hint}\n"
85 if self.ctx is not None:
86 color = self.ctx.color
87 echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color)
88 echo(
89 _("Error: {message}").format(message=self.format_message()),
90 file=file,
91 color=color,
92 )
95class BadParameter(UsageError):
96 """An exception that formats out a standardized error message for a
97 bad parameter. This is useful when thrown from a callback or type as
98 Click will attach contextual information to it (for instance, which
99 parameter it is).
101 .. versionadded:: 2.0
103 :param param: the parameter object that caused this error. This can
104 be left out, and Click will attach this info itself
105 if possible.
106 :param param_hint: a string that shows up as parameter name. This
107 can be used as alternative to `param` in cases
108 where custom validation should happen. If it is
109 a string it's used as such, if it's a list then
110 each item is quoted and separated.
111 """
113 def __init__(
114 self,
115 message: str,
116 ctx: Context | None = None,
117 param: Parameter | None = None,
118 param_hint: cabc.Sequence[str] | str | None = None,
119 ) -> None:
120 super().__init__(message, ctx)
121 self.param = param
122 self.param_hint = param_hint
124 def format_message(self) -> str:
125 if self.param_hint is not None:
126 param_hint = self.param_hint
127 elif self.param is not None:
128 param_hint = self.param.get_error_hint(self.ctx) # type: ignore
129 else:
130 return _("Invalid value: {message}").format(message=self.message)
132 return _("Invalid value for {param_hint}: {message}").format(
133 param_hint=_join_param_hints(param_hint), message=self.message
134 )
137class MissingParameter(BadParameter):
138 """Raised if click required an option or argument but it was not
139 provided when invoking the script.
141 .. versionadded:: 4.0
143 :param param_type: a string that indicates the type of the parameter.
144 The default is to inherit the parameter type from
145 the given `param`. Valid values are ``'parameter'``,
146 ``'option'`` or ``'argument'``.
147 """
149 def __init__(
150 self,
151 message: str | None = None,
152 ctx: Context | None = None,
153 param: Parameter | None = None,
154 param_hint: cabc.Sequence[str] | str | None = None,
155 param_type: str | None = None,
156 ) -> None:
157 super().__init__(message or "", ctx, param, param_hint)
158 self.param_type = param_type
160 def format_message(self) -> str:
161 if self.param_hint is not None:
162 param_hint: cabc.Sequence[str] | str | None = self.param_hint
163 elif self.param is not None:
164 param_hint = self.param.get_error_hint(self.ctx) # type: ignore
165 else:
166 param_hint = None
168 param_hint = _join_param_hints(param_hint)
169 param_hint = f" {param_hint}" if param_hint else ""
171 param_type = self.param_type
172 if param_type is None and self.param is not None:
173 param_type = self.param.param_type_name
175 msg = self.message
176 if self.param is not None:
177 msg_extra = self.param.type.get_missing_message(
178 param=self.param, ctx=self.ctx
179 )
180 if msg_extra:
181 if msg:
182 msg += f". {msg_extra}"
183 else:
184 msg = msg_extra
186 msg = f" {msg}" if msg else ""
188 # Translate param_type for known types.
189 if param_type == "argument":
190 missing = _("Missing argument")
191 elif param_type == "option":
192 missing = _("Missing option")
193 elif param_type == "parameter":
194 missing = _("Missing parameter")
195 else:
196 missing = _("Missing {param_type}").format(param_type=param_type)
198 return f"{missing}{param_hint}.{msg}"
200 def __str__(self) -> str:
201 if not self.message:
202 param_name = self.param.name if self.param else None
203 return _("Missing parameter: {param_name}").format(param_name=param_name)
204 else:
205 return self.message
208class NoSuchOption(UsageError):
209 """Raised if click attempted to handle an option that does not
210 exist.
212 .. versionadded:: 4.0
213 """
215 def __init__(
216 self,
217 option_name: str,
218 message: str | None = None,
219 possibilities: cabc.Sequence[str] | None = None,
220 ctx: Context | None = None,
221 ) -> None:
222 if message is None:
223 message = _("No such option: {name}").format(name=option_name)
225 super().__init__(message, ctx)
226 self.option_name = option_name
227 self.possibilities = possibilities
229 def format_message(self) -> str:
230 if not self.possibilities:
231 return self.message
233 possibility_str = ", ".join(sorted(self.possibilities))
234 suggest = ngettext(
235 "Did you mean {possibility}?",
236 "(Possible options: {possibilities})",
237 len(self.possibilities),
238 ).format(possibility=possibility_str, possibilities=possibility_str)
239 return f"{self.message} {suggest}"
242class BadOptionUsage(UsageError):
243 """Raised if an option is generally supplied but the use of the option
244 was incorrect. This is for instance raised if the number of arguments
245 for an option is not correct.
247 .. versionadded:: 4.0
249 :param option_name: the name of the option being used incorrectly.
250 """
252 def __init__(
253 self, option_name: str, message: str, ctx: Context | None = None
254 ) -> None:
255 super().__init__(message, ctx)
256 self.option_name = option_name
259class BadArgumentUsage(UsageError):
260 """Raised if an argument is generally supplied but the use of the argument
261 was incorrect. This is for instance raised if the number of values
262 for an argument is not correct.
264 .. versionadded:: 6.0
265 """
268class NoArgsIsHelpError(UsageError):
269 def __init__(self, ctx: Context) -> None:
270 self.ctx: Context
271 super().__init__(ctx.get_help(), ctx=ctx)
273 def show(self, file: t.IO[t.Any] | None = None) -> None:
274 echo(self.format_message(), file=file, err=True, color=self.ctx.color)
277class FileError(ClickException):
278 """Raised if a file cannot be opened."""
280 def __init__(self, filename: str, hint: str | None = None) -> None:
281 if hint is None:
282 hint = _("unknown error")
284 super().__init__(hint)
285 self.ui_filename: str = format_filename(filename)
286 self.filename = filename
288 def format_message(self) -> str:
289 return _("Could not open file {filename!r}: {message}").format(
290 filename=self.ui_filename, message=self.message
291 )
294class Abort(RuntimeError):
295 """An internal signalling exception that signals Click to abort."""
298class Exit(RuntimeError):
299 """An exception that indicates that the application should exit with some
300 status code.
302 :param code: the status code to exit with.
303 """
305 __slots__ = ("exit_code",)
307 def __init__(self, code: int = 0) -> None:
308 self.exit_code: int = code