mirror of https://github.com/python/cpython
gh-104922: Make `PY_SSIZE_T_CLEAN` not mandatory again (#105051)
This commit is contained in:
parent
f90d3f68db
commit
adccff3b3f
|
@ -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
|
||||
|
|
|
@ -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 <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
|
||||
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>
|
||||
|
||||
static PyObject *
|
||||
|
|
|
@ -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 <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
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -9,34 +9,17 @@ extern "C" {
|
|||
|
||||
#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_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.
|
||||
|
|
|
@ -901,23 +901,6 @@ class String_TestCase(unittest.TestCase):
|
|||
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')
|
||||
|
|
|
@ -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``.
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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 @@ error:
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue