diff options
Diffstat (limited to 'Modules/_testcapi/float.c')
-rw-r--r-- | Modules/_testcapi/float.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/Modules/_testcapi/float.c b/Modules/_testcapi/float.c index 15ea97e..e386913 100644 --- a/Modules/_testcapi/float.c +++ b/Modules/_testcapi/float.c @@ -99,9 +99,68 @@ _testcapi_float_unpack_impl(PyObject *module, const char *data, return PyFloat_FromDouble(d); } + +/* Test PyOS_string_to_double. */ +static PyObject * +test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + double result; + const char *msg; + +#define CHECK_STRING(STR, expected) \ + do { \ + result = PyOS_string_to_double(STR, NULL, NULL); \ + if (result == -1.0 && PyErr_Occurred()) { \ + return NULL; \ + } \ + if (result != (double)expected) { \ + msg = "conversion of " STR " to float failed"; \ + goto fail; \ + } \ + } while (0) + +#define CHECK_INVALID(STR) \ + do { \ + result = PyOS_string_to_double(STR, NULL, NULL); \ + if (result == -1.0 && PyErr_Occurred()) { \ + if (PyErr_ExceptionMatches(PyExc_ValueError)) { \ + PyErr_Clear(); \ + } \ + else { \ + return NULL; \ + } \ + } \ + else { \ + msg = "conversion of " STR " didn't raise ValueError"; \ + goto fail; \ + } \ + } while (0) + + CHECK_STRING("0.1", 0.1); + CHECK_STRING("1.234", 1.234); + CHECK_STRING("-1.35", -1.35); + CHECK_STRING(".1e01", 1.0); + CHECK_STRING("2.e-2", 0.02); + + CHECK_INVALID(" 0.1"); + CHECK_INVALID("\t\n-3"); + CHECK_INVALID(".123 "); + CHECK_INVALID("3\n"); + CHECK_INVALID("123abc"); + + Py_RETURN_NONE; + fail: + PyErr_Format(PyExc_AssertionError, "test_string_to_double: %s", msg); + return NULL; +#undef CHECK_STRING +#undef CHECK_INVALID +} + + static PyMethodDef test_methods[] = { _TESTCAPI_FLOAT_PACK_METHODDEF _TESTCAPI_FLOAT_UNPACK_METHODDEF + {"test_string_to_double", test_string_to_double, METH_NOARGS}, {NULL}, }; |