Python 3.12.0a5 fixes

This commit is contained in:
Miro Hrončok 2023-03-01 12:33:35 +01:00
commit bff314d73f
5 changed files with 310 additions and 1 deletions

116
15de63e460.patch Normal file
View file

@ -0,0 +1,116 @@
From 15de63e460e8a634aeb6bede0ba40ffa759f8c08 Mon Sep 17 00:00:00 2001
From: da-woods <dw-git@d-woods.co.uk>
Date: Sun, 17 Jul 2022 10:51:11 +0100
Subject: [PATCH] Account for possible extension type struct padding when
calculating the itemsize for the "size changed" check (GH-4894)
---
Cython/Compiler/ModuleNode.py | 6 +++---
Cython/Utility/ImportExport.c | 40 ++++++++++++++++++++++++++++++++---
2 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index 56845330df..e81b63d0a6 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -3078,12 +3078,12 @@ def generate_type_import_call(self, type, code, import_generator, error_code=Non
if not condition:
code.putln("") # start in new line
code.putln("#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000")
- code.putln('sizeof(%s),' % objstruct)
+ code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT(%s),' % (objstruct, objstruct))
code.putln("#else")
- code.putln('sizeof(%s),' % sizeof_objstruct)
+ code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT(%s),' % (sizeof_objstruct, sizeof_objstruct))
code.putln("#endif")
else:
- code.put('sizeof(%s), ' % objstruct)
+ code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT(%s),' % (objstruct, objstruct))
# check_size
if type.check_size and type.check_size in ('error', 'warn', 'ignore'):
diff --git a/Cython/Utility/ImportExport.c b/Cython/Utility/ImportExport.c
index 1689c11381..e1458fc8ff 100644
--- a/Cython/Utility/ImportExport.c
+++ b/Cython/Utility/ImportExport.c
@@ -301,13 +301,24 @@ static int __Pyx_SetPackagePathFromImportLib(PyObject *module_name) {
#ifndef __PYX_HAVE_RT_ImportType_proto
#define __PYX_HAVE_RT_ImportType_proto
+#if __STDC_VERSION__ >= 201112L
+#include <stdalign.h>
+#endif
+
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#define __PYX_GET_STRUCT_ALIGNMENT(s) alignof(s)
+#else
+// best guess at what the alignment could be since we can't measure it
+#define __PYX_GET_STRUCT_ALIGNMENT(s) sizeof(void*)
+#endif
+
enum __Pyx_ImportType_CheckSize {
__Pyx_ImportType_CheckSize_Error = 0,
__Pyx_ImportType_CheckSize_Warn = 1,
__Pyx_ImportType_CheckSize_Ignore = 2
};
-static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); /*proto*/
+static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize check_size); /*proto*/
#endif
@@ -316,13 +327,15 @@ static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name,
#ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name,
- size_t size, enum __Pyx_ImportType_CheckSize check_size)
+ size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize check_size)
{
PyObject *result = 0;
char warning[200];
Py_ssize_t basicsize;
+ Py_ssize_t itemsize;
#ifdef Py_LIMITED_API
PyObject *py_basicsize;
+ PyObject *py_itemsize;
#endif
result = PyObject_GetAttrString(module, class_name);
@@ -336,6 +349,7 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name,
}
#ifndef Py_LIMITED_API
basicsize = ((PyTypeObject *)result)->tp_basicsize;
+ itemsize = ((PyTypeObject *)result)->tp_itemsize;
#else
py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
if (!py_basicsize)
@@ -345,8 +359,28 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name,
py_basicsize = 0;
if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
goto bad;
+ py_itemsize = PyObject_GetAttrString(result, "__itemsize__");
+ if (!py_itemsize)
+ goto bad;
+ itemsize = PyLong_AsSsize_t(py_itemsize);
+ Py_DECREF(py_itemsize);
+ py_itemsize = 0;
+ if (itemsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
#endif
- if ((size_t)basicsize < size) {
+ if (itemsize) {
+ // If itemsize is smaller than the alignment the struct can end up with some extra
+ // padding at the end. In this case we need to work out the maximum size that
+ // the padding could be when calculating the range of valid struct sizes.
+ if (size % alignment) {
+ // if this is true we've probably calculated the alignment wrongly
+ // (most likely because alignof isn't available)
+ alignment = size % alignment;
+ }
+ if (itemsize < (Py_ssize_t)alignment)
+ itemsize = (Py_ssize_t)alignment;
+ }
+ if ((size_t)(basicsize + itemsize) < size) {
PyErr_Format(PyExc_ValueError,
"%.200s.%.200s size changed, may indicate binary incompatibility. "
"Expected %zd from C header, got %zd from PyObject",

25
21e64ec206.patch Normal file
View file

@ -0,0 +1,25 @@
From 21e64ec20619d9ac530030a8e0c259912af10407 Mon Sep 17 00:00:00 2001
From: Matti Picus <matti.picus@gmail.com>
Date: Tue, 29 Nov 2022 08:55:55 +0200
Subject: [PATCH] Disable "py_unicode_strings" test in Py3.12, which removed
the support for it.
Picked from https://github.com/cython/cython/commit/9d38bf8d620fd09166a5469c76b54f66d7fbd828
---
runtests.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/runtests.py b/runtests.py
index 91a0dd2570..cc79a53250 100755
--- a/runtests.py
+++ b/runtests.py
@@ -429,6 +429,9 @@ def get_openmp_compiler_flags(language):
'run.pep526_variable_annotations', # typing module
'run.test_exceptions', # copied from Py3.7+
]),
+ (3,11,999): (operator.gt, lambda x: x in ['run.py_unicode_strings',
+ ]),
+
}
INCLUDE_DIRS = [ d for d in os.getenv('INCLUDE', '').split(os.pathsep) if d ]

34
3397705da0.patch Normal file
View file

@ -0,0 +1,34 @@
From 3397705da036bb2df4a5b8b4bf08dbad7bdb409f Mon Sep 17 00:00:00 2001
From: Stefan Behnel <stefan_ml@behnel.de>
Date: Tue, 7 Mar 2023 08:43:06 +0100
Subject: [PATCH] Stop using PyLong internals and dict versioning in Py3.12 for
0.29.x (handled differently in master).
---
Cython/Utility/ModuleSetupCode.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
index 33aac2c4a7..e8fe62be00 100644
--- a/Cython/Utility/ModuleSetupCode.c
+++ b/Cython/Utility/ModuleSetupCode.c
@@ -208,7 +208,8 @@
#undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0
#elif !defined(CYTHON_USE_PYLONG_INTERNALS)
- #define CYTHON_USE_PYLONG_INTERNALS 1
+ // PyLong internals changed in Py3.12.
+ #define CYTHON_USE_PYLONG_INTERNALS (PY_VERSION_HEX < 0x030C00A5)
#endif
#ifndef CYTHON_USE_PYLIST_INTERNALS
#define CYTHON_USE_PYLIST_INTERNALS 1
@@ -252,7 +253,8 @@
#define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1)
#endif
#ifndef CYTHON_USE_DICT_VERSIONS
- #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1)
+ // The dict version field is now deprecated in Py3.12.
+ #define CYTHON_USE_DICT_VERSIONS ((PY_VERSION_HEX >= 0x030600B1) && (PY_VERSION_HEX < 0x030C00A5))
#endif
#if PY_VERSION_HEX >= 0x030B00A4
#undef CYTHON_USE_EXC_INFO_STACK

View file

@ -6,7 +6,7 @@
Name: Cython
Version: 0.29.33
Release: 1%{?dist}
Release: 2%{?dist}
Summary: Language for writing Python extension modules
License: Apache-2.0
@ -18,6 +18,17 @@ Source: https://github.com/cython/cython/archive/%{version}/Cython-%{ver
# Fixes https://bugzilla.redhat.com/2155090
Patch: emacs-docstring-wrap.patch
# Python 3.12 backports and fixes:
# Stop using PyLong internals and dict versioning in Py3.12 for 0.29.x
Patch: https://github.com/cython/cython/commit/3397705da0.patch
# Allow Py3.12 AttributeError suggestions in doctest output
Patch: https://github.com/cython/cython/commit/d883ccdec1.patch
# Disable "py_unicode_strings" test in Py3.12, which removed the support for it
Patch: https://github.com/cython/cython/commit/21e64ec206.patch
# Account for possible extension type struct padding when calculating the itemsize for the "size changed" check
Patch: https://github.com/cython/cython/commit/15de63e460.patch
BuildRequires: python3-devel
BuildRequires: python3-setuptools
@ -133,6 +144,10 @@ cp -p cython-mode-init.el cython-mode-init.elc %{buildroot}%{_emacs_sitestartdir
%changelog
* Wed Mar 01 2023 Miro Hrončok <mhroncok@redhat.com> - 0.29.33-2
- Make Cython work with Python 3.12.0a5
- Fixes: rhbz#2172822
* Fri Feb 17 2023 Miro Hrončok <mhroncok@redhat.com> - 0.29.33-1
- Update to 0.29.33
- Fix test failures with NumPy 1.24

119
d883ccdec1.patch Normal file
View file

@ -0,0 +1,119 @@
From d883ccdec11dabc41e43e98ff4e12da5649e6316 Mon Sep 17 00:00:00 2001
From: Stefan Behnel <stefan_ml@behnel.de>
Date: Tue, 7 Mar 2023 09:02:53 +0100
Subject: [PATCH] Allow Py3.12 AttributeError suggestions in doctest output.
---
tests/run/special_methods_T561.pyx | 12 +++----
tests/run/special_methods_T561_py3.pyx | 43 ++++++++++++--------------
2 files changed, 26 insertions(+), 29 deletions(-)
diff --git a/tests/run/special_methods_T561.pyx b/tests/run/special_methods_T561.pyx
index e5d1ec5bce..1c5f7ceb10 100644
--- a/tests/run/special_methods_T561.pyx
+++ b/tests/run/special_methods_T561.pyx
@@ -49,10 +49,10 @@ __doc__ = u"""
>>> g01 = object.__getattribute__(GetAttr(), '__getattribute__')
>>> g01('attr')
GetAttr getattr 'attr'
- >>> g10 = object.__getattribute__(GetAttribute(), '__getattr__')
+ >>> g10 = object.__getattribute__(GetAttribute(), '__getattr__') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
- AttributeError: 'special_methods_T561.GetAttribute' object has no attribute '__getattr__'
+ AttributeError: 'special_methods_T561.GetAttribute' object has no attribute '__getattr__'...
>>> g11 = object.__getattribute__(GetAttribute(), '__getattribute__')
>>> g11('attr')
GetAttribute getattribute 'attr'
@@ -62,15 +62,15 @@ __doc__ = u"""
>>> sa_setattr('foo', 'bar')
SetAttr setattr 'foo' 'bar'
>>> sa_delattr = SetAttr().__delattr__
- >>> sa_delattr('foo')
+ >>> sa_delattr('foo') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
- AttributeError: 'special_methods_T561.SetAttr' object has no attribute 'foo'
+ AttributeError: 'special_methods_T561.SetAttr' object has no attribute 'foo'...
>>> da_setattr = DelAttr().__setattr__
- >>> da_setattr('foo', 'bar')
+ >>> da_setattr('foo', 'bar') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
- AttributeError: 'special_methods_T561.DelAttr' object has no attribute 'foo'
+ AttributeError: 'special_methods_T561.DelAttr' object has no attribute 'foo'...
>>> da_delattr = DelAttr().__delattr__
>>> da_delattr('foo')
DelAttr delattr 'foo'
diff --git a/tests/run/special_methods_T561_py3.pyx b/tests/run/special_methods_T561_py3.pyx
index 9320022549..b766591d86 100644
--- a/tests/run/special_methods_T561_py3.pyx
+++ b/tests/run/special_methods_T561_py3.pyx
@@ -7,47 +7,44 @@
__doc__ = u"""
>>> vs0 = VerySpecial(0)
VS __init__ 0
+
>>> # Python 3 does not use __cmp__, so any provided __cmp__ method is
>>> # discarded under Python 3.
- >>> vs0_cmp = vs0.__cmp__
+ >>> vs0_cmp = vs0.__cmp__ # doctest: +ELLIPSIS
Traceback (most recent call last):
- ...
- AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__cmp__'
+ AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__cmp__'...
+
>>> # Python 3 does not use __div__ or __idiv__, so these methods are
>>> # discarded under Python 3.
- >>> vs0_div = vs0.__div__
+ >>> vs0_div = vs0.__div__ # doctest: +ELLIPSIS
Traceback (most recent call last):
- ...
- AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__div__'
- >>> vs0_rdiv = vs0.__rdiv__
+ AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__div__'...
+ >>> vs0_rdiv = vs0.__rdiv__ # doctest: +ELLIPSIS
Traceback (most recent call last):
- ...
- AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__rdiv__'
- >>> vs0_idiv = vs0.__idiv__
+ AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__rdiv__'...
+ >>> vs0_idiv = vs0.__idiv__ # doctest: +ELLIPSIS
Traceback (most recent call last):
- ...
- AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__idiv__'
+ AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__idiv__'...
+
>>> # Python 3 does not use __oct__ or __hex__, so these methods are
>>> # discarded under Python 3.
- >>> vs0_oct = vs0.__oct__
+ >>> vs0_oct = vs0.__oct__ # doctest: +ELLIPSIS
Traceback (most recent call last):
- ...
- AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__oct__'
- >>> vs0_hex = vs0.__hex__
+ AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__oct__'...
+ >>> vs0_hex = vs0.__hex__ # doctest: +ELLIPSIS
Traceback (most recent call last):
- ...
- AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__hex__'
+ AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__hex__'...
+
>>> # Python 3 does not use __long__; if you define __long__ but not
>>> # __int__, the __long__ definition will be used for __int__.
- >>> Ll = Long().__long__
+ >>> Ll = Long().__long__ # doctest: +ELLIPSIS
Traceback (most recent call last):
- ...
- AttributeError: 'special_methods_T561_py3.Long' object has no attribute '__long__'
+ AttributeError: 'special_methods_T561_py3.Long' object has no attribute '__long__'...
>>> Li = Long().__int__
>>> Li()
Long __long__
- >>> # As of Python 3, defining __nonzero__ gives you a __bool__ method
- >>> # instead.
+
+ >>> # As of Python 3, defining __nonzero__ gives you a __bool__ method instead.
>>> vs0_bool = vs0.__bool__
>>> vs0_bool()
VS __nonzero__ 0