From 5d6fbe82078fe67437755bccfa504dbbcf909a74 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 12 Oct 2011 19:39:57 +0200 Subject: Instantiate the OS-related exception as soon as we raise it, so that "except" works properly. --- Lib/test/test_pep3151.py | 12 ++++++++++++ Python/errors.c | 16 ++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_pep3151.py b/Lib/test/test_pep3151.py index 9d92425..3c52bc6 100644 --- a/Lib/test/test_pep3151.py +++ b/Lib/test/test_pep3151.py @@ -79,6 +79,18 @@ class HierarchyTest(unittest.TestCase): e = SubOSError(EEXIST, "Bad file descriptor") self.assertIs(type(e), SubOSError) + def test_try_except(self): + # 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") + except FileNotFoundError: + pass + else: + self.fail("should have raised a FileNotFoundError") + class AttributesTest(unittest.TestCase): diff --git a/Python/errors.c b/Python/errors.c index 6e69d23..5988e1b 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -341,7 +341,7 @@ PyObject * PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) { PyObject *message; - PyObject *v; + PyObject *v, *args; int i = errno; #ifndef MS_WINDOWS char *s; @@ -410,14 +410,18 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) } if (filenameObject != NULL) - v = Py_BuildValue("(iOO)", i, message, filenameObject); + args = Py_BuildValue("(iOO)", i, message, filenameObject); else - v = Py_BuildValue("(iO)", i, message); + args = Py_BuildValue("(iO)", i, message); 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); + } } #ifdef MS_WINDOWS LocalFree(s_buf); -- cgit v0.12