From 4141e9b8daf3850e6eff48f19df84b22736a7fe3 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 29 Jul 2022 20:44:48 +0300 Subject: [PATCH 1/5] Add PyLong_FromUintptr_t and PyLong_AsUintptr_t --- Doc/c-api/long.rst | 17 +++++++++++++++++ Doc/data/refcounts.dat | 6 ++++++ Doc/data/stable_abi.dat | 2 ++ Doc/whatsnew/3.12.rst | 4 ++++ Include/longobject.h | 2 ++ Lib/test/test_stable_abi_ctypes.py | 2 ++ Misc/ACKS | 1 + ...022-07-29-20-10-07.gh-issue-95417.vyK6p6.rst | 2 ++ Misc/stable_abi.toml | 4 ++++ Objects/longobject.c | 17 +++++++++++++++++ PC/python3dll.c | 2 ++ 11 files changed, 59 insertions(+) create mode 100644 Misc/NEWS.d/next/C API/2022-07-29-20-10-07.gh-issue-95417.vyK6p6.rst diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 56a7c069de908e..1d7d884fd9c7ff 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 1694cad6f43ba7..62832e49873038 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -1169,6 +1169,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: @@ -1213,6 +1216,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 82cd5796efd27d..aa222091ee4067 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -352,6 +352,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,, @@ -363,6 +364,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 0c53bc0c1111d7..72683c82c36fd9 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -403,6 +403,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`.) + Porting to Python 3.12 ---------------------- 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 53e93ab6b9b4c9..422b5e296ddc7b 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 32475f874c36db..fbe047a77d7c00 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -806,6 +806,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 84bec827096050..7c68f57ac81f98 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -924,6 +924,8 @@ added = '3.2' [function.PyLong_AsUnsignedLong] added = '3.2' +[function.PyLong_AsUintptr_t] + added = '3.12' [function.PyLong_AsUnsignedLongLong] added = '3.2' [function.PyLong_AsUnsignedLongLongMask] @@ -942,6 +944,8 @@ added = '3.2' [function.PyLong_FromSsize_t] added = '3.2' +[function.PyLong_FromUintptr_t] + added = '3.12' [function.PyLong_FromString] added = '3.2' [function.PyLong_FromUnsignedLong] diff --git a/Objects/longobject.c b/Objects/longobject.c index 90ed02b8c27a19..966bdff608a272 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -732,6 +732,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. */ @@ -1222,6 +1231,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 024ec49d68d797..41b1f9082bee93 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) From 5922fe7045441dc590d0f7275098d776cf178731 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 29 Jul 2022 21:48:54 +0300 Subject: [PATCH 2/5] Restore alphabetical order in stable_abi.toml --- Misc/stable_abi.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 7c68f57ac81f98..92ff0b977e1e79 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -922,10 +922,10 @@ added = '3.2' [function.PyLong_AsSsize_t] added = '3.2' -[function.PyLong_AsUnsignedLong] - added = '3.2' [function.PyLong_AsUintptr_t] added = '3.12' +[function.PyLong_AsUnsignedLong] + added = '3.2' [function.PyLong_AsUnsignedLongLong] added = '3.2' [function.PyLong_AsUnsignedLongLongMask] @@ -944,10 +944,10 @@ added = '3.2' [function.PyLong_FromSsize_t] added = '3.2' -[function.PyLong_FromUintptr_t] - added = '3.12' [function.PyLong_FromString] added = '3.2' +[function.PyLong_FromUintptr_t] + added = '3.12' [function.PyLong_FromUnsignedLong] added = '3.2' [function.PyLong_FromUnsignedLongLong] From a33b087bd8970fde4706db3bf45e43aaae9b46fe Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Thu, 4 Aug 2022 18:58:17 +0300 Subject: [PATCH 3/5] Remove an extra empty line between 2nd level headers --- Doc/whatsnew/3.12.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index de89d00a7c9f4d..1968fcfc065b40 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -427,7 +427,6 @@ New Features inherit the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. (Contributed by Petr Viktorin in :gh:`93012`.) - Porting to Python 3.12 ---------------------- From 70138bf970e9a305b797ba589c193cd6d8d5396a Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sat, 13 Aug 2022 16:20:07 +0400 Subject: [PATCH 4/5] Cleanup post-merge discrepancies --- Doc/whatsnew/3.12.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 7ce1633fff6bdd..e6e1828ba6ff69 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -446,8 +446,7 @@ New Features * :c:func:`PyVectorcall_Call` * :c:type:`vectorcallfunc` -* (XXX: this should be combined with :gh:`93274` when that is done) - The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class +* The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class when the class's :py:meth:`~object.__call__` method is reassigned. This makes vectorcall safe to use with mutable types (i.e. heap types without the :const:`immutable ` flag). From 8108397f4a07e1991957fa4c830a5f7ab846669c Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sat, 13 Aug 2022 16:22:10 +0400 Subject: [PATCH 5/5] Once again --- Doc/whatsnew/3.12.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index e6e1828ba6ff69..174e80f744b624 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -446,7 +446,7 @@ New Features * :c:func:`PyVectorcall_Call` * :c:type:`vectorcallfunc` -* The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class + The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class when the class's :py:meth:`~object.__call__` method is reassigned. This makes vectorcall safe to use with mutable types (i.e. heap types without the :const:`immutable ` flag).