@@ -151,7 +151,7 @@ $ pytest --pyargs <your-package> --doctest-modules --doctest-collect=api
151
151
See [ More fine-grained control] ( #more-fine-grained-control ) section
152
152
for details on how to customize the behavior.
153
153
154
- ** NOTE ** Currently, ` pytest --doctest-modules ` only collects doctests and skips
154
+ ** NOTE** Currently, ` pytest --doctest-modules ` only collects doctests and skips
155
155
'regular' unit tests. This differs from the vanilla ` pytest ` behavior, which collects
156
156
both doctests and unit tests.
157
157
The behavior will change in a future version: ` scipy-doctest==2.0 ` ** will change the
@@ -318,7 +318,7 @@ $ spin smoke-tutorials # ReST user guide tutorials
318
318
319
319
Here is a (non-exhaustive) list of possible gotchas:
320
320
321
- - _ In-place development builds_ .
321
+ #### _ In-place development builds_ .
322
322
323
323
Some tools (looking at you ` meson-python ` ) simulate in-place builds with a
324
324
` build-install ` directory. If this directory is located under the project root,
@@ -342,10 +342,10 @@ If push really comes to shove, you may try using the magic env variable:
342
342
however the need usually indicates an issue with the package itself.
343
343
(see [ gh-107 ] ( https://github.com/scipy/scipy_doctest/pull/107 ) for an example).
344
344
345
- - _ Optional dependencies are not that optional_
345
+ #### _ Optional dependencies are not that optional_
346
346
347
347
If your package contains optional dependencies, doctests do not know about them
348
- being optional. So you either guard the imports in doctests (yikes!), or
348
+ being optional. So you either guard the imports in doctests themselves (yikes!), or
349
349
the collections fails if dependencies are not available.
350
350
351
351
The solution is to explicitly ` --ignore ` the paths to modules with optionals.
@@ -361,7 +361,7 @@ Note that installed packages are no different:
361
361
$ pytest --pyargs scipy --doctest-modules --ignore=/path/to/installed/scipy/_lib
362
362
```
363
363
364
- - _ Doctest collection strategies_
364
+ #### _ Doctest collection strategies_
365
365
366
366
The default collection strategy follows ` doctest ` module and ` pytest ` . This leads
367
367
to duplicates if your package has the split between public and \_ private modules,
@@ -371,19 +371,19 @@ objects will be collected.
371
371
372
372
The decision on what is public is as follows: an object is public iff
373
373
374
- - it is included into the ` __all__ ` list of a public module;
375
- - the name of the object does not have a leading underscore;
376
- - the name of the module from which the object is collected does not have
374
+ - it is included into the ` __all__ ` list of a public module;
375
+ - the name of the object does not have a leading underscore;
376
+ - the name of the module from which the object is collected does not have
377
377
a leading underscore.
378
378
379
379
Consider an example: ` scipy.linalg.det ` is defined in ` scipy/linalg/_basic.py ` ,
380
380
so it is collected twice, from ` _basic.py ` and from ` __init__.py ` . The rule above
381
381
leads to
382
382
383
- - ` scipy.linalg._basic.det ` , collected from ` scipy/linalg/_basic.py ` , is private.
384
- - ` scipy.linalg.det ` , collected from ` scipy/linalg/__init__.py ` , is public.
383
+ - ` scipy.linalg._basic.det ` , collected from ` scipy/linalg/_basic.py ` , is private.
384
+ - ` scipy.linalg.det ` , collected from ` scipy/linalg/__init__.py ` , is public.
385
385
386
- - _ ` pytest ` 's assertion rewriting_
386
+ #### _ ` pytest ` 's assertion rewriting_
387
387
388
388
In some rare cases you may need to either explicitly register the ` scipy_doctest `
389
389
package with the ` pytest ` assertion rewriting machinery, or ask it to avoid rewriting
@@ -395,31 +395,52 @@ In general, rewriting assertions is not very useful for doctests, as the
395
395
output on error is fixed by the doctest machinery anyway. Therefore, we believe
396
396
adding ` --assert=plain ` is reasonable.
397
397
398
+ #### _ Mixing strings and numbers_
399
+
400
+ Generally, we aim to handle mixtures of strings and numeric data. Deeply nested data
401
+ structures, however, may cause the checker to fall back to the vanilla ` doctest ` literal
402
+ checking. For instance, ` ["value", 1/3] ` will use the floating-point aware checker, and
403
+ so will ` {"value": 1/3, "other value": 2/3} ` or ` [(1, 2), (3, 4)] ` ; Meanwhile, nested
404
+ dictionaries, ` {"a": dict(value=1/3)} ` , or lists of tuples with mixed entries,
405
+ ` [("a", 1/3), ("b", 2/3)] ` , will currently fall back to vanilla ` doctest ` literal
406
+ comparisons.
407
+
408
+ We stress that no matter how tricky or deeply nested the output is, the worst case
409
+ scenario is that the floating-point aware checker is not used. If you have a case where
410
+ ` doctest ` works correctly and ` scipy_doctest ` does not, please report it as a bug.
411
+
412
+
398
413
## Prior art and related work
399
414
400
415
- ` pytest ` provides some limited floating-point aware ` NumericLiteralChecker ` .
401
416
402
417
- ` pytest-doctestplus ` plugin from the ` AstroPy ` project has similar goals.
403
418
The package is well established and widely used. From a user perspective, main
404
419
differences are: (i) ` pytest-doctestplus ` is more sensitive to formatting,
405
- including whitespace---thus if numpy tweaks its output formatting, doctests
406
- may start failing; (ii) there is still a need for ` # doctest: +FLOAT_CMP `
420
+ including whitespace; (ii) there is still a need for ` # doctest: +FLOAT_CMP `
407
421
directives.
408
422
409
- This project takes a different approach: in addition to plugging into ` pytest ` ,
410
- we closely follow the ` doctest ` API and implementation, which are naturally
411
- way more stable then ` pytest ` .
423
+ This project takes a slightly different approach: we strive to make numeric comparisons
424
+ whitespace insensitive and automatic, without a need for explicit markup. For rare cases
425
+ which require additional configuration, we either keep it in the tool (thus out of
426
+ reader-visible docstrings), or provide human-readable markers (hence ` # may vary `
427
+ not ` # doctest +SKIP ` ).
428
+ Furthermore, in addition to plugging into ` pytest ` , we provide an API layer which closely
429
+ follows the ` doctest ` API. Essentially all aspects of doctesting are user-configurable.
430
+
431
+ - ` xdoctest ` package relies on a deeper rewrite of the standard-library ` doctest `
432
+ functionality, and uses an AST-based analysis to parse code examples out of docstrings.
412
433
413
434
- ` NumPy ` and ` SciPy ` were using modified doctesting in their ` refguide-check ` utilities.
414
- These utilities are tightly coupled to their libraries, and have been reported
435
+ These utilities were tightly coupled to their libraries, and have been reported
415
436
to be not easy to reason about, work with, and extend to other projects.
416
437
417
- This project is mainly the core functionality of the modified
418
- ` refguide-check ` doctesting, extracted to a separate package.
419
- We believe having it separate simplifies both addressing the needs of these
420
- two packages, and potential adoption by other projects.
438
+ This project is mainly the core functionality of the modified ` refguide-check ` doctesting,
439
+ extracted to a separate package. We believe having it separate simplifies both
440
+ addressing the needs of these two packages, and adoption by other projects.
441
+
421
442
422
- ### Bug reports, feature requests and contributions
443
+ ## Bug reports, feature requests and contributions
423
444
424
445
This package is work in progress. Contributions are most welcome!
425
446
Please don't hesitate to open an issue in the tracker or send a pull request.
0 commit comments