Commits

mattip  committed 9359e47 Merge

merge default into branch

  • Participants
  • Parent commits 13cf0ac, 99d559e
  • Branches win32-fixes4

Comments (0)

Files changed (5)

File pypy/doc/whatsnew-head.rst

 
 .. branch: improve-consecutive-dict-lookups
 Improve the situation when dict lookups of the same key are performed in a chain
+
+.. branch: add_PyErr_SetFromErrnoWithFilenameObject_try_2
+.. branch: test_SetFromErrnoWithFilename_NULL
+.. branch: test_SetFromErrnoWithFilename__tweaks
+
+.. branch: refactor_PyErr_SetFromErrnoWithFilename
+Add support for PyErr_SetFromErrnoWithFilenameObject to cpyext

File pypy/module/cpyext/pyerrors.py

     this is used to define the filename attribute of the exception instance.
     Return value: always NULL."""
     # XXX Doesn't actually do anything with PyErr_CheckSignals.
+    if llfilename:
+        w_filename = rffi.charp2str(llfilename)
+        filename = space.wrap(w_filename)
+    else:
+        filename = space.w_None
+
+    PyErr_SetFromErrnoWithFilenameObject(space, w_type, filename)
+
+@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."""
+    # XXX Doesn't actually do anything with PyErr_CheckSignals.
     errno = get_errno()
     msg = os.strerror(errno)
-    if llfilename:
-        w_filename = rffi.charp2str(llfilename)
+    if w_value:
         w_error = space.call_function(w_type,
                                       space.wrap(errno),
                                       space.wrap(msg),
-                                      space.wrap(w_filename))
+                                      w_value)
     else:
         w_error = space.call_function(w_type,
                                       space.wrap(errno),

File pypy/module/cpyext/test/test_pyerrors.py

         except OSError, e:
             assert e.errno == errno.EBADF
             assert e.strerror == os.strerror(errno.EBADF)
-            assert e.filename == None
+            assert e.filename is None
 
     def test_SetFromErrnoWithFilename(self):
-        import sys
-        if sys.platform != 'win32':
-            skip("callbacks through ll2ctypes modify errno")
         import errno, os
 
         module = self.import_extension('foo', [
                 ("set_from_errno", "METH_NOARGS",
                  '''
                  errno = EBADF;
-                 PyErr_SetFromErrnoWithFilename(PyExc_OSError, "blyf");
+                 PyErr_SetFromErrnoWithFilename(PyExc_OSError, "/path/to/file");
                  return NULL;
                  '''),
                 ],
                 prologue="#include <errno.h>")
-        try:
-            module.set_from_errno()
-        except OSError, e:
-            assert e.filename == "blyf"
-            assert e.errno == errno.EBADF
-            assert e.strerror == os.strerror(errno.EBADF)
+        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_SetFromErrnoWithFilename_NULL(self):
+        import errno, os
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 errno = EBADF;
+                 PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL);
+                 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_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', [

File pypy/sandbox/test/test_pypy_interact.py

-import os, sys, stat, errno
+import os, stat, errno, py
 from pypy.sandbox.pypy_interact import PyPySandboxedProc
 from rpython.translator.interactive import Translation
 
 SITE_PY_CONTENT = LIB_PYTHON.join('site.py').read()
 ERROR_TEXT = os.strerror(errno.ENOENT)
 
+if os.name == 'nt':
+    py.test.skip('sandbox not supported on windows')
+
 def assert_(cond, text):
     if not cond:
         print "assert failed:", text

File rpython/jit/backend/x86/arch.py

 #
 #        +--------------------+    <== aligned to 16 bytes
 #        |   return address   |
-#        +--------------------+
-#        |    saved regs      |
-#        +--------------------+
-#        |   scratch          |
-#        |      space         |
-#        +--------------------+    <== aligned to 16 bytes
+#        +--------------------+           ----------------------.
+#        |    saved regs      |                FRAME_FIXED_SIZE |
+#        +--------------------+       --------------------.     |
+#        |   scratch          |          PASS_ON_MY_FRAME |     |
+#        |      space         |                           |     |
+#        +--------------------+    <== aligned to 16 -----' ----'
 
 # All the rest of the data is in a GC-managed variable-size "frame".
 # This frame object's address is always stored in the register EBP/RBP.
 # start of every frame: the saved value of some registers
 
 if WORD == 4:
-    # ebp + ebx + esi + edi + 14 extra words + return address = 19 words
+    # ebp + ebx + esi + edi + 15 extra words = 19 words
     FRAME_FIXED_SIZE = 19
-    PASS_ON_MY_FRAME = 14
+    PASS_ON_MY_FRAME = 15
     JITFRAME_FIXED_SIZE = 6 + 8 * 2 # 6 GPR + 8 XMM * 2 WORDS/float
 else:
-    # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19
+    # rbp + rbx + r12 + r13 + r14 + r15 + 13 extra words = 19
     FRAME_FIXED_SIZE = 19
-    PASS_ON_MY_FRAME = 12
+    PASS_ON_MY_FRAME = 13
     JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM
 
 assert PASS_ON_MY_FRAME >= 12       # asmgcc needs at least JIT_USE_WORDS + 3