Skip to content

Commit

Permalink
Implement string-to-float conversion in Limited API (cythonGH-5695)
Browse files Browse the repository at this point in the history
  • Loading branch information
ap-- authored and rinarakaki committed Nov 3, 2023
1 parent 66310b8 commit accd2fe
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
34 changes: 30 additions & 4 deletions Cython/Utility/Optimize.c
Expand Up @@ -688,7 +688,7 @@ static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj);/*proto*/
/////////////// pyunicode_as_double.proto ///////////////
//@requires: pybytes_as_double

#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS
static const char* __Pyx__PyUnicode_AsDouble_Copy(const void* data, const int kind, char* buffer, Py_ssize_t start, Py_ssize_t end) {
int last_was_punctuation;
Py_ssize_t i;
Expand Down Expand Up @@ -812,7 +812,7 @@ static double __Pyx_PyUnicode_AsDouble_WithSpaces(PyObject *obj) {

static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj) {
// Currently not optimised for Py2.7.
#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS
if (unlikely(__Pyx_PyUnicode_READY(obj) == -1))
return (double)-1;
if (likely(PyUnicode_IS_ASCII(obj))) {
Expand All @@ -834,10 +834,32 @@ static double __Pyx_SlowPyString_AsDouble(PyObject *obj);/*proto*/
static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length);/*proto*/

static CYTHON_INLINE double __Pyx_PyBytes_AsDouble(PyObject *obj) {
return __Pyx__PyBytes_AsDouble(obj, PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj));
char* as_c_string;
Py_ssize_t size;
#if CYTHON_ASSUME_SAFE_MACROS
as_c_string = PyBytes_AS_STRING(obj);
size = PyBytes_GET_SIZE(obj);
#else
if (PyBytes_AsStringAndSize(obj, &as_c_string, &size) < 0) {
return (double)-1;
}
#endif
return __Pyx__PyBytes_AsDouble(obj, as_c_string, size);
}
static CYTHON_INLINE double __Pyx_PyByteArray_AsDouble(PyObject *obj) {
return __Pyx__PyBytes_AsDouble(obj, PyByteArray_AS_STRING(obj), PyByteArray_GET_SIZE(obj));
char* as_c_string;
Py_ssize_t size;
#if CYTHON_ASSUME_SAFE_MACROS
as_c_string = PyByteArray_AS_STRING(obj);
size = PyByteArray_GET_SIZE(obj);
#else
as_c_string = PyByteArray_AsString(obj);
if (as_c_string == NULL) {
return (double)-1;
}
size = PyByteArray_Size(obj);
#endif
return __Pyx__PyBytes_AsDouble(obj, as_c_string, size);
}


Expand All @@ -851,7 +873,11 @@ static double __Pyx_SlowPyString_AsDouble(PyObject *obj) {
float_value = PyFloat_FromString(obj, 0);
#endif
if (likely(float_value)) {
#if CYTHON_ASSUME_SAFE_MACROS
double value = PyFloat_AS_DOUBLE(float_value);
#else
double value = PyFloat_AsDouble(float_value);
#endif
Py_DECREF(float_value);
return value;
}
Expand Down
9 changes: 8 additions & 1 deletion tests/run/isolated_limited_api_tests.srctree
Expand Up @@ -40,6 +40,10 @@ limited.E()

assert limited.decode(b'a', bytearray(b'b')) == "ab"

assert limited.cast_float(1) == 1.0
assert limited.cast_float("2.0") == 2.0
assert limited.cast_float(bytearray(b"3")) == 3.0


##################### limited.pyx #############################

Expand Down Expand Up @@ -73,7 +77,10 @@ def raises():

def decode(bytes b, bytearray ba):
return b.decode("utf-8") + ba.decode("utf-8")


def cast_float(object o):
return float(o)

class C:
pass

Expand Down

0 comments on commit accd2fe

Please sign in to comment.