scipy-doctest 1.5.1__tar.gz → 1.6__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.
Files changed (29) hide show
  1. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/PKG-INFO +1 -1
  2. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/__init__.py +1 -1
  3. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/frontend.py +12 -2
  4. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/impl.py +8 -0
  5. scipy_doctest-1.6/scipy_doctest/tests/finder_cases_2.py +22 -0
  6. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/test_finder.py +59 -7
  7. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/LICENSE +0 -0
  8. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/README.md +0 -0
  9. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/pyproject.toml +0 -0
  10. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/__main__.py +0 -0
  11. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/conftest.py +0 -0
  12. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/plugin.py +0 -0
  13. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/__init__.py +0 -0
  14. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/failure_cases.py +0 -0
  15. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/failure_cases_2.py +0 -0
  16. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/finder_cases.py +0 -0
  17. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/local_file.txt +0 -0
  18. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/local_file_cases.py +0 -0
  19. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/module_cases.py +0 -0
  20. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/octave_a.mat +0 -0
  21. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/scipy_ndimage_tutorial_clone.rst +0 -0
  22. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/stopwords_cases.py +0 -0
  23. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/test_parser.py +0 -0
  24. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/test_pytest_configuration.py +0 -0
  25. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/test_runner.py +0 -0
  26. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/test_skipmarkers.py +0 -0
  27. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/test_testfile.py +0 -0
  28. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/tests/test_testmod.py +0 -0
  29. {scipy_doctest-1.5.1 → scipy_doctest-1.6}/scipy_doctest/util.py +0 -0
@@ -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
@@ -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
@@ -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.
@@ -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
+
File without changes
File without changes