PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/module/cpyext/test/test_pystrtod.py

https://bitbucket.org/pypy/pypy/
Python | 167 lines | 162 code | 5 blank | 0 comment | 0 complexity | d8c2ce0b02ec2a67d77a5ac03bf0e6b7 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import math
  2. from pypy.module.cpyext import pystrtod
  3. from pypy.module.cpyext.test.test_api import BaseApiTest
  4. from rpython.rtyper.lltypesystem import rffi
  5. from rpython.rtyper.lltypesystem import lltype
  6. class TestPyOS_string_to_double(BaseApiTest):
  7. def test_simple_float(self, api):
  8. s = rffi.str2charp('0.4')
  9. null = lltype.nullptr(rffi.CCHARPP.TO)
  10. r = api.PyOS_string_to_double(s, null, None)
  11. assert r == 0.4
  12. rffi.free_charp(s)
  13. def test_empty_string(self, api):
  14. s = rffi.str2charp('')
  15. null = lltype.nullptr(rffi.CCHARPP.TO)
  16. r = api.PyOS_string_to_double(s, null, None)
  17. assert r == -1.0
  18. raises(ValueError)
  19. api.PyErr_Clear()
  20. rffi.free_charp(s)
  21. def test_bad_string(self, api):
  22. s = rffi.str2charp(' 0.4')
  23. null = lltype.nullptr(rffi.CCHARPP.TO)
  24. r = api.PyOS_string_to_double(s, null, None)
  25. assert r == -1.0
  26. raises(ValueError)
  27. api.PyErr_Clear()
  28. rffi.free_charp(s)
  29. def test_overflow_pos(self, api):
  30. s = rffi.str2charp('1e500')
  31. null = lltype.nullptr(rffi.CCHARPP.TO)
  32. r = api.PyOS_string_to_double(s, null, None)
  33. assert math.isinf(r)
  34. assert r > 0
  35. rffi.free_charp(s)
  36. def test_overflow_neg(self, api):
  37. s = rffi.str2charp('-1e500')
  38. null = lltype.nullptr(rffi.CCHARPP.TO)
  39. r = api.PyOS_string_to_double(s, null, None)
  40. assert math.isinf(r)
  41. assert r < 0
  42. rffi.free_charp(s)
  43. def test_overflow_exc(self, space, api):
  44. s = rffi.str2charp('1e500')
  45. null = lltype.nullptr(rffi.CCHARPP.TO)
  46. r = api.PyOS_string_to_double(s, null, space.w_ValueError)
  47. assert r == -1.0
  48. raises(ValueError)
  49. api.PyErr_Clear()
  50. rffi.free_charp(s)
  51. def test_endptr_number(self, api):
  52. s = rffi.str2charp('0.4')
  53. endp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
  54. r = api.PyOS_string_to_double(s, endp, None)
  55. assert r == 0.4
  56. endp_addr = rffi.cast(rffi.LONG, endp[0])
  57. s_addr = rffi.cast(rffi.LONG, s)
  58. assert endp_addr == s_addr + 3
  59. rffi.free_charp(s)
  60. lltype.free(endp, flavor='raw')
  61. def test_endptr_tail(self, api):
  62. s = rffi.str2charp('0.4 foo')
  63. endp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
  64. r = api.PyOS_string_to_double(s, endp, None)
  65. assert r == 0.4
  66. endp_addr = rffi.cast(rffi.LONG, endp[0])
  67. s_addr = rffi.cast(rffi.LONG, s)
  68. assert endp_addr == s_addr + 3
  69. rffi.free_charp(s)
  70. lltype.free(endp, flavor='raw')
  71. def test_endptr_no_conversion(self, api):
  72. s = rffi.str2charp('foo')
  73. endp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
  74. r = api.PyOS_string_to_double(s, endp, None)
  75. assert r == -1.0
  76. raises(ValueError)
  77. endp_addr = rffi.cast(rffi.LONG, endp[0])
  78. s_addr = rffi.cast(rffi.LONG, s)
  79. assert endp_addr == s_addr
  80. api.PyErr_Clear()
  81. rffi.free_charp(s)
  82. lltype.free(endp, flavor='raw')
  83. class TestPyOS_double_to_string(BaseApiTest):
  84. def test_format_code(self, api):
  85. ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
  86. r = api.PyOS_double_to_string(150.0, 'e', 1, 0, ptype)
  87. assert '1.5e+02' == rffi.charp2str(r)
  88. type_value = rffi.cast(lltype.Signed, ptype[0])
  89. assert pystrtod.Py_DTST_FINITE == type_value
  90. rffi.free_charp(r)
  91. lltype.free(ptype, flavor='raw')
  92. def test_precision(self, api):
  93. ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
  94. r = api.PyOS_double_to_string(3.14159269397, 'g', 5, 0, ptype)
  95. assert '3.1416' == rffi.charp2str(r)
  96. type_value = rffi.cast(lltype.Signed, ptype[0])
  97. assert pystrtod.Py_DTST_FINITE == type_value
  98. rffi.free_charp(r)
  99. lltype.free(ptype, flavor='raw')
  100. def test_flags_sign(self, api):
  101. ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
  102. r = api.PyOS_double_to_string(-3.14, 'g', 3, 1, ptype)
  103. assert '-3.14' == rffi.charp2str(r)
  104. type_value = rffi.cast(lltype.Signed, ptype[0])
  105. assert pystrtod.Py_DTST_FINITE == type_value
  106. rffi.free_charp(r)
  107. lltype.free(ptype, flavor='raw')
  108. def test_flags_add_dot_0(self, api):
  109. ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
  110. r = api.PyOS_double_to_string(3, 'g', 5, 2, ptype)
  111. assert '3.0' == rffi.charp2str(r)
  112. type_value = rffi.cast(lltype.Signed, ptype[0])
  113. assert pystrtod.Py_DTST_FINITE == type_value
  114. rffi.free_charp(r)
  115. lltype.free(ptype, flavor='raw')
  116. def test_flags_alt(self, api):
  117. ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
  118. r = api.PyOS_double_to_string(314., 'g', 3, 4, ptype)
  119. assert '314.' == rffi.charp2str(r)
  120. type_value = rffi.cast(lltype.Signed, ptype[0])
  121. assert pystrtod.Py_DTST_FINITE == type_value
  122. rffi.free_charp(r)
  123. lltype.free(ptype, flavor='raw')
  124. def test_ptype_nan(self, api):
  125. ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
  126. r = api.PyOS_double_to_string(float('nan'), 'g', 3, 4, ptype)
  127. assert 'nan' == rffi.charp2str(r)
  128. type_value = rffi.cast(lltype.Signed, ptype[0])
  129. assert pystrtod.Py_DTST_NAN == type_value
  130. rffi.free_charp(r)
  131. lltype.free(ptype, flavor='raw')
  132. def test_ptype_infinity(self, api):
  133. ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
  134. r = api.PyOS_double_to_string(1e200 * 1e200, 'g', 0, 0, ptype)
  135. assert 'inf' == rffi.charp2str(r)
  136. type_value = rffi.cast(lltype.Signed, ptype[0])
  137. assert pystrtod.Py_DTST_INFINITE == type_value
  138. rffi.free_charp(r)
  139. lltype.free(ptype, flavor='raw')
  140. def test_ptype_null(self, api):
  141. ptype = lltype.nullptr(rffi.INTP.TO)
  142. r = api.PyOS_double_to_string(3.14, 'g', 3, 0, ptype)
  143. assert '3.14' == rffi.charp2str(r)
  144. assert ptype == lltype.nullptr(rffi.INTP.TO)
  145. rffi.free_charp(r)