Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions Python/errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -1697,13 +1697,18 @@ err_programtext(PyThreadState *tstate, FILE *fp, int lineno)
PyObject *
PyErr_ProgramText(const char *filename, int lineno)
{
FILE *fp;
if (filename == NULL || *filename == '\0' || lineno <= 0) {
if (filename == NULL) {
return NULL;
}
PyThreadState *tstate = _PyThreadState_GET();
fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE);
return err_programtext(tstate, fp, lineno);

PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
if (filename_obj == NULL) {
PyErr_Clear();
return NULL;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that the contract of this function allows raising an exception? It seems that PyErr_ProgramTextObject takes care to clear the exception, as does err_programtext.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. In case of doubt, I added a PyErr_Clear() call.

My first intent was to deprecate the function. IMO it was exposed by mistake in the stable ABI. But since PyErr_ProgramTextObject() is still needed, I prefer to rewrite PyErr_ProgramText() with PyErr_ProgramTextObject().

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Better safe than sorry :)

}
PyObject *res = PyErr_ProgramTextObject(filename_obj, lineno);
Py_DECREF(filename_obj);
return res;
}

PyObject *
Expand Down