Skip to content

Commit 13d62f3

Browse files
authored
Merge pull request #196 from scipy/dicts
ENH: handle dicts to check values not only the keys
2 parents e1a9521 + fce8ac4 commit 13d62f3

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

scipy_doctest/impl.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import warnings
33
import inspect
44
import doctest
5+
import operator
56
from doctest import NORMALIZE_WHITESPACE, ELLIPSIS, IGNORE_EXCEPTION_DETAIL
67
from itertools import zip_longest
78
from sys import version_info
@@ -413,6 +414,19 @@ def check_output(self, want, got, optionflags):
413414
if is_list_or_tuple and type(a_want) is not type(a_got):
414415
return False
415416

417+
# dicts and other mappings need special treatment
418+
want_is_dict = hasattr(a_want, 'items')
419+
got_is_dict = hasattr(a_got, 'items')
420+
if operator.xor(want_is_dict, got_is_dict):
421+
# either both are dicts or both are not
422+
return False
423+
424+
if want_is_dict:
425+
# convert dicts into lists of key-value pairs and retry
426+
want_items = str(list(a_want.items()))
427+
got_items = str(list(a_got.items()))
428+
return self.check_output(want_items, got_items, optionflags)
429+
416430
# ... and defer to numpy
417431
strict = self.config.strict_check
418432
try:

scipy_doctest/tests/failure_cases.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,46 @@ def dtype_mismatch():
5353
>>> 3.0
5454
3
5555
"""
56+
57+
58+
def dict_not_dict():
59+
"""
60+
>>> dict(a=1, b=2)
61+
['a', 'b']
62+
"""
63+
64+
def dict_not_dict_2():
65+
"""
66+
>>> [('a', 1), ('b', 2)]
67+
{'a': 1, 'b': 2}
68+
"""
69+
70+
71+
def dict_wrong_keys():
72+
"""
73+
>>> dict(a=1, b=2)
74+
{'c': 1, 'd': 2}
75+
"""
76+
77+
78+
def dict_wrong_values():
79+
"""
80+
>>> dict(a=1, b=2)
81+
{'a': -1, 'b': -2}
82+
"""
83+
84+
85+
def dict_wrong_values_np():
86+
"""
87+
>>> import numpy as np
88+
>>> dict(a=1, b=np.arange(3)/3)
89+
{'a': 1, 'b': array([0, 0.335, 0.669])}
90+
"""
91+
92+
93+
def dict_nested_wrong_values_np():
94+
"""
95+
>>> import numpy as np
96+
>>> dict(a=1, b=dict(blurb=np.arange(3)/3))
97+
{'a': 1, 'b': {'blurb': array([0, 0.335, 0.669])}}
98+
"""

scipy_doctest/tests/module_cases.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,21 @@ def array_and_list_2():
242242
>>> [1, 2, 3]
243243
array([1, 2, 3])
244244
"""
245+
246+
247+
def two_dicts():
248+
"""
249+
>>> import numpy as np
250+
>>> dict(a=0, b=1)
251+
{'a': 0, 'b': 1}
252+
>>> {'a': 0., 'b': np.arange(3) / 3 }
253+
{'a': 0.0, 'b': array([0, 0.33333333, 0.66666667])}
254+
"""
255+
256+
def nested_dicts():
257+
"""
258+
>>> import numpy as np
259+
>>> {'a': 1.0, 'b': dict(blurb=np.arange(3)/3)}
260+
{'a': 1.0, 'b': {'blurb': array([0, 0.33333333, 0.66666667])}}
261+
"""
262+

scipy_doctest/tests/test_testmod.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ def test_tuple_and_list():
117117
config=config)
118118
assert res.failed == 2
119119

120+
def test_dict():
121+
config = DTConfig()
122+
res, _ = _testmod(failure_cases,
123+
strategy=[failure_cases.dict_not_dict,
124+
failure_cases.dict_not_dict_2,
125+
failure_cases.dict_wrong_keys,
126+
failure_cases.dict_wrong_values,
127+
failure_cases.dict_wrong_values_np,
128+
failure_cases.dict_nested_wrong_values_np],
129+
config=config)
130+
assert res.failed == 6
131+
120132

121133
@pytest.mark.parametrize('strict, num_fails', [(True, 1), (False, 0)])
122134
class TestStrictDType:

0 commit comments

Comments
 (0)