Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/click/exceptions.py: 32%
117 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1import os
2import typing as t
3from gettext import gettext as _
4from gettext import ngettext
6from ._compat import get_text_stderr
7from .utils import echo
9if t.TYPE_CHECKING: 9 ↛ 10line 9 didn't jump to line 10, because the condition on line 9 was never true
10 from .core import Context
11 from .core import Parameter
14def _join_param_hints(
15 param_hint: t.Optional[t.Union[t.Sequence[str], str]]
16) -> t.Optional[str]:
17 if param_hint is not None and not isinstance(param_hint, str):
18 return " / ".join(repr(x) for x in param_hint)
20 return param_hint
23class ClickException(Exception):
24 """An exception that Click can handle and show to the user."""
26 #: The exit code for this exception.
27 exit_code = 1
29 def __init__(self, message: str) -> None:
30 super().__init__(message)
31 self.message = message
33 def format_message(self) -> str:
34 return self.message
36 def __str__(self) -> str:
37 return self.message
39 def show(self, file: t.Optional[t.IO] = None) -> None:
40 if file is None:
41 file = get_text_stderr()
43 echo(_("Error: {message}").format(message=self.format_message()), file=file)
46class UsageError(ClickException):
47 """An internal exception that signals a usage error. This typically
48 aborts any further handling.
50 :param message: the error message to display.
51 :param ctx: optionally the context that caused this error. Click will
52 fill in the context automatically in some situations.
53 """
55 exit_code = 2
57 def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None:
58 super().__init__(message)
59 self.ctx = ctx
60 self.cmd = self.ctx.command if self.ctx else None
62 def show(self, file: t.Optional[t.IO] = None) -> None:
63 if file is None:
64 file = get_text_stderr()
65 color = None
66 hint = ""
67 if (
68 self.ctx is not None
69 and self.ctx.command.get_help_option(self.ctx) is not None
70 ):
71 hint = _("Try '{command} {option}' for help.").format(
72 command=self.ctx.command_path, option=self.ctx.help_option_names[0]
73 )
74 hint = f"{hint}\n"
75 if self.ctx is not None:
76 color = self.ctx.color
77 echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color)
78 echo(
79 _("Error: {message}").format(message=self.format_message()),
80 file=file,
81 color=color,
82 )
85class BadParameter(UsageError):
86 """An exception that formats out a standardized error message for a
87 bad parameter. This is useful when thrown from a callback or type as
88 Click will attach contextual information to it (for instance, which
89 parameter it is).
91 .. versionadded:: 2.0
93 :param param: the parameter object that caused this error. This can
94 be left out, and Click will attach this info itself
95 if possible.
96 :param param_hint: a string that shows up as parameter name. This
97 can be used as alternative to `param` in cases
98 where custom validation should happen. If it is
99 a string it's used as such, if it's a list then
100 each item is quoted and separated.
101 """
103 def __init__(
104 self,
105 message: str,
106 ctx: t.Optional["Context"] = None,
107 param: t.Optional["Parameter"] = None,
108 param_hint: t.Optional[str] = None,
109 ) -> None:
110 super().__init__(message, ctx)
111 self.param = param
112 self.param_hint = param_hint
114 def format_message(self) -> str:
115 if self.param_hint is not None:
116 param_hint = self.param_hint
117 elif self.param is not None:
118 param_hint = self.param.get_error_hint(self.ctx) # type: ignore
119 else:
120 return _("Invalid value: {message}").format(message=self.message)
122 return _("Invalid value for {param_hint}: {message}").format(
123 param_hint=_join_param_hints(param_hint), message=self.message
124 )
127class MissingParameter(BadParameter):
128 """Raised if click required an option or argument but it was not
129 provided when invoking the script.
131 .. versionadded:: 4.0
133 :param param_type: a string that indicates the type of the parameter.
134 The default is to inherit the parameter type from
135 the given `param`. Valid values are ``'parameter'``,
136 ``'option'`` or ``'argument'``.
137 """
139 def __init__(
140 self,
141 message: t.Optional[str] = None,
142 ctx: t.Optional["Context"] = None,
143 param: t.Optional["Parameter"] = None,
144 param_hint: t.Optional[str] = None,
145 param_type: t.Optional[str] = None,
146 ) -> None:
147 super().__init__(message or "", ctx, param, param_hint)
148 self.param_type = param_type
150 def format_message(self) -> str:
151 if self.param_hint is not None:
152 param_hint: t.Optional[str] = self.param_hint
153 elif self.param is not None:
154 param_hint = self.param.get_error_hint(self.ctx) # type: ignore
155 else:
156 param_hint = None
158 param_hint = _join_param_hints(param_hint)
159 param_hint = f" {param_hint}" if param_hint else ""
161 param_type = self.param_type
162 if param_type is None and self.param is not None:
163 param_type = self.param.param_type_name
165 msg = self.message
166 if self.param is not None:
167 msg_extra = self.param.type.get_missing_message(self.param)
168 if msg_extra:
169 if msg:
170 msg += f". {msg_extra}"
171 else:
172 msg = msg_extra
174 msg = f" {msg}" if msg else ""
176 # Translate param_type for known types.
177 if param_type == "argument":
178 missing = _("Missing argument")
179 elif param_type == "option":
180 missing = _("Missing option")
181 elif param_type == "parameter":
182 missing = _("Missing parameter")
183 else:
184 missing = _("Missing {param_type}").format(param_type=param_type)
186 return f"{missing}{param_hint}.{msg}"
188 def __str__(self) -> str:
189 if not self.message:
190 param_name = self.param.name if self.param else None
191 return _("Missing parameter: {param_name}").format(param_name=param_name)
192 else:
193 return self.message
196class NoSuchOption(UsageError):
197 """Raised if click attempted to handle an option that does not
198 exist.
200 .. versionadded:: 4.0
201 """
203 def __init__(
204 self,
205 option_name: str,
206 message: t.Optional[str] = None,
207 possibilities: t.Optional[t.Sequence[str]] = None,
208 ctx: t.Optional["Context"] = None,
209 ) -> None:
210 if message is None:
211 message = _("No such option: {name}").format(name=option_name)
213 super().__init__(message, ctx)
214 self.option_name = option_name
215 self.possibilities = possibilities
217 def format_message(self) -> str:
218 if not self.possibilities:
219 return self.message
221 possibility_str = ", ".join(sorted(self.possibilities))
222 suggest = ngettext(
223 "Did you mean {possibility}?",
224 "(Possible options: {possibilities})",
225 len(self.possibilities),
226 ).format(possibility=possibility_str, possibilities=possibility_str)
227 return f"{self.message} {suggest}"
230class BadOptionUsage(UsageError):
231 """Raised if an option is generally supplied but the use of the option
232 was incorrect. This is for instance raised if the number of arguments
233 for an option is not correct.
235 .. versionadded:: 4.0
237 :param option_name: the name of the option being used incorrectly.
238 """
240 def __init__(
241 self, option_name: str, message: str, ctx: t.Optional["Context"] = None
242 ) -> None:
243 super().__init__(message, ctx)
244 self.option_name = option_name
247class BadArgumentUsage(UsageError):
248 """Raised if an argument is generally supplied but the use of the argument
249 was incorrect. This is for instance raised if the number of values
250 for an argument is not correct.
252 .. versionadded:: 6.0
253 """
256class FileError(ClickException):
257 """Raised if a file cannot be opened."""
259 def __init__(self, filename: str, hint: t.Optional[str] = None) -> None:
260 if hint is None:
261 hint = _("unknown error")
263 super().__init__(hint)
264 self.ui_filename = os.fsdecode(filename)
265 self.filename = filename
267 def format_message(self) -> str:
268 return _("Could not open file {filename!r}: {message}").format(
269 filename=self.ui_filename, message=self.message
270 )
273class Abort(RuntimeError):
274 """An internal signalling exception that signals Click to abort."""
277class Exit(RuntimeError):
278 """An exception that indicates that the application should exit with some
279 status code.
281 :param code: the status code to exit with.
282 """
284 __slots__ = ("exit_code",)
286 def __init__(self, code: int = 0) -> None:
287 self.exit_code = code