Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 669c882

Browse filesBrowse files
authored
Add PyLong_FromUInt64() and PyLong_AsUInt64() (#114)
1 parent 38e2d32 commit 669c882
Copy full SHA for 669c882

File tree

Expand file treeCollapse file tree

4 files changed

+168
-8
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+168
-8
lines changed

‎docs/api.rst

Copy file name to clipboardExpand all lines: docs/api.rst
+33-8Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,39 @@ Python 3.14
8989

9090
See `PyUnicodeWriter_Format() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicodeWriter_Format>`__.
9191

92+
.. c:function:: int PyLong_AsInt32(PyObject *obj, int32_t *pvalue)
93+
94+
See `PyLong_AsInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsInt32>`__.
95+
96+
.. c:function:: int PyLong_AsInt64(PyObject *obj, int64_t *pvalue)
97+
98+
See `PyLong_AsInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsInt64>`__.
99+
100+
.. c:function:: int PyLong_AsUInt32(PyObject *obj, uint32_t *pvalue)
101+
102+
See `PyLong_AsUInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsUInt32>`__.
103+
104+
.. c:function:: int PyLong_AsUInt64(PyObject *obj, uint64_t *pvalue)
105+
106+
See `PyLong_AsUInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_AsUInt64>`__.
107+
108+
.. c:function:: PyObject* PyLong_FromInt32(int32_t value)
109+
110+
See `PyLong_FromInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromInt32>`__.
111+
112+
.. c:function:: PyObject* PyLong_FromInt64(int64_t value)
113+
114+
See `PyLong_FromInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromInt64>`__.
115+
116+
.. c:function:: PyObject* PyLong_FromUInt32(uint32_t value)
117+
118+
See `PyLong_FromUInt32() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromUInt32>`__.
119+
120+
.. c:function:: PyObject* PyLong_FromUInt64(uint64_t value)
121+
122+
See `PyLong_FromUInt64() documentation <https://docs.python.org/dev/c-api/long.html#c.PyLong_FromUInt64>`__.
123+
124+
92125
Not supported:
93126

94127
* ``PyConfig_Get()``
@@ -108,14 +141,6 @@ Not supported:
108141
* ``PyInitConfig_SetInt()``
109142
* ``PyInitConfig_SetStr()``
110143
* ``PyInitConfig_SetStrList()``
111-
* ``PyLong_AsInt32()``
112-
* ``PyLong_AsInt64()``
113-
* ``PyLong_AsUInt32()``
114-
* ``PyLong_AsUInt64()``
115-
* ``PyLong_FromInt32()``
116-
* ``PyLong_FromInt64()``
117-
* ``PyLong_FromUInt32()``
118-
* ``PyLong_FromUInt64()``
119144
* ``PyType_GetBaseByToken()``
120145
* ``PyUnicodeWriter_DecodeUTF8Stateful()``
121146
* ``Py_InitializeFromInitConfig()``

‎docs/changelog.rst

Copy file name to clipboardExpand all lines: docs/changelog.rst
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ Changelog
55

66
* ``PyBytes_Join()``
77
* ``PyIter_NextItem()``
8+
* ``PyLong_AsInt32()``
9+
* ``PyLong_AsInt64()``
10+
* ``PyLong_AsUInt32()``
11+
* ``PyLong_AsUInt64()``
12+
* ``PyLong_FromInt32()``
13+
* ``PyLong_FromInt64()``
14+
* ``PyLong_FromUInt32()``
15+
* ``PyLong_FromUInt64()``
816
* ``PyUnicode_Equal()``
917
* ``Py_HashBuffer()``
1018

‎pythoncapi_compat.h

Copy file name to clipboardExpand all lines: pythoncapi_compat.h
+85Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ extern "C" {
4545
# define _PyObject_CAST(op) _Py_CAST(PyObject*, op)
4646
#endif
4747

48+
#ifndef Py_BUILD_ASSERT
49+
# define Py_BUILD_ASSERT(cond) \
50+
do { \
51+
(void)sizeof(char [1 - 2 * !(cond)]); \
52+
} while(0)
53+
#endif
54+
4855

4956
// bpo-42262 added Py_NewRef() to Python 3.10.0a3
5057
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
@@ -1605,6 +1612,84 @@ static inline int PyIter_NextItem(PyObject *iter, PyObject **item)
16051612
#endif
16061613

16071614

1615+
#if PY_VERSION_HEX < 0x030E00A0
1616+
static inline PyObject* PyLong_FromInt32(int32_t value)
1617+
{
1618+
Py_BUILD_ASSERT(sizeof(long) >= 4);
1619+
return PyLong_FromLong(value);
1620+
}
1621+
1622+
static inline PyObject* PyLong_FromInt64(int64_t value)
1623+
{
1624+
Py_BUILD_ASSERT(sizeof(long long) >= 8);
1625+
return PyLong_FromLongLong(value);
1626+
}
1627+
1628+
static inline PyObject* PyLong_FromUInt32(uint32_t value)
1629+
{
1630+
Py_BUILD_ASSERT(sizeof(unsigned long) >= 4);
1631+
return PyLong_FromUnsignedLong(value);
1632+
}
1633+
1634+
static inline PyObject* PyLong_FromUInt64(uint64_t value)
1635+
{
1636+
Py_BUILD_ASSERT(sizeof(unsigned long long) >= 8);
1637+
return PyLong_FromUnsignedLongLong(value);
1638+
}
1639+
1640+
static inline int PyLong_AsInt32(PyObject *obj, int32_t *pvalue)
1641+
{
1642+
Py_BUILD_ASSERT(sizeof(int) == 4);
1643+
int value = PyLong_AsInt(obj);
1644+
if (value == -1 && PyErr_Occurred()) {
1645+
return -1;
1646+
}
1647+
*pvalue = (int32_t)value;
1648+
return 0;
1649+
}
1650+
1651+
static inline int PyLong_AsInt64(PyObject *obj, int64_t *pvalue)
1652+
{
1653+
Py_BUILD_ASSERT(sizeof(long long) == 8);
1654+
long long value = PyLong_AsLongLong(obj);
1655+
if (value == -1 && PyErr_Occurred()) {
1656+
return -1;
1657+
}
1658+
*pvalue = (int64_t)value;
1659+
return 0;
1660+
}
1661+
1662+
static inline int PyLong_AsUInt32(PyObject *obj, uint32_t *pvalue)
1663+
{
1664+
Py_BUILD_ASSERT(sizeof(long) >= 4);
1665+
unsigned long value = PyLong_AsUnsignedLong(obj);
1666+
if (value == (unsigned long)-1 && PyErr_Occurred()) {
1667+
return -1;
1668+
}
1669+
#if SIZEOF_LONG > 4
1670+
if ((unsigned long)UINT32_MAX < value) {
1671+
PyErr_SetString(PyExc_OverflowError,
1672+
"Python int too large to convert to C uint32_t");
1673+
return -1;
1674+
}
1675+
#endif
1676+
*pvalue = (uint32_t)value;
1677+
return 0;
1678+
}
1679+
1680+
static inline int PyLong_AsUInt64(PyObject *obj, uint64_t *pvalue)
1681+
{
1682+
Py_BUILD_ASSERT(sizeof(long long) == 8);
1683+
unsigned long long value = PyLong_AsUnsignedLongLong(obj);
1684+
if (value == (unsigned long long)-1 && PyErr_Occurred()) {
1685+
return -1;
1686+
}
1687+
*pvalue = (uint64_t)value;
1688+
return 0;
1689+
}
1690+
#endif
1691+
1692+
16081693
#ifdef __cplusplus
16091694
}
16101695
#endif

‎tests/test_pythoncapi_compat_cext.c

Copy file name to clipboardExpand all lines: tests/test_pythoncapi_compat_cext.c
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,6 +1971,47 @@ test_iter(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
19711971
}
19721972

19731973

1974+
static PyObject *
1975+
test_long_stdint(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
1976+
{
1977+
PyObject *obj;
1978+
1979+
// Test PyLong_FromInt32() and PyLong_AsInt32()
1980+
obj = PyLong_FromInt32(INT32_C(-0x12345678));
1981+
assert(obj != NULL);
1982+
int32_t i32;
1983+
assert(PyLong_AsInt32(obj, &i32) == 0);
1984+
assert(i32 == INT32_C(-0x12345678));
1985+
Py_DECREF(obj);
1986+
1987+
// Test PyLong_FromUInt32() and PyLong_AsUInt32()
1988+
obj = PyLong_FromUInt32(UINT32_C(0xDEADBEEF));
1989+
assert(obj != NULL);
1990+
uint32_t u32;
1991+
assert(PyLong_AsUInt32(obj, &u32) == 0);
1992+
assert(u32 == UINT32_C(0xDEADBEEF));
1993+
Py_DECREF(obj);
1994+
1995+
// Test PyLong_FromInt64() and PyLong_AsInt64()
1996+
obj = PyLong_FromInt64(INT64_C(-0x12345678DEADBEEF));
1997+
assert(obj != NULL);
1998+
int64_t i64;
1999+
assert(PyLong_AsInt64(obj, &i64) == 0);
2000+
assert(i64 == INT64_C(-0x12345678DEADBEEF));
2001+
Py_DECREF(obj);
2002+
2003+
// Test PyLong_FromUInt64() and PyLong_AsUInt64()
2004+
obj = PyLong_FromUInt64(UINT64_C(0xDEADBEEF12345678));
2005+
assert(obj != NULL);
2006+
uint64_t u64;
2007+
assert(PyLong_AsUInt64(obj, &u64) == 0);
2008+
assert(u64 == UINT64_C(0xDEADBEEF12345678));
2009+
Py_DECREF(obj);
2010+
2011+
Py_RETURN_NONE;
2012+
}
2013+
2014+
19742015
static struct PyMethodDef methods[] = {
19752016
{"test_object", test_object, METH_NOARGS, _Py_NULL},
19762017
{"test_py_is", test_py_is, METH_NOARGS, _Py_NULL},
@@ -2016,6 +2057,7 @@ static struct PyMethodDef methods[] = {
20162057
#endif
20172058
{"test_bytes", test_bytes, METH_NOARGS, _Py_NULL},
20182059
{"test_iter", test_iter, METH_NOARGS, _Py_NULL},
2060+
{"test_long_stdint", test_long_stdint, METH_NOARGS, _Py_NULL},
20192061
{_Py_NULL, _Py_NULL, 0, _Py_NULL}
20202062
};
20212063

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.