cmd2 3.1.0__tar.gz → 3.1.2__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 (337) hide show
  1. {cmd2-3.1.0 → cmd2-3.1.2}/.pre-commit-config.yaml +2 -2
  2. cmd2-3.1.2/.prettierignore +5 -0
  3. {cmd2-3.1.0 → cmd2-3.1.2}/CHANGELOG.md +14 -0
  4. cmd2-3.1.2/LICENSE +18 -0
  5. {cmd2-3.1.0 → cmd2-3.1.2}/MANIFEST.in +1 -1
  6. {cmd2-3.1.0 → cmd2-3.1.2}/Makefile +47 -9
  7. {cmd2-3.1.0 → cmd2-3.1.2}/PKG-INFO +4 -3
  8. {cmd2-3.1.0 → cmd2-3.1.2}/README.md +1 -1
  9. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/argparse_custom.py +63 -21
  10. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/parsing.py +7 -1
  11. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/rich_utils.py +1 -74
  12. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/styles.py +2 -4
  13. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2.egg-info/PKG-INFO +4 -3
  14. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2.egg-info/SOURCES.txt +2 -104
  15. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2.egg-info/requires.txt +2 -1
  16. {cmd2-3.1.0 → cmd2-3.1.2}/docs/doc_conventions.md +1 -1
  17. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/argument_processing.md +2 -2
  18. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/clipboard.md +5 -0
  19. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/settings.md +4 -3
  20. cmd2-3.1.2/docs/javascripts/readthedocs.js +8 -0
  21. {cmd2-3.1.0 → cmd2-3.1.2}/docs/migrating/minimum.md +4 -4
  22. {cmd2-3.1.0 → cmd2-3.1.2}/examples/README.md +4 -2
  23. cmd2-3.1.2/examples/async_call.py +80 -0
  24. {cmd2-3.1.0 → cmd2-3.1.2}/examples/cmd2_history.dat +0 -0
  25. {cmd2-3.1.0 → cmd2-3.1.2}/examples/modular_commands/commandset_custominit.py +2 -3
  26. {cmd2-3.1.0 → cmd2-3.1.2}/examples/modular_commands.py +3 -3
  27. cmd2-3.1.2/examples/pretty_print.py +44 -0
  28. {cmd2-3.1.0 → cmd2-3.1.2}/examples/rich_tables.py +7 -0
  29. {cmd2-3.1.0 → cmd2-3.1.2}/mkdocs.yml +7 -8
  30. {cmd2-3.1.0 → cmd2-3.1.2}/package.json +1 -1
  31. {cmd2-3.1.0 → cmd2-3.1.2}/pyproject.toml +4 -9
  32. {cmd2-3.1.0 → cmd2-3.1.2}/ruff.toml +3 -0
  33. cmd2-3.1.2/scripts/validate_tag.py +88 -0
  34. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_argparse_custom.py +49 -11
  35. cmd2-3.1.2/tests/test_rich_utils.py +144 -0
  36. cmd2-3.1.0/.prettierignore +0 -2
  37. cmd2-3.1.0/LICENSE +0 -21
  38. cmd2-3.1.0/docs/javascripts/readthedocs.js +0 -33
  39. cmd2-3.1.0/docs/stylesheets/readthedocs.css +0 -11
  40. cmd2-3.1.0/examples/.mypy_cache/3.12/@plugins_snapshot.json +0 -1
  41. cmd2-3.1.0/examples/.mypy_cache/3.12/_ast.data.json +0 -1
  42. cmd2-3.1.0/examples/.mypy_cache/3.12/_ast.meta.json +0 -1
  43. cmd2-3.1.0/examples/.mypy_cache/3.12/_codecs.data.json +0 -1
  44. cmd2-3.1.0/examples/.mypy_cache/3.12/_codecs.meta.json +0 -1
  45. cmd2-3.1.0/examples/.mypy_cache/3.12/_collections_abc.data.json +0 -1
  46. cmd2-3.1.0/examples/.mypy_cache/3.12/_collections_abc.meta.json +0 -1
  47. cmd2-3.1.0/examples/.mypy_cache/3.12/_typeshed/__init__.data.json +0 -1
  48. cmd2-3.1.0/examples/.mypy_cache/3.12/_typeshed/__init__.meta.json +0 -1
  49. cmd2-3.1.0/examples/.mypy_cache/3.12/_typeshed/importlib.data.json +0 -1
  50. cmd2-3.1.0/examples/.mypy_cache/3.12/_typeshed/importlib.meta.json +0 -1
  51. cmd2-3.1.0/examples/.mypy_cache/3.12/abc.data.json +0 -1
  52. cmd2-3.1.0/examples/.mypy_cache/3.12/abc.meta.json +0 -1
  53. cmd2-3.1.0/examples/.mypy_cache/3.12/argparse.data.json +0 -1
  54. cmd2-3.1.0/examples/.mypy_cache/3.12/argparse.meta.json +0 -1
  55. cmd2-3.1.0/examples/.mypy_cache/3.12/builtins.data.json +0 -1
  56. cmd2-3.1.0/examples/.mypy_cache/3.12/builtins.meta.json +0 -1
  57. cmd2-3.1.0/examples/.mypy_cache/3.12/codecs.data.json +0 -1
  58. cmd2-3.1.0/examples/.mypy_cache/3.12/codecs.meta.json +0 -1
  59. cmd2-3.1.0/examples/.mypy_cache/3.12/collections/__init__.data.json +0 -1
  60. cmd2-3.1.0/examples/.mypy_cache/3.12/collections/__init__.meta.json +0 -1
  61. cmd2-3.1.0/examples/.mypy_cache/3.12/collections/abc.data.json +0 -1
  62. cmd2-3.1.0/examples/.mypy_cache/3.12/collections/abc.meta.json +0 -1
  63. cmd2-3.1.0/examples/.mypy_cache/3.12/contextlib.data.json +0 -1
  64. cmd2-3.1.0/examples/.mypy_cache/3.12/contextlib.meta.json +0 -1
  65. cmd2-3.1.0/examples/.mypy_cache/3.12/dataclasses.data.json +0 -1
  66. cmd2-3.1.0/examples/.mypy_cache/3.12/dataclasses.meta.json +0 -1
  67. cmd2-3.1.0/examples/.mypy_cache/3.12/email/__init__.data.json +0 -1
  68. cmd2-3.1.0/examples/.mypy_cache/3.12/email/__init__.meta.json +0 -1
  69. cmd2-3.1.0/examples/.mypy_cache/3.12/email/_policybase.data.json +0 -1
  70. cmd2-3.1.0/examples/.mypy_cache/3.12/email/_policybase.meta.json +0 -1
  71. cmd2-3.1.0/examples/.mypy_cache/3.12/email/charset.data.json +0 -1
  72. cmd2-3.1.0/examples/.mypy_cache/3.12/email/charset.meta.json +0 -1
  73. cmd2-3.1.0/examples/.mypy_cache/3.12/email/contentmanager.data.json +0 -1
  74. cmd2-3.1.0/examples/.mypy_cache/3.12/email/contentmanager.meta.json +0 -1
  75. cmd2-3.1.0/examples/.mypy_cache/3.12/email/errors.data.json +0 -1
  76. cmd2-3.1.0/examples/.mypy_cache/3.12/email/errors.meta.json +0 -1
  77. cmd2-3.1.0/examples/.mypy_cache/3.12/email/header.data.json +0 -1
  78. cmd2-3.1.0/examples/.mypy_cache/3.12/email/header.meta.json +0 -1
  79. cmd2-3.1.0/examples/.mypy_cache/3.12/email/message.data.json +0 -1
  80. cmd2-3.1.0/examples/.mypy_cache/3.12/email/message.meta.json +0 -1
  81. cmd2-3.1.0/examples/.mypy_cache/3.12/email/policy.data.json +0 -1
  82. cmd2-3.1.0/examples/.mypy_cache/3.12/email/policy.meta.json +0 -1
  83. cmd2-3.1.0/examples/.mypy_cache/3.12/enum.data.json +0 -1
  84. cmd2-3.1.0/examples/.mypy_cache/3.12/enum.meta.json +0 -1
  85. cmd2-3.1.0/examples/.mypy_cache/3.12/genericpath.data.json +0 -1
  86. cmd2-3.1.0/examples/.mypy_cache/3.12/genericpath.meta.json +0 -1
  87. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/__init__.data.json +0 -1
  88. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/__init__.meta.json +0 -1
  89. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/_abc.data.json +0 -1
  90. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/_abc.meta.json +0 -1
  91. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/abc.data.json +0 -1
  92. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/abc.meta.json +0 -1
  93. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/machinery.data.json +0 -1
  94. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/machinery.meta.json +0 -1
  95. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/metadata/__init__.data.json +0 -1
  96. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/metadata/__init__.meta.json +0 -1
  97. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/metadata/_meta.data.json +0 -1
  98. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/metadata/_meta.meta.json +0 -1
  99. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/readers.data.json +0 -1
  100. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/readers.meta.json +0 -1
  101. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/resources/__init__.data.json +0 -1
  102. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/resources/__init__.meta.json +0 -1
  103. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/resources/abc.data.json +0 -1
  104. cmd2-3.1.0/examples/.mypy_cache/3.12/importlib/resources/abc.meta.json +0 -1
  105. cmd2-3.1.0/examples/.mypy_cache/3.12/io.data.json +0 -1
  106. cmd2-3.1.0/examples/.mypy_cache/3.12/io.meta.json +0 -1
  107. cmd2-3.1.0/examples/.mypy_cache/3.12/os/__init__.data.json +0 -1
  108. cmd2-3.1.0/examples/.mypy_cache/3.12/os/__init__.meta.json +0 -1
  109. cmd2-3.1.0/examples/.mypy_cache/3.12/os/path.data.json +0 -1
  110. cmd2-3.1.0/examples/.mypy_cache/3.12/os/path.meta.json +0 -1
  111. cmd2-3.1.0/examples/.mypy_cache/3.12/pathlib.data.json +0 -1
  112. cmd2-3.1.0/examples/.mypy_cache/3.12/pathlib.meta.json +0 -1
  113. cmd2-3.1.0/examples/.mypy_cache/3.12/posixpath.data.json +0 -1
  114. cmd2-3.1.0/examples/.mypy_cache/3.12/posixpath.meta.json +0 -1
  115. cmd2-3.1.0/examples/.mypy_cache/3.12/re.data.json +0 -1
  116. cmd2-3.1.0/examples/.mypy_cache/3.12/re.meta.json +0 -1
  117. cmd2-3.1.0/examples/.mypy_cache/3.12/resource.data.json +0 -1
  118. cmd2-3.1.0/examples/.mypy_cache/3.12/resource.meta.json +0 -1
  119. cmd2-3.1.0/examples/.mypy_cache/3.12/sre_compile.data.json +0 -1
  120. cmd2-3.1.0/examples/.mypy_cache/3.12/sre_compile.meta.json +0 -1
  121. cmd2-3.1.0/examples/.mypy_cache/3.12/sre_constants.data.json +0 -1
  122. cmd2-3.1.0/examples/.mypy_cache/3.12/sre_constants.meta.json +0 -1
  123. cmd2-3.1.0/examples/.mypy_cache/3.12/sre_parse.data.json +0 -1
  124. cmd2-3.1.0/examples/.mypy_cache/3.12/sre_parse.meta.json +0 -1
  125. cmd2-3.1.0/examples/.mypy_cache/3.12/subprocess.data.json +0 -1
  126. cmd2-3.1.0/examples/.mypy_cache/3.12/subprocess.meta.json +0 -1
  127. cmd2-3.1.0/examples/.mypy_cache/3.12/sys/__init__.data.json +0 -1
  128. cmd2-3.1.0/examples/.mypy_cache/3.12/sys/__init__.meta.json +0 -1
  129. cmd2-3.1.0/examples/.mypy_cache/3.12/sys/_monitoring.data.json +0 -1
  130. cmd2-3.1.0/examples/.mypy_cache/3.12/sys/_monitoring.meta.json +0 -1
  131. cmd2-3.1.0/examples/.mypy_cache/3.12/types.data.json +0 -1
  132. cmd2-3.1.0/examples/.mypy_cache/3.12/types.meta.json +0 -1
  133. cmd2-3.1.0/examples/.mypy_cache/3.12/typing.data.json +0 -1
  134. cmd2-3.1.0/examples/.mypy_cache/3.12/typing.meta.json +0 -1
  135. cmd2-3.1.0/examples/.mypy_cache/3.12/typing_extensions.data.json +0 -1
  136. cmd2-3.1.0/examples/.mypy_cache/3.12/typing_extensions.meta.json +0 -1
  137. cmd2-3.1.0/examples/.mypy_cache/3.12/zipfile/__init__.data.json +0 -1
  138. cmd2-3.1.0/examples/.mypy_cache/3.12/zipfile/__init__.meta.json +0 -1
  139. cmd2-3.1.0/examples/.mypy_cache/3.12/zipfile/_path.data.json +0 -1
  140. cmd2-3.1.0/examples/.mypy_cache/3.12/zipfile/_path.meta.json +0 -1
  141. cmd2-3.1.0/examples/.mypy_cache/CACHEDIR.TAG +0 -3
  142. cmd2-3.1.0/examples/pretty_print.py +0 -29
  143. cmd2-3.1.0/tasks.py +0 -275
  144. cmd2-3.1.0/tests/test_rich_utils.py +0 -331
  145. {cmd2-3.1.0 → cmd2-3.1.2}/.prettierrc +0 -0
  146. {cmd2-3.1.0 → cmd2-3.1.2}/GEMINI.md +0 -0
  147. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/__init__.py +0 -0
  148. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/argparse_completer.py +0 -0
  149. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/clipboard.py +0 -0
  150. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/cmd2.py +0 -0
  151. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/colors.py +0 -0
  152. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/command_definition.py +0 -0
  153. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/constants.py +0 -0
  154. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/decorators.py +0 -0
  155. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/exceptions.py +0 -0
  156. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/history.py +0 -0
  157. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/plugin.py +0 -0
  158. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/py.typed +0 -0
  159. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/py_bridge.py +0 -0
  160. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/rl_utils.py +0 -0
  161. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/string_utils.py +0 -0
  162. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/terminal_utils.py +0 -0
  163. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/transcript.py +0 -0
  164. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2/utils.py +0 -0
  165. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2.egg-info/dependency_links.txt +0 -0
  166. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2.egg-info/top_level.txt +0 -0
  167. {cmd2-3.1.0 → cmd2-3.1.2}/cmd2.png +0 -0
  168. {cmd2-3.1.0 → cmd2-3.1.2}/codecov.yml +0 -0
  169. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/argparse_completer.md +0 -0
  170. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/argparse_custom.md +0 -0
  171. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/clipboard.md +0 -0
  172. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/cmd.md +0 -0
  173. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/colors.md +0 -0
  174. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/command_definition.md +0 -0
  175. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/constants.md +0 -0
  176. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/decorators.md +0 -0
  177. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/exceptions.md +0 -0
  178. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/history.md +0 -0
  179. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/index.md +0 -0
  180. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/parsing.md +0 -0
  181. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/plugin.md +0 -0
  182. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/py_bridge.md +0 -0
  183. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/rich_utils.md +0 -0
  184. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/rl_utils.md +0 -0
  185. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/string_utils.md +0 -0
  186. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/styles.md +0 -0
  187. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/terminal_utils.md +0 -0
  188. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/transcript.md +0 -0
  189. {cmd2-3.1.0 → cmd2-3.1.2}/docs/api/utils.md +0 -0
  190. {cmd2-3.1.0 → cmd2-3.1.2}/docs/examples/alternate_event_loops.md +0 -0
  191. {cmd2-3.1.0 → cmd2-3.1.2}/docs/examples/examples.md +0 -0
  192. {cmd2-3.1.0 → cmd2-3.1.2}/docs/examples/getting_started.md +0 -0
  193. {cmd2-3.1.0 → cmd2-3.1.2}/docs/examples/index.md +0 -0
  194. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/builtin_commands.md +0 -0
  195. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/commands.md +0 -0
  196. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/completion.md +0 -0
  197. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/disable_commands.md +0 -0
  198. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/embedded_python_shells.md +0 -0
  199. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/generating_output.md +0 -0
  200. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/help.md +0 -0
  201. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/history.md +0 -0
  202. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/hooks.md +0 -0
  203. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/index.md +0 -0
  204. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/initialization.md +0 -0
  205. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/misc.md +0 -0
  206. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/modular_commands.md +0 -0
  207. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/multiline_commands.md +0 -0
  208. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/os.md +0 -0
  209. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/packaging.md +0 -0
  210. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/plugins.md +0 -0
  211. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/prompt.md +0 -0
  212. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/redirection.md +0 -0
  213. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/scripting.md +0 -0
  214. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/shortcuts_aliases_macros.md +0 -0
  215. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/startup_commands.md +0 -0
  216. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/table_creation.md +0 -0
  217. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/theme.md +0 -0
  218. {cmd2-3.1.0 → cmd2-3.1.2}/docs/features/transcripts.md +0 -0
  219. {cmd2-3.1.0 → cmd2-3.1.2}/docs/index.md +0 -0
  220. {cmd2-3.1.0 → cmd2-3.1.2}/docs/migrating/incompatibilities.md +0 -0
  221. {cmd2-3.1.0 → cmd2-3.1.2}/docs/migrating/index.md +0 -0
  222. {cmd2-3.1.0 → cmd2-3.1.2}/docs/migrating/next_steps.md +0 -0
  223. {cmd2-3.1.0 → cmd2-3.1.2}/docs/migrating/why.md +0 -0
  224. {cmd2-3.1.0 → cmd2-3.1.2}/docs/mixins/index.md +0 -0
  225. {cmd2-3.1.0 → cmd2-3.1.2}/docs/mixins/mixin_template.md +0 -0
  226. {cmd2-3.1.0 → cmd2-3.1.2}/docs/overrides/main.html +0 -0
  227. {cmd2-3.1.0 → cmd2-3.1.2}/docs/overview/alternatives.md +0 -0
  228. {cmd2-3.1.0 → cmd2-3.1.2}/docs/overview/index.md +0 -0
  229. {cmd2-3.1.0 → cmd2-3.1.2}/docs/overview/installation.md +0 -0
  230. {cmd2-3.1.0 → cmd2-3.1.2}/docs/overview/integrating.md +0 -0
  231. {cmd2-3.1.0 → cmd2-3.1.2}/docs/overview/resources.md +0 -0
  232. {cmd2-3.1.0 → cmd2-3.1.2}/docs/stylesheets/cmd2.css +0 -0
  233. {cmd2-3.1.0 → cmd2-3.1.2}/docs/testing.md +0 -0
  234. {cmd2-3.1.0 → cmd2-3.1.2}/docs/upgrades.md +0 -0
  235. {cmd2-3.1.0 → cmd2-3.1.2}/examples/.cmd2rc +0 -0
  236. {cmd2-3.1.0 → cmd2-3.1.2}/examples/argparse_completion.py +0 -0
  237. {cmd2-3.1.0 → cmd2-3.1.2}/examples/argparse_example.py +0 -0
  238. {cmd2-3.1.0 → cmd2-3.1.2}/examples/async_printing.py +0 -0
  239. {cmd2-3.1.0 → cmd2-3.1.2}/examples/basic_completion.py +0 -0
  240. {cmd2-3.1.0 → cmd2-3.1.2}/examples/cmd_as_argument.py +0 -0
  241. {cmd2-3.1.0 → cmd2-3.1.2}/examples/color.py +0 -0
  242. {cmd2-3.1.0 → cmd2-3.1.2}/examples/command_sets.py +0 -0
  243. {cmd2-3.1.0 → cmd2-3.1.2}/examples/custom_parser.py +0 -0
  244. {cmd2-3.1.0 → cmd2-3.1.2}/examples/custom_types.py +0 -0
  245. {cmd2-3.1.0 → cmd2-3.1.2}/examples/default_categories.py +0 -0
  246. {cmd2-3.1.0 → cmd2-3.1.2}/examples/dynamic_commands.py +0 -0
  247. {cmd2-3.1.0 → cmd2-3.1.2}/examples/environment.py +0 -0
  248. {cmd2-3.1.0 → cmd2-3.1.2}/examples/event_loops.py +0 -0
  249. {cmd2-3.1.0 → cmd2-3.1.2}/examples/exit_code.py +0 -0
  250. {cmd2-3.1.0 → cmd2-3.1.2}/examples/getting_started.py +0 -0
  251. {cmd2-3.1.0 → cmd2-3.1.2}/examples/hello_cmd2.py +0 -0
  252. {cmd2-3.1.0 → cmd2-3.1.2}/examples/help_categories.py +0 -0
  253. {cmd2-3.1.0 → cmd2-3.1.2}/examples/hooks.py +0 -0
  254. {cmd2-3.1.0 → cmd2-3.1.2}/examples/migrating.py +0 -0
  255. {cmd2-3.1.0 → cmd2-3.1.2}/examples/mixin.py +0 -0
  256. {cmd2-3.1.0 → cmd2-3.1.2}/examples/modular_commands/__init__.py +0 -0
  257. {cmd2-3.1.0 → cmd2-3.1.2}/examples/modular_commands/commandset_basic.py +0 -0
  258. {cmd2-3.1.0 → cmd2-3.1.2}/examples/modular_commands/commandset_complex.py +0 -0
  259. {cmd2-3.1.0 → cmd2-3.1.2}/examples/paged_output.py +0 -0
  260. {cmd2-3.1.0 → cmd2-3.1.2}/examples/persistent_history.py +0 -0
  261. {cmd2-3.1.0 → cmd2-3.1.2}/examples/python_scripting.py +0 -0
  262. {cmd2-3.1.0 → cmd2-3.1.2}/examples/read_input.py +0 -0
  263. {cmd2-3.1.0 → cmd2-3.1.2}/examples/remove_builtin_commands.py +0 -0
  264. {cmd2-3.1.0 → cmd2-3.1.2}/examples/remove_settable.py +0 -0
  265. {cmd2-3.1.0 → cmd2-3.1.2}/examples/rich_theme.py +0 -0
  266. {cmd2-3.1.0 → cmd2-3.1.2}/examples/scripts/arg_printer.py +0 -0
  267. {cmd2-3.1.0 → cmd2-3.1.2}/examples/scripts/conditional.py +0 -0
  268. {cmd2-3.1.0 → cmd2-3.1.2}/examples/scripts/nested.txt +0 -0
  269. {cmd2-3.1.0 → cmd2-3.1.2}/examples/scripts/quit.txt +0 -0
  270. {cmd2-3.1.0 → cmd2-3.1.2}/examples/scripts/save_help_text.py +0 -0
  271. {cmd2-3.1.0 → cmd2-3.1.2}/examples/scripts/script.py +0 -0
  272. {cmd2-3.1.0 → cmd2-3.1.2}/examples/scripts/script.txt +0 -0
  273. {cmd2-3.1.0 → cmd2-3.1.2}/examples/tmux_launch.sh +0 -0
  274. {cmd2-3.1.0 → cmd2-3.1.2}/examples/tmux_split.sh +0 -0
  275. {cmd2-3.1.0 → cmd2-3.1.2}/examples/transcript_example.py +0 -0
  276. {cmd2-3.1.0 → cmd2-3.1.2}/examples/transcripts/exampleSession.txt +0 -0
  277. {cmd2-3.1.0 → cmd2-3.1.2}/examples/transcripts/pirate.transcript +0 -0
  278. {cmd2-3.1.0 → cmd2-3.1.2}/examples/transcripts/quit.txt +0 -0
  279. {cmd2-3.1.0 → cmd2-3.1.2}/examples/transcripts/transcript_regex.txt +0 -0
  280. {cmd2-3.1.0 → cmd2-3.1.2}/examples/unicode_commands.py +0 -0
  281. {cmd2-3.1.0 → cmd2-3.1.2}/setup.cfg +0 -0
  282. {cmd2-3.1.0 → cmd2-3.1.2}/tests/.cmd2rc +0 -0
  283. {cmd2-3.1.0 → cmd2-3.1.2}/tests/__init__.py +0 -0
  284. {cmd2-3.1.0 → cmd2-3.1.2}/tests/conftest.py +0 -0
  285. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/echo.py +0 -0
  286. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/environment.py +0 -0
  287. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/help.py +0 -0
  288. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/py_locals.py +0 -0
  289. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/pyscript_dir.py +0 -0
  290. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/raises_exception.py +0 -0
  291. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/recursive.py +0 -0
  292. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/self_in_py.py +0 -0
  293. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/stdout_capture.py +0 -0
  294. {cmd2-3.1.0 → cmd2-3.1.2}/tests/pyscript/stop.py +0 -0
  295. {cmd2-3.1.0 → cmd2-3.1.2}/tests/relative_multiple.txt +0 -0
  296. {cmd2-3.1.0 → cmd2-3.1.2}/tests/script.py +0 -0
  297. {cmd2-3.1.0 → cmd2-3.1.2}/tests/script.txt +0 -0
  298. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/binary.bin +0 -0
  299. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/empty.txt +0 -0
  300. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/help.txt +0 -0
  301. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/nested.txt +0 -0
  302. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/one_down.txt +0 -0
  303. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/postcmds.txt +0 -0
  304. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/precmds.txt +0 -0
  305. {cmd2-3.1.0 → cmd2-3.1.2}/tests/scripts/utf8.txt +0 -0
  306. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_argparse.py +0 -0
  307. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_argparse_completer.py +0 -0
  308. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_argparse_subcommands.py +0 -0
  309. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_categories.py +0 -0
  310. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_cmd2.py +0 -0
  311. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_commandset.py +0 -0
  312. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_completion.py +0 -0
  313. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_future_annotations.py +0 -0
  314. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_history.py +0 -0
  315. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_parsing.py +0 -0
  316. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_plugin.py +0 -0
  317. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_run_pyscript.py +0 -0
  318. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_string_utils.py +0 -0
  319. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_terminal_utils.py +0 -0
  320. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_transcript.py +0 -0
  321. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_utils.py +0 -0
  322. {cmd2-3.1.0 → cmd2-3.1.2}/tests/test_utils_defining_class.py +0 -0
  323. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/bol_eol.txt +0 -0
  324. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/characterclass.txt +0 -0
  325. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/dotstar.txt +0 -0
  326. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/extension_notation.txt +0 -0
  327. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/failure.txt +0 -0
  328. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/from_cmdloop.txt +0 -0
  329. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/multiline_no_regex.txt +0 -0
  330. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/multiline_regex.txt +0 -0
  331. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/no_output.txt +0 -0
  332. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/no_output_last.txt +0 -0
  333. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/singleslash.txt +0 -0
  334. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/slashes_escaped.txt +0 -0
  335. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/slashslash.txt +0 -0
  336. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/spaces.txt +0 -0
  337. {cmd2-3.1.0 → cmd2-3.1.2}/tests/transcripts/word_boundaries.txt +0 -0
@@ -9,7 +9,7 @@ repos:
9
9
  - id: trailing-whitespace
10
10
 
11
11
  - repo: https://github.com/astral-sh/ruff-pre-commit
12
- rev: "v0.14.10"
12
+ rev: "v0.14.14"
13
13
  hooks:
14
14
  - id: ruff-format
15
15
  args: [--config=ruff.toml]
@@ -21,5 +21,5 @@ repos:
21
21
  hooks:
22
22
  - id: prettier
23
23
  additional_dependencies:
24
- - prettier@3.7.4
24
+ - prettier@3.8.0
25
25
  - prettier-plugin-toml@2.0.6
@@ -0,0 +1,5 @@
1
+ # File is nicely lined up
2
+ .github/CODEOWNERS
3
+
4
+ # Markdown documentation files with non-standard syntax for mkdocstrings that Prettier should not auto-format
5
+ docs/features/initialization.md
@@ -1,3 +1,13 @@
1
+ ## 3.1.2 (January 26, 2026)
2
+
3
+ - Bug Fixes
4
+ - Fixed missing `typing-extensions` dependency for Python 3.10
5
+
6
+ ## 3.1.1 (January 26, 2026)
7
+
8
+ - Bug Fixes
9
+ - Fixed bug where `rich-argparse` was not coloring cmd2's custom `nargs` formatting
10
+
1
11
  ## 3.1.0 (December 25, 2025)
2
12
 
3
13
  - Potentially Breaking Changes
@@ -44,6 +54,10 @@ time reading the [rich documentation](https://rich.readthedocs.io/).
44
54
  - `_set_parser_prog` renamed to `set_parser_prog` (without the leading underscore) and moved
45
55
  to `argparse_custom` module
46
56
  - Renamed history `--output_file` to `--output-file` to follow common command-line practices
57
+ - `cmd2.Cmd.ppretty` method removed - `rich` has more and better options for pretty printing,
58
+ see the
59
+ [pretty_print.py](https://github.com/python-cmd2/cmd2/blob/main/examples/pretty_print.py)
60
+ example for a demonstration of pretty-printing JSON data
47
61
 
48
62
  - Enhancements
49
63
  - Enhanced all print methods (`poutput()`, `perror()`, `ppaged()`, etc.) to natively render
cmd2-3.1.2/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2008-2026 Catherine Devlin and others
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction,
7
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
17
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,4 +1,4 @@
1
- include LICENSE README.md CHANGELOG.md mkdocs.yml pyproject.toml ruff.toml tasks.py
1
+ include LICENSE README.md CHANGELOG.md Makefile mkdocs.yml pyproject.toml ruff.toml
2
2
  recursive-include examples *
3
3
  recursive-include tests *
4
4
  recursive-include docs *
@@ -1,4 +1,7 @@
1
1
  # Simple Makefile for use with a uv-based development environment
2
+ # The at (@) prefix tells make to suppress output from the command
3
+ # The hyphen (-) prefix tells make to ignore errors (e.g., if a directory doesn't exist)
4
+
2
5
  .PHONY: install
3
6
  install: ## Install the virtual environment with dependencies
4
7
  @echo "🚀 Creating uv Python virtual environment"
@@ -37,22 +40,17 @@ test: ## Test the code with pytest.
37
40
 
38
41
  .PHONY: docs-test
39
42
  docs-test: ## Test if documentation can be built without warnings or errors
40
- @uv run mkdocs build -s
43
+ @uv run zensical build -s
41
44
 
42
45
  .PHONY: docs
43
- docs: ## Build and serve the documentation
44
- @uv run mkdocs serve
46
+ docs: ## Build and serve the documentation (and open in default browser)
47
+ @uv run zensical serve -o
45
48
 
46
49
  .PHONY: build
47
50
  build: clean-build ## Build wheel file
48
51
  @echo "🚀 Creating wheel file"
49
52
  @uv build
50
53
 
51
- .PHONY: clean-build
52
- clean-build: ## Clean build artifacts
53
- @echo "🚀 Removing build artifacts"
54
- @uv run python -c "import shutil; import os; shutil.rmtree('dist') if os.path.exists('dist') else None"
55
-
56
54
  .PHONY: tag
57
55
  tag: ## Add a Git tag and push it to origin with syntax: make tag TAG=tag_name
58
56
  @echo "🚀 Creating git tag: ${TAG}"
@@ -63,7 +61,7 @@ tag: ## Add a Git tag and push it to origin with syntax: make tag TAG=tag_name
63
61
  .PHONY: validate-tag
64
62
  validate-tag: ## Check to make sure that a tag exists for the current HEAD and it looks like a valid version number
65
63
  @echo "🚀 Validating version tag"
66
- @uv run inv validatetag
64
+ @uv run scripts/validate_tag.py
67
65
 
68
66
  .PHONY: publish-test
69
67
  publish-test: validate-tag build ## Test publishing a release to PyPI, uses token from ~/.pypirc file.
@@ -75,6 +73,46 @@ publish: validate-tag build ## Publish a release to PyPI, uses token from ~/.pyp
75
73
  @echo "🚀 Publishing."
76
74
  @uv run uv-publish
77
75
 
76
+ # Define variables for files/directories to clean
77
+ BUILD_DIRS = build dist *.egg-info
78
+ DOC_DIRS = build
79
+ MYPY_DIRS = .mypy_cache dmypy.json dmypy.sock
80
+ TEST_DIRS = .cache .coverage .pytest_cache htmlcov
81
+
82
+ .PHONY: clean-build
83
+ clean-build: ## Clean build artifacts
84
+ @echo "🚀 Removing build artifacts"
85
+ @uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(BUILD_DIRS)'.split() if os.path.isdir(d)]"
86
+
87
+ .PHONY: clean-docs
88
+ clean-docs: ## Clean documentation artifacts
89
+ @echo "🚀 Removing documentation artifacts"
90
+ @uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(DOC_DIRS)'.split() if os.path.isdir(d)]"
91
+
92
+ .PHONY: clean-mypy
93
+ clean-mypy: ## Clean mypy artifacts
94
+ @echo "🚀 Removing mypy artifacts"
95
+ @uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(MYPY_DIRS)'.split() if os.path.isdir(d)]"
96
+
97
+ .PHONY: clean-pycache
98
+ clean-pycache: ## Clean pycache artifacts
99
+ @echo "🚀 Removing pycache artifacts"
100
+ @-find . -type d -name "__pycache__" -exec rm -r {} +
101
+
102
+ .PHONY: clean-ruff
103
+ clean-ruff: ## Clean ruff artifacts
104
+ @echo "🚀 Removing ruff artifacts"
105
+ @uv run ruff clean
106
+
107
+ .PHONY: clean-test
108
+ clean-test: ## Clean test artifacts
109
+ @echo "🚀 Removing test artifacts"
110
+ @uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(TEST_DIRS)'.split() if os.path.isdir(d)]"
111
+
112
+ .PHONY: clean
113
+ clean: clean-build clean-docs clean-mypy clean-pycache clean-ruff clean-test ## Clean all artifacts
114
+ @echo "🚀 Cleaned all artifacts"
115
+
78
116
  .PHONY: help
79
117
  help:
80
118
  @uv run python -c "import re; \
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cmd2
3
- Version: 3.1.0
3
+ Version: 3.1.2
4
4
  Summary: cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python
5
5
  Author: cmd2 Contributors
6
6
  License-Expression: MIT
@@ -26,14 +26,15 @@ Requires-Dist: backports.strenum; python_version == "3.10"
26
26
  Requires-Dist: gnureadline>=8; platform_system == "Darwin"
27
27
  Requires-Dist: pyperclip>=1.8.2
28
28
  Requires-Dist: pyreadline3>=3.4; platform_system == "Windows"
29
- Requires-Dist: rich>=14.1.0
29
+ Requires-Dist: rich>=14.3.0
30
30
  Requires-Dist: rich-argparse>=1.7.1
31
+ Requires-Dist: typing-extensions; python_version == "3.10"
31
32
  Dynamic: license-file
32
33
 
33
34
  <h1 align="center">cmd2 : immersive interactive command line applications</h1>
34
35
 
35
36
  [![Latest Version](https://img.shields.io/pypi/v/cmd2.svg?style=flat-square&label=latest%20stable%20version)](https://pypi.python.org/pypi/cmd2/)
36
- [![GitHub Actions](https://github.com/python-cmd2/cmd2/workflows/CI/badge.svg)](https://github.com/python-cmd2/cmd2/actions?query=workflow%3ACI)
37
+ [![Tests](https://github.com/python-cmd2/cmd2/actions/workflows/tests.yml/badge.svg)](https://github.com/python-cmd2/cmd2/actions/workflows/tests.yml)
37
38
  [![codecov](https://codecov.io/gh/python-cmd2/cmd2/branch/main/graph/badge.svg)](https://codecov.io/gh/python-cmd2/cmd2)
38
39
  [![Documentation Status](https://readthedocs.org/projects/cmd2/badge/?version=latest)](http://cmd2.readthedocs.io/en/latest/?badge=latest)
39
40
  <a href="https://discord.gg/RpVG6tk"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg" alt="Chat"></a>
@@ -1,7 +1,7 @@
1
1
  <h1 align="center">cmd2 : immersive interactive command line applications</h1>
2
2
 
3
3
  [![Latest Version](https://img.shields.io/pypi/v/cmd2.svg?style=flat-square&label=latest%20stable%20version)](https://pypi.python.org/pypi/cmd2/)
4
- [![GitHub Actions](https://github.com/python-cmd2/cmd2/workflows/CI/badge.svg)](https://github.com/python-cmd2/cmd2/actions?query=workflow%3ACI)
4
+ [![Tests](https://github.com/python-cmd2/cmd2/actions/workflows/tests.yml/badge.svg)](https://github.com/python-cmd2/cmd2/actions/workflows/tests.yml)
5
5
  [![codecov](https://codecov.io/gh/python-cmd2/cmd2/branch/main/graph/badge.svg)](https://codecov.io/gh/python-cmd2/cmd2)
6
6
  [![Documentation Status](https://readthedocs.org/projects/cmd2/badge/?version=latest)](http://cmd2.readthedocs.io/en/latest/?badge=latest)
7
7
  <a href="https://discord.gg/RpVG6tk"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg" alt="Chat"></a>
@@ -258,14 +258,11 @@ sub-parser from a sub-parsers group. See _SubParsersAction_remove_parser` for mo
258
258
  import argparse
259
259
  import re
260
260
  import sys
261
- from argparse import (
262
- ONE_OR_MORE,
263
- ZERO_OR_MORE,
264
- ArgumentError,
265
- )
261
+ from argparse import ArgumentError
266
262
  from collections.abc import (
267
263
  Callable,
268
264
  Iterable,
265
+ Iterator,
269
266
  Sequence,
270
267
  )
271
268
  from gettext import gettext
@@ -294,6 +291,12 @@ from rich_argparse import (
294
291
  RichHelpFormatter,
295
292
  )
296
293
 
294
+ if sys.version_info >= (3, 11):
295
+ from typing import Self
296
+ else:
297
+ from typing_extensions import Self
298
+
299
+
297
300
  from . import constants
298
301
  from . import rich_utils as ru
299
302
  from .rich_utils import Cmd2RichArgparseConsole
@@ -380,7 +383,7 @@ class CompletionItem(str): # noqa: SLOT000
380
383
  See header of this file for more information
381
384
  """
382
385
 
383
- def __new__(cls, value: object, *_args: Any, **_kwargs: Any) -> 'CompletionItem':
386
+ def __new__(cls, value: object, *_args: Any, **_kwargs: Any) -> Self:
384
387
  """Responsible for creating and returning a new instance, called before __init__ when an object is instantiated."""
385
388
  return super().__new__(cls, value)
386
389
 
@@ -1295,29 +1298,68 @@ class Cmd2HelpFormatter(RichHelpFormatter):
1295
1298
 
1296
1299
  return format_tuple
1297
1300
 
1301
+ def _build_nargs_range_str(self, nargs_range: tuple[int, int | float]) -> str:
1302
+ """Generate nargs range string for help text."""
1303
+ if nargs_range[1] == constants.INFINITY:
1304
+ # {min+}
1305
+ range_str = f"{{{nargs_range[0]}+}}"
1306
+ else:
1307
+ # {min..max}
1308
+ range_str = f"{{{nargs_range[0]}..{nargs_range[1]}}}"
1309
+
1310
+ return range_str
1311
+
1298
1312
  def _format_args(self, action: argparse.Action, default_metavar: str) -> str:
1299
- """Handle ranged nargs and make other output less verbose."""
1313
+ """Override to handle cmd2's custom nargs formatting.
1314
+
1315
+ All formats in this function need to be handled by _rich_metavar_parts().
1316
+ """
1300
1317
  metavar = self._determine_metavar(action, default_metavar)
1301
1318
  metavar_formatter = self._metavar_formatter(action, default_metavar)
1302
1319
 
1303
1320
  # Handle nargs specified as a range
1304
1321
  nargs_range = action.get_nargs_range() # type: ignore[attr-defined]
1305
1322
  if nargs_range is not None:
1306
- range_str = f'{nargs_range[0]}+' if nargs_range[1] == constants.INFINITY else f'{nargs_range[0]}..{nargs_range[1]}'
1307
-
1308
- return '{}{{{}}}'.format('%s' % metavar_formatter(1), range_str) # noqa: UP031
1309
-
1310
- # Make this output less verbose. Do not customize the output when metavar is a
1311
- # tuple of strings. Allow argparse's formatter to handle that instead.
1312
- if isinstance(metavar, str):
1313
- if action.nargs == ZERO_OR_MORE:
1314
- return '[%s [...]]' % metavar_formatter(1) # noqa: UP031
1315
- if action.nargs == ONE_OR_MORE:
1316
- return '%s [...]' % metavar_formatter(1) # noqa: UP031
1317
- if isinstance(action.nargs, int) and action.nargs > 1:
1318
- return '{}{{{}}}'.format('%s' % metavar_formatter(1), action.nargs) # noqa: UP031
1323
+ arg_str = '%s' % metavar_formatter(1) # noqa: UP031
1324
+ range_str = self._build_nargs_range_str(nargs_range)
1325
+ return f"{arg_str}{range_str}"
1326
+
1327
+ # When nargs is just a number, argparse repeats the arg in the help text.
1328
+ # For instance, when nargs=5 the help text looks like: 'command arg arg arg arg arg'.
1329
+ # To make this less verbose, format it like: 'command arg{5}'.
1330
+ # Do not customize the output when metavar is a tuple of strings. Allow argparse's
1331
+ # formatter to handle that instead.
1332
+ if isinstance(metavar, str) and isinstance(action.nargs, int) and action.nargs > 1:
1333
+ arg_str = '%s' % metavar_formatter(1) # noqa: UP031
1334
+ return f"{arg_str}{{{action.nargs}}}"
1335
+
1336
+ # Fallback to parent for all other cases
1337
+ return super()._format_args(action, default_metavar)
1338
+
1339
+ def _rich_metavar_parts(
1340
+ self,
1341
+ action: argparse.Action,
1342
+ default_metavar: str,
1343
+ ) -> Iterator[tuple[str, bool]]:
1344
+ """Override to handle all cmd2-specific formatting in _format_args()."""
1345
+ metavar = self._determine_metavar(action, default_metavar)
1346
+ metavar_formatter = self._metavar_formatter(action, default_metavar)
1319
1347
 
1320
- return super()._format_args(action, default_metavar) # type: ignore[arg-type]
1348
+ # Handle nargs specified as a range
1349
+ nargs_range = action.get_nargs_range() # type: ignore[attr-defined]
1350
+ if nargs_range is not None:
1351
+ yield "%s" % metavar_formatter(1), True # noqa: UP031
1352
+ yield self._build_nargs_range_str(nargs_range), False
1353
+ return
1354
+
1355
+ # Handle specific integer nargs (e.g., nargs=5 -> arg{5})
1356
+ if isinstance(metavar, str) and isinstance(action.nargs, int) and action.nargs > 1:
1357
+ yield "%s" % metavar_formatter(1), True # noqa: UP031
1358
+ yield f"{{{action.nargs}}}", False
1359
+ return
1360
+
1361
+ # Fallback to parent for all other cases
1362
+ yield from super()._rich_metavar_parts(action, default_metavar)
1321
1363
 
1322
1364
 
1323
1365
  class RawDescriptionCmd2HelpFormatter(
@@ -2,6 +2,7 @@
2
2
 
3
3
  import re
4
4
  import shlex
5
+ import sys
5
6
  from collections.abc import Iterable
6
7
  from dataclasses import (
7
8
  dataclass,
@@ -9,6 +10,11 @@ from dataclasses import (
9
10
  )
10
11
  from typing import Any
11
12
 
13
+ if sys.version_info >= (3, 11):
14
+ from typing import Self
15
+ else:
16
+ from typing_extensions import Self
17
+
12
18
  from . import (
13
19
  constants,
14
20
  utils,
@@ -144,7 +150,7 @@ class Statement(str): # noqa: SLOT000
144
150
  # Used in JSON dictionaries
145
151
  _args_field = 'args'
146
152
 
147
- def __new__(cls, value: object, *_pos_args: Any, **_kw_args: Any) -> 'Statement':
153
+ def __new__(cls, value: object, *_pos_args: Any, **_kw_args: Any) -> Self:
148
154
  """Create a new instance of Statement.
149
155
 
150
156
  We must override __new__ because we are subclassing `str` which is
@@ -1,10 +1,7 @@
1
1
  """Provides common utilities to support Rich in cmd2-based applications."""
2
2
 
3
3
  import re
4
- from collections.abc import (
5
- Iterable,
6
- Mapping,
7
- )
4
+ from collections.abc import Mapping
8
5
  from enum import Enum
9
6
  from typing import (
10
7
  IO,
@@ -22,7 +19,6 @@ from rich.console import (
22
19
  from rich.padding import Padding
23
20
  from rich.pretty import is_expandable
24
21
  from rich.protocol import rich_cast
25
- from rich.segment import Segment
26
22
  from rich.style import StyleType
27
23
  from rich.table import (
28
24
  Column,
@@ -380,72 +376,3 @@ def _from_ansi_has_newline_bug() -> bool:
380
376
  # Only apply the monkey patch if the bug is present
381
377
  if _from_ansi_has_newline_bug():
382
378
  Text.from_ansi = _from_ansi_wrapper # type: ignore[assignment]
383
-
384
-
385
- ###################################################################################
386
- # Segment.apply_style() monkey patch
387
- ###################################################################################
388
-
389
- # Save original Segment.apply_style() so we can call it in our wrapper
390
- _orig_segment_apply_style = Segment.apply_style
391
-
392
-
393
- @classmethod # type: ignore[misc]
394
- def _apply_style_wrapper(cls: type[Segment], *args: Any, **kwargs: Any) -> Iterable["Segment"]:
395
- r"""Wrap Segment.apply_style() to fix bug with styling newlines.
396
-
397
- This wrapper handles an issue where Segment.apply_style() includes newlines
398
- within styled Segments. As a result, when printing text using a background color
399
- and soft wrapping, the background color incorrectly carries over onto the following line.
400
-
401
- You can reproduce this behavior by calling console.print() using a background color
402
- and soft wrapping.
403
-
404
- For example:
405
- console.print("line_1", style="blue on white", soft_wrap=True)
406
-
407
- When soft wrapping is disabled, console.print() splits Segments into their individual
408
- lines, which separates the newlines from the styled text. Therefore, the background color
409
- issue does not occur in that mode.
410
-
411
- This function copies that behavior to fix this the issue even when soft wrapping is enabled.
412
-
413
- There is currently a pull request on Rich to fix this.
414
- https://github.com/Textualize/rich/pull/3839
415
- """
416
- styled_segments = list(_orig_segment_apply_style(*args, **kwargs))
417
- newline_segment = cls.line()
418
-
419
- # If the final segment ends in a newline, that newline will be stripped by Segment.split_lines().
420
- # Save an unstyled newline to restore later.
421
- end_segment = newline_segment if styled_segments and styled_segments[-1].text.endswith("\n") else None
422
-
423
- # Use Segment.split_lines() to separate the styled text from the newlines.
424
- # This way the ANSI reset code will appear before any newline.
425
- sanitized_segments: list[Segment] = []
426
-
427
- lines = list(Segment.split_lines(styled_segments))
428
- for index, line in enumerate(lines):
429
- sanitized_segments.extend(line)
430
- if index < len(lines) - 1:
431
- sanitized_segments.append(newline_segment)
432
-
433
- if end_segment is not None:
434
- sanitized_segments.append(end_segment)
435
-
436
- return sanitized_segments
437
-
438
-
439
- def _rich_has_styled_newline_bug() -> bool:
440
- """Check if newlines are styled when soft wrapping."""
441
- console = Console(force_terminal=True)
442
- with console.capture() as capture:
443
- console.print("line_1", style="blue on white", soft_wrap=True)
444
-
445
- # Check if we see a styled newline in the output
446
- return "\x1b[34;47m\n\x1b[0m" in capture.get()
447
-
448
-
449
- # Only apply the monkey patch if the bug is present
450
- if _rich_has_styled_newline_bug():
451
- Segment.apply_style = _apply_style_wrapper # type: ignore[assignment]
@@ -51,7 +51,6 @@ class Cmd2Style(StrEnum):
51
51
 
52
52
  COMMAND_LINE = "cmd2.example" # Command line examples in help text
53
53
  ERROR = "cmd2.error" # Error text (used by perror())
54
- EXCEPTION_TYPE = "cmd2.exception.type" # Used by pexcept to mark an exception type
55
54
  HELP_HEADER = "cmd2.help.header" # Help table header text
56
55
  HELP_LEADER = "cmd2.help.leader" # Text right before the help tables are listed
57
56
  SUCCESS = "cmd2.success" # Success text (used by psuccess())
@@ -63,9 +62,8 @@ class Cmd2Style(StrEnum):
63
62
  DEFAULT_CMD2_STYLES: dict[str, StyleType] = {
64
63
  Cmd2Style.COMMAND_LINE: Style(color=Color.CYAN, bold=True),
65
64
  Cmd2Style.ERROR: Style(color=Color.BRIGHT_RED),
66
- Cmd2Style.EXCEPTION_TYPE: Style(color=Color.DARK_ORANGE, bold=True),
67
- Cmd2Style.HELP_HEADER: Style(color=Color.BRIGHT_GREEN, bold=True),
68
- Cmd2Style.HELP_LEADER: Style(color=Color.CYAN, bold=True),
65
+ Cmd2Style.HELP_HEADER: Style(color=Color.BRIGHT_GREEN),
66
+ Cmd2Style.HELP_LEADER: Style(color=Color.CYAN),
69
67
  Cmd2Style.SUCCESS: Style(color=Color.GREEN),
70
68
  Cmd2Style.TABLE_BORDER: Style(color=Color.BRIGHT_GREEN),
71
69
  Cmd2Style.WARNING: Style(color=Color.BRIGHT_YELLOW),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cmd2
3
- Version: 3.1.0
3
+ Version: 3.1.2
4
4
  Summary: cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python
5
5
  Author: cmd2 Contributors
6
6
  License-Expression: MIT
@@ -26,14 +26,15 @@ Requires-Dist: backports.strenum; python_version == "3.10"
26
26
  Requires-Dist: gnureadline>=8; platform_system == "Darwin"
27
27
  Requires-Dist: pyperclip>=1.8.2
28
28
  Requires-Dist: pyreadline3>=3.4; platform_system == "Windows"
29
- Requires-Dist: rich>=14.1.0
29
+ Requires-Dist: rich>=14.3.0
30
30
  Requires-Dist: rich-argparse>=1.7.1
31
+ Requires-Dist: typing-extensions; python_version == "3.10"
31
32
  Dynamic: license-file
32
33
 
33
34
  <h1 align="center">cmd2 : immersive interactive command line applications</h1>
34
35
 
35
36
  [![Latest Version](https://img.shields.io/pypi/v/cmd2.svg?style=flat-square&label=latest%20stable%20version)](https://pypi.python.org/pypi/cmd2/)
36
- [![GitHub Actions](https://github.com/python-cmd2/cmd2/workflows/CI/badge.svg)](https://github.com/python-cmd2/cmd2/actions?query=workflow%3ACI)
37
+ [![Tests](https://github.com/python-cmd2/cmd2/actions/workflows/tests.yml/badge.svg)](https://github.com/python-cmd2/cmd2/actions/workflows/tests.yml)
37
38
  [![codecov](https://codecov.io/gh/python-cmd2/cmd2/branch/main/graph/badge.svg)](https://codecov.io/gh/python-cmd2/cmd2)
38
39
  [![Documentation Status](https://readthedocs.org/projects/cmd2/badge/?version=latest)](http://cmd2.readthedocs.io/en/latest/?badge=latest)
39
40
  <a href="https://discord.gg/RpVG6tk"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg" alt="Chat"></a>
@@ -13,7 +13,6 @@ mkdocs.yml
13
13
  package.json
14
14
  pyproject.toml
15
15
  ruff.toml
16
- tasks.py
17
16
  cmd2/__init__.py
18
17
  cmd2/argparse_completer.py
19
18
  cmd2/argparse_custom.py
@@ -113,11 +112,11 @@ docs/overview/installation.md
113
112
  docs/overview/integrating.md
114
113
  docs/overview/resources.md
115
114
  docs/stylesheets/cmd2.css
116
- docs/stylesheets/readthedocs.css
117
115
  examples/.cmd2rc
118
116
  examples/README.md
119
117
  examples/argparse_completion.py
120
118
  examples/argparse_example.py
119
+ examples/async_call.py
121
120
  examples/async_printing.py
122
121
  examples/basic_completion.py
123
122
  examples/cmd2_history.dat
@@ -151,108 +150,6 @@ examples/tmux_launch.sh
151
150
  examples/tmux_split.sh
152
151
  examples/transcript_example.py
153
152
  examples/unicode_commands.py
154
- examples/.mypy_cache/CACHEDIR.TAG
155
- examples/.mypy_cache/3.12/@plugins_snapshot.json
156
- examples/.mypy_cache/3.12/_ast.data.json
157
- examples/.mypy_cache/3.12/_ast.meta.json
158
- examples/.mypy_cache/3.12/_codecs.data.json
159
- examples/.mypy_cache/3.12/_codecs.meta.json
160
- examples/.mypy_cache/3.12/_collections_abc.data.json
161
- examples/.mypy_cache/3.12/_collections_abc.meta.json
162
- examples/.mypy_cache/3.12/abc.data.json
163
- examples/.mypy_cache/3.12/abc.meta.json
164
- examples/.mypy_cache/3.12/argparse.data.json
165
- examples/.mypy_cache/3.12/argparse.meta.json
166
- examples/.mypy_cache/3.12/builtins.data.json
167
- examples/.mypy_cache/3.12/builtins.meta.json
168
- examples/.mypy_cache/3.12/codecs.data.json
169
- examples/.mypy_cache/3.12/codecs.meta.json
170
- examples/.mypy_cache/3.12/contextlib.data.json
171
- examples/.mypy_cache/3.12/contextlib.meta.json
172
- examples/.mypy_cache/3.12/dataclasses.data.json
173
- examples/.mypy_cache/3.12/dataclasses.meta.json
174
- examples/.mypy_cache/3.12/enum.data.json
175
- examples/.mypy_cache/3.12/enum.meta.json
176
- examples/.mypy_cache/3.12/genericpath.data.json
177
- examples/.mypy_cache/3.12/genericpath.meta.json
178
- examples/.mypy_cache/3.12/io.data.json
179
- examples/.mypy_cache/3.12/io.meta.json
180
- examples/.mypy_cache/3.12/pathlib.data.json
181
- examples/.mypy_cache/3.12/pathlib.meta.json
182
- examples/.mypy_cache/3.12/posixpath.data.json
183
- examples/.mypy_cache/3.12/posixpath.meta.json
184
- examples/.mypy_cache/3.12/re.data.json
185
- examples/.mypy_cache/3.12/re.meta.json
186
- examples/.mypy_cache/3.12/resource.data.json
187
- examples/.mypy_cache/3.12/resource.meta.json
188
- examples/.mypy_cache/3.12/sre_compile.data.json
189
- examples/.mypy_cache/3.12/sre_compile.meta.json
190
- examples/.mypy_cache/3.12/sre_constants.data.json
191
- examples/.mypy_cache/3.12/sre_constants.meta.json
192
- examples/.mypy_cache/3.12/sre_parse.data.json
193
- examples/.mypy_cache/3.12/sre_parse.meta.json
194
- examples/.mypy_cache/3.12/subprocess.data.json
195
- examples/.mypy_cache/3.12/subprocess.meta.json
196
- examples/.mypy_cache/3.12/types.data.json
197
- examples/.mypy_cache/3.12/types.meta.json
198
- examples/.mypy_cache/3.12/typing.data.json
199
- examples/.mypy_cache/3.12/typing.meta.json
200
- examples/.mypy_cache/3.12/typing_extensions.data.json
201
- examples/.mypy_cache/3.12/typing_extensions.meta.json
202
- examples/.mypy_cache/3.12/_typeshed/__init__.data.json
203
- examples/.mypy_cache/3.12/_typeshed/__init__.meta.json
204
- examples/.mypy_cache/3.12/_typeshed/importlib.data.json
205
- examples/.mypy_cache/3.12/_typeshed/importlib.meta.json
206
- examples/.mypy_cache/3.12/collections/__init__.data.json
207
- examples/.mypy_cache/3.12/collections/__init__.meta.json
208
- examples/.mypy_cache/3.12/collections/abc.data.json
209
- examples/.mypy_cache/3.12/collections/abc.meta.json
210
- examples/.mypy_cache/3.12/email/__init__.data.json
211
- examples/.mypy_cache/3.12/email/__init__.meta.json
212
- examples/.mypy_cache/3.12/email/_policybase.data.json
213
- examples/.mypy_cache/3.12/email/_policybase.meta.json
214
- examples/.mypy_cache/3.12/email/charset.data.json
215
- examples/.mypy_cache/3.12/email/charset.meta.json
216
- examples/.mypy_cache/3.12/email/contentmanager.data.json
217
- examples/.mypy_cache/3.12/email/contentmanager.meta.json
218
- examples/.mypy_cache/3.12/email/errors.data.json
219
- examples/.mypy_cache/3.12/email/errors.meta.json
220
- examples/.mypy_cache/3.12/email/header.data.json
221
- examples/.mypy_cache/3.12/email/header.meta.json
222
- examples/.mypy_cache/3.12/email/message.data.json
223
- examples/.mypy_cache/3.12/email/message.meta.json
224
- examples/.mypy_cache/3.12/email/policy.data.json
225
- examples/.mypy_cache/3.12/email/policy.meta.json
226
- examples/.mypy_cache/3.12/importlib/__init__.data.json
227
- examples/.mypy_cache/3.12/importlib/__init__.meta.json
228
- examples/.mypy_cache/3.12/importlib/_abc.data.json
229
- examples/.mypy_cache/3.12/importlib/_abc.meta.json
230
- examples/.mypy_cache/3.12/importlib/abc.data.json
231
- examples/.mypy_cache/3.12/importlib/abc.meta.json
232
- examples/.mypy_cache/3.12/importlib/machinery.data.json
233
- examples/.mypy_cache/3.12/importlib/machinery.meta.json
234
- examples/.mypy_cache/3.12/importlib/readers.data.json
235
- examples/.mypy_cache/3.12/importlib/readers.meta.json
236
- examples/.mypy_cache/3.12/importlib/metadata/__init__.data.json
237
- examples/.mypy_cache/3.12/importlib/metadata/__init__.meta.json
238
- examples/.mypy_cache/3.12/importlib/metadata/_meta.data.json
239
- examples/.mypy_cache/3.12/importlib/metadata/_meta.meta.json
240
- examples/.mypy_cache/3.12/importlib/resources/__init__.data.json
241
- examples/.mypy_cache/3.12/importlib/resources/__init__.meta.json
242
- examples/.mypy_cache/3.12/importlib/resources/abc.data.json
243
- examples/.mypy_cache/3.12/importlib/resources/abc.meta.json
244
- examples/.mypy_cache/3.12/os/__init__.data.json
245
- examples/.mypy_cache/3.12/os/__init__.meta.json
246
- examples/.mypy_cache/3.12/os/path.data.json
247
- examples/.mypy_cache/3.12/os/path.meta.json
248
- examples/.mypy_cache/3.12/sys/__init__.data.json
249
- examples/.mypy_cache/3.12/sys/__init__.meta.json
250
- examples/.mypy_cache/3.12/sys/_monitoring.data.json
251
- examples/.mypy_cache/3.12/sys/_monitoring.meta.json
252
- examples/.mypy_cache/3.12/zipfile/__init__.data.json
253
- examples/.mypy_cache/3.12/zipfile/__init__.meta.json
254
- examples/.mypy_cache/3.12/zipfile/_path.data.json
255
- examples/.mypy_cache/3.12/zipfile/_path.meta.json
256
153
  examples/modular_commands/__init__.py
257
154
  examples/modular_commands/commandset_basic.py
258
155
  examples/modular_commands/commandset_complex.py
@@ -268,6 +165,7 @@ examples/transcripts/exampleSession.txt
268
165
  examples/transcripts/pirate.transcript
269
166
  examples/transcripts/quit.txt
270
167
  examples/transcripts/transcript_regex.txt
168
+ scripts/validate_tag.py
271
169
  tests/.cmd2rc
272
170
  tests/__init__.py
273
171
  tests/conftest.py
@@ -1,5 +1,5 @@
1
1
  pyperclip>=1.8.2
2
- rich>=14.1.0
2
+ rich>=14.3.0
3
3
  rich-argparse>=1.7.1
4
4
 
5
5
  [:platform_system == "Darwin"]
@@ -10,3 +10,4 @@ pyreadline3>=3.4
10
10
 
11
11
  [:python_version == "3.10"]
12
12
  backports.strenum
13
+ typing-extensions
@@ -62,7 +62,7 @@ See the [Links](https://www.markdownguide.org/basic-syntax/) Markdown syntax doc
62
62
 
63
63
  ## API Documentation
64
64
 
65
- The API documentation is mostly pulled from docstrings in the source code using the MkDocs
65
+ The API documentation is mostly pulled from docstrings in the source code using the Zensical
66
66
  [mkdocstrings](https://mkdocstrings.github.io/) plugin.
67
67
 
68
68
  When using `mkdocstrings`, it must be preceded by a blank line before and after, i.e.: