You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/features/argument_processing.md
+17-16Lines changed: 17 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,7 +39,7 @@ command which might have its own argument parsing.
39
39
For each command in the `cmd2.Cmd` subclass which requires argument parsing, create a unique
40
40
instance of `argparse.ArgumentParser()` which can parse the input appropriately for the command.
41
41
Then decorate the command method with the `@with_argparser` decorator, passing the argument parser
42
-
as the first parameter to the decorator. This changes the second argument to the command method,
42
+
as the first parameter to the decorator. This changes the second argument of the command method,
43
43
which will contain the results of `ArgumentParser.parse_args()`.
44
44
45
45
Here's what it looks like:
@@ -68,10 +68,11 @@ def do_speak(self, opts):
68
68
69
69
!!! note
70
70
71
-
`cmd2` sets the `prog` variable in the argument parser based on the name of the method it is decorating. This will override anything you specify in `prog` variable when creating the argument parser.
71
+
`cmd2` sets the `prog` variable in the argument parser based on the name of the method it is decorating.
72
+
This will override anything you specify in `prog` variable when creating the argument parser.
72
73
73
-
As of the 3.0.0 release, `cmd2` sets `prog` when the instance-specific parser is created, which is
74
-
later than it did previously.
74
+
As of the 3.0.0 release, `cmd2` sets `prog` when the instance-specific parser is created, which is later
75
+
than in previous versions.
75
76
76
77
## Help Messages
77
78
@@ -110,7 +111,7 @@ optional arguments:
110
111
```
111
112
112
113
If you would prefer, you can set the `description` while instantiating the `argparse.ArgumentParser`
113
-
and leave the docstring on your method empty:
114
+
and leave the docstring on your method blank:
114
115
115
116
```py
116
117
from cmd2 import Cmd2ArgumentParser, with_argparser
@@ -226,8 +227,8 @@ class CmdLineApp(cmd2.Cmd):
226
227
227
228
## Unknown Positional Arguments
228
229
229
-
If you want all unknown arguments to be passed to your command as a list of strings, then decorate
230
-
the command method with the `@with_argparser(..., with_unknown_args=True)` decorator.
230
+
To pass all unknown arguments to be passed to your command as a list of strings, then decorate the
231
+
command method with the `@with_argparser(..., with_unknown_args=True)` decorator.
Copy file name to clipboardExpand all lines: docs/features/scripting.md
+60-63Lines changed: 60 additions & 63 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
1
# Scripting
2
2
3
-
Operating system shells have long had the ability to execute a sequence of commands saved in a text
4
-
file. These script files make long sequences of commands easier to repeatedly execute. `cmd2`
5
-
supports two similar mechanisms: command scripts and python scripts.
3
+
Operating system shells have long been able to execute a sequence of commands saved in a text file.
4
+
These script files simplify the repeated execution of long command sequences. `cmd2` supports two
5
+
similar mechanisms: command scripts and python scripts.
6
6
7
7
## Command Scripts
8
8
@@ -25,20 +25,19 @@ it inside a `cmd2` application.
25
25
26
26
Command script files can be executed using the built-in
27
27
[run_script](./builtin_commands.md#run_script) command or the `@` shortcut (if your application is
28
-
using the default shortcuts). Both ASCII and UTF-8 encoded unicode text files are supported. The
28
+
using the default shortcuts). Both ASCII and UTF-8 encoded Unicode text files are supported. The
29
29
[run_script](./builtin_commands.md#run_script) command supports tab completion of file system paths.
30
30
There is a variant [\_relative_run_script](./builtin_commands.md#_relative_run_script) command or
31
31
`@@` shortcut (if using the default shortcuts) for use within a script which uses paths relative to
32
32
the first script.
33
33
34
34
### Comments
35
35
36
-
Any command line input where the first non-whitespace character is a `#` will be treated as a
37
-
comment. This means any `#` character appearing later in the command will be treated as a literal.
38
-
The same applies to a `#` in the middle of a multiline command, even if it is the first character on
39
-
a line.
36
+
A command line is a comment if the first non-whitespace character is a `#`. This means any `#`
37
+
character appearing later in the command will be treated as a literal. The same applies to a `#` in
38
+
the middle of a multiline command, even if it is the first character on a line.
40
39
41
-
Comments are useful in scripts, but would be pointless within an interactive session.
40
+
Comments are useful in scripts, but are generally not used within an interactive session.
42
41
43
42
(Cmd) # this is a comment
44
43
(Cmd) command # this is not a comment
@@ -62,11 +61,11 @@ as shown above it has the ability to pass command-line arguments to the scripts
62
61
63
62
## Developing a cmd2 API
64
63
65
-
If you as an app designer have not explicitly disabled the `run_pyscript` command it must be assumed
66
-
that your application is structured for use in higherlevel python scripting. The following sections
67
-
are meant as guidelines and highlight possible pitfalls with both production and consumption of API
68
-
functionality. For clarity when speaking of "scripter" we are referring to those writing scripts to
69
-
be run by pyscript and "designer" as the `cmd2`application author.
64
+
If you as an app designer have not explicitly disabled the `run_pyscript` command, you should assume
65
+
your application will be used for higher-level Python scripting. The following sections are meant as
66
+
guidelines and highlight possible pitfalls with both production and consumption of API
67
+
functionality. For clarity, a "scripter" writes pyscripts, and a "designer" is the `cmd2`
68
+
application author.
70
69
71
70
### Basics
72
71
@@ -76,10 +75,9 @@ workflows using simple `app` calls. The result of a `run_pyscript` app call yiel
76
75
`data`.
77
76
78
77
`stdout` and `stderr` are fairly straightforward representations of normal data streams and
79
-
accurately reflect what is seen by the user during normal cmd2 interaction. `stop` contains
80
-
information about how the invoked command has ended its lifecycle. Lastly `data` contains any
81
-
information the designer sets via `self.last_result` or `self._cmd.last_result` if called from
82
-
inside a CommandSet.
78
+
accurately reflect what the user sees during normal cmd2 interaction. `stop` contains information
79
+
about how the invoked command has ended its lifecycle. Lastly `data` contains any information the
80
+
designer sets via `self.last_result` or `self._cmd.last_result` if called from inside a CommandSet.
83
81
84
82
Python scripts executed with [run_pyscript](./builtin_commands.md#run_pyscript) can run `cmd2`
85
83
application commands by using the syntax:
@@ -94,7 +92,7 @@ where:
94
92
attribute
95
93
-`command` and `args` are entered exactly like they would be entered by a user of your application.
96
94
97
-
Using fstrings tends to be the most straight forward and easily readable way to provide parameters.:
95
+
Using f-strings tends to be the most straightforward and easily readable way to provide parameters.:
98
96
99
97
```py
100
98
first ='first'
@@ -112,11 +110,10 @@ script for more information.
112
110
### Design principles
113
111
114
112
If your cmd2 application follows the
115
-
[unix_design_philosophy](https://en.wikipedia.org/wiki/Unix_philosophy) a scripter will have the
116
-
most flexibility to piece together workflows using different commands. If the designer's application
117
-
is more complete and less likely to be augmented in the future a scripter may opt for simple serial
118
-
scripts with little control flow. In either case, choices made by the designer will have effects on
119
-
scripters.
113
+
[Unix design philosophy](https://en.wikipedia.org/wiki/Unix_philosophy) a scripter will have the
114
+
most flexibility to create workflows using different commands. If the designer's application is more
115
+
complete and less likely to be augmented in the future a scripter can use simple serial scripts with
116
+
little control flow. In either case, choices made by the designer will have effects on scripters.
120
117
121
118
The following diagram illustrates the different boundaries to keep in mind.
122
119
@@ -140,18 +137,18 @@ flowchart LR
140
137
141
138
!!! note
142
139
143
-
As a designer it is preferable to design from the inside out. Your code will be infinitely far easier to unit test than at the higher level. While there are regression testing extensions for cmd2, unit testing will always be faster for development.
140
+
As a designer, you should design from the inside out. Your code will be much easier to unit test than at the higher level. While there are regression testing extensions for cmd2, unit testing will always be faster for development.
144
141
145
142
!!! warning
146
143
147
-
It is bad design for a highlevel pyscript to know about, let alone access, lowlevel class libraries of an application. Resist this urge at all costs, unless it's necessary.
144
+
It is bad design for a high-level pyscript to know about, let alone access, low-level class libraries of an application. Resist this urge as much as possible, unless it's necessary.
148
145
149
146
### Developing a Basic API
150
147
151
-
`cmd2`out of the box allows scripters to take advantage of all exposed `do_*` commands. As a
152
-
scripter one can easily interact with the application via `stdout`and`stderr`.
148
+
By default, `cmd2` allows scripters to take advantage of all exposed `do_*` commands. As a scripter,
149
+
you can easily interact with the application via `stdout`and`stderr`.
153
150
154
-
As a baseline let's start off with the the following `cmd2` application called `FirstApp`
151
+
As a baseline, let's start with the following `cmd2` application called `FirstApp`
155
152
156
153
```py
157
154
#!/usr/bin/env python
@@ -198,7 +195,7 @@ if __name__ == '__main__':
198
195
sys.exit(c.cmdloop())
199
196
```
200
197
201
-
Let's start off on the wrong foot:
198
+
Let's start with an example of what not to do:
202
199
203
200
```py
204
201
app('speak'
@@ -212,20 +209,20 @@ SyntaxError: unexpected EOF while parsing
212
209
SyntaxError: unexpected EOFwhile parsing
213
210
```
214
211
215
-
cmd2 pyscripts require **valid**python code as a first step.
212
+
`cmd2` pyscripts require **valid**Python code as a first step.
216
213
217
214
!!! warning
218
215
219
-
It is a common misconception that all application exceptions will "bubble" up from below. Unfortunately or fortunately this isnot the case. `cmd2`sinkholesall application exceptions and there are no means to handle them.
216
+
It is a common misconception that all application exceptions will propagate up from below. This isnot the case. `cmd2`catchesall application exceptions and there are no means to handle them.
220
217
221
218
When executing the `speak` command without parameters you see the following error:
222
219
223
220
(Cmd) speak
224
221
Usage: speak [-h] [-p] [-s] [-r REPEAT] words [...]
225
222
Error: the following arguments are required: words
226
223
227
-
Even though this is a fully qualified `cmd2` error the pyscript must lookfor this error and perform
228
-
error checking.:
224
+
Even though this is a fully qualified `cmd2` error, the pyscript must checkfor this error and
225
+
perform error checking.:
229
226
230
227
```py
231
228
app('speak')
@@ -247,7 +244,7 @@ print(result)
247
244
(Cmd) run_pyscript script.py
248
245
CommandResult(stdout='', stderr='Usage: speak [-h] [-p] [-s] [-r REPEAT] words [...]\nError: the following arguments are required: words\n\n', stop=False, data=None)
249
246
250
-
Now we can see that there has been an error. Let's re write the script to perform error checking.:
247
+
Now we can see that there has been an error. Let's rewrite the script to perform error checking.:
251
248
252
249
```py
253
250
result= app('speak')
@@ -259,7 +256,7 @@ if not result:
259
256
(Cmd) run_pyscript script.py
260
257
Something went wrong
261
258
262
-
In Python development, it is good practice to fail andexit quickly after user input.:
259
+
In Python development, it is good practice to fail fast after user input.:
263
260
264
261
```py
265
262
import sys
@@ -276,8 +273,8 @@ print("Continuing along..")
276
273
(Cmd) run_pyscript script.py
277
274
Continuing along..
278
275
279
-
We changed the input to be a valid `speak` command but no output. Again we must inspect the
280
-
`CommandResult`:
276
+
We changed the input to be a valid `speak` command, but there was no output. Again we must inspect
277
+
the `CommandResult`:
281
278
282
279
```py
283
280
import sys
@@ -294,18 +291,18 @@ print(result.stdout)
294
291
(Cmd) run_pyscript script.py
295
292
TRUTH!!!
296
293
297
-
By just using `stdout`and`stderr` it is possible to string together commands with rudimentary
298
-
control flow. In the next section we will show how to take advantage of`cmd_result` data.
294
+
By just using `stdout`and`stderr` it is possible to chain commands with rudimentary control flow.
295
+
In the next section we will show how to use`cmd_result` data.
299
296
300
297
### Developing an Advanced API
301
298
302
-
Until now the application designer has paid little attention to scripters and their needs. Wouldn't
303
-
it be nice ifwhile creating pyscripts one did not have to parse data from`stdout`? We can
304
-
accommodate the weary scripter by adding one small line at the end of our `do_*` commands.
299
+
So far, we haven't focused on the scripter's needs. Wouldn't it be nice if while creating pyscripts
300
+
you did not have to parse data from`stdout`? We can accommodate the scripter by adding one small
301
+
line at the end of our `do_*` commands.
305
302
306
303
`self.last_result = <value>`
307
304
308
-
Adding the above line supercharges a cmd2 application and opens a new world of possibilities.
305
+
Adding the above line enhances a cmd2 application and opens a new world of possibilities.
309
306
310
307
!!! tip
311
308
@@ -315,7 +312,7 @@ Adding the above line supercharges a cmd2 application and opens a new world of p
315
312
self._cmd.last_result =<value>
316
313
```
317
314
318
-
In the following command example we returnan array containing directory elements.:
315
+
In the following command example we returna list containing directory elements.:
319
316
320
317
```py
321
318
dir_parser= cmd2.Cmd2ArgumentParser()
@@ -353,22 +350,22 @@ Results:
353
350
Cmd) run_pyscript script.py
354
351
['.venv', 'app.py', 'script.py']
355
352
356
-
As a rule of thumb it is safer for the designer to return simple scalar types as command results
357
-
instead of complex objects. If thereisbenefitin providing class objects designers should choose
358
-
immutable over mutable types and never provide direct access to class members as this could
0 commit comments