-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: Fix segfault when an error occurs in np.fromfile #12354
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2044,6 +2044,7 @@ static PyObject * | |
array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds) | ||
{ | ||
PyObject *file = NULL, *ret; | ||
PyObject *err_type = NULL, *err_value = NULL, *err_traceback = NULL; | ||
char *sep = ""; | ||
Py_ssize_t nin = -1; | ||
static char *kwlist[] = {"file", "dtype", "count", "sep", NULL}; | ||
|
@@ -2079,18 +2080,26 @@ array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds) | |
} | ||
ret = PyArray_FromFile(fp, type, (npy_intp) nin, sep); | ||
|
||
/* If an exception is thrown in the call to PyArray_FromFile | ||
* we need to clear it, and restore it later to ensure that | ||
* we can cleanup the duplicated file descriptor properly. | ||
*/ | ||
PyErr_Fetch(&err_type, &err_value, &err_traceback); | ||
if (npy_PyFile_DupClose2(file, fp, orig_pos) < 0) { | ||
npy_PyErr_ChainExceptions(err_type, err_value, err_traceback); | ||
goto fail; | ||
} | ||
if (own && npy_PyFile_CloseFile(file) < 0) { | ||
npy_PyErr_ChainExceptions(err_type, err_value, err_traceback); | ||
goto fail; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be neat to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is part of the C-API that I'm not really familiar with - What are the differences between them and why would I want to use one over the other? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
>>> try:
raise ValueError
except:
raise KeyError
Traceback (most recent call last):
File "<pyshell#5>", line 2, in <module>
raise ValueError
ValueError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#5>", line 4, in <module>
raise KeyError
KeyError While >>> try:
raise ValueError
except Exception as e:
raise KeyError from e
Traceback (most recent call last):
File "<pyshell#7>", line 2, in <module>
raise ValueError
ValueError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<pyshell#7>", line 4, in <module>
raise KeyError from e
KeyError There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the explanation, I've added the implementation of that and have used it. |
||
} | ||
PyErr_Restore(err_type, err_value, err_traceback); | ||
Py_DECREF(file); | ||
return ret; | ||
|
||
fail: | ||
Py_DECREF(file); | ||
Py_DECREF(ret); | ||
Py_XDECREF(ret); | ||
return NULL; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation has been taken from the cpython source: https://github.com/python/cpython/blob/50b48572d9a90c5bb36e2bef6179548ea927a35a/Python/errors.c#L389-L414