From d38b1c74f3f28a3f9a73c142d9be83425adaa6e1 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sun, 30 Sep 2001 05:09:37 +0000 Subject: SF [#466125] PyLong_AsLongLong works for any integer. 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 | 5 +++++ Misc/ACKS | 1 + Misc/NEWS | 4 ++++ Modules/_testcapimodule.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ Objects/longobject.c | 8 +++++++- 5 files changed, 67 insertions(+), 1 deletion(-) 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; } -- cgit v0.12