summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/ext/extending.tex5
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/_testcapimodule.c50
-rw-r--r--Objects/longobject.c8
5 files changed, 67 insertions, 1 deletions
diff --git a/Doc/ext/extending.tex b/Doc/ext/extending.tex
index d3661ab..87d3736 100644
--- a/Doc/ext/extending.tex
+++ b/Doc/ext/extending.tex
@@ -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}.
diff --git a/Misc/ACKS b/Misc/ACKS
index 3b6802c..5352b15 100644
--- 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
diff --git a/Misc/NEWS b/Misc/NEWS
index c05ff95..1b2b76b 100644
--- 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
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 1a875f7..b17a277 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -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 */
};
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 8f7d9e4..be4af3f 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -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;
}