Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r2655:2022122f5ad3
Date: 2016-03-30 17:22 +0200
http://bitbucket.org/cffi/cffi/changeset/2022122f5ad3/

Log:    Change the API of ffi.list_types()

diff --git a/c/ffi_obj.c b/c/ffi_obj.c
--- a/c/ffi_obj.c
+++ b/c/ffi_obj.c
@@ -863,54 +863,57 @@
 }
 
 PyDoc_STRVAR(ffi_list_types_doc,
-"Build and return a list of all user type names known in this FFI instance.\n"
-"\n"
-"Contains typedef names (sorted in alphabetical order), followed by the\n"
-"'struct xxx' (sorted) and finally the 'union xxx' (sorted as well).");
+"Returns the user type names known to this FFI instance.\n"
+"This returns a tuple containing three lists of names:\n"
+"(typedef_names, names_of_structs, names_of_unions)");
 
 static PyObject *ffi_list_types(FFIObject *self, PyObject *noargs)
 {
-    int is_union, look_for_union;
     Py_ssize_t i, n1 = self->types_builder.ctx.num_typenames;
     Py_ssize_t n23 = self->types_builder.ctx.num_struct_unions;
-    PyObject *o, *result = PyList_New(n1);
-    if (result == NULL)
-        return NULL;
+    PyObject *o, *lst[3] = {NULL, NULL, NULL}, *result = NULL;
+
+    lst[0] = PyList_New(n1);
+    if (lst[0] == NULL)
+        goto error;
+    lst[1] = PyList_New(0);
+    if (lst[1] == NULL)
+        goto error;
+    lst[2] = PyList_New(0);
+    if (lst[2] == NULL)
+        goto error;
 
     for (i = 0; i < n1; i++) {
         o = PyText_FromString(self->types_builder.ctx.typenames[i].name);
         if (o == NULL)
             goto error;
-        PyList_SET_ITEM(result, i, o);
+        PyList_SET_ITEM(lst[0], i, o);
     }
 
-    for (look_for_union = 0; look_for_union < 2; look_for_union++) {
-        for (i = 0; i < n23; i++) {
-            const struct _cffi_struct_union_s *s;
-            int err;
+    for (i = 0; i < n23; i++) {
+        const struct _cffi_struct_union_s *s;
+        int err, index;
 
-            s = &self->types_builder.ctx.struct_unions[i];
-            if (s->name[0] == '$')
-                continue;
+        s = &self->types_builder.ctx.struct_unions[i];
+        if (s->name[0] == '$')
+            continue;
 
-            is_union = (s->flags & _CFFI_F_UNION) != 0;
-            if (is_union != look_for_union)
-                continue;
-
-            o = PyText_FromFormat(is_union ? "union %s" : "struct %s", 
s->name);
-            if (o == NULL)
-                goto error;
-            err = PyList_Append(result, o);
-            Py_DECREF(o);
-            if (err < 0)
-                goto error;
-        }
+        o = PyText_FromString(s->name);
+        if (o == NULL)
+            goto error;
+        index = (s->flags & _CFFI_F_UNION) ? 2 : 1;
+        err = PyList_Append(lst[index], o);
+        Py_DECREF(o);
+        if (err < 0)
+            goto error;
     }
+    result = PyTuple_Pack(3, lst[0], lst[1], lst[2]);
+    /* fall-through */
+ error:
+    Py_XDECREF(lst[2]);
+    Py_XDECREF(lst[1]);
+    Py_XDECREF(lst[0]);
     return result;
-
- error:
-    Py_DECREF(result);
-    return NULL;
 }
 
 PyDoc_STRVAR(ffi_memmove_doc,
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -722,10 +722,9 @@
                          "objects")
 
     def list_types(self):
-        """Build and return a list of all user type names known in this FFI
-        instance.  Contains typedef names (sorted in alphabetical order),
-        followed by the 'struct xxx' (sorted) and finally the 'union xxx'
-        (sorted as well).
+        """Returns the user type names known to this FFI instance.
+        This returns a tuple containing three lists of names:
+        (typedef_names, names_of_structs, names_of_unions)
         """
         typedefs = []
         structs = []
@@ -734,13 +733,13 @@
             if key.startswith('typedef '):
                 typedefs.append(key[8:])
             elif key.startswith('struct '):
-                structs.append(key)
+                structs.append(key[7:])
             elif key.startswith('union '):
-                unions.append(key)
+                unions.append(key[6:])
         typedefs.sort()
         structs.sort()
         unions.sort()
-        return typedefs + structs + unions
+        return (typedefs, structs, unions)
 
 
 def _load_backend_lib(backend, name, flags):
diff --git a/doc/source/using.rst b/doc/source/using.rst
--- a/doc/source/using.rst
+++ b/doc/source/using.rst
@@ -1228,10 +1228,10 @@
 
 .. __: https://bitbucket.org/cffi/cffi/issues/233/
 
-**ffi.list_types()**: builds and returns a list of all user type names
-known in this FFI instance.  The list contains typedef names (sorted in
-alphabetical order), followed by the 'struct xxx' (sorted) and finally
-the 'union xxx' (sorted as well).  *New in version 1.6.*
+**ffi.list_types()**: Returns the user type names known to this FFI
+instance.  This returns a tuple containing three lists of names:
+``(typedef_names, names_of_structs, names_of_unions)``.  *New in
+version 1.6.*
 
 
 .. _`Preparing and Distributing modules`: cdef.html#loading-libraries
diff --git a/testing/cffi0/test_ffi_backend.py 
b/testing/cffi0/test_ffi_backend.py
--- a/testing/cffi0/test_ffi_backend.py
+++ b/testing/cffi0/test_ffi_backend.py
@@ -427,31 +427,32 @@
     def test_introspect_typedef(self):
         ffi = FFI()
         ffi.cdef("typedef int foo_t;")
-        assert ffi.list_types() == ['foo_t']
+        assert ffi.list_types() == (['foo_t'], [], [])
         assert ffi.typeof('foo_t').kind == 'primitive'
         assert ffi.typeof('foo_t').cname == 'int'
         #
         ffi.cdef("typedef signed char a_t, c_t, g_t, b_t;")
-        assert ffi.list_types() == ['a_t', 'b_t', 'c_t', 'foo_t', 'g_t']
+        assert ffi.list_types() == (['a_t', 'b_t', 'c_t', 'foo_t', 'g_t'],
+                                    [], [])
 
     def test_introspect_struct(self):
         ffi = FFI()
         ffi.cdef("struct foo_s { int a; };")
-        assert ffi.list_types() == ['struct foo_s']
+        assert ffi.list_types() == ([], ['foo_s'], [])
         assert ffi.typeof('struct foo_s').kind == 'struct'
         assert ffi.typeof('struct foo_s').cname == 'struct foo_s'
 
     def test_introspect_union(self):
         ffi = FFI()
         ffi.cdef("union foo_s { int a; };")
-        assert ffi.list_types() == ['union foo_s']
+        assert ffi.list_types() == ([], [], ['foo_s'])
         assert ffi.typeof('union foo_s').kind == 'union'
         assert ffi.typeof('union foo_s').cname == 'union foo_s'
 
     def test_introspect_struct_and_typedef(self):
         ffi = FFI()
         ffi.cdef("typedef struct { int a; } foo_t;")
-        assert ffi.list_types() == ['foo_t']
+        assert ffi.list_types() == (['foo_t'], [], [])
         assert ffi.typeof('foo_t').kind == 'struct'
         assert ffi.typeof('foo_t').cname == 'foo_t'
 
@@ -460,14 +461,14 @@
         ffi2 = FFI()
         ffi1.cdef("typedef signed char schar_t; struct sint_t { int x; };")
         ffi2.include(ffi1)
-        assert ffi1.list_types() == sorted(ffi2.list_types()) == [
-            'schar_t', 'struct sint_t']
+        assert ffi1.list_types() == ffi2.list_types() == (
+            ['schar_t'], ['sint_t'], [])
 
     def test_introspect_order(self):
         ffi = FFI()
         ffi.cdef("union aaa { int a; }; typedef struct ccc { int a; } b;")
         ffi.cdef("union g   { int a; }; typedef struct cc  { int a; } bbb;")
         ffi.cdef("union aa  { int a; }; typedef struct a   { int a; } bb;")
-        assert ffi.list_types() == ['b', 'bb', 'bbb',
-                                    'struct a', 'struct cc', 'struct ccc',
-                                    'union aa', 'union aaa', 'union g']
+        assert ffi.list_types() == (['b', 'bb', 'bbb'],
+                                    ['a', 'cc', 'ccc'],
+                                    ['aa', 'aaa', 'g'])
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1796,7 +1796,7 @@
     lib = verify(ffi, 'test_introspect_typedef', """
         typedef int foo_t;
     """)
-    assert ffi.list_types() == ['foo_t']
+    assert ffi.list_types() == (['foo_t'], [], [])
     assert ffi.typeof('foo_t').kind == 'primitive'
     assert ffi.typeof('foo_t').cname == 'int'
 
@@ -1806,7 +1806,7 @@
     lib = verify(ffi, 'test_introspect_typedef_multiple', """
         typedef signed char a_t, c_t, g_t, b_t;
     """)
-    assert ffi.list_types() == ['a_t', 'b_t', 'c_t', 'g_t']
+    assert ffi.list_types() == (['a_t', 'b_t', 'c_t', 'g_t'], [], [])
 
 def test_introspect_struct():
     ffi = FFI()
@@ -1814,7 +1814,7 @@
     lib = verify(ffi, 'test_introspect_struct', """
         struct foo_s { int a; };
     """)
-    assert ffi.list_types() == ['struct foo_s']
+    assert ffi.list_types() == ([], ['foo_s'], [])
     assert ffi.typeof('struct foo_s').kind == 'struct'
     assert ffi.typeof('struct foo_s').cname == 'struct foo_s'
 
@@ -1824,7 +1824,7 @@
     lib = verify(ffi, 'test_introspect_union', """
         union foo_s { int a; };
     """)
-    assert ffi.list_types() == ['union foo_s']
+    assert ffi.list_types() == ([], [], ['foo_s'])
     assert ffi.typeof('union foo_s').kind == 'union'
     assert ffi.typeof('union foo_s').cname == 'union foo_s'
 
@@ -1834,7 +1834,7 @@
     lib = verify(ffi, 'test_introspect_struct_and_typedef', """
         typedef struct { int a; } foo_t;
     """)
-    assert ffi.list_types() == ['foo_t']
+    assert ffi.list_types() == (['foo_t'], [], [])
     assert ffi.typeof('foo_t').kind == 'struct'
     assert ffi.typeof('foo_t').cname == 'foo_t'
 
@@ -1849,8 +1849,8 @@
     ffi2.include(ffi1)
     verify(ffi1, "test_introspect_included_type_parent", SOURCE)
     verify(ffi2, "test_introspect_included_type", SOURCE)
-    assert ffi1.list_types() == ffi2.list_types() == [
-        'schar_t', 'struct sint_t']
+    assert ffi1.list_types() == ffi2.list_types() == (
+            ['schar_t'], ['sint_t'], [])
 
 def test_introspect_order():
     ffi = FFI()
@@ -1862,6 +1862,6 @@
         union g   { int a; }; typedef struct cc  { int a; } bbb;
         union aa  { int a; }; typedef struct a   { int a; } bb;
     """)
-    assert ffi.list_types() == ['b', 'bb', 'bbb',
-                                'struct a', 'struct cc', 'struct ccc',
-                                'union aa', 'union aaa', 'union g']
+    assert ffi.list_types() == (['b', 'bb', 'bbb'],
+                                    ['a', 'cc', 'ccc'],
+                                    ['aa', 'aaa', 'g'])
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to