scipy-doctest 1.1__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 +12 -0
- scipy_doctest/__main__.py +6 -0
- scipy_doctest/conftest.py +5 -0
- scipy_doctest/frontend.py +468 -0
- scipy_doctest/impl.py +506 -0
- scipy_doctest/plugin.py +336 -0
- scipy_doctest/tests/__init__.py +0 -0
- scipy_doctest/tests/failure_cases.py +17 -0
- scipy_doctest/tests/failure_cases_2.py +27 -0
- scipy_doctest/tests/finder_cases.py +65 -0
- scipy_doctest/tests/local_file.txt +0 -0
- scipy_doctest/tests/local_file_cases.py +37 -0
- scipy_doctest/tests/module_cases.py +192 -0
- scipy_doctest/tests/octave_a.mat +0 -0
- scipy_doctest/tests/scipy_ndimage_tutorial_clone.rst +2018 -0
- scipy_doctest/tests/stopwords_cases.py +9 -0
- scipy_doctest/tests/test_finder.py +170 -0
- scipy_doctest/tests/test_parser.py +36 -0
- scipy_doctest/tests/test_pytest_configuration.py +95 -0
- scipy_doctest/tests/test_runner.py +105 -0
- scipy_doctest/tests/test_skipmarkers.py +202 -0
- scipy_doctest/tests/test_testfile.py +24 -0
- scipy_doctest/tests/test_testmod.py +158 -0
- scipy_doctest/util.py +279 -0
- scipy_doctest-1.1.dist-info/LICENSE +29 -0
- scipy_doctest-1.1.dist-info/METADATA +390 -0
- scipy_doctest-1.1.dist-info/RECORD +29 -0
- scipy_doctest-1.1.dist-info/WHEEL +4 -0
- scipy_doctest-1.1.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Doctests on steroids.
|
|
3
|
+
|
|
4
|
+
Whitespace-insensitive, numpy-aware, floating-point-aware doctest helpers.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
__version__ = "1.1"
|
|
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
|
+
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
""" Copy-pasting my way through python/cpython/Lib/doctest.py. """
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
import inspect
|
|
6
|
+
import doctest
|
|
7
|
+
|
|
8
|
+
from .impl import DTFinder, DTRunner, DebugDTRunner, DTParser, DTConfig
|
|
9
|
+
from .util import (matplotlib_make_nongui as mpl,
|
|
10
|
+
temp_cwd, np_errstate,
|
|
11
|
+
get_public_objects, _map_verbosity)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def find_doctests(module, strategy=None,
|
|
15
|
+
# doctest parameters. These fall through to the DocTestFinder
|
|
16
|
+
name=None, exclude_empty=True, globs=None, extraglobs=None,
|
|
17
|
+
# our configuration
|
|
18
|
+
config=None):
|
|
19
|
+
"""Find doctests in a module.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
m : module
|
|
24
|
+
The base module to look into
|
|
25
|
+
strategy : str or list of objects, optional
|
|
26
|
+
The strategy to use to find doctests.
|
|
27
|
+
If "public", look into public, non-deprecated objects in the module.
|
|
28
|
+
If a list of objects, only look into the docstring of these objects
|
|
29
|
+
If None, use the standard `doctest` behavior.
|
|
30
|
+
Default is None.
|
|
31
|
+
name : str, optional
|
|
32
|
+
The name of the module. Is used to construct the names of DocTest
|
|
33
|
+
objects. Default is the `module.__name__`.
|
|
34
|
+
exclude_empty : bool, optional
|
|
35
|
+
Comes from the stdlib `doctest` module. See Notes.
|
|
36
|
+
Default is True.
|
|
37
|
+
globs : dict, optional
|
|
38
|
+
Comes from the stdlib `doctest` module. See Notes.
|
|
39
|
+
Default is None.
|
|
40
|
+
extraglobs : dict, optional
|
|
41
|
+
Comes from the stdlib `doctest` module. See Notes.
|
|
42
|
+
Default is None.
|
|
43
|
+
config
|
|
44
|
+
A `DTConfig` instance
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
tests : list
|
|
49
|
+
A list of `doctest.DocTest`s that are defined by the module docstring,
|
|
50
|
+
and by its contained objects’ docstrings. The selection is controlled
|
|
51
|
+
by the `strategy` argument.
|
|
52
|
+
|
|
53
|
+
Notes
|
|
54
|
+
-----
|
|
55
|
+
See https://docs.python.org/3/library/doctest.html#doctestfinder-objects
|
|
56
|
+
for details on the `doctest`-inherited parameters (`name`, `globs`,
|
|
57
|
+
`extraglobs`). Note that these are provided mainly for compatibility with
|
|
58
|
+
the stdlib `doctest` and can be left with default values unless you are
|
|
59
|
+
doing something unusual.
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
if config is None:
|
|
63
|
+
config = DTConfig()
|
|
64
|
+
|
|
65
|
+
finder = DTFinder(exclude_empty=exclude_empty, config=config)
|
|
66
|
+
|
|
67
|
+
if strategy is None:
|
|
68
|
+
tests = finder.find(module, name, globs=globs, extraglobs=extraglobs)
|
|
69
|
+
tests = [t for t in tests if t.name not in config.skiplist]
|
|
70
|
+
return tests
|
|
71
|
+
|
|
72
|
+
if strategy == "api":
|
|
73
|
+
(items, names), failures = get_public_objects(module,
|
|
74
|
+
skiplist=config.skiplist)
|
|
75
|
+
if failures:
|
|
76
|
+
mesg = "\n".join([_[2] for _ in failures])
|
|
77
|
+
raise ValueError(mesg)
|
|
78
|
+
items.append(module)
|
|
79
|
+
names.append(module.__name__)
|
|
80
|
+
else:
|
|
81
|
+
# strategy must then be a list of objects to look at
|
|
82
|
+
if not isinstance(strategy, list):
|
|
83
|
+
raise ValueError(f"Expected a list of objects, got {strategy}.")
|
|
84
|
+
items = strategy[:]
|
|
85
|
+
names = [item.__name__ for item in items]
|
|
86
|
+
|
|
87
|
+
# Having collected the list of objects, extract doctests
|
|
88
|
+
tests = []
|
|
89
|
+
for item, name in zip(items, names):
|
|
90
|
+
full_name = module.__name__ + '.' + name
|
|
91
|
+
if inspect.ismodule(item):
|
|
92
|
+
# do not recurse, only inspect the module docstring
|
|
93
|
+
_finder = DTFinder(recurse=False, config=config)
|
|
94
|
+
t = _finder.find(item, name, globs=globs, extraglobs=extraglobs)
|
|
95
|
+
else:
|
|
96
|
+
t = finder.find(item, full_name, globs=globs, extraglobs=extraglobs)
|
|
97
|
+
tests += t
|
|
98
|
+
|
|
99
|
+
# If the skiplist contains methods of objects, their doctests may have been
|
|
100
|
+
# left in the `tests` list. Remove them.
|
|
101
|
+
tests = [t for t in tests if t.name not in config.skiplist]
|
|
102
|
+
return tests
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def testmod(m=None, name=None, globs=None, verbose=None,
|
|
106
|
+
report=True, optionflags=None, extraglobs=None,
|
|
107
|
+
raise_on_error=False, exclude_empty=True,
|
|
108
|
+
strategy=None, config=None):
|
|
109
|
+
"""Run modified doctesting on a module or on docstrings of a list of objects.
|
|
110
|
+
|
|
111
|
+
This function is an analog of the `testmod` driver from the standard library.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
m : module, optional
|
|
116
|
+
Test examples in docstrings in functions and classes reachable
|
|
117
|
+
from module `m` (or the current module if `m` is not supplied),
|
|
118
|
+
starting with ``m.__doc__``.
|
|
119
|
+
name : str, optional
|
|
120
|
+
Gives the name of the module; by default use ``m.__name__``.
|
|
121
|
+
globs : dict, optional
|
|
122
|
+
A dict to be used as the globals when executing examples; A copy of this
|
|
123
|
+
dict is actually used for each docstring, so that each docstring's
|
|
124
|
+
examples start with a clean slate.
|
|
125
|
+
By default, use `config.default_namespace`.
|
|
126
|
+
report : bool, optional
|
|
127
|
+
Prints a summary at the end when `True`, else prints nothing at the end.
|
|
128
|
+
In verbose mode, the summary is detailed, else very brief (in fact,
|
|
129
|
+
empty if all tests passed)
|
|
130
|
+
Default is True.
|
|
131
|
+
verbose : int
|
|
132
|
+
Control the run verbosity:
|
|
133
|
+
0 means only report failures,
|
|
134
|
+
1 means emit object names,
|
|
135
|
+
2 is the max verbosity from doctest (print all examples/want/got).
|
|
136
|
+
Default is 0.
|
|
137
|
+
optionflags : int, optional
|
|
138
|
+
`doctest` module optionflags for checking examples. See the stdlib
|
|
139
|
+
`doctest` module documentation for details.
|
|
140
|
+
Default is to use `config.optionflags`.
|
|
141
|
+
extraglobs : dict, optional
|
|
142
|
+
Provided for compatibility with `doctest.testmod`. Default is None.
|
|
143
|
+
raise_on_error : bool, optional
|
|
144
|
+
Raise an exception on the first unexpected exception or failure.
|
|
145
|
+
This allows failures to be post-mortem debugged.
|
|
146
|
+
Default is `False`.
|
|
147
|
+
exclude_empty : bool, optional
|
|
148
|
+
Whether to exclude from consideration objects with no docstrings.
|
|
149
|
+
Comes from the stdlib `doctest` module. See Notes.
|
|
150
|
+
Default is True.
|
|
151
|
+
strategy : str or list of objects, optional
|
|
152
|
+
The strategy to use to find doctests.
|
|
153
|
+
If "api", look into public, non-deprecated objects in the module.
|
|
154
|
+
If a list of objects, only look into the docstring of these objects
|
|
155
|
+
If None, use the standard `doctest` behavior.
|
|
156
|
+
Default is None.
|
|
157
|
+
config : a DTConfig instance, optional
|
|
158
|
+
Various configuration options. See the `DTconfig` docstring for details.
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
(result, history)
|
|
163
|
+
`result` is a namedtuple ``TestResult(failed, attempted)``
|
|
164
|
+
`history` is a dict with details of which objects were examined (the
|
|
165
|
+
keys are object names and values are individual objects' ``TestResult``s)
|
|
166
|
+
|
|
167
|
+
Examples
|
|
168
|
+
--------
|
|
169
|
+
>>> from scipy import constants
|
|
170
|
+
>>> from scpdt import testmod
|
|
171
|
+
>>> result, history = testmod(constants, strategy='api')
|
|
172
|
+
>>> result
|
|
173
|
+
TestResults(failed=0, attempted=25)
|
|
174
|
+
>>> len(history)
|
|
175
|
+
160
|
|
176
|
+
|
|
177
|
+
Notes
|
|
178
|
+
-----
|
|
179
|
+
The signature is made to be (mostly) consistent with `doctest.testmod`.
|
|
180
|
+
For details on the `doctest`-inherited parameters see
|
|
181
|
+
https://docs.python.org/3/library/doctest.html.
|
|
182
|
+
For an overview, see ``help(doctest)``.
|
|
183
|
+
|
|
184
|
+
** Doctest discovery **
|
|
185
|
+
|
|
186
|
+
The default doctest discovery strategy, `testmod(..., strategy=None)`, is
|
|
187
|
+
inherited from the stdlib `doctest` module with all its limitations.
|
|
188
|
+
For instance, it may have difficulties with complex packages, where the
|
|
189
|
+
implementation is spread across several modules.
|
|
190
|
+
|
|
191
|
+
For complex packages, prefer `strategy='api'`, which works as follows:
|
|
192
|
+
- take the names of public objects from the `__all__` attribute of the package.
|
|
193
|
+
- if `__all__` is not defined, take `dir(module)` and filter out names
|
|
194
|
+
which start with a leading underscore and dunders.
|
|
195
|
+
- filter out deprecated items, i.e. those which raise `DeprecationWarning`.
|
|
196
|
+
|
|
197
|
+
"""
|
|
198
|
+
### mimic `doctest.testmod` initial set-ups
|
|
199
|
+
# If no module was given, then use __main__.
|
|
200
|
+
if m is None:
|
|
201
|
+
m = sys.modules.get('__main__')
|
|
202
|
+
|
|
203
|
+
# Check that we were actually given a module.
|
|
204
|
+
if not inspect.ismodule(m):
|
|
205
|
+
raise TypeError("testmod: module required; %r" % (m,))
|
|
206
|
+
|
|
207
|
+
# If no name was given, then use the module's name.
|
|
208
|
+
if name is None:
|
|
209
|
+
name = m.__name__
|
|
210
|
+
|
|
211
|
+
### Set up the configuration
|
|
212
|
+
if config is None:
|
|
213
|
+
config = DTConfig()
|
|
214
|
+
|
|
215
|
+
# pull the the namespace to run examples in, also optionflags from `config`
|
|
216
|
+
if globs is None:
|
|
217
|
+
globs = dict(config.default_namespace)
|
|
218
|
+
else:
|
|
219
|
+
globs = globs.copy()
|
|
220
|
+
flags = config.optionflags
|
|
221
|
+
|
|
222
|
+
output = sys.stderr
|
|
223
|
+
|
|
224
|
+
# Fail fast or run all tests
|
|
225
|
+
verbose, dtverbose = _map_verbosity(verbose)
|
|
226
|
+
if raise_on_error:
|
|
227
|
+
runner = DebugDTRunner(verbose=dtverbose, optionflags=flags, config=config)
|
|
228
|
+
else:
|
|
229
|
+
runner = DTRunner(verbose=dtverbose, optionflags=flags, config=config)
|
|
230
|
+
|
|
231
|
+
### Find, parse, and run all tests in the given module.
|
|
232
|
+
tests = find_doctests(
|
|
233
|
+
m, strategy, name, exclude_empty, globs, extraglobs, config=config
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
for test in tests:
|
|
237
|
+
if verbose == 1:
|
|
238
|
+
output.write(test.name + '\n')
|
|
239
|
+
# restore the errstate/print state after each docstring.
|
|
240
|
+
# Also make MPL backend non-GUI and close the figures.
|
|
241
|
+
# The order of context managers is actually relevant. Consider
|
|
242
|
+
# a user_context_mgr that turns warnings into errors.
|
|
243
|
+
# Additionally, suppose that MPL deprecates something and plt.something
|
|
244
|
+
# starts issuing warngings. Now all of those become errors
|
|
245
|
+
# *unless* the `mpl()` context mgr has a chance to filter them out
|
|
246
|
+
# *before* they become errors in `config.user_context_mgr()`.
|
|
247
|
+
with np_errstate():
|
|
248
|
+
with config.user_context_mgr(test):
|
|
249
|
+
with mpl(), temp_cwd(test, config.local_resources):
|
|
250
|
+
runner.run(test, out=output.write)
|
|
251
|
+
if report:
|
|
252
|
+
runner.summarize()
|
|
253
|
+
return doctest.TestResults(runner.failures, runner.tries), runner.get_history()
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def testfile(filename, module_relative=True, name=None, package=None,
|
|
257
|
+
globs=None, verbose=None, report=True, optionflags=None,
|
|
258
|
+
extraglobs=None, raise_on_error=False, parser=None,
|
|
259
|
+
encoding='utf-8', config=None):
|
|
260
|
+
"""Test examples in the given file.
|
|
261
|
+
|
|
262
|
+
This function is an analog of the `doctest.testfile` driver from the
|
|
263
|
+
standard library.
|
|
264
|
+
|
|
265
|
+
Parameters
|
|
266
|
+
----------
|
|
267
|
+
filename : str
|
|
268
|
+
The name of the file to run doctesting on.
|
|
269
|
+
module_relative: bool, optional
|
|
270
|
+
Whether the file name is relative to a module or a package.
|
|
271
|
+
This parameter is similar to the `doctest.testfile` parameter.
|
|
272
|
+
If True, then `filename` speficies a module-relative path (if `package`
|
|
273
|
+
is specified, then its relative to that package).
|
|
274
|
+
If False, then `filename` specifies an absolute path or a path relative
|
|
275
|
+
to the current working directory.
|
|
276
|
+
See `doctest.testfile` documentation for details.
|
|
277
|
+
Default is True.
|
|
278
|
+
name : str, optional
|
|
279
|
+
Give the name of the test; by default use the file basename.
|
|
280
|
+
package : str, optional
|
|
281
|
+
Gives a Python package or the name of a Python package whose directory
|
|
282
|
+
should be used as the base directory for a module relative filename.
|
|
283
|
+
If no package is specified, then the calling module's directory is used
|
|
284
|
+
as the base directory for module relative filenames. It is an error to
|
|
285
|
+
specify "package" if "module_relative" is False.
|
|
286
|
+
See `doctest.testfile` documentation for details.
|
|
287
|
+
Default is to specify no package.
|
|
288
|
+
globs : dict, optional
|
|
289
|
+
A dict to be used as the globals when executing examples;
|
|
290
|
+
By default, use `config.default_namespace`.
|
|
291
|
+
report : bool, optional
|
|
292
|
+
Prints a summary at the end when `True`, else prints nothing at the end.
|
|
293
|
+
In verbose mode, the summary is detailed, else very brief (in fact,
|
|
294
|
+
empty if all tests passed)
|
|
295
|
+
Default is True.
|
|
296
|
+
verbose : int
|
|
297
|
+
Control the run verbosity:
|
|
298
|
+
0 means only report failures,
|
|
299
|
+
1 means emit object names,
|
|
300
|
+
2 is the max verbosity from doctest (print all examples/want/got).
|
|
301
|
+
Default is 0.
|
|
302
|
+
optionflags : int, optional
|
|
303
|
+
`doctest` module optionflags for checking examples. See the stdlib
|
|
304
|
+
`doctest` module documentation for details.
|
|
305
|
+
Default is to use `config.optionflags`.
|
|
306
|
+
extraglobs : dict, optional
|
|
307
|
+
Provided for compatibility with `doctest.testmod`. Default is None.
|
|
308
|
+
raise_on_error : bool, optional
|
|
309
|
+
Raise an exception on the first unexpected exception or failure.
|
|
310
|
+
This allows failures to be post-mortem debugged.
|
|
311
|
+
Default is `False`.
|
|
312
|
+
parser: a DTParser object, optional
|
|
313
|
+
By default, a `DTParser(config)` is used.
|
|
314
|
+
encoding : str, optional
|
|
315
|
+
Encoding to use when converting the `testfile` to unicode.
|
|
316
|
+
Default is 'utf-8'.
|
|
317
|
+
config : a DTConfig instance, optional
|
|
318
|
+
Various configuration options. See the `DTconfig` docstring for details.
|
|
319
|
+
|
|
320
|
+
Returns
|
|
321
|
+
-------
|
|
322
|
+
(result, history)
|
|
323
|
+
`result` is a namedtuple ``TestResult(failed, attempted)``
|
|
324
|
+
`history` is a dict with details of which objects were examined (the
|
|
325
|
+
keys are object names and values are individual objects' ``TestResult``s)
|
|
326
|
+
"""
|
|
327
|
+
# initial configuration
|
|
328
|
+
if config is None:
|
|
329
|
+
config = DTConfig()
|
|
330
|
+
if globs is None:
|
|
331
|
+
globs = dict(config.default_namespace)
|
|
332
|
+
else:
|
|
333
|
+
globs = globs.copy()
|
|
334
|
+
if optionflags is None:
|
|
335
|
+
optionflags = config.optionflags
|
|
336
|
+
|
|
337
|
+
######### mimic `doctest.tesfile` initial set-ups
|
|
338
|
+
# c.f. https://github.com/python/cpython/blob/3.10/Lib/doctest.py#L2064
|
|
339
|
+
if package and not module_relative:
|
|
340
|
+
raise ValueError("Package may only be specified for module-"
|
|
341
|
+
"relative paths.")
|
|
342
|
+
|
|
343
|
+
# Relativize the path
|
|
344
|
+
text, filename = doctest._load_testfile(filename, package, module_relative,
|
|
345
|
+
encoding or "utf-8")
|
|
346
|
+
|
|
347
|
+
# If no name was given, then use the file's name.
|
|
348
|
+
if name is None:
|
|
349
|
+
name = os.path.basename(filename)
|
|
350
|
+
|
|
351
|
+
# Assemble the globals.
|
|
352
|
+
if extraglobs is not None:
|
|
353
|
+
globs.update(extraglobs)
|
|
354
|
+
if '__name__' not in globs:
|
|
355
|
+
globs['__name__'] = '__main__'
|
|
356
|
+
##### done copy-pasting from doctest.testfile
|
|
357
|
+
|
|
358
|
+
# Fail fast or run all tests
|
|
359
|
+
verbose, dtverbose = _map_verbosity(verbose)
|
|
360
|
+
if raise_on_error:
|
|
361
|
+
runner = DebugDTRunner(
|
|
362
|
+
verbose=dtverbose, optionflags=optionflags, config=config
|
|
363
|
+
)
|
|
364
|
+
else:
|
|
365
|
+
runner = DTRunner(
|
|
366
|
+
verbose=dtverbose, optionflags=optionflags, config=config
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
### Parse doctest examples out of the input file and run them.
|
|
370
|
+
if parser is None:
|
|
371
|
+
parser = DTParser(config)
|
|
372
|
+
test = parser.get_doctest(text, globs, name, filename, 0)
|
|
373
|
+
|
|
374
|
+
if test.name in config.skiplist:
|
|
375
|
+
# nothing to do, bail out
|
|
376
|
+
return doctest.TestResults(0, 0), runner.get_history()
|
|
377
|
+
|
|
378
|
+
output = sys.stderr
|
|
379
|
+
if verbose == 1:
|
|
380
|
+
output.write(test.name + '\n')
|
|
381
|
+
|
|
382
|
+
# see testmod for discussion of these context managers
|
|
383
|
+
with np_errstate():
|
|
384
|
+
with config.user_context_mgr(test):
|
|
385
|
+
with mpl(), temp_cwd(test, config.local_resources):
|
|
386
|
+
runner.run(test, out=output.write)
|
|
387
|
+
if report:
|
|
388
|
+
runner.summarize()
|
|
389
|
+
return doctest.TestResults(runner.failures, runner.tries), runner.get_history()
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def run_docstring_examples(f, globs=None, verbose=False, name='NoName',
|
|
393
|
+
optionflags=None, config=None):
|
|
394
|
+
"""Run examples in the docstring of the object `f`.
|
|
395
|
+
|
|
396
|
+
Parameters
|
|
397
|
+
----------
|
|
398
|
+
f
|
|
399
|
+
Can be a function, a class, a module etc
|
|
400
|
+
globs : dict, optional
|
|
401
|
+
A dict to be used as the globals when executing examples; A copy of this
|
|
402
|
+
dict is actually used for each docstring, so that each docstring's
|
|
403
|
+
examples start with a clean slate.
|
|
404
|
+
By default, use `config.default_namespace`.
|
|
405
|
+
verbose : bool, optional
|
|
406
|
+
Control the verbosity of the report.
|
|
407
|
+
name : str, optional
|
|
408
|
+
The object name.
|
|
409
|
+
optionflags : int, optional
|
|
410
|
+
`doctest` module optionflags for checking examples. See the stdlib
|
|
411
|
+
`doctest` module documentation for details.
|
|
412
|
+
Default is to use `config.optionflags`.
|
|
413
|
+
config : a DTConfig instance, optional
|
|
414
|
+
Various configuration options. See the `DTconfig` docstring for details.
|
|
415
|
+
"""
|
|
416
|
+
if config is None:
|
|
417
|
+
config = DTConfig()
|
|
418
|
+
if globs is None:
|
|
419
|
+
globs = dict(config.default_namespace)
|
|
420
|
+
if verbose is None:
|
|
421
|
+
verbose = 0
|
|
422
|
+
if optionflags is None:
|
|
423
|
+
optionflags = config.optionflags
|
|
424
|
+
|
|
425
|
+
m = f.__module__
|
|
426
|
+
import importlib
|
|
427
|
+
module = importlib.import_module(m)
|
|
428
|
+
|
|
429
|
+
return testmod(module, name=name, globs=globs, verbose=verbose,
|
|
430
|
+
optionflags=optionflags, strategy=[f], config=config)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
def _main():
|
|
434
|
+
"""CLI for `$ python -m scpdt pythonfile.py`, cf `__main__.py`
|
|
435
|
+
"""
|
|
436
|
+
import argparse
|
|
437
|
+
|
|
438
|
+
parser = argparse.ArgumentParser(description="doctest runner")
|
|
439
|
+
parser.add_argument('-v', '--verbose', action='count', default=0,
|
|
440
|
+
help='print verbose (`-v`) or very verbose (`-vv`) '
|
|
441
|
+
'output for all tests')
|
|
442
|
+
parser.add_argument('-x', '--fail-fast', action='store_true',
|
|
443
|
+
help=('stop running tests after first failure'))
|
|
444
|
+
parser.add_argument('file', nargs='+',
|
|
445
|
+
help='file containing the tests to run')
|
|
446
|
+
args = parser.parse_args()
|
|
447
|
+
testfiles = args.file
|
|
448
|
+
verbose = args.verbose
|
|
449
|
+
|
|
450
|
+
for filename in testfiles:
|
|
451
|
+
if filename.endswith(".py"):
|
|
452
|
+
# It is a module -- insert its dir into sys.path and try to
|
|
453
|
+
# import it. If it is part of a package, that possibly
|
|
454
|
+
# won't work because of package imports.
|
|
455
|
+
dirname, filename = os.path.split(filename)
|
|
456
|
+
sys.path.insert(0, dirname)
|
|
457
|
+
m = __import__(filename[:-3])
|
|
458
|
+
del sys.path[0]
|
|
459
|
+
result, _ = testmod(m, verbose=verbose,
|
|
460
|
+
raise_on_error=args.fail_fast)
|
|
461
|
+
else:
|
|
462
|
+
result, _ = testfile(filename, module_relative=False,
|
|
463
|
+
verbose=verbose, raise_on_error=args.fail_fast)
|
|
464
|
+
|
|
465
|
+
if result.failed:
|
|
466
|
+
return 1
|
|
467
|
+
return 0
|
|
468
|
+
|