Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d38b1c7

Browse files
committed
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.
1 parent ac1af80 commit d38b1c7

5 files changed

Lines changed: 67 additions & 1 deletion

File tree

Doc/ext/extending.tex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,11 @@ \section{Extracting Parameters in Extension Functions
743743
\item[\samp{l} (integer) {[long int]}]
744744
Convert a Python integer to a C \ctype{long int}.
745745

746+
\item[\samp{L} (integer) {[LONG_LONG]}]
747+
Convert a Python integer to a C \ctype{long long}. This format is only
748+
available on platforms that support \ctype{long long} (or \ctype{_int64}
749+
on Windows).
750+
746751
\item[\samp{c} (string of length 1) {[char]}]
747752
Convert a Python character, represented as a string of length 1, to a
748753
C \ctype{char}.

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ Grant Edwards
114114
Lance Ellinghaus
115115
David Ely
116116
Jeff Epler
117+
Tom Epperly
117118
Stoffel Erasmus
118119
Michael Ernst
119120
Ben Escoto

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Build
1414

1515
C API
1616

17+
- PyLong_AsLongLong() now accepts int (as well as long) arguments.
18+
Consequently, PyArg_ParseTuple's 'L' code also accepts int (as well
19+
as long) arguments.
20+
1721
New platforms
1822

1923
Tests

Modules/_testcapimodule.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,55 @@ test_longlong_api(PyObject* self, PyObject* args)
255255
#undef F_U_TO_PY
256256
#undef F_PY_TO_U
257257

258+
/* Test the L code for PyArg_ParseTuple. This should deliver a LONG_LONG
259+
for both long and int arguments. The test may leak a little memory if
260+
it fails.
261+
*/
262+
static PyObject *
263+
test_L_code(PyObject *self, PyObject *args)
264+
{
265+
PyObject *tuple, *num;
266+
LONG_LONG value;
267+
268+
if (!PyArg_ParseTuple(args, ":test_L_code"))
269+
return NULL;
270+
271+
tuple = PyTuple_New(1);
272+
if (tuple == NULL)
273+
return NULL;
274+
275+
num = PyLong_FromLong(42);
276+
if (num == NULL)
277+
return NULL;
278+
279+
PyTuple_SET_ITEM(tuple, 0, num);
280+
281+
value = -1;
282+
if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
283+
return NULL;
284+
if (value != 42)
285+
return raiseTestError("test_L_code",
286+
"L code returned wrong value for long 42");
287+
288+
Py_DECREF(num);
289+
num = PyInt_FromLong(42);
290+
if (num == NULL)
291+
return NULL;
292+
293+
PyTuple_SET_ITEM(tuple, 0, num);
294+
295+
value = -1;
296+
if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
297+
return NULL;
298+
if (value != 42)
299+
return raiseTestError("test_L_code",
300+
"L code returned wrong value for int 42");
301+
302+
Py_DECREF(tuple);
303+
Py_INCREF(Py_None);
304+
return Py_None;
305+
}
306+
258307
#endif /* ifdef HAVE_LONG_LONG */
259308

260309
static PyObject *
@@ -291,6 +340,7 @@ static PyMethodDef TestMethods[] = {
291340
{"test_long_api", test_long_api, METH_VARARGS},
292341
#ifdef HAVE_LONG_LONG
293342
{"test_longlong_api", test_longlong_api, METH_VARARGS},
343+
{"test_L_code", test_L_code, METH_VARARGS},
294344
#endif
295345
{NULL, NULL} /* sentinel */
296346
};

Objects/longobject.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,13 @@ PyLong_AsLongLong(PyObject *vv)
679679
int one = 1;
680680
int res;
681681

682-
if (vv == NULL || !PyLong_Check(vv)) {
682+
if (vv == NULL) {
683+
PyErr_BadInternalCall();
684+
return -1;
685+
}
686+
if (!PyLong_Check(vv)) {
687+
if (PyInt_Check(vv))
688+
return (LONG_LONG)PyInt_AsLong(vv);
683689
PyErr_BadInternalCall();
684690
return -1;
685691
}

0 commit comments

Comments
 (0)