Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9ea8e4c

Browse files
author
Victor Stinner
committed
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.
1 parent ecd0207 commit 9ea8e4c

2 files changed

Lines changed: 21 additions & 6 deletions

File tree

Lib/test/test_pep3151.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,23 @@ def test_OSError_subclass_mapping(self):
8080
self.assertIs(type(e), SubOSError)
8181

8282
def test_try_except(self):
83+
filename = "some_hopefully_non_existing_file"
84+
8385
# This checks that try .. except checks the concrete exception
8486
# (FileNotFoundError) and not the base type specified when
8587
# PyErr_SetFromErrnoWithFilenameObject was called.
8688
# (it is therefore deliberate that it doesn't use assertRaises)
8789
try:
88-
open("some_hopefully_non_existing_file")
90+
open(filename)
91+
except FileNotFoundError:
92+
pass
93+
else:
94+
self.fail("should have raised a FileNotFoundError")
95+
96+
# Another test for PyErr_SetExcFromWindowsErrWithFilenameObject()
97+
self.assertFalse(os.path.exists(filename))
98+
try:
99+
os.unlink(filename)
89100
except FileNotFoundError:
90101
pass
91102
else:

Python/errors.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
468468
int len;
469469
WCHAR *s_buf = NULL; /* Free via LocalFree */
470470
PyObject *message;
471-
PyObject *v;
471+
PyObject *args, *v;
472472
DWORD err = (DWORD)ierr;
473473
if (err==0) err = GetLastError();
474474
len = FormatMessageW(
@@ -504,12 +504,16 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
504504
filenameObject = Py_None;
505505
/* This is the constructor signature for passing a Windows error code.
506506
The POSIX translation will be figured out by the constructor. */
507-
v = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);
507+
args = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);
508508
Py_DECREF(message);
509509

510-
if (v != NULL) {
511-
PyErr_SetObject(exc, v);
512-
Py_DECREF(v);
510+
if (args != NULL) {
511+
v = PyObject_Call(exc, args, NULL);
512+
Py_DECREF(args);
513+
if (v != NULL) {
514+
PyErr_SetObject((PyObject *) Py_TYPE(v), v);
515+
Py_DECREF(v);
516+
}
513517
}
514518
LocalFree(s_buf);
515519
return NULL;

0 commit comments

Comments
 (0)