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:
parent
ac1af8093e
commit
d38b1c74f3
|
@ -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}.
|
||||
|
|
|
@ -114,6 +114,7 @@ Grant Edwards
|
|||
Lance Ellinghaus
|
||||
David Ely
|
||||
Jeff Epler
|
||||
Tom Epperly
|
||||
Stoffel Erasmus
|
||||
Michael Ernst
|
||||
Ben Escoto
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue