cli-command-parser 2025.7.13__tar.gz → 2025.9.27__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/LICENSE +1 -1
  2. {cli_command_parser-2025.7.13/lib/cli_command_parser.egg-info → cli_command_parser-2025.9.27}/PKG-INFO +1 -1
  3. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/__init__.py +1 -1
  4. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/__version__.py +1 -1
  5. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/commands.py +22 -8
  6. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/choice_map.py +3 -3
  7. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27/lib/cli_command_parser.egg-info}/PKG-INFO +1 -1
  8. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/MANIFEST.in +0 -0
  9. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/entry_points.txt +0 -0
  10. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/__main__.py +0 -0
  11. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/annotations.py +0 -0
  12. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/command_parameters.py +0 -0
  13. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/compat.py +0 -0
  14. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/config.py +0 -0
  15. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/context.py +0 -0
  16. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/__init__.py +0 -0
  17. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/__main__.py +0 -0
  18. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/argparse_ast.py +0 -0
  19. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/argparse_utils.py +0 -0
  20. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/cli.py +0 -0
  21. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/command_builder.py +0 -0
  22. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/utils.py +0 -0
  23. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/conversion/visitor.py +0 -0
  24. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/core.py +0 -0
  25. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/documentation.py +0 -0
  26. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/error_handling/__init__.py +0 -0
  27. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/error_handling/base.py +0 -0
  28. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/error_handling/other.py +0 -0
  29. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/error_handling/windows.py +0 -0
  30. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/exceptions.py +0 -0
  31. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/formatting/__init__.py +0 -0
  32. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/formatting/commands.py +0 -0
  33. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/formatting/params.py +0 -0
  34. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/formatting/restructured_text.py +0 -0
  35. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/formatting/utils.py +0 -0
  36. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/__init__.py +0 -0
  37. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/base.py +0 -0
  38. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/choices.py +0 -0
  39. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/exceptions.py +0 -0
  40. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/files.py +0 -0
  41. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/numeric.py +0 -0
  42. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/patterns.py +0 -0
  43. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/time.py +0 -0
  44. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/inputs/utils.py +0 -0
  45. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/metadata.py +0 -0
  46. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/nargs.py +0 -0
  47. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/__init__.py +0 -0
  48. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/actions.py +0 -0
  49. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/base.py +0 -0
  50. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/groups.py +0 -0
  51. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/option_strings.py +0 -0
  52. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/options.py +0 -0
  53. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/pass_thru.py +0 -0
  54. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parameters/positionals.py +0 -0
  55. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parse_tree.py +0 -0
  56. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/parser.py +0 -0
  57. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/testing.py +0 -0
  58. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/typing.py +0 -0
  59. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser/utils.py +0 -0
  60. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser.egg-info/SOURCES.txt +0 -0
  61. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser.egg-info/dependency_links.txt +0 -0
  62. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser.egg-info/entry_points.txt +0 -0
  63. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser.egg-info/requires.txt +0 -0
  64. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/lib/cli_command_parser.egg-info/top_level.txt +0 -0
  65. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/pyproject.toml +0 -0
  66. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/readme.rst +0 -0
  67. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/requirements-dev.txt +0 -0
  68. {cli_command_parser-2025.7.13 → cli_command_parser-2025.9.27}/setup.cfg +0 -0
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright 2022 Doug Skrypa
189
+ Copyright 2025 Doug Skrypa
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli_command_parser
3
- Version: 2025.7.13
3
+ Version: 2025.9.27
4
4
  Summary: CLI Command Parser
5
5
  Home-page: https://github.com/dskrypa/cli_command_parser
6
6
  Author: Doug Skrypa
@@ -4,7 +4,7 @@ Command Parser
4
4
  :author: Doug Skrypa
5
5
  """
6
6
 
7
- from .commands import AsyncCommand, Command, main
7
+ from .commands import AsyncCommand, Command, main, print_help
8
8
  from .config import (
9
9
  AllowLeadingDash,
10
10
  AmbiguousComboMode,
@@ -1,7 +1,7 @@
1
1
  __title__ = 'cli_command_parser'
2
2
  __description__ = 'CLI Command Parser'
3
3
  __url__ = 'https://github.com/dskrypa/cli_command_parser'
4
- __version__ = '2025.07.13'
4
+ __version__ = '2025.09.27'
5
5
  __author__ = 'Doug Skrypa'
6
6
  __author_email__ = 'dskrypa@gmail.com'
7
7
  __license__ = 'Apache 2.0'
@@ -9,18 +9,18 @@ from __future__ import annotations
9
9
  import logging
10
10
  from abc import ABC
11
11
  from contextlib import ExitStack
12
- from typing import TYPE_CHECKING, Optional, Sequence, Type, overload
12
+ from typing import TYPE_CHECKING, Sequence, TextIO, Type, overload
13
13
 
14
14
  from .context import ActionPhase, Context, get_or_create_context
15
15
  from .core import CommandMeta, get_params, get_top_level_commands
16
- from .exceptions import ParamConflict
16
+ from .exceptions import ParamConflict, ParserExit
17
17
  from .parser import parse_args_and_get_next_cmd
18
18
  from .utils import maybe_await
19
19
 
20
20
  if TYPE_CHECKING:
21
21
  from .typing import Bool, CommandObj
22
22
 
23
- __all__ = ['Command', 'AsyncCommand', 'main']
23
+ __all__ = ['Command', 'AsyncCommand', 'main', 'print_help']
24
24
  log = logging.getLogger(__name__)
25
25
 
26
26
  Argv = Sequence[str]
@@ -50,13 +50,13 @@ class Command(ABC, metaclass=CommandMeta):
50
50
 
51
51
  @classmethod
52
52
  @overload
53
- def parse_and_run(cls: Type[CommandObj], argv: Argv = None, **kwargs) -> Optional[CommandObj]:
53
+ def parse_and_run(cls: Type[CommandObj], argv: Argv = None, **kwargs) -> CommandObj | None:
54
54
  # These overloads indicate that an instance of the same type or another may be returned
55
55
  ...
56
56
 
57
57
  @classmethod
58
58
  @overload
59
- def parse_and_run(cls, argv: Argv = None, **kwargs) -> Optional[CommandObj]: ...
59
+ def parse_and_run(cls, argv: Argv = None, **kwargs) -> CommandObj | None: ...
60
60
 
61
61
  @classmethod
62
62
  def parse_and_run(cls, argv=None, **kwargs):
@@ -214,7 +214,7 @@ class Command(ABC, metaclass=CommandMeta):
214
214
  """
215
215
  self._run_actions_(ActionPhase.BEFORE_MAIN, args, kwargs)
216
216
 
217
- def main(self, *args, **kwargs) -> Optional[int]:
217
+ def main(self, *args, **kwargs) -> int | None:
218
218
  """
219
219
  Primary method that is called when running a Command.
220
220
 
@@ -340,7 +340,7 @@ class AsyncCommand(Command, ABC):
340
340
  """Asynchronous version of :meth:`Command._before_main_`."""
341
341
  await self._run_actions_(ActionPhase.BEFORE_MAIN, args, kwargs)
342
342
 
343
- async def main(self, *args, **kwargs) -> Optional[int]:
343
+ async def main(self, *args, **kwargs) -> int | None:
344
344
  """Asynchronous version of :meth:`Command.main`."""
345
345
  with self._Command__ctx as ctx: # noqa
346
346
  action = get_params(self).action
@@ -355,7 +355,7 @@ class AsyncCommand(Command, ABC):
355
355
  await self._run_actions_(ActionPhase.AFTER_MAIN, args, kwargs)
356
356
 
357
357
 
358
- def main(argv: Argv = None, return_command: Bool = False, **kwargs) -> Optional[CommandObj]:
358
+ def main(argv: Argv = None, return_command: Bool = False, **kwargs) -> CommandObj | None:
359
359
  """
360
360
  Convenience function that can be used as the main entry point for a program.
361
361
 
@@ -389,3 +389,17 @@ def main(argv: Argv = None, return_command: Bool = False, **kwargs) -> Optional[
389
389
 
390
390
  command = commands[0].parse_and_run(argv, **kwargs)
391
391
  return command if return_command else None
392
+
393
+
394
+ def print_help(command: Command, *, exit: bool = True, file: TextIO | None = None): # noqa
395
+ """
396
+ User-callable version of the ``--help`` / ``-h`` action. Prints help text, then optionally exits.
397
+
398
+ :param command: The command for which help text should be printed.
399
+ :param exit: Whether a :class:`~.ParserExit` exception should be raised after help text is printed. If True (the
400
+ default), the program will exit with code 0 (success). If False, no exception will be raised.
401
+ :param file: The file-like object (stream) to write to; defaults to the current sys.stdout.
402
+ """
403
+ print(get_params(command).formatter.format_help(), file=file)
404
+ if exit:
405
+ raise ParserExit
@@ -126,14 +126,14 @@ class ChoiceMap(BasePositional[str], Generic[T], actions=(Concatenate,)):
126
126
  self.nargs = Nargs(lengths)
127
127
 
128
128
  @classmethod
129
- def _validate_positional(cls, value: str, prefix: str = 'choice'):
129
+ def _validate_positional(cls, value: str):
130
130
  if not value or value.startswith('-'):
131
131
  raise cls._choice_validation_exc(
132
- f"Invalid {cls.__name__} {prefix}={value!r} - may not be empty or start with '-'"
132
+ f"Invalid {cls.__name__} choice={value!r} - may not be empty or start with '-'"
133
133
  )
134
134
 
135
135
  if bad := {c for c in value if (c in whitespace and c != ' ') or c not in printable}:
136
- raise cls._choice_validation_exc(f'Invalid {cls.__name__} {prefix}={value!r} - invalid characters: {bad}')
136
+ raise cls._choice_validation_exc(f'Invalid {cls.__name__} choice={value!r} - invalid characters: {bad}')
137
137
 
138
138
  def register_choice(self, choice: str, target: T = _NotSet, help: str = None): # noqa
139
139
  self._validate_positional(choice)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli_command_parser
3
- Version: 2025.7.13
3
+ Version: 2025.9.27
4
4
  Summary: CLI Command Parser
5
5
  Home-page: https://github.com/dskrypa/cli_command_parser
6
6
  Author: Doug Skrypa