]> granicus.if.org Git - python/commitdiff
SF [#466125] PyLong_AsLongLong works for any integer.
authorTim Peters <tim.peters@gmail.com>
Sun, 30 Sep 2001 05:09:37 +0000 (05:09 +0000)
committerTim Peters <tim.peters@gmail.com>
Sun, 30 Sep 2001 05:09:37 +0000 (05:09 +0000)
Generalize PyLong_AsLongLong to accept int arguments too.  The real point
is so that PyArg_ParseTuple's 'L' code does too.  That code was
undocumented (AFAICT), so documented it.

Doc/ext/extending.tex
Misc/ACKS
Misc/NEWS
Modules/_testcapimodule.c
Objects/longobject.c

index d3661ab40f6f40cdaefaa1451b5d20c906b23609..87d3736870cd2e4e3265c674148ffb0dca489830 100644 (file)
@@ -743,6 +743,11 @@ Convert a Python integer to a plain C \ctype{int}.
 \item[\samp{l} (integer) {[long int]}]
 Convert a Python integer to a C \ctype{long int}.
 
+\item[\samp{L} (integer) {[LONG_LONG]}]
+Convert a Python integer to a C \ctype{long long}.  This format is only
+available on platforms that support \ctype{long long} (or \ctype{_int64}
+on Windows).
+
 \item[\samp{c} (string of length 1) {[char]}]
 Convert a Python character, represented as a string of length 1, to a
 C \ctype{char}.
index 3b6802c874247bdd4543b7dbb4c1f20a88cf1b3b..5352b15c3eded3a586a55326a92d54c1c92c5dcd 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -114,6 +114,7 @@ Grant Edwards
 Lance Ellinghaus
 David Ely
 Jeff Epler
+Tom Epperly
 Stoffel Erasmus
 Michael Ernst
 Ben Escoto
index c05ff95b25d302f0d4fb7f313c6a578ed86293ae..1b2b76b9578859248ccc0231d7085edca69e8b79 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -14,6 +14,10 @@ Build
 
 C API
 
+- PyLong_AsLongLong() now accepts int (as well as long) arguments.
+  Consequently, PyArg_ParseTuple's 'L' code also accepts int (as well
+  as long) arguments.
+
 New platforms
 
 Tests
index 1a875f77c0167f8b8df61b82a29a90c426ab6f0a..b17a277b9cf10b9df5e6297ccf9b0b68160a85b7 100644 (file)
@@ -255,6 +255,55 @@ test_longlong_api(PyObject* self, PyObject* args)
 #undef F_U_TO_PY
 #undef F_PY_TO_U
 
+/* Test the L code for PyArg_ParseTuple.  This should deliver a LONG_LONG
+   for both long and int arguments.  The test may leak a little memory if
+   it fails.
+*/
+static PyObject *
+test_L_code(PyObject *self, PyObject *args)
+{
+       PyObject *tuple, *num;
+       LONG_LONG value;
+
+        if (!PyArg_ParseTuple(args, ":test_L_code"))
+                return NULL;
+
+        tuple = PyTuple_New(1);
+        if (tuple == NULL)
+               return NULL;
+
+        num = PyLong_FromLong(42);
+        if (num == NULL)
+               return NULL;
+
+        PyTuple_SET_ITEM(tuple, 0, num);
+
+        value = -1;
+        if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
+               return NULL;
+        if (value != 42)
+               return raiseTestError("test_L_code",
+                       "L code returned wrong value for long 42");
+
+       Py_DECREF(num);
+        num = PyInt_FromLong(42);
+        if (num == NULL)
+               return NULL;
+
+        PyTuple_SET_ITEM(tuple, 0, num);
+
+       value = -1;
+        if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
+               return NULL;
+        if (value != 42)
+               return raiseTestError("test_L_code",
+                       "L code returned wrong value for int 42");
+
+       Py_DECREF(tuple);
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
 #endif /* ifdef HAVE_LONG_LONG */
 
 static PyObject *
@@ -291,6 +340,7 @@ static PyMethodDef TestMethods[] = {
        {"test_long_api",       test_long_api,          METH_VARARGS},
 #ifdef HAVE_LONG_LONG
        {"test_longlong_api",   test_longlong_api,      METH_VARARGS},
+       {"test_L_code",         test_L_code,            METH_VARARGS},
 #endif
        {NULL, NULL} /* sentinel */
 };
index 8f7d9e4f8412e49234e19d7b830d180d4f78469a..be4af3f2e61478115f9d3c008aac130285da26d4 100644 (file)
@@ -679,7 +679,13 @@ PyLong_AsLongLong(PyObject *vv)
        int one = 1;
        int res;
 
-       if (vv == NULL || !PyLong_Check(vv)) {
+       if (vv == NULL) {
+               PyErr_BadInternalCall();
+               return -1;
+       }
+       if (!PyLong_Check(vv)) {
+               if (PyInt_Check(vv))
+                       return (LONG_LONG)PyInt_AsLong(vv);
                PyErr_BadInternalCall();
                return -1;
        }