[pypy-commit] cffi default: Add ffi.CData and ffi.CType.
arigo
noreply at buildbot.pypy.org
Tue Sep 4 15:26:34 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r917:41a7f979ae19
Date: 2012-09-04 15:26 +0200
http://bitbucket.org/cffi/cffi/changeset/41a7f979ae19/
Log: Add ffi.CData and ffi.CType.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -4105,6 +4105,12 @@
return Py_None;
}
+static PyObject *b__get_types(PyObject *self, PyObject *noarg)
+{
+ return PyTuple_Pack(2, (PyObject *)&CData_Type,
+ (PyObject *)&CTypeDescr_Type);
+}
+
/************************************************************/
static char _testfunc0(char a, char b)
@@ -4322,6 +4328,7 @@
{"buffer", b_buffer, METH_VARARGS},
{"get_errno", b_get_errno, METH_NOARGS},
{"set_errno", b_set_errno, METH_VARARGS},
+ {"_get_types", b__get_types, METH_NOARGS},
{"_testfunc", b__testfunc, METH_VARARGS},
{NULL, NULL} /* Sentinel */
};
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1,6 +1,6 @@
import py
from _cffi_backend import *
-from _cffi_backend import _getfields, _testfunc
+from _cffi_backend import _getfields, _testfunc, _get_types
# ____________________________________________________________
@@ -2067,3 +2067,16 @@
BStruct = new_struct_type("foo")
complete_struct_or_union(BStruct, [('b', BInt, -1, 1)],
None, 5, 1)
+
+def test_CData_CType():
+ CData, CType = _get_types()
+ BChar = new_primitive_type("char")
+ BCharP = new_pointer_type(BChar)
+ nullchr = cast(BChar, 0)
+ chrref = newp(BCharP, None)
+ assert isinstance(nullchr, CData)
+ assert isinstance(chrref, CData)
+ assert not isinstance(BChar, CData)
+ assert not isinstance(nullchr, CType)
+ assert not isinstance(chrref, CType)
+ assert isinstance(BChar, CType)
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -69,6 +69,7 @@
del self._cdefsources[:]
#
self.NULL = self.cast("void *", 0)
+ self.CData, self.CType = backend._get_types()
def cdef(self, csource, override=False):
"""Parse the given C source. This registers all declared functions,
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -10,7 +10,11 @@
xrange = range
bytechr = lambda num: bytes([num])
+class CTypesType(type):
+ pass
+
class CTypesData(object):
+ __metaclass__ = CTypesType
__slots__ = ['__weakref__']
def __init__(self, *args):
@@ -285,6 +289,9 @@
def set_ffi(self, ffi):
self.ffi = ffi
+ def _get_types(self):
+ return CTypesData, CTypesType
+
def nonstandard_integer_types(self):
UNSIGNED = 0x1000
result = {}
diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -952,6 +952,13 @@
assert ffi.typeof(ptr) is ffi.typeof("foo_t*")
...
+.. versionadded:: 0.4
+ ``ffi.CData, ffi.CType``: the Python type of the objects referred to
+ as ``<cdata>`` and ``<ctype>`` in the rest of this document. Note
+ that some cdata objects may be actually of a subclass of
+ ``ffi.CData``, and similarly with ctype, so you should check with
+ ``if isinstance(x, ffi.CData)``.
+
``ffi.sizeof("C type" or cdata object)``: return the size of the
argument in bytes. The argument can be either a C type, or a cdata object,
like in the equivalent ``sizeof`` operator in C.
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -1383,3 +1383,12 @@
del q
import gc; gc.collect(); gc.collect(); gc.collect()
assert seen == [1]
+
+ def test_CData_CType(self):
+ ffi = FFI(backend=self.Backend())
+ assert isinstance(ffi.cast("int", 0), ffi.CData)
+ assert isinstance(ffi.new("int *"), ffi.CData)
+ assert not isinstance(ffi.typeof("int"), ffi.CData)
+ assert not isinstance(ffi.cast("int", 0), ffi.CType)
+ assert not isinstance(ffi.new("int *"), ffi.CType)
+ assert isinstance(ffi.typeof("int"), ffi.CType)
diff --git a/testing/test_cdata.py b/testing/test_cdata.py
--- a/testing/test_cdata.py
+++ b/testing/test_cdata.py
@@ -21,6 +21,8 @@
return FakeType('ptr-to-%r' % (x,))
def cast(self, x, y):
return 'casted!'
+ def _get_types(self):
+ return "CData", "CType"
class FakeType(object):
diff --git a/testing/test_parsing.py b/testing/test_parsing.py
--- a/testing/test_parsing.py
+++ b/testing/test_parsing.py
@@ -43,6 +43,8 @@
return FakeType("<void>")
def cast(self, x, y):
return 'casted!'
+ def _get_types(self):
+ return "CData", "CType"
class FakeType(object):
def __init__(self, cdecl):
More information about the pypy-commit
mailing list