Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/face/errors.py: 46%
65 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:23 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:23 +0000
2from boltons.iterutils import unique
4import face.utils
6class FaceException(Exception):
7 """The basest base exception Face has. Rarely directly instantiated
8 if ever, but useful for catching.
9 """
10 pass
13class ArgumentParseError(FaceException):
14 """A base exception used for all errors raised during argument
15 parsing.
17 Many subtypes have a ".from_parse()" classmethod that creates an
18 exception message from the values available during the parse
19 process.
20 """
21 pass
24class ArgumentArityError(ArgumentParseError):
25 """Raised when too many or too few positional arguments are passed to
26 the command. See PosArgSpec for more info.
27 """
28 pass
31class InvalidSubcommand(ArgumentParseError):
32 """
33 Raised when an unrecognized subcommand is passed.
34 """
35 @classmethod
36 def from_parse(cls, prs, subcmd_name):
37 # TODO: add edit distance calculation
38 valid_subcmds = unique([path[:1][0] for path in prs.subprs_map.keys()])
39 msg = ('unknown subcommand "%s", choose from: %s'
40 % (subcmd_name, ', '.join(valid_subcmds)))
41 return cls(msg)
44class UnknownFlag(ArgumentParseError):
45 """
46 Raised when an unrecognized flag is passed.
47 """
48 @classmethod
49 def from_parse(cls, cmd_flag_map, flag_name):
50 # TODO: add edit distance calculation
51 valid_flags = unique([face.utils.format_flag_label(flag) for flag in
52 cmd_flag_map.values() if not flag.display.hidden])
53 msg = ('unknown flag "%s", choose from: %s'
54 % (flag_name, ', '.join(valid_flags)))
55 return cls(msg)
58class InvalidFlagArgument(ArgumentParseError):
59 """Raised when the argument passed to a flag (the value directly
60 after it in argv) fails to parse. Tries to automatically detect
61 when an argument is missing.
62 """
63 @classmethod
64 def from_parse(cls, cmd_flag_map, flag, arg, exc=None):
65 if arg is None:
66 return cls('expected argument for flag %s' % flag.name)
68 val_parser = flag.parse_as
69 vp_label = getattr(val_parser, 'display_name', face.utils.FRIENDLY_TYPE_NAMES.get(val_parser))
70 if vp_label is None:
71 vp_label = repr(val_parser)
72 tmpl = 'flag %s converter (%r) failed to parse value: %r'
73 else:
74 tmpl = 'flag %s expected a valid %s value, not %r'
75 msg = tmpl % (flag.name, vp_label, arg)
77 if exc:
78 # TODO: put this behind a verbose flag?
79 msg += ' (got error: %r)' % exc
80 if arg.startswith('-'):
81 msg += '. (Did you forget to pass an argument?)'
83 return cls(msg)
86class InvalidPositionalArgument(ArgumentParseError):
87 """Raised when one of the positional arguments does not
88 parse/validate as specified. See PosArgSpec for more info.
89 """
90 @classmethod
91 def from_parse(cls, posargspec, arg, exc):
92 prep, type_desc = face.utils.get_type_desc(posargspec.parse_as)
93 return cls('positional argument failed to parse %s'
94 ' %s: %r (got error: %r)' % (prep, type_desc, arg, exc))
97class MissingRequiredFlags(ArgumentParseError):
98 """
99 Raised when a required flag is not passed. See Flag for more info.
100 """
101 @classmethod
102 def from_parse(cls, cmd_flag_map, parsed_flag_map, missing_flag_names):
103 msg = ('missing required arguments for flags: %s'
104 % ', '.join(missing_flag_names))
105 return cls(msg)
108class DuplicateFlag(ArgumentParseError):
109 """Raised when a flag is passed multiple times, and the flag's
110 "multi" setting is set to 'error'.
111 """
112 @classmethod
113 def from_parse(cls, flag, arg_val_list):
114 avl_text = ', '.join([repr(v) for v in arg_val_list])
115 if callable(flag.parse_as):
116 msg = ('more than one value was passed for flag "%s": %s'
117 % (flag.name, avl_text))
118 else:
119 msg = ('flag "%s" was used multiple times, but can be used only once' % flag.name)
120 return cls(msg)
123## Non-parse related exceptions (used primarily in command.py instead of parser.py)
125class CommandLineError(FaceException, SystemExit):
126 """A :exc:`~face.FaceException` and :exc:`SystemExit` subtype that
127 enables safely catching runtime errors that would otherwise cause
128 the process to exit.
130 If instances of this exception are left uncaught, they will exit
131 the process.
133 If raised from a :meth:`~face.Command.run()` call and
134 ``print_error`` is True, face will print the error before
135 reraising. See :meth:`face.Command.run()` for more details.
136 """
137 def __init__(self, msg, code=1):
138 SystemExit.__init__(self, msg)
139 self.code = code
142class UsageError(CommandLineError):
143 """Application developers should raise this :exc:`CommandLineError`
144 subtype to indicate to users that the application user has used
145 the command incorrectly.
147 Instead of printing an ugly stack trace, Face will print a
148 readable error message of your choosing, then exit with a nonzero
149 exit code.
150 """
152 def format_message(self):
153 msg = self.args[0]
154 lines = msg.splitlines()
155 msg = '\n '.join(lines)
156 return 'error: ' + msg