diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index 9713431688d499..b7cdf293d22380 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -27,9 +27,18 @@ unit; the entry in (round) parentheses is the Python object type that matches the format unit; and the entry in [square] brackets is the type of the C variable(s) whose address should be passed. +.. _arg-parsing-string-and-buffers: + Strings and buffers ------------------- +.. note:: + + On Python 3.12 and older, the macro :c:macro:`!PY_SSIZE_T_CLEAN` must be + defined before including :file:`Python.h` to use all ``#`` variants of + formats (``s#``, ``y#``, etc.) explained below. + This is not necessary on Python 3.13 and later. + These formats allow accessing an object as a contiguous chunk of memory. You don't have to provide raw storage for the returned unicode or bytes area. @@ -68,15 +77,6 @@ There are three ways strings and buffers can be converted to C: whether the input object is immutable (e.g. whether it would honor a request for a writable buffer, or whether another thread can mutate the data). -.. note:: - - For all ``#`` variants of formats (``s#``, ``y#``, etc.), the macro - :c:macro:`PY_SSIZE_T_CLEAN` must be defined before including - :file:`Python.h`. On Python 3.9 and older, the type of the length argument - is :c:type:`Py_ssize_t` if the :c:macro:`PY_SSIZE_T_CLEAN` macro is defined, - or int otherwise. - - ``s`` (:class:`str`) [const char \*] Convert a Unicode object to a C pointer to a character string. A pointer to an existing string is stored in the character pointer diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index d9bf4fd6c7ae0e..c37b69f988a6b4 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -70,7 +70,7 @@ the module and a copyright notice if you like). headers are included. It is recommended to always define ``PY_SSIZE_T_CLEAN`` before including - ``Python.h``. See :ref:`parsetuple` for a description of this macro. + ``Python.h``. See :ref:`arg-parsing-string-and-buffers` for a description of this macro. All user-visible symbols defined by :file:`Python.h` have a prefix of ``Py`` or ``PY``, except those defined in standard header files. For convenience, and @@ -649,7 +649,7 @@ Note that any Python object references which are provided to the caller are Some example calls:: - #define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */ + #define PY_SSIZE_T_CLEAN #include :: @@ -745,7 +745,7 @@ it returns false and raises an appropriate exception. Here is an example module which uses keywords, based on an example by Geoff Philbrick (philbrick@hks.com):: - #define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */ + #define PY_SSIZE_T_CLEAN #include static PyObject * diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 44c0915492dcc0..13b9be1c8ee23f 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -292,6 +292,13 @@ C API Changes New Features ------------ +* You no longer have to define the ``PY_SSIZE_T_CLEAN`` macro before including + :file:`Python.h` when using ``#`` formats in + :ref:`format codes `. + APIs accepting the format codes always use ``Py_ssize_t`` for ``#`` formats. + (Contributed by Inada Naoki in :gh:`104922`.) + + Porting to Python 3.13 ---------------------- diff --git a/Include/abstract.h b/Include/abstract.h index 064b0300b51ea2..b4c2bedef442bf 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -135,12 +135,6 @@ extern "C" { This function always succeeds. */ -#ifdef PY_SSIZE_T_CLEAN -# define PyObject_CallFunction _PyObject_CallFunction_SizeT -# define PyObject_CallMethod _PyObject_CallMethod_SizeT -#endif - - #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 /* Call a callable Python object without any arguments */ PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func); @@ -195,15 +189,6 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...); -PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable, - const char *format, - ...); - -PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj, - const char *name, - const char *format, - ...); - /* Call a callable Python object 'callable' with a variable number of C arguments. The C arguments are provided as PyObject* values, terminated by a NULL. diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 3b27aab2fc4798..992dd068db90ea 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -4,10 +4,6 @@ /* === Object Protocol ================================================== */ -#ifdef PY_SSIZE_T_CLEAN -# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT -#endif - /* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) format to a Python dictionary ("kwargs" dict). @@ -113,11 +109,6 @@ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, const char *format, ...); -PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, - _Py_Identifier *name, - const char *format, - ...); - PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( PyObject *obj, _Py_Identifier *name, diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h index 88f34fe7513bf2..a5d95d15440df1 100644 --- a/Include/cpython/modsupport.h +++ b/Include/cpython/modsupport.h @@ -2,20 +2,6 @@ # error "this header file must not be included directly" #endif -/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier - to mean Py_ssize_t */ -#ifdef PY_SSIZE_T_CLEAN -#define _Py_VaBuildStack _Py_VaBuildStack_SizeT -#else -PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); -PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT( - PyObject **small_stack, - Py_ssize_t small_stack_len, - const char *format, - va_list va, - Py_ssize_t *p_nargs); -#endif - PyAPI_FUNC(int) _PyArg_UnpackStack( PyObject *const *args, Py_ssize_t nargs, @@ -63,13 +49,6 @@ typedef struct _PyArg_Parser { struct _PyArg_Parser *next; } _PyArg_Parser; -#ifdef PY_SSIZE_T_CLEAN -#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT -#define _PyArg_ParseStack _PyArg_ParseStack_SizeT -#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT -#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT -#endif - PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, struct _PyArg_Parser *, ...); PyAPI_FUNC(int) _PyArg_ParseStack( diff --git a/Include/modsupport.h b/Include/modsupport.h index 4e369bd56b4d20..7d4cfe853aaa7e 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -9,34 +9,17 @@ extern "C" { #include // va_list -/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier - to mean Py_ssize_t */ -#ifdef PY_SSIZE_T_CLEAN -#define PyArg_Parse _PyArg_Parse_SizeT -#define PyArg_ParseTuple _PyArg_ParseTuple_SizeT -#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT -#define PyArg_VaParse _PyArg_VaParse_SizeT -#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT -#define Py_BuildValue _Py_BuildValue_SizeT -#define Py_VaBuildValue _Py_VaBuildValue_SizeT -#endif - -/* Due to a glitch in 3.2, the _SizeT versions weren't exported from the DLL. */ -#if !defined(PY_SSIZE_T_CLEAN) || !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); + const char *, char **, ...); PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, va_list); -#endif + const char *, char **, va_list); + PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *); PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); -PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); - - PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); // Add an attribute with name 'name' and value 'obj' to the module 'mod. diff --git a/Lib/test/test_capi/test_getargs.py b/Lib/test/test_capi/test_getargs.py index 3792d1a6515b44..01bc30779add73 100644 --- a/Lib/test/test_capi/test_getargs.py +++ b/Lib/test/test_capi/test_getargs.py @@ -901,23 +901,6 @@ def test_s_hash(self): self.assertRaises(TypeError, getargs_s_hash, memoryview(b'memoryview')) self.assertRaises(TypeError, getargs_s_hash, None) - def test_s_hash_int(self): - # "s#" without PY_SSIZE_T_CLEAN defined. - from _testcapi import getargs_s_hash_int - from _testcapi import getargs_s_hash_int2 - buf = bytearray([1, 2]) - self.assertRaises(SystemError, getargs_s_hash_int, buf, "abc") - self.assertRaises(SystemError, getargs_s_hash_int, buf, x=42) - self.assertRaises(SystemError, getargs_s_hash_int, buf, x="abc") - self.assertRaises(SystemError, getargs_s_hash_int2, buf, ("abc",)) - self.assertRaises(SystemError, getargs_s_hash_int2, buf, x=42) - self.assertRaises(SystemError, getargs_s_hash_int2, buf, x="abc") - buf.append(3) # still mutable -- not locked by a buffer export - # getargs_s_hash_int(buf) may not raise SystemError because skipitem() - # is not called. But it is an implementation detail. - # getargs_s_hash_int(buf) - # getargs_s_hash_int2(buf) - def test_z(self): from _testcapi import getargs_z self.assertEqual(getargs_z('abc\xe9'), b'abc\xc3\xa9') diff --git a/Misc/NEWS.d/next/C API/2023-05-29-16-09-27.gh-issue-104922.L23qaU.rst b/Misc/NEWS.d/next/C API/2023-05-29-16-09-27.gh-issue-104922.L23qaU.rst new file mode 100644 index 00000000000000..ca56d0b4403b8c --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-05-29-16-09-27.gh-issue-104922.L23qaU.rst @@ -0,0 +1,3 @@ +``PY_SSIZE_T_CLEAN`` is no longer required to use ``'#'`` formats in APIs +like :c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue`. They uses +``Py_ssize_t`` for ``'#'`` regardless ``PY_SSIZE_T_CLEAN``. diff --git a/Modules/_testcapi/getargs.c b/Modules/_testcapi/getargs.c index aa201319950de7..95ef2d2a546d31 100644 --- a/Modules/_testcapi/getargs.c +++ b/Modules/_testcapi/getargs.c @@ -816,44 +816,6 @@ test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -#undef PyArg_ParseTupleAndKeywords -PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); - -static PyObject * -getargs_s_hash_int(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"", "", "x", NULL}; - Py_buffer buf = {NULL}; - const char *s; - int len; - int i = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|s#i", keywords, - &buf, &s, &len, &i)) - { - return NULL; - } - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyObject * -getargs_s_hash_int2(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"", "", "x", NULL}; - Py_buffer buf = {NULL}; - const char *s; - int len; - int i = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|(s#)i", keywords, - &buf, &s, &len, &i)) - { - return NULL; - } - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - static PyObject * gh_99240_clear_args(PyObject *self, PyObject *args) { @@ -906,8 +868,6 @@ static PyMethodDef test_methods[] = { {"getargs_positional_only_and_keywords", _PyCFunction_CAST(getargs_positional_only_and_keywords), METH_VARARGS|METH_KEYWORDS}, {"getargs_s", getargs_s, METH_VARARGS}, {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, - {"getargs_s_hash_int", _PyCFunction_CAST(getargs_s_hash_int), METH_VARARGS|METH_KEYWORDS}, - {"getargs_s_hash_int2", _PyCFunction_CAST(getargs_s_hash_int2), METH_VARARGS|METH_KEYWORDS}, {"getargs_s_star", getargs_s_star, METH_VARARGS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_u", getargs_u, METH_VARARGS}, diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 66c1cbabe0f8c4..86b6dc3b36fe7d 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3266,8 +3266,6 @@ test_atexit(PyObject *self, PyObject *Py_UNUSED(args)) } -static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); - static PyMethodDef TestMethods[] = { {"set_errno", set_errno, METH_VARARGS}, {"test_config", test_config, METH_NOARGS}, @@ -3297,7 +3295,6 @@ static PyMethodDef TestMethods[] = { {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, - {"test_buildvalue_issue38913", test_buildvalue_issue38913, METH_NOARGS}, {"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS}, {"test_get_type_name", test_get_type_name, METH_NOARGS}, {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, @@ -4067,47 +4064,3 @@ PyInit__testcapi(void) PyState_AddModule(m, &_testcapimodule); return m; } - -/* Test the C API exposed when PY_SSIZE_T_CLEAN is not defined */ - -#undef Py_BuildValue -PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); - -static PyObject * -test_buildvalue_issue38913(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *res; - const char str[] = "string"; - const Py_UNICODE unicode[] = L"unicode"; - assert(!PyErr_Occurred()); - - res = Py_BuildValue("(s#O)", str, 1, Py_None); - assert(res == NULL); - if (!PyErr_ExceptionMatches(PyExc_SystemError)) { - return NULL; - } - PyErr_Clear(); - - res = Py_BuildValue("(z#O)", str, 1, Py_None); - assert(res == NULL); - if (!PyErr_ExceptionMatches(PyExc_SystemError)) { - return NULL; - } - PyErr_Clear(); - - res = Py_BuildValue("(y#O)", str, 1, Py_None); - assert(res == NULL); - if (!PyErr_ExceptionMatches(PyExc_SystemError)) { - return NULL; - } - PyErr_Clear(); - - res = Py_BuildValue("(u#O)", unicode, 1, Py_None); - assert(res == NULL); - if (!PyErr_ExceptionMatches(PyExc_SystemError)) { - return NULL; - } - PyErr_Clear(); - - Py_RETURN_NONE; -} diff --git a/Objects/call.c b/Objects/call.c index 0d548dcd5e1aed..e9002d350c9288 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -519,7 +519,7 @@ _PyObject_Call_Prepend(PyThreadState *tstate, PyObject *callable, static PyObject * _PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, - const char *format, va_list va, int is_size_t) + const char *format, va_list va) { PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); @@ -535,14 +535,8 @@ _PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, return _PyObject_CallNoArgsTstate(tstate, callable); } - if (is_size_t) { - stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, - format, va, &nargs); - } - else { - stack = _Py_VaBuildStack(small_stack, small_stack_len, - format, va, &nargs); - } + stack = _Py_VaBuildStack(small_stack, small_stack_len, + format, va, &nargs); if (stack == NULL) { return NULL; } @@ -581,7 +575,7 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...) PyThreadState *tstate = _PyThreadState_GET(); va_start(va, format); - result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); + result = _PyObject_CallFunctionVa(tstate, callable, format, va); va_end(va); return result; @@ -599,21 +593,24 @@ PyEval_CallFunction(PyObject *callable, const char *format, ...) PyThreadState *tstate = _PyThreadState_GET(); va_start(va, format); - result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); + result = _PyObject_CallFunctionVa(tstate, callable, format, va); va_end(va); return result; } -PyObject * +/* _PyObject_CallFunction_SizeT is exact copy of PyObject_CallFunction. + * This function must be kept because it is part of the stable ABI. + */ +PyAPI_FUNC(PyObject *) /* abi_only */ _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) { PyThreadState *tstate = _PyThreadState_GET(); va_list va; va_start(va, format); - PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va, 1); + PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va); va_end(va); return result; @@ -621,7 +618,7 @@ _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) static PyObject* -callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_list va, int is_size_t) +callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_list va) { assert(callable != NULL); if (!PyCallable_Check(callable)) { @@ -631,7 +628,7 @@ callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_lis return NULL; } - return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t); + return _PyObject_CallFunctionVa(tstate, callable, format, va); } PyObject * @@ -650,7 +647,7 @@ PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) va_list va; va_start(va, format); - PyObject *retval = callmethod(tstate, callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va); va_end(va); Py_DECREF(callable); @@ -676,7 +673,7 @@ PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) va_list va; va_start(va, format); - PyObject *retval = callmethod(tstate, callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va); va_end(va); Py_DECREF(callable); @@ -700,7 +697,7 @@ _PyObject_CallMethod(PyObject *obj, PyObject *name, va_list va; va_start(va, format); - PyObject *retval = callmethod(tstate, callable, format, va, 1); + PyObject *retval = callmethod(tstate, callable, format, va); va_end(va); Py_DECREF(callable); @@ -724,7 +721,7 @@ _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, va_list va; va_start(va, format); - PyObject *retval = callmethod(tstate, callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va); va_end(va); Py_DECREF(callable); @@ -737,13 +734,15 @@ PyObject * _PyObject_CallMethodFormat(PyThreadState *tstate, PyObject *callable, { va_list va; va_start(va, format); - PyObject *retval = callmethod(tstate, callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va); va_end(va); return retval; } -PyObject * +// _PyObject_CallMethod_SizeT is exact copy of PyObject_CallMethod. +// This function must be kept because it is part of the stable ABI. +PyAPI_FUNC(PyObject *) /* abi_only */ _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, const char *format, ...) { @@ -759,31 +758,7 @@ _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, va_list va; va_start(va, format); - PyObject *retval = callmethod(tstate, callable, format, va, 1); - va_end(va); - - Py_DECREF(callable); - return retval; -} - - -PyObject * -_PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, - const char *format, ...) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (obj == NULL || name == NULL) { - return null_error(tstate); - } - - PyObject *callable = _PyObject_GetAttrId(obj, name); - if (callable == NULL) { - return NULL; - } - - va_list va; - va_start(va, format); - PyObject *retval = callmethod(tstate, callable, format, va, 1); + PyObject *retval = callmethod(tstate, callable, format, va); va_end(va); Py_DECREF(callable); diff --git a/Python/getargs.c b/Python/getargs.c index 66dd90877fe6ff..5639aba9bc9d88 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -12,44 +12,17 @@ #ifdef __cplusplus extern "C" { #endif -int PyArg_Parse(PyObject *, const char *, ...); -int PyArg_ParseTuple(PyObject *, const char *, ...); -int PyArg_VaParse(PyObject *, const char *, va_list); - -int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); -int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, va_list); - -int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, ...); -int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list); - -#ifdef HAVE_DECLSPEC_DLL -/* Export functions */ + +/* Export Stable ABIs (abi only) */ PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); -PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, - const char *format, ...); -PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, - PyObject *kwnames, - struct _PyArg_Parser *parser, ...); PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, const char *, char **, ...); -PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list); PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, const char *, char **, va_list); -PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, - struct _PyArg_Parser *, ...); -PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list); -#endif - #define FLAG_COMPAT 1 -#define FLAG_SIZE_T 2 typedef int (*destr_t)(PyObject *, void *); @@ -114,7 +87,7 @@ _PyArg_Parse_SizeT(PyObject *args, const char *format, ...) va_list va; va_start(va, format); - retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T); + retval = vgetargs1(args, format, &va, FLAG_COMPAT); va_end(va); return retval; } @@ -132,14 +105,14 @@ PyArg_ParseTuple(PyObject *args, const char *format, ...) return retval; } -PyAPI_FUNC(int) +int _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) { int retval; va_list va; va_start(va, format); - retval = vgetargs1(args, format, &va, FLAG_SIZE_T); + retval = vgetargs1(args, format, &va, 0); va_end(va); return retval; } @@ -157,19 +130,6 @@ _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, . return retval; } -PyAPI_FUNC(int) -_PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) -{ - int retval; - va_list va; - - va_start(va, format); - retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T); - va_end(va); - return retval; -} - - int PyArg_VaParse(PyObject *args, const char *format, va_list va) { @@ -183,7 +143,7 @@ PyArg_VaParse(PyObject *args, const char *format, va_list va) return retval; } -PyAPI_FUNC(int) +int _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) { va_list lva; @@ -191,7 +151,7 @@ _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) va_copy(lva, va); - retval = vgetargs1(args, format, &lva, FLAG_SIZE_T); + retval = vgetargs1(args, format, &lva, 0); va_end(lva); return retval; } @@ -657,13 +617,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, char *msgbuf, size_t bufsize, freelist_t *freelist) { #define RETURN_ERR_OCCURRED return msgbuf - /* For # codes */ -#define REQUIRE_PY_SSIZE_T_CLEAN \ - if (!(flags & FLAG_SIZE_T)) { \ - PyErr_SetString(PyExc_SystemError, \ - "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \ - RETURN_ERR_OCCURRED; \ - } const char *format = *p_format; char c = *format++; @@ -917,7 +870,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, if (count < 0) return converterr(buf, arg, msgbuf, bufsize); if (*format == '#') { - REQUIRE_PY_SSIZE_T_CLEAN; Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); *psize = count; format++; @@ -961,7 +913,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } else if (*format == '#') { /* a string or read-only bytes-like object */ /* "s#" or "z#" */ const void **p = (const void **)va_arg(*p_va, const char **); - REQUIRE_PY_SSIZE_T_CLEAN; Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); if (c == 'z' && arg == Py_None) { @@ -1099,7 +1050,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, trailing 0-byte */ - REQUIRE_PY_SSIZE_T_CLEAN; Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); format++; @@ -1274,7 +1224,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, *p_format = format; return NULL; -#undef REQUIRE_PY_SSIZE_T_CLEAN #undef RETURN_ERR_OCCURRED } @@ -1343,7 +1292,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args, return retval; } -PyAPI_FUNC(int) +int _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, @@ -1363,7 +1312,7 @@ _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, va_start(va, kwlist); retval = vgetargskeywords(args, keywords, format, - kwlist, &va, FLAG_SIZE_T); + kwlist, &va, 0); va_end(va); return retval; } @@ -1394,7 +1343,7 @@ PyArg_VaParseTupleAndKeywords(PyObject *args, return retval; } -PyAPI_FUNC(int) +int _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, @@ -1415,7 +1364,7 @@ _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, va_copy(lva, va); retval = vgetargskeywords(args, keywords, format, - kwlist, &lva, FLAG_SIZE_T); + kwlist, &lva, 0); va_end(lva); return retval; } @@ -1433,7 +1382,7 @@ _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, return retval; } -PyAPI_FUNC(int) +int _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, struct _PyArg_Parser *parser, ...) { @@ -1441,12 +1390,12 @@ _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, va_list va; va_start(va, parser); - retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T); + retval = vgetargskeywordsfast(args, keywords, parser, &va, 0); va_end(va); return retval; } -PyAPI_FUNC(int) +int _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, struct _PyArg_Parser *parser, ...) { @@ -1459,7 +1408,7 @@ _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject * return retval; } -PyAPI_FUNC(int) +int _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, struct _PyArg_Parser *parser, ...) { @@ -1467,7 +1416,7 @@ _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyOb va_list va; va_start(va, parser); - retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T); + retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0); va_end(va); return retval; } @@ -1487,20 +1436,6 @@ _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, return retval; } -PyAPI_FUNC(int) -_PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, - struct _PyArg_Parser *parser, va_list va) -{ - int retval; - va_list lva; - - va_copy(lva, va); - - retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T); - va_end(lva); - return retval; -} - static void error_unexpected_keyword_arg(PyObject *kwargs, PyObject *kwnames, PyObject *kwtuple, const char *fname) { @@ -2710,9 +2645,6 @@ skipitem(const char **p_format, va_list *p_va, int flags) } if (*format == '#') { if (p_va != NULL) { - if (!(flags & FLAG_SIZE_T)) { - return "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"; - } (void) va_arg(*p_va, Py_ssize_t *); } format++; diff --git a/Python/modsupport.c b/Python/modsupport.c index be229c987b8a78..e2092ac2099d03 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -5,11 +5,9 @@ #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_object.h" // _PyType_IsReady() -#define FLAG_SIZE_T 1 typedef double va_double; -static PyObject *va_build_value(const char *, va_list, int); -static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); +static PyObject *va_build_value(const char *, va_list); int @@ -84,21 +82,21 @@ countformat(const char *format, char endchar) /* Generic function to create a value -- the inverse of getargs() */ /* After an original idea and first implementation by Steven Miale */ -static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t, int); -static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mkvalue(const char**, va_list *, int); +static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t); +static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t); +static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t); +static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t); +static PyObject *do_mkvalue(const char**, va_list *); static void -do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) { assert(PyErr_Occurred()); PyObject *v = PyTuple_New(n); for (Py_ssize_t i = 0; i < n; i++) { PyObject *exc = PyErr_GetRaisedException(); - PyObject *w = do_mkvalue(p_format, p_va, flags); + PyObject *w = do_mkvalue(p_format, p_va); PyErr_SetRaisedException(exc); if (w != NULL) { if (v != NULL) { @@ -121,7 +119,7 @@ do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int } static PyObject * -do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) { PyObject *d; Py_ssize_t i; @@ -130,27 +128,27 @@ do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int if (n % 2) { PyErr_SetString(PyExc_SystemError, "Bad dict format"); - do_ignore(p_format, p_va, endchar, n, flags); + do_ignore(p_format, p_va, endchar, n); return NULL; } /* Note that we can't bail immediately on error as this will leak refcounts on any 'N' arguments. */ if ((d = PyDict_New()) == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); + do_ignore(p_format, p_va, endchar, n); return NULL; } for (i = 0; i < n; i+= 2) { PyObject *k, *v; - k = do_mkvalue(p_format, p_va, flags); + k = do_mkvalue(p_format, p_va); if (k == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); + do_ignore(p_format, p_va, endchar, n - i - 1); Py_DECREF(d); return NULL; } - v = do_mkvalue(p_format, p_va, flags); + v = do_mkvalue(p_format, p_va); if (v == NULL || PyDict_SetItem(d, k, v) < 0) { - do_ignore(p_format, p_va, endchar, n - i - 2, flags); + do_ignore(p_format, p_va, endchar, n - i - 2); Py_DECREF(k); Py_XDECREF(v); Py_DECREF(d); @@ -171,7 +169,7 @@ do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int } static PyObject * -do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) { PyObject *v; Py_ssize_t i; @@ -181,13 +179,13 @@ do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int refcounts on any 'N' arguments. */ v = PyList_New(n); if (v == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); + do_ignore(p_format, p_va, endchar, n); return NULL; } for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); + PyObject *w = do_mkvalue(p_format, p_va); if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); + do_ignore(p_format, p_va, endchar, n - i - 1); Py_DECREF(v); return NULL; } @@ -206,7 +204,7 @@ do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int static int do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, - char endchar, Py_ssize_t n, int flags) + char endchar, Py_ssize_t n) { Py_ssize_t i; @@ -216,9 +214,9 @@ do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, /* Note that we can't bail immediately on error as this will leak refcounts on any 'N' arguments. */ for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); + PyObject *w = do_mkvalue(p_format, p_va); if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); + do_ignore(p_format, p_va, endchar, n - i - 1); goto error; } stack[i] = w; @@ -242,7 +240,7 @@ do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, } static PyObject * -do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n) { PyObject *v; Py_ssize_t i; @@ -251,13 +249,13 @@ do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int /* Note that we can't bail immediately on error as this will leak refcounts on any 'N' arguments. */ if ((v = PyTuple_New(n)) == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); + do_ignore(p_format, p_va, endchar, n); return NULL; } for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); + PyObject *w = do_mkvalue(p_format, p_va); if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); + do_ignore(p_format, p_va, endchar, n - i - 1); Py_DECREF(v); return NULL; } @@ -275,28 +273,21 @@ do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int } static PyObject * -do_mkvalue(const char **p_format, va_list *p_va, int flags) +do_mkvalue(const char **p_format, va_list *p_va) { -#define ERROR_NEED_PY_SSIZE_T_CLEAN \ - { \ - PyErr_SetString(PyExc_SystemError, \ - "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \ - return NULL; \ - } - for (;;) { switch (*(*p_format)++) { case '(': return do_mktuple(p_format, p_va, ')', - countformat(*p_format, ')'), flags); + countformat(*p_format, ')')); case '[': return do_mklist(p_format, p_va, ']', - countformat(*p_format, ']'), flags); + countformat(*p_format, ']')); case '{': return do_mkdict(p_format, p_va, '}', - countformat(*p_format, '}'), flags); + countformat(*p_format, '}')); case 'b': case 'B': @@ -342,13 +333,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) Py_ssize_t n; if (**p_format == '#') { ++*p_format; - if (flags & FLAG_SIZE_T) { - n = va_arg(*p_va, Py_ssize_t); - } - else { - n = va_arg(*p_va, int); - ERROR_NEED_PY_SSIZE_T_CLEAN; - } + n = va_arg(*p_va, Py_ssize_t); } else n = -1; @@ -392,13 +377,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) Py_ssize_t n; if (**p_format == '#') { ++*p_format; - if (flags & FLAG_SIZE_T) { - n = va_arg(*p_va, Py_ssize_t); - } - else { - n = va_arg(*p_va, int); - ERROR_NEED_PY_SSIZE_T_CLEAN; - } + n = va_arg(*p_va, Py_ssize_t); } else n = -1; @@ -427,13 +406,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) Py_ssize_t n; if (**p_format == '#') { ++*p_format; - if (flags & FLAG_SIZE_T) { - n = va_arg(*p_va, Py_ssize_t); - } - else { - n = va_arg(*p_va, int); - ERROR_NEED_PY_SSIZE_T_CLEAN; - } + n = va_arg(*p_va, Py_ssize_t); } else n = -1; @@ -499,8 +472,6 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) } } - -#undef ERROR_NEED_PY_SSIZE_T_CLEAN } @@ -510,18 +481,18 @@ Py_BuildValue(const char *format, ...) va_list va; PyObject* retval; va_start(va, format); - retval = va_build_value(format, va, 0); + retval = va_build_value(format, va); va_end(va); return retval; } -PyObject * +PyAPI_FUNC(PyObject *) /* abi only */ _Py_BuildValue_SizeT(const char *format, ...) { va_list va; PyObject* retval; va_start(va, format); - retval = va_build_value(format, va, FLAG_SIZE_T); + retval = va_build_value(format, va); va_end(va); return retval; } @@ -529,17 +500,17 @@ _Py_BuildValue_SizeT(const char *format, ...) PyObject * Py_VaBuildValue(const char *format, va_list va) { - return va_build_value(format, va, 0); + return va_build_value(format, va); } -PyObject * +PyAPI_FUNC(PyObject *) /* abi only */ _Py_VaBuildValue_SizeT(const char *format, va_list va) { - return va_build_value(format, va, FLAG_SIZE_T); + return va_build_value(format, va); } static PyObject * -va_build_value(const char *format, va_list va, int flags) +va_build_value(const char *format, va_list va) { const char *f = format; Py_ssize_t n = countformat(f, '\0'); @@ -553,9 +524,9 @@ va_build_value(const char *format, va_list va, int flags) } va_copy(lva, va); if (n == 1) { - retval = do_mkvalue(&f, &lva, flags); + retval = do_mkvalue(&f, &lva); } else { - retval = do_mktuple(&f, &lva, '\0', n, flags); + retval = do_mktuple(&f, &lva, '\0', n); } va_end(lva); return retval; @@ -564,20 +535,6 @@ va_build_value(const char *format, va_list va, int flags) PyObject ** _Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *format, va_list va, Py_ssize_t *p_nargs) -{ - return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs); -} - -PyObject ** -_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, Py_ssize_t *p_nargs) -{ - return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs); -} - -static PyObject ** -va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, int flags, Py_ssize_t *p_nargs) { const char *f; Py_ssize_t n; @@ -609,7 +566,7 @@ va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, va_copy(lva, va); f = format; - res = do_mkstack(stack, &f, &lva, '\0', n, flags); + res = do_mkstack(stack, &f, &lva, '\0', n); va_end(lva); if (res < 0) { diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 33147f012b611d..32be7ec09ebfd6 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -211,7 +211,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event, /* Initialize event args now */ if (argFormat && argFormat[0]) { - eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs); + eventArgs = Py_VaBuildValue(argFormat, vargs); if (eventArgs && !PyTuple_Check(eventArgs)) { PyObject *argTuple = PyTuple_Pack(1, eventArgs); Py_SETREF(eventArgs, argTuple);