[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