utils_test.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import doctest
  2. import inspect
  3. __all__ = ['module_doctest']
  4. # The utilities below were obtained from:
  5. # https://github.com/cython/cython/wiki/FAQ
  6. # #how-can-i-run-doctests-in-cython-code-pyx-files
  7. #
  8. # Cython-compatible wrapper for doctest.testmod().
  9. #
  10. # Usage example, assuming a Cython module mymod.pyx is compiled.
  11. # This is run from the command line, passing a command to Python:
  12. # python -c "import cydoctest, mymod; cydoctest.testmod(mymod)"
  13. #
  14. # (This still won't let a Cython module run its own doctests
  15. # when called with "python mymod.py", but it's pretty close.
  16. # Further options can be passed to testmod() as desired, e.g.
  17. # verbose=True.)
  18. def _from_module(module, object):
  19. """
  20. Return true if the given object is defined in the given module.
  21. """
  22. if module is None:
  23. return True
  24. elif inspect.getmodule(object) is not None:
  25. return module is inspect.getmodule(object)
  26. elif inspect.isfunction(object):
  27. return module.__dict__ is object.func_globals
  28. elif inspect.isclass(object):
  29. return module.__name__ == object.__module__
  30. elif hasattr(object, '__module__'):
  31. return module.__name__ == object.__module__
  32. elif isinstance(object, property):
  33. return True # [XX] no way not be sure.
  34. else:
  35. raise ValueError("object must be a class or function")
  36. def _fix_module_doctest(module):
  37. """
  38. Extract docstrings from cython functions, that would be skipped by doctest
  39. otherwise.
  40. """
  41. module.__test__ = {}
  42. for name in dir(module):
  43. value = getattr(module, name)
  44. if (inspect.isbuiltin(value) and isinstance(value.__doc__, str) and
  45. _from_module(module, value)):
  46. module.__test__[name] = value.__doc__
  47. def module_doctest(m, *args, **kwargs):
  48. """
  49. Fix a Cython module's doctests, then call doctest.testmod()
  50. All other arguments are passed directly to doctest.testmod().
  51. Return True on success, False on failure.
  52. """
  53. _fix_module_doctest(m)
  54. return doctest.testmod(m, *args, **kwargs).failed == 0