From 4ed63c9899845eba43c00f75a2193369bbc60ea3 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 8 Aug 2022 16:11:07 +0200 Subject: [PATCH] Revert "gh-93274: Expose receiving vectorcall in the Limited API (GH-95717)" This reverts commit 656dad702d3b25bf678ee9bd7109d98876946258. --- Doc/data/stable_abi.dat | 3 - Doc/whatsnew/3.12.rst | 14 +--- Include/abstract.h | 10 --- Include/cpython/abstract.h | 10 +-- Include/cpython/object.h | 3 + Include/object.h | 9 +-- Lib/test/test_call.py | 5 -- Lib/test/test_stable_abi_ctypes.py | 2 - ...2-08-01-16-21-39.gh-issue-93274.QoDHEu.rst | 3 - Misc/stable_abi.toml | 9 --- Modules/Setup.stdlib.in | 2 +- Modules/_testcapi/parts.h | 1 - Modules/_testcapi/vectorcall_limited.c | 77 ------------------- Modules/_testcapimodule.c | 3 - Objects/call.c | 8 -- PC/python3dll.c | 2 - PCbuild/_testcapi.vcxproj | 1 - PCbuild/_testcapi.vcxproj.filters | 3 - 18 files changed, 13 insertions(+), 152 deletions(-) delete mode 100644 Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst delete mode 100644 Modules/_testcapi/vectorcall_limited.c diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index fde62eacd00a7c..82cd5796efd27d 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -783,8 +783,6 @@ function,PyUnicode_WriteChar,3.7,, type,PyVarObject,3.2,,members member,PyVarObject.ob_base,3.2,, member,PyVarObject.ob_size,3.2,, -function,PyVectorcall_Call,3.12,, -function,PyVectorcall_NARGS,3.12,, type,PyWeakReference,3.2,,opaque function,PyWeakref_GetObject,3.2,, function,PyWeakref_NewProxy,3.2,, @@ -885,5 +883,4 @@ type,symtable,3.2,,opaque type,ternaryfunc,3.2,, type,traverseproc,3.2,, type,unaryfunc,3.2,, -type,vectorcallfunc,3.12,, type,visitproc,3.2,, diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index f1696cc4584cd5..ddf9e1f6a59b47 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -426,22 +426,14 @@ New Features an additional metaclass argument. (Contributed by Wenzel Jakob in :gh:`93012`.) -* API for creating objects that can be called using - :ref:`the vectorcall protocol ` was added to the - :ref:`Limited API `: - - * :const:`Py_TPFLAGS_HAVE_VECTORCALL` - * :c:func:`PyVectorcall_NARGS` - * :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 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). Mutable types that do not override :c:member:`~PyTypeObject.tp_call` now - inherit the ``Py_TPFLAGS_HAVE_VECTORCALL`` flag. - (Contributed by Petr Viktorin in :gh:`93274`.) + inherit the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + (Contributed by Petr Viktorin in :gh:`93012`.) Porting to Python 3.12 ---------------------- diff --git a/Include/abstract.h b/Include/abstract.h index 784ff7e928676f..576024e09c4101 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -228,16 +228,6 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs( PyObject *name, ...); -/* Given a vectorcall nargsf argument, return the actual number of arguments. - * (For use outside the limited API, this is re-defined as a static inline - * function in cpython/abstract.h) - */ -PyAPI_FUNC(Py_ssize_t) PyVectorcall_NARGS(size_t nargsf); - -/* Call "callable" (which must support vectorcall) with positional arguments - "tuple" and keyword arguments "dict". "dict" may also be NULL */ -PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); - /* Implemented elsewhere: diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 6da29cde9f6092..7038918f018880 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -53,12 +53,8 @@ PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( #define PY_VECTORCALL_ARGUMENTS_OFFSET \ (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1)) -// PyVectorcall_NARGS() is exported as a function for the stable ABI. -// Here (when we are not using the stable ABI), the name is overridden to -// call a static inline function for best performance. -#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n) static inline Py_ssize_t -_PyVectorcall_NARGS(size_t n) +PyVectorcall_NARGS(size_t n) { return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; } @@ -88,6 +84,10 @@ PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( size_t nargsf, PyObject *kwargs); +/* Call "callable" (which must support vectorcall) with positional arguments + "tuple" and keyword arguments "dict". "dict" may also be NULL */ +PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); + // Same as PyObject_Vectorcall(), except without keyword arguments PyAPI_FUNC(PyObject *) _PyObject_FastCall( PyObject *func, diff --git a/Include/cpython/object.h b/Include/cpython/object.h index c80fc1df0e0ba4..a26fc7f6aadfb4 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -54,6 +54,9 @@ typedef struct _Py_Identifier { typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); typedef void (*releasebufferproc)(PyObject *, Py_buffer *); +typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + typedef struct { /* Number implementations must check *both* diff --git a/Include/object.h b/Include/object.h index 7d499d8b306e57..c00b9eb583420a 100644 --- a/Include/object.h +++ b/Include/object.h @@ -228,11 +228,6 @@ typedef int (*initproc)(PyObject *, PyObject *, PyObject *); typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030c0000 // 3.12 -typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames); -#endif - typedef struct{ int slot; /* slot id, see below */ void *pfunc; /* function pointer */ @@ -386,13 +381,11 @@ given type object has a specified feature. #define Py_TPFLAGS_BASETYPE (1UL << 10) /* Set if the type implements the vectorcall protocol (PEP 590) */ -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 -#define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) #ifndef Py_LIMITED_API +#define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) // Backwards compatibility alias for API that was provisional in Python 3.8 #define _Py_TPFLAGS_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL #endif -#endif /* Set if the type is 'ready' -- fully initialized */ #define Py_TPFLAGS_READY (1UL << 12) diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index d3a254f15b6291..6c81a154f65f47 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -759,11 +759,6 @@ def __call__(self, *args): self.assertEqual(expected, meth(*args1, **kwargs)) self.assertEqual(expected, wrapped(*args, **kwargs)) - def test_vectorcall_limited(self): - from _testcapi import pyobject_vectorcall - obj = _testcapi.LimitedVectorCallClass() - self.assertEqual(pyobject_vectorcall(obj, (), ()), "vectorcall called") - class A: def method_two_args(self, x, y): diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index a803e3a5025985..53e93ab6b9b4c9 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -782,8 +782,6 @@ def test_windows_feature_macros(self): "PyUnicode_Translate", "PyUnicode_Type", "PyUnicode_WriteChar", - "PyVectorcall_Call", - "PyVectorcall_NARGS", "PyWeakref_GetObject", "PyWeakref_NewProxy", "PyWeakref_NewRef", diff --git a/Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst b/Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst deleted file mode 100644 index da6cce4a7b283a..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst +++ /dev/null @@ -1,3 +0,0 @@ -API for implementing vectorcall (:c:data:`Py_TPFLAGS_HAVE_VECTORCALL`, -:c:func:`PyVectorcall_NARGS` and :c:func:`PyVectorcall_Call`) was added to -the limited API and stable ABI. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 4da002a0586299..84bec827096050 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2275,14 +2275,5 @@ added = '3.11' [function.PyErr_SetHandledException] added = '3.11' - [function.PyType_FromMetaclass] added = '3.12' -[const.Py_TPFLAGS_HAVE_VECTORCALL] - added = '3.12' -[function.PyVectorcall_NARGS] - added = '3.12' -[function.PyVectorcall_Call] - added = '3.12' -[typedef.vectorcallfunc] - added = '3.12' diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 908e6df9766731..c5dc1e8eb45377 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -169,7 +169,7 @@ @MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c @MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c -@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c +@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c # Some testing modules MUST be built as shared libraries. *shared* diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index 4b672c9d05bddd..e6d2ed23cb18e7 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -1,5 +1,4 @@ #include "Python.h" int _PyTestCapi_Init_Vectorcall(PyObject *module); -int _PyTestCapi_Init_VectorcallLimited(PyObject *module); int _PyTestCapi_Init_Heaptype(PyObject *module); diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c deleted file mode 100644 index 63ea3b3101b276..00000000000000 --- a/Modules/_testcapi/vectorcall_limited.c +++ /dev/null @@ -1,77 +0,0 @@ -#define Py_LIMITED_API 0x030c0000 // 3.12 -#include "parts.h" -#include "structmember.h" // PyMemberDef - -/* Test Vectorcall in the limited API */ - -static PyObject * -LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { - return PyUnicode_FromString("tp_call called"); -} - -static PyObject * -LimitedVectorCallClass_vectorcall(PyObject *callable, - PyObject *const *args, - size_t nargsf, - PyObject *kwnames) { - return PyUnicode_FromString("vectorcall called"); -} - -static PyObject * -LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw) -{ - PyObject *self = ((allocfunc)PyType_GetSlot(tp, Py_tp_alloc))(tp, 0); - if (!self) { - return NULL; - } - *(vectorcallfunc*)((char*)self + sizeof(PyObject)) = ( - LimitedVectorCallClass_vectorcall); - return self; -} - -static PyMemberDef LimitedVectorCallClass_members[] = { - {"__vectorcalloffset__", T_PYSSIZET, sizeof(PyObject), READONLY}, - {NULL} -}; - -static PyType_Slot LimitedVectorallClass_slots[] = { - {Py_tp_new, LimitedVectorCallClass_new}, - {Py_tp_call, LimitedVectorCallClass_tpcall}, - {Py_tp_members, LimitedVectorCallClass_members}, - {0}, -}; - -static PyType_Spec LimitedVectorCallClass_spec = { - .name = "_testcapi.LimitedVectorCallClass", - .basicsize = (int)(sizeof(PyObject) + sizeof(vectorcallfunc)), - .flags = Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_HAVE_VECTORCALL - | Py_TPFLAGS_BASETYPE, - .slots = LimitedVectorallClass_slots, -}; - -static PyMethodDef TestMethods[] = { - /* Add module methods here. - * (Empty list left here as template/example, since using - * PyModule_AddFunctions isn't very common.) - */ - {NULL}, -}; - -int -_PyTestCapi_Init_VectorcallLimited(PyObject *m) { - if (PyModule_AddFunctions(m, TestMethods) < 0) { - return -1; - } - - PyObject *LimitedVectorCallClass = PyType_FromModuleAndSpec( - m, &LimitedVectorCallClass_spec, NULL); - if (!LimitedVectorCallClass) { - return -1; - } - if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) { - return -1; - } - - return 0; -} diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 8004fa18bcc528..517591465b4914 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6865,9 +6865,6 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Vectorcall(m) < 0) { return NULL; } - if (_PyTestCapi_Init_VectorcallLimited(m) < 0) { - return NULL; - } if (_PyTestCapi_Init_Heaptype(m) < 0) { return NULL; } diff --git a/Objects/call.c b/Objects/call.c index c2509db2a9a263..ed168c9c4796e2 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1047,11 +1047,3 @@ _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, PyMem_Free((PyObject **)stack - 1); Py_DECREF(kwnames); } - -// Export for the stable ABI -#undef PyVectorcall_NARGS -Py_ssize_t -PyVectorcall_NARGS(size_t n) -{ - return _PyVectorcall_NARGS(n); -} diff --git a/PC/python3dll.c b/PC/python3dll.c index 89bbd05932b853..024ec49d68d797 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -723,8 +723,6 @@ EXPORT_FUNC(PyUnicodeTranslateError_GetStart) EXPORT_FUNC(PyUnicodeTranslateError_SetEnd) EXPORT_FUNC(PyUnicodeTranslateError_SetReason) EXPORT_FUNC(PyUnicodeTranslateError_SetStart) -EXPORT_FUNC(PyVectorcall_Call) -EXPORT_FUNC(PyVectorcall_NARGS) EXPORT_FUNC(PyWeakref_GetObject) EXPORT_FUNC(PyWeakref_NewProxy) EXPORT_FUNC(PyWeakref_NewRef) diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index 0cb4e44cf73444..a88540cab19f9a 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -95,7 +95,6 @@ - diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index 4da972f279c8a3..a43ab5ea0ff941 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -15,9 +15,6 @@ Source Files - - Source Files - Source Files