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.
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
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
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>
::
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 *
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
----------------------
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);
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.
/* === 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).
_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,
# 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,
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(
#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.
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')
--- /dev/null
+``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``.
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)
{
{"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},
}
-static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
-
static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
{"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},
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;
-}
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);
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;
}
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;
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;
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)) {
return NULL;
}
- return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t);
+ return _PyObject_CallFunctionVa(tstate, callable, format, va);
}
PyObject *
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);
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);
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);
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);
{
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, ...)
{
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);
#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 *);
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;
}
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;
}
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)
{
return retval;
}
-PyAPI_FUNC(int)
+int
_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
{
va_list lva;
va_copy(lva, va);
- retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
+ retval = vgetargs1(args, format, &lva, 0);
va_end(lva);
return retval;
}
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++;
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++;
} 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) {
trailing 0-byte
*/
- REQUIRE_PY_SSIZE_T_CLEAN;
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
format++;
*p_format = format;
return NULL;
-#undef REQUIRE_PY_SSIZE_T_CLEAN
#undef RETURN_ERR_OCCURRED
}
return retval;
}
-PyAPI_FUNC(int)
+int
_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
PyObject *keywords,
const char *format,
va_start(va, kwlist);
retval = vgetargskeywords(args, keywords, format,
- kwlist, &va, FLAG_SIZE_T);
+ kwlist, &va, 0);
va_end(va);
return retval;
}
return retval;
}
-PyAPI_FUNC(int)
+int
_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
PyObject *keywords,
const char *format,
va_copy(lva, va);
retval = vgetargskeywords(args, keywords, format,
- kwlist, &lva, FLAG_SIZE_T);
+ kwlist, &lva, 0);
va_end(lva);
return retval;
}
return retval;
}
-PyAPI_FUNC(int)
+int
_PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
struct _PyArg_Parser *parser, ...)
{
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, ...)
{
return retval;
}
-PyAPI_FUNC(int)
+int
_PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
struct _PyArg_Parser *parser, ...)
{
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;
}
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)
{
}
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++;
#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
/* 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) {
}
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;
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);
}
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;
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;
}
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;
/* 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;
}
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;
/* 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;
}
}
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':
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;
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;
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;
}
}
-
-#undef ERROR_NEED_PY_SSIZE_T_CLEAN
}
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;
}
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');
}
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;
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;
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) {
/* 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);