diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 4f6f865db8be13..c27a0f10d34ecf 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -62,6 +62,11 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. Return a new :c:type:`PyLongObject` object from a C :c:type:`size_t`, or ``NULL`` on failure. +.. c:function:: PyObject* PyLong_FromUintptr_t(uintptr_t p) + + Return a new :c:type:`PyLongObject` object from a C :c:type:`uintptr_t`, or + ``NULL`` on failure. + .. c:function:: PyObject* PyLong_FromLongLong(long long v) @@ -242,6 +247,18 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. Use :c:func:`PyErr_Occurred` to disambiguate. +.. c:function:: uintptr_t PyLong_AsUintptr_t(PyObject *pylong) + + Return a a C :c:type:`uintptr_t` representation of *pylong*. *pylong* + must be an instance of :c:type:`PyLongObject`. + + Raise :exc:`OverflowError` if the value of *pylong* is out of range for a + :c:type:`uintptr_t`. + + Returns ``(uintptr_t)-1`` on error. + Use :c:func:`PyErr_Occurred` to disambiguate. + + .. c:function:: unsigned long long PyLong_AsUnsignedLongLong(PyObject *pylong) .. index:: diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 51ccacf13f9e3b..39401bfd9d16af 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -1177,6 +1177,9 @@ PyLong_AsSize_t:PyObject*:pylong:0: PyLong_AsSsize_t:Py_ssize_t::: PyLong_AsSsize_t:PyObject*:pylong:0: +PyLong_AsUintptr_t:uintptr_t::: +PyLong_AsUintptr_t:PyObject*:pylong:0: + PyLong_AsUnsignedLong:unsigned long::: PyLong_AsUnsignedLong:PyObject*:pylong:0: @@ -1221,6 +1224,9 @@ PyLong_FromString:const char*:str:: PyLong_FromString:char**:pend:: PyLong_FromString:int:base:: +PyLong_FromUintptr_t:PyObject*::+1: +PyLong_FromUintptr_t:uintptr_t:v:: + PyLong_FromUnicodeObject:PyObject*::+1: PyLong_FromUnicodeObject:PyObject*:u:0: PyLong_FromUnicodeObject:int:base:: diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 133658491c5a4f..66364e783a8757 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -353,6 +353,7 @@ function,PyLong_AsLongLong,3.2,, function,PyLong_AsLongLongAndOverflow,3.2,, function,PyLong_AsSize_t,3.2,, function,PyLong_AsSsize_t,3.2,, +function,PyLong_AsUintptr_t,3.12,, function,PyLong_AsUnsignedLong,3.2,, function,PyLong_AsUnsignedLongLong,3.2,, function,PyLong_AsUnsignedLongLongMask,3.2,, @@ -364,6 +365,7 @@ function,PyLong_FromLongLong,3.2,, function,PyLong_FromSize_t,3.2,, function,PyLong_FromSsize_t,3.2,, function,PyLong_FromString,3.2,, +function,PyLong_FromUintptr_t,3.12,, function,PyLong_FromUnsignedLong,3.2,, function,PyLong_FromUnsignedLongLong,3.2,, function,PyLong_FromVoidPtr,3.2,, diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 0eb28799a4f5fa..d75bbf15f667f6 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -583,6 +583,10 @@ New Features an additional metaclass argument. (Contributed by Wenzel Jakob in :gh:`93012`.) +* Added limited C API :c:func:`PyLong_AsUintptr_t` and + :c:func:`PyLong_FromUintptr_t`. + (Contributed by Oleg Iarygin in :gh:`95417`.) + * API for creating objects that can be called using :ref:`the vectorcall protocol ` was added to the :ref:`Limited API `: diff --git a/Include/longobject.h b/Include/longobject.h index e559e238ae5a35..265d67a78bd9fb 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -17,11 +17,13 @@ PyAPI_FUNC(PyObject *) PyLong_FromLong(long); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); +PyAPI_FUNC(PyObject *) PyLong_FromUintptr_t(uintptr_t); PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); PyAPI_FUNC(long) PyLong_AsLong(PyObject *); PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *); +PyAPI_FUNC(uintptr_t) PyLong_AsUintptr_t(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 67c653428a6dee..c31877aa7150cb 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -374,6 +374,7 @@ def test_windows_feature_macros(self): "PyLong_AsLongLongAndOverflow", "PyLong_AsSize_t", "PyLong_AsSsize_t", + "PyLong_AsUintptr_t", "PyLong_AsUnsignedLong", "PyLong_AsUnsignedLongLong", "PyLong_AsUnsignedLongLongMask", @@ -385,6 +386,7 @@ def test_windows_feature_macros(self): "PyLong_FromSize_t", "PyLong_FromSsize_t", "PyLong_FromString", + "PyLong_FromUintptr_t", "PyLong_FromUnsignedLong", "PyLong_FromUnsignedLongLong", "PyLong_FromVoidPtr", diff --git a/Misc/ACKS b/Misc/ACKS index 5d97067b85d3d4..118204352b9e18 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -810,6 +810,7 @@ Oleg Höfling Robert Hölzl Stefan Hölzl Catalin Iacob +Oleg Iarygin Mihai Ibanescu Ali Ikinci Aaron Iles diff --git a/Misc/NEWS.d/next/C API/2022-07-29-20-10-07.gh-issue-95417.vyK6p6.rst b/Misc/NEWS.d/next/C API/2022-07-29-20-10-07.gh-issue-95417.vyK6p6.rst new file mode 100644 index 00000000000000..082206b0fbaa04 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-07-29-20-10-07.gh-issue-95417.vyK6p6.rst @@ -0,0 +1,2 @@ +Added :c:func:`PyLong_AsUintptr_t` and :c:func:`PyLong_FromUintptr_t`. Patch +by Oleg Iarygin. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index e18a6e8f6a9c2c..ba4797a1f9977a 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -929,6 +929,8 @@ added = '3.2' [function.PyLong_AsSsize_t] added = '3.2' +[function.PyLong_AsUintptr_t] + added = '3.12' [function.PyLong_AsUnsignedLong] added = '3.2' [function.PyLong_AsUnsignedLongLong] @@ -951,6 +953,8 @@ added = '3.2' [function.PyLong_FromString] added = '3.2' +[function.PyLong_FromUintptr_t] + added = '3.12' [function.PyLong_FromUnsignedLong] added = '3.2' [function.PyLong_FromUnsignedLongLong] diff --git a/Objects/longobject.c b/Objects/longobject.c index cf859ccb970730..3a0ab1c8ef3830 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -738,6 +738,15 @@ PyLong_AsSize_t(PyObject *vv) return x; } +/* Get a C uintptr_t from an int object. Returns (uintptr_t)-1 and sets + an error condition if overflow occurs. */ + +uintptr_t +PyLong_AsUintptr_t(PyObject *vv) +{ + return (uintptr_t)PyLong_AsVoidPtr(vv); +} + /* Get a C unsigned long int from an int object, ignoring the high bits. Returns -1 and sets an error condition if an error occurs. */ @@ -1228,6 +1237,14 @@ PyLong_FromSsize_t(Py_ssize_t ival) return (PyObject *)v; } +/* Create a new int object from a C uintptr_t. */ + +PyObject * +PyLong_FromUintptr_t(uintptr_t ival) +{ + return PyLong_FromVoidPtr((void *)ival); +} + /* Get a C long long int from an int object or any object that has an __index__ method. Return -1 and set an error if overflow occurs. */ diff --git a/PC/python3dll.c b/PC/python3dll.c index 931f316bb99843..bb9015c7b998e1 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -330,6 +330,7 @@ EXPORT_FUNC(PyLong_AsLongLong) EXPORT_FUNC(PyLong_AsLongLongAndOverflow) EXPORT_FUNC(PyLong_AsSize_t) EXPORT_FUNC(PyLong_AsSsize_t) +EXPORT_FUNC(PyLong_AsUintptr_t) EXPORT_FUNC(PyLong_AsUnsignedLong) EXPORT_FUNC(PyLong_AsUnsignedLongLong) EXPORT_FUNC(PyLong_AsUnsignedLongLongMask) @@ -341,6 +342,7 @@ EXPORT_FUNC(PyLong_FromLongLong) EXPORT_FUNC(PyLong_FromSize_t) EXPORT_FUNC(PyLong_FromSsize_t) EXPORT_FUNC(PyLong_FromString) +EXPORT_FUNC(PyLong_FromUintptr_t) EXPORT_FUNC(PyLong_FromUnsignedLong) EXPORT_FUNC(PyLong_FromUnsignedLongLong) EXPORT_FUNC(PyLong_FromVoidPtr)