[pypy-commit] pypy add_PyErr_SetFromErrnoWithFilenameObject_try_2: Make PyErr_SetFromErrnoWithFilenameObject work with any Python object; not just strings
Marc Abramowitz
noreply at buildbot.pypy.org
Mon Mar 24 07:38:44 CET 2014
Author: Marc Abramowitz <marc at marc-abramowitz.com>
Branch: add_PyErr_SetFromErrnoWithFilenameObject_try_2
Changeset: r70225:a00eb16f44ee
Date: 2014-03-23 23:29 -0700
http://bitbucket.org/pypy/pypy/changeset/a00eb16f44ee/
Log: Make PyErr_SetFromErrnoWithFilenameObject work with any Python
object; not just strings
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
@@ -165,15 +165,24 @@
raise OperationError(w_type, w_error)
@cpython_api([PyObject, PyObject], PyObject)
-def PyErr_SetFromErrnoWithFilenameObject(space, w_type, filename_object):
+def PyErr_SetFromErrnoWithFilenameObject(space, w_type, w_value):
"""Similar to PyErr_SetFromErrno(), with the additional behavior that if
- filename_object is not NULL, it is passed to the constructor of type as a
+ 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."""
- from pypy.module.cpyext.stringobject import PyString_AsString
- PyErr_SetFromErrnoWithFilename(space, w_type,
- PyString_AsString(space, filename_object))
+ 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,7 +215,7 @@
assert exc_info.value.errno == errno.EBADF
assert exc_info.value.strerror == os.strerror(errno.EBADF)
- def test_SetFromErrnoWithFilenameObject(self):
+ def test_SetFromErrnoWithFilenameObject__PyString(self):
import errno, os
module = self.import_extension('foo', [
@@ -234,6 +234,82 @@
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",
More information about the pypy-commit
mailing list