Author: Tom Krauss <thomas.p.kra...@gmail.com>
Branch: sirtom67/float_complex
Changeset: r2879:6dcf51c6003c
Date: 2017-02-05 17:13 -0600
http://bitbucket.org/cffi/cffi/changeset/6dcf51c6003c/

Log:    float complex progress. Added __complex__ method to cdata. Test
        currently failing at > assert repr(complex(cast(p, -0j))) == '-0j' E
        assert '0j' == '-0j' E - 0j E + -0j E ? +

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -884,6 +884,26 @@
     return 0;
 }
 
+static Py_complex
+read_raw_complex_data(char *target, int size)
+{
+    Py_complex r = {.real=0, .imag=0};
+    if (size == 2*sizeof(float)) {
+        float real_part, imag_part;
+        memcpy(&real_part, target + 0,             sizeof(float));
+        memcpy(&imag_part, target + sizeof(float), sizeof(float));
+        r.real = real_part;
+        r.imag = imag_part;
+        return r;
+    }
+    if (size == 2*sizeof(double)) {
+        memcpy(&(r.real), target, 2*sizeof(double));
+        return r;
+    }
+    Py_FatalError("read_raw_complex_data: bad float size");
+    return r;
+}
+
 static void
 write_raw_float_data(char *target, double source, int size)
 {
@@ -1011,6 +1031,10 @@
             return (PyObject *)cd;
         }
     }
+    else if (ct->ct_flags & CT_PRIMITIVE_COMPLEX) {
+        Py_complex value = read_raw_complex_data(data, ct->ct_size);
+        return PyComplex_FromCComplex(value);
+    }
     else if (ct->ct_flags & CT_PRIMITIVE_CHAR) {
         /*READ(data, ct->ct_size)*/
         if (ct->ct_size == sizeof(char))
@@ -2009,6 +2033,10 @@
         }
         return PyFloat_FromDouble(value);
     }
+    if (cd->c_type->ct_flags & CT_PRIMITIVE_COMPLEX) {
+        double value = read_raw_float_data(cd->c_data, cd->c_type->ct_size);
+        return PyComplex_FromDoubles(value, 0.0);
+    }
     PyErr_Format(PyExc_TypeError, "float() not supported on cdata '%s'",
                  cd->c_type->ct_name);
     return NULL;
@@ -2808,6 +2836,19 @@
     }
 }
 
+static PyObject *cdata_complex(PyObject *cd_, PyObject *noarg)
+{
+    CDataObject *cd = (CDataObject *)cd_;
+
+    if (cd->c_type->ct_flags & CT_PRIMITIVE_COMPLEX) {
+        Py_complex value = read_raw_complex_data(cd->c_data, 
cd->c_type->ct_size);
+        return PyComplex_FromCComplex(value);
+    }
+    PyErr_Format(PyExc_TypeError, "complex() not supported on cdata '%s'",
+                 cd->c_type->ct_name);
+    return NULL;
+}
+
 static PyObject *cdata_iter(CDataObject *);
 
 static PyNumberMethods CData_as_number = {
@@ -2857,8 +2898,9 @@
 };
 
 static PyMethodDef cdata_methods[] = {
-    {"__dir__",   cdata_dir,      METH_NOARGS},
-    {NULL,        NULL}           /* sentinel */
+    {"__dir__",     cdata_dir,      METH_NOARGS},
+    {"__complex__", cdata_complex,  METH_NOARGS},
+    {NULL,          NULL}           /* sentinel */
 };
 
 static PyTypeObject CData_Type = {
@@ -3599,7 +3641,6 @@
         /* cast to a complex */
         Py_complex value;
         PyObject *io;
-        printf("_cffi_backend.c do_cast  ct->ct_size=%ld\n", ct->ct_size);
         if (CData_Check(ob)) {
             CDataObject *cdsrc = (CDataObject *)ob;
 
@@ -3983,8 +4024,6 @@
     int name_size;
     ffi_type *ffitype;
 
-    printf("hello\n");
-
     for (ptypes=types; ; ptypes++) {
         if (ptypes->name == NULL) {
 #ifndef HAVE_WCHAR_H
diff --git a/c/realize_c_type.c b/c/realize_c_type.c
--- a/c/realize_c_type.c
+++ b/c/realize_c_type.c
@@ -101,7 +101,6 @@
 
 static PyObject *build_primitive_type(int num)
 {
-    fprintf(stderr, "fooooooooooooo    num=%d\n",num);
     /* XXX too many translations between here and new_primitive_type() */
     static const char *primitive_name[] = {
         NULL,
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -197,12 +197,12 @@
         py.test.raises(TypeError, float, cast(p, -150))
         assert complex(cast(p, 1.25)) == 1.25
         assert complex(cast(p, 1.25j)) == 1.25j
-        assert float(cast(p, INF*1j)) == INF*1j
-        assert float(cast(p, -INF)) == -INF
+        assert complex(cast(p, complex(0,INF))) == complex(0,INF)
+        assert complex(cast(p, -INF)) == -INF
         if name == "float":
             assert complex(cast(p, 1.1j)) != 1.1j         # rounding error
             assert complex(cast(p, 1E200+3j)) == INF+3j   # limited range
-            assert complex(cast(p, 3+1E200j)) == 3+INF*1j # limited range
+            assert complex(cast(p, complex(3,1E200))) == complex(3,INF) # 
limited range
 
         assert cast(p, -1.1j) != cast(p, -1.1j)
         assert repr(complex(cast(p, -0.0)).real) == '-0.0'
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to