[pypy-commit] cffi default: Split this test in two.

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r558:95c88bfbf9f7
Date: 2012-06-28 22:17 +0200
http://bitbucket.org/cffi/cffi/changeset/95c88bfbf9f7/

Log:Split this test in two.

diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1140,7 +1140,7 @@
 p.a1 = ['x', 'y']
 assert str(p.a1) == 'xyo'
 
-def test_struct_return_in_func():
+def test_invalid_function_result_types():
 BFunc = new_function_type((), new_void_type())
 BArray = new_array_type(new_pointer_type(BFunc), 5)# works
 new_function_type((), BFunc)# works
@@ -1150,6 +1150,7 @@
(), new_union_type("foo_u"))
 py.test.raises(TypeError, new_function_type, (), BArray)
 
+def test_struct_return_in_func():
 if sys.platform == 'win32':
 py.test.skip("function returning struct")
 BChar = new_primitive_type("char")
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Document function calls, including struct returns (next checkins).

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r561:29ca338c6740
Date: 2012-06-29 10:25 +0200
http://bitbucket.org/cffi/cffi/changeset/29ca338c6740/

Log:Document function calls, including struct returns (next checkins).

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -493,6 +493,50 @@
 it all the time.
 
 
+Function calls
+--
+
+When calling C functions, passing arguments follows mostly the same
+rules as assigning to structure fields, and the return value follows the
+same rules as reading a structure field.  For example::
+
+ffi.cdef("""
+int foo(int a, int b);
+""")
+lib = ffi.verify("#include ")
+
+n = lib.foo(2, 3) # returns a normal integer
+
+As an extension, you can pass to ``char *`` arguments a normal Python
+string (but don't pass a normal Python string to functions that take a
+``char *`` argument and may mutate it!)::
+
+ffi.cdef("""
+size_t strlen(const char *);
+""")
+C = ffi.dlopen(None)
+
+assert C.strlen("hello") == 5
+
+CFFI supports passing and returning structs to functions and callbacks.
+Example (sketch)::
+
+>>> ffi.cdef("""
+... struct foo_s { int a, b; };
+... struct foo_s function_returning_a_struct(void);
+... """)
+>>> lib = ffi.verify("#include ")
+>>> lib.function_returning_a_struct()
+
+
+There are a few "obscure-case" limitations to the argument types and
+return type.  You cannot pass directly as argument a union, nor a struct
+which uses bitfields (note that passing a *pointer* to anything is
+fine).  If you pass a struct, the struct type cannot have been declared
+with "``...;``" and completed with ``verify()``; you need to declare it
+completely in ``cdef()``.
+
+
 Variadic function calls
 ---
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Exception to the no-keepalive rule: add one keepalive for a case

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r560:6b874784716c
Date: 2012-06-29 10:24 +0200
http://bitbucket.org/cffi/cffi/changeset/6b874784716c/

Log:Exception to the no-keepalive rule: add one keepalive for a case
that is occasionally hard to work around.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -41,7 +41,8 @@
 #define CT_PRIMITIVE_FITS_LONG   2048
 #define CT_IS_OPAQUE 4096
 #define CT_IS_ENUM   8192
-#define CT_CUSTOM_FIELD_POS 16384
+#define CT_IS_PTR_TO_OWNED  16384
+#define CT_CUSTOM_FIELD_POS 32768
 #define CT_PRIMITIVE_ANY  (CT_PRIMITIVE_SIGNED |\
CT_PRIMITIVE_UNSIGNED |  \
CT_PRIMITIVE_CHAR |  \
@@ -126,6 +127,11 @@
 } CDataObject_own_length;
 
 typedef struct {
+CDataObject_own_base head;
+PyObject *structobj;
+} CDataObject_own_structptr;
+
+typedef struct {
 ffi_cif cif;
 /* the following information is used when doing the call:
- a buffer of size 'exchange_size' is malloced
@@ -1007,7 +1013,10 @@
 if (cdb->weakreflist != NULL)
 PyObject_ClearWeakRefs((PyObject *) cdb);
 
-if (cdb->head.c_type->ct_flags & CT_FUNCTIONPTR) {
+if (cdb->head.c_type->ct_flags & CT_IS_PTR_TO_OWNED) {
+Py_DECREF(((CDataObject_own_structptr *)cdb)->structobj);
+}
+else if (cdb->head.c_type->ct_flags & CT_FUNCTIONPTR) {
 /* a callback */
 ffi_closure *closure = (ffi_closure *)cdb->head.c_data;
 PyObject *args = (PyObject *)(closure->user_data);
@@ -1275,15 +1284,33 @@
 }
 
 static PyObject *
-cdata_subscript(CDataObject *cd, PyObject *key)
+cdataowning_subscript(CDataObject *cd, PyObject *key)
 {
 char *c = _cdata_get_indexed_ptr(cd, key);
-CTypeDescrObject *ctitem = cd->c_type->ct_itemdescr;
 /* use 'mp_subscript' instead of 'sq_item' because we don't want
negative indexes to be corrected automatically */
 if (c == NULL)
 return NULL;
-return convert_to_object(c, ctitem);
+
+if (cd->c_type->ct_flags & CT_IS_PTR_TO_OWNED) {
+PyObject *res = ((CDataObject_own_structptr *)cd)->structobj;
+Py_INCREF(res);
+return res;
+}
+else {
+return convert_to_object(c, cd->c_type->ct_itemdescr);
+}
+}
+
+static PyObject *
+cdata_subscript(CDataObject *cd, PyObject *key)
+{
+char *c = _cdata_get_indexed_ptr(cd, key);
+/* use 'mp_subscript' instead of 'sq_item' because we don't want
+   negative indexes to be corrected automatically */
+if (c == NULL)
+return NULL;
+return convert_to_object(c, cd->c_type->ct_itemdescr);
 }
 
 static int
@@ -1603,6 +1630,12 @@
 (objobjargproc)cdata_ass_sub, /*mp_ass_subscript*/
 };
 
+static PyMappingMethods CDataOwn_as_mapping = {
+(lenfunc)cdata_length, /*mp_length*/
+(binaryfunc)cdataowning_subscript, /*mp_subscript*/
+(objobjargproc)cdata_ass_sub, /*mp_ass_subscript*/
+};
+
 static PyTypeObject CData_Type = {
 PyVarObject_HEAD_INIT(NULL, 0)
 "_cffi_backend.CData",
@@ -1645,7 +1678,7 @@
 (reprfunc)cdataowning_repr, /* tp_repr */
 0,  /* tp_as_number */
 0,  /* tp_as_sequence */
-0,  /* tp_as_mapping */
+&CDataOwn_as_mapping,   /* tp_as_mapping */
 0,  /* tp_hash */
 0,  /* tp_call */
 0,  /* tp_str */
@@ -1752,6 +1785,7 @@
 static PyObject *b_newp(PyObject *self, PyObject *args)
 {
 CTypeDescrObject *ct, *ctitem;
+CDataObject *cd;
 CDataObject_own_base *cdb;
 PyObject *init = Py_None;
 Py_ssize_t dataoffset, datasize, explicitlength;
@@ -1812,23 +1846,48 @@
 cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
 if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
 return NULL;
-
-Py_INCREF(ct);
-cdb->head.c_type = ct;
+cdb->weakreflist = NULL;
 cdb->head.c_data = ((char *)cdb) + dataoffset;
-cdb->weakreflist = NULL;
 if (explicitlength >= 0)
 ((CDataObject_own_length*)cdb)->length = explicitlength;
 
-memset(cdb->head.c_data, 0, datasize);
-if (init != Py_None) {
-if (convert_from_object(cdb->head.c_data,
-  (ct->ct_flags & CT_POINTER) ? ct->ct_itemdescr : ct, init) < 0) {
+if (ct->ct_flags & CT_IS_PTR_TO_OWNED) {
+/* common case of ptr-to-struct (or ptr-to-union): for this case
+   we build two objects instead of one, with the memory-owning
+   one being really the struct (or union) and the returned one
+   having a strong reference to it */
+CDataObject_own_structptr *cdp;
+
+ctitem = ct->ct_itemdescr;
+Py_INCREF(ctitem);

[pypy-commit] cffi default: hg backout 0ed9b03dd40d, f0cdef5768b5, 95c88bfbf9f7.

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r559:ae0b6ba4b07b
Date: 2012-06-29 09:10 +0200
http://bitbucket.org/cffi/cffi/changeset/ae0b6ba4b07b/

Log:hg backout 0ed9b03dd40d, f0cdef5768b5, 95c88bfbf9f7.

Will redo struct-returning functions slightly differently.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -22,11 +22,6 @@
 # define USE__THREAD
 #endif
 
-/* Define CAN_RETURN_STRUCTS if the C compiler supports returning structs */
-#if !defined(MS_WIN32)
-# define CAN_RETURN_STRUCTS
-#endif
-
 //
 
 /* base type flag: exactly one of the following: */
@@ -1425,9 +1420,6 @@
 return PyObject_GenericSetAttr((PyObject *)cd, attr, value);
 }
 
-static PyObject *
-convert_struct_to_owning_object(char *data, CTypeDescrObject *ct); /*forward*/
-
 static cif_description_t *
 fb_prepare_cif(PyObject *fargs, CTypeDescrObject *fresult);/* forward */
 
@@ -1550,9 +1542,6 @@
 res = Py_None;
 Py_INCREF(res);
 }
-else if (fresult->ct_flags & CT_STRUCT) {
-res = convert_struct_to_owning_object(resultdata, fresult);
-}
 else {
 res = convert_to_object(resultdata, fresult);
 }
@@ -1760,46 +1749,10 @@
 
 //
 
-static CDataObject *allocate_owning_object(Py_ssize_t dataoffset,
-   Py_ssize_t datasize,
-   CTypeDescrObject *ct)
-{
-CDataObject_own_base *cdb;
-cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
-if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
-return NULL;
-
-Py_INCREF(ct);
-cdb->head.c_type = ct;
-cdb->head.c_data = ((char *)cdb) + dataoffset;
-cdb->weakreflist = NULL;
-return &cdb->head;
-}
-
-static PyObject *
-convert_struct_to_owning_object(char *data, CTypeDescrObject *ct)
-{
-CDataObject *cd;
-Py_ssize_t dataoffset = offsetof(CDataObject_own_nolength, alignment);
-Py_ssize_t datasize = ct->ct_size;
-
-if ((ct->ct_flags & (CT_STRUCT|CT_IS_OPAQUE)) != CT_STRUCT) {
-PyErr_SetString(PyExc_TypeError,
-"return type is not a struct or is opaque");
-return NULL;
-}
-cd = allocate_owning_object(dataoffset, datasize, ct);
-if (cd == NULL)
-return NULL;
-
-memcpy(cd->c_data, data, datasize);
-return (PyObject *)cd;
-}
-
 static PyObject *b_newp(PyObject *self, PyObject *args)
 {
 CTypeDescrObject *ct, *ctitem;
-CDataObject *cd;
+CDataObject_own_base *cdb;
 PyObject *init = Py_None;
 Py_ssize_t dataoffset, datasize, explicitlength;
 if (!PyArg_ParseTuple(args, "O!|O:newp", &CTypeDescr_Type, &ct, &init))
@@ -1856,21 +1809,26 @@
 return NULL;
 }
 
-cd = allocate_owning_object(dataoffset, datasize, ct);
-if (cd == NULL)
+cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
+if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
 return NULL;
+
+Py_INCREF(ct);
+cdb->head.c_type = ct;
+cdb->head.c_data = ((char *)cdb) + dataoffset;
+cdb->weakreflist = NULL;
 if (explicitlength >= 0)
-((CDataObject_own_length*)cd)->length = explicitlength;
-
-memset(cd->c_data, 0, datasize);
+((CDataObject_own_length*)cdb)->length = explicitlength;
+
+memset(cdb->head.c_data, 0, datasize);
 if (init != Py_None) {
-if (convert_from_object(cd->c_data,
+if (convert_from_object(cdb->head.c_data,
   (ct->ct_flags & CT_POINTER) ? ct->ct_itemdescr : ct, init) < 0) {
-Py_DECREF(cd);
+Py_DECREF(cdb);
 return NULL;
 }
 }
-return (PyObject *)cd;
+return (PyObject *)cdb;
 }
 
 static CDataObject *_new_casted_primitive(CTypeDescrObject *ct)
@@ -2785,14 +2743,11 @@
 if (PyErr_Occurred())
 return -1;
 if (cif_descr != NULL) {
-#ifndef CAN_RETURN_STRUCTS
 if (fb->rtype->type == FFI_TYPE_STRUCT) {
 PyErr_SetString(PyExc_NotImplementedError,
-"functions returning structs are not supported "
-"on this platform");
+"functions returning structs are not supported");
 return -1;
 }
-#endif
 /* exchange data size */
 /* first, enough room for an array of 'nargs' pointers */
 exchange_offset = nargs * sizeof(void*);
@@ -2990,9 +2945,9 @@
   &ellipsis))
 return NULL;
 
-if (fresult->ct_flags & CT_UNION) {
+if (fresult->ct_flags & (CT_STRUCT|CT_UNION)) {
 PyErr_SetString(PyExc_NotImplementedError,
-"functions returning a union");
+"functions returning a struct or a union");
 return NULL;
 }
 if ((fresult->ct_si

[pypy-commit] cffi default: Add a passing test about callbacks returning structs.

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r563:c3e818533793
Date: 2012-06-29 10:49 +0200
http://bitbucket.org/cffi/cffi/changeset/c3e818533793/

Log:Add a passing test about callbacks returning structs.

diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -878,6 +878,24 @@
 for i, f in enumerate(flist):
 assert f(-142) == -142 + i
 
+def test_callback_returning_struct():
+BSChar = new_primitive_type("signed char")
+BInt = new_primitive_type("int")
+BDouble = new_primitive_type("double")
+BStruct = new_struct_type("foo")
+BStructPtr = new_pointer_type(BStruct)
+complete_struct_or_union(BStruct, [('a', BSChar, -1),
+   ('b', BDouble, -1)])
+def cb(n):
+return newp(BStructPtr, [-n, 1E-42])[0]
+BFunc = new_function_type((BInt,), BStruct)
+f = callback(BFunc, cb)
+s = f(10)
+assert typeof(s) is BStruct
+assert repr(s).startswith("http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Do again struct-returning funcs

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r562:d1ae2e54055d
Date: 2012-06-29 10:42 +0200
http://bitbucket.org/cffi/cffi/changeset/d1ae2e54055d/

Log:Do again struct-returning funcs

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1447,6 +1447,9 @@
 return PyObject_GenericSetAttr((PyObject *)cd, attr, value);
 }
 
+static PyObject *
+convert_struct_to_owning_object(char *data, CTypeDescrObject *ct); /*forward*/
+
 static cif_description_t *
 fb_prepare_cif(PyObject *fargs, CTypeDescrObject *fresult);/* forward */
 
@@ -1569,6 +1572,9 @@
 res = Py_None;
 Py_INCREF(res);
 }
+else if (fresult->ct_flags & CT_STRUCT) {
+res = convert_struct_to_owning_object(resultdata, fresult);
+}
 else {
 res = convert_to_object(resultdata, fresult);
 }
@@ -1782,6 +1788,41 @@
 
 //
 
+static CDataObject_own_base *allocate_owning_object(Py_ssize_t size,
+CTypeDescrObject *ct)
+{
+CDataObject_own_base *cdb;
+cdb = (CDataObject_own_base *)PyObject_Malloc(size);
+if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
+return NULL;
+
+Py_INCREF(ct);
+cdb->head.c_type = ct;
+cdb->weakreflist = NULL;
+return cdb;
+}
+
+static PyObject *
+convert_struct_to_owning_object(char *data, CTypeDescrObject *ct)
+{
+CDataObject_own_base *cdb;
+Py_ssize_t dataoffset = offsetof(CDataObject_own_nolength, alignment);
+Py_ssize_t datasize = ct->ct_size;
+
+if ((ct->ct_flags & (CT_STRUCT|CT_IS_OPAQUE)) != CT_STRUCT) {
+PyErr_SetString(PyExc_TypeError,
+"return type is not a struct or is opaque");
+return NULL;
+}
+cdb = allocate_owning_object(dataoffset + datasize, ct);
+if (cdb == NULL)
+return NULL;
+cdb->head.c_data = ((char *)cdb) + dataoffset;
+
+memcpy(cdb->head.c_data, data, datasize);
+return (PyObject *)cdb;
+}
+
 static PyObject *b_newp(PyObject *self, PyObject *args)
 {
 CTypeDescrObject *ct, *ctitem;
@@ -1843,41 +1884,39 @@
 return NULL;
 }
 
-cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
-if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
-return NULL;
-cdb->weakreflist = NULL;
-cdb->head.c_data = ((char *)cdb) + dataoffset;
-if (explicitlength >= 0)
-((CDataObject_own_length*)cdb)->length = explicitlength;
-
 if (ct->ct_flags & CT_IS_PTR_TO_OWNED) {
 /* common case of ptr-to-struct (or ptr-to-union): for this case
we build two objects instead of one, with the memory-owning
one being really the struct (or union) and the returned one
having a strong reference to it */
-CDataObject_own_structptr *cdp;
-
-ctitem = ct->ct_itemdescr;
-Py_INCREF(ctitem);
-cdb->head.c_type = ctitem;
-
-cdp = (CDataObject_own_structptr *)
-PyObject_Malloc(sizeof(CDataObject_own_structptr));
-if (PyObject_Init((PyObject *)cdp, &CDataOwning_Type) == NULL) {
+CDataObject_own_base *cdp;
+
+cdb = allocate_owning_object(dataoffset + datasize, ct->ct_itemdescr);
+if (cdb == NULL)
+return NULL;
+
+cdp = allocate_owning_object(sizeof(CDataObject_own_structptr), ct);
+if (cdp == NULL) {
 Py_DECREF(cdb);
 return NULL;
 }
-cdp->head.weakreflist = NULL;
-cdp->head.head.c_data = cdb->head.c_data;
-cdp->structobj = (PyObject *)cdb;   /* store away the only reference */
-cd = &cdp->head.head;
+/* store the only reference to cdb into cdp */
+((CDataObject_own_structptr *)cdp)->structobj = (PyObject *)cdb;
+assert(explicitlength < 0);
+
+cdb->head.c_data = cdp->head.c_data = ((char *)cdb) + dataoffset;
+cd = &cdp->head;
 }
 else {
+cdb = allocate_owning_object(dataoffset + datasize, ct);
+if (cdb == NULL)
+return NULL;
+
+cdb->head.c_data = ((char *)cdb) + dataoffset;
+if (explicitlength >= 0)
+((CDataObject_own_length*)cdb)->length = explicitlength;
 cd = &cdb->head;
 }
-Py_INCREF(ct);
-cd->c_type = ct;
 
 memset(cd->c_data, 0, datasize);
 if (init != Py_None) {
@@ -2804,11 +2843,6 @@
 if (PyErr_Occurred())
 return -1;
 if (cif_descr != NULL) {
-if (fb->rtype->type == FFI_TYPE_STRUCT) {
-PyErr_SetString(PyExc_NotImplementedError,
-"functions returning structs are not supported");
-return -1;
-}
 /* exchange data size */
 /* first, enough room for an array of 'nargs' pointers */
 exchange_offset = nargs * sizeof(void*);
@@ -3006,9 +3040,9 @@
   &ellipsis))
   

[pypy-commit] cffi default: Test and implementation (again) for verify().

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r564:a506f1856eb6
Date: 2012-06-29 10:49 +0200
http://bitbucket.org/cffi/cffi/changeset/a506f1856eb6/

Log:Test and implementation (again) for verify().

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3694,6 +3694,7 @@
 _cffi_from_c_char,
 convert_to_object,
 convert_from_object,
+convert_struct_to_owning_object,
 };
 
 //
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -184,6 +184,9 @@
 elif isinstance(tp, model.ArrayType):
 return '_cffi_from_c_deref((char *)%s, _cffi_type(%d))' % (
 var, self.gettypenum(tp))
+elif isinstance(tp, model.StructType):
+return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % (
+var, self.gettypenum(tp))
 else:
 raise NotImplementedError(tp)
 
@@ -614,7 +617,9 @@
 ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16])
 #define _cffi_to_c   \
 ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17])
-#define _CFFI_NUM_EXPORTS 18
+#define _cffi_from_c_struct  \
+((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18])
+#define _CFFI_NUM_EXPORTS 19
 
 #if SIZEOF_LONG < SIZEOF_LONG_LONG
 #  define _cffi_to_c_long_long PyLong_AsLongLong
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -576,3 +576,23 @@
 """)
 msg = 'cannot pass as a argument a struct that was completed with verify()'
 assert msg in str(e.value)
+
+def test_func_returns_struct():
+ffi = FFI()
+ffi.cdef("""
+struct foo_s { int aa, bb; };
+struct foo_s foo(int a, int b);
+""")
+lib = ffi.verify("""
+struct foo_s { int aa, bb; };
+struct foo_s foo(int a, int b) {
+struct foo_s r;
+r.aa = a*a;
+r.bb = b*b;
+return r;
+}
+""")
+s = lib.foo(6, 7)
+assert repr(s) == ""
+assert s.aa == 36
+assert s.bb == 49
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Document "new in version 0.2".

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r565:d3ad38171573
Date: 2012-06-29 10:52 +0200
http://bitbucket.org/cffi/cffi/changeset/d3ad38171573/

Log:Document "new in version 0.2".

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -536,6 +536,9 @@
 with "``...;``" and completed with ``verify()``; you need to declare it
 completely in ``cdef()``.
 
+.. versionadded:: 0.2
+   Aside from these limitations, functions and callbacks can return structs.
+
 
 Variadic function calls
 ---
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Add more tests for struct returns.

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r566:c2e7a851edcb
Date: 2012-06-29 10:58 +0200
http://bitbucket.org/cffi/cffi/changeset/c2e7a851edcb/

Log:Add more tests for struct returns.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3523,6 +3523,33 @@
 return result;
 }
 
+struct _testfunc11_s { int a1, a2; };
+static struct _testfunc11_s _testfunc11(int n)
+{
+struct _testfunc11_s result;
+result.a1 = n;
+result.a2 = n * n;
+return result;
+}
+
+struct _testfunc12_s { double a1; };
+static struct _testfunc12_s _testfunc12(int n)
+{
+struct _testfunc12_s result;
+result.a1 = n;
+return result;
+}
+
+struct _testfunc13_s { int a1, a2, a3; };
+static struct _testfunc13_s _testfunc13(int n)
+{
+struct _testfunc13_s result;
+result.a1 = n;
+result.a2 = n * n;
+result.a3 = n * n * n;
+return result;
+}
+
 static PyObject *b__testfunc(PyObject *self, PyObject *args)
 {
 /* for testing only */
@@ -3542,6 +3569,9 @@
 case 8: f = stderr; break;
 case 9: f = &_testfunc9; break;
 case 10: f = &_testfunc10; break;
+case 11: f = &_testfunc11; break;
+case 12: f = &_testfunc12; break;
+case 13: f = &_testfunc13; break;
 default:
 PyErr_SetNone(PyExc_ValueError);
 return NULL;
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1171,6 +1171,7 @@
 def test_struct_return_in_func():
 BChar = new_primitive_type("char")
 BShort = new_primitive_type("short")
+BDouble = new_primitive_type("double")
 BInt = new_primitive_type("int")
 BStruct = new_struct_type("foo_s")
 complete_struct_or_union(BStruct, [('a1', BChar, -1),
@@ -1181,6 +1182,37 @@
 assert repr(s) == ""
 assert s.a1 == chr(40)
 assert s.a2 == 40 * 40
+#
+BStruct11 = new_struct_type("test11")
+complete_struct_or_union(BStruct11, [('a1', BInt, -1),
+ ('a2', BInt, -1)])
+BFunc11 = new_function_type((BInt,), BStruct11)
+f = cast(BFunc11, _testfunc(11))
+s = f(40)
+assert repr(s) == ""
+assert s.a1 == 40
+assert s.a2 == 40 * 40
+#
+BStruct12 = new_struct_type("test12")
+complete_struct_or_union(BStruct12, [('a1', BDouble, -1),
+ ])
+BFunc12 = new_function_type((BInt,), BStruct12)
+f = cast(BFunc12, _testfunc(12))
+s = f(40)
+assert repr(s) == ""
+assert s.a1 == 40.0
+#
+BStruct13 = new_struct_type("test13")
+complete_struct_or_union(BStruct13, [('a1', BInt, -1),
+ ('a2', BInt, -1),
+ ('a3', BInt, -1)])
+BFunc13 = new_function_type((BInt,), BStruct13)
+f = cast(BFunc13, _testfunc(13))
+s = f(40)
+assert repr(s) == ""
+assert s.a1 == 40
+assert s.a2 == 40 * 40
+assert s.a3 == 40 * 40 * 40
 
 def test_cast_with_functionptr():
 BFunc = new_function_type((), new_void_type())
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: More tests for MSVC's struct return type. Add a workaround similar

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r567:ee603675e7aa
Date: 2012-06-29 11:26 +0200
http://bitbucket.org/cffi/cffi/changeset/ee603675e7aa/

Log:More tests for MSVC's struct return type. Add a workaround similar
to the one present in ctypes.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2747,7 +2747,8 @@
 }
 }
 
-static ffi_type *fb_fill_type(struct funcbuilder_s *fb, CTypeDescrObject *ct)
+static ffi_type *fb_fill_type(struct funcbuilder_s *fb, CTypeDescrObject *ct,
+  int is_result_type)
 {
 if (ct->ct_flags & CT_PRIMITIVE_ANY) {
 return (ffi_type *)ct->ct_extra;
@@ -2785,6 +2786,19 @@
 return NULL;
 }
 
+#ifdef USE_C_LIBFFI_MSVC
+/* MSVC returns small structures in registers.  Pretend int32 or
+   int64 return type.  This is needed as a workaround for what
+   is really a bug of libffi_msvc seen as an independent library
+   (ctypes has a similar workaround). */
+if (is_result_type) {
+if (ct->ct_size <= 4)
+return &ffi_type_sint32;
+if (ct->ct_size <= 8)
+return &ffi_type_sint64;
+}
+#endif
+
 n = PyDict_Size(ct->ct_stuff);
 elements = fb_alloc(fb, (n + 1) * sizeof(ffi_type*));
 cf = (CFieldObject *)ct->ct_extra;
@@ -2796,7 +2810,7 @@
 "cannot pass as argument a struct with bit fields");
 return NULL;
 }
-ffifield = fb_fill_type(fb, cf->cf_type);
+ffifield = fb_fill_type(fb, cf->cf_type, 0);
 if (elements != NULL)
 elements[i] = ffifield;
 cf = cf->cf_next;
@@ -2839,7 +2853,7 @@
 fb->nargs = nargs;
 
 /* ffi buffer: next comes the result type */
-fb->rtype = fb_fill_type(fb, fresult);
+fb->rtype = fb_fill_type(fb, fresult, 1);
 if (PyErr_Occurred())
 return -1;
 if (cif_descr != NULL) {
@@ -2867,7 +2881,7 @@
 
 /* ffi buffer: fill in the ffi for the i'th argument */
 assert(farg != NULL);
-atype = fb_fill_type(fb, farg);
+atype = fb_fill_type(fb, farg, 0);
 if (PyErr_Occurred())
 return -1;
 
@@ -3550,6 +3564,41 @@
 return result;
 }
 
+struct _testfunc14_s { float a1; };
+static struct _testfunc14_s _testfunc14(int n)
+{
+struct _testfunc14_s result;
+result.a1 = (float)n;
+return result;
+}
+
+struct _testfunc15_s { float a1; int a2; };
+static struct _testfunc15_s _testfunc15(int n)
+{
+struct _testfunc15_s result;
+result.a1 = (float)n;
+result.a2 = n * n;
+return result;
+}
+
+struct _testfunc16_s { float a1, a2; };
+static struct _testfunc16_s _testfunc16(int n)
+{
+struct _testfunc16_s result;
+result.a1 = (float)n;
+result.a2 = -(float)n;
+return result;
+}
+
+struct _testfunc17_s { int a1; float a2; };
+static struct _testfunc17_s _testfunc17(int n)
+{
+struct _testfunc17_s result;
+result.a1 = n;
+result.a2 = (float)n * (float)n;
+return result;
+}
+
 static PyObject *b__testfunc(PyObject *self, PyObject *args)
 {
 /* for testing only */
@@ -3572,6 +3621,10 @@
 case 11: f = &_testfunc11; break;
 case 12: f = &_testfunc12; break;
 case 13: f = &_testfunc13; break;
+case 14: f = &_testfunc14; break;
+case 15: f = &_testfunc15; break;
+case 16: f = &_testfunc16; break;
+case 17: f = &_testfunc17; break;
 default:
 PyErr_SetNone(PyExc_ValueError);
 return NULL;
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1171,6 +1171,7 @@
 def test_struct_return_in_func():
 BChar = new_primitive_type("char")
 BShort = new_primitive_type("short")
+BFloat = new_primitive_type("float")
 BDouble = new_primitive_type("double")
 BInt = new_primitive_type("int")
 BStruct = new_struct_type("foo_s")
@@ -1213,6 +1214,45 @@
 assert s.a1 == 40
 assert s.a2 == 40 * 40
 assert s.a3 == 40 * 40 * 40
+#
+BStruct14 = new_struct_type("test14")
+complete_struct_or_union(BStruct14, [('a1', BFloat, -1),
+ ])
+BFunc14 = new_function_type((BInt,), BStruct14)
+f = cast(BFunc14, _testfunc(14))
+s = f(40)
+assert repr(s) == ""
+assert s.a1 == 40.0
+#
+BStruct15 = new_struct_type("test15")
+complete_struct_or_union(BStruct15, [('a1', BFloat, -1),
+ ('a2', BInt, -1)])
+BFunc15 = new_function_type((BInt,), BStruct15)
+f = cast(BFunc15, _testfunc(15))
+s = f(40)
+assert repr(s) == ""
+assert s.a1 == 40.0
+assert s.a2 == 40 * 40
+#
+BStruct16 = new_struct_type("test16")
+complete_struct_or_union(BStruct16, [('a1', BFloat, -1),
+ ('a2', BFloat, -1)])
+BFunc16 = new_function_type((BInt,), BStruct16)
+f = cas

[pypy-commit] pypy default: Merged in ltratt/pypy (pull request #73)

2012-06-29 Thread fijal
Author: Maciej Fijalkowski 
Branch: 
Changeset: r55872:26b81a6d9365
Date: 2012-06-29 12:26 +0200
http://bitbucket.org/pypy/pypy/changeset/26b81a6d9365/

Log:Merged in ltratt/pypy (pull request #73)

diff --git a/pypy/module/select/interp_kqueue.py 
b/pypy/module/select/interp_kqueue.py
--- a/pypy/module/select/interp_kqueue.py
+++ b/pypy/module/select/interp_kqueue.py
@@ -7,6 +7,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+import sys
 
 
 eci = ExternalCompilationInfo(
@@ -20,14 +21,26 @@
 _compilation_info_ = eci
 
 
-CConfig.kevent = rffi_platform.Struct("struct kevent", [
-("ident", rffi.UINTPTR_T),
-("filter", rffi.SHORT),
-("flags", rffi.USHORT),
-("fflags", rffi.UINT),
-("data", rffi.INTPTR_T),
-("udata", rffi.VOIDP),
-])
+if "openbsd" in sys.platform:
+IDENT_UINT = True
+CConfig.kevent = rffi_platform.Struct("struct kevent", [
+("ident", rffi.UINT),
+("filter", rffi.SHORT),
+("flags", rffi.USHORT),
+("fflags", rffi.UINT),
+("data", rffi.INT),
+("udata", rffi.VOIDP),
+])
+else:
+IDENT_UINT = False
+CConfig.kevent = rffi_platform.Struct("struct kevent", [
+("ident", rffi.UINTPTR_T),
+("filter", rffi.SHORT),
+("flags", rffi.USHORT),
+("fflags", rffi.UINT),
+("data", rffi.INTPTR_T),
+("udata", rffi.VOIDP),
+])
 
 
 CConfig.timespec = rffi_platform.Struct("struct timespec", [
@@ -243,16 +256,24 @@
 self.event.c_udata = rffi.cast(rffi.VOIDP, udata)
 
 def _compare_all_fields(self, other, op):
-l_ident = self.event.c_ident
-r_ident = other.event.c_ident
+if IDENT_UINT:
+l_ident = rffi.cast(lltype.Unsigned, self.event.c_ident)
+r_ident = rffi.cast(lltype.Unsigned, other.event.c_ident)
+else:
+l_ident = self.event.c_ident
+r_ident = other.event.c_ident
 l_filter = rffi.cast(lltype.Signed, self.event.c_filter)
 r_filter = rffi.cast(lltype.Signed, other.event.c_filter)
 l_flags = rffi.cast(lltype.Unsigned, self.event.c_flags)
 r_flags = rffi.cast(lltype.Unsigned, other.event.c_flags)
 l_fflags = rffi.cast(lltype.Unsigned, self.event.c_fflags)
 r_fflags = rffi.cast(lltype.Unsigned, other.event.c_fflags)
-l_data = self.event.c_data
-r_data = other.event.c_data
+if IDENT_UINT:
+l_data = rffi.cast(lltype.Signed, self.event.c_data)
+r_data = rffi.cast(lltype.Signed, other.event.c_data)
+else:
+l_data = self.event.c_data
+r_data = other.event.c_data
 l_udata = rffi.cast(lltype.Unsigned, self.event.c_udata)
 r_udata = rffi.cast(lltype.Unsigned, other.event.c_udata)
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Use appropriate types for struct kevent on OpenBSD.

2012-06-29 Thread ltratt
Author: Laurence Tratt 
Branch: 
Changeset: r55871:6942c79aa982
Date: 2012-06-27 12:03 +0100
http://bitbucket.org/pypy/pypy/changeset/6942c79aa982/

Log:Use appropriate types for struct kevent on OpenBSD.

Without this, RPython's type system spots something's wrong and
throws an error; even if it didn't, the resulting C code would
probably have been wrong.

diff --git a/pypy/module/select/interp_kqueue.py 
b/pypy/module/select/interp_kqueue.py
--- a/pypy/module/select/interp_kqueue.py
+++ b/pypy/module/select/interp_kqueue.py
@@ -7,6 +7,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+import sys
 
 
 eci = ExternalCompilationInfo(
@@ -20,14 +21,26 @@
 _compilation_info_ = eci
 
 
-CConfig.kevent = rffi_platform.Struct("struct kevent", [
-("ident", rffi.UINTPTR_T),
-("filter", rffi.SHORT),
-("flags", rffi.USHORT),
-("fflags", rffi.UINT),
-("data", rffi.INTPTR_T),
-("udata", rffi.VOIDP),
-])
+if "openbsd" in sys.platform:
+IDENT_UINT = True
+CConfig.kevent = rffi_platform.Struct("struct kevent", [
+("ident", rffi.UINT),
+("filter", rffi.SHORT),
+("flags", rffi.USHORT),
+("fflags", rffi.UINT),
+("data", rffi.INT),
+("udata", rffi.VOIDP),
+])
+else:
+IDENT_UINT = False
+CConfig.kevent = rffi_platform.Struct("struct kevent", [
+("ident", rffi.UINTPTR_T),
+("filter", rffi.SHORT),
+("flags", rffi.USHORT),
+("fflags", rffi.UINT),
+("data", rffi.INTPTR_T),
+("udata", rffi.VOIDP),
+])
 
 
 CConfig.timespec = rffi_platform.Struct("struct timespec", [
@@ -243,16 +256,24 @@
 self.event.c_udata = rffi.cast(rffi.VOIDP, udata)
 
 def _compare_all_fields(self, other, op):
-l_ident = self.event.c_ident
-r_ident = other.event.c_ident
+if IDENT_UINT:
+l_ident = rffi.cast(lltype.Unsigned, self.event.c_ident)
+r_ident = rffi.cast(lltype.Unsigned, other.event.c_ident)
+else:
+l_ident = self.event.c_ident
+r_ident = other.event.c_ident
 l_filter = rffi.cast(lltype.Signed, self.event.c_filter)
 r_filter = rffi.cast(lltype.Signed, other.event.c_filter)
 l_flags = rffi.cast(lltype.Unsigned, self.event.c_flags)
 r_flags = rffi.cast(lltype.Unsigned, other.event.c_flags)
 l_fflags = rffi.cast(lltype.Unsigned, self.event.c_fflags)
 r_fflags = rffi.cast(lltype.Unsigned, other.event.c_fflags)
-l_data = self.event.c_data
-r_data = other.event.c_data
+if IDENT_UINT:
+l_data = rffi.cast(lltype.Signed, self.event.c_data)
+r_data = rffi.cast(lltype.Signed, other.event.c_data)
+else:
+l_data = self.event.c_data
+r_data = other.event.c_data
 l_udata = rffi.cast(lltype.Unsigned, self.event.c_udata)
 r_udata = rffi.cast(lltype.Unsigned, other.event.c_udata)
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: add license to MANIFEST.in

2012-06-29 Thread fijal
Author: Maciej Fijalkowski 
Branch: 
Changeset: r568:7d9ca9550bd3
Date: 2012-06-29 12:28 +0200
http://bitbucket.org/cffi/cffi/changeset/7d9ca9550bd3/

Log:add license to MANIFEST.in

diff --git a/MANIFEST.in b/MANIFEST.in
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
 recursive-include cffi *.py
 recursive-include c *.c *.h *.asm
 recursive-include testing *.py
-recursive-include doc *.py *.rst Makefile *.bat
+recursive-include doc *.py *.rst Makefile *.bat LICENSE
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Add a test that the version is consistent.

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r569:e96c7e18aecf
Date: 2012-06-29 12:41 +0200
http://bitbucket.org/cffi/cffi/changeset/e96c7e18aecf/

Log:Add a test that the version is consistent.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3815,5 +3815,9 @@
 if (v == NULL || PyModule_AddObject(m, "_C_API", v) < 0)
 return;
 
+v = PyString_FromString("0.2");
+if (v == NULL || PyModule_AddObject(m, "__version__", v) < 0)
+return;
+
 init_errno();
 }
diff --git a/cffi/__init__.py b/cffi/__init__.py
--- a/cffi/__init__.py
+++ b/cffi/__init__.py
@@ -3,3 +3,6 @@
 
 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
+
+__version__ = "0.2"
+__version_info__ = (0, 2)
diff --git a/testing/test_version.py b/testing/test_version.py
new file mode 100644
--- /dev/null
+++ b/testing/test_version.py
@@ -0,0 +1,16 @@
+import os
+import cffi, _cffi_backend
+
+def test_version():
+v = cffi.__version__
+assert v == '%s.%s' % cffi.__version_info__
+assert v == _cffi_backend.__version__
+
+def test_doc_version():
+parent = os.path.dirname(os.path.dirname(__file__))
+p = os.path.join(parent, 'doc', 'source', 'conf.py')
+content = file(p).read()
+#
+v = cffi.__version__
+assert ("version = '%s'\n" % v) in content
+assert ("release = '%s'\n" % v) in content
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Documentation updates

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r570:71f5e672a341
Date: 2012-06-29 16:52 +0200
http://bitbucket.org/cffi/cffi/changeset/71f5e672a341/

Log:Documentation updates

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -242,7 +242,7 @@
   size_t, ssize_t
 
 As we will see on `the verification step`_ below, the declarations can
-also contain "``...``" at various places; there are placeholders that will
+also contain "``...``" at various places; these are placeholders that will
 be completed by a call to ``verify()``.
 
 
@@ -250,11 +250,14 @@
 -
 
 ``ffi.dlopen(libpath)``: this function opens a shared library and
-returns a module-like library object.  You can use the library object to
-call the functions previously declared by ``ffi.cdef()``, and to read or
-write global variables.  Note that you can use a single ``cdef()`` to
-declare functions from multiple libraries, as long as you load each of
-them with ``dlopen()`` and access the functions from the correct one.
+returns a module-like library object.  You need to use *either*
+``ffi.dlopen()`` *or* ``ffi.verify()``, documented below_.
+
+You can use the library object to call the functions previously declared
+by ``ffi.cdef()``, and to read or write global variables.  Note that you
+can use a single ``cdef()`` to declare functions from multiple
+libraries, as long as you load each of them with ``dlopen()`` and access
+the functions from the correct one.
 
 The ``libpath`` is the file name of the shared library, which can
 contain a full path or not (in which case it is searched in standard
@@ -274,6 +277,8 @@
 cannot call functions from a library without linking it in your program,
 as ``dlopen()`` does dynamically in C.
 
+.. _below:
+
 
 The verification step
 -
@@ -281,12 +286,15 @@
 ``ffi.verify(source, **kwargs)``: verifies that the current ffi signatures
 compile on this machine, and return a dynamic library object.  The
 dynamic library can be used to call functions and access global
-variables declared by a previous ``ffi.cdef()``.  The library is compiled
-by the C compiler: it gives you C-level API compatibility (including
-calling macros, as long as you declared them as functions in
-``ffi.cdef()``).  This differs from ``ffi.dlopen()``, which requires
-ABI-level compatibility and must be called several times to open several
-shared libraries.
+variables declared by a previous ``ffi.cdef()``.  You don't need to use
+``ffi.dlopen()`` in this case.
+
+The returned library is a custom one, compiled just-in-time by the C
+compiler: it gives you C-level API compatibility (including calling
+macros, as long as you declared them as functions in ``ffi.cdef()``).
+This differs from ``ffi.dlopen()``, which requires ABI-level
+compatibility and must be called several times to open several shared
+libraries.
 
 On top of CPython, the new library is actually a CPython C extension
 module.  This solution constrains you to have a C compiler (future work
@@ -322,16 +330,19 @@
if you pass a ``int *`` argument to a function expecting a ``long *``.
 
 Moreover, you can use "``...``" in the following places in the ``cdef()``
-for leaving details unspecified (filled in by the C compiler):
+for leaving details unspecified, which are then completed by the C
+compiler during ``verify()``:
 
 *  structure declarations: any ``struct`` that ends with "``...;``" is
-   partial.  It will be completed by the compiler.  (But note that you
-   can only access fields that you declared.)  Any ``struct``
-   declaration without "``...;``" is assumed to be exact, and this is
+   partial: it may be missing fields and/or have them declared out of order.
+   This declaration will be corrected by the compiler.  (But note that you
+   can only access fields that you declared, not others.)  Any ``struct``
+   declaration which doesn't use "``...``" is assumed to be exact, but this is
checked: you get a ``VerificationError`` if it is not.
 
 *  unknown types: the syntax "``typedef ... foo_t;``" declares the type
-   ``foo_t`` as opaque.
+   ``foo_t`` as opaque.  Useful mainly for when the API takes and returns
+   ``foo_t *`` without you needing to looking inside the ``foo_t``.
 
 *  array lengths: when used as structure fields, arrays can have an
unspecified length, as in "``int n[];``".  The length is completed
@@ -356,6 +367,14 @@
to write the ``const`` together with the variable name, as in
``static char *const FOO;``).
 
+Currently, finding automatically the size of an integer type is not
+supported.  You need to declare them with ``typedef int myint;`` or
+``typedef long myint;`` or ``typedef long long myint;`` or their
+unsigned equivalent.  Depending on the usage, the C compiler might give
+warnings if you misdeclare ``myint`` as the wrong type even if it is
+equivalent on this platform (e.g. using ``long`` instead of ``long
+long`` or vice-versa on 64-

[pypy-commit] cffi default: Add MacOS 10.6 instructions.

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r571:f081fe201bd4
Date: 2012-06-29 17:17 +0200
http://bitbucket.org/cffi/cffi/changeset/f081fe201bd4/

Log:Add MacOS 10.6 instructions.

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -71,6 +71,8 @@
 * https://bitbucket.org/cffi/cffi/downloads
 
 * ``python setup.py install`` or ``python setup_base.py install``
+  (should work out of the box on Ubuntu or Windows; see below for
+  `MacOS 10.6`_)
 
 * or you can directly import and use ``cffi``, but if you don't
   compile the ``_cffi_backend`` extension module, it will fall back
@@ -91,6 +93,41 @@
 .. _`testing/test_verify.py`: 
https://bitbucket.org/cffi/cffi/src/default/testing/test_verify.py
 
 
+Platform-specific instructions
+--
+
+``libffi`` is notoriously messy to install and use --- to the point that
+CPython includes its own copy to avoid relying on external packages.
+CFFI did the same for Windows, but (so far) not for other platforms.
+Ubuntu Linux seems to work out of the box.  Here are some
+(user-supplied) instructions for other platforms.
+
+
+MacOS 10.6
+++
+
+(Thanks Juraj Sukop for this)
+
+For building libffi you can use the default install path, but then, in
+``setup.py`` you need to change::
+
+include_dirs = []
+
+to::
+
+include_dirs = ['/usr/local/lib/libffi-3.0.11/include']
+
+Then running ``python setup.py build`` complains about "fatal error: error 
writing to -: Broken pipe", which can be fixed by running::
+
+ARCHFLAGS="-arch i386 -arch x86_64" python setup.py build
+
+as described here_.
+
+.. _here: 
http://superuser.com/questions/259278/python-2-6-1-pycrypto-2-3-pypi-package-broken-pipe-during-build
+
+
+===
+
 Examples
 ===
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Give again the link to the demo directory here.

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r572:70101d453a7f
Date: 2012-06-29 18:09 +0200
http://bitbucket.org/cffi/cffi/changeset/70101d453a7f/

Log:Give again the link to the demo directory here.

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -173,6 +173,9 @@
 ``struct passwd``, but so far require a C compiler at runtime.  (We plan
 to improve with caching and a way to distribute the compiled code.)
 
+You will find a number of larger examples using ``verify()`` in the
+`demo`_ directory.
+
 Struct/Array Example
 
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] extradoc extradoc: Add a note

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: extradoc
Changeset: r4221:45b651669f9c
Date: 2012-06-29 19:43 +0200
http://bitbucket.org/pypy/extradoc/changeset/45b651669f9c/

Log:Add a note

diff --git a/talk/ep2012/stm/talk.rst b/talk/ep2012/stm/talk.rst
--- a/talk/ep2012/stm/talk.rst
+++ b/talk/ep2012/stm/talk.rst
@@ -56,6 +56,8 @@
   moved from 'alpha' to 'beta': it runs e.g. a big part of
   **PyOpenSSL** and **lxml**
 
+* py3k in progress (but 2.7 support never going away)
+
 PyPy organization
 -
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] extradoc extradoc: Add a draft of the first part

2012-06-29 Thread arigo
Author: Armin Rigo 
Branch: extradoc
Changeset: r4222:cba08044f438
Date: 2012-06-29 19:44 +0200
http://bitbucket.org/pypy/extradoc/changeset/cba08044f438/

Log:Add a draft of the first part

diff --git a/talk/ep2012/stm/stm.txt b/talk/ep2012/stm/stm.txt
new file mode 100644
--- /dev/null
+++ b/talk/ep2012/stm/stm.txt
@@ -0,0 +1,113 @@
+
+
+Problem
+---
+
+  Python is slow-ish, by some factor N
+
+  (Python / other lang) ~= N ~= const
+
+  CPU speed used to grow exponentially, but no longer
+
+  one program written in Python runs on one core only
+
+  which means that one program written in Python will in the future run
+  exponentially slower, when compared with "other lang"
+
+  does not matter for all programs... or does it?  think about it this way:
+
+1. my script runs anyway in 0.1 seconds.
+
+   Yes, but what if you were running it on 2002 hardware?  it would take
+   3 seconds.  On 1982 hardware?  One hour.  So if the CPU speed growth
+   stop had occurred in 1982 already, then your script would still take
+   one hour today to run in Python.  (Or half an hour thanks to the
+   continuing hard work of a dedicated core team...)
+
+2. I can use other solutions involving launching multiple processes
+   and exchanging data between them.
+
+   Yes, which is fine.  For some problems it is the "correct"
+   solution (separation for security, etc.).  But for some other
+   problems it doesn't apply or at least not easily.  Imagine a
+   Python without GC.  You can of course handle manually allocating
+   and freeing objects, like in C++.  But you're missing a vast
+   simplification that you get for free in Python.
+
+
+This presentation is not about removing the GIL
+---
+
+pypy-stm is a Python without the GIL, the fourth in this category:
+
+ - Python 1.4 patch by Greg Stein in 1996
+ - Jython
+ - IronPython
+
+Demo pypy-stm
+
+No JIT integration so far, about 4x slower than a JIT-less PyPy
+
+Will talk later about "STM".
+
+Some hardware support (HTM) coming in 2013 (Intel's Haswell CPU),
+which promizes to make it easy to do the same with CPython
+
+So removing the GIL is suddenly around the corner
+
+
+The catch
+-
+
+You have to use threads
+
+
+Threads
+---
+
+Threads are messy to use correctly
+
+Similar to doing explicit memory management: I would like my program to
+figure it automatically, not have to worry about it every single line of
+code.
+
+Debugging a race condition is a nightmare, totally non-reproductible.
+
+
+This presentation is really about this new feature
+--
+
+Demo: pypy-stm using the "transaction" module
+
+Demo how to insert usage of it in pypy/rpython/rtyper.py
+
+
+What you get
+
+
+A fool-proof API that gives multicore usages *without using threads*
+
+Implemented in pypy-stm --- slowly, but who cares? :-)  when you have
+an unlimited supply of cores...  (ok, I agree we care anyway.)
+
+How?  See below.
+
+
+What about CPython?
+---
+
+HTM coming in Intel's Haswell CPU is not going to be enough at all for
+this.  It'll eventually get there, but in how many years?  and how many
+more years before we can assume that every CPU out there has it?
+
+In the meantime there seem to be no move from the CPython core
+developers to try to implement STM.  It would be a major undertaking.
+
+So the future looks to me like: (CPython / other lang) will go down
+exponentially until the point, in 10-20 years, where HTM is good
+enough for CPython.  A "dark age" of CPython...
+
+
+Transactional Memory
+
+
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy kill-import_from_lib_pypy: move config cache recreation code to pypy/tool/lib_pypy

2012-06-29 Thread RonnyPfannschmidt
Author: Ronny Pfannschmidt 
Branch: kill-import_from_lib_pypy
Changeset: r55873:95707b7b2e26
Date: 2012-06-29 21:26 +0200
http://bitbucket.org/pypy/pypy/changeset/95707b7b2e26/

Log:move config cache recreation code to pypy/tool/lib_pypy

diff --git a/lib_pypy/ctypes_config_cache/dumpcache.py 
b/lib_pypy/ctypes_config_cache/dumpcache.py
deleted file mode 100644
--- a/lib_pypy/ctypes_config_cache/dumpcache.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import os
-from ctypes_configure import dumpcache
-from pypy.jit.backend import detect_cpu
-
-def dumpcache2(basename, config):
-model = detect_cpu.autodetect_main_model_and_size()
-filename = '_%s_%s_.py' % (basename, model)
-dumpcache.dumpcache(__file__, filename, config)
-#
-filename = os.path.join(os.path.dirname(__file__),
-'_%s_cache.py' % (basename,))
-g = open(filename, 'w')
-print >> g, '''\
-try:
-from __pypy__ import cpumodel
-except ImportError:
-from pypy.jit.backend import detect_cpu
-cpumodel = detect_cpu.autodetect_main_model_and_size()
-# XXX relative import, should be removed together with
-# XXX the relative imports done e.g. by lib_pypy/pypy_test/test_hashlib
-mod = __import__("_%s_%%s_" %% (cpumodel,),
- globals(), locals(), ["*"])
-globals().update(mod.__dict__)\
-''' % (basename,)
-g.close()
diff --git a/lib_pypy/ctypes_config_cache/rebuild.py 
b/lib_pypy/ctypes_config_cache/rebuild.py
--- a/lib_pypy/ctypes_config_cache/rebuild.py
+++ b/lib_pypy/ctypes_config_cache/rebuild.py
@@ -10,55 +10,7 @@
 autopath_py = os.path.abspath(autopath_py)
 execfile(autopath_py, dict(__name__='autopath', __file__=autopath_py))
 
-import os, sys
-import py
-
-_dirpath = os.path.dirname(__file__) or os.curdir
-
-from pypy.tool.ansi_print import ansi_log
-log = py.log.Producer("ctypes_config_cache")
-py.log.setconsumer("ctypes_config_cache", ansi_log)
-
-
-def rebuild_one(name):
-filename = os.path.join(_dirpath, name)
-d = {'__file__': filename}
-path = sys.path[:]
-try:
-sys.path.insert(0, _dirpath)
-execfile(filename, d)
-finally:
-sys.path[:] = path
-
-def try_rebuild():
-from pypy.jit.backend import detect_cpu
-model = detect_cpu.autodetect_main_model_and_size()
-# remove the files '_*_model_.py'
-left = {}
-for p in os.listdir(_dirpath):
-if p.startswith('_') and (p.endswith('_%s_.py' % model) or
-  p.endswith('_%s_.pyc' % model)):
-os.unlink(os.path.join(_dirpath, p))
-elif p.startswith('_') and (p.endswith('_.py') or
-p.endswith('_.pyc')):
-for i in range(2, len(p)-4):
-left[p[:i]] = True
-# remove the files '_*_cache.py' if there is no '_*_*_.py' left around
-for p in os.listdir(_dirpath):
-if p.startswith('_') and (p.endswith('_cache.py') or
-  p.endswith('_cache.pyc')):
-if p[:-9] not in left:
-os.unlink(os.path.join(_dirpath, p))
-#
-for p in os.listdir(_dirpath):
-if p.endswith('.ctc.py'):
-try:
-rebuild_one(p)
-except Exception, e:
-log.ERROR("Running %s:\n  %s: %s" % (
-os.path.join(_dirpath, p),
-e.__class__.__name__, e))
-
+from pypy.tool.lib_pypy import try_rebuild
 
 if __name__ == '__main__':
 try_rebuild()
diff --git a/pypy/tool/lib_pypy.py b/pypy/tool/lib_pypy.py
--- a/pypy/tool/lib_pypy.py
+++ b/pypy/tool/lib_pypy.py
@@ -1,8 +1,91 @@
+import os
+import sys
+
 import py
 import pypy
 import pypy.module
 from pypy.module.sys.version import CPYTHON_VERSION
 
+from ctypes_configure import dumpcache
+from pypy.jit.backend import detect_cpu
+
+
+from pypy.tool.ansi_print import ansi_log
+log = py.log.Producer("ctypes_config_cache")
+py.log.setconsumer("ctypes_config_cache", ansi_log)
+
+
 LIB_ROOT = py.path.local(pypy.__path__[0]).dirpath()
 LIB_PYPY =  LIB_ROOT.join('lib_pypy')
 LIB_PYTHON = LIB_ROOT.join('lib-python', '%d.%d' % CPYTHON_VERSION[:2])
+
+
+ctypes_cachedir = LIB_PYPY.join('ctypes_config_cache')
+
+
+def dumpcache2(basename, config, sourcefile):
+model = detect_cpu.autodetect_main_model_and_size()
+filename = '_%s_%s_.py' % (basename, model)
+dumpcache.dumpcache(sourcefile, filename, config)
+#
+filename = ctypes_cachedir.join('_%s_cache.py' % (basename))
+filename.write('''\
+try:
+from __pypy__ import cpumodel
+except ImportError:
+from pypy.jit.backend import detect_cpu
+cpumodel = detect_cpu.autodetect_main_model_and_size()
+# XXX relative import, should be removed together with
+# XXX the relative imports done e.g. by lib_pypy/pypy_test/test_hashlib
+mod = __import__("_BASENAME_%s_" % (cpumodel,),
+ globals(), locals(), ["*"])
+globals().update(mod.__dict__)\\
+'''.replace("BASENAME", basename))
+
+
+
+
+
+def rebuild_on

[pypy-commit] pypy kill-import_from_lib_pypy: move the dump writing from the ctypes config cache to tool.lib_pypy

2012-06-29 Thread RonnyPfannschmidt
Author: Ronny Pfannschmidt 
Branch: kill-import_from_lib_pypy
Changeset: r55874:87755db8d523
Date: 2012-06-29 21:34 +0200
http://bitbucket.org/pypy/pypy/changeset/87755db8d523/

Log:move the dump writing from the ctypes config cache to tool.lib_pypy

diff --git a/lib_pypy/ctypes_config_cache/locale.ctc.py 
b/lib_pypy/ctypes_config_cache/locale.ctc.py
--- a/lib_pypy/ctypes_config_cache/locale.ctc.py
+++ b/lib_pypy/ctypes_config_cache/locale.ctc.py
@@ -5,7 +5,6 @@
 
 from ctypes_configure.configure import (configure, ExternalCompilationInfo,
 ConstantInteger, DefinedConstantInteger, SimpleType, check_eci)
-import dumpcache
 
 # 
 
@@ -70,4 +69,3 @@
 
 config['ALL_CONSTANTS'] = tuple(_CONSTANTS)
 config['HAS_LANGINFO'] = HAS_LANGINFO
-dumpcache.dumpcache2('locale', config)
diff --git a/lib_pypy/ctypes_config_cache/resource.ctc.py 
b/lib_pypy/ctypes_config_cache/resource.ctc.py
--- a/lib_pypy/ctypes_config_cache/resource.ctc.py
+++ b/lib_pypy/ctypes_config_cache/resource.ctc.py
@@ -5,7 +5,6 @@
 
 
 from ctypes import sizeof
-import dumpcache
 from ctypes_configure.configure import (configure,
 ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger,
 SimpleType)
@@ -59,4 +58,3 @@
 del config[key]
 
 config['ALL_CONSTANTS'] = _CONSTANTS + tuple(optional_constants)
-dumpcache.dumpcache2('resource', config)
diff --git a/lib_pypy/ctypes_config_cache/syslog.ctc.py 
b/lib_pypy/ctypes_config_cache/syslog.ctc.py
--- a/lib_pypy/ctypes_config_cache/syslog.ctc.py
+++ b/lib_pypy/ctypes_config_cache/syslog.ctc.py
@@ -5,7 +5,6 @@
 
 from ctypes_configure.configure import (configure,
 ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger)
-import dumpcache
 
 
 _CONSTANTS = (
@@ -72,4 +71,3 @@
 all_constants = config.keys()
 all_constants.sort()
 config['ALL_CONSTANTS'] = tuple(all_constants)
-dumpcache.dumpcache2('syslog', config)
diff --git a/pypy/tool/lib_pypy.py b/pypy/tool/lib_pypy.py
--- a/pypy/tool/lib_pypy.py
+++ b/pypy/tool/lib_pypy.py
@@ -1,11 +1,13 @@
 import os
 import sys
+from functools import partial
 
 import py
 import pypy
 import pypy.module
 from pypy.module.sys.version import CPYTHON_VERSION
 
+
 from ctypes_configure import dumpcache
 from pypy.jit.backend import detect_cpu
 
@@ -49,17 +51,12 @@
 def rebuild_one(path):
 filename = str(path)
 d = {'__file__': filename}
-#XXX: hack
-class DumpCache:
-@staticmethod
-def dumpcache2(basename, config):
-dumpcache2(basename, config, filename)
-
-sys.modules['dumpcache'] = DumpCache()
 try:
 execfile(filename, d)
 finally:
-del sys.modules['dumpcache']
+base = path.basename.split('.')[0]
+dumpcache2(base, d['config'], filename)
+
 
 def try_rebuild():
 from pypy.jit.backend import detect_cpu
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit