Skip to content

Commit 1472b99

Browse files
authored
Attempt to fix ReadTheDocs Sphinx build (#1337)
* Attempt to fix ReadTheDocs Sphinx build * Fix linting for docs/conf.py
1 parent 28bb96c commit 1472b99

File tree

5 files changed

+74
-31
lines changed

5 files changed

+74
-31
lines changed

.readthedocs.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Read the Docs configuration file for Sphinx projects
2+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3+
4+
# Required
5+
version: 2
6+
7+
# Set the OS, Python version and other tools you might need
8+
build:
9+
os: ubuntu-22.04
10+
tools:
11+
python: "3.12"
12+
13+
# Build documentation in the "docs/" directory with Sphinx
14+
sphinx:
15+
configuration: docs/conf.py
16+
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
17+
# builder: "dirhtml"
18+
# Fail on all warnings to avoid broken references
19+
# fail_on_warning: true
20+
21+
# Optionally build your docs in additional formats such as PDF and ePub
22+
# formats:
23+
# - pdf
24+
# - epub
25+
formats: all
26+
27+
# Optional but recommended, declare the Python requirements required to build your documentation
28+
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
29+
python:
30+
install:
31+
- requirements: docs/requirements.txt

docs/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
add these directories to sys.path here. If the directory is relative to the
1818
documentation root, use os.path.abspath to make it absolute, like shown here.
1919
"""
20+
2021
# Import for custom theme from Read the Docs
22+
import sphinx_rtd_theme
2123

2224
import cmd2
2325

@@ -51,7 +53,7 @@
5153

5254
# General information about the project.
5355
project = 'cmd2'
54-
copyright = '2010-2021, cmd2 contributors'
56+
copyright = '2010-2024, cmd2 contributors'
5557
author = 'cmd2 contributors'
5658

5759
# The version info for the project you're documenting, acts as replacement for
@@ -89,6 +91,9 @@
8991
# The theme to use for HTML and HTML Help pages. See the documentation for
9092
# a list of builtin themes.
9193

94+
# Custom theme from ReadTheDocs
95+
html_theme = 'sphinx_rtd_theme'
96+
9297
# Theme options are theme-specific and customize the look and feel of a theme
9398
# further. For a list of options available for each theme, see the
9499
# documentation.

docs/features/scripting.rst

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -84,25 +84,25 @@ command. Here's a simple example that uses the arg_printer_ script::
8484
system paths, and as shown above it has the ability to pass command-line
8585
arguments to the scripts invoked.
8686

87-
Developing a CMD2 API
87+
Developing a CMD2 API
8888
---------------------
8989

9090
If you as an app designer have not explicitly disabled the run_pyscript command it must be assumed
9191
that your application is structured for use in higher level python scripting. The following sections
9292
are meant as guidelines and highlight possible pitfalls with both production and consumption
9393
of API functionality. For clarity when speaking of "scripter" we are referring to those writing
94-
scripts to be run by pyscript and "designer" as the CMD2 application author.
94+
scripts to be run by pyscript and "designer" as the CMD2 application author.
9595

9696
Basics
9797
~~~~~~
9898

9999
Without any work on the part of the designer, a scripter can take advantage of piecing together workflows
100-
using simple ``app`` calls. The result of a run_pyscript app call yields a ``CommandResult`` object exposing
101-
four members: ``Stdout``, ``Stderr``, ``Stop``, and ``Data``.
100+
using simple ``app`` calls. The result of a run_pyscript app call yields a ``CommandResult`` object exposing
101+
four members: ``Stdout``, ``Stderr``, ``Stop``, and ``Data``.
102102

103103
``Stdout`` and ``Stderr`` are fairly straightforward representations of normal data streams and accurately reflect
104-
what is seen by the user during normal cmd2 interaction. ``Stop`` contains information about how the invoked
105-
command has ended its lifecycle. Lastly ``Data`` contains any information the designer sets via ``self.last_result``
104+
what is seen by the user during normal cmd2 interaction. ``Stop`` contains information about how the invoked
105+
command has ended its lifecycle. Lastly ``Data`` contains any information the designer sets via ``self.last_result``
106106
or ``self._cmd.last_result`` if called from inside a CommandSet.
107107

108108

@@ -118,7 +118,7 @@ where:
118118
* ``command`` and ``args`` are entered exactly like they would be entered by
119119
a user of your application.
120120

121-
Using fstrings tends to be the most straight forward and easily readable way to
121+
Using fstrings tends to be the most straight forward and easily readable way to
122122
provide parameters.::
123123

124124
first = 'first'
@@ -136,7 +136,7 @@ Design principles
136136
If the cmd2 application follows the unix_design_philosophy_ a scriptor will have the most flexibility
137137
to piece together workflows using different commands. If the designers' application is more complete
138138
and less likely to be augmented in the future a scripter may opt for simple serial scripts with little
139-
control flow. In either case, choices made by the designer will have effects on scripters.
139+
control flow. In either case, choices made by the designer will have effects on scripters.
140140

141141
The following diagram illustrates the different boundaries to keep in mind.
142142

@@ -167,7 +167,7 @@ The following diagram illustrates the different boundaries to keep in mind.
167167
.. note::
168168

169169
As a designer it is preferable to design from the inside to out. Your code will be
170-
infinitely far easier to unit test than at the higher level. While there are
170+
infinitely far easier to unit test than at the higher level. While there are
171171
regression testing extensions for cmd2 UnitTesting will always be faster for development.
172172

173173
.. warning::
@@ -178,7 +178,7 @@ The following diagram illustrates the different boundaries to keep in mind.
178178
Developing a Basic API
179179
~~~~~~~~~~~~~~~~~~~~~~
180180

181-
CMD2 out of the box allows scripters to take advantage of all exposed ``do_*`` commands. As a
181+
CMD2 out of the box allows scripters to take advantage of all exposed ``do_*`` commands. As a
182182
scripter one can easily interact with the application via ``stdout`` and ``stderr``.
183183

184184
As a baseline lets start off with the familiar FirstApp
@@ -243,7 +243,7 @@ Lets start off on the wrong foot::
243243
^
244244
SyntaxError: unexpected EOF while parsing
245245

246-
cmd2 pyscripts require **valid** python code as a first step.
246+
cmd2 pyscripts require **valid** python code as a first step.
247247

248248
.. warning::
249249

@@ -253,7 +253,7 @@ cmd2 pyscripts require **valid** python code as a first step.
253253

254254
When executing the ``speak`` command without parameters you see the following error::
255255

256-
(Cmd) speak
256+
(Cmd) speak
257257
Usage: speak [-h] [-p] [-s] [-r REPEAT] words [...]
258258
Error: the following arguments are required: words
259259

@@ -264,19 +264,19 @@ Even though this is a fully qualified CMD2 error the py_script must look for thi
264264

265265
::
266266

267-
(Cmd) run_pyscript script.py
267+
(Cmd) run_pyscript script.py
268268
Working
269-
(Cmd)
269+
(Cmd)
270270

271-
You should notice that no error message is printed. Let's utilize the ``CommandResult``
271+
You should notice that no error message is printed. Let's utilize the ``CommandResult``
272272
object to inspect the actual returned data.::
273273

274274
result = app('speak')
275275
print(result)
276276

277277
::
278278

279-
(Cmd) run_pyscript script.py
279+
(Cmd) run_pyscript script.py
280280
CommandResult(stdout='', stderr='Usage: speak [-h] [-p] [-s] [-r REPEAT] words [...]\nError: the following arguments are required: words\n\n', stop=False, data=None)
281281

282282
Now we can see that there has been an error. Let's re write the script to perform error checking.::
@@ -288,7 +288,7 @@ Now we can see that there has been an error. Let's re write the script to perfor
288288

289289
::
290290

291-
(Cmd) run_pyscript script.py
291+
(Cmd) run_pyscript script.py
292292
Something went wrong
293293

294294
In python development is good practice to fail and exit quickly after user input.::
@@ -305,10 +305,10 @@ In python development is good practice to fail and exit quickly after user input
305305

306306
::
307307

308-
(Cmd) run_pyscript script.py
308+
(Cmd) run_pyscript script.py
309309
Continuing along..
310310

311-
We changed the input to be a valid ``speak`` command but no output. Again we must inspect the
311+
We changed the input to be a valid ``speak`` command but no output. Again we must inspect the
312312
``CommandResult``::
313313

314314
import sys
@@ -323,7 +323,7 @@ We changed the input to be a valid ``speak`` command but no output. Again we mus
323323

324324
::
325325

326-
(Cmd) run_pyscript script.py
326+
(Cmd) run_pyscript script.py
327327
TRUTH!!!
328328

329329
By just using ``stdout`` and ``stderr`` it is possible to string together commands
@@ -334,7 +334,7 @@ Developing an Advanced API
334334
~~~~~~~~~~~~~~~~~~~~~~~~~~
335335

336336
Until now the application designer has paid little attention to scripters and their needs.
337-
Wouldn't it be nice if while creating py_scripts one did not have to parse data from ``stdout``? We can
337+
Wouldn't it be nice if while creating py_scripts one did not have to parse data from ``stdout``? We can
338338
accomodate the weary scripter by adding one small line at the end of our ``do_*`` commands.
339339

340340
``self.last_result = <value>``
@@ -378,22 +378,22 @@ The following script retrieves the array contents.::
378378

379379
Results::
380380

381-
Cmd) run_pyscript script.py
381+
Cmd) run_pyscript script.py
382382
['.venv', 'app.py', 'script.py']
383383

384-
As a rule of thumb it is safer for the designer to return simple scalar types as command results instead of complex objects.
385-
If there is benefit in providing class objects designers should choose immutable over mutable types and never
384+
As a rule of thumb it is safer for the designer to return simple scalar types as command results instead of complex
385+
objects. If there is benefit in providing class objects designers should choose immutable over mutable types and never
386386
provide direct access to class members as this could potentially lead to violation of the open_closed_principle_.
387387

388-
When possible, a dataclass is a lightweight solution perfectly suited for data manipulation. Lets dive into an
388+
When possible, a dataclass is a lightweight solution perfectly suited for data manipulation. Lets dive into an
389389
example.
390390

391391
The following fictitional application has two commands: ``build`` and ``status``. We can pretend that the build action
392392
happens somewhere else in the world at an REST API endpoint and has significant computational cost. The status command
393393
for all intents and purposes will only show the current status of a build task. The application has provided all that is
394-
needed for a user to start a build and then determine it's status. The problem however is that with a long running process
395-
the user may want to wait for it to finish. A designer may be tempted to create a command to start a build and then
396-
poll for status until finished but this scenario is better solved as an extensible script.
394+
needed for a user to start a build and then determine it's status. The problem however is that with a long running
395+
process the user may want to wait for it to finish. A designer may be tempted to create a command to start a build and
396+
then poll for status until finished but this scenario is better solved as an extensible script.
397397

398398
app.py::
399399

@@ -501,7 +501,7 @@ The below is a possible solution via pyscript::
501501

502502
build_status = result.data
503503

504-
# If the status shows complete then we are done
504+
# If the status shows complete then we are done
505505
if build_status.status in ['finished', 'canceled']:
506506
print(f"Build {build.name} has completed")
507507
break
@@ -520,4 +520,4 @@ The below is a possible solution via pyscript::
520520
https://en.wikipedia.org/wiki/Unix_philosophy
521521

522522
.. _open_closed_principle:
523-
https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle
523+
https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle

docs/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Sphinx>=8.1.0
2+
sphinx-autobuild>=2024.10.3
3+
sphinx-rtd-theme>=3.0.1

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ per-file-ignores."cmd2/__init__.py" = [
156156
"F401", # Unused import
157157
]
158158

159+
per-file-ignores."docs/conf.py" = [
160+
"F401", # Unused import
161+
]
162+
159163
per-file-ignores."examples/override_parser.py" = [
160164
"E402", # Module level import not at top of file
161165
]

0 commit comments

Comments
 (0)