[pypy-commit] cffi cffi-1.0: setting globals; listing globals

arigo noreply at buildbot.pypy.org
Thu Apr 16 09:53:58 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1724:f897a98f6448
Date: 2015-04-16 09:54 +0200
http://bitbucket.org/cffi/cffi/changeset/f897a98f6448/

Log:	setting globals; listing globals

diff --git a/new/cglob.c b/new/cglob.c
--- a/new/cglob.c
+++ b/new/cglob.c
@@ -55,12 +55,12 @@
     return convert_to_object(gs->gs_data, gs->gs_type);
 }
 
-#if 0
 static int write_global_var(GlobSupportObject *gs, PyObject *obj)
 {
     return convert_from_object(gs->gs_data, gs->gs_type, obj);
 }
 
+#if 0
 static PyObject *addressof_global_var(GlobSupportObject *gs)
 {
     return new_simple_cdata(gs->gs_data, gs->gs_type);
diff --git a/new/lib_obj.c b/new/lib_obj.c
--- a/new/lib_obj.c
+++ b/new/lib_obj.c
@@ -139,8 +139,11 @@
 static PyObject *lib_getattr(LibObject *lib, PyObject *name)
 {
     PyObject *x = PyDict_GetItem(lib->l_dict, name);
-    if (x == NULL)
+    if (x == NULL) {
         x = lib_build_and_cache_attr(lib, name);
+        if (x == NULL)
+            return NULL;
+    }
 
     if (GlobSupport_Check(x)) {
         return read_global_var((GlobSupportObject *)x);
@@ -148,21 +151,22 @@
     return x;
 }
 
-#if 0
-static int lib_setattr(ZefLibObject *lib, PyObject *name, PyObject *val)
+static int lib_setattr(LibObject *lib, PyObject *name, PyObject *val)
 {
-    PyObject *x = lib_findattr(lib, name, PyExc_AttributeError);
-    if (x == NULL)
-        return -1;
+    PyObject *x = PyDict_GetItem(lib->l_dict, name);
+    if (x == NULL) {
+        x = lib_build_and_cache_attr(lib, name);
+        if (x == NULL)
+            return -1;
+    }
 
     if (val == NULL) {
-        PyErr_SetString(PyExc_AttributeError,
-                        "cannot delete attributes from Lib object");
+        PyErr_SetString(PyExc_AttributeError, "C attribute cannot be deleted");
         return -1;
     }
 
-    if (ZefGlobSupport_Check(x)) {
-        return write_global_var((ZefGlobSupportObject *)x, val);
+    if (GlobSupport_Check(x)) {
+        return write_global_var((GlobSupportObject *)x, val);
     }
 
     PyErr_Format(PyExc_AttributeError,
@@ -171,16 +175,31 @@
     return -1;
 }
 
-static PyObject *lib_dir(PyObject *lib, PyObject *noarg)
+static PyObject *lib_dir(LibObject *lib, PyObject *noarg)
 {
-    return PyDict_Keys(((ZefLibObject *)lib)->l_dict);
+    const struct _cffi_global_s *g = lib->l_ctx->globals;
+    int total = lib->l_ctx->num_globals;
+
+    PyObject *lst = PyList_New(total);
+    if (lst == NULL)
+        return NULL;
+
+    int i;
+    for (i = 0; i < total; i++) {
+        PyObject *s = PyString_FromString(g[i].name);
+        if (s == NULL) {
+            Py_DECREF(lst);
+            return NULL;
+        }
+        PyList_SET_ITEM(lst, i, s);
+    }
+    return lst;
 }
 
 static PyMethodDef lib_methods[] = {
-    {"__dir__",   lib_dir,  METH_NOARGS},
+    {"__dir__",   (PyCFunction)lib_dir,  METH_NOARGS},
     {NULL,        NULL}           /* sentinel */
 };
-#endif
 
 static PyTypeObject Lib_Type = {
     PyVarObject_HEAD_INIT(NULL, 0)
@@ -200,11 +219,7 @@
     0,                                          /* tp_call */
     0,                                          /* tp_str */
     (getattrofunc)lib_getattr,                  /* tp_getattro */
-#if 0 // XXX
     (setattrofunc)lib_setattr,                  /* tp_setattro */
-#else
-    0,
-#endif
     0,                                          /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT,                         /* tp_flags */
     0,                                          /* tp_doc */
@@ -214,11 +229,7 @@
     0,                                          /* tp_weaklistoffset */
     0,                                          /* tp_iter */
     0,                                          /* tp_iternext */
-#if 0 // XXX
     lib_methods,                                /* tp_methods */
-#else
-    0,
-#endif
     0,                                          /* tp_members */
     0,                                          /* tp_getset */
     0,                                          /* tp_base */
diff --git a/new/recompiler.py b/new/recompiler.py
--- a/new/recompiler.py
+++ b/new/recompiler.py
@@ -1,4 +1,4 @@
-import os
+import os, sys
 from cffi1 import ffiplatform, model
 from cffi_opcode import *
 
@@ -433,6 +433,8 @@
 
 def verify(ffi, module_name, preamble, *args, **kwds):
     import imp
+    assert module_name not in sys.modules, "module name conflict: %r" % (
+        module_name,)
     outputfilename = recompile(ffi, module_name, preamble, *args, **kwds)
     module = imp.load_dynamic(module_name, outputfilename)
     ffi._verified(module.ffi)
diff --git a/new/test_recompiler.py b/new/test_recompiler.py
--- a/new/test_recompiler.py
+++ b/new/test_recompiler.py
@@ -1,3 +1,4 @@
+import py
 from recompiler import Recompiler, verify
 from cffi1 import FFI
 
@@ -79,3 +80,27 @@
     ffi = FFI()
     ffi.cdef("typedef int **foo_t;")
     lib = verify(ffi, 'test_typedef', 'typedef int **foo_t;')
+
+def test_global_var_int():
+    ffi = FFI()
+    ffi.cdef("int a, b;")
+    lib = verify(ffi, 'test_global_var_int', 'int a = 999, b;')
+    assert lib.a == 999
+    lib.a -= 1001
+    assert lib.a == -2
+    lib.a = -2147483648
+    assert lib.a == -2147483648
+    py.test.raises(OverflowError, "lib.a = 2147483648")
+    py.test.raises(OverflowError, "lib.a = -2147483649")
+    lib.b = 525      # try with the first access being in setattr, too
+    assert lib.b == 525
+
+def test_dir():
+    ffi = FFI()
+    ffi.cdef("int ff(int); int aa;")
+    lib = verify(ffi, 'test_dir', """
+        int aa;
+        int ff(int x) { return x+aa; }
+    """)
+    lib.aa = 5
+    assert dir(lib) == ['aa', 'ff']


More information about the pypy-commit mailing list