Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.

PyLong_AsDouble() and PyLong_AsUnsignedLongLong() now raise TypeError (rather
than SystemError) when passed a non-integer argument, matching the behavior of
all the other PyLong_As*() functions.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 51c79c9..456a8a59 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -769,6 +769,68 @@
     return Py_None;
 }
 
+/* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that
+   non-integer arguments are handled correctly. It should be extended to
+   test overflow handling.
+ */
+
+static PyObject *
+test_long_as_size_t(PyObject *self)
+{
+    size_t out_u;
+    Py_ssize_t out_s;
+
+    Py_INCREF(Py_None);
+
+    out_u = PyLong_AsSize_t(Py_None);
+    if (out_u != (size_t)-1 || !PyErr_Occurred())
+        return raiseTestError("test_long_as_size_t",
+                              "PyLong_AsSize_t(None) didn't complain");
+    if (!PyErr_ExceptionMatches(PyExc_TypeError))
+        return raiseTestError("test_long_as_size_t",
+                              "PyLong_AsSize_t(None) raised "
+                              "something other than TypeError");
+    PyErr_Clear();
+
+    out_s = PyLong_AsSsize_t(Py_None);
+    if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred())
+        return raiseTestError("test_long_as_size_t",
+                              "PyLong_AsSsize_t(None) didn't complain");
+    if (!PyErr_ExceptionMatches(PyExc_TypeError))
+        return raiseTestError("test_long_as_size_t",
+                              "PyLong_AsSsize_t(None) raised "
+                              "something other than TypeError");
+    PyErr_Clear();
+
+    /* Py_INCREF(Py_None) omitted - we already have a reference to it. */
+    return Py_None;
+}
+
+/* Test the PyLong_AsDouble API. At present this just tests that
+   non-integer arguments are handled correctly.
+ */
+
+static PyObject *
+test_long_as_double(PyObject *self)
+{
+    double out;
+
+    Py_INCREF(Py_None);
+
+    out = PyLong_AsDouble(Py_None);
+    if (out != -1.0 || !PyErr_Occurred())
+        return raiseTestError("test_long_as_double",
+                              "PyLong_AsDouble(None) didn't complain");
+    if (!PyErr_ExceptionMatches(PyExc_TypeError))
+        return raiseTestError("test_long_as_double",
+                              "PyLong_AsDouble(None) raised "
+                              "something other than TypeError");
+    PyErr_Clear();
+
+    /* Py_INCREF(Py_None) omitted - we already have a reference to it. */
+    return Py_None;
+}
+
 /* Test the L code for PyArg_ParseTuple.  This should deliver a PY_LONG_LONG
    for both long and int arguments.  The test may leak a little memory if
    it fails.
@@ -2267,6 +2329,8 @@
     {"test_long_api",           (PyCFunction)test_long_api,      METH_NOARGS},
     {"test_long_and_overflow", (PyCFunction)test_long_and_overflow,
      METH_NOARGS},
+    {"test_long_as_double",     (PyCFunction)test_long_as_double,METH_NOARGS},
+    {"test_long_as_size_t",     (PyCFunction)test_long_as_size_t,METH_NOARGS},
     {"test_long_numbits",       (PyCFunction)test_long_numbits,  METH_NOARGS},
     {"test_k_code",             (PyCFunction)test_k_code,        METH_NOARGS},
     {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS},
diff --git a/Modules/testcapi_long.h b/Modules/testcapi_long.h
index fa94fd6..5784452 100644
--- a/Modules/testcapi_long.h
+++ b/Modules/testcapi_long.h
@@ -177,6 +177,32 @@
         Py_DECREF(one);
     }
 
+    /* Test F_PY_TO_{S,U} on non-pylong input. This should raise a TypeError. */
+    {
+        TYPENAME out;
+        unsigned TYPENAME uout;
+
+        Py_INCREF(Py_None);
+
+        out = F_PY_TO_S(Py_None);
+        if (out != (TYPENAME)-1 || !PyErr_Occurred())
+            return error("PyLong_AsXXX(None) didn't complain");
+        if (!PyErr_ExceptionMatches(PyExc_TypeError))
+            return error("PyLong_AsXXX(None) raised "
+                         "something other than TypeError");
+        PyErr_Clear();
+
+        uout = F_PY_TO_U(Py_None);
+        if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
+            return error("PyLong_AsXXX(None) didn't complain");
+        if (!PyErr_ExceptionMatches(PyExc_TypeError))
+            return error("PyLong_AsXXX(None) raised "
+                         "something other than TypeError");
+        PyErr_Clear();
+
+        Py_DECREF(Py_None);
+    }
+
     Py_INCREF(Py_None);
     return Py_None;
 }