From 426963f7303ed68ac548d72495cd873d3b762a49 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Thu, 31 Dec 2020 12:04:03 +0900 Subject: [PATCH] Imported Upstream version 0.28.4 --- CHANGES.rst | 16 ++++++++++++++++ Cython/Compiler/ModuleNode.py | 2 +- Cython/Shadow.py | 2 +- Cython/Utility/Coroutine.c | 2 +- Cython/Utility/Exceptions.c | 10 +++++----- Cython/Utility/ModuleSetupCode.c | 35 ++++++++++++++++++++++++++++++++++- appveyor.yml | 16 ++++++++-------- tests/run/no_gc_clear.pyx | 15 +++++++++++++++ tests/run/tryexcept.pyx | 34 ++++++++++++++++++++++++++++++++++ 9 files changed, 115 insertions(+), 17 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 45b7055..59545c6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,22 @@ Cython Changelog ================ +0.28.4 (2018-07-08) +=================== + +Bugs fixed +---------- + +* Reallowing ``tp_clear()`` in a subtype of an ``@no_gc_clear`` extension type + generated an invalid C function call to the (non-existent) base type implementation. + (Github issue #2309) + +* Exception catching based on a non-literal (runtime) tuple could fail to match the + exception. (Github issue #2425) + +* Compile fix for CPython 3.7.0a2. (Github issue #2477) + + 0.28.3 (2018-05-27) =================== diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 9449502..64cec6d 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1603,7 +1603,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("}") def generate_clear_function(self, scope, code, cclass_entry): - tp_slot = TypeSlots.GCDependentSlot("tp_clear") + tp_slot = TypeSlots.get_slot_by_name("tp_clear") slot_func = scope.mangle_internal("tp_clear") base_type = scope.parent_type.base_type if tp_slot.slot_code(scope) != slot_func: diff --git a/Cython/Shadow.py b/Cython/Shadow.py index 0f14a58..f126c44 100644 --- a/Cython/Shadow.py +++ b/Cython/Shadow.py @@ -1,7 +1,7 @@ # cython.* namespace for pure mode. from __future__ import absolute_import -__version__ = "0.28.3" +__version__ = "0.28.4" try: from __builtin__ import basestring diff --git a/Cython/Utility/Coroutine.c b/Cython/Utility/Coroutine.c index f795a76..4f576ef 100644 --- a/Cython/Utility/Coroutine.c +++ b/Cython/Utility/Coroutine.c @@ -1851,7 +1851,7 @@ static void __Pyx__ReturnWithStopIteration(PyObject* value) { } #if CYTHON_FAST_THREAD_STATE __Pyx_PyThreadState_assign - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 if (!$local_tstate_cname->exc_state.exc_type) #else if (!$local_tstate_cname->exc_type) diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c index 8628e3a..3f9c031 100644 --- a/Cython/Utility/Exceptions.c +++ b/Cython/Utility/Exceptions.c @@ -359,7 +359,7 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) *value = local_value; *tb = local_tb; #if CYTHON_FAST_THREAD_STATE - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 tmp_type = tstate->exc_state.exc_type; tmp_value = tstate->exc_state.exc_value; tmp_tb = tstate->exc_state.exc_traceback; @@ -403,7 +403,7 @@ static CYTHON_INLINE void __Pyx_ReraiseException(void) { PyObject *type = NULL, *value = NULL, *tb = NULL; #if CYTHON_FAST_THREAD_STATE PyThreadState *tstate = PyThreadState_GET(); - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 type = tstate->exc_state.exc_type; value = tstate->exc_state.exc_value; tb = tstate->exc_state.exc_traceback; @@ -455,7 +455,7 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject #if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 *type = tstate->exc_state.exc_type; *value = tstate->exc_state.exc_value; *tb = tstate->exc_state.exc_traceback; @@ -472,7 +472,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject * static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 tmp_type = tstate->exc_state.exc_type; tmp_value = tstate->exc_state.exc_value; tmp_tb = tstate->exc_state.exc_traceback; @@ -510,7 +510,7 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 tmp_type = tstate->exc_state.exc_type; tmp_value = tstate->exc_state.exc_value; tmp_tb = tstate->exc_state.exc_traceback; diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c index c1ba400..7b9d245 100644 --- a/Cython/Utility/ModuleSetupCode.c +++ b/Cython/Utility/ModuleSetupCode.c @@ -765,15 +765,48 @@ static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, // so far, we only call PyErr_GivenExceptionMatches() with an exception type (not instance) as first argument // => optimise for that case +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + // the tighter subtype checking in Py3 allows faster out-of-order comparison + for (i=0; i pure safety check assertions. + assert(PyExceptionClass_Check(exc_type1)); + assert(PyExceptionClass_Check(exc_type2)); if (likely(err == exc_type1 || err == exc_type2)) return 1; if (likely(PyExceptionClass_Check(err))) { return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2); diff --git a/appveyor.yml b/appveyor.yml index 15ab737..e6a15d1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,12 +17,12 @@ environment: PYTHON_VERSION: "2.7" PYTHON_ARCH: "64" - - PYTHON: "C:\\Python34" - PYTHON_VERSION: "3.4" + - PYTHON: "C:\\Python36" + PYTHON_VERSION: "3.6" PYTHON_ARCH: "32" - - PYTHON: "C:\\Python34-x64" - PYTHON_VERSION: "3.4" + - PYTHON: "C:\\Python36-x64" + PYTHON_VERSION: "3.6" PYTHON_ARCH: "64" - PYTHON: "C:\\Python35" @@ -33,12 +33,12 @@ environment: PYTHON_VERSION: "3.5" PYTHON_ARCH: "64" - - PYTHON: "C:\\Python36" - PYTHON_VERSION: "3.6" + - PYTHON: "C:\\Python34" + PYTHON_VERSION: "3.4" PYTHON_ARCH: "32" - - PYTHON: "C:\\Python36-x64" - PYTHON_VERSION: "3.6" + - PYTHON: "C:\\Python34-x64" + PYTHON_VERSION: "3.4" PYTHON_ARCH: "64" clone_depth: 5 diff --git a/tests/run/no_gc_clear.pyx b/tests/run/no_gc_clear.pyx index 401bcee..643ec4c 100644 --- a/tests/run/no_gc_clear.pyx +++ b/tests/run/no_gc_clear.pyx @@ -56,6 +56,21 @@ cdef class DisableTpClear: pto.tp_clear(self) +cdef class ReallowTpClear(DisableTpClear): + """ + >>> import gc + >>> obj = ReallowTpClear() + >>> is_tp_clear_null(obj) + False + + >>> obj.attr = obj # create hard reference cycle + >>> del obj; _ignore = gc.collect() + + # Problem: cannot really validate that the cycle was cleaned up without using weakrefs etc... + """ + cdef public object attr + + def test_closure_without_clear(str x): """ >>> c = test_closure_without_clear('abc') diff --git a/tests/run/tryexcept.pyx b/tests/run/tryexcept.pyx index de40855..dddf7de 100644 --- a/tests/run/tryexcept.pyx +++ b/tests/run/tryexcept.pyx @@ -58,6 +58,36 @@ def single_except_expression(a, x): i = 3 return i + +exceptions = (ValueError, TypeError) + + +def single_except_global_tuple(x): + """ + >>> single_except_global_tuple(None) + 2 + >>> single_except_global_tuple(ValueError('test')) + 3 + >>> single_except_global_tuple(TypeError('test')) + 3 + >>> class TypeErrorSubtype(TypeError): pass + >>> single_except_global_tuple(TypeErrorSubtype('test')) + 3 + >>> single_except_global_tuple(AttributeError('test')) + Traceback (most recent call last): + AttributeError: test + """ + cdef int i + try: + i = 1 + if x: + raise x + i = 2 + except exceptions: + i = 3 + return i + + def double_except_no_raise(a,b): """ >>> double_except_no_raise(TypeError, ValueError) @@ -179,6 +209,10 @@ def normal_and_bare_except_raise(x, a): 2 >>> normal_and_bare_except_raise(ValueError('test'), TypeError) 3 + >>> normal_and_bare_except_raise(TypeError('test'), (TypeError, ValueError)) + 2 + >>> normal_and_bare_except_raise(ValueError('test'), (TypeError, ValueError)) + 2 >>> normal_and_bare_except_raise(None, TypeError) 1 """ -- 2.7.4