|
29 | 29 |
|
30 | 30 | __all__ = [ |
31 | 31 | "ActionConfigFile", |
32 | | - "ActionYesNo", |
| 32 | + "ActionFail", |
33 | 33 | "ActionParser", |
| 34 | + "ActionYesNo", |
34 | 35 | ] |
35 | 36 |
|
36 | 37 |
|
@@ -65,7 +66,7 @@ def _find_action_and_subcommand( |
65 | 66 | fallback_action = None |
66 | 67 | for action in actions: |
67 | 68 | if action.dest == dest or f"--{dest}" in action.option_strings: |
68 | | - if isinstance(action, _ActionConfigLoad): |
| 69 | + if isinstance(action, (_ActionConfigLoad, ActionFail)): |
69 | 70 | fallback_action = action |
70 | 71 | else: |
71 | 72 | return action, None |
@@ -435,6 +436,34 @@ def get_args_after_opt(self, args): |
435 | 436 | return args[num + 1 :] |
436 | 437 |
|
437 | 438 |
|
| 439 | +class ActionFail(Action): |
| 440 | + """Action that always fails parsing with a given error.""" |
| 441 | + |
| 442 | + def __init__(self, message: str = "option unavailable", **kwargs): |
| 443 | + """Initializer for ActionFail instance. |
| 444 | +
|
| 445 | + Args: |
| 446 | + message: Text for the error to show. Use `%(option)s`/`%(value)s` to include the option and/or value. |
| 447 | + """ |
| 448 | + if len(kwargs) == 0: |
| 449 | + self._message = message |
| 450 | + else: |
| 451 | + self._message = kwargs.pop("_message") |
| 452 | + kwargs["default"] = SUPPRESS |
| 453 | + kwargs["required"] = False |
| 454 | + if kwargs["option_strings"] == []: |
| 455 | + kwargs["nargs"] = "?" |
| 456 | + super().__init__(**kwargs) |
| 457 | + |
| 458 | + def __call__(self, *args, **kwargs): |
| 459 | + """Always fails with given message.""" |
| 460 | + if len(args) == 0: |
| 461 | + kwargs["_message"] = self._message |
| 462 | + return ActionFail(**kwargs) |
| 463 | + parser, _, value, option = args |
| 464 | + parser.error(self._message % {"value": value, "option": option}) |
| 465 | + |
| 466 | + |
438 | 467 | class ActionYesNo(Action): |
439 | 468 | """Paired options --[yes_prefix]opt, --[no_prefix]opt to set True or False respectively.""" |
440 | 469 |
|
|
0 commit comments