[pypy-commit] pypy default: test, fix for raising non-TypeError exception when conversion fails

mattip pypy.commits at gmail.com
Sun Sep 11 15:47:25 EDT 2016


Author: Matti Picus <matti.picus at gmail.com>
Branch: 
Changeset: r87008:2e99c5b56c4f
Date: 2016-09-11 22:46 +0300
http://bitbucket.org/pypy/pypy/changeset/2e99c5b56c4f/

Log:	test, fix for raising non-TypeError exception when conversion fails

diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py
--- a/pypy/module/cpyext/sequence.py
+++ b/pypy/module/cpyext/sequence.py
@@ -43,16 +43,20 @@
 def PySequence_Fast(space, w_obj, m):
     """Returns the sequence o as a tuple, unless it is already a tuple or list, in
     which case o is returned.  Use PySequence_Fast_GET_ITEM() to access the
-    members of the result.  Returns NULL on failure.  If the object is not a
-    sequence, raises TypeError with m as the message text."""
+    members of the result.  Returns NULL on failure.  If the object cannot be
+    converted to a sequence, and raises a TypeError, raise a new TypeError with
+    m as the message text. If the conversion otherwise, fails, reraise the
+    original exception"""
     if isinstance(w_obj, W_ListObject):
         # make sure we can return a borrowed obj from PySequence_Fast_GET_ITEM    
         w_obj.convert_to_cpy_strategy(space)
         return w_obj
     try:
         return W_ListObject.newlist_cpyext(space, space.listview(w_obj))
-    except OperationError:
-        raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m)))
+    except OperationError as e:
+        if e.match(space, space.w_TypeError):
+            raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m)))
+        raise e
 
 @cpython_api([rffi.VOIDP, Py_ssize_t], PyObject, result_borrowed=True)
 def PySequence_Fast_GET_ITEM(space, w_obj, index):
diff --git a/pypy/module/cpyext/test/test_sequence.py b/pypy/module/cpyext/test/test_sequence.py
--- a/pypy/module/cpyext/test/test_sequence.py
+++ b/pypy/module/cpyext/test/test_sequence.py
@@ -267,3 +267,31 @@
         assert module.test_fast_sequence(s[0:-1])
         assert module.test_fast_sequence(s[::-1])
 
+    def test_fast_keyerror(self):
+        module = self.import_extension('foo', [
+            ("test_fast_sequence", "METH_VARARGS",
+             """
+                PyObject *foo;
+                PyObject * seq = PyTuple_GetItem(args, 0);
+                if (seq == NULL)
+                    Py_RETURN_NONE;
+                foo = PySequence_Fast(seq, "Could not convert object to sequence");
+                if (foo != NULL)
+                {
+                    return foo;
+                }
+                if (PyErr_ExceptionMatches(PyExc_KeyError)) {
+                    PyErr_Clear();
+                    return PyBool_FromLong(1);
+                }
+                return NULL;
+             """)])
+        class Map(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise KeyError()
+
+        assert module.test_fast_sequence(Map()) is True
+


More information about the pypy-commit mailing list