[pypy-commit] cffi cffi-1.0: Tweak tweak tweak: use an initialization sequence on CPython that is closer
arigo
noreply at buildbot.pypy.org
Mon May 11 11:14:49 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1966:897b96412b7a
Date: 2015-05-11 11:15 +0200
http://bitbucket.org/cffi/cffi/changeset/897b96412b7a/
Log: Tweak tweak tweak: use an initialization sequence on CPython that is
closer to the PyPy one. Should make future version checking more
uniform in CPython and PyPy.
diff --git a/_cffi1/_cffi_include.h b/_cffi1/_cffi_include.h
--- a/_cffi1/_cffi_include.h
+++ b/_cffi1/_cffi_include.h
@@ -51,14 +51,6 @@
#ifndef PYPY_VERSION
-#if PY_MAJOR_VERSION < 3
-# undef PyCapsule_CheckExact
-# undef PyCapsule_GetPointer
-# define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
-# define PyCapsule_GetPointer(capsule, name) \
- (PyCObject_AsVoidPtr(capsule))
-#endif
-
#if PY_MAJOR_VERSION >= 3
# define PyInt_FromLong PyLong_FromLong
#endif
@@ -143,10 +135,7 @@
((Py_ssize_t(*)(CTypeDescrObject *, PyObject *, char **))_cffi_exports[23])
#define _cffi_convert_array_from_object \
((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[24])
-#define _cffi_init_module \
- ((PyObject *(*)(char *, const struct _cffi_type_context_s *)) \
- _cffi_exports[25])
-#define _CFFI_NUM_EXPORTS 26
+#define _CFFI_NUM_EXPORTS 25
typedef struct _ctypedescr CTypeDescrObject;
@@ -156,41 +145,37 @@
assert((((uintptr_t)_cffi_types[index]) & 1) == 0), \
(CTypeDescrObject *)_cffi_types[index])
-static int _cffi_init(void)
+static PyObject *_cffi_init(char *module_name, Py_ssize_t version,
+ const struct _cffi_type_context_s *ctx)
{
- PyObject *module, *c_api_object = NULL;
- void *src;
+ PyObject *module, *o_arg, *new_module;
+ void *raw[] = {
+ (void *)module_name,
+ (void *)version,
+ (void *)_cffi_exports,
+ (void *)ctx,
+ };
module = PyImport_ImportModule("_cffi_backend");
if (module == NULL)
goto failure;
- c_api_object = PyObject_GetAttrString(module, "_C_API");
- if (c_api_object == NULL)
+ o_arg = PyLong_FromVoidPtr((void *)raw);
+ if (o_arg == NULL)
goto failure;
- if (!PyCapsule_CheckExact(c_api_object)) {
- PyErr_SetNone(PyExc_ImportError);
- goto failure;
- }
- src = PyCapsule_GetPointer(c_api_object, "cffi");
- if ((uintptr_t)(((void **)src)[0]) < _CFFI_NUM_EXPORTS) {
- PyErr_SetString(PyExc_ImportError,
- "the _cffi_backend module is an outdated version");
- goto failure;
- }
- memcpy(_cffi_exports, src, _CFFI_NUM_EXPORTS * sizeof(void *));
+ new_module = PyObject_CallMethod(
+ module, "_init_cffi_1_0_external_module", "O", o_arg);
+
+ Py_DECREF(o_arg);
Py_DECREF(module);
- Py_DECREF(c_api_object);
- return 0;
+ return new_module;
failure:
Py_XDECREF(module);
- Py_XDECREF(c_api_object);
- return -1;
+ return NULL;
}
-
#endif
/********** end CPython-specific section **********/
diff --git a/_cffi1/cffi1_module.c b/_cffi1/cffi1_module.c
--- a/_cffi1/cffi1_module.c
+++ b/_cffi1/cffi1_module.c
@@ -103,16 +103,9 @@
return -1;
}
-static PyObject *_cffi_init_module(char *module_name,
- const struct _cffi_type_context_s *ctx)
+static PyObject *_my_Py_InitModule(char *module_name)
{
- PyObject *m;
- FFIObject *ffi;
- LibObject *lib;
-
#if PY_MAJOR_VERSION >= 3
- /* note: the module_def leaks, but anyway the C extension module cannot
- be unloaded */
struct PyModuleDef *module_def, local_module_def = {
PyModuleDef_HEAD_INIT,
module_name,
@@ -120,17 +113,57 @@
-1,
NULL, NULL, NULL, NULL, NULL
};
+ /* note: the 'module_def' is allocated dynamically and leaks,
+ but anyway the C extension module can never be unloaded */
module_def = PyMem_Malloc(sizeof(struct PyModuleDef));
if (module_def == NULL)
return PyErr_NoMemory();
*module_def = local_module_def;
- m = PyModule_Create(module_def);
+ return PyModule_Create(module_def);
#else
- m = Py_InitModule(module_name, NULL);
+ return Py_InitModule(module_name, NULL);
#endif
+}
+
+#define CFFI_VERSION_MIN 0x2600
+#define CFFI_VERSION_MAX 0x260F
+
+static PyObject *b_init_cffi_1_0_external_module(PyObject *self, PyObject *arg)
+{
+ PyObject *m;
+ FFIObject *ffi;
+ LibObject *lib;
+ Py_ssize_t version;
+ char *module_name, *exports;
+ void **raw;
+ const struct _cffi_type_context_s *ctx;
+
+ raw = (void **)PyLong_AsVoidPtr(arg);
+ if (raw == NULL)
+ return NULL;
+
+ module_name = (char *)raw[0];
+ version = (Py_ssize_t)raw[1];
+ exports = (char *)raw[2];
+ ctx = (const struct _cffi_type_context_s *)raw[3];
+
+ if (version < CFFI_VERSION_MIN || version > CFFI_VERSION_MAX) {
+ if (!PyErr_Occurred())
+ PyErr_Format(PyExc_ImportError,
+ "cffi extension module '%s' has unknown version %p",
+ module_name, (void *)version);
+ return NULL;
+ }
+
+ /* initialize the exports array */
+ memcpy(exports, (char *)cffi_exports, sizeof(cffi_exports));
+
+ /* make the module object */
+ m = _my_Py_InitModule(module_name);
if (m == NULL)
return NULL;
+ /* build the FFI and Lib object inside this new module */
ffi = ffi_internal_new(&FFI_Type, ctx);
Py_XINCREF(ffi); /* make the ffi object really immortal */
if (ffi == NULL || PyModule_AddObject(m, "ffi", (PyObject *)ffi) < 0)
diff --git a/_cffi1/recompiler.py b/_cffi1/recompiler.py
--- a/_cffi1/recompiler.py
+++ b/_cffi1/recompiler.py
@@ -227,7 +227,7 @@
prnt('};')
prnt()
#
- # the init function, loading _cffi_backend and calling a method there
+ # the init function
base_module_name = self.module_name.split('.')[-1]
prnt('#ifdef PYPY_VERSION')
prnt('PyMODINIT_FUNC')
@@ -251,18 +251,14 @@
prnt('PyMODINIT_FUNC')
prnt('PyInit_%s(void)' % (base_module_name,))
prnt('{')
- prnt(' if (_cffi_init() < 0)')
- prnt(' return NULL;')
- prnt(' return _cffi_init_module("%s", &_cffi_type_context);' % (
+ prnt(' return _cffi_init("%s", 0x2600, &_cffi_type_context);' % (
self.module_name,))
prnt('}')
prnt('#else')
prnt('PyMODINIT_FUNC')
prnt('init%s(void)' % (base_module_name,))
prnt('{')
- prnt(' if (_cffi_init() < 0)')
- prnt(' return;')
- prnt(' _cffi_init_module("%s", &_cffi_type_context);' % (
+ prnt(' _cffi_init("%s", 0x2600, &_cffi_type_context);' % (
self.module_name,))
prnt('}')
prnt('#endif')
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -5763,6 +5763,10 @@
return Py_None;
}
+static PyObject *b_init_cffi_1_0_external_module(PyObject *, PyObject *);
+/* forward, see _cffi1/cffi1_module.c */
+
+
static PyMethodDef FFIBackendMethods[] = {
{"load_library", b_load_library, METH_VARARGS},
{"new_primitive_type", b_new_primitive_type, METH_VARARGS},
@@ -5796,6 +5800,7 @@
{"_get_types", b__get_types, METH_NOARGS},
{"_testfunc", b__testfunc, METH_VARARGS},
{"_testbuff", b__testbuff, METH_VARARGS},
+ {"_init_cffi_1_0_external_module", b_init_cffi_1_0_external_module, METH_O},
{NULL, NULL} /* Sentinel */
};
@@ -5908,10 +5913,8 @@
}
#endif
-#include "../_cffi1/cffi1_module.c"
-
static void *cffi_exports[] = {
- (void *)26,
+ NULL,
_cffi_to_c_i8,
_cffi_to_c_u8,
_cffi_to_c_i16,
@@ -5941,11 +5944,14 @@
_cffi_to_c__Bool,
_prepare_pointer_call_argument,
convert_array_from_object,
- _cffi_init_module,
};
/************************************************************/
+#include "../_cffi1/cffi1_module.c"
+
+/************************************************************/
+
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef FFIBackendModuleDef = {
PyModuleDef_HEAD_INIT,
@@ -6016,11 +6022,12 @@
"__name__", v) < 0)
INITERROR;
+ /* this is for backward compatibility only */
v = PyCapsule_New((void *)cffi_exports, "cffi", NULL);
if (v == NULL || PyModule_AddObject(m, "_C_API", v) < 0)
INITERROR;
- v = PyText_FromString("1.0.0b2");
+ v = PyText_FromString("1.0.0");
if (v == NULL || PyModule_AddObject(m, "__version__", v) < 0)
INITERROR;
diff --git a/cffi/__init__.py b/cffi/__init__.py
--- a/cffi/__init__.py
+++ b/cffi/__init__.py
@@ -4,8 +4,8 @@
from .api import FFI, CDefError, FFIError
from .ffiplatform import VerificationError, VerificationMissing
-__version__ = "1.0.0b2"
-__version_info__ = (1, 0, 0, "beta", 2)
+__version__ = "1.0.0"
+__version_info__ = (1, 0, 0)
# The verifier module file names are based on the CRC32 of a string that
# contains the following version number. It may be older than __version__
More information about the pypy-commit
mailing list