Update to 1.16.0

- Fixes: rhbz#2240695

Upstream has moved to GitHub and this release is no longer tagged on heptapod.

The requirements.txt file is gone, we only need pytest anyway to test this package.
This commit is contained in:
Miro Hrončok 2023-10-02 11:26:28 +02:00
parent 95781d2210
commit f1dfeed52b
10 changed files with 9 additions and 6175 deletions

View File

@ -1,95 +0,0 @@
From 8a3c2c816d789639b49d3ae867213393ed7abdff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
Date: Fri, 15 Jul 2022 16:11:37 +0200
Subject: [PATCH] Adjust tests for a last minute Python 3.11 change in the
traceback format
See https://github.com/python/cpython/issues/93883
and https://github.com/python/cpython/pull/93994
--HG--
branch : python3.11.0b4
---
c/test_c.py | 35 ++---------------------------------
1 file changed, 2 insertions(+), 33 deletions(-)
diff --git a/c/test_c.py b/c/test_c.py
index cde83b80..048711c7 100644
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1342,11 +1342,11 @@ def test_callback_exception():
except ImportError:
import io as cStringIO # Python 3
import linecache
- def matches(istr, ipattern, ipattern38, ipattern311):
+ def matches(istr, ipattern, ipattern38, ipattern311=None):
if sys.version_info >= (3, 8):
ipattern = ipattern38
if sys.version_info >= (3, 11):
- ipattern = ipattern311
+ ipattern = ipattern311 or ipattern38
str, pattern = istr, ipattern
while '$' in pattern:
i = pattern.index('$')
@@ -1400,16 +1400,6 @@ Traceback (most recent call last):
File "$", line $, in check_value
$
ValueError: 42
-""", """\
-Exception ignored from cffi callback <function$Zcb1 at 0x$>:
-Traceback (most recent call last):
- File "$", line $, in Zcb1
- $
- $
- File "$", line $, in check_value
- $
- $
-ValueError: 42
""")
sys.stderr = cStringIO.StringIO()
bigvalue = 20000
@@ -1424,13 +1414,6 @@ Traceback (most recent call last):
File "$", line $, in test_callback_exception
$
OverflowError: integer 60000 does not fit 'short'
-""", """\
-Exception ignored from cffi callback <function$Zcb1 at 0x$>, trying to convert the result back to C:
-Traceback (most recent call last):
- File "$", line $, in test_callback_exception
- $
- $
-OverflowError: integer 60000 does not fit 'short'
""")
sys.stderr = cStringIO.StringIO()
bigvalue = 20000
@@ -1479,19 +1462,6 @@ Traceback (most recent call last):
File "$", line $, in test_callback_exception
$
TypeError: $integer$
-""", """\
-Exception ignored from cffi callback <function$Zcb1 at 0x$>, trying to convert the result back to C:
-Traceback (most recent call last):
- File "$", line $, in test_callback_exception
- $
- $
-OverflowError: integer 60000 does not fit 'short'
-Exception ignored during handling of the above exception by 'onerror':
-Traceback (most recent call last):
- File "$", line $, in test_callback_exception
- $
- $
-TypeError: $integer$
""")
#
sys.stderr = cStringIO.StringIO()
@@ -1526,7 +1496,6 @@ Exception ignored from cffi callback <function$Zcb1 at 0x$>, trying to convert t
Traceback (most recent call last):
File "$", line $, in test_callback_exception
$
- $
OverflowError: integer 60000 does not fit 'short'
Exception ignored during handling of the above exception by 'onerror':
Traceback (most recent call last):
--
GitLab

5414
115.patch

File diff suppressed because it is too large Load Diff

103
116.patch
View File

@ -1,103 +0,0 @@
From 9c7d865e17ec16a847090a3e0d1498b698b99756 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
Date: Mon, 14 Nov 2022 12:30:12 +0100
Subject: [PATCH 1/2] Drop py.code usage from tests, no longer depend on the
deprecated py package
--HG--
branch : py.code
---
README.md | 2 +-
requirements.txt | 1 -
testing/cffi0/test_zintegration.py | 3 ++-
testing/cffi1/test_dlopen_unicode_literals.py | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index b4b84884..d39d88da 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ Testing/development tips
To run tests under CPython, run::
- pip install pytest py # if you don't have pytest and py already
+ pip install pytest # if you don't have pytest already
pip install pycparser
python setup.py build_ext -f -i
pytest c/ testing/
diff --git a/requirements.txt b/requirements.txt
index 881a093f..a97f0282 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,2 @@
pycparser
pytest
-py
diff --git a/testing/cffi0/test_zintegration.py b/testing/cffi0/test_zintegration.py
index d6a02ce0..ca2d4642 100644
--- a/testing/cffi0/test_zintegration.py
+++ b/testing/cffi0/test_zintegration.py
@@ -1,5 +1,6 @@
import py, os, sys, shutil
import subprocess
+import textwrap
from testing.udir import udir
import pytest
@@ -66,7 +67,7 @@ def really_run_setup_and_program(dirname, venv_dir_and_paths, python_snippet):
remove(os.path.join(basedir, '__pycache__'))
olddir = os.getcwd()
python_f = udir.join('x.py')
- python_f.write(py.code.Source(python_snippet))
+ python_f.write(textwrap.dedent(python_snippet))
try:
os.chdir(str(SNIPPET_DIR.join(dirname)))
if os.name == 'nt':
diff --git a/testing/cffi1/test_dlopen_unicode_literals.py b/testing/cffi1/test_dlopen_unicode_literals.py
index e792866e..dc955a57 100644
--- a/testing/cffi1/test_dlopen_unicode_literals.py
+++ b/testing/cffi1/test_dlopen_unicode_literals.py
@@ -1,4 +1,4 @@
-import py, os
+import os
s = """from __future__ import unicode_literals
"""
@@ -6,4 +6,4 @@ s = """from __future__ import unicode_literals
with open(os.path.join(os.path.dirname(__file__), 'test_dlopen.py')) as f:
s += f.read()
-exec(py.code.compile(s))
+exec(compile(s, filename='test_dlopen.py', mode='exec'))
--
GitLab
From 4c1551037965864cfe5494647af014e2390d077c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
Date: Mon, 14 Nov 2022 13:12:31 +0100
Subject: [PATCH 2/2] Make the space count consistent with the past
--HG--
branch : py.code
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index d39d88da..21c82b84 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ Testing/development tips
To run tests under CPython, run::
- pip install pytest # if you don't have pytest already
+ pip install pytest # if you don't have pytest already
pip install pycparser
python setup.py build_ext -f -i
pytest c/ testing/
--
GitLab

View File

@ -1,315 +0,0 @@
From 482f0af7e188755ec50e278ee9862e85aa3bf2fc Mon Sep 17 00:00:00 2001
From: Armin Rigo <arigo@tunes.org>
Date: Thu, 8 Jun 2023 16:14:19 +0200
Subject: [PATCH] Python 3.12 compatibility, step 1
---
cffi/_imp_emulation.py | 83 ++++++++++++++++++++++++++++++++
cffi/vengine_cpy.py | 3 +-
setup.py | 2 +
testing/cffi0/test_verify.py | 3 +-
testing/cffi0/test_zdistutils.py | 7 +--
testing/cffi1/test_new_ffi_1.py | 10 ++--
testing/cffi1/test_verify1.py | 3 +-
testing/cffi1/test_zdist.py | 9 ++--
testing/support.py | 8 +--
9 files changed, 108 insertions(+), 20 deletions(-)
create mode 100644 cffi/_imp_emulation.py
diff --git a/cffi/_imp_emulation.py b/cffi/_imp_emulation.py
new file mode 100644
index 00000000..136abddd
--- /dev/null
+++ b/cffi/_imp_emulation.py
@@ -0,0 +1,83 @@
+
+try:
+ # this works on Python < 3.12
+ from imp import *
+
+except ImportError:
+ # this is a limited emulation for Python >= 3.12.
+ # Note that this is used only for tests or for the old ffi.verify().
+ # This is copied from the source code of Python 3.11.
+
+ from _imp import (acquire_lock, release_lock,
+ is_builtin, is_frozen)
+
+ from importlib._bootstrap import _load
+
+ from importlib import machinery
+ import os
+ import sys
+ import tokenize
+
+ SEARCH_ERROR = 0
+ PY_SOURCE = 1
+ PY_COMPILED = 2
+ C_EXTENSION = 3
+ PY_RESOURCE = 4
+ PKG_DIRECTORY = 5
+ C_BUILTIN = 6
+ PY_FROZEN = 7
+ PY_CODERESOURCE = 8
+ IMP_HOOK = 9
+
+ def get_suffixes():
+ extensions = [(s, 'rb', C_EXTENSION)
+ for s in machinery.EXTENSION_SUFFIXES]
+ source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
+ bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
+ return extensions + source + bytecode
+
+ def find_module(name, path=None):
+ if not isinstance(name, str):
+ raise TypeError("'name' must be a str, not {}".format(type(name)))
+ elif not isinstance(path, (type(None), list)):
+ # Backwards-compatibility
+ raise RuntimeError("'path' must be None or a list, "
+ "not {}".format(type(path)))
+
+ if path is None:
+ if is_builtin(name):
+ return None, None, ('', '', C_BUILTIN)
+ elif is_frozen(name):
+ return None, None, ('', '', PY_FROZEN)
+ else:
+ path = sys.path
+
+ for entry in path:
+ package_directory = os.path.join(entry, name)
+ for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]:
+ package_file_name = '__init__' + suffix
+ file_path = os.path.join(package_directory, package_file_name)
+ if os.path.isfile(file_path):
+ return None, package_directory, ('', '', PKG_DIRECTORY)
+ for suffix, mode, type_ in get_suffixes():
+ file_name = name + suffix
+ file_path = os.path.join(entry, file_name)
+ if os.path.isfile(file_path):
+ break
+ else:
+ continue
+ break # Break out of outer loop when breaking out of inner loop.
+ else:
+ raise ImportError(name, name=name)
+
+ encoding = None
+ if 'b' not in mode:
+ with open(file_path, 'rb') as file:
+ encoding = tokenize.detect_encoding(file.readline)[0]
+ file = open(file_path, mode, encoding=encoding)
+ return file, file_path, (suffix, mode, type_)
+
+ def load_dynamic(name, path, file=None):
+ loader = machinery.ExtensionFileLoader(name, path)
+ spec = machinery.ModuleSpec(name=name, loader=loader, origin=path)
+ return _load(spec)
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
index 6de0df0e..49727d36 100644
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -1,9 +1,10 @@
#
# DEPRECATED: implementation for ffi.verify()
#
-import sys, imp
+import sys
from . import model
from .error import VerificationError
+from . import _imp_emulation as imp
class VCPythonEngine(object):
diff --git a/setup.py b/setup.py
index 7fd8f46d..99ab397e 100644
--- a/setup.py
+++ b/setup.py
@@ -65,6 +65,8 @@ def no_working_compiler_found():
no_compiler_found = True
def get_config():
+ if sys.version_info >= (3, 12):
+ import setuptools # makes 'distutils' available
from distutils.core import Distribution
from distutils.sysconfig import get_config_vars
get_config_vars() # workaround for a bug of distutils, e.g. on OS/X
diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py
index 96d752d7..31fcc6dd 100644
--- a/testing/cffi0/test_verify.py
+++ b/testing/cffi0/test_verify.py
@@ -1575,7 +1575,8 @@ def test_addressof():
def test_callback_in_thread():
if sys.platform == 'win32':
pytest.skip("pthread only")
- import os, subprocess, imp
+ import os, subprocess
+ from cffi import _imp_emulation as imp
arg = os.path.join(os.path.dirname(__file__), 'callback_in_thread.py')
g = subprocess.Popen([sys.executable, arg,
os.path.dirname(imp.find_module('cffi')[1])])
diff --git a/testing/cffi0/test_zdistutils.py b/testing/cffi0/test_zdistutils.py
index 6f46fa82..08c432c7 100644
--- a/testing/cffi0/test_zdistutils.py
+++ b/testing/cffi0/test_zdistutils.py
@@ -1,9 +1,10 @@
-import sys, os, imp, math, shutil
+import sys, os, math, shutil
import pytest
from cffi import FFI, FFIError
from cffi.verifier import Verifier, _locate_engine_class, _get_so_suffixes
from cffi.ffiplatform import maybe_relative_path
from testing.udir import udir
+from testing.support import load_dynamic
class DistUtilsTest(object):
@@ -80,7 +81,7 @@ class DistUtilsTest(object):
v.compile_module()
assert v.get_module_name().startswith('_cffi_')
if v.generates_python_module():
- mod = imp.load_dynamic(v.get_module_name(), v.modulefilename)
+ mod = load_dynamic(v.get_module_name(), v.modulefilename)
assert hasattr(mod, '_cffi_setup')
def test_compile_module_explicit_filename(self):
@@ -95,7 +96,7 @@ class DistUtilsTest(object):
assert filename == v.modulefilename
assert v.get_module_name() == basename
if v.generates_python_module():
- mod = imp.load_dynamic(v.get_module_name(), v.modulefilename)
+ mod = load_dynamic(v.get_module_name(), v.modulefilename)
assert hasattr(mod, '_cffi_setup')
def test_name_from_checksum_of_cdef(self):
diff --git a/testing/cffi1/test_new_ffi_1.py b/testing/cffi1/test_new_ffi_1.py
index c874a362..a461176c 100644
--- a/testing/cffi1/test_new_ffi_1.py
+++ b/testing/cffi1/test_new_ffi_1.py
@@ -1,5 +1,5 @@
import pytest
-import platform, imp
+import platform
import sys, os, ctypes
import cffi
from testing.udir import udir
@@ -91,7 +91,7 @@ def setup_module():
outputfilename = recompile(ffi1, "test_new_ffi_1", CCODE,
tmpdir=str(udir))
- module = imp.load_dynamic("test_new_ffi_1", outputfilename)
+ module = load_dynamic("test_new_ffi_1", outputfilename)
ffi = module.ffi
construction_params = (ffi1, CCODE)
@@ -1619,7 +1619,7 @@ class TestNewFFI1:
ffi2 = cffi.FFI(); ffi2.cdef(CDEF2)
outputfilename = recompile(ffi2, "test_multiple_independent_structs",
CDEF2, tmpdir=str(udir))
- module = imp.load_dynamic("test_multiple_independent_structs",
+ module = load_dynamic("test_multiple_independent_structs",
outputfilename)
ffi1 = module.ffi
foo1 = ffi1.new("struct ab *", [10])
@@ -1635,7 +1635,7 @@ class TestNewFFI1:
outputfilename = recompile(ffi2,
"test_include_struct_union_enum_typedef",
CCODE, tmpdir=str(udir))
- module = imp.load_dynamic("test_include_struct_union_enum_typedef",
+ module = load_dynamic("test_include_struct_union_enum_typedef",
outputfilename)
ffi2 = module.ffi
#
@@ -1783,7 +1783,7 @@ class TestNewFFI1:
"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)
+ load_dynamic("_test_import_from_lib", outputfilename)
from _test_import_from_lib.lib import myfunc, myvar, MYFOO
assert MYFOO == 42
assert myfunc(43) == 44
diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py
index 6245281b..f1a5fa14 100644
--- a/testing/cffi1/test_verify1.py
+++ b/testing/cffi1/test_verify1.py
@@ -1535,7 +1535,8 @@ def test_callback_in_thread():
pytest.xfail("adapt or remove")
if sys.platform == 'win32':
pytest.skip("pthread only")
- import os, subprocess, imp
+ import os, subprocess
+ from cffi import _imp_emulation as imp
arg = os.path.join(os.path.dirname(__file__), 'callback_in_thread.py')
g = subprocess.Popen([sys.executable, arg,
os.path.dirname(imp.find_module('cffi')[1])])
diff --git a/testing/cffi1/test_zdist.py b/testing/cffi1/test_zdist.py
index 58d5bc8d..b1013da1 100644
--- a/testing/cffi1/test_zdist.py
+++ b/testing/cffi1/test_zdist.py
@@ -41,11 +41,10 @@ class TestDist(object):
tmp_home = mkdtemp()
assert tmp_home != None, "cannot create temporary homedir"
env['HOME'] = tmp_home
+ pathlist = sys.path[:]
if cwd is None:
- newpath = self.rootdir
- if 'PYTHONPATH' in env:
- newpath += os.pathsep + env['PYTHONPATH']
- env['PYTHONPATH'] = newpath
+ pathlist.insert(0, self.rootdir)
+ env['PYTHONPATH'] = os.pathsep.join(pathlist)
try:
subprocess.check_call([self.executable] + args, cwd=cwd, env=env)
finally:
@@ -291,7 +290,7 @@ class TestDist(object):
f.write("""if 1:
# https://bugs.python.org/issue23246
import sys
- if sys.platform == 'win32':
+ if sys.platform == 'win32' or sys.version_info >= (3, 12):
try:
import setuptools
except ImportError:
diff --git a/testing/support.py b/testing/support.py
index f0677194..666c351b 100644
--- a/testing/support.py
+++ b/testing/support.py
@@ -1,7 +1,8 @@
import sys, os
+from cffi._imp_emulation import load_dynamic
if sys.version_info < (3,):
- __all__ = ['u', 'arraytostring']
+ __all__ = ['u', 'arraytostring', 'load_dynamic']
class U(object):
def __add__(self, other):
@@ -16,7 +17,7 @@ if sys.version_info < (3,):
return a.tostring()
else:
- __all__ = ['u', 'unicode', 'long', 'arraytostring']
+ __all__ = ['u', 'unicode', 'long', 'arraytostring', 'load_dynamic']
u = ""
unicode = str
long = int
@@ -72,14 +73,13 @@ class FdWriteCapture(object):
return self._value
def _verify(ffi, module_name, preamble, *args, **kwds):
- import imp
from cffi.recompiler import recompile
from .udir import udir
assert module_name not in sys.modules, "module name conflict: %r" % (
module_name,)
kwds.setdefault('tmpdir', str(udir))
outputfilename = recompile(ffi, module_name, preamble, *args, **kwds)
- module = imp.load_dynamic(module_name, outputfilename)
+ module = load_dynamic(module_name, outputfilename)
#
# hack hack hack: copy all *bound methods* from module.ffi back to the
# ffi instance. Then calls like ffi.new() will invoke module.ffi.new().
--
GitLab

View File

@ -1,25 +0,0 @@
From 69660bdf6544338edd524b73004b7accfa464c68 Mon Sep 17 00:00:00 2001
From: Armin Rigo <arigo@tunes.org>
Date: Thu, 8 Jun 2023 19:02:08 +0200
Subject: [PATCH] gah
---
c/misc_thread_common.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/c/misc_thread_common.h b/c/misc_thread_common.h
index 9e9a818d..ead9c83c 100644
--- a/c/misc_thread_common.h
+++ b/c/misc_thread_common.h
@@ -166,7 +166,7 @@ thread_canary_free_zombies(void)
break;
PyThreadState_Clear(tstate); /* calls thread_canary_dealloc on 'ob',
but now ob->zombie_next == NULL. */
-#if PY_HEX_VERSION >= 0x030C0000
+#if PY_VERSION_HEX >= 0x030C0000
/* this might be a bug introduced in 3.12, or just me abusing the
API around there. The issue is that PyThreadState_Delete()
called on a random old tstate will clear the *current* thread
--
GitLab

View File

@ -1,45 +0,0 @@
From 814c55ebf46da49cdb0733756b9568486c682d03 Mon Sep 17 00:00:00 2001
From: Armin Rigo <arigo@tunes.org>
Date: Thu, 8 Jun 2023 19:18:37 +0200
Subject: [PATCH] fix for multiple embedded modules loaded in parallel from
multiple threads
---
cffi/_embedding.h | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/cffi/_embedding.h b/cffi/_embedding.h
index 265630ea..c5eaf889 100644
--- a/cffi/_embedding.h
+++ b/cffi/_embedding.h
@@ -321,10 +321,11 @@ static int _cffi_carefully_make_gil(void)
int old_value, locked_value = -42;
assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG));
# else
- static PyBufferProcs empty_buffer_procs;
+ static struct ebp_s { PyBufferProcs buf; int mark; } empty_buffer_procs;
+ empty_buffer_procs.mark = -42;
PyBufferProcs *volatile *lock = (PyBufferProcs *volatile *)
&PyCapsule_Type.tp_as_buffer;
- PyBufferProcs *old_value, *locked_value = &empty_buffer_procs;
+ PyBufferProcs *old_value, *locked_value = &empty_buffer_procs.buf;
# endif
while (1) { /* spin loop */
@@ -334,7 +335,13 @@ static int _cffi_carefully_make_gil(void)
break;
}
else {
+# if PY_VERSION_HEX < 0x030C0000
assert(old_value == locked_value);
+# else
+ /* The pointer should point to a possibly different
+ empty_buffer_procs from another C extension module */
+ assert(((struct ebp_s *)old_value)->mark == -42);
+# endif
/* 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
--
GitLab

View File

@ -1,103 +0,0 @@
From 87f514b8a4fc6b29df8febf1176ad846007a5b56 Mon Sep 17 00:00:00 2001
From: Armin Rigo <arigo@tunes.org>
Date: Thu, 8 Jun 2023 18:34:20 +0200
Subject: [PATCH] Fix for what may be a CPython 3.12 bug, or just me abusing
the API
---
c/misc_thread_common.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/c/misc_thread_common.h b/c/misc_thread_common.h
index 66e28354..9e9a818d 100644
--- a/c/misc_thread_common.h
+++ b/c/misc_thread_common.h
@@ -102,6 +102,7 @@ thread_canary_dealloc(ThreadCanaryObj *ob)
'local_thread_canary' accesses need to be protected with
the TLS_ZOM_LOCK.
*/
+ //fprintf(stderr, "entering dealloc(%p)\n", ob);
TLS_ZOM_LOCK();
if (ob->zombie_next != NULL) {
//fprintf(stderr, "thread_canary_dealloc(%p): ZOMBIE\n", ob);
@@ -136,6 +137,7 @@ thread_canary_make_zombie(ThreadCanaryObj *ob)
ob->zombie_prev = last;
last->zombie_next = ob;
cffi_zombie_head.zombie_prev = ob;
+ //fprintf(stderr, "thread_canary_make_zombie(%p) DONE\n", ob);
}
static void
@@ -164,6 +166,15 @@ thread_canary_free_zombies(void)
break;
PyThreadState_Clear(tstate); /* calls thread_canary_dealloc on 'ob',
but now ob->zombie_next == NULL. */
+#if PY_HEX_VERSION >= 0x030C0000
+ /* this might be a bug introduced in 3.12, or just me abusing the
+ API around there. The issue is that PyThreadState_Delete()
+ called on a random old tstate will clear the *current* thread
+ notion of what PyGILState_GetThisThreadState() should be, at
+ least if the internal 'bound_gilstate' flag is set in the old
+ tstate. Workaround: clear that flag. */
+ tstate->_status.bound_gilstate = 0;
+#endif
PyThreadState_Delete(tstate);
//fprintf(stderr, "thread_canary_free_zombie: cleared and deleted tstate=%p\n", tstate);
}
@@ -213,9 +224,11 @@ thread_canary_register(PyThreadState *tstate)
tstate->gilstate_counter++;
/* ^^^ this means 'tstate' will never be automatically freed by
PyGILState_Release() */
+ //fprintf(stderr, "CANARY: ready, tstate=%p, tls=%p, canary=%p\n", tstate, tls, canary);
return;
ignore_error:
+ //fprintf(stderr, "CANARY: IGNORED ERROR\n");
PyErr_Clear();
}
@@ -334,6 +347,7 @@ static PyGILState_STATE gil_ensure(void)
*/
PyGILState_STATE result;
PyThreadState *ts = PyGILState_GetThisThreadState();
+ //fprintf(stderr, "%p: gil_ensure(), tstate=%p, tls=%p\n", get_cffi_tls(), ts, get_cffi_tls());
if (ts != NULL) {
ts->gilstate_counter++;
@@ -341,9 +355,11 @@ static PyGILState_STATE gil_ensure(void)
/* common case: 'ts' is our non-current thread state and
we have to make it current and acquire the GIL */
PyEval_RestoreThread(ts);
+ //fprintf(stderr, "%p: gil_ensure(), tstate=%p MADE CURRENT\n", get_cffi_tls(), ts);
return PyGILState_UNLOCKED;
}
else {
+ //fprintf(stderr, "%p: gil_ensure(), tstate=%p ALREADY CURRENT\n", get_cffi_tls(), ts);
return PyGILState_LOCKED;
}
}
@@ -353,6 +369,7 @@ static PyGILState_STATE gil_ensure(void)
assert(result == PyGILState_UNLOCKED);
ts = PyGILState_GetThisThreadState();
+ //fprintf(stderr, "%p: gil_ensure(), made a new tstate=%p\n", get_cffi_tls(), ts);
assert(ts != NULL);
assert(ts == get_current_ts());
assert(ts->gilstate_counter >= 1);
@@ -361,11 +378,13 @@ static PyGILState_STATE gil_ensure(void)
thread really shuts down */
thread_canary_register(ts);
+ assert(ts == PyGILState_GetThisThreadState());
return result;
}
}
static void gil_release(PyGILState_STATE oldstate)
{
+ //fprintf(stderr, "%p: gil_release(%d), tls=%p\n", get_cffi_tls(), (int)oldstate, get_cffi_tls());
PyGILState_Release(oldstate);
}
--
GitLab

View File

@ -1,54 +0,0 @@
From c3593e41b9aaf8d8bfce2c97fa6bfbd8a54e8974 Mon Sep 17 00:00:00 2001
From: Armin Rigo <arigo@tunes.org>
Date: Thu, 8 Jun 2023 16:57:32 +0200
Subject: [PATCH] step 2: partially fix embedding for 3.12
---
cffi/_embedding.h | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/cffi/_embedding.h b/cffi/_embedding.h
index 8e8df882..265630ea 100644
--- a/cffi/_embedding.h
+++ b/cffi/_embedding.h
@@ -283,6 +283,15 @@ static int _cffi_carefully_make_gil(void)
Python < 3.8 because someone might use a mixture of cffi
embedded modules, some of which were compiled before this file
changed.
+
+ In Python >= 3.12, this stopped working because that particular
+ tp_version_tag gets modified during interpreter startup. It's
+ arguably a bad idea before 3.12 too, but again we can't change
+ that because someone might use a mixture of cffi embedded
+ modules, and no-one reported a bug so far. In Python >= 3.12
+ we go instead for PyCapsuleType.tp_as_buffer, which is supposed
+ to always be NULL. We write to it temporarily a pointer to
+ a struct full of NULLs, which is semantically the same.
*/
#ifdef WITH_THREAD
@@ -307,13 +316,19 @@ static int _cffi_carefully_make_gil(void)
}
}
# else
+# if PY_VERSION_HEX < 0x030C0000
int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag;
- int old_value, locked_value;
+ int old_value, locked_value = -42;
assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG));
+# else
+ static PyBufferProcs empty_buffer_procs;
+ PyBufferProcs *volatile *lock = (PyBufferProcs *volatile *)
+ &PyCapsule_Type.tp_as_buffer;
+ PyBufferProcs *old_value, *locked_value = &empty_buffer_procs;
+# endif
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;
--
GitLab

View File

@ -1,27 +1,15 @@
Name: python-cffi
Version: 1.15.1
Version: 1.16.0
Release: %autorelease
Summary: Foreign Function Interface for Python to call C code
# Patch 482f0af has bits copied from CPython (PSF-2.0)
# cffi is MIT
# cffi/_imp_emulation.py has bits copied from CPython (PSF-2.0)
License: MIT AND PSF-2.0
URL: https://cffi.readthedocs.org/
Source: https://foss.heptapod.net/pypy/cffi/-/archive/v%{version}/cffi-v%{version}.tar.bz2
# Adjust tests for a last minute Python 3.11 change in the traceback format
Patch: https://foss.heptapod.net/pypy/cffi/-/merge_requests/113.patch
# Drop usage of the deprecated py.test package
Patch: https://foss.heptapod.net/pypy/cffi/-/merge_requests/115.patch
# Drop usage of the deprecated py.code package
Patch: https://foss.heptapod.net/pypy/cffi/-/merge_requests/116.patch
# Python 3.12 compatibility
Patch: https://foss.heptapod.net/pypy/cffi/-/commit/482f0af.patch
Patch: https://foss.heptapod.net/pypy/cffi/-/commit/c3593e4.patch
Patch: https://foss.heptapod.net/pypy/cffi/-/commit/87f514b.patch
Patch: https://foss.heptapod.net/pypy/cffi/-/commit/69660bd.patch
Patch: https://foss.heptapod.net/pypy/cffi/-/commit/814c55e.patch
URL: https://github.com/python-cffi/cffi
Source: %{url}/archive/v%{version}/cffi-%{version}.tar.gz
BuildRequires: python3-devel
BuildRequires: python3-pytest
BuildRequires: make
BuildRequires: libffi-devel
BuildRequires: gcc
@ -54,11 +42,11 @@ Documentation for CFFI, the Foreign Function Interface for Python.
%prep
%autosetup -p1 -n cffi-v%{version}
%autosetup -p1 -n cffi-%{version}
%generate_buildrequires
%pyproject_buildrequires requirements.txt
%pyproject_buildrequires
%build

View File

@ -1 +1 @@
SHA512 (cffi-v1.15.1.tar.bz2) = 4505c1e3206b66fbdf06ba39be6daac14a35f7148cef3156bb2015792cb59c004ea13fe7c7514feb35ecc5e7526a88fc0b3036ae84fd146a0a3b55bc676e8e51
SHA512 (cffi-1.16.0.tar.gz) = 2115f4d2431f36b18494182d2abb378a750c970dfdf083cfc287b004e52830efe703f07f71a17c89060b47eaa3b52e7b2390017d1980eb39695bdaf31bac3bb5