diff --git a/cffi-python38.patch b/cffi-python38.patch new file mode 100644 index 0000000..fd4df59 --- /dev/null +++ b/cffi-python38.patch @@ -0,0 +1,136 @@ +# HG changeset patch +# User Armin Rigo +# Date 1552719624 -3600 +# Node ID 272b53198be984719f29748f998504d1e0634e21 +# Parent ff25b4e68195de3034253a1b35e096f8b616aa73 +py3.8 fixes + +diff --git a/cffi/_embedding.h b/cffi/_embedding.h +--- a/cffi/_embedding.h ++++ b/cffi/_embedding.h +@@ -169,8 +169,10 @@ + global_dict = PyDict_New(); + if (global_dict == NULL) + goto error; +- if (PyDict_SetItemString(global_dict, "__builtins__", +- PyThreadState_GET()->interp->builtins) < 0) ++ PyObject *builtins = PyEval_GetBuiltins(); ++ if (builtins == NULL) ++ goto error; ++ if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) + goto error; + x = PyEval_EvalCode( + #if PY_MAJOR_VERSION < 3 +@@ -263,23 +265,33 @@ + So we use a global variable as a simple spin lock. This global + variable must be from 'libpythonX.Y.so', not from this + cffi-based extension module, because it must be shared from +- different cffi-based extension modules. We choose ++ different cffi-based extension modules. ++ ++ In Python < 3.8, we choose + _PyParser_TokenNames[0] as a completely arbitrary pointer value + that is never written to. The default is to point to the + string "ENDMARKER". We change it temporarily to point to the + next character in that string. (Yes, I know it's REALLY + obscure.) ++ ++ In Python >= 3.8, this string array is no longer writable, so ++ instead we pick PyCapsuleType.tp_version_tag. We can't change ++ Python < 3.8 because someone might use a mixture of cffi ++ embedded modules, some of which were compiled before this file ++ changed. + */ + + #ifdef WITH_THREAD ++# if PY_VERSION_HEX < 0x03080000 + char *volatile *lock = (char *volatile *)_PyParser_TokenNames; +- char *old_value; ++ char *old_value, *locked_value; + + while (1) { /* spin loop */ + old_value = *lock; ++ locked_value = old_value + 1; + if (old_value[0] == 'E') { + assert(old_value[1] == 'N'); +- if (cffi_compare_and_swap(lock, old_value, old_value + 1)) ++ if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { +@@ -290,6 +302,27 @@ + this is only run at start-up anyway. */ + } + } ++# else ++ int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; ++ int old_value, locked_value; ++ assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); ++ ++ while (1) { /* spin loop */ ++ old_value = *lock; ++ locked_value = -42; ++ if (old_value == 0) { ++ if (cffi_compare_and_swap(lock, old_value, locked_value)) ++ break; ++ } ++ else { ++ assert(old_value == locked_value); ++ /* should ideally do a spin loop instruction here, but ++ hard to do it portably and doesn't really matter I ++ think: PyEval_InitThreads() should be very fast, and ++ this is only run at start-up anyway. */ ++ } ++ } ++# endif + #endif + + /* call Py_InitializeEx() */ +@@ -306,7 +339,7 @@ + + #ifdef WITH_THREAD + /* release the lock */ +- while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) ++ while (!cffi_compare_and_swap(lock, locked_value, old_value)) + ; + #endif + +diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py +--- a/testing/cffi0/test_verify.py ++++ b/testing/cffi0/test_verify.py +@@ -20,7 +20,8 @@ + extra_compile_args.append('-Qunused-arguments') + else: + # assume a standard gcc +- extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] ++ extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', ++ '-Wno-unused-parameter'] + + class FFI(FFI): + def verify(self, *args, **kwds): +diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py +--- a/testing/cffi1/test_verify1.py ++++ b/testing/cffi1/test_verify1.py +@@ -22,7 +22,8 @@ + extra_compile_args.append('-Qunused-arguments') + else: + # assume a standard gcc +- extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] ++ extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', ++ '-Wno-unused-parameter'] + + class FFI(FFI): + error = _cffi_backend.FFI.error +diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py +--- a/testing/embedding/test_basic.py ++++ b/testing/embedding/test_basic.py +@@ -172,7 +172,8 @@ + result = popen.stdout.read() + err = popen.wait() + if err: +- raise OSError("%r failed with exit code %r" % (name, err)) ++ raise OSError("%r failed with exit code %r" % ( ++ os.path.join(path, executable_name), err)) + return result + + diff --git a/python-cffi.spec b/python-cffi.spec index 6b94973..da8700e 100644 --- a/python-cffi.spec +++ b/python-cffi.spec @@ -6,6 +6,9 @@ License: MIT URL: https://cffi.readthedocs.org/ Source0: %{pypi_source cffi} +# https://bugzilla.redhat.com/show_bug.cgi?id=1693617 +Patch0: cffi-python38.patch + BuildRequires: libffi-devel BuildRequires: gcc @@ -58,7 +61,7 @@ BuildArch: noarch Documentation for CFFI, the Foreign Function Interface for Python. %prep -%autosetup -n cffi-%{version} +%autosetup -p1 -n cffi-%{version} %build %py2_build