Skip to content

Commit 8109811

Browse files
authored
Add PyLong_AsInt() function (python#72)
1 parent 4734c8e commit 8109811

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

docs/api.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ Python 3.13
7575
7676
See `Py_IsFinalizing() documentation <https://docs.python.org/dev/c-api/init.html#c.Py_IsFinalizing>`__.
7777
78+
.. c:function:: int PyDict_ContainsString(PyObject *p, const char *key)
79+
80+
See `PyDict_ContainsString() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_ContainsString>`__.
81+
82+
.. c:function:: int PyLong_AsInt(PyObject *obj)
83+
84+
See `PyLong_AsInt() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsInt>`__.
85+
7886
7987
Python 3.12
8088
-----------

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Changelog
22
=========
33

4+
* 2023-08-25: Add ``PyDict_ContainsString()`` and ``PyLong_AsInt()`` functions.
45
* 2023-08-21: Remove support for Python 2.7, Python 3.4 and older.
56
* 2023-08-16: Add ``Py_IsFinalizing()`` function.
67
* 2023-07-21: Add ``PyDict_GetItemRef()`` function.

pythoncapi_compat.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,28 @@ static inline int PyDict_ContainsString(PyObject *op, const char *key)
834834
#endif
835835

836836

837+
// gh-108445 added PyLong_AsInt() to Python 3.13.0a1
838+
#if PY_VERSION_HEX < 0x030D00A1
839+
static inline int PyLong_AsInt(PyObject *obj)
840+
{
841+
#ifdef PYPY_VERSION
842+
long value = PyLong_AsLong(obj);
843+
if (value == -1 && PyErr_Occurred()) {
844+
return -1;
845+
}
846+
if (value < (long)INT_MIN || (long)INT_MAX < value) {
847+
PyErr_SetString(PyExc_OverflowError,
848+
"Python int too large to convert to C int");
849+
return -1;
850+
}
851+
return (int)value;
852+
#else
853+
return _PyLong_AsInt(obj);
854+
#endif
855+
}
856+
#endif
857+
858+
837859
#ifdef __cplusplus
838860
}
839861
#endif

tests/test_pythoncapi_compat_cext.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,35 @@ test_dict_api(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
12091209
}
12101210

12111211

1212+
static PyObject *
1213+
test_long_api(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
1214+
{
1215+
// test PyLong_AsInt()
1216+
assert(!PyErr_Occurred());
1217+
PyObject *obj = PyLong_FromLong(123);
1218+
if (obj == NULL) {
1219+
return NULL;
1220+
}
1221+
int value = PyLong_AsInt(obj);
1222+
assert(value == 123);
1223+
assert(!PyErr_Occurred());
1224+
Py_DECREF(obj);
1225+
1226+
// test PyLong_AsInt() with overflow
1227+
PyObject *obj2 = PyLong_FromLongLong((long long)INT_MAX + 1);
1228+
if (obj2 == NULL) {
1229+
return NULL;
1230+
}
1231+
value = PyLong_AsInt(obj2);
1232+
assert(value == -1);
1233+
assert(PyErr_ExceptionMatches(PyExc_OverflowError));
1234+
PyErr_Clear();
1235+
Py_DECREF(obj2);
1236+
1237+
Py_RETURN_NONE;
1238+
}
1239+
1240+
12121241
static struct PyMethodDef methods[] = {
12131242
{"test_object", test_object, METH_NOARGS, _Py_NULL},
12141243
{"test_py_is", test_py_is, METH_NOARGS, _Py_NULL},
@@ -1234,6 +1263,7 @@ static struct PyMethodDef methods[] = {
12341263
{"test_getattr", test_getattr, METH_NOARGS, _Py_NULL},
12351264
{"test_getitem", test_getitem, METH_NOARGS, _Py_NULL},
12361265
{"test_dict_api", test_dict_api, METH_NOARGS, _Py_NULL},
1266+
{"test_long_api", test_long_api, METH_NOARGS, _Py_NULL},
12371267
{_Py_NULL, _Py_NULL, 0, _Py_NULL}
12381268
};
12391269

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy