Issue #20517: Functions in the os module that accept two filenames
now register both filenames in the exception on failure.
This required adding new C API functions allowing OSError exceptions
to reference two filenames instead of one.
diff --git a/Python/errors.c b/Python/errors.c
index 90dc729..0057e5e 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -410,6 +410,12 @@
 PyObject *
 PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
 {
+    return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL);
+}
+
+PyObject *
+PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2)
+{
     PyObject *message;
     PyObject *v, *args;
     int i = errno;
@@ -480,10 +486,15 @@
         return NULL;
     }
 
-    if (filenameObject != NULL)
-        args = Py_BuildValue("(iOO)", i, message, filenameObject);
-    else
+    if (filenameObject != NULL) {
+        if (filenameObject2 != NULL)
+            args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2);
+        else
+            args = Py_BuildValue("(iOO)", i, message, filenameObject);
+    } else {
+        assert(filenameObject2 == NULL);
         args = Py_BuildValue("(iO)", i, message);
+    }
     Py_DECREF(message);
 
     if (args != NULL) {
@@ -500,16 +511,26 @@
     return NULL;
 }
 
-
 PyObject *
 PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
 {
     PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
-    PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
+    PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
     Py_XDECREF(name);
     return result;
 }
 
+PyObject *
+PyErr_SetFromErrnoWithFilenames(PyObject *exc, const char *filename, const char *filename2)
+{
+    PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
+    PyObject *name2 = filename2 ? PyUnicode_DecodeFSDefault(filename2) : NULL;
+    PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, name2);
+    Py_XDECREF(name);
+    Py_XDECREF(name2);
+    return result;
+}
+
 #ifdef MS_WINDOWS
 PyObject *
 PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)
@@ -517,16 +538,31 @@
     PyObject *name = filename ?
                      PyUnicode_FromUnicode(filename, wcslen(filename)) :
              NULL;
-    PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
+    PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
     Py_XDECREF(name);
     return result;
 }
+
+PyObject *
+PyErr_SetFromErrnoWithUnicodeFilenames(PyObject *exc, const Py_UNICODE *filename, const Py_UNICODE *filename2)
+{
+    PyObject *name = filename ?
+                     PyUnicode_FromUnicode(filename, wcslen(filename)) :
+             NULL;
+    PyObject *name2 = filename2 ?
+                     PyUnicode_FromUnicode(filename2, wcslen(filename2)) :
+             NULL;
+    PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, name2);
+    Py_XDECREF(name);
+    Py_XDECREF(name2);
+    return result;
+}
 #endif /* MS_WINDOWS */
 
 PyObject *
 PyErr_SetFromErrno(PyObject *exc)
 {
-    return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
+    return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL);
 }
 
 #ifdef MS_WINDOWS
@@ -536,6 +572,16 @@
     int ierr,
     PyObject *filenameObject)
 {
+    return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr,
+        filenameObject, NULL);
+}
+
+PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
+    PyObject *exc,
+    int ierr,
+    PyObject *filenameObject,
+    PyObject *filenameObject2)
+{
     int len;
     WCHAR *s_buf = NULL; /* Free via LocalFree */
     PyObject *message;
@@ -571,11 +617,15 @@
         return NULL;
     }
 
-    if (filenameObject == NULL)
-        filenameObject = Py_None;
-    /* This is the constructor signature for passing a Windows error code.
+    if (filenameObject == NULL) {
+        assert(filenameObject2 == NULL);
+        filenameObject = filenameObject2 = Py_None;
+    }
+    else if (filenameObject2 == NULL)
+        filenameObject2 = Py_None;
+    /* This is the constructor signature for OSError.
        The POSIX translation will be figured out by the constructor. */
-    args = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);
+    args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2);
     Py_DECREF(message);
 
     if (args != NULL) {
@@ -596,13 +646,31 @@
     const char *filename)
 {
     PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
-    PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
+    PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
                                                                  ierr,
-                                                                 name);
+                                                                 name,
+                                                                 NULL);
     Py_XDECREF(name);
     return ret;
 }
 
+PyObject *PyErr_SetExcFromWindowsErrWithFilenames(
+    PyObject *exc,
+    int ierr,
+    const char *filename,
+    const char *filename2)
+{
+    PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
+    PyObject *name2 = filename2 ? PyUnicode_DecodeFSDefault(filename2) : NULL;
+    PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
+                                                                 ierr,
+                                                                 name,
+                                                                 name2);
+    Py_XDECREF(name);
+    Py_XDECREF(name2);
+    return ret;
+}
+
 PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
     PyObject *exc,
     int ierr,
@@ -611,31 +679,69 @@
     PyObject *name = filename ?
                      PyUnicode_FromUnicode(filename, wcslen(filename)) :
              NULL;
-    PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
+    PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
                                                                  ierr,
-                                                                 name);
+                                                                 name,
+                                                                 NULL);
     Py_XDECREF(name);
     return ret;
 }
 
+PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilenames(
+    PyObject *exc,
+    int ierr,
+    const Py_UNICODE *filename,
+    const Py_UNICODE *filename2)
+{
+    PyObject *name = filename ?
+                     PyUnicode_FromUnicode(filename, wcslen(filename)) :
+             NULL;
+    PyObject *name2 = filename2 ?
+                     PyUnicode_FromUnicode(filename2, wcslen(filename2)) :
+             NULL;
+    PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
+                                                                 ierr,
+                                                                 name,
+                                                                 name2);
+    Py_XDECREF(name);
+    Py_XDECREF(name2);
+    return ret;
+}
+
 PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
 {
-    return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
+    return PyErr_SetExcFromWindowsErrWithFilenames(exc, ierr, NULL, NULL);
 }
 
 PyObject *PyErr_SetFromWindowsErr(int ierr)
 {
-    return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError,
-                                                  ierr, NULL);
+    return PyErr_SetExcFromWindowsErrWithFilenames(PyExc_OSError,
+                                                  ierr, NULL, NULL);
 }
+
+PyObject *PyErr_SetFromWindowsErrWithFilenames(
+    int ierr,
+    const char *filename,
+    const char *filename2)
+{
+    PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
+    PyObject *name2 = filename2 ? PyUnicode_DecodeFSDefault(filename2) : NULL;
+    PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
+                                                  PyExc_OSError,
+                                                  ierr, name, name2);
+    Py_XDECREF(name);
+    Py_XDECREF(name2);
+    return result;
+}
+
 PyObject *PyErr_SetFromWindowsErrWithFilename(
     int ierr,
     const char *filename)
 {
     PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
-    PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
+    PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
                                                   PyExc_OSError,
-                                                  ierr, name);
+                                                  ierr, name, NULL);
     Py_XDECREF(name);
     return result;
 }
@@ -647,12 +753,31 @@
     PyObject *name = filename ?
                      PyUnicode_FromUnicode(filename, wcslen(filename)) :
              NULL;
-    PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
+    PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
                                                   PyExc_OSError,
-                                                  ierr, name);
+                                                  ierr, name, NULL);
     Py_XDECREF(name);
     return result;
 }
+
+PyObject *PyErr_SetFromWindowsErrWithUnicodeFilenames(
+    int ierr,
+    const Py_UNICODE *filename,
+    const Py_UNICODE *filename2)
+{
+    PyObject *name = filename ?
+                     PyUnicode_FromUnicode(filename, wcslen(filename)) :
+             NULL;
+    PyObject *name2 = filename2 ?
+                     PyUnicode_FromUnicode(filename2, wcslen(filename2)) :
+             NULL;
+    PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
+                                                  PyExc_OSError,
+                                                  ierr, name, name2);
+    Py_XDECREF(name);
+    Py_XDECREF(name2);
+    return result;
+}
 #endif /* MS_WINDOWS */
 
 PyObject *