[pypy-svn] r73303 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test

exarkun at codespeak.net exarkun at codespeak.net
Fri Apr 2 19:51:34 CEST 2010


Author: exarkun
Date: Fri Apr  2 19:51:31 2010
New Revision: 73303

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/api.py
   pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py
   pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py
Log:
Attempt to add PyErr_SetFromErrno; the test currently fails because it gets the wrong errno back from the OSError raised

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py	Fri Apr  2 19:51:31 2010
@@ -230,7 +230,7 @@
     }
 
 for exc_name in ['TypeError', 'ValueError', 'KeyError', 'Exception',
-                 'BaseException', 'SystemError']:
+                 'BaseException', 'SystemError', 'OSError']:
     GLOBALS['PyExc_' + exc_name] = ('PyObject*', 'space.w_' + exc_name)
 
 for cpyname, pypyexpr in {"Type": "space.w_type",

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py	Fri Apr  2 19:51:31 2010
@@ -1,8 +1,11 @@
+import os
+
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL
 from pypy.module.cpyext.pyobject import PyObject, make_ref, register_container
 from pypy.module.cpyext.state import State
+from pypy.rlib.rposix import get_errno
 
 @cpython_api([PyObject, PyObject], lltype.Void)
 def PyErr_SetObject(space, w_type, w_value):
@@ -16,6 +19,28 @@
     message = rffi.charp2str(message_ptr)
     PyErr_SetObject(space, w_type, space.wrap(message))
 
+
+ at cpython_api([PyObject], PyObject)
+def PyErr_SetFromErrno(space, w_type):
+    """
+    This is a convenience function to raise an exception when a C library function
+    has returned an error and set the C variable errno.  It constructs a
+    tuple object whose first item is the integer errno value and whose
+    second item is the corresponding error message (gotten from strerror()),
+    and then calls PyErr_SetObject(type, object).  On Unix, when the
+    errno value is EINTR, indicating an interrupted system call,
+    this calls PyErr_CheckSignals(), and if that set the error indicator,
+    leaves it set to that.  The function always returns NULL, so a wrapper
+    function around a system call can write return PyErr_SetFromErrno(type);
+    when the system call returns an error.
+    Return value: always NULL."""
+    # XXX Doesn't actually do anything with PyErr_CheckSignals.
+    errno = get_errno()
+    errno_w = space.wrap(errno)
+    message_w = space.wrap(os.strerror(errno))
+    PyErr_SetObject(space, w_type, errno_w, message_w)
+
+
 @cpython_api([], PyObject, borrowed=True)
 def PyErr_Occurred(space):
     state = space.fromcache(State)

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py	Fri Apr  2 19:51:31 2010
@@ -1721,25 +1721,6 @@
     Return value: always NULL."""
     raise NotImplementedError
 
- at cpython_api([PyObject], PyObject)
-def PyErr_SetFromErrno(space, type):
-    """
-    
-    
-    
-    This is a convenience function to raise an exception when a C library function
-    has returned an error and set the C variable errno.  It constructs a
-    tuple object whose first item is the integer errno value and whose
-    second item is the corresponding error message (gotten from strerror()),
-    and then calls PyErr_SetObject(type, object).  On Unix, when the
-    errno value is EINTR, indicating an interrupted system call,
-    this calls PyErr_CheckSignals(), and if that set the error indicator,
-    leaves it set to that.  The function always returns NULL, so a wrapper
-    function around a system call can write return PyErr_SetFromErrno(type);
-    when the system call returns an error.
-    Return value: always NULL."""
-    raise NotImplementedError
-
 @cpython_api([PyObject, rffi.CCHARP], PyObject)
 def PyErr_SetFromErrnoWithFilename(space, type, filename):
     """Similar to PyErr_SetFromErrno(), with the additional behavior that if

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py	Fri Apr  2 19:51:31 2010
@@ -52,6 +52,8 @@
 
         api.PyErr_Clear()
 
+
+
 class AppTestFetch(AppTestCpythonExtensionBase):
     def test_occurred(self):
         module = self.import_extension('foo', [
@@ -65,3 +67,24 @@
              ),
             ])
         module.check_error()
+
+
+    def test_SetFromErrno(self):
+        import errno
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 int close(int);
+                 close(-1);
+                 PyErr_SetFromErrno(PyExc_OSError);
+                 return NULL;
+                 '''),
+                ])
+        try:
+            module.set_from_errno()
+        except OSError, e:
+            assert e.errno == errno.EBADF
+            assert e.message == os.strerror(errno.EBADF)
+
+



More information about the Pypy-commit mailing list