Author: Tom Krauss <thomas.p.kra...@gmail.com> Branch: sirtom67/float_complex Changeset: r2921:8e77b23da941 Date: 2017-03-27 08:27 -0500 http://bitbucket.org/cffi/cffi/changeset/8e77b23da941/
Log: tests pass. Had to #include <complex.h> - might want to make that optional diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2964,9 +2964,20 @@ if (cd->c_type->ct_flags & CT_PRIMITIVE_COMPLEX) { Py_complex value = read_raw_complex_data(cd->c_data, cd->c_type->ct_size); PyObject *op = PyComplex_FromCComplex(value); - PyComplexObject *opc = (PyComplexObject *) op; return op; } + // floats can also be converted to complex + if (cd->c_type->ct_flags & CT_PRIMITIVE_FLOAT) { + Py_complex value; + if (!(cd->c_type->ct_flags & CT_IS_LONGDOUBLE)) { + value.real = read_raw_float_data(cd->c_data, cd->c_type->ct_size); + } + else { + value.real = (double)read_raw_longdouble_data(cd->c_data); + } + value.imag = 0.0; + return PyComplex_FromCComplex(value); + } PyErr_Format(PyExc_TypeError, "complex() not supported on cdata '%s'", cd->c_type->ct_name); return NULL; diff --git a/c/parse_c_type.c b/c/parse_c_type.c --- a/c/parse_c_type.c +++ b/c/parse_c_type.c @@ -797,7 +797,6 @@ int parse_c_type_from(struct _cffi_parse_info_s *info, size_t *output_index, const char *input) { - printf("parse_c_type_from\n"); int result; token_t token; diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h --- a/cffi/_cffi_include.h +++ b/cffi/_cffi_include.h @@ -16,6 +16,7 @@ #endif #include <Python.h> +#include <complex.h> #ifdef __cplusplus extern "C" { #endif @@ -99,6 +100,29 @@ #define _cffi_to_c_double PyFloat_AsDouble #define _cffi_to_c_float PyFloat_AsDouble +#define _cffi_from_c_float__Complex(x) PyComplex_FromDoubles(crealf(x), cimagf(x)) +#define _cffi_from_c_double__Complex(x) PyComplex_FromDoubles(creal(x), cimag(x)) + +/* inefficient - converts twice! */ +#define _cffi_to_c_float__Complex(op) \ + ( ((float)(PyComplex_AsCComplex(op).real)) + \ + I*((float)(PyComplex_AsCComplex(op).imag)) ) +/* not safe! +//#define _cffi_to_c_float__Complex(op) \ +// ( ((float)((PyComplexObject *)(op))->cval.real) + \ +// I*((float)((PyComplexObject *)(op))->cval.imag) ) +*/ + +/* inefficient - converts twice! */ +#define _cffi_to_c_double__Complex(op) \ + ( (PyComplex_AsCComplex(op).real) + \ + I*(PyComplex_AsCComplex(op).imag) ) +/* not safe! +//#define _cffi_to_c_double__Complex(op) \ +// ( (((PyComplexObject *)(op))->cval.real) + \ +// I*(((PyComplexObject *)(op))->cval.imag) ) +*/ + #define _cffi_from_c_int(x, type) \ (((type)-1) > 0 ? /* unsigned */ \ (sizeof(type) < sizeof(long) ? \ @@ -110,9 +134,6 @@ PyInt_FromLong((long)x) : \ PyLong_FromLongLong((long long)x))) -#define _cffi_from_c_float__Complex(x) PyComplex_FromDoubles(crealf(x), cimagf(x)) -#define _cffi_from_c_double__Complex(x) PyComplex_FromDoubles(creal(x), cimag(x)) - #define _cffi_to_c_int(o, type) \ ((type)( \ sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py --- a/cffi/vengine_cpy.py +++ b/cffi/vengine_cpy.py @@ -806,6 +806,7 @@ cffimod_header = r''' #include <Python.h> #include <stddef.h> +#include <complex.h> /* this block of #ifs should be kept exactly identical between c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */ @@ -873,6 +874,29 @@ #define _cffi_to_c_double PyFloat_AsDouble #define _cffi_to_c_float PyFloat_AsDouble +#define _cffi_from_c_float__Complex(x) PyComplex_FromDoubles(crealf(x), cimagf(x)) +#define _cffi_from_c_double__Complex(x) PyComplex_FromDoubles(creal(x), cimag(x)) + +/* inefficient - converts twice! */ +#define _cffi_to_c_float__Complex(op) \ + ( ((float)(PyComplex_AsCComplex(op).real)) + \ + I*((float)(PyComplex_AsCComplex(op).imag)) ) +/* not safe! +//#define _cffi_to_c_float__Complex(op) \ +// ( ((float)((PyComplexObject *)(op))->cval.real) + \ +// I*((float)((PyComplexObject *)(op))->cval.imag) ) +*/ + +/* inefficient - converts twice! */ +#define _cffi_to_c_double__Complex(op) \ + ( (PyComplex_AsCComplex(op).real) + \ + I*(PyComplex_AsCComplex(op).imag) ) +/* not safe! +//#define _cffi_to_c_double__Complex(op) \ +// ( (((PyComplexObject *)(op))->cval.real) + \ +// I*(((PyComplexObject *)(op))->cval.imag) ) +*/ + #define _cffi_from_c_int_const(x) \ (((x) > 0) ? \ ((unsigned long long)(x) <= (unsigned long long)LONG_MAX) ? \ diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -241,14 +241,15 @@ F = tp.is_float_type() I = tp.is_integer_type() assert C == (typename in ('char', 'wchar_t')) - assert F == (typename in ('float', 'double', 'long double')) + assert F == (typename in ('float', 'double', 'long double', 'float _Complex', 'double _Complex')) assert I + F + C == 1 # one and only one of them is true def test_all_integer_and_float_types(): typenames = [] for typename in all_primitive_types: if (all_primitive_types[typename] == 'c' or - typename == '_Bool' or typename == 'long double'): + typename == '_Bool' or typename == 'long double' + or '_Complex' in typename): # omit _Complex since ffi does not yet support pass else: typenames.append(typename) diff --git a/testing/cffi1/test_new_ffi_1.py b/testing/cffi1/test_new_ffi_1.py --- a/testing/cffi1/test_new_ffi_1.py +++ b/testing/cffi1/test_new_ffi_1.py @@ -1704,6 +1704,8 @@ "ptrdiff_t", "size_t", "ssize_t", + 'double _Complex', + 'float _Complex', ]) for name in PRIMITIVE_TO_INDEX: x = ffi.sizeof(name) diff --git a/testing/cffi1/test_realize_c_type.py b/testing/cffi1/test_realize_c_type.py --- a/testing/cffi1/test_realize_c_type.py +++ b/testing/cffi1/test_realize_c_type.py @@ -45,8 +45,14 @@ def test_all_primitives(): for name in cffi_opcode.PRIMITIVE_TO_INDEX: - check(name, name) + if '_Complex' not in name: + check(name, name) +def test_complex_primitives(): + py.test.xfail("ffi does not support complex yet") + for name in cffi_opcode.PRIMITIVE_TO_INDEX: + if '_Complex' in name: + check(name, name) def check_func(input, expected_output=None): import _cffi_backend diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py --- a/testing/cffi1/test_verify1.py +++ b/testing/cffi1/test_verify1.py @@ -221,7 +221,7 @@ F = tp.is_float_type() I = tp.is_integer_type() assert C == (typename in ('char', 'wchar_t')) - assert F == (typename in ('float', 'double', 'long double')) + assert F == (typename in ('float', 'double', 'long double', 'float _Complex', 'double _Complex')) assert I + F + C == 1 # one and only one of them is true def test_all_integer_and_float_types(): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit