test_utils.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import inspect
  2. import sys
  3. import pytest
  4. from numpy.core import arange
  5. from numpy.testing import assert_, assert_equal, assert_raises_regex
  6. from numpy.lib import deprecate, deprecate_with_doc
  7. import numpy.lib.utils as utils
  8. from io import StringIO
  9. @pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO")
  10. @pytest.mark.skipif(
  11. sys.version_info == (3, 10, 0, "candidate", 1),
  12. reason="Broken as of bpo-44524",
  13. )
  14. def test_lookfor():
  15. out = StringIO()
  16. utils.lookfor('eigenvalue', module='numpy', output=out,
  17. import_modules=False)
  18. out = out.getvalue()
  19. assert_('numpy.linalg.eig' in out)
  20. @deprecate
  21. def old_func(self, x):
  22. return x
  23. @deprecate(message="Rather use new_func2")
  24. def old_func2(self, x):
  25. return x
  26. def old_func3(self, x):
  27. return x
  28. new_func3 = deprecate(old_func3, old_name="old_func3", new_name="new_func3")
  29. def old_func4(self, x):
  30. """Summary.
  31. Further info.
  32. """
  33. return x
  34. new_func4 = deprecate(old_func4)
  35. def old_func5(self, x):
  36. """Summary.
  37. Bizarre indentation.
  38. """
  39. return x
  40. new_func5 = deprecate(old_func5, message="This function is\ndeprecated.")
  41. def old_func6(self, x):
  42. """
  43. Also in PEP-257.
  44. """
  45. return x
  46. new_func6 = deprecate(old_func6)
  47. @deprecate_with_doc(msg="Rather use new_func7")
  48. def old_func7(self,x):
  49. return x
  50. def test_deprecate_decorator():
  51. assert_('deprecated' in old_func.__doc__)
  52. def test_deprecate_decorator_message():
  53. assert_('Rather use new_func2' in old_func2.__doc__)
  54. def test_deprecate_fn():
  55. assert_('old_func3' in new_func3.__doc__)
  56. assert_('new_func3' in new_func3.__doc__)
  57. def test_deprecate_with_doc_decorator_message():
  58. assert_('Rather use new_func7' in old_func7.__doc__)
  59. @pytest.mark.skipif(sys.flags.optimize == 2, reason="-OO discards docstrings")
  60. @pytest.mark.parametrize('old_func, new_func', [
  61. (old_func4, new_func4),
  62. (old_func5, new_func5),
  63. (old_func6, new_func6),
  64. ])
  65. def test_deprecate_help_indentation(old_func, new_func):
  66. _compare_docs(old_func, new_func)
  67. # Ensure we don't mess up the indentation
  68. for knd, func in (('old', old_func), ('new', new_func)):
  69. for li, line in enumerate(func.__doc__.split('\n')):
  70. if li == 0:
  71. assert line.startswith(' ') or not line.startswith(' '), knd
  72. elif line:
  73. assert line.startswith(' '), knd
  74. def _compare_docs(old_func, new_func):
  75. old_doc = inspect.getdoc(old_func)
  76. new_doc = inspect.getdoc(new_func)
  77. index = new_doc.index('\n\n') + 2
  78. assert_equal(new_doc[index:], old_doc)
  79. @pytest.mark.skipif(sys.flags.optimize == 2, reason="-OO discards docstrings")
  80. def test_deprecate_preserve_whitespace():
  81. assert_('\n Bizarre' in new_func5.__doc__)
  82. def test_deprecate_module():
  83. assert_(old_func.__module__ == __name__)
  84. def test_safe_eval_nameconstant():
  85. # Test if safe_eval supports Python 3.4 _ast.NameConstant
  86. utils.safe_eval('None')
  87. class TestByteBounds:
  88. def test_byte_bounds(self):
  89. # pointer difference matches size * itemsize
  90. # due to contiguity
  91. a = arange(12).reshape(3, 4)
  92. low, high = utils.byte_bounds(a)
  93. assert_equal(high - low, a.size * a.itemsize)
  94. def test_unusual_order_positive_stride(self):
  95. a = arange(12).reshape(3, 4)
  96. b = a.T
  97. low, high = utils.byte_bounds(b)
  98. assert_equal(high - low, b.size * b.itemsize)
  99. def test_unusual_order_negative_stride(self):
  100. a = arange(12).reshape(3, 4)
  101. b = a.T[::-1]
  102. low, high = utils.byte_bounds(b)
  103. assert_equal(high - low, b.size * b.itemsize)
  104. def test_strided(self):
  105. a = arange(12)
  106. b = a[::2]
  107. low, high = utils.byte_bounds(b)
  108. # the largest pointer address is lost (even numbers only in the
  109. # stride), and compensate addresses for striding by 2
  110. assert_equal(high - low, b.size * 2 * b.itemsize - b.itemsize)
  111. def test_assert_raises_regex_context_manager():
  112. with assert_raises_regex(ValueError, 'no deprecation warning'):
  113. raise ValueError('no deprecation warning')
  114. def test_info_method_heading():
  115. # info(class) should only print "Methods:" heading if methods exist
  116. class NoPublicMethods:
  117. pass
  118. class WithPublicMethods:
  119. def first_method():
  120. pass
  121. def _has_method_heading(cls):
  122. out = StringIO()
  123. utils.info(cls, output=out)
  124. return 'Methods:' in out.getvalue()
  125. assert _has_method_heading(WithPublicMethods)
  126. assert not _has_method_heading(NoPublicMethods)