[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