scipy-doctest 1.2.0__py3-none-any.whl → 1.3__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,11 +1,21 @@
1
1
  """
2
- Doctests on steroids.
3
-
4
- Whitespace-insensitive, numpy-aware, floating-point-aware doctest helpers.
2
+ Configurable, whitespace-insensitive, floating-point-aware doctest helpers.
5
3
  """
6
4
 
7
5
 
8
- __version__ = "1.2.0"
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
+
9
19
 
10
20
  from .impl import DTChecker, DTFinder, DTParser, DTRunner, DebugDTRunner, DTConfig # noqa
11
21
  from .frontend import testmod, testfile, find_doctests, run_docstring_examples # noqa
scipy_doctest/impl.py CHANGED
@@ -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,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scipy_doctest
3
- Version: 1.2.0
4
- Summary: Doctests on steroids.
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/ev-br/scpdt
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 -e .
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
- #### Command-line interface
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
- #### More fine-grained control
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
- ### The SciPy Doctest Pytest Plugin
222
+ To set any of these attributes, create an instance of `DTConfig` and assign the attributes
223
+ in a usual way.
171
224
 
172
- The pytest plugin enables the use of `scipy_doctest` tools to perform doctests.
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
- Follow the given instructions to utilize the pytest plugin for doctesting.
230
+ ### Examples
175
231
 
176
- ### Running Doctests on SciPy
232
+ ```
233
+ dt_config = DTConfig()
234
+ ```
177
235
 
178
- 1. **Install plugin**
236
+ or, if using pytest,
179
237
 
180
- ```bash
181
- pip install scipy-doctest
238
+ ```python
239
+ from scipy_doctest.conftest import dt_config # a DTConfig instance with default settings
182
240
  ```
183
241
 
184
- 2. **Configure Your Doctesting Experience**
242
+ and then
185
243
 
186
- To tailor your doctesting experience, you can utilize an instance of `DTConfig`.
187
- An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/scipy/scipy_doctest#tailoring-your-doctesting-experience) section.
244
+ ```
245
+ dt_config.rndm_markers = {'# unintialized'}
188
246
 
189
- 3. **Run Doctests**
247
+ dt_config.stopwords = {'plt.', 'plt.hist', 'plt.show'}
190
248
 
191
- Doctesting is configured to execute on SciPy using the `dev.py` module.
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
- To run all doctests, use the following command:
194
- ```bash
195
- python dev.py smoke-docs
254
+ dt_config.skiplist = {
255
+ 'scipy.special.sinc',
256
+ 'scipy.misc.who',
257
+ 'scipy.optimize.show_options'
258
+ }
196
259
  ```
197
260
 
198
- To run doctests on specific SciPy modules, e.g: `cluster`, use the following command:
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
- ### Running Doctests on Other Packages/Projects
264
+ #### Alternative Checkers
205
265
 
206
- If you want to run doctests on packages or projects other than SciPy, follow these steps:
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
- ```bash
211
- pip install scipy-doctest
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
- 2. **Register or Load the Plugin**
282
+ and
215
283
 
216
- Next, you need to register or load the pytest plugin within your test module or `conftest.py` file.
284
+ ```
285
+ dt_config = DTConfig()
286
+ dt_config.CheckerKlass = VanillaOutputChecker
287
+ ```
217
288
 
218
- To do this, add the following line of code:
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
- pytest_plugins = "scipy_doctest"
224
- ```
294
+ ### The SciPy Doctest Pytest Plugin
225
295
 
226
- 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.
296
+ The pytest plugin enables the use of `scipy_doctest` tools to perform doctests.
227
297
 
228
- 3. **Configure your doctesting experience**
298
+ Follow the given instructions to utilize the pytest plugin for doctesting.
229
299
 
230
- An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/scipy/scipy_doctest#tailoring-your-doctesting-experience) section.
300
+ ### NumPy and SciPy wrappers
231
301
 
232
- 4. **Run doctests**
233
302
 
234
- Once the plugin is registered, you can run your doctests by executing the following command:
303
+ NumPy wraps `scipy-doctest` with the `spin` command
235
304
 
236
- ```bash
237
- $ python -m pytest --doctest-modules
238
305
  ```
239
- or
240
- ```bash
241
- $ pytest --pyargs <your-package> --doctest-modules
306
+ $ spin check-docs
242
307
  ```
243
308
 
244
- By default, all doctests are collected. To only collect public objects, `strategy="api"`,
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
- ### Tailoring Your Doctesting Experience
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; (iii) being a pytest plugin, `pytest-doctestplus` is tightly
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` use modified doctesting in their `refguide-check` utilities.
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 nothing but the core functionality of the modified
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.
@@ -1,8 +1,8 @@
1
- scipy_doctest/__init__.py,sha256=2cXsI_Nouas9cxQOHWxWrteVnYCqgCY4CsngSMXplsQ,314
1
+ scipy_doctest/__init__.py,sha256=4h7LxZKVG1xkxplJEYHb_FyIlIO-YptKsr7auAwOPEQ,649
2
2
  scipy_doctest/__main__.py,sha256=H8jTO13GlOLzexbgu7lHMJW1y3_NhLOSArARFZ5WS7o,90
3
3
  scipy_doctest/conftest.py,sha256=5vZxzuH042urYIToiKWANDJHQPoGkfQI-ppQ_cuHgM0,53
4
4
  scipy_doctest/frontend.py,sha256=7Vz9VIRmzdkmwPD1OtI9sJSxCXIF7jmSxXyt6asjaI0,18628
5
- scipy_doctest/impl.py,sha256=pHNmQHSieXaRB4tb5Qa85h4j2Ovr_yxxVb4A36QOS7c,21638
5
+ scipy_doctest/impl.py,sha256=vM5c6O6VoTubFl8KltEp9-M425dig4y15-Wb5_3D9xc,22018
6
6
  scipy_doctest/plugin.py,sha256=DzTPBCDIre5b2e8JLiTGw7d9zhCP9hYqXcxeKpFTtys,12900
7
7
  scipy_doctest/util.py,sha256=R-pS9FSL5hQNmOA0nhRDLOL1riFVAoK-OhG70ilaKhw,8057
8
8
  scipy_doctest/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -22,8 +22,8 @@ scipy_doctest/tests/test_runner.py,sha256=qP4u8ngbUK946HhMM6Py70hi0W0DcZGcCN258p
22
22
  scipy_doctest/tests/test_skipmarkers.py,sha256=dCng4YfW7OWNnURSlxe7uoYUzURksPXi2AIlehbGk3w,7204
23
23
  scipy_doctest/tests/test_testfile.py,sha256=66ZHUpEGGg8MfQT8EKSZ8Zx5pV55gP__TZejGMYwBHA,733
24
24
  scipy_doctest/tests/test_testmod.py,sha256=6rng0wQ9FE4P7LKtH_vbQrfd5J3SHoG77A-Z6gVA7yc,5497
25
- scipy_doctest-1.2.0.dist-info/entry_points.txt,sha256=dFda3z6PjFL7pEWokv_QmoLwE8X1HETCY1H60xopQ-s,47
26
- scipy_doctest-1.2.0.dist-info/LICENSE,sha256=xH5PVX8bm8e1JxkmJ-e5FsZsOa7FsNOMfepmCvMoR9g,1523
27
- scipy_doctest-1.2.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
28
- scipy_doctest-1.2.0.dist-info/METADATA,sha256=dUi0rBx7fzl1_zFUJX30fKLFeU_CJ2V5QHeU_n7fu_o,15929
29
- scipy_doctest-1.2.0.dist-info/RECORD,,
25
+ scipy_doctest-1.3.dist-info/entry_points.txt,sha256=dFda3z6PjFL7pEWokv_QmoLwE8X1HETCY1H60xopQ-s,47
26
+ scipy_doctest-1.3.dist-info/LICENSE,sha256=xH5PVX8bm8e1JxkmJ-e5FsZsOa7FsNOMfepmCvMoR9g,1523
27
+ scipy_doctest-1.3.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
28
+ scipy_doctest-1.3.dist-info/METADATA,sha256=OAUIMMQKyz3hGMc4NieB6LFO-6Z_OXoXXj_WbZA4BWE,14508
29
+ scipy_doctest-1.3.dist-info/RECORD,,