Author: Alex Gaynor <[email protected]>
Branch: 
Changeset: r70226:0f14db5ced36
Date: 2014-03-23 23:38 -0700
http://bitbucket.org/pypy/pypy/changeset/0f14db5ced36/

Log:    Merged in
        msabramo/pypy/add_PyErr_SetFromErrnoWithFilenameObject_try_2 (pull
        request #211)

        Add PyErr_SetFromErrnoWithFilenameObject to cpyext

diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py
--- a/pypy/module/cpyext/pyerrors.py
+++ b/pypy/module/cpyext/pyerrors.py
@@ -164,6 +164,26 @@
                                       space.wrap(msg))
     raise OperationError(w_type, w_error)
 
+@cpython_api([PyObject, PyObject], PyObject)
+def PyErr_SetFromErrnoWithFilenameObject(space, w_type, w_value):
+    """Similar to PyErr_SetFromErrno(), with the additional behavior that if
+    w_value is not NULL, it is passed to the constructor of type as a
+    third parameter.  In the case of exceptions such as IOError and OSError,
+    this is used to define the filename attribute of the exception instance.
+    Return value: always NULL."""
+    errno = get_errno()
+    msg = os.strerror(errno)
+    if w_value:
+        w_error = space.call_function(w_type,
+                                      space.wrap(errno),
+                                      space.wrap(msg),
+                                      w_value)
+    else:
+        w_error = space.call_function(w_type,
+                                      space.wrap(errno),
+                                      space.wrap(msg))
+    raise OperationError(w_type, w_error)
+
 @cpython_api([], rffi.INT_real, error=-1)
 def PyErr_CheckSignals(space):
     """
diff --git a/pypy/module/cpyext/test/test_pyerrors.py 
b/pypy/module/cpyext/test/test_pyerrors.py
--- a/pypy/module/cpyext/test/test_pyerrors.py
+++ b/pypy/module/cpyext/test/test_pyerrors.py
@@ -215,6 +215,101 @@
         assert exc_info.value.errno == errno.EBADF
         assert exc_info.value.strerror == os.strerror(errno.EBADF)
 
+    def test_SetFromErrnoWithFilenameObject__PyString(self):
+        import errno, os
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 errno = EBADF;
+                 PyObject *filenameObject = 
PyString_FromString("/path/to/file");
+                 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, 
filenameObject);
+                 Py_DECREF(filenameObject);
+                 return NULL;
+                 '''),
+                ],
+                prologue="#include <errno.h>")
+        exc_info = raises(OSError, module.set_from_errno)
+        assert exc_info.value.filename == "/path/to/file"
+        assert exc_info.value.errno == errno.EBADF
+        assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+    def test_SetFromErrnoWithFilenameObject__PyInt(self):
+        import errno, os
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 errno = EBADF;
+                 PyObject *intObject = PyInt_FromLong(3);
+                 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, 
intObject);
+                 Py_DECREF(intObject);
+                 return NULL;
+                 '''),
+                ],
+                prologue="#include <errno.h>")
+        exc_info = raises(OSError, module.set_from_errno)
+        assert exc_info.value.filename == 3
+        assert exc_info.value.errno == errno.EBADF
+        assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+    def test_SetFromErrnoWithFilenameObject__PyList(self):
+        import errno, os
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 errno = EBADF;
+                 PyObject *lst = Py_BuildValue("[iis]", 1, 2, "three");
+                 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, lst);
+                 Py_DECREF(lst);
+                 return NULL;
+                 '''),
+                ],
+                prologue="#include <errno.h>")
+        exc_info = raises(OSError, module.set_from_errno)
+        assert exc_info.value.filename == [1, 2, "three"]
+        assert exc_info.value.errno == errno.EBADF
+        assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+    def test_SetFromErrnoWithFilenameObject__PyTuple(self):
+        import errno, os
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 errno = EBADF;
+                 PyObject *tuple = Py_BuildValue("(iis)", 1, 2, "three");
+                 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, tuple);
+                 Py_DECREF(tuple);
+                 return NULL;
+                 '''),
+                ],
+                prologue="#include <errno.h>")
+        exc_info = raises(OSError, module.set_from_errno)
+        assert exc_info.value.filename == (1, 2, "three")
+        assert exc_info.value.errno == errno.EBADF
+        assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+    def test_SetFromErrnoWithFilenameObject__Py_None(self):
+        import errno, os
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 errno = EBADF;
+                 PyObject *none = Py_BuildValue("");
+                 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, none);
+                 Py_DECREF(none);
+                 return NULL;
+                 '''),
+                ],
+                prologue="#include <errno.h>")
+        exc_info = raises(OSError, module.set_from_errno)
+        assert exc_info.value.filename is None
+        assert exc_info.value.errno == errno.EBADF
+        assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
     def test_PyErr_Display(self):
         module = self.import_extension('foo', [
             ("display_error", "METH_VARARGS",
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to