[pypy-commit] cffi sirtom67/float_complex: Fix test, fix all abort()

arigo pypy.commits at gmail.com
Mon May 29 13:11:20 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: sirtom67/float_complex
Changeset: r2936:ab6edb3987e7
Date: 2017-05-29 18:50 +0200
http://bitbucket.org/cffi/cffi/changeset/ab6edb3987e7/

Log:	Fix test, fix all abort()

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1565,7 +1565,11 @@
         return convert_struct_from_object(data, ct, init, NULL);
     }
     if (ct->ct_flags & CT_PRIMITIVE_COMPLEX) {
-        abort(); // XXX
+        Py_complex value = PyComplex_AsCComplex(init);
+        if (PyErr_Occurred())
+            return -1;
+        write_raw_complex_data(data, value, ct->ct_size);
+        return 0;
     }
     PyErr_Format(PyExc_SystemError,
                  "convert_from_object: '%s'", ct->ct_name);
@@ -2005,7 +2009,9 @@
             return read_raw_float_data(cd->c_data, cd->c_type->ct_size) != 0.0;
         }
         if (cd->c_type->ct_flags & CT_PRIMITIVE_COMPLEX) {
-            abort(); // XXX
+            Py_complex value = read_raw_complex_data(cd->c_data,
+                                                     cd->c_type->ct_size);
+            return value.real != 0.0 || value.imag != 0.0;
         }
     }
     return cd->c_data != NULL;
@@ -2964,19 +2970,10 @@
         PyObject *op = PyComplex_FromCComplex(value);
         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);
-    }
-    abort(); // XXX ints, etc.
+    /* <cdata 'float'> or <cdata 'int'> cannot be directly converted by
+       calling complex(), just like <cdata 'int'> cannot be directly
+       converted by calling float() */
+
     PyErr_Format(PyExc_TypeError, "complex() not supported on cdata '%s'",
                  cd->c_type->ct_name);
     return NULL;
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -217,16 +217,17 @@
         #
         py.test.raises(TypeError, cast, new_primitive_type(name), 1+0j)
         #
-        assert complex(cast(new_primitive_type("char"), "A")) == 65 + 0j
-        assert complex(cast(new_primitive_type("int"), 65)) == 65 + 0j
-        assert complex(cast(new_primitive_type("uint64_t"), 65)) == 65 + 0j
-        assert complex(cast(new_primitive_type("float"), 65.5)) == 65.5 + 0j
+        for basetype in ["char", "int", "uint64_t", "float",
+                         "double", "long double"]:
+            baseobj = cast(new_primitive_type(basetype), 65)
+            py.test.raises(TypeError, complex, baseobj)
         #
         BArray = new_array_type(new_pointer_type(p), 10)
         x = newp(BArray, None)
         x[5] = 12.34 + 56.78j
         assert type(x[5]) is complex
-        assert x[5] == 12.34 + 56.78j
+        assert abs(x[5] - (12.34 + 56.78j)) < 1e-5
+        assert (x[5] == 12.34 + 56.78j) == (name == "double")  # rounding error
     py.test.raises(TypeError, cast, new_primitive_type("int"), 1+0j)
 
 def test_character_type():


More information about the pypy-commit mailing list