Skip to content

Commit 8a4f827

Browse files
committed
Fixed mkdocstrings auto python documentation
Also fixed Markdown syntax in a lot more files
1 parent 1316bdd commit 8a4f827

21 files changed

+440
-361
lines changed

.github/CONTRIBUTING.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,15 @@ The tables below list all prerequisites along with the minimum required version
6767
| ------------------------------------------------------------------------------------------ | --------------- | --------------------------------- |
6868
| [codecov](http://doc.pytest.org/en/latest/) | `2.1.13` | Cover coverage reporting |
6969
| [invoke](https://www.pyinvoke.org/) | `2.2.0` | Command automation |
70+
| [griffe_typingdoc](https://github.com/mkdocstrings/griffe-typingdoc) | `0.2.7` | mkdocstrings extension for typing |
7071
| [mypy](https://mypy-lang.org/) | `1.13.0` | Static type checker |
7172
| [pytest](https://docs.pytest.org/en/stable/) | `3.0.6` | Unit and integration tests |
7273
| [pytest-cov](http://doc.pytest.org/en/latest/) | `6.0.0` | Pytest code coverage |
7374
| [pytest-mock](https://pypi.org/project/pytest-mock/) | `3.14.0` | Pytest mocker fixture |
7475
| [mkdocs-include-markdown-plugin](https://pypi.org/project/mkdocs-include-markdown-plugin/) | `7.1.2` | MkDocs Plugin include MkDn |
7576
| [mkdocs-macros-plugin](https://mkdocs-macros-plugin.readthedocs.io/) | `1.3.7` | MkDocs Plugin for macros |
7677
| [mkdocs-material](https://squidfunk.github.io/mkdocs-material/) | `9.5.49` | Documentation |
77-
| [mkdocstrings](https://mkdocstrings.github.io/) | `0.27.0` | Automatic documentation from code |
78+
| [mkdocstrings[python]](https://mkdocstrings.github.io/) | `0.27.0` | MkDocs Plugin for Python AutoDoc |
7879
| [ruff](https://github.com/astral-sh/ruff) | `0.7.3` | Fast linter and formatter |
7980
| [uv](https://github.com/astral-sh/uv) | `0.5.1` | Python package management |
8081

.github/workflows/doc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ jobs:
2626
with:
2727
python-version: ${{ matrix.python-version }}
2828
- name: Install python prerequisites
29-
run: pip install -U --user pip setuptools setuptools-scm mkdocs-include-markdown-plugin mkdocs-macros-plugin mkdocs-material mkdocstrings[python] . plugins/ext_test
29+
run: pip install -U --user pip setuptools setuptools-scm griffe_typingdoc mkdocs-include-markdown-plugin mkdocs-macros-plugin mkdocs-material mkdocstrings[python] . plugins/ext_test
3030
- name: MkDocs documentation build
3131
run: mkdocs build

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Markdown documentation files with non-standards syntax for mkdocstrings that Prettier should not auto-format
2+
docs/features/initialization.md

.prettierrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"overrides": [
3+
{
4+
"files": "*.md",
5+
"options": {
6+
"tabWidth": 4
7+
}
8+
}
9+
]
10+
}

Pipfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ build = "*"
1313
cmd2 = { editable = true, path = "." }
1414
cmd2_ext_test = { editable = true, path = "plugins/ext_test" }
1515
codecov = "*"
16-
doc8 = "*"
1716
gnureadline = { version = "*", sys_platform = "== 'darwin'" }
17+
griffe-typingdoc = "*"
1818
invoke = "*"
1919
ipython = "*"
2020
mypy = "*"
@@ -27,6 +27,7 @@ setuptools-scm = "*"
2727
mkdocs-include-markdown-plugin = "*"
2828
mkdocs-macros-plugin = "*"
2929
mkdocs-material = "*"
30+
mkdocstrings[python] = "*"
3031
twine = ">=1.11"
3132

3233
[pipenv]

docs/features/embedded_python_shells.md

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
If the `cmd2.Cmd` class is instantiated with `include_py=True`, then the optional `py` command will be present and run an interactive Python shell:
66

7-
from cmd2 import Cmd
8-
class App(Cmd):
9-
def __init__(self):
10-
Cmd.__init__(self, include_py=True)
7+
```py
8+
from cmd2 import Cmd
9+
class App(Cmd):
10+
def __init__(self):
11+
Cmd.__init__(self, include_py=True)
12+
```
1113

12-
The Python shell can run CLI commands from you application using the object named in `self.pyscript_name` (defaults to `app`). This wrapper provides access to execute commands in your `cmd2` application while maintaining isolation from the full ``Cmd`` instance. For example, any application command can be run with `app("command ...")`.
14+
The Python shell can run CLI commands from you application using the object named in `self.pyscript_name` (defaults to `app`). This wrapper provides access to execute commands in your `cmd2` application while maintaining isolation from the full `Cmd` instance. For example, any application command can be run with `app("command ...")`.
1315

1416
You may optionally enable full access to to your application by setting `self.self_in_py` to `True`. Enabling this flag adds `self` to the python session, which is a reference to your `cmd2` application. This can be useful for debugging your application.
1517

@@ -19,37 +21,41 @@ Anything in `self.py_locals` is always available in the Python environment.
1921

2022
All of these parameters are also available to Python scripts which run in your application via the `run_pyscript` command:
2123

22-
- supports tab completion of file system paths
23-
- has the ability to pass command-line arguments to the scripts invoked
24+
- supports tab completion of file system paths
25+
- has the ability to pass command-line arguments to the scripts invoked
2426

25-
This command provides a more complicated and more powerful scripting capability than that provided by the simple text file scripts. Python scripts can include conditional control flow logic. See the **python_scripting.py** `cmd2` application and the **script_conditional.py** script in the `examples` source code directory for an example of how to achieve this in your own applications. See `features/scripting:Scripting`{.interpreted-text role="ref"} for an explanation of both scripting methods in **cmd2** applications.
27+
This command provides a more complicated and more powerful scripting capability than that provided by the simple text file scripts. Python scripts can include conditional control flow logic. See the **python_scripting.py** `cmd2` application and the **script_conditional.py** script in the `examples` source code directory for an example of how to achieve this in your own applications. See [Scripting](./scripting.md) for an explanation of both scripting methods in **cmd2** applications.
2628

2729
A simple example of using `run_pyscript` is shown below along with the [arg_printer](https://github.com/python-cmd2/cmd2/blob/master/examples/scripts/arg_printer.py) script:
2830

29-
(Cmd) run_pyscript examples/scripts/arg_printer.py foo bar baz
30-
Running Python script 'arg_printer.py' which was called with 3 arguments
31-
arg 1: 'foo'
32-
arg 2: 'bar'
33-
arg 3: 'baz'
31+
```sh
32+
(Cmd) run_pyscript examples/scripts/arg_printer.py foo bar baz
33+
Running Python script 'arg_printer.py' which was called with 3 arguments
34+
arg 1: 'foo'
35+
arg 2: 'bar'
36+
arg 3: 'baz'
37+
```
3438

3539
## IPython (optional)
3640

3741
**If** [IPython](http://ipython.readthedocs.io) is installed on the system **and** the `cmd2.Cmd` class is instantiated with `include_ipy=True`, then the optional `ipy` command will run an interactive IPython shell:
3842

39-
from cmd2 import Cmd
40-
class App(Cmd):
41-
def __init__(self):
42-
Cmd.__init__(self, include_ipy=True)
43+
```py
44+
from cmd2 import Cmd
45+
class App(Cmd):
46+
def __init__(self):
47+
Cmd.__init__(self, include_ipy=True)
48+
```
4349

4450
The `ipy` command enters an interactive [IPython](http://ipython.readthedocs.io) session. Similar to an interactive Python session, this shell can access your application instance via `self` if `self.self_in_py` is `True` and any changes to your application made via `self` will persist. However, any local or global variable created within the `ipy` shell will not persist in the CLI's environment
4551

4652
Also, as in the interactive Python session, the `ipy` shell has access to the contents of `self.py_locals` and can call back into the application using the `app` object (or your custom name).
4753

4854
[IPython](http://ipython.readthedocs.io) provides many advantages, including:
4955

50-
> - Comprehensive object introspection
51-
> - Get help on objects with `?`
52-
> - Extensible tab completion, with support by default for completion of python variables and keywords
53-
> - Good built-in [ipdb](https://pypi.org/project/ipdb/) debugger
56+
> - Comprehensive object introspection
57+
> - Get help on objects with `?`
58+
> - Extensible tab completion, with support by default for completion of python variables and keywords
59+
> - Good built-in [ipdb](https://pypi.org/project/ipdb/) debugger
5460
5561
The object introspection and tab completion make IPython particularly efficient for debugging as well as for interactive experimentation and data analysis.

docs/features/generating_output.md

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,51 @@
22

33
A standard `cmd` application can produce output by using either of these methods:
44

5-
print("Greetings, Professor Falken.", file=self.stdout)
6-
self.stdout.write("Shall we play a game?\n")
5+
```py
6+
print("Greetings, Professor Falken.", file=self.stdout)
7+
self.stdout.write("Shall we play a game?\n")
8+
```
79

810
While you could send output directly to `sys.stdout`, `cmd2.Cmd`{.interpreted-text role="mod"} can be initialized with a `stdin` and `stdout` variables, which it stores as `self.stdin` and `self.stdout`. By using these variables every time you produce output, you can trivially change where all the output goes by changing how you initialize your class.
911

10-
`cmd2.Cmd`{.interpreted-text role="mod"} extends this approach in a number of convenient ways. See `features/redirection:Output Redirection And Pipes`{.interpreted-text role="ref"} for information on how users can change where the output of a command is sent. In order for those features to work, the output you generate must be sent to `self.stdout`. You can use the methods described above, and everything will work fine. `cmd2.Cmd`{.interpreted-text role="mod"} also includes a number of output related methods which you may use to enhance the output your application produces.
12+
`cmd2.Cmd` extends this approach in a number of convenient ways. See [Output Redirection and Pipes](./redirection.md#output-redirection-and-pipes) for information on how users can change where the output of a command is sent. In order for those features to work, the output you generate must be sent to `self.stdout`. You can use the methods described above, and everything will work fine. `cmd2.Cmd`{.interpreted-text role="mod"} also includes a number of output related methods which you may use to enhance the output your application produces.
1113

1214
## Ordinary Output
1315

14-
The `~cmd2.Cmd.poutput`{.interpreted-text role="meth"} method is similar to the Python [built-in print function](https://docs.python.org/3/library/functions.html#print). `~cmd2.Cmd.poutput`{.interpreted-text role="meth"} adds two conveniences:
16+
The `cmd2.Cmd.poutput` method is similar to the Python [built-in print function](https://docs.python.org/3/library/functions.html#print). `cmd2.Cmd.poutput` adds two conveniences:
1517

16-
> 1\. Since users can pipe output to a shell command, it catches `BrokenPipeError` and outputs the contents of `self.broken_pipe_warning` to `stderr`. `self.broken_pipe_warning` defaults to an empty string so this method will just swallow the exception. If you want to show an error message, put it in `self.broken_pipe_warning` when you initialize `~cmd2.Cmd`{.interpreted-text role="mod"}.
17-
>
18-
> 2\. It examines and honors the `features/settings:allow_style`{.interpreted-text role="ref"} setting. See `features/generating_output:Colored Output`{.interpreted-text role="ref"} below for more details.
18+
1. Since users can pipe output to a shell command, it catches `BrokenPipeError` and outputs the contents of `self.broken_pipe_warning` to `stderr`. `self.broken_pipe_warning` defaults to an empty string so this method will just swallow the exception. If you want to show an error message, put it in `self.broken_pipe_warning` when you initialize `cmd2.Cmd`.
19+
2. It examines and honors the [allow_style](./settings.md#allowstylestyle) setting. See [Colored Output](#colored-output) below for more details.
1920

2021
Here's a simple command that shows this method in action:
2122

22-
def do_echo(self, args):
23-
"""A simple command showing how poutput() works"""
24-
self.poutput(args)
23+
```py
24+
def do_echo(self, args):
25+
"""A simple command showing how poutput() works"""
26+
self.poutput(args)
27+
```
2528

2629
## Error Messages
2730

28-
When an error occurs in your program, you can display it on `sys.stderr` by calling the `~.cmd2.Cmd.perror`{.interpreted-text role="meth"} method. By default this method applies `cmd2.ansi.style_error`{.interpreted-text role="meth"} to the output.
31+
When an error occurs in your program, you can display it on `sys.stderr` by calling the `.cmd2.Cmd.perror` method. By default this method applies `cmd2.ansi.style_error` to the output.
2932

3033
## Warning Messages
3134

32-
`~.cmd2.Cmd.pwarning`{.interpreted-text role="meth"} is just like `~.cmd2.Cmd.perror`{.interpreted-text role="meth"} but applies `cmd2.ansi.style_warning`{.interpreted-text role="meth"} to the output.
35+
`cmd2.Cmd.pwarning` is just like `cmd2.Cmd.perror` but applies `cmd2.ansi.style_warning` to the output.
3336

3437
## Feedback
3538

36-
You may have the need to display information to the user which is not intended to be part of the generated output. This could be debugging information or status information about the progress of long running commands. It's not output, it's not error messages, it's feedback. If you use the `features/settings:Timing`{.interpreted-text role="ref"} setting, the output of how long it took the command to run will be output as feedback. You can use the `~.cmd2.Cmd.pfeedback`{.interpreted-text role="meth"} method to produce this type of output, and several `features/settings:Settings`{.interpreted-text role="ref"} control how it is handled.
39+
You may have the need to display information to the user which is not intended to be part of the generated output. This could be debugging information or status information about the progress of long running commands. It's not output, it's not error messages, it's feedback. If you use the [Timing](./settings.md#timing) setting, the output of how long it took the command to run will be output as feedback. You can use the `cmd2.Cmd.pfeedback` method to produce this type of output, and several [Settings](./settings.md) control how it is handled.
3740

38-
If the `features/settings:quiet`{.interpreted-text role="ref"} setting is `True`, then calling `~.cmd2.Cmd.pfeedback`{.interpreted-text role="meth"} produces no output. If `features/settings:quiet`{.interpreted-text role="ref"} is `False`, the `features/settings:feedback_to_output`{.interpreted-text role="ref"} setting is consulted to determine whether to send the output to `stdout` or `stderr`.
41+
If the [quiet](./settings.md#quiet) setting is `True`, then calling `cmd2.Cmd.pfeedback` produces no output. If [quiet](./settings.md#quiet) is `False`, the [feedback_to_output](./settings.md#feedbackto_outputto_output) setting is consulted to determine whether to send the output to `stdout` or `stderr`.
3942

4043
## Exceptions
4144

42-
If your app catches an exception and you would like to display the exception to the user, the `~.cmd2.Cmd.pexcept`{.interpreted-text role="meth"} method can help. The default behavior is to just display the message contained within the exception. However, if the `features/settings:debug`{.interpreted-text role="ref"} setting is `True`, then the entire stack trace will be displayed.
45+
If your app catches an exception and you would like to display the exception to the user, the `cmd2.Cmd.pexcept` method can help. The default behavior is to just display the message contained within the exception. However, if the [debug](./settings.md#debug) setting is `True`, then the entire stack trace will be displayed.
4346

4447
## Paging Output
4548

46-
If you know you are going to generate a lot of output, you may want to display it in a way that the user can scroll forwards and backwards through it. If you pass all of the output to be displayed in a single call to `~.cmd2.Cmd.ppaged`{.interpreted-text role="meth"}, it will be piped to an operating system appropriate shell command to page the output. On Windows, the output is piped to `more`; on Unix-like operating systems like MacOS and Linux, it is piped to `less`.
49+
If you know you are going to generate a lot of output, you may want to display it in a way that the user can scroll forwards and backwards through it. If you pass all of the output to be displayed in a single call to `.cmd2.Cmd.ppaged`, it will be piped to an operating system appropriate shell command to page the output. On Windows, the output is piped to `more`; on Unix-like operating systems like MacOS and Linux, it is piped to `less`.
4750

4851
## Colored Output
4952

@@ -53,27 +56,27 @@ You can add your own [ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_
5356

5457
After adding the desired escape sequences to your output, you should use one of these methods to present the output to the user:
5558

56-
- `.cmd2.Cmd.poutput`{.interpreted-text role="meth"}
57-
- `.cmd2.Cmd.perror`{.interpreted-text role="meth"}
58-
- `.cmd2.Cmd.pwarning`{.interpreted-text role="meth"}
59-
- `.cmd2.Cmd.pexcept`{.interpreted-text role="meth"}
60-
- `.cmd2.Cmd.pfeedback`{.interpreted-text role="meth"}
61-
- `.cmd2.Cmd.ppaged`{.interpreted-text role="meth"}
59+
- `cmd2.Cmd.poutput`
60+
- `cmd2.Cmd.perror`
61+
- `cmd2.Cmd.pwarning`
62+
- `cmd2.Cmd.pexcept`
63+
- `cmd2.Cmd.pfeedback`
64+
- `cmd2.Cmd.ppaged`
6265

63-
These methods all honor the `features/settings:allow_style`{.interpreted-text role="ref"} setting, which users can modify to control whether these escape codes are passed through to the terminal or not.
66+
These methods all honor the [allow_style](./settings.md#allowstylestyle) setting, which users can modify to control whether these escape codes are passed through to the terminal or not.
6467

6568
## Aligning Text
6669

6770
If you would like to generate output which is left, center, or right aligned within a specified width or the terminal width, the following functions can help:
6871

69-
- `cmd2.utils.align_left`{.interpreted-text role="meth"}
70-
- `cmd2.utils.align_center`{.interpreted-text role="meth"}
71-
- `cmd2.utils.align_right`{.interpreted-text role="meth"}
72+
- `cmd2.utils.align_left`
73+
- `cmd2.utils.align_center`
74+
- `cmd2.utils.align_right`
7275

7376
These functions differ from Python's string justifying functions in that they support characters with display widths greater than 1. Additionally, ANSI style sequences are safely ignored and do not count toward the display width. This means colored text is supported. If text has line breaks, then each line is aligned independently.
7477

7578
## Columnar Output
7679

7780
When generating output in multiple columns, you often need to calculate the width of each item so you can pad it appropriately with spaces. However, there are categories of Unicode characters that occupy 2 cells, and other that occupy 0. To further complicate matters, you might have included ANSI escape sequences in the output to generate colors on the terminal.
7881

79-
The `cmd2.ansi.style_aware_wcswidth`{.interpreted-text role="meth"} function solves both of these problems. Pass it a string, and regardless of which Unicode characters and ANSI text style escape sequences it contains, it will tell you how many characters on the screen that string will consume when printed.
82+
The `cmd2.ansi.style_aware_wcswidth` function solves both of these problems. Pass it a string, and regardless of which Unicode characters and ANSI text style escape sequences it contains, it will tell you how many characters on the screen that string will consume when printed.

0 commit comments

Comments
 (0)