• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

oir / startle / 21615607726

03 Feb 2026 03:22AM UTC coverage: 98.73% (+0.05%) from 98.676%
21615607726

Pull #134

github

web-flow
Merge 376a83c47 into a5d20b7fa
Pull Request #134: Untitled refactor PR

250 of 250 branches covered (100.0%)

Branch coverage included in aggregate %.

1227 of 1246 relevant lines covered (98.48%)

0.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.44
startle/error.py
1
from typing import Any
1✔
2

3

4
class ParserOptionError(Exception):
1✔
5
    """
6
    Exception raised when there is an error providing an option to the parser.
7
    """
8

9
    pass
1✔
10

11

12
class ParserValueError(ValueError):
1✔
13
    """
14
    Exception raised when there is an error parsing a value.
15
    """
16

17
    pass
1✔
18

19

20
class ParserConfigError(Exception):
1✔
21
    """
22
    Exception raised when there is an error in the parser configuration
23
    (during construction of the parser, prior to parsing).
24
    """
25

26
    pass
1✔
27

28

29
# Below are the specific errors derived from one of the above base errors
30

31

32
class MissingOptionNameError(ParserOptionError):
1✔
33
    """
34
    Exception raised when `-` does not have a name following it.
35
    """
36

37
    def __init__(self) -> None:
1✔
38
        super().__init__("Prefix `-` is not followed by an option!")
1✔
39

40

41
class MissingOptionValueError(ParserOptionError):
1✔
42
    """
43
    Exception raised when an option is missing an argument value
44
    (e.g. `--option` is given but no value follows).
45
    """
46

47
    def __init__(self, name: str) -> None:
1✔
48
        super().__init__(f"Option `{name}` is missing argument!")
1✔
49

50

51
class MissingRequiredOptionError(ParserOptionError):
1✔
52
    """
53
    Exception raised when a required option is missing.
54
    """
55

56
    def __init__(self, name: str) -> None:
1✔
57
        super().__init__(f"Required option `{name}` is not provided!")
1✔
58

59

60
class MissingRequiredPositionalArgumentError(ParserOptionError):
1✔
61
    """
62
    Exception raised when a required positional argument is missing.
63
    """
64

65
    def __init__(self, long_name: str) -> None:
1✔
66
        super().__init__(f"Required positional argument <{long_name}> is not provided!")
1✔
67

68

69
class UnexpectedOptionError(ParserOptionError):
1✔
70
    """
71
    Exception raised when an unexpected option is provided to the parser.
72
    """
73

74
    def __init__(self, name: str) -> None:
1✔
75
        super().__init__(f"Unexpected option `{name}`!")
1✔
76

77

78
class UnexpectedPositionalArgumentError(ParserOptionError):
1✔
79
    """
80
    Exception raised when an unexpected positional argument is provided to the parser.
81
    """
82

83
    def __init__(self, value: str) -> None:
1✔
84
        super().__init__(f"Unexpected positional argument: `{value}`!")
1✔
85

86

87
class DuplicateOptionError(ParserOptionError):
1✔
88
    """
89
    Exception raised when a duplicate option is provided to the parser when it is not n-ary.
90
    """
91

92
    def __init__(self, name: str) -> None:
1✔
93
        super().__init__(f"Option `{name}` is multiply given!")
1✔
94

95

96
class DuplicatePositionalArgumentError(ParserOptionError):
1✔
97
    """
98
    Exception raised when a duplicate positional argument is provided to the parser when it is not n-ary.
99
    This is practically impossible to happen via command-line input, but kept for
100
    completeness and programming errors.
101
    """
102

103
    def __init__(self, name: str) -> None:
1✔
104
        super().__init__(f"Positional argument `{name}` is multiply given!")
×
105

106

107
class FlagWithValueError(ParserOptionError):
1✔
108
    """
109
    Exception raised when a flag option is provided with a value via --option=value syntax.
110
    """
111

112
    def __init__(self, name: str) -> None:
1✔
113
        super().__init__(f"Option `{name}` is a flag and cannot be assigned a value!")
1✔
114

115

116
class NonFlagInShortNameCombinationError(ParserOptionError):
1✔
117
    """
118
    Exception raised when a non-flag option is used in a short name combination (e.g. -abc),
119
    not as the last one.
120
    """
121

122
    def __init__(self, name: str) -> None:
1✔
123
        super().__init__(f"Option `{name}` is not a flag and cannot be combined!")
1✔
124

125

126
class NameCollisionError(ParserConfigError):
1✔
127
    """
128
    Exception raised when there is a name collision in the parser configuration during
129
    recursive parsing with `flat` naming.
130
    """
131

132
    def __init__(self, name: str, obj_name: str) -> None:
1✔
133
        super().__init__(
1✔
134
            f"Option name `{name}` is used multiple times in `{obj_name}`!"
135
            " Recursive parsing with `flat` naming requires unique option names among all levels."
136
        )
137

138

139
class HelpCollisionError(ParserConfigError):
1✔
140
    """
141
    Exception raised when `help` is used as a parameter name.
142
    """
143

144
    def __init__(self, obj_name: str) -> None:
1✔
145
        super().__init__(f"Cannot use `help` as parameter name in `{obj_name}`!")
1✔
146

147

148
class VariadicChildParamError(ParserConfigError):
1✔
149
    """
150
    Exception raised when a variadic parameter is found in child Args during recursive parsing.
151
    """
152

153
    def __init__(self, param_name: str, obj_name: str) -> None:
1✔
154
        super().__init__(
1✔
155
            f"Cannot have variadic parameter `{param_name}` in child Args of `{obj_name}`!"
156
        )
157

158

159
class VariadicNonRecursableParamError(ParserConfigError):
1✔
160
    def __init__(self, param_name: str, obj_name: str) -> None:
1✔
161
        super().__init__(
1✔
162
            f"Cannot recurse into variadic parameter `{param_name}` in `{obj_name}`!"
163
        )
164

165

166
class NaryNonRecursableParamError(ParserConfigError):
1✔
167
    def __init__(self, param_name: str, obj_name: str) -> None:
1✔
168
        super().__init__(
1✔
169
            f"Cannot recurse into n-ary parameter `{param_name}` in `{obj_name}`!"
170
        )
171

172

173
class NonClassNonRecursableParamError(ParserConfigError):
1✔
174
    def __init__(self, param_name: str, annotation: Any, obj_name: str) -> None:
1✔
175
        super().__init__(
1✔
176
            f"Cannot recurse into parameter `{param_name}` of non-class type "
177
            f"`{annotation}` in `{obj_name}`!"
178
        )
179

180

181
class UnsupportedTypeError(ParserConfigError):
1✔
182
    """
183
    Exception raised when an unsupported type is encountered during parser construction.
184
    """
185

186
    def __init__(self, param_name: str, annotation: Any, obj_name: str) -> None:
1✔
187
        super().__init__(
1✔
188
            f"Unsupported type `{annotation}` for parameter `{param_name}` in `{obj_name}`!"
189
        )
190

191

192
class MissingNameError(ParserConfigError):
1✔
193
    """
194
    Exception raised when both long and short names are missing when initializing `Name`.
195
    """
196

197
    def __init__(self) -> None:
1✔
198
        super().__init__("Named arguments should have at least one name!")
1✔
199

200

201
class MissingContainerTypeError(ParserConfigError):
1✔
202
    """
203
    Exception raised when a n-ary parameter is missing a container type.
204
    """
205

206
    def __init__(self) -> None:
1✔
207
        super().__init__("Container type must be specified for n-ary options!")
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc