-
Notifications
You must be signed in to change notification settings - Fork 30
/
cydoctest.py
68 lines (55 loc) · 2.04 KB
/
cydoctest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!python
"""
Taken from https://github.com/cython/cython/wiki/FAQ#how-can-i-run-doctests-in-cython-code-pyx-files
Cython-compatible wrapper for doctest.testmod().
Usage example, assuming a Cython module mymod.pyx is compiled.
This is run from the command line, passing a command to Python:
python -c "import cydoctest, mymod; cydoctest.testmod(mymod)"
(This still won't let a Cython module run its own doctests
when called with "python mymod.py", but it's pretty close.
Further options can be passed to testmod() as desired, e.g.
verbose=True.)
"""
import sys
import doctest
import inspect
def _from_module(module, object):
"""
Return true if the given object is defined in the given module.
"""
if module is None:
return True
elif inspect.getmodule(object) is not None:
return module is inspect.getmodule(object)
elif inspect.isfunction(object):
return module.__dict__ is object.func_globals
elif inspect.isclass(object):
return module.__name__ == object.__module__
elif hasattr(object, '__module__'):
return module.__name__ == object.__module__
elif isinstance(object, property):
return True # [XX] no way not be sure.
else:
raise ValueError("object must be a class or function")
def fix_module_doctest(module):
"""
Extract docstrings from cython functions, that would be skipped by doctest
otherwise.
"""
module.__test__ = {}
for name in dir(module):
value = getattr(module, name)
if inspect.isbuiltin(value) and isinstance(value.__doc__, str) and _from_module(module, value):
module.__test__[name] = value.__doc__
def testmod(m=None, *args, **kwargs):
"""
Fix a Cython module's doctests, then call doctest.testmod()
All other arguments are passed directly to doctest.testmod().
"""
fix_module_doctest(m)
result = doctest.testmod(m, *args, **kwargs)
if result.failed > 0:
sys.exit('%d test(s) failed' % result.failed)
if __name__ == "__main__":
import pyroaring
testmod(pyroaring)