Imported Upstream version 0.28.4 upstream/0.28.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 31 Dec 2020 03:04:03 +0000 (12:04 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 31 Dec 2020 03:04:03 +0000 (12:04 +0900)
CHANGES.rst
Cython/Compiler/ModuleNode.py
Cython/Shadow.py
Cython/Utility/Coroutine.c
Cython/Utility/Exceptions.c
Cython/Utility/ModuleSetupCode.c
appveyor.yml
tests/run/no_gc_clear.pyx
tests/run/tryexcept.pyx

index 45b7055..59545c6 100644 (file)
@@ -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)
 ===================
 
index 9449502..64cec6d 100644 (file)
@@ -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:
index 0f14a58..f126c44 100644 (file)
@@ -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
index f795a76..4f576ef 100644 (file)
@@ -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)
index 8628e3a..3f9c031 100644 (file)
@@ -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;
index c1ba400..7b9d245 100644 (file)
@@ -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<n; i++) {
+        if (exc_type == PyTuple_GET_ITEM(tuple, i)) return 1;
+    }
+#endif
+    for (i=0; i<n; i++) {
+        PyObject *t = PyTuple_GET_ITEM(tuple, i);
+        #if PY_MAJOR_VERSION < 3
+        if (likely(exc_type == t)) return 1;
+        #endif
+        if (likely(PyExceptionClass_Check(t))) {
+            if (__Pyx_inner_PyErr_GivenExceptionMatches2(exc_type, NULL, t)) return 1;
+        } else {
+            // FIXME: Py3: PyErr_SetString(PyExc_TypeError, "catching classes that do not inherit from BaseException is not allowed");
+        }
+    }
+    return 0;
+}
+
 static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) {
     if (likely(err == exc_type)) return 1;
     if (likely(PyExceptionClass_Check(err))) {
-        return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type);
+        if (likely(PyExceptionClass_Check(exc_type))) {
+            return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type);
+        } else if (likely(PyTuple_Check(exc_type))) {
+            return __Pyx_PyErr_GivenExceptionMatchesTuple(err, exc_type);
+        } else {
+            // FIXME: Py3: PyErr_SetString(PyExc_TypeError, "catching classes that do not inherit from BaseException is not allowed");
+        }
     }
     return PyErr_GivenExceptionMatches(err, exc_type);
 }
 
 static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) {
+    // Only used internally with known exception types => 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);
index 15ab737..e6a15d1 100644 (file)
@@ -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
index 401bcee..643ec4c 100644 (file)
@@ -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')
index de40855..dddf7de 100644 (file)
@@ -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
     """