Commit 7d8d57e9 authored by Armin Rigo's avatar Armin Rigo
Browse files

"from foo.lib import *"

parent f7f3bb71b123
......@@ -378,16 +378,49 @@ static PyObject *lib_build_and_cache_attr(LibObject *lib, PyObject *name,
} \
} while (0)
static PyObject *_lib_dir1(LibObject *lib, int ignore_type)
{
const struct _cffi_global_s *g = lib->l_types_builder->ctx.globals;
int i, count = 0, total = lib->l_types_builder->ctx.num_globals;
PyObject *lst = PyList_New(total);
if (lst == NULL)
return NULL;
for (i = 0; i < total; i++) {
if (_CFFI_GETOP(g[i].type_op) != ignore_type) {
PyObject *s = PyText_FromString(g[i].name);
if (s == NULL)
goto error;
PyList_SET_ITEM(lst, count, s);
count++;
}
}
if (PyList_SetSlice(lst, count, total, NULL) < 0)
goto error;
return lst;
error:
Py_DECREF(lst);
return NULL;
}
static PyObject *lib_getattr(LibObject *lib, PyObject *name)
{
PyObject *x;
LIB_GET_OR_CACHE_ADDR(x, lib, name, return NULL);
LIB_GET_OR_CACHE_ADDR(x, lib, name, goto missing);
if (GlobSupport_Check(x)) {
return read_global_var((GlobSupportObject *)x);
}
Py_INCREF(x);
return x;
missing:
if (strcmp(PyText_AsUTF8(name), "__all__") == 0) {
PyErr_Clear();
return _lib_dir1(lib, _CFFI_OP_GLOBAL_VAR);
}
return NULL;
}
static int lib_setattr(LibObject *lib, PyObject *name, PyObject *val)
......@@ -410,27 +443,13 @@ static int lib_setattr(LibObject *lib, PyObject *name, PyObject *val)
return -1;
}
static PyObject *lib_dir(LibObject *lib, PyObject *noarg)
static PyObject *lib_dir(PyObject *self, PyObject *noarg)
{
const struct _cffi_global_s *g = lib->l_types_builder->ctx.globals;
int i, total = lib->l_types_builder->ctx.num_globals;
PyObject *lst = PyList_New(total);
if (lst == NULL)
return NULL;
for (i = 0; i < total; i++) {
PyObject *s = PyText_FromString(g[i].name);
if (s == NULL) {
Py_DECREF(lst);
return NULL;
}
PyList_SET_ITEM(lst, i, s);
}
return lst;
return _lib_dir1((LibObject *)self, -1);
}
static PyMethodDef lib_methods[] = {
{"__dir__", (PyCFunction)lib_dir, METH_NOARGS},
{"__dir__", lib_dir, METH_NOARGS},
{NULL, NULL} /* sentinel */
};
......
......@@ -1702,12 +1702,18 @@ class TestNewFFI1:
def test_import_from_lib(self):
ffi2 = cffi.FFI()
ffi2.cdef("int myfunc(int);\n#define MYFOO ...\n")
ffi2.cdef("int myfunc(int); int myvar;\n#define MYFOO ...\n")
outputfilename = recompile(ffi2, "_test_import_from_lib",
"int myfunc(int x) { return x + 1; }\n"
"int myvar = -5;\n"
"#define MYFOO 42", tmpdir=str(udir))
imp.load_dynamic("_test_import_from_lib", outputfilename)
from _test_import_from_lib.lib import myfunc, MYFOO
from _test_import_from_lib.lib import myfunc, myvar, MYFOO
assert MYFOO == 42
assert myfunc(43) == 44
assert myvar == -5 # but can't be changed, so not very useful
py.test.raises(ImportError, "from _test_import_from_lib.lib import bar")
d = {}
exec "from _test_import_from_lib.lib import *" in d
assert (set(key for key in d if not key.startswith('_')) ==
set(['myfunc', 'MYFOO']))
......@@ -1043,9 +1043,14 @@ def test_alignment_of_longlong():
def test_import_from_lib():
ffi = FFI()
ffi.cdef("#define MYFOO ...")
lib = verify(ffi, 'test_import_from_lib', "#define MYFOO 42")
ffi.cdef("int mybar(int); int myvar;\n#define MYFOO ...")
lib = verify(ffi, 'test_import_from_lib',
"#define MYFOO 42\n"
"static int mybar(int x) { return x + 1; }\n"
"static int myvar = -5;")
assert sys.modules['_CFFI_test_import_from_lib'].lib is lib
assert sys.modules['_CFFI_test_import_from_lib.lib'] is lib
from _CFFI_test_import_from_lib.lib import MYFOO
assert MYFOO == 42
assert not hasattr(lib, '__dict__')
assert lib.__all__ == ['MYFOO', 'mybar'] # but not 'myvar'
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment