scipy-doctest 1.1__tar.gz → 1.2.0__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.1 → scipy_doctest-1.2.0}/PKG-INFO +32 -24
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/README.md +31 -23
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/__init__.py +1 -1
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/frontend.py +5 -2
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/impl.py +35 -3
- scipy_doctest-1.2.0/scipy_doctest/tests/failure_cases.py +47 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/module_cases.py +42 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/test_testmod.py +18 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/util.py +2 -2
- scipy_doctest-1.1/scipy_doctest/tests/failure_cases.py +0 -17
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/LICENSE +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/pyproject.toml +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/__main__.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/conftest.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/plugin.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/__init__.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/failure_cases_2.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/finder_cases.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/local_file.txt +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/local_file_cases.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/octave_a.mat +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/scipy_ndimage_tutorial_clone.rst +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/stopwords_cases.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/test_finder.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/test_parser.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/test_pytest_configuration.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/test_runner.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/test_skipmarkers.py +0 -0
- {scipy_doctest-1.1 → scipy_doctest-1.2.0}/scipy_doctest/tests/test_testfile.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: scipy_doctest
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Doctests on steroids.
|
|
5
5
|
Maintainer-email: SciPy developers <scipy-dev@python.org>
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -19,6 +19,15 @@ Provides-Extra: test
|
|
|
19
19
|
|
|
20
20
|
# Floating-point aware, human readable, numpy-compatible doctesting.
|
|
21
21
|
|
|
22
|
+
## TL;DR
|
|
23
|
+
|
|
24
|
+
This project extends the standard library `doctest` module to allow flexibility
|
|
25
|
+
and easy customization of finding, parsing and checking code examples in
|
|
26
|
+
documentation.
|
|
27
|
+
|
|
28
|
+
Can be used either as drop-in `doctest` replacement or through the `pytest`
|
|
29
|
+
integration. Uses a floating-point aware doctest checker by default.
|
|
30
|
+
|
|
22
31
|
## Motivation and scope
|
|
23
32
|
|
|
24
33
|
Having examples in the documentation is great. Having wrong examples in the
|
|
@@ -92,7 +101,7 @@ the output. Thus the example source needs to be valid python code still.
|
|
|
92
101
|
|
|
93
102
|
```
|
|
94
103
|
$ pip install -e .
|
|
95
|
-
$ pytest --pyargs
|
|
104
|
+
$ pytest --pyargs scipy_doctest
|
|
96
105
|
```
|
|
97
106
|
|
|
98
107
|
## Usage
|
|
@@ -110,7 +119,7 @@ For example,
|
|
|
110
119
|
|
|
111
120
|
```
|
|
112
121
|
>>> from scipy import linalg
|
|
113
|
-
>>> from
|
|
122
|
+
>>> from scipy_doctest import testmod
|
|
114
123
|
>>> res, hist = testmod(linalg, strategy='api')
|
|
115
124
|
>>> res
|
|
116
125
|
TestResults(failed=0, attempted=764)
|
|
@@ -126,7 +135,7 @@ the behavior of the eponymous functions of the `doctest` module).
|
|
|
126
135
|
|
|
127
136
|
There is a basic CLI, which also mimics that of the `doctest` module:
|
|
128
137
|
```
|
|
129
|
-
$ python -m
|
|
138
|
+
$ python -m scipy_doctest foo.py
|
|
130
139
|
```
|
|
131
140
|
|
|
132
141
|
Note that, just like `$ python -m doctest foo.py`, this may
|
|
@@ -134,7 +143,7 @@ fail if `foo.py` is a part of a package due to package imports.
|
|
|
134
143
|
|
|
135
144
|
Text files can also be CLI-checked:
|
|
136
145
|
```
|
|
137
|
-
$ python -m
|
|
146
|
+
$ python -m scipy_doctest bar.rst
|
|
138
147
|
```
|
|
139
148
|
|
|
140
149
|
|
|
@@ -158,25 +167,24 @@ passing the instance to `testmod` or constructors of `DT*` objects. Defaults
|
|
|
158
167
|
are provided, based on a long-term usage in SciPy.
|
|
159
168
|
|
|
160
169
|
|
|
161
|
-
### The
|
|
170
|
+
### The SciPy Doctest Pytest Plugin
|
|
162
171
|
|
|
163
|
-
The pytest plugin enables the use of
|
|
172
|
+
The pytest plugin enables the use of `scipy_doctest` tools to perform doctests.
|
|
164
173
|
|
|
165
174
|
Follow the given instructions to utilize the pytest plugin for doctesting.
|
|
166
175
|
|
|
167
|
-
### Running
|
|
168
|
-
1. **Install plugin**
|
|
176
|
+
### Running Doctests on SciPy
|
|
169
177
|
|
|
170
|
-
|
|
178
|
+
1. **Install plugin**
|
|
171
179
|
|
|
172
180
|
```bash
|
|
173
|
-
pip install
|
|
181
|
+
pip install scipy-doctest
|
|
174
182
|
```
|
|
175
183
|
|
|
176
184
|
2. **Configure Your Doctesting Experience**
|
|
177
185
|
|
|
178
186
|
To tailor your doctesting experience, you can utilize an instance of `DTConfig`.
|
|
179
|
-
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/
|
|
187
|
+
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/scipy/scipy_doctest#tailoring-your-doctesting-experience) section.
|
|
180
188
|
|
|
181
189
|
3. **Run Doctests**
|
|
182
190
|
|
|
@@ -184,13 +192,13 @@ Doctesting is configured to execute on SciPy using the `dev.py` module.
|
|
|
184
192
|
|
|
185
193
|
To run all doctests, use the following command:
|
|
186
194
|
```bash
|
|
187
|
-
python dev.py
|
|
195
|
+
python dev.py smoke-docs
|
|
188
196
|
```
|
|
189
197
|
|
|
190
198
|
To run doctests on specific SciPy modules, e.g: `cluster`, use the following command:
|
|
191
199
|
|
|
192
200
|
```bash
|
|
193
|
-
python dev.py
|
|
201
|
+
python dev.py smoke-docs -s cluster
|
|
194
202
|
```
|
|
195
203
|
|
|
196
204
|
### Running Doctests on Other Packages/Projects
|
|
@@ -200,7 +208,7 @@ If you want to run doctests on packages or projects other than SciPy, follow the
|
|
|
200
208
|
1. **Install the plugin**
|
|
201
209
|
|
|
202
210
|
```bash
|
|
203
|
-
pip install
|
|
211
|
+
pip install scipy-doctest
|
|
204
212
|
```
|
|
205
213
|
|
|
206
214
|
2. **Register or Load the Plugin**
|
|
@@ -212,14 +220,14 @@ To do this, add the following line of code:
|
|
|
212
220
|
```python
|
|
213
221
|
# In your conftest.py file or test module
|
|
214
222
|
|
|
215
|
-
pytest_plugins = "
|
|
223
|
+
pytest_plugins = "scipy_doctest"
|
|
216
224
|
```
|
|
217
225
|
|
|
218
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.
|
|
219
227
|
|
|
220
228
|
3. **Configure your doctesting experience**
|
|
221
229
|
|
|
222
|
-
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/
|
|
230
|
+
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/scipy/scipy_doctest#tailoring-your-doctesting-experience) section.
|
|
223
231
|
|
|
224
232
|
4. **Run doctests**
|
|
225
233
|
|
|
@@ -242,7 +250,7 @@ $ pytest --pyargs <your-package> --doctest-modules --doctest-collect=api
|
|
|
242
250
|
|
|
243
251
|
### Tailoring Your Doctesting Experience
|
|
244
252
|
|
|
245
|
-
[DTConfig](https://github.com/
|
|
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.
|
|
246
254
|
|
|
247
255
|
These attributes include:
|
|
248
256
|
1. **default_namespace (dict):** Defines the namespace in which examples are executed.
|
|
@@ -262,7 +270,7 @@ Typically, it is entered for each DocTest (especially in API documentation), ens
|
|
|
262
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`.
|
|
263
271
|
|
|
264
272
|
To set any of these attributes, create an instance of `DTConfig` called `dt_config`.
|
|
265
|
-
This instance is already set as an [attribute of pytest's `Config` object](https://github.com/
|
|
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).
|
|
266
274
|
|
|
267
275
|
**Example:**
|
|
268
276
|
|
|
@@ -270,8 +278,8 @@ This instance is already set as an [attribute of pytest's `Config` object](https
|
|
|
270
278
|
dt_config = DTConfig()
|
|
271
279
|
dt_config.stopwords = {'plt.', '.hist', '.show'}
|
|
272
280
|
dt_config.local_resources = {
|
|
273
|
-
'
|
|
274
|
-
'
|
|
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']
|
|
275
283
|
}
|
|
276
284
|
dt_config.skiplist = {
|
|
277
285
|
'scipy.special.sinc',
|
|
@@ -280,9 +288,9 @@ dt_config.skiplist = {
|
|
|
280
288
|
}
|
|
281
289
|
```
|
|
282
290
|
|
|
283
|
-
If you don't set these attributes, the [default settings](https://github.com/
|
|
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.
|
|
284
292
|
|
|
285
|
-
By following these steps, you will be able to effectively use the
|
|
293
|
+
By following these steps, you will be able to effectively use the SciPy Doctest pytest plugin for doctests in your Python projects.
|
|
286
294
|
|
|
287
295
|
Happy testing!
|
|
288
296
|
|
|
@@ -309,7 +317,7 @@ instead of `$ pytest --pyargs scipy`.
|
|
|
309
317
|
If push comes to shove, you may try using the magic env variable:
|
|
310
318
|
` PY_IGNORE_IMPORTMISMATCH=1 pytest ...`,
|
|
311
319
|
however the need usually indicates an issue with the package itself.
|
|
312
|
-
(see [gh-107](https://github.com/
|
|
320
|
+
(see [gh-107](https://github.com/scipy/scipy_doctest/pull/107) for an example).
|
|
313
321
|
|
|
314
322
|
- *Optional dependencies are not that optional*
|
|
315
323
|
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Floating-point aware, human readable, numpy-compatible doctesting.
|
|
2
2
|
|
|
3
|
+
## TL;DR
|
|
4
|
+
|
|
5
|
+
This project extends the standard library `doctest` module to allow flexibility
|
|
6
|
+
and easy customization of finding, parsing and checking code examples in
|
|
7
|
+
documentation.
|
|
8
|
+
|
|
9
|
+
Can be used either as drop-in `doctest` replacement or through the `pytest`
|
|
10
|
+
integration. Uses a floating-point aware doctest checker by default.
|
|
11
|
+
|
|
3
12
|
## Motivation and scope
|
|
4
13
|
|
|
5
14
|
Having examples in the documentation is great. Having wrong examples in the
|
|
@@ -73,7 +82,7 @@ the output. Thus the example source needs to be valid python code still.
|
|
|
73
82
|
|
|
74
83
|
```
|
|
75
84
|
$ pip install -e .
|
|
76
|
-
$ pytest --pyargs
|
|
85
|
+
$ pytest --pyargs scipy_doctest
|
|
77
86
|
```
|
|
78
87
|
|
|
79
88
|
## Usage
|
|
@@ -91,7 +100,7 @@ For example,
|
|
|
91
100
|
|
|
92
101
|
```
|
|
93
102
|
>>> from scipy import linalg
|
|
94
|
-
>>> from
|
|
103
|
+
>>> from scipy_doctest import testmod
|
|
95
104
|
>>> res, hist = testmod(linalg, strategy='api')
|
|
96
105
|
>>> res
|
|
97
106
|
TestResults(failed=0, attempted=764)
|
|
@@ -107,7 +116,7 @@ the behavior of the eponymous functions of the `doctest` module).
|
|
|
107
116
|
|
|
108
117
|
There is a basic CLI, which also mimics that of the `doctest` module:
|
|
109
118
|
```
|
|
110
|
-
$ python -m
|
|
119
|
+
$ python -m scipy_doctest foo.py
|
|
111
120
|
```
|
|
112
121
|
|
|
113
122
|
Note that, just like `$ python -m doctest foo.py`, this may
|
|
@@ -115,7 +124,7 @@ fail if `foo.py` is a part of a package due to package imports.
|
|
|
115
124
|
|
|
116
125
|
Text files can also be CLI-checked:
|
|
117
126
|
```
|
|
118
|
-
$ python -m
|
|
127
|
+
$ python -m scipy_doctest bar.rst
|
|
119
128
|
```
|
|
120
129
|
|
|
121
130
|
|
|
@@ -139,25 +148,24 @@ passing the instance to `testmod` or constructors of `DT*` objects. Defaults
|
|
|
139
148
|
are provided, based on a long-term usage in SciPy.
|
|
140
149
|
|
|
141
150
|
|
|
142
|
-
### The
|
|
151
|
+
### The SciPy Doctest Pytest Plugin
|
|
143
152
|
|
|
144
|
-
The pytest plugin enables the use of
|
|
153
|
+
The pytest plugin enables the use of `scipy_doctest` tools to perform doctests.
|
|
145
154
|
|
|
146
155
|
Follow the given instructions to utilize the pytest plugin for doctesting.
|
|
147
156
|
|
|
148
|
-
### Running
|
|
149
|
-
1. **Install plugin**
|
|
157
|
+
### Running Doctests on SciPy
|
|
150
158
|
|
|
151
|
-
|
|
159
|
+
1. **Install plugin**
|
|
152
160
|
|
|
153
161
|
```bash
|
|
154
|
-
pip install
|
|
162
|
+
pip install scipy-doctest
|
|
155
163
|
```
|
|
156
164
|
|
|
157
165
|
2. **Configure Your Doctesting Experience**
|
|
158
166
|
|
|
159
167
|
To tailor your doctesting experience, you can utilize an instance of `DTConfig`.
|
|
160
|
-
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/
|
|
168
|
+
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/scipy/scipy_doctest#tailoring-your-doctesting-experience) section.
|
|
161
169
|
|
|
162
170
|
3. **Run Doctests**
|
|
163
171
|
|
|
@@ -165,13 +173,13 @@ Doctesting is configured to execute on SciPy using the `dev.py` module.
|
|
|
165
173
|
|
|
166
174
|
To run all doctests, use the following command:
|
|
167
175
|
```bash
|
|
168
|
-
python dev.py
|
|
176
|
+
python dev.py smoke-docs
|
|
169
177
|
```
|
|
170
178
|
|
|
171
179
|
To run doctests on specific SciPy modules, e.g: `cluster`, use the following command:
|
|
172
180
|
|
|
173
181
|
```bash
|
|
174
|
-
python dev.py
|
|
182
|
+
python dev.py smoke-docs -s cluster
|
|
175
183
|
```
|
|
176
184
|
|
|
177
185
|
### Running Doctests on Other Packages/Projects
|
|
@@ -181,7 +189,7 @@ If you want to run doctests on packages or projects other than SciPy, follow the
|
|
|
181
189
|
1. **Install the plugin**
|
|
182
190
|
|
|
183
191
|
```bash
|
|
184
|
-
pip install
|
|
192
|
+
pip install scipy-doctest
|
|
185
193
|
```
|
|
186
194
|
|
|
187
195
|
2. **Register or Load the Plugin**
|
|
@@ -193,14 +201,14 @@ To do this, add the following line of code:
|
|
|
193
201
|
```python
|
|
194
202
|
# In your conftest.py file or test module
|
|
195
203
|
|
|
196
|
-
pytest_plugins = "
|
|
204
|
+
pytest_plugins = "scipy_doctest"
|
|
197
205
|
```
|
|
198
206
|
|
|
199
207
|
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.
|
|
200
208
|
|
|
201
209
|
3. **Configure your doctesting experience**
|
|
202
210
|
|
|
203
|
-
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/
|
|
211
|
+
An in-depth explanation is given in the [tailoring your doctesting experience](https://github.com/scipy/scipy_doctest#tailoring-your-doctesting-experience) section.
|
|
204
212
|
|
|
205
213
|
4. **Run doctests**
|
|
206
214
|
|
|
@@ -223,7 +231,7 @@ $ pytest --pyargs <your-package> --doctest-modules --doctest-collect=api
|
|
|
223
231
|
|
|
224
232
|
### Tailoring Your Doctesting Experience
|
|
225
233
|
|
|
226
|
-
[DTConfig](https://github.com/
|
|
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.
|
|
227
235
|
|
|
228
236
|
These attributes include:
|
|
229
237
|
1. **default_namespace (dict):** Defines the namespace in which examples are executed.
|
|
@@ -243,7 +251,7 @@ Typically, it is entered for each DocTest (especially in API documentation), ens
|
|
|
243
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`.
|
|
244
252
|
|
|
245
253
|
To set any of these attributes, create an instance of `DTConfig` called `dt_config`.
|
|
246
|
-
This instance is already set as an [attribute of pytest's `Config` object](https://github.com/
|
|
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).
|
|
247
255
|
|
|
248
256
|
**Example:**
|
|
249
257
|
|
|
@@ -251,8 +259,8 @@ This instance is already set as an [attribute of pytest's `Config` object](https
|
|
|
251
259
|
dt_config = DTConfig()
|
|
252
260
|
dt_config.stopwords = {'plt.', '.hist', '.show'}
|
|
253
261
|
dt_config.local_resources = {
|
|
254
|
-
'
|
|
255
|
-
'
|
|
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']
|
|
256
264
|
}
|
|
257
265
|
dt_config.skiplist = {
|
|
258
266
|
'scipy.special.sinc',
|
|
@@ -261,9 +269,9 @@ dt_config.skiplist = {
|
|
|
261
269
|
}
|
|
262
270
|
```
|
|
263
271
|
|
|
264
|
-
If you don't set these attributes, the [default settings](https://github.com/
|
|
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.
|
|
265
273
|
|
|
266
|
-
By following these steps, you will be able to effectively use the
|
|
274
|
+
By following these steps, you will be able to effectively use the SciPy Doctest pytest plugin for doctests in your Python projects.
|
|
267
275
|
|
|
268
276
|
Happy testing!
|
|
269
277
|
|
|
@@ -290,7 +298,7 @@ instead of `$ pytest --pyargs scipy`.
|
|
|
290
298
|
If push comes to shove, you may try using the magic env variable:
|
|
291
299
|
` PY_IGNORE_IMPORTMISMATCH=1 pytest ...`,
|
|
292
300
|
however the need usually indicates an issue with the package itself.
|
|
293
|
-
(see [gh-107](https://github.com/
|
|
301
|
+
(see [gh-107](https://github.com/scipy/scipy_doctest/pull/107) for an example).
|
|
294
302
|
|
|
295
303
|
- *Optional dependencies are not that optional*
|
|
296
304
|
|
|
@@ -5,7 +5,7 @@ Whitespace-insensitive, numpy-aware, floating-point-aware doctest helpers.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
__version__ = "1.
|
|
8
|
+
__version__ = "1.2.0"
|
|
9
9
|
|
|
10
10
|
from .impl import DTChecker, DTFinder, DTParser, DTRunner, DebugDTRunner, DTConfig # noqa
|
|
11
11
|
from .frontend import testmod, testfile, find_doctests, run_docstring_examples # noqa
|
|
@@ -70,8 +70,11 @@ def find_doctests(module, strategy=None,
|
|
|
70
70
|
return tests
|
|
71
71
|
|
|
72
72
|
if strategy == "api":
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
|
|
74
|
+
with config.user_context_mgr():
|
|
75
|
+
# user_context_mgr may want to e.g. filter warnings on imports?
|
|
76
|
+
(items, names), failures = get_public_objects(module,
|
|
77
|
+
skiplist=config.skiplist)
|
|
75
78
|
if failures:
|
|
76
79
|
mesg = "\n".join([_[2] for _ in failures])
|
|
77
80
|
raise ValueError(mesg)
|
|
@@ -2,6 +2,7 @@ import re
|
|
|
2
2
|
import warnings
|
|
3
3
|
import doctest
|
|
4
4
|
from doctest import NORMALIZE_WHITESPACE, ELLIPSIS, IGNORE_EXCEPTION_DETAIL
|
|
5
|
+
from itertools import zip_longest
|
|
5
6
|
|
|
6
7
|
import numpy as np
|
|
7
8
|
|
|
@@ -219,6 +220,30 @@ def try_convert_namedtuple(got):
|
|
|
219
220
|
return got_again
|
|
220
221
|
|
|
221
222
|
|
|
223
|
+
def try_convert_printed_array(got):
|
|
224
|
+
"""Printed arrays: reinsert commas.
|
|
225
|
+
"""
|
|
226
|
+
# a minimal version is `s_got = ", ".join(got[1:-1].split())`
|
|
227
|
+
# but it fails if there's a space after the opening bracket: "[ 0 1 2 ]"
|
|
228
|
+
# For 2D arrays, split into rows, drop spurious entries, then reassemble.
|
|
229
|
+
if not got.startswith('['):
|
|
230
|
+
return got
|
|
231
|
+
|
|
232
|
+
g1 = got[1:-1] # strip outer "[...]"-s
|
|
233
|
+
rows = [x for x in g1.split("[") if x]
|
|
234
|
+
rows2 = [", ".join(row.split()) for row in rows]
|
|
235
|
+
|
|
236
|
+
if got.startswith("[["):
|
|
237
|
+
# was a 2D array, restore the opening brackets in rows; XXX clean up
|
|
238
|
+
rows3 = ["[" + row for row in rows2]
|
|
239
|
+
else:
|
|
240
|
+
rows3 = rows2
|
|
241
|
+
|
|
242
|
+
# add back the outer brackets
|
|
243
|
+
s_got = "[" + ", ".join(rows3) + "]"
|
|
244
|
+
return s_got
|
|
245
|
+
|
|
246
|
+
|
|
222
247
|
def has_masked(got):
|
|
223
248
|
return 'masked_array' in got and '--' in got
|
|
224
249
|
|
|
@@ -280,8 +305,9 @@ class DTChecker(doctest.OutputChecker):
|
|
|
280
305
|
cond = (s_want.startswith("[") and s_want.endswith("]") and
|
|
281
306
|
s_got.startswith("[") and s_got.endswith("]"))
|
|
282
307
|
if cond:
|
|
283
|
-
s_want =
|
|
284
|
-
s_got =
|
|
308
|
+
s_want = try_convert_printed_array(s_want)
|
|
309
|
+
s_got = try_convert_printed_array(s_got)
|
|
310
|
+
|
|
285
311
|
return self.check_output(s_want, s_got, optionflags)
|
|
286
312
|
|
|
287
313
|
#handle array abbreviation for n-dimensional arrays, n >= 1
|
|
@@ -322,13 +348,19 @@ class DTChecker(doctest.OutputChecker):
|
|
|
322
348
|
else:
|
|
323
349
|
return self.check_output(want_again, got_again, optionflags)
|
|
324
350
|
|
|
351
|
+
# Validate data type if list or tuple
|
|
352
|
+
is_list_or_tuple = (isinstance(a_want, (list, tuple)) and
|
|
353
|
+
isinstance(a_got, (list, tuple)))
|
|
354
|
+
if is_list_or_tuple and type(a_want) is not type(a_got):
|
|
355
|
+
return False
|
|
356
|
+
|
|
325
357
|
# ... and defer to numpy
|
|
326
358
|
try:
|
|
327
359
|
return self._do_check(a_want, a_got)
|
|
328
360
|
except Exception:
|
|
329
361
|
# heterog tuple, eg (1, np.array([1., 2.]))
|
|
330
362
|
try:
|
|
331
|
-
return all(self._do_check(w, g) for w, g in
|
|
363
|
+
return all(self._do_check(w, g) for w, g in zip_longest(a_want, a_got))
|
|
332
364
|
except (TypeError, ValueError):
|
|
333
365
|
return False
|
|
334
366
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
__all__ = ['func9', 'func10', 'iterable_length_1', 'iterable_length_2',
|
|
2
|
+
'tuple_and_list_1', 'tuple_and_list_2']
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def func9():
|
|
6
|
+
"""
|
|
7
|
+
Wrong output.
|
|
8
|
+
>>> import numpy as np
|
|
9
|
+
>>> np.array([1, 2, 3])
|
|
10
|
+
array([2, 3, 4])
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def func10():
|
|
15
|
+
"""
|
|
16
|
+
NameError
|
|
17
|
+
>>> import numpy as np
|
|
18
|
+
>>> np.arraY([1, 2, 3])
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def iterable_length_1():
|
|
23
|
+
"""
|
|
24
|
+
>>> [1, 2, 3]
|
|
25
|
+
[1, 2, 3, 4]
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def iterable_length_2():
|
|
30
|
+
"""
|
|
31
|
+
>>> [1, 2, 3]
|
|
32
|
+
[1, 2]
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def tuple_and_list_1():
|
|
37
|
+
"""
|
|
38
|
+
>>> [0, 1, 2]
|
|
39
|
+
(0, 1, 2)
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def tuple_and_list_2():
|
|
44
|
+
"""
|
|
45
|
+
>>> (0, 1, 2)
|
|
46
|
+
[0, 1, 2]
|
|
47
|
+
"""
|
|
@@ -44,6 +44,32 @@ def func3():
|
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
def func_printed_arrays():
|
|
48
|
+
"""
|
|
49
|
+
Check various ways handling of printed arrays can go wrong.
|
|
50
|
+
|
|
51
|
+
>>> import numpy as np
|
|
52
|
+
>>> a = np.arange(8).reshape(2, 4) / 3
|
|
53
|
+
>>> print(a) # numpy 1.26.4
|
|
54
|
+
[[0. 0.33333333 0.66666667 1. ]
|
|
55
|
+
[1.33333333 1.66666667 2. 2.33333333]]
|
|
56
|
+
|
|
57
|
+
>>> print(a) # add spaces (older repr?)
|
|
58
|
+
[[ 0. 0.33333333 0.66666667 1. ]
|
|
59
|
+
[ 1.33333333 1.66666667 2. 2.33333333 ]]
|
|
60
|
+
|
|
61
|
+
Also check 1D arrays
|
|
62
|
+
>>> a1 = np.arange(3)
|
|
63
|
+
>>> print(a1)
|
|
64
|
+
[0 1 2]
|
|
65
|
+
>>> print(a1)
|
|
66
|
+
[ 0 1 2]
|
|
67
|
+
>>> print(a1)
|
|
68
|
+
[ 0 1 2 ]
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
|
|
47
73
|
def func4():
|
|
48
74
|
"""
|
|
49
75
|
Test `# may vary` markers : these should not break doctests (but the code
|
|
@@ -190,3 +216,19 @@ def test_cmplx_nan():
|
|
|
190
216
|
>>> 1j*np.complex128(np.nan)
|
|
191
217
|
np.complex128(nan+nanj)
|
|
192
218
|
"""
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def array_and_list_1():
|
|
222
|
+
"""
|
|
223
|
+
>>> import numpy as np
|
|
224
|
+
>>> np.array([1, 2, 3])
|
|
225
|
+
[1, 2, 3]
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def array_and_list_2():
|
|
230
|
+
"""
|
|
231
|
+
>>> import numpy as np
|
|
232
|
+
>>> [1, 2, 3]
|
|
233
|
+
array([1, 2, 3])
|
|
234
|
+
"""
|
|
@@ -99,6 +99,24 @@ def test_user_context():
|
|
|
99
99
|
config=config)
|
|
100
100
|
|
|
101
101
|
|
|
102
|
+
def test_wrong_lengths():
|
|
103
|
+
config = DTConfig()
|
|
104
|
+
res, _ = _testmod(failure_cases,
|
|
105
|
+
strategy=[failure_cases.iterable_length_1,
|
|
106
|
+
failure_cases.iterable_length_2],
|
|
107
|
+
config=config)
|
|
108
|
+
assert res.failed == 2
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_tuple_and_list():
|
|
112
|
+
config = DTConfig()
|
|
113
|
+
res, _ = _testmod(failure_cases,
|
|
114
|
+
strategy=[failure_cases.tuple_and_list_1,
|
|
115
|
+
failure_cases.tuple_and_list_2],
|
|
116
|
+
config=config)
|
|
117
|
+
assert res.failed == 2
|
|
118
|
+
|
|
119
|
+
|
|
102
120
|
class TestLocalFiles:
|
|
103
121
|
def test_local_files(self):
|
|
104
122
|
# A doctest tries to open a local file. Test that it works
|
|
@@ -98,7 +98,7 @@ def numpy_rndm_state():
|
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
@contextmanager
|
|
101
|
-
def noop_context_mgr(test):
|
|
101
|
+
def noop_context_mgr(test=None):
|
|
102
102
|
"""Do nothing.
|
|
103
103
|
|
|
104
104
|
This is a stub context manager to serve as a default for
|
|
@@ -117,7 +117,7 @@ def np_errstate():
|
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
@contextmanager
|
|
120
|
-
def warnings_errors(test):
|
|
120
|
+
def warnings_errors(test=None):
|
|
121
121
|
"""Temporarily turn all warnings to errors."""
|
|
122
122
|
with warnings.catch_warnings():
|
|
123
123
|
warnings.simplefilter('error', Warning)
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
__all__ = ['func9', 'func10']
|
|
2
|
-
|
|
3
|
-
def func9():
|
|
4
|
-
"""
|
|
5
|
-
Wrong output.
|
|
6
|
-
>>> import numpy as np
|
|
7
|
-
>>> np.array([1, 2, 3])
|
|
8
|
-
array([2, 3, 4])
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def func10():
|
|
13
|
-
"""
|
|
14
|
-
NameError
|
|
15
|
-
>>> import numpy as np
|
|
16
|
-
>>> np.arraY([1, 2, 3])
|
|
17
|
-
"""
|
|
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.1 → scipy_doctest-1.2.0}/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
|