gh-104922: Make PY_SSIZE_T_CLEAN not mandatory again (#105051)

This commit is contained in:
Inada Naoki 2023-05-31 18:38:55 +09:00 committed by GitHub
parent f90d3f68db
commit adccff3b3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 105 additions and 397 deletions

View file

@ -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 the format unit; and the entry in [square] brackets is the type of the C
variable(s) whose address should be passed. variable(s) whose address should be passed.
.. _arg-parsing-string-and-buffers:
Strings 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. 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 You don't have to provide raw storage for the returned unicode or bytes
area. 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 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). 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 \*] ``s`` (:class:`str`) [const char \*]
Convert a Unicode object to a C pointer to a character string. Convert a Unicode object to a C pointer to a character string.
A pointer to an existing string is stored in the character pointer A pointer to an existing string is stored in the character pointer

View file

@ -70,7 +70,7 @@ the module and a copyright notice if you like).
headers are included. headers are included.
It is recommended to always define ``PY_SSIZE_T_CLEAN`` before including 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 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 ``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:: Some example calls::
#define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */ #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
:: ::
@ -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 Here is an example module which uses keywords, based on an example by Geoff
Philbrick (philbrick@hks.com):: Philbrick (philbrick@hks.com)::
#define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */ #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
static PyObject * static PyObject *

View file

@ -292,6 +292,13 @@ C API Changes
New Features 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 <arg-parsing-string-and-buffers>`.
APIs accepting the format codes always use ``Py_ssize_t`` for ``#`` formats.
(Contributed by Inada Naoki in :gh:`104922`.)
Porting to Python 3.13 Porting to Python 3.13
---------------------- ----------------------

View file

@ -135,12 +135,6 @@ extern "C" {
This function always succeeds. */ 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 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
/* Call a callable Python object without any arguments */ /* Call a callable Python object without any arguments */
PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func); PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func);
@ -195,15 +189,6 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj,
const char *name, const char *name,
const char *format, ...); 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 /* Call a callable Python object 'callable' with a variable number of C
arguments. The C arguments are provided as PyObject* values, terminated arguments. The C arguments are provided as PyObject* values, terminated
by a NULL. by a NULL.

View file

@ -4,10 +4,6 @@
/* === Object Protocol ================================================== */ /* === 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) /* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
format to a Python dictionary ("kwargs" dict). format to a Python dictionary ("kwargs" dict).
@ -113,11 +109,6 @@ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
_Py_Identifier *name, _Py_Identifier *name,
const char *format, ...); const char *format, ...);
PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
_Py_Identifier *name,
const char *format,
...);
PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
PyObject *obj, PyObject *obj,
_Py_Identifier *name, _Py_Identifier *name,

View file

@ -2,20 +2,6 @@
# error "this header file must not be included directly" # error "this header file must not be included directly"
#endif #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( PyAPI_FUNC(int) _PyArg_UnpackStack(
PyObject *const *args, PyObject *const *args,
Py_ssize_t nargs, Py_ssize_t nargs,
@ -63,13 +49,6 @@ typedef struct _PyArg_Parser {
struct _PyArg_Parser *next; struct _PyArg_Parser *next;
} _PyArg_Parser; } _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 *, PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
struct _PyArg_Parser *, ...); struct _PyArg_Parser *, ...);
PyAPI_FUNC(int) _PyArg_ParseStack( PyAPI_FUNC(int) _PyArg_ParseStack(

View file

@ -9,20 +9,6 @@ extern "C" {
#include <stdarg.h> // va_list #include <stdarg.h> // 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_Parse(PyObject *, const char *, ...);
PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);
PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
@ -30,13 +16,10 @@ PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list);
PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
const char *, char **, va_list); const char *, char **, va_list);
#endif
PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *); PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *);
PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); 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(const char *, ...);
PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list);
// Add an attribute with name 'name' and value 'obj' to the module 'mod. // Add an attribute with name 'name' and value 'obj' to the module 'mod.

View file

@ -901,23 +901,6 @@ class String_TestCase(unittest.TestCase):
self.assertRaises(TypeError, getargs_s_hash, memoryview(b'memoryview')) self.assertRaises(TypeError, getargs_s_hash, memoryview(b'memoryview'))
self.assertRaises(TypeError, getargs_s_hash, None) 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): def test_z(self):
from _testcapi import getargs_z from _testcapi import getargs_z
self.assertEqual(getargs_z('abc\xe9'), b'abc\xc3\xa9') self.assertEqual(getargs_z('abc\xe9'), b'abc\xc3\xa9')

View file

@ -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``.

View file

@ -816,44 +816,6 @@ test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored))
Py_RETURN_NONE; 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 * static PyObject *
gh_99240_clear_args(PyObject *self, PyObject *args) 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_positional_only_and_keywords", _PyCFunction_CAST(getargs_positional_only_and_keywords), METH_VARARGS|METH_KEYWORDS},
{"getargs_s", getargs_s, METH_VARARGS}, {"getargs_s", getargs_s, METH_VARARGS},
{"getargs_s_hash", getargs_s_hash, 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_s_star", getargs_s_star, METH_VARARGS},
{"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_tuple", getargs_tuple, METH_VARARGS},
{"getargs_u", getargs_u, METH_VARARGS}, {"getargs_u", getargs_u, METH_VARARGS},

View file

@ -3266,8 +3266,6 @@ test_atexit(PyObject *self, PyObject *Py_UNUSED(args))
} }
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
static PyMethodDef TestMethods[] = { static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS}, {"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS}, {"test_config", test_config, METH_NOARGS},
@ -3297,7 +3295,6 @@ static PyMethodDef TestMethods[] = {
{"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O},
{"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS},
{"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, {"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_statictype_slots", test_get_statictype_slots, METH_NOARGS},
{"test_get_type_name", test_get_type_name, METH_NOARGS}, {"test_get_type_name", test_get_type_name, METH_NOARGS},
{"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS},
@ -4067,47 +4064,3 @@ PyInit__testcapi(void)
PyState_AddModule(m, &_testcapimodule); PyState_AddModule(m, &_testcapimodule);
return m; 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;
}

View file

@ -519,7 +519,7 @@ _PyObject_Call_Prepend(PyThreadState *tstate, PyObject *callable,
static PyObject * static PyObject *
_PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, _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]; PyObject* small_stack[_PY_FASTCALL_SMALL_STACK];
const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(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); 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, stack = _Py_VaBuildStack(small_stack, small_stack_len,
format, va, &nargs); format, va, &nargs);
}
if (stack == NULL) { if (stack == NULL) {
return NULL; return NULL;
} }
@ -581,7 +575,7 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...)
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
va_start(va, format); va_start(va, format);
result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); result = _PyObject_CallFunctionVa(tstate, callable, format, va);
va_end(va); va_end(va);
return result; return result;
@ -599,21 +593,24 @@ PyEval_CallFunction(PyObject *callable, const char *format, ...)
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
va_start(va, format); va_start(va, format);
result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); result = _PyObject_CallFunctionVa(tstate, callable, format, va);
va_end(va); va_end(va);
return result; 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, ...) _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
va_list va; va_list va;
va_start(va, format); va_start(va, format);
PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va, 1); PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va);
va_end(va); va_end(va);
return result; return result;
@ -621,7 +618,7 @@ _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...)
static PyObject* 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); assert(callable != NULL);
if (!PyCallable_Check(callable)) { if (!PyCallable_Check(callable)) {
@ -631,7 +628,7 @@ callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_lis
return NULL; return NULL;
} }
return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t); return _PyObject_CallFunctionVa(tstate, callable, format, va);
} }
PyObject * PyObject *
@ -650,7 +647,7 @@ PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
va_list va; va_list va;
va_start(va, format); va_start(va, format);
PyObject *retval = callmethod(tstate, callable, format, va, 0); PyObject *retval = callmethod(tstate, callable, format, va);
va_end(va); va_end(va);
Py_DECREF(callable); Py_DECREF(callable);
@ -676,7 +673,7 @@ PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...)
va_list va; va_list va;
va_start(va, format); va_start(va, format);
PyObject *retval = callmethod(tstate, callable, format, va, 0); PyObject *retval = callmethod(tstate, callable, format, va);
va_end(va); va_end(va);
Py_DECREF(callable); Py_DECREF(callable);
@ -700,7 +697,7 @@ _PyObject_CallMethod(PyObject *obj, PyObject *name,
va_list va; va_list va;
va_start(va, format); va_start(va, format);
PyObject *retval = callmethod(tstate, callable, format, va, 1); PyObject *retval = callmethod(tstate, callable, format, va);
va_end(va); va_end(va);
Py_DECREF(callable); Py_DECREF(callable);
@ -724,7 +721,7 @@ _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name,
va_list va; va_list va;
va_start(va, format); va_start(va, format);
PyObject *retval = callmethod(tstate, callable, format, va, 0); PyObject *retval = callmethod(tstate, callable, format, va);
va_end(va); va_end(va);
Py_DECREF(callable); Py_DECREF(callable);
@ -737,13 +734,15 @@ PyObject * _PyObject_CallMethodFormat(PyThreadState *tstate, PyObject *callable,
{ {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
PyObject *retval = callmethod(tstate, callable, format, va, 0); PyObject *retval = callmethod(tstate, callable, format, va);
va_end(va); va_end(va);
return retval; 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, _PyObject_CallMethod_SizeT(PyObject *obj, const char *name,
const char *format, ...) const char *format, ...)
{ {
@ -759,31 +758,7 @@ _PyObject_CallMethod_SizeT(PyObject *obj, const char *name,
va_list va; va_list va;
va_start(va, format); 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);
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);
va_end(va); va_end(va);
Py_DECREF(callable); Py_DECREF(callable);

View file

@ -12,44 +12,17 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 *, /* Export Stable ABIs (abi only) */
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 */
PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); 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_ParseTuple_SizeT(PyObject *, const char *, ...);
PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
const char *, char **, ...); 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_VaParse_SizeT(PyObject *, const char *, va_list);
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
const char *, char **, va_list); 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_COMPAT 1
#define FLAG_SIZE_T 2
typedef int (*destr_t)(PyObject *, void *); typedef int (*destr_t)(PyObject *, void *);
@ -114,7 +87,7 @@ _PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
va_list va; va_list va;
va_start(va, format); va_start(va, format);
retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T); retval = vgetargs1(args, format, &va, FLAG_COMPAT);
va_end(va); va_end(va);
return retval; return retval;
} }
@ -132,14 +105,14 @@ PyArg_ParseTuple(PyObject *args, const char *format, ...)
return retval; return retval;
} }
PyAPI_FUNC(int) int
_PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
{ {
int retval; int retval;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
retval = vgetargs1(args, format, &va, FLAG_SIZE_T); retval = vgetargs1(args, format, &va, 0);
va_end(va); va_end(va);
return retval; return retval;
} }
@ -157,19 +130,6 @@ _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, .
return retval; 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 int
PyArg_VaParse(PyObject *args, const char *format, va_list va) 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; return retval;
} }
PyAPI_FUNC(int) int
_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
{ {
va_list lva; va_list lva;
@ -191,7 +151,7 @@ _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
va_copy(lva, va); va_copy(lva, va);
retval = vgetargs1(args, format, &lva, FLAG_SIZE_T); retval = vgetargs1(args, format, &lva, 0);
va_end(lva); va_end(lva);
return retval; 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) char *msgbuf, size_t bufsize, freelist_t *freelist)
{ {
#define RETURN_ERR_OCCURRED return msgbuf #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; const char *format = *p_format;
char c = *format++; char c = *format++;
@ -917,7 +870,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if (count < 0) if (count < 0)
return converterr(buf, arg, msgbuf, bufsize); return converterr(buf, arg, msgbuf, bufsize);
if (*format == '#') { if (*format == '#') {
REQUIRE_PY_SSIZE_T_CLEAN;
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
*psize = count; *psize = count;
format++; 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 */ } else if (*format == '#') { /* a string or read-only bytes-like object */
/* "s#" or "z#" */ /* "s#" or "z#" */
const void **p = (const void **)va_arg(*p_va, const char **); 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*); Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
if (c == 'z' && arg == Py_None) { 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 trailing 0-byte
*/ */
REQUIRE_PY_SSIZE_T_CLEAN;
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
format++; format++;
@ -1274,7 +1224,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
*p_format = format; *p_format = format;
return NULL; return NULL;
#undef REQUIRE_PY_SSIZE_T_CLEAN
#undef RETURN_ERR_OCCURRED #undef RETURN_ERR_OCCURRED
} }
@ -1343,7 +1292,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args,
return retval; return retval;
} }
PyAPI_FUNC(int) int
_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
PyObject *keywords, PyObject *keywords,
const char *format, const char *format,
@ -1363,7 +1312,7 @@ _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
va_start(va, kwlist); va_start(va, kwlist);
retval = vgetargskeywords(args, keywords, format, retval = vgetargskeywords(args, keywords, format,
kwlist, &va, FLAG_SIZE_T); kwlist, &va, 0);
va_end(va); va_end(va);
return retval; return retval;
} }
@ -1394,7 +1343,7 @@ PyArg_VaParseTupleAndKeywords(PyObject *args,
return retval; return retval;
} }
PyAPI_FUNC(int) int
_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
PyObject *keywords, PyObject *keywords,
const char *format, const char *format,
@ -1415,7 +1364,7 @@ _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
va_copy(lva, va); va_copy(lva, va);
retval = vgetargskeywords(args, keywords, format, retval = vgetargskeywords(args, keywords, format,
kwlist, &lva, FLAG_SIZE_T); kwlist, &lva, 0);
va_end(lva); va_end(lva);
return retval; return retval;
} }
@ -1433,7 +1382,7 @@ _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
return retval; return retval;
} }
PyAPI_FUNC(int) int
_PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
struct _PyArg_Parser *parser, ...) struct _PyArg_Parser *parser, ...)
{ {
@ -1441,12 +1390,12 @@ _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
va_list va; va_list va;
va_start(va, parser); va_start(va, parser);
retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T); retval = vgetargskeywordsfast(args, keywords, parser, &va, 0);
va_end(va); va_end(va);
return retval; return retval;
} }
PyAPI_FUNC(int) int
_PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
struct _PyArg_Parser *parser, ...) struct _PyArg_Parser *parser, ...)
{ {
@ -1459,7 +1408,7 @@ _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *
return retval; return retval;
} }
PyAPI_FUNC(int) int
_PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
struct _PyArg_Parser *parser, ...) struct _PyArg_Parser *parser, ...)
{ {
@ -1467,7 +1416,7 @@ _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyOb
va_list va; va_list va;
va_start(va, parser); 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); va_end(va);
return retval; return retval;
} }
@ -1487,20 +1436,6 @@ _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
return retval; 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 static void
error_unexpected_keyword_arg(PyObject *kwargs, PyObject *kwnames, PyObject *kwtuple, const char *fname) 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 (*format == '#') {
if (p_va != NULL) { 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 *); (void) va_arg(*p_va, Py_ssize_t *);
} }
format++; format++;

View file

@ -5,11 +5,9 @@
#include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_object.h" // _PyType_IsReady() #include "pycore_object.h" // _PyType_IsReady()
#define FLAG_SIZE_T 1
typedef double va_double; typedef double va_double;
static PyObject *va_build_value(const char *, va_list, int); static PyObject *va_build_value(const char *, va_list);
static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*);
int int
@ -84,21 +82,21 @@ countformat(const char *format, char endchar)
/* Generic function to create a value -- the inverse of getargs() */ /* Generic function to create a value -- the inverse of getargs() */
/* After an original idea and first implementation by Steven Miale */ /* After an original idea and first implementation by Steven Miale */
static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t, 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, int); 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, int); static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t);
static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int); static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t);
static PyObject *do_mkvalue(const char**, va_list *, int); static PyObject *do_mkvalue(const char**, va_list *);
static void 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()); assert(PyErr_Occurred());
PyObject *v = PyTuple_New(n); PyObject *v = PyTuple_New(n);
for (Py_ssize_t i = 0; i < n; i++) { for (Py_ssize_t i = 0; i < n; i++) {
PyObject *exc = PyErr_GetRaisedException(); PyObject *exc = PyErr_GetRaisedException();
PyObject *w = do_mkvalue(p_format, p_va, flags); PyObject *w = do_mkvalue(p_format, p_va);
PyErr_SetRaisedException(exc); PyErr_SetRaisedException(exc);
if (w != NULL) { if (w != NULL) {
if (v != 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 * 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; PyObject *d;
Py_ssize_t i; 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) { if (n % 2) {
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError,
"Bad dict format"); "Bad dict format");
do_ignore(p_format, p_va, endchar, n, flags); do_ignore(p_format, p_va, endchar, n);
return NULL; return NULL;
} }
/* Note that we can't bail immediately on error as this will leak /* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */ refcounts on any 'N' arguments. */
if ((d = PyDict_New()) == NULL) { if ((d = PyDict_New()) == NULL) {
do_ignore(p_format, p_va, endchar, n, flags); do_ignore(p_format, p_va, endchar, n);
return NULL; return NULL;
} }
for (i = 0; i < n; i+= 2) { for (i = 0; i < n; i+= 2) {
PyObject *k, *v; PyObject *k, *v;
k = do_mkvalue(p_format, p_va, flags); k = do_mkvalue(p_format, p_va);
if (k == NULL) { 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); Py_DECREF(d);
return NULL; 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) { 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_DECREF(k);
Py_XDECREF(v); Py_XDECREF(v);
Py_DECREF(d); 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 * 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; PyObject *v;
Py_ssize_t i; 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. */ refcounts on any 'N' arguments. */
v = PyList_New(n); v = PyList_New(n);
if (v == NULL) { if (v == NULL) {
do_ignore(p_format, p_va, endchar, n, flags); do_ignore(p_format, p_va, endchar, n);
return NULL; return NULL;
} }
for (i = 0; i < n; i++) { 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) { 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); Py_DECREF(v);
return NULL; 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 static int
do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, 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; 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 /* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */ refcounts on any 'N' arguments. */
for (i = 0; i < n; i++) { 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) { 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; goto error;
} }
stack[i] = w; stack[i] = w;
@ -242,7 +240,7 @@ error:
} }
static PyObject * 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; PyObject *v;
Py_ssize_t i; 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 /* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */ refcounts on any 'N' arguments. */
if ((v = PyTuple_New(n)) == NULL) { 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; return NULL;
} }
for (i = 0; i < n; i++) { 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) { 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); Py_DECREF(v);
return NULL; 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 * 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 (;;) { for (;;) {
switch (*(*p_format)++) { switch (*(*p_format)++) {
case '(': case '(':
return do_mktuple(p_format, p_va, ')', return do_mktuple(p_format, p_va, ')',
countformat(*p_format, ')'), flags); countformat(*p_format, ')'));
case '[': case '[':
return do_mklist(p_format, p_va, ']', return do_mklist(p_format, p_va, ']',
countformat(*p_format, ']'), flags); countformat(*p_format, ']'));
case '{': case '{':
return do_mkdict(p_format, p_va, '}', return do_mkdict(p_format, p_va, '}',
countformat(*p_format, '}'), flags); countformat(*p_format, '}'));
case 'b': case 'b':
case 'B': case 'B':
@ -342,14 +333,8 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags)
Py_ssize_t n; Py_ssize_t n;
if (**p_format == '#') { if (**p_format == '#') {
++*p_format; ++*p_format;
if (flags & FLAG_SIZE_T) {
n = va_arg(*p_va, Py_ssize_t); n = va_arg(*p_va, Py_ssize_t);
} }
else {
n = va_arg(*p_va, int);
ERROR_NEED_PY_SSIZE_T_CLEAN;
}
}
else else
n = -1; n = -1;
if (u == NULL) { if (u == NULL) {
@ -392,14 +377,8 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags)
Py_ssize_t n; Py_ssize_t n;
if (**p_format == '#') { if (**p_format == '#') {
++*p_format; ++*p_format;
if (flags & FLAG_SIZE_T) {
n = va_arg(*p_va, Py_ssize_t); n = va_arg(*p_va, Py_ssize_t);
} }
else {
n = va_arg(*p_va, int);
ERROR_NEED_PY_SSIZE_T_CLEAN;
}
}
else else
n = -1; n = -1;
if (str == NULL) { if (str == NULL) {
@ -427,14 +406,8 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags)
Py_ssize_t n; Py_ssize_t n;
if (**p_format == '#') { if (**p_format == '#') {
++*p_format; ++*p_format;
if (flags & FLAG_SIZE_T) {
n = va_arg(*p_va, Py_ssize_t); n = va_arg(*p_va, Py_ssize_t);
} }
else {
n = va_arg(*p_va, int);
ERROR_NEED_PY_SSIZE_T_CLEAN;
}
}
else else
n = -1; n = -1;
if (str == NULL) { if (str == NULL) {
@ -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; va_list va;
PyObject* retval; PyObject* retval;
va_start(va, format); va_start(va, format);
retval = va_build_value(format, va, 0); retval = va_build_value(format, va);
va_end(va); va_end(va);
return retval; return retval;
} }
PyObject * PyAPI_FUNC(PyObject *) /* abi only */
_Py_BuildValue_SizeT(const char *format, ...) _Py_BuildValue_SizeT(const char *format, ...)
{ {
va_list va; va_list va;
PyObject* retval; PyObject* retval;
va_start(va, format); va_start(va, format);
retval = va_build_value(format, va, FLAG_SIZE_T); retval = va_build_value(format, va);
va_end(va); va_end(va);
return retval; return retval;
} }
@ -529,17 +500,17 @@ _Py_BuildValue_SizeT(const char *format, ...)
PyObject * PyObject *
Py_VaBuildValue(const char *format, va_list va) 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) _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 * 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; const char *f = format;
Py_ssize_t n = countformat(f, '\0'); 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); va_copy(lva, va);
if (n == 1) { if (n == 1) {
retval = do_mkvalue(&f, &lva, flags); retval = do_mkvalue(&f, &lva);
} else { } else {
retval = do_mktuple(&f, &lva, '\0', n, flags); retval = do_mktuple(&f, &lva, '\0', n);
} }
va_end(lva); va_end(lva);
return retval; return retval;
@ -564,20 +535,6 @@ va_build_value(const char *format, va_list va, int flags)
PyObject ** PyObject **
_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len, _Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len,
const char *format, va_list va, Py_ssize_t *p_nargs) 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; const char *f;
Py_ssize_t n; Py_ssize_t n;
@ -609,7 +566,7 @@ va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len,
va_copy(lva, va); va_copy(lva, va);
f = format; f = format;
res = do_mkstack(stack, &f, &lva, '\0', n, flags); res = do_mkstack(stack, &f, &lva, '\0', n);
va_end(lva); va_end(lva);
if (res < 0) { if (res < 0) {

View file

@ -211,7 +211,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
/* Initialize event args now */ /* Initialize event args now */
if (argFormat && argFormat[0]) { if (argFormat && argFormat[0]) {
eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs); eventArgs = Py_VaBuildValue(argFormat, vargs);
if (eventArgs && !PyTuple_Check(eventArgs)) { if (eventArgs && !PyTuple_Check(eventArgs)) {
PyObject *argTuple = PyTuple_Pack(1, eventArgs); PyObject *argTuple = PyTuple_Pack(1, eventArgs);
Py_SETREF(eventArgs, argTuple); Py_SETREF(eventArgs, argTuple);