scipy-doctest 1.5.1__py3-none-any.whl → 1.6__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
@@ -3,7 +3,7 @@ Configurable, whitespace-insensitive, floating-point-aware doctest helpers.
3
3
  """
4
4
 
5
5
 
6
- __version__ = "1.5.1"
6
+ __version__ = "1.6"
7
7
 
8
8
  try:
9
9
  # register internal modules with pytest; obscure errors galore otherwise
scipy_doctest/frontend.py CHANGED
@@ -90,14 +90,24 @@ def find_doctests(module, strategy=None,
90
90
  # Having collected the list of objects, extract doctests
91
91
  tests = []
92
92
  for item, name in zip(items, names):
93
- full_name = module.__name__ + '.' + name
94
93
  if inspect.ismodule(item):
95
94
  # do not recurse, only inspect the module docstring
96
95
  _finder = DTFinder(recurse=False, config=config)
97
96
  t = _finder.find(item, name, globs=globs, extraglobs=extraglobs)
97
+ unique_t = set(t)
98
98
  else:
99
+ full_name = module.__name__ + '.' + name
99
100
  t = finder.find(item, full_name, globs=globs, extraglobs=extraglobs)
100
- tests += t
101
+
102
+ unique_t = set(t)
103
+ if hasattr(item, '__mro__'):
104
+ # is a class, inspect superclasses
105
+ # cf https://github.com/scipy/scipy_doctest/issues/177
106
+ # item.__mro__ starts with itself, ends with `object`
107
+ for item_ in item.__mro__[1:-1]:
108
+ t_ = finder.find(item_, full_name, globs=globs, extraglobs=extraglobs)
109
+ unique_t.update(set(t_))
110
+ tests += list(unique_t)
101
111
 
102
112
  # If the skiplist contains methods of objects, their doctests may have been
103
113
  # left in the `tests` list. Remove them.
scipy_doctest/impl.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import re
2
2
  import warnings
3
+ import inspect
3
4
  import doctest
4
5
  from doctest import NORMALIZE_WHITESPACE, ELLIPSIS, IGNORE_EXCEPTION_DETAIL
5
6
  from itertools import zip_longest
@@ -538,6 +539,13 @@ class DTFinder(doctest.DocTestFinder):
538
539
  # XXX: does this make similar checks in testmod/testfile duplicate?
539
540
  if module not in self.config.skiplist:
540
541
  tests = super().find(obj, name, module, globs, extraglobs)
542
+
543
+ if inspect.isclass(obj):
544
+ for name_, method in inspect.getmembers(obj):
545
+ if inspect.isdatadescriptor(method):
546
+ tests += super().find(
547
+ method, f'{name}.{name_}', module, globs, extraglobs
548
+ )
541
549
  return tests
542
550
 
543
551
 
@@ -0,0 +1,22 @@
1
+ """
2
+ Private method in subclasses
3
+ """
4
+
5
+ __all__ = ["Klass"]
6
+
7
+ class _PrivateKlass:
8
+ def private_method(self):
9
+ """
10
+ >>> 2 / 3
11
+ 0.667
12
+ """
13
+ pass
14
+
15
+
16
+ class Klass(_PrivateKlass):
17
+ def public_method(self):
18
+ """
19
+ >>> 3 / 4
20
+ 0.74
21
+ """
22
+ pass
@@ -1,10 +1,14 @@
1
1
  import pytest
2
2
 
3
+ import numpy as np
4
+
3
5
  from . import finder_cases
6
+ from . import finder_cases_2
4
7
  from ..util import get_all_list, get_public_objects
5
8
  from ..impl import DTFinder, DTConfig
6
9
  from ..frontend import find_doctests
7
10
 
11
+
8
12
  def test_get_all_list():
9
13
  items, depr, other = get_all_list(finder_cases)
10
14
  assert sorted(items) == ['Klass', 'func']
@@ -111,6 +115,7 @@ class TestSkiplist:
111
115
  # - *private* stuff, which is not in `__all__`
112
116
  wanted_names = ['Klass', 'Klass.meth']
113
117
  wanted_names = [base] + [base + '.' + n for n in wanted_names]
118
+ wanted_names += [f'{base}.Klass.__weakref__']
114
119
 
115
120
  assert sorted(names) == sorted(wanted_names)
116
121
 
@@ -129,6 +134,7 @@ class TestSkiplist:
129
134
  # - the 'base' module (via the strategy=<list>)
130
135
  wanted_names = ['Klass', 'Klass.meth']
131
136
  wanted_names = [base + '.' + n for n in wanted_names]
137
+ wanted_names += [f'{base}.Klass.__weakref__']
132
138
 
133
139
  assert sorted(names) == sorted(wanted_names)
134
140
 
@@ -137,9 +143,13 @@ def test_explicit_object_list():
137
143
  objs = [finder_cases.Klass]
138
144
  tests = find_doctests(finder_cases, strategy=objs)
139
145
 
146
+ names = sorted([test.name for test in tests])
147
+
140
148
  base = 'scipy_doctest.tests.finder_cases'
141
- assert ([test.name for test in tests] ==
142
- [base + '.Klass', base + '.Klass.meth', base + '.Klass.meth_2'])
149
+ expected = sorted([f'{base}.Klass', f'{base}.Klass.__weakref__',
150
+ f'{base}.Klass.meth', f'{base}.Klass.meth_2',])
151
+
152
+ assert names == expected
143
153
 
144
154
 
145
155
  def test_explicit_object_list_with_module():
@@ -149,22 +159,64 @@ def test_explicit_object_list_with_module():
149
159
  objs = [finder_cases, finder_cases.Klass]
150
160
  tests = find_doctests(finder_cases, strategy=objs)
151
161
 
162
+ names = sorted([test.name for test in tests])
163
+
152
164
  base = 'scipy_doctest.tests.finder_cases'
153
- assert ([test.name for test in tests] ==
154
- [base, base + '.Klass', base + '.Klass.meth', base + '.Klass.meth_2'])
165
+ expected = sorted([base, f'{base}.Klass', f'{base}.Klass.__weakref__',
166
+ f'{base}.Klass.meth', f'{base}.Klass.meth_2'])
167
+
168
+ assert names == expected
155
169
 
156
170
 
157
171
  def test_find_doctests_api():
158
172
  # Test that the module itself is included with strategy='api'
159
173
  tests = find_doctests(finder_cases, strategy='api')
160
174
 
175
+ names = sorted([test.name for test in tests])
176
+
161
177
  base = 'scipy_doctest.tests.finder_cases'
162
- assert ([test.name for test in tests] ==
163
- [base + '.func', base + '.Klass', base + '.Klass.meth',
164
- base + '.Klass.meth_2', base])
178
+ expected = sorted([base + '.func', base + '.Klass', base + '.Klass.meth',
179
+ base + '.Klass.meth_2', base + '.Klass.__weakref__', base])
180
+
181
+ assert names == expected
165
182
 
166
183
 
167
184
  def test_dtfinder_config():
168
185
  config = DTConfig()
169
186
  finder = DTFinder(config=config)
170
187
  assert finder.config is config
188
+
189
+
190
+ @pytest.mark.skipif(np.__version__ < '2', reason="XXX check if works on numpy 1.x")
191
+ def test_descriptors_get_collected():
192
+ tests = find_doctests(np, strategy=[np.dtype])
193
+ names = [test.name for test in tests]
194
+ assert 'numpy.dtype.kind' in names # was previously missing
195
+
196
+
197
+ @pytest.mark.parametrize('strategy', [None, 'api'])
198
+ def test_private_superclasses(strategy):
199
+ # Test that methods from inherited private superclasses get collected
200
+ tests = find_doctests(finder_cases_2, strategy=strategy)
201
+
202
+ names = set(test.name.split('.')[-1] for test in tests)
203
+ expected_names = ['finder_cases_2', 'public_method', 'private_method']
204
+ if strategy == 'api':
205
+ expected_names += ['__weakref__']
206
+
207
+ assert len(tests) == len(expected_names)
208
+ assert names == set(expected_names)
209
+
210
+
211
+ def test_private_superclasses_2():
212
+ # similar to test_private_superclass, only with an explicit strategy=list
213
+ tests = find_doctests(finder_cases_2, strategy=[finder_cases_2.Klass])
214
+
215
+ names = set(test.name.split('.')[-1] for test in tests)
216
+ expected_names = ['public_method', 'private_method', '__weakref__']
217
+
218
+ assert len(tests) == len(expected_names)
219
+ assert names == set(expected_names)
220
+
221
+
222
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: scipy_doctest
3
- Version: 1.5.1
3
+ Version: 1.6
4
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
@@ -1,29 +1,30 @@
1
- scipy_doctest/__init__.py,sha256=-RFBEAnfRqgEUJmvLL5MBc6HfuyqetcTQgPsRcVFREU,651
1
+ scipy_doctest/__init__.py,sha256=7yxrEzBJa5wOYwTNIVk07V_hvLLH-SFLEZGwDIAYurs,649
2
2
  scipy_doctest/__main__.py,sha256=H8jTO13GlOLzexbgu7lHMJW1y3_NhLOSArARFZ5WS7o,90
3
3
  scipy_doctest/conftest.py,sha256=5vZxzuH042urYIToiKWANDJHQPoGkfQI-ppQ_cuHgM0,53
4
- scipy_doctest/frontend.py,sha256=7Vz9VIRmzdkmwPD1OtI9sJSxCXIF7jmSxXyt6asjaI0,18628
5
- scipy_doctest/impl.py,sha256=NC61Qy-4VXd3Vjk9WXyTf0oPcm6ZdIiv7WxeVSffTrw,24083
4
+ scipy_doctest/frontend.py,sha256=g4CIPcQH-q1dWc6B0NgkeO5_lDVh2kX7oDHJDEJObLM,19124
5
+ scipy_doctest/impl.py,sha256=tEetxiCUcwz4XFmlDbeBx7ahZvYSQvOFwiaDbBZQEe0,24409
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
9
9
  scipy_doctest/tests/failure_cases.py,sha256=ReSRSugjKDNoWO5M4h-vwCbX_7BwkktlwEjFiGWI3F4,732
10
10
  scipy_doctest/tests/failure_cases_2.py,sha256=gupqwSICvzurGIiKVNJRJX9jkmtFR7_Rf3snWU-4Nac,784
11
11
  scipy_doctest/tests/finder_cases.py,sha256=s4sq5HZ7m5mXEi1N8dbkgCRY6AxEGcirFRYhEyEG7rw,872
12
+ scipy_doctest/tests/finder_cases_2.py,sha256=Z5pnvVQKk3Z8bWpnQyBSnM02qk-80R0doi7DYUbMBaU,306
12
13
  scipy_doctest/tests/local_file.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
14
  scipy_doctest/tests/local_file_cases.py,sha256=xQeD809EoLxY-QIb0X7ZPl6Ecyme3zjnf95AHJ_8gp0,914
14
15
  scipy_doctest/tests/module_cases.py,sha256=W3u97oMJ8yf0rqrsiQbB1yMMTkKAVz4gNpBLDhijHek,5860
15
16
  scipy_doctest/tests/octave_a.mat,sha256=lOfXBSOdMG7_kruTnOHjixXkPy3zSUt10A1FSVjfngI,288
16
17
  scipy_doctest/tests/scipy_ndimage_tutorial_clone.rst,sha256=uCtH99RQM0hvDK2_5lgBO2hqtMUOUQhPKxWn4zwHjSs,81594
17
18
  scipy_doctest/tests/stopwords_cases.py,sha256=OEZkoFW3B9nHUCG_5adSkLI91avSwNjw-NeUS0D6Yz0,156
18
- scipy_doctest/tests/test_finder.py,sha256=9bBa3OvB8aTPixMkAFAPlCul7Bm7J95GKri0npOMp9M,6136
19
+ scipy_doctest/tests/test_finder.py,sha256=lzxLj0QSSKYjy9Cp74d5jzl4BZ5pA667iXGd7xRxPkY,7781
19
20
  scipy_doctest/tests/test_parser.py,sha256=cmK5kXqTWPUdSVor4bPu6yoikIukDIkVXjIjk1TTPI8,925
20
21
  scipy_doctest/tests/test_pytest_configuration.py,sha256=2aesrRyHFdMcRMjARXJ5g8nMtaYC0gb_48Mh8U58RzE,2573
21
22
  scipy_doctest/tests/test_runner.py,sha256=qP4u8ngbUK946HhMM6Py70hi0W0DcZGcCN258phhM7g,2936
22
23
  scipy_doctest/tests/test_skipmarkers.py,sha256=C5U8BKF3Ti-nPWekt2yK6a3j3Tcg_pq-Z5IuiR-F9eU,7835
23
24
  scipy_doctest/tests/test_testfile.py,sha256=66ZHUpEGGg8MfQT8EKSZ8Zx5pV55gP__TZejGMYwBHA,733
24
25
  scipy_doctest/tests/test_testmod.py,sha256=PoOI0o2_dXjWDmDkUUKqcJiyZvh46YpjlmMxyW6PXyI,5874
25
- scipy_doctest-1.5.1.dist-info/entry_points.txt,sha256=dFda3z6PjFL7pEWokv_QmoLwE8X1HETCY1H60xopQ-s,47
26
- scipy_doctest-1.5.1.dist-info/LICENSE,sha256=xH5PVX8bm8e1JxkmJ-e5FsZsOa7FsNOMfepmCvMoR9g,1523
27
- scipy_doctest-1.5.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
28
- scipy_doctest-1.5.1.dist-info/METADATA,sha256=r7zprKH8IAsQde_mAkhp8SOYdlpV6iUc9pttsYu7wu4,14869
29
- scipy_doctest-1.5.1.dist-info/RECORD,,
26
+ scipy_doctest-1.6.dist-info/entry_points.txt,sha256=dFda3z6PjFL7pEWokv_QmoLwE8X1HETCY1H60xopQ-s,47
27
+ scipy_doctest-1.6.dist-info/LICENSE,sha256=xH5PVX8bm8e1JxkmJ-e5FsZsOa7FsNOMfepmCvMoR9g,1523
28
+ scipy_doctest-1.6.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
29
+ scipy_doctest-1.6.dist-info/METADATA,sha256=a7JvqLaDc-LQ0nsKN9X3gEa4MzQ7aNA8pH8zMqOMHNw,14867
30
+ scipy_doctest-1.6.dist-info/RECORD,,