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.
This commit is contained in:
Tim Peters 2001-09-30 05:09:37 +00:00
parent ac1af8093e
commit d38b1c74f3
5 changed files with 67 additions and 1 deletions

View 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}.

View File

@ -114,6 +114,7 @@ Grant Edwards
Lance Ellinghaus
David Ely
Jeff Epler
Tom Epperly
Stoffel Erasmus
Michael Ernst
Ben Escoto

View File

@ -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

View 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 */
};

View 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;
}