[Python-checkins] cpython: Instantiate the OS-related exception as soon as we raise it, so that "except"

victor.stinner python-checkins at python.org
Mon Oct 17 20:18:02 CEST 2011


http://hg.python.org/cpython/rev/84aed9ef7aaf
changeset:   72965:84aed9ef7aaf
user:        Victor Stinner <victor.stinner at haypocalc.com>
date:        Mon Oct 17 20:18:58 2011 +0200
summary:
  Instantiate the OS-related exception as soon as we raise it, so that "except"
works properly.

PyErr_SetFromErrnoWithFilenameObject() was already fixed by the changeset
793c75177d28. This commit fixes PyErr_SetExcFromWindowsErrWithFilenameObject(),
used on Windows.

files:
  Lib/test/test_pep3151.py |  13 ++++++++++++-
  Python/errors.c          |  14 +++++++++-----
  2 files changed, 21 insertions(+), 6 deletions(-)


diff --git a/Lib/test/test_pep3151.py b/Lib/test/test_pep3151.py
--- a/Lib/test/test_pep3151.py
+++ b/Lib/test/test_pep3151.py
@@ -80,12 +80,23 @@
         self.assertIs(type(e), SubOSError)
 
     def test_try_except(self):
+        filename = "some_hopefully_non_existing_file"
+
         # This checks that try .. except checks the concrete exception
         # (FileNotFoundError) and not the base type specified when
         # PyErr_SetFromErrnoWithFilenameObject was called.
         # (it is therefore deliberate that it doesn't use assertRaises)
         try:
-            open("some_hopefully_non_existing_file")
+            open(filename)
+        except FileNotFoundError:
+            pass
+        else:
+            self.fail("should have raised a FileNotFoundError")
+
+        # Another test for PyErr_SetExcFromWindowsErrWithFilenameObject()
+        self.assertFalse(os.path.exists(filename))
+        try:
+            os.unlink(filename)
         except FileNotFoundError:
             pass
         else:
diff --git a/Python/errors.c b/Python/errors.c
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -468,7 +468,7 @@
     int len;
     WCHAR *s_buf = NULL; /* Free via LocalFree */
     PyObject *message;
-    PyObject *v;
+    PyObject *args, *v;
     DWORD err = (DWORD)ierr;
     if (err==0) err = GetLastError();
     len = FormatMessageW(
@@ -504,12 +504,16 @@
         filenameObject = Py_None;
     /* This is the constructor signature for passing a Windows error code.
        The POSIX translation will be figured out by the constructor. */
-    v = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);
+    args = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);
     Py_DECREF(message);
 
-    if (v != NULL) {
-        PyErr_SetObject(exc, v);
-        Py_DECREF(v);
+    if (args != NULL) {
+        v = PyObject_Call(exc, args, NULL);
+        Py_DECREF(args);
+        if (v != NULL) {
+            PyErr_SetObject((PyObject *) Py_TYPE(v), v);
+            Py_DECREF(v);
+        }
     }
     LocalFree(s_buf);
     return NULL;

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list