Skip to content

Commit

Permalink
Remove support for Python 2.7 from C code
Browse files Browse the repository at this point in the history
Most of this is removing code for PY_VERSION_MINOR < 3, removing the
guards for PY_VERSION_MAJOR >= 3, and removing all unnecessary macros
that would now have a single definition (e.g., PyText_Check ->
PyUnicode_Check) in favour of using the direct Python C API for clarity.
Only in minor circumstances some small logic needed to be changed.

Signed-off-by: Rodrigo Tobar <[email protected]>
  • Loading branch information
rtobar committed Dec 29, 2024
1 parent b57a92c commit 88ef0b5
Show file tree
Hide file tree
Showing 17 changed files with 136 additions and 577 deletions.
427 changes: 93 additions & 334 deletions src/c/_cffi_backend.c

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/c/call_python.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static PyObject *_get_interpstate_dict(void)
/* from there on, we know the (sub-)interpreter is still valid */

if (attr_name == NULL) {
attr_name = PyText_InternFromString("__cffi_backend_extern_py");
attr_name = PyUnicode_InternFromString("__cffi_backend_extern_py");
if (attr_name == NULL)
goto error;
}
Expand Down Expand Up @@ -90,7 +90,7 @@ static PyObject *_ffi_def_extern_decorator(PyObject *outer_args, PyObject *fn)
name = PyObject_GetAttrString(fn, "__name__");
if (name == NULL)
return NULL;
s = PyText_AsUTF8(name);
s = PyUnicode_AsUTF8(name);
if (s == NULL) {
Py_DECREF(name);
return NULL;
Expand Down
13 changes: 3 additions & 10 deletions src/c/cdlopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ static void *cdlopen_fetch(PyObject *libname, void *libhandle,

if (libhandle == NULL) {
PyErr_Format(FFIError, "library '%s' has been closed",
PyText_AS_UTF8(libname));
PyUnicode_AsUTF8(libname));
return NULL;
}

Expand All @@ -16,7 +16,7 @@ static void *cdlopen_fetch(PyObject *libname, void *libhandle,
if (address == NULL) {
const char *error = dlerror();
PyErr_Format(FFIError, "symbol '%s' not found in library '%s': %s",
symbol, PyText_AS_UTF8(libname), error);
symbol, PyUnicode_AsUTF8(libname), error);
}
return address;
}
Expand All @@ -32,7 +32,7 @@ static int cdlopen_close(PyObject *libname, void *libhandle)
if (libhandle != NULL && dlclose(libhandle) != 0) {
const char *error = dlerror();
PyErr_Format(FFIError, "closing library '%s': %s",
PyText_AS_UTF8(libname), error);
PyUnicode_AsUTF8(libname), error);
return -1;
}
return 0;
Expand Down Expand Up @@ -195,13 +195,6 @@ static int ffiobj_init(PyObject *self, PyObject *args, PyObject *kwds)
_CFFI_GETOP(nglobs[i].type_op) == _CFFI_OP_ENUM) {
PyObject *o = PyTuple_GET_ITEM(globals, i * 2 + 1);
nglobs[i].address = &_cdl_realize_global_int;
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(o)) {
nintconsts[i].neg = PyInt_AS_LONG(o) <= 0;
nintconsts[i].value = (long long)PyInt_AS_LONG(o);
}
else
#endif
{
nintconsts[i].neg = PyObject_RichCompareBool(o, Py_False,
Py_LE);
Expand Down
8 changes: 1 addition & 7 deletions src/c/cffi1_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static int init_ffi_lib(PyObject *m)
return -1;

for (i = 0; all_dlopen_flags[i].name != NULL; i++) {
x = PyInt_FromLong(all_dlopen_flags[i].value);
x = PyLong_FromLong(all_dlopen_flags[i].value);
if (x == NULL)
return -1;
res = PyDict_SetItemString(FFI_Type.tp_dict,
Expand Down Expand Up @@ -116,7 +116,6 @@ static int make_included_tuples(char *module_name,

static PyObject *_my_Py_InitModule(char *module_name)
{
#if PY_MAJOR_VERSION >= 3
struct PyModuleDef *module_def, local_module_def = {
PyModuleDef_HEAD_INIT,
module_name,
Expand All @@ -131,9 +130,6 @@ static PyObject *_my_Py_InitModule(char *module_name)
return PyErr_NoMemory();
*module_def = local_module_def;
return PyModule_Create(module_def);
#else
return Py_InitModule(module_name, NULL);
#endif
}

static PyObject *b_init_cffi_1_0_external_module(PyObject *self, PyObject *arg)
Expand Down Expand Up @@ -205,12 +201,10 @@ static PyObject *b_init_cffi_1_0_external_module(PyObject *self, PyObject *arg)
(PyObject *)lib) < 0)
return NULL;

#if PY_MAJOR_VERSION >= 3
/* add manually 'module_name' in sys.modules: it seems that
Py_InitModule() is not enough to do that */
if (PyDict_SetItemString(modules_dict, module_name, m) < 0)
return NULL;
#endif

return m;
}
2 changes: 1 addition & 1 deletion src/c/cglob.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static void *fetch_global_var_addr(GlobSupportObject *gs)
}
if (data == NULL) {
PyErr_Format(FFIError, "global variable '%s' is at address NULL",
PyText_AS_UTF8(gs->gs_name));
PyUnicode_AsUTF8(gs->gs_name));
return NULL;
}
return data;
Expand Down
2 changes: 1 addition & 1 deletion src/c/commontypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ static PyObject *b__get_common_types(PyObject *self, PyObject *arg)
size_t i;
for (i = 0; i < num_common_simple_types; i++) {
const char *s = common_simple_types[i];
PyObject *o = PyText_FromString(s + strlen(s) + 1);
PyObject *o = PyUnicode_FromString(s + strlen(s) + 1);
if (o == NULL)
return NULL;
err = PyDict_SetItemString(arg, s, o);
Expand Down
38 changes: 7 additions & 31 deletions src/c/ffi_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,12 @@ static CTypeDescrObject *_ffi_type(FFIObject *ffi, PyObject *arg,
/* Returns the CTypeDescrObject from the user-supplied 'arg'.
Does not return a new reference!
*/
if ((accept & ACCEPT_STRING) && PyText_Check(arg)) {
if ((accept & ACCEPT_STRING) && PyUnicode_Check(arg)) {
PyObject *types_dict = ffi->types_builder.types_dict;
PyObject *x = PyDict_GetItem(types_dict, arg);

if (x == NULL) {
const char *input_text = PyText_AS_UTF8(arg);
const char *input_text = PyUnicode_AsUTF8(arg);
int err, index = parse_c_type(&ffi->info, input_text);
if (index < 0)
return _ffi_bad_type(ffi, input_text);
Expand Down Expand Up @@ -226,17 +226,6 @@ static CTypeDescrObject *_ffi_type(FFIObject *ffi, PyObject *arg,
else if ((accept & ACCEPT_CDATA) && CData_Check(arg)) {
return ((CDataObject *)arg)->c_type;
}
#if PY_MAJOR_VERSION < 3
else if (PyUnicode_Check(arg)) {
CTypeDescrObject *result;
arg = PyUnicode_AsASCIIString(arg);
if (arg == NULL)
return NULL;
result = _ffi_type(ffi, arg, accept);
Py_DECREF(arg);
return result;
}
#endif
else {
const char *m1 = (accept & ACCEPT_STRING) ? "string" : "";
const char *m2 = (accept & ACCEPT_CTYPE) ? "ctype object" : "";
Expand Down Expand Up @@ -272,7 +261,7 @@ static PyObject *ffi_sizeof(FFIObject *self, PyObject *arg)
return NULL;
}
}
return PyInt_FromSsize_t(size);
return PyLong_FromSsize_t(size);
}

PyDoc_STRVAR(ffi_alignof_doc,
Expand All @@ -289,7 +278,7 @@ static PyObject *ffi_alignof(FFIObject *self, PyObject *arg)
align = get_alignment(ct);
if (align < 0)
return NULL;
return PyInt_FromLong(align);
return PyLong_FromLong(align);
}

PyDoc_STRVAR(ffi_typeof_doc,
Expand Down Expand Up @@ -507,7 +496,7 @@ static PyObject *ffi_offsetof(FFIObject *self, PyObject *args)
return NULL;
offset += ofs1;
}
return PyInt_FromSsize_t(offset);
return PyLong_FromSsize_t(offset);
}

PyDoc_STRVAR(ffi_addressof_doc,
Expand Down Expand Up @@ -620,9 +609,7 @@ static PyObject *ffi_getctype(FFIObject *self, PyObject *args, PyObject *kwds)
CTypeDescrObject *ct;
size_t replace_with_len;
static char *keywords[] = {"cdecl", "replace_with", NULL};
#if PY_MAJOR_VERSION >= 3
PyObject *u;
#endif

if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:getctype", keywords,
&c_decl, &replace_with))
Expand Down Expand Up @@ -656,14 +643,12 @@ static PyObject *ffi_getctype(FFIObject *self, PyObject *args, PyObject *kwds)
if (add_paren)
p[replace_with_len] = ')';

#if PY_MAJOR_VERSION >= 3
/* bytes -> unicode string */
u = PyUnicode_DecodeLatin1(PyBytes_AS_STRING(res),
PyBytes_GET_SIZE(res),
NULL);
Py_DECREF(res);
res = u;
#endif

return res;
}
Expand Down Expand Up @@ -912,7 +897,7 @@ static PyObject *ffi_list_types(FFIObject *self, PyObject *noargs)
goto error;

for (i = 0; i < n1; i++) {
o = PyText_FromString(self->types_builder.ctx.typenames[i].name);
o = PyUnicode_FromString(self->types_builder.ctx.typenames[i].name);
if (o == NULL)
goto error;
PyList_SET_ITEM(lst[0], i, o);
Expand All @@ -926,7 +911,7 @@ static PyObject *ffi_list_types(FFIObject *self, PyObject *noargs)
if (s->name[0] == '$')
continue;

o = PyText_FromString(s->name);
o = PyUnicode_FromString(s->name);
if (o == NULL)
goto error;
index = (s->flags & _CFFI_F_UNION) ? 2 : 1;
Expand Down Expand Up @@ -971,22 +956,13 @@ PyDoc_STRVAR(ffi_init_once_doc,
"of function() is done. If function() raises an exception, it is\n"
"propagated and nothing is cached.");

#if PY_MAJOR_VERSION < 3
/* PyCapsule_New is redefined to be PyCObject_FromVoidPtr in _cffi_backend,
which gives 2.6 compatibility; but the destructor signature is different */
static void _free_init_once_lock(void *lock)
{
PyThread_free_lock((PyThread_type_lock)lock);
}
#else
static void _free_init_once_lock(PyObject *capsule)
{
PyThread_type_lock lock;
lock = PyCapsule_GetPointer(capsule, "cffi_init_once_lock");
if (lock != NULL)
PyThread_free_lock(lock);
}
#endif

static PyObject *ffi_init_once(FFIObject *self, PyObject *args, PyObject *kwds)
{
Expand Down
2 changes: 1 addition & 1 deletion src/c/file_emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static FILE *PyFile_AsFile(PyObject *ob_file)
ob_mode = PyObject_GetAttrString(ob_file, "mode");
if (ob_mode == NULL)
goto fail;
mode = PyText_AsUTF8(ob_mode);
mode = PyUnicode_AsUTF8(ob_mode);
if (mode == NULL)
goto fail;

Expand Down
26 changes: 12 additions & 14 deletions src/c/lib_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ static int lib_traverse(LibObject *lib, visitproc visit, void *arg)

static PyObject *lib_repr(LibObject *lib)
{
return PyText_FromFormat("<Lib object for '%.200s'>",
PyText_AS_UTF8(lib->l_libname));
return PyUnicode_FromFormat("<Lib object for '%.200s'>",
PyUnicode_AsUTF8(lib->l_libname));
}

static PyObject *lib_build_cpython_func(LibObject *lib,
Expand All @@ -131,7 +131,7 @@ static PyObject *lib_build_cpython_func(LibObject *lib,
int i, type_index = _CFFI_GETARG(g->type_op);
_cffi_opcode_t *opcodes = lib->l_types_builder->ctx.types;
static const char *const format = ";\n\nCFFI C function from %s.lib";
const char *libname = PyText_AS_UTF8(lib->l_libname);
const char *libname = PyUnicode_AsUTF8(lib->l_libname);
struct funcbuilder_s funcbuilder;

/* return type: */
Expand Down Expand Up @@ -214,7 +214,7 @@ static PyObject *lib_build_and_cache_attr(LibObject *lib, PyObject *name,
const struct _cffi_global_s *g;
CTypeDescrObject *ct;
builder_c_t *types_builder = lib->l_types_builder;
const char *s = PyText_AsUTF8(name);
const char *s = PyUnicode_AsUTF8(name);
if (s == NULL)
return NULL;

Expand Down Expand Up @@ -269,7 +269,7 @@ static PyObject *lib_build_and_cache_attr(LibObject *lib, PyObject *name,
PyErr_Format(PyExc_AttributeError,
"cffi library '%.200s' has no function, constant "
"or global variable named '%.200s'",
PyText_AS_UTF8(lib->l_libname), s);
PyUnicode_AsUTF8(lib->l_libname), s);
return NULL;
}

Expand Down Expand Up @@ -465,7 +465,7 @@ static PyObject *_lib_dir1(LibObject *lib, int ignore_global_vars)
if (op == _CFFI_OP_GLOBAL_VAR || op == _CFFI_OP_GLOBAL_VAR_F)
continue;
}
s = PyText_FromString(g[i].name);
s = PyUnicode_FromString(g[i].name);
if (s == NULL)
goto error;
PyList_SET_ITEM(lst, count, s);
Expand All @@ -489,7 +489,7 @@ static PyObject *_lib_dict(LibObject *lib)
return NULL;

for (i = 0; i < total; i++) {
name = PyText_FromString(g[i].name);
name = PyUnicode_FromString(g[i].name);
if (name == NULL)
goto error;

Expand Down Expand Up @@ -521,7 +521,7 @@ static PyObject *lib_getattr(LibObject *lib, PyObject *name)

missing:
/*** ATTRIBUTEERROR IS SET HERE ***/
p = PyText_AsUTF8(name);
p = PyUnicode_AsUTF8(name);
if (p == NULL)
return NULL;
if (strcmp(p, "__all__") == 0) {
Expand All @@ -545,16 +545,14 @@ static PyObject *lib_getattr(LibObject *lib, PyObject *name)
module-like behavior */
if (strcmp(p, "__name__") == 0) {
PyErr_Clear();
return PyText_FromFormat("%s.lib", PyText_AS_UTF8(lib->l_libname));
return PyUnicode_FromFormat("%s.lib", PyUnicode_AsUTF8(lib->l_libname));
}
#if PY_MAJOR_VERSION >= 3
if (strcmp(p, "__loader__") == 0 || strcmp(p, "__spec__") == 0) {
/* some more module-like behavior hacks */
PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
#endif
return NULL;
}

Expand All @@ -574,7 +572,7 @@ static int lib_setattr(LibObject *lib, PyObject *name, PyObject *val)

PyErr_Format(PyExc_AttributeError,
"cannot write to function or constant '%.200s'",
PyText_Check(name) ? PyText_AS_UTF8(name) : "?");
PyUnicode_Check(name) ? PyUnicode_AsUTF8(name) : "?");
return -1;
}

Expand Down Expand Up @@ -632,7 +630,7 @@ static LibObject *lib_internal_new(FFIObject *ffi, const char *module_name,
LibObject *lib;
PyObject *libname, *dict;

libname = PyText_FromString(module_name);
libname = PyUnicode_FromString(module_name);
if (libname == NULL)
goto err1;

Expand Down Expand Up @@ -699,7 +697,7 @@ static PyObject *address_of_global_var(PyObject *args)

/* rebuild a string from 'varname', to do typechecks and to force
a unicode back to a plain string (on python 2) */
o_varname = PyText_FromString(varname);
o_varname = PyUnicode_FromString(varname);
if (o_varname == NULL)
return NULL;

Expand Down
Loading

0 comments on commit 88ef0b5

Please sign in to comment.