scipy-doctest 1.2.0__tar.gz → 1.3__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.
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/PKG-INFO +119 -101
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/README.md +116 -98
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/pyproject.toml +1 -1
- scipy_doctest-1.3/scipy_doctest/__init__.py +22 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/impl.py +8 -0
- scipy_doctest-1.2.0/scipy_doctest/__init__.py +0 -12
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/LICENSE +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/__main__.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/conftest.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/frontend.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/plugin.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/__init__.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/failure_cases.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/failure_cases_2.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/finder_cases.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/local_file.txt +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/local_file_cases.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/module_cases.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/octave_a.mat +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/scipy_ndimage_tutorial_clone.rst +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/stopwords_cases.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/test_finder.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/test_parser.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/test_pytest_configuration.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/test_runner.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/test_skipmarkers.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/test_testfile.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/test_testmod.py +0 -0
- {scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/util.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: scipy_doctest
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.3
|
|
4
|
+
Summary: Configurable, whitespace-insensitive, floating-point-aware doctest helpers.
|
|
5
5
|
Maintainer-email: SciPy developers <scipy-dev@python.org>
|
|
6
6
|
Requires-Python: >=3.8
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
@@ -14,7 +14,7 @@ Requires-Dist: numpy>=1.19.5
|
|
|
14
14
|
Requires-Dist: pytest
|
|
15
15
|
Requires-Dist: scipy ; extra == "test"
|
|
16
16
|
Requires-Dist: matplotlib ; extra == "test"
|
|
17
|
-
Project-URL: Home, https://github.com/
|
|
17
|
+
Project-URL: Home, https://github.com/scipy/scipy_doctest
|
|
18
18
|
Provides-Extra: test
|
|
19
19
|
|
|
20
20
|
# Floating-point aware, human readable, numpy-compatible doctesting.
|
|
@@ -100,7 +100,7 @@ the output. Thus the example source needs to be valid python code still.
|
|
|
100
100
|
## Install and test
|
|
101
101
|
|
|
102
102
|
```
|
|
103
|
-
$ pip install -
|
|
103
|
+
$ pip install scipy-doctest
|
|
104
104
|
$ pytest --pyargs scipy_doctest
|
|
105
105
|
```
|
|
106
106
|
|
|
@@ -112,9 +112,56 @@ or nearly so.
|
|
|
112
112
|
|
|
113
113
|
The other layer is the `pytest` plugin.
|
|
114
114
|
|
|
115
|
+
### Run doctests via pytest
|
|
116
|
+
|
|
117
|
+
To run doctests on your package or project, follow these steps:
|
|
118
|
+
|
|
119
|
+
1. **Install the plugin**
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install scipy-doctest
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
2. **Register or load the plugin**
|
|
126
|
+
|
|
127
|
+
Next, you need to register or load the pytest plugin within your test module or `conftest.py` file.
|
|
128
|
+
|
|
129
|
+
To do this, add the following line of code:
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
# In your conftest.py file or test module
|
|
133
|
+
|
|
134
|
+
pytest_plugins = "scipy_doctest"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Check out the [pytest documentation](https://docs.pytest.org/en/stable/how-to/writing_plugins.html#requiring-loading-plugins-in-a-test-module-or-conftest-file) for more information on requiring/loading plugins in a test module or `conftest.py` file.
|
|
138
|
+
|
|
139
|
+
3. **Run doctests**
|
|
140
|
+
|
|
141
|
+
Once the plugin is registered, run the doctests by executing the following command:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
$ python -m pytest --doctest-modules
|
|
145
|
+
```
|
|
146
|
+
or
|
|
147
|
+
```bash
|
|
148
|
+
$ pytest --pyargs <your-package> --doctest-modules
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
By default, all doctests are collected. To only collect public objects, `strategy="api"`,
|
|
152
|
+
use the command flag
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
$ pytest --pyargs <your-package> --doctest-modules --doctest-collect=api
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
See [More fine-grained control](https://github.com/scipy/scipy_doctest#More-fine-grained-control) section
|
|
159
|
+
for details on how to customize the behavior.
|
|
160
|
+
|
|
115
161
|
|
|
116
162
|
### Basic usage
|
|
117
163
|
|
|
164
|
+
The use of `pytest` is optional, and you can use the `doctest` layer API.
|
|
118
165
|
For example,
|
|
119
166
|
|
|
120
167
|
```
|
|
@@ -131,7 +178,8 @@ For more details, see the `testmod` docstring. Other useful functions are
|
|
|
131
178
|
`find_doctests`, `run_docstring_examples` and `testfile` (the latter two mimic
|
|
132
179
|
the behavior of the eponymous functions of the `doctest` module).
|
|
133
180
|
|
|
134
|
-
|
|
181
|
+
|
|
182
|
+
### Command-line interface
|
|
135
183
|
|
|
136
184
|
There is a basic CLI, which also mimics that of the `doctest` module:
|
|
137
185
|
```
|
|
@@ -146,8 +194,10 @@ Text files can also be CLI-checked:
|
|
|
146
194
|
$ python -m scipy_doctest bar.rst
|
|
147
195
|
```
|
|
148
196
|
|
|
197
|
+
Notice that the command-line usage only uses the default `DTConfig` settings.
|
|
198
|
+
|
|
149
199
|
|
|
150
|
-
|
|
200
|
+
## More fine-grained control
|
|
151
201
|
|
|
152
202
|
More fine-grained control of the functionality is available via the following
|
|
153
203
|
classes
|
|
@@ -166,133 +216,104 @@ configuration is simply creating an instance, overriding an attribute and
|
|
|
166
216
|
passing the instance to `testmod` or constructors of `DT*` objects. Defaults
|
|
167
217
|
are provided, based on a long-term usage in SciPy.
|
|
168
218
|
|
|
219
|
+
See the [DTConfig docstring](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/impl.py#L24)
|
|
220
|
+
for the full set of attributes that allow you to fine-tune your doctesting experience.
|
|
169
221
|
|
|
170
|
-
|
|
222
|
+
To set any of these attributes, create an instance of `DTConfig` and assign the attributes
|
|
223
|
+
in a usual way.
|
|
171
224
|
|
|
172
|
-
|
|
225
|
+
If using the pytest plugin, it is convenient to use the default instance, which
|
|
226
|
+
is predefined in `scipy_doctest/conftest.py`. This instance will be automatically
|
|
227
|
+
passed around via an
|
|
228
|
+
[attribute of pytest's `Config` object](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/plugin.py#L39).
|
|
173
229
|
|
|
174
|
-
|
|
230
|
+
### Examples
|
|
175
231
|
|
|
176
|
-
|
|
232
|
+
```
|
|
233
|
+
dt_config = DTConfig()
|
|
234
|
+
```
|
|
177
235
|
|
|
178
|
-
|
|
236
|
+
or, if using pytest,
|
|
179
237
|
|
|
180
|
-
```
|
|
181
|
-
|
|
238
|
+
```python
|
|
239
|
+
from scipy_doctest.conftest import dt_config # a DTConfig instance with default settings
|
|
182
240
|
```
|
|
183
241
|
|
|
184
|
-
|
|
242
|
+
and then
|
|
185
243
|
|
|
186
|
-
|
|
187
|
-
|
|
244
|
+
```
|
|
245
|
+
dt_config.rndm_markers = {'# unintialized'}
|
|
188
246
|
|
|
189
|
-
|
|
247
|
+
dt_config.stopwords = {'plt.', 'plt.hist', 'plt.show'}
|
|
190
248
|
|
|
191
|
-
|
|
249
|
+
dt_config.local_resources = {
|
|
250
|
+
'scipy_doctest.tests.local_file_cases.local_files': ['scipy_doctest/tests/local_file.txt'],
|
|
251
|
+
'scipy_doctest.tests.local_file_cases.sio': ['scipy_doctest/tests/octave_a.mat']
|
|
252
|
+
}
|
|
192
253
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
254
|
+
dt_config.skiplist = {
|
|
255
|
+
'scipy.special.sinc',
|
|
256
|
+
'scipy.misc.who',
|
|
257
|
+
'scipy.optimize.show_options'
|
|
258
|
+
}
|
|
196
259
|
```
|
|
197
260
|
|
|
198
|
-
|
|
261
|
+
If you don't set these attributes, the [default settings](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/impl.py#L94) of the attributes are used.
|
|
199
262
|
|
|
200
|
-
```bash
|
|
201
|
-
python dev.py smoke-docs -s cluster
|
|
202
|
-
```
|
|
203
263
|
|
|
204
|
-
|
|
264
|
+
#### Alternative Checkers
|
|
205
265
|
|
|
206
|
-
|
|
266
|
+
By default, we use the floating-point aware `DTChecker`. If you want to use an
|
|
267
|
+
alternative checker, all you need to do is to define the corresponding class,
|
|
268
|
+
and add an attribute to the `DTConfig` instance. For example,
|
|
207
269
|
|
|
208
|
-
1. **Install the plugin**
|
|
209
270
|
|
|
210
|
-
```
|
|
211
|
-
|
|
271
|
+
```
|
|
272
|
+
class VanillaOutputChecker(doctest.OutputChecker):
|
|
273
|
+
"""doctest.OutputChecker to drop in for DTChecker.
|
|
274
|
+
|
|
275
|
+
LSP break: OutputChecker does not have __init__,
|
|
276
|
+
here we add it to agree with DTChecker.
|
|
277
|
+
"""
|
|
278
|
+
def __init__(self, config):
|
|
279
|
+
pass
|
|
212
280
|
```
|
|
213
281
|
|
|
214
|
-
|
|
282
|
+
and
|
|
215
283
|
|
|
216
|
-
|
|
284
|
+
```
|
|
285
|
+
dt_config = DTConfig()
|
|
286
|
+
dt_config.CheckerKlass = VanillaOutputChecker
|
|
287
|
+
```
|
|
217
288
|
|
|
218
|
-
|
|
289
|
+
See [a pytest example](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/tests/test_pytest_configuration.py#L63)
|
|
290
|
+
and [a doctest example](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/tests/test_runner.py#L94)
|
|
291
|
+
for more details.
|
|
219
292
|
|
|
220
|
-
```python
|
|
221
|
-
# In your conftest.py file or test module
|
|
222
293
|
|
|
223
|
-
|
|
224
|
-
```
|
|
294
|
+
### The SciPy Doctest Pytest Plugin
|
|
225
295
|
|
|
226
|
-
|
|
296
|
+
The pytest plugin enables the use of `scipy_doctest` tools to perform doctests.
|
|
227
297
|
|
|
228
|
-
|
|
298
|
+
Follow the given instructions to utilize the pytest plugin for doctesting.
|
|
229
299
|
|
|
230
|
-
|
|
300
|
+
### NumPy and SciPy wrappers
|
|
231
301
|
|
|
232
|
-
4. **Run doctests**
|
|
233
302
|
|
|
234
|
-
|
|
303
|
+
NumPy wraps `scipy-doctest` with the `spin` command
|
|
235
304
|
|
|
236
|
-
```bash
|
|
237
|
-
$ python -m pytest --doctest-modules
|
|
238
305
|
```
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
$ pytest --pyargs <your-package> --doctest-modules
|
|
306
|
+
$ spin check-docs
|
|
242
307
|
```
|
|
243
308
|
|
|
244
|
-
|
|
245
|
-
use the command flag
|
|
309
|
+
SciPy wraps `scipy-doctest` with custom `dev.py` commands:
|
|
246
310
|
|
|
247
|
-
```bash
|
|
248
|
-
$ pytest --pyargs <your-package> --doctest-modules --doctest-collect=api
|
|
249
311
|
```
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
[DTConfig](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/impl.py#L23) offers a variety of attributes that allow you to fine-tune your doctesting experience.
|
|
254
|
-
|
|
255
|
-
These attributes include:
|
|
256
|
-
1. **default_namespace (dict):** Defines the namespace in which examples are executed.
|
|
257
|
-
2. **check_namespace (dict):** Specifies the namespace for conducting checks.
|
|
258
|
-
3. **rndm_markers (set):** Provides additional directives which act like `# doctest: + SKIP`.
|
|
259
|
-
4. **atol (float) and rtol (float):** Sets absolute and relative tolerances for validating doctest examples.
|
|
260
|
-
Specifically, it governs the check using `np.allclose(want, got, atol=atol, rtol=rtol)`.
|
|
261
|
-
5. **optionflags (int):** These are doctest option flags.
|
|
262
|
-
The default setting includes `NORMALIZE_WHITESPACE` | `ELLIPSIS` | `IGNORE_EXCEPTION_DETAIL`.
|
|
263
|
-
6. **stopwords (set):** If an example contains any of these stopwords, the output is not checked (though the source's validity is still assessed).
|
|
264
|
-
7. **pseudocode (list):** Lists strings that, when found in an example, result in no doctesting. This resembles the `# doctest +SKIP` directive and is useful for pseudocode blocks or similar cases.
|
|
265
|
-
8. **skiplist (set):** A list of names of objects with docstrings known to fail doctesting and are intentionally excluded from testing.
|
|
266
|
-
9. **user_context_mgr:** A context manager for running tests.
|
|
267
|
-
Typically, it is entered for each DocTest (especially in API documentation), ensuring proper testing isolation.
|
|
268
|
-
10. **local_resources (dict):** Specifies local files needed for specific tests. The format is `{test.name: list-of-files}`. File paths are relative to the path of `test.filename`.
|
|
269
|
-
11. **parse_namedtuples (bool):** Determines whether to perform a literal comparison (e.g., `TTestResult(pvalue=0.9, statistic=42)`) or extract and compare the tuple values (e.g., `(0.9, 42)`). The default is `True`.
|
|
270
|
-
12. **nameerror_after_exception (bool):** Controls whether subsequent examples in the same test, after one has failed, may raise spurious NameErrors. Set to `True` if you want to observe these errors or if your test is expected to raise NameErrors. The default is `False`.
|
|
271
|
-
|
|
272
|
-
To set any of these attributes, create an instance of `DTConfig` called `dt_config`.
|
|
273
|
-
This instance is already set as an [attribute of pytest's `Config` object](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/plugin.py#L39).
|
|
274
|
-
|
|
275
|
-
**Example:**
|
|
276
|
-
|
|
277
|
-
```python
|
|
278
|
-
dt_config = DTConfig()
|
|
279
|
-
dt_config.stopwords = {'plt.', '.hist', '.show'}
|
|
280
|
-
dt_config.local_resources = {
|
|
281
|
-
'scipy_doctest.tests.local_file_cases.local_files': ['scipy_doctest/tests/local_file.txt'],
|
|
282
|
-
'scipy_doctest.tests.local_file_cases.sio': ['scipy_doctest/tests/octave_a.mat']
|
|
283
|
-
}
|
|
284
|
-
dt_config.skiplist = {
|
|
285
|
-
'scipy.special.sinc',
|
|
286
|
-
'scipy.misc.who',
|
|
287
|
-
'scipy.optimize.show_options'
|
|
288
|
-
}
|
|
312
|
+
$ python dev.py smoke-docs # check docstrings
|
|
313
|
+
$ python dev.py smoke-tutorials # ReST user guide tutorials
|
|
289
314
|
```
|
|
290
315
|
|
|
291
|
-
If you don't set these attributes, the [default settings](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/impl.py#L94) of the attributes are used.
|
|
292
|
-
|
|
293
|
-
By following these steps, you will be able to effectively use the SciPy Doctest pytest plugin for doctests in your Python projects.
|
|
294
316
|
|
|
295
|
-
Happy testing!
|
|
296
317
|
|
|
297
318
|
## Rough edges and sharp bits
|
|
298
319
|
|
|
@@ -326,7 +347,7 @@ being optional. So you either guard the imports in doctests (yikes!), or
|
|
|
326
347
|
the collections fails if dependencies are not available.
|
|
327
348
|
|
|
328
349
|
The solution is to explicitly `--ignore` the paths to modules with optionals.
|
|
329
|
-
(or use `DTConfig.pytest_extra_ignore` list):
|
|
350
|
+
(or, equivalently, use `DTConfig.pytest_extra_ignore` list):
|
|
330
351
|
|
|
331
352
|
```
|
|
332
353
|
$ pytest --ignore=/build-install/lib/scipy/python3.10/site-packages/scipy/_lib ...
|
|
@@ -370,20 +391,17 @@ leads to
|
|
|
370
391
|
differences are: (i) `pytest-doctestplus` is more sensitive to formatting,
|
|
371
392
|
including whitespace---thus if numpy tweaks its output formatting, doctests
|
|
372
393
|
may start failing; (ii) there is still a need for `# doctest: +FLOAT_CMP`
|
|
373
|
-
directives
|
|
374
|
-
coupled to `pytest`. It thus needs to follow `pytest` releases, and
|
|
375
|
-
some maintenance work may be required to adapt when `pytest` publishes a new
|
|
376
|
-
release.
|
|
394
|
+
directives.
|
|
377
395
|
|
|
378
396
|
This project takes a different approach: in addition to plugging into `pytest`,
|
|
379
397
|
we closely follow the `doctest` API and implementation, which are naturally
|
|
380
398
|
way more stable then `pytest`.
|
|
381
399
|
|
|
382
|
-
- `NumPy` and `SciPy`
|
|
400
|
+
- `NumPy` and `SciPy` were using modified doctesting in their `refguide-check` utilities.
|
|
383
401
|
These utilities are tightly coupled to their libraries, and have been reported
|
|
384
402
|
to be not easy to reason about, work with, and extend to other projects.
|
|
385
403
|
|
|
386
|
-
This project is
|
|
404
|
+
This project is mainly the core functionality of the modified
|
|
387
405
|
`refguide-check` doctesting, extracted to a separate package.
|
|
388
406
|
We believe having it separate simplifies both addressing the needs of these
|
|
389
407
|
two packages, and potential adoption by other projects.
|
|
@@ -81,7 +81,7 @@ the output. Thus the example source needs to be valid python code still.
|
|
|
81
81
|
## Install and test
|
|
82
82
|
|
|
83
83
|
```
|
|
84
|
-
$ pip install -
|
|
84
|
+
$ pip install scipy-doctest
|
|
85
85
|
$ pytest --pyargs scipy_doctest
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -93,9 +93,56 @@ or nearly so.
|
|
|
93
93
|
|
|
94
94
|
The other layer is the `pytest` plugin.
|
|
95
95
|
|
|
96
|
+
### Run doctests via pytest
|
|
97
|
+
|
|
98
|
+
To run doctests on your package or project, follow these steps:
|
|
99
|
+
|
|
100
|
+
1. **Install the plugin**
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pip install scipy-doctest
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
2. **Register or load the plugin**
|
|
107
|
+
|
|
108
|
+
Next, you need to register or load the pytest plugin within your test module or `conftest.py` file.
|
|
109
|
+
|
|
110
|
+
To do this, add the following line of code:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
# In your conftest.py file or test module
|
|
114
|
+
|
|
115
|
+
pytest_plugins = "scipy_doctest"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Check out the [pytest documentation](https://docs.pytest.org/en/stable/how-to/writing_plugins.html#requiring-loading-plugins-in-a-test-module-or-conftest-file) for more information on requiring/loading plugins in a test module or `conftest.py` file.
|
|
119
|
+
|
|
120
|
+
3. **Run doctests**
|
|
121
|
+
|
|
122
|
+
Once the plugin is registered, run the doctests by executing the following command:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
$ python -m pytest --doctest-modules
|
|
126
|
+
```
|
|
127
|
+
or
|
|
128
|
+
```bash
|
|
129
|
+
$ pytest --pyargs <your-package> --doctest-modules
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
By default, all doctests are collected. To only collect public objects, `strategy="api"`,
|
|
133
|
+
use the command flag
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
$ pytest --pyargs <your-package> --doctest-modules --doctest-collect=api
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
See [More fine-grained control](https://github.com/scipy/scipy_doctest#More-fine-grained-control) section
|
|
140
|
+
for details on how to customize the behavior.
|
|
141
|
+
|
|
96
142
|
|
|
97
143
|
### Basic usage
|
|
98
144
|
|
|
145
|
+
The use of `pytest` is optional, and you can use the `doctest` layer API.
|
|
99
146
|
For example,
|
|
100
147
|
|
|
101
148
|
```
|
|
@@ -112,7 +159,8 @@ For more details, see the `testmod` docstring. Other useful functions are
|
|
|
112
159
|
`find_doctests`, `run_docstring_examples` and `testfile` (the latter two mimic
|
|
113
160
|
the behavior of the eponymous functions of the `doctest` module).
|
|
114
161
|
|
|
115
|
-
|
|
162
|
+
|
|
163
|
+
### Command-line interface
|
|
116
164
|
|
|
117
165
|
There is a basic CLI, which also mimics that of the `doctest` module:
|
|
118
166
|
```
|
|
@@ -127,8 +175,10 @@ Text files can also be CLI-checked:
|
|
|
127
175
|
$ python -m scipy_doctest bar.rst
|
|
128
176
|
```
|
|
129
177
|
|
|
178
|
+
Notice that the command-line usage only uses the default `DTConfig` settings.
|
|
179
|
+
|
|
130
180
|
|
|
131
|
-
|
|
181
|
+
## More fine-grained control
|
|
132
182
|
|
|
133
183
|
More fine-grained control of the functionality is available via the following
|
|
134
184
|
classes
|
|
@@ -147,133 +197,104 @@ configuration is simply creating an instance, overriding an attribute and
|
|
|
147
197
|
passing the instance to `testmod` or constructors of `DT*` objects. Defaults
|
|
148
198
|
are provided, based on a long-term usage in SciPy.
|
|
149
199
|
|
|
200
|
+
See the [DTConfig docstring](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/impl.py#L24)
|
|
201
|
+
for the full set of attributes that allow you to fine-tune your doctesting experience.
|
|
150
202
|
|
|
151
|
-
|
|
203
|
+
To set any of these attributes, create an instance of `DTConfig` and assign the attributes
|
|
204
|
+
in a usual way.
|
|
152
205
|
|
|
153
|
-
|
|
206
|
+
If using the pytest plugin, it is convenient to use the default instance, which
|
|
207
|
+
is predefined in `scipy_doctest/conftest.py`. This instance will be automatically
|
|
208
|
+
passed around via an
|
|
209
|
+
[attribute of pytest's `Config` object](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/plugin.py#L39).
|
|
154
210
|
|
|
155
|
-
|
|
211
|
+
### Examples
|
|
156
212
|
|
|
157
|
-
|
|
213
|
+
```
|
|
214
|
+
dt_config = DTConfig()
|
|
215
|
+
```
|
|
158
216
|
|
|
159
|
-
|
|
217
|
+
or, if using pytest,
|
|
160
218
|
|
|
161
|
-
```
|
|
162
|
-
|
|
219
|
+
```python
|
|
220
|
+
from scipy_doctest.conftest import dt_config # a DTConfig instance with default settings
|
|
163
221
|
```
|
|
164
222
|
|
|
165
|
-
|
|
223
|
+
and then
|
|
166
224
|
|
|
167
|
-
|
|
168
|
-
|
|
225
|
+
```
|
|
226
|
+
dt_config.rndm_markers = {'# unintialized'}
|
|
169
227
|
|
|
170
|
-
|
|
228
|
+
dt_config.stopwords = {'plt.', 'plt.hist', 'plt.show'}
|
|
171
229
|
|
|
172
|
-
|
|
230
|
+
dt_config.local_resources = {
|
|
231
|
+
'scipy_doctest.tests.local_file_cases.local_files': ['scipy_doctest/tests/local_file.txt'],
|
|
232
|
+
'scipy_doctest.tests.local_file_cases.sio': ['scipy_doctest/tests/octave_a.mat']
|
|
233
|
+
}
|
|
173
234
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
235
|
+
dt_config.skiplist = {
|
|
236
|
+
'scipy.special.sinc',
|
|
237
|
+
'scipy.misc.who',
|
|
238
|
+
'scipy.optimize.show_options'
|
|
239
|
+
}
|
|
177
240
|
```
|
|
178
241
|
|
|
179
|
-
|
|
242
|
+
If you don't set these attributes, the [default settings](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/impl.py#L94) of the attributes are used.
|
|
180
243
|
|
|
181
|
-
```bash
|
|
182
|
-
python dev.py smoke-docs -s cluster
|
|
183
|
-
```
|
|
184
244
|
|
|
185
|
-
|
|
245
|
+
#### Alternative Checkers
|
|
186
246
|
|
|
187
|
-
|
|
247
|
+
By default, we use the floating-point aware `DTChecker`. If you want to use an
|
|
248
|
+
alternative checker, all you need to do is to define the corresponding class,
|
|
249
|
+
and add an attribute to the `DTConfig` instance. For example,
|
|
188
250
|
|
|
189
|
-
1. **Install the plugin**
|
|
190
251
|
|
|
191
|
-
```
|
|
192
|
-
|
|
252
|
+
```
|
|
253
|
+
class VanillaOutputChecker(doctest.OutputChecker):
|
|
254
|
+
"""doctest.OutputChecker to drop in for DTChecker.
|
|
255
|
+
|
|
256
|
+
LSP break: OutputChecker does not have __init__,
|
|
257
|
+
here we add it to agree with DTChecker.
|
|
258
|
+
"""
|
|
259
|
+
def __init__(self, config):
|
|
260
|
+
pass
|
|
193
261
|
```
|
|
194
262
|
|
|
195
|
-
|
|
263
|
+
and
|
|
196
264
|
|
|
197
|
-
|
|
265
|
+
```
|
|
266
|
+
dt_config = DTConfig()
|
|
267
|
+
dt_config.CheckerKlass = VanillaOutputChecker
|
|
268
|
+
```
|
|
198
269
|
|
|
199
|
-
|
|
270
|
+
See [a pytest example](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/tests/test_pytest_configuration.py#L63)
|
|
271
|
+
and [a doctest example](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/tests/test_runner.py#L94)
|
|
272
|
+
for more details.
|
|
200
273
|
|
|
201
|
-
```python
|
|
202
|
-
# In your conftest.py file or test module
|
|
203
274
|
|
|
204
|
-
|
|
205
|
-
```
|
|
275
|
+
### The SciPy Doctest Pytest Plugin
|
|
206
276
|
|
|
207
|
-
|
|
277
|
+
The pytest plugin enables the use of `scipy_doctest` tools to perform doctests.
|
|
208
278
|
|
|
209
|
-
|
|
279
|
+
Follow the given instructions to utilize the pytest plugin for doctesting.
|
|
210
280
|
|
|
211
|
-
|
|
281
|
+
### NumPy and SciPy wrappers
|
|
212
282
|
|
|
213
|
-
4. **Run doctests**
|
|
214
283
|
|
|
215
|
-
|
|
284
|
+
NumPy wraps `scipy-doctest` with the `spin` command
|
|
216
285
|
|
|
217
|
-
```bash
|
|
218
|
-
$ python -m pytest --doctest-modules
|
|
219
286
|
```
|
|
220
|
-
|
|
221
|
-
```bash
|
|
222
|
-
$ pytest --pyargs <your-package> --doctest-modules
|
|
287
|
+
$ spin check-docs
|
|
223
288
|
```
|
|
224
289
|
|
|
225
|
-
|
|
226
|
-
use the command flag
|
|
290
|
+
SciPy wraps `scipy-doctest` with custom `dev.py` commands:
|
|
227
291
|
|
|
228
|
-
```bash
|
|
229
|
-
$ pytest --pyargs <your-package> --doctest-modules --doctest-collect=api
|
|
230
292
|
```
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
[DTConfig](https://github.com/scipy/scipy_doctest/blob/main/scipy_doctest/impl.py#L23) offers a variety of attributes that allow you to fine-tune your doctesting experience.
|
|
235
|
-
|
|
236
|
-
These attributes include:
|
|
237
|
-
1. **default_namespace (dict):** Defines the namespace in which examples are executed.
|
|
238
|
-
2. **check_namespace (dict):** Specifies the namespace for conducting checks.
|
|
239
|
-
3. **rndm_markers (set):** Provides additional directives which act like `# doctest: + SKIP`.
|
|
240
|
-
4. **atol (float) and rtol (float):** Sets absolute and relative tolerances for validating doctest examples.
|
|
241
|
-
Specifically, it governs the check using `np.allclose(want, got, atol=atol, rtol=rtol)`.
|
|
242
|
-
5. **optionflags (int):** These are doctest option flags.
|
|
243
|
-
The default setting includes `NORMALIZE_WHITESPACE` | `ELLIPSIS` | `IGNORE_EXCEPTION_DETAIL`.
|
|
244
|
-
6. **stopwords (set):** If an example contains any of these stopwords, the output is not checked (though the source's validity is still assessed).
|
|
245
|
-
7. **pseudocode (list):** Lists strings that, when found in an example, result in no doctesting. This resembles the `# doctest +SKIP` directive and is useful for pseudocode blocks or similar cases.
|
|
246
|
-
8. **skiplist (set):** A list of names of objects with docstrings known to fail doctesting and are intentionally excluded from testing.
|
|
247
|
-
9. **user_context_mgr:** A context manager for running tests.
|
|
248
|
-
Typically, it is entered for each DocTest (especially in API documentation), ensuring proper testing isolation.
|
|
249
|
-
10. **local_resources (dict):** Specifies local files needed for specific tests. The format is `{test.name: list-of-files}`. File paths are relative to the path of `test.filename`.
|
|
250
|
-
11. **parse_namedtuples (bool):** Determines whether to perform a literal comparison (e.g., `TTestResult(pvalue=0.9, statistic=42)`) or extract and compare the tuple values (e.g., `(0.9, 42)`). The default is `True`.
|
|
251
|
-
12. **nameerror_after_exception (bool):** Controls whether subsequent examples in the same test, after one has failed, may raise spurious NameErrors. Set to `True` if you want to observe these errors or if your test is expected to raise NameErrors. The default is `False`.
|
|
252
|
-
|
|
253
|
-
To set any of these attributes, create an instance of `DTConfig` called `dt_config`.
|
|
254
|
-
This instance is already set as an [attribute of pytest's `Config` object](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/plugin.py#L39).
|
|
255
|
-
|
|
256
|
-
**Example:**
|
|
257
|
-
|
|
258
|
-
```python
|
|
259
|
-
dt_config = DTConfig()
|
|
260
|
-
dt_config.stopwords = {'plt.', '.hist', '.show'}
|
|
261
|
-
dt_config.local_resources = {
|
|
262
|
-
'scipy_doctest.tests.local_file_cases.local_files': ['scipy_doctest/tests/local_file.txt'],
|
|
263
|
-
'scipy_doctest.tests.local_file_cases.sio': ['scipy_doctest/tests/octave_a.mat']
|
|
264
|
-
}
|
|
265
|
-
dt_config.skiplist = {
|
|
266
|
-
'scipy.special.sinc',
|
|
267
|
-
'scipy.misc.who',
|
|
268
|
-
'scipy.optimize.show_options'
|
|
269
|
-
}
|
|
293
|
+
$ python dev.py smoke-docs # check docstrings
|
|
294
|
+
$ python dev.py smoke-tutorials # ReST user guide tutorials
|
|
270
295
|
```
|
|
271
296
|
|
|
272
|
-
If you don't set these attributes, the [default settings](https://github.com/scipy/scipy_doctest/blob/58ff06a837b7bff1dbac6560013fc6fd07952ae2/scipy_doctest/impl.py#L94) of the attributes are used.
|
|
273
|
-
|
|
274
|
-
By following these steps, you will be able to effectively use the SciPy Doctest pytest plugin for doctests in your Python projects.
|
|
275
297
|
|
|
276
|
-
Happy testing!
|
|
277
298
|
|
|
278
299
|
## Rough edges and sharp bits
|
|
279
300
|
|
|
@@ -307,7 +328,7 @@ being optional. So you either guard the imports in doctests (yikes!), or
|
|
|
307
328
|
the collections fails if dependencies are not available.
|
|
308
329
|
|
|
309
330
|
The solution is to explicitly `--ignore` the paths to modules with optionals.
|
|
310
|
-
(or use `DTConfig.pytest_extra_ignore` list):
|
|
331
|
+
(or, equivalently, use `DTConfig.pytest_extra_ignore` list):
|
|
311
332
|
|
|
312
333
|
```
|
|
313
334
|
$ pytest --ignore=/build-install/lib/scipy/python3.10/site-packages/scipy/_lib ...
|
|
@@ -351,20 +372,17 @@ leads to
|
|
|
351
372
|
differences are: (i) `pytest-doctestplus` is more sensitive to formatting,
|
|
352
373
|
including whitespace---thus if numpy tweaks its output formatting, doctests
|
|
353
374
|
may start failing; (ii) there is still a need for `# doctest: +FLOAT_CMP`
|
|
354
|
-
directives
|
|
355
|
-
coupled to `pytest`. It thus needs to follow `pytest` releases, and
|
|
356
|
-
some maintenance work may be required to adapt when `pytest` publishes a new
|
|
357
|
-
release.
|
|
375
|
+
directives.
|
|
358
376
|
|
|
359
377
|
This project takes a different approach: in addition to plugging into `pytest`,
|
|
360
378
|
we closely follow the `doctest` API and implementation, which are naturally
|
|
361
379
|
way more stable then `pytest`.
|
|
362
380
|
|
|
363
|
-
- `NumPy` and `SciPy`
|
|
381
|
+
- `NumPy` and `SciPy` were using modified doctesting in their `refguide-check` utilities.
|
|
364
382
|
These utilities are tightly coupled to their libraries, and have been reported
|
|
365
383
|
to be not easy to reason about, work with, and extend to other projects.
|
|
366
384
|
|
|
367
|
-
This project is
|
|
385
|
+
This project is mainly the core functionality of the modified
|
|
368
386
|
`refguide-check` doctesting, extracted to a separate package.
|
|
369
387
|
We believe having it separate simplifies both addressing the needs of these
|
|
370
388
|
two packages, and potential adoption by other projects.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configurable, whitespace-insensitive, floating-point-aware doctest helpers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
__version__ = "1.3"
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
# register internal modules with pytest; obscure errors galore otherwise
|
|
10
|
+
import pytest
|
|
11
|
+
pytest.register_assert_rewrite(
|
|
12
|
+
"scipy_doctest.conftest", "scipy_doctest.impl", "scipy_doctest.util",
|
|
13
|
+
"scipy_doctest.frontend", "scipy_doctest.plugin"
|
|
14
|
+
)
|
|
15
|
+
except ModuleNotFoundError:
|
|
16
|
+
# pytest is optional, so nothing to do
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
from .impl import DTChecker, DTFinder, DTParser, DTRunner, DebugDTRunner, DTConfig # noqa
|
|
21
|
+
from .frontend import testmod, testfile, find_doctests, run_docstring_examples # noqa
|
|
22
|
+
|
|
@@ -91,6 +91,14 @@ class DTConfig:
|
|
|
91
91
|
adding `# may vary` to the outputs of all examples.
|
|
92
92
|
Each key is a doctest name to skip, and the corresponding value is
|
|
93
93
|
a string. If not empty, the string value is used as the skip reason.
|
|
94
|
+
CheckerKlass : object, optional
|
|
95
|
+
The class for the Checker object. Must mimic the ``DTChecker`` API:
|
|
96
|
+
subclass the `doctest.OutputChecker` and make the constructor signature
|
|
97
|
+
read ``__init__(self, config=None)``, where `config` is a ``DTConfig``
|
|
98
|
+
instance.
|
|
99
|
+
This class will be instantiated by ``DTRunner``.
|
|
100
|
+
Defaults to `DTChecker`.
|
|
101
|
+
|
|
94
102
|
"""
|
|
95
103
|
def __init__(self, *, # DTChecker configuration
|
|
96
104
|
CheckerKlass=None,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Doctests on steroids.
|
|
3
|
-
|
|
4
|
-
Whitespace-insensitive, numpy-aware, floating-point-aware doctest helpers.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
__version__ = "1.2.0"
|
|
9
|
-
|
|
10
|
-
from .impl import DTChecker, DTFinder, DTParser, DTRunner, DebugDTRunner, DTConfig # noqa
|
|
11
|
-
from .frontend import testmod, testfile, find_doctests, run_docstring_examples # noqa
|
|
12
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scipy_doctest-1.2.0 → scipy_doctest-1.3}/scipy_doctest/tests/scipy_ndimage_tutorial_clone.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|