8000 gh-65210: Add const qualifiers in PyArg_VaParseTupleAndKeywords() (GH… · python/cpython@da6760b · GitHub
[go: up one dir, main page]

Skip to content

Commit da6760b

Browse files
gh-65210: Add const qualifiers in PyArg_VaParseTupleAndKeywords() (GH-105958)
Change the declaration of the keywords parameter in functions PyArg_ParseTupleAndKeywords() and PyArg_VaParseTupleAndKeywords() from `char **` to `char * const *` in C and `const char * const *` in C++. It makes these functions compatible with argument of type `const char * const *`, `const char **` or `char * const *` in C++ and `char * const *` in C without explicit type cast. Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
1 parent cda7379 commit da6760b

File tree

7 files changed

+57
-13
lines changed

7 files changed

+57
-13
lines changed

Doc/c-api/arg.rst

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ API Functions
413413
than a variable number of arguments.
414414
415415
416-
.. c:function:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...)
416+
.. c:function:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char * const *keywords, ...)
417417
418418
Parse the parameters of a function that takes both positional and keyword
419419
parameters into local variables.
@@ -424,15 +424,24 @@ API Functions
424424
Returns true on success; on failure, it returns false and raises the
425425
appropriate exception.
426426
427+
.. note::
428+
429+
The *keywords* parameter declaration is :c:expr:`char * const *` in C and
430+
:c:expr:`const char * const *` in C++.
431+
This can be overridden with the :c:macro:`PY_CXX_CONST` macro.
432+
427433
.. versionchanged:: 3.6
428434
Added support for :ref:`positional-only parameters
429435
<positional-only_parameter>`.
430436
431437
.. versionchanged:: 3.13
438+
The *keywords* parameter has now type :c:expr:`char * const *` in C and
439+
:c:expr:`const char * const *` in C++, instead of :c:expr:`char **`.
432440
Added support for non-ASCII keyword parameter names.
433441
434442
435-
.. c:function:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs)
443+
444+
.. c:function:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char * const *keywords, va_list vargs)
436445
437446
Identical to :c:func:`PyArg_ParseTupleAndKeywords`, except that it accepts a
438447
va_list rather than a variable number of arguments.
@@ -505,6 +514,19 @@ API Functions
505514
506515
PyArg_ParseTuple(args, "O|O:ref", &object, &callback)
507516
517+
.. c:macro:: PY_CXX_CONST
518+
519+
The value to be inserted, if any, before :c:expr:`char * const *`
520+
in the *keywords* parameter declaration of
521+
:c:func:`PyArg_ParseTupleAndKeywords` and
522+
:c:func:`PyArg_VaParseTupleAndKeywords`.
523+
Default empty for C and ``const`` for C++
524+
(:c:expr:`const char * const *`).
525+
To override, define it to the desired value before including
526+
:file:`Python.h`.
527+
528+
.. versionadded:: 3.13
529+
508530
509531
---------------
510532
Building values

Doc/extending/extending.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ Keyword Parameters for Extension Functions
735735
The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows::
736736

737737
int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,
738-
const char *format, char *kwlist[], ...);
738+
const char *format, char * const *kwlist, ...);
739739

740740
The *arg* and *format* parameters are identical to those of the
741741
:c:func:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of

Doc/whatsnew/3.13.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,16 @@ New Features
11111111
APIs accepting the format codes always use ``Py_ssize_t`` for ``#`` formats.
11121112
(Contributed by Inada Naoki in :gh:`104922`.)
11131113

1114+
* The *keywords* parameter of :c:func:`PyArg_ParseTupleAndKeywords` and
1115+
:c:func:`PyArg_VaParseTupleAndKeywords` has now type :c:expr:`char * const *`
1116+
in C and :c:expr:`const char * const *` in C++, instead of :c:expr:`char **`.
1117+
It makes these functions compatible with arguments of type
1118+
:c:expr:`const char * const *`, :c:expr:`const char **` or
1119+
:c:expr:`char * const *` in C++ and :c:expr:`char * const *` in C
1120+
without an explicit type cast.
1121+
This can be overridden with the :c:macro:`PY_CXX_CONST` macro.
1122+
(Contributed by Serhiy Storchaka in :gh:`65210`.)
1123+
11141124
* Add :c:func:`PyImport_AddModuleRef`: similar to
11151125
:c:func:`PyImport_AddModule`, but return a :term:`strong reference` instead
11161126
of a :term:`borrowed reference`.

Include/modsupport.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ extern "C" {
99
PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...);
1010
PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);
1111
PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
12-
const char *, char **, ...);
12+
const char *, PY_CXX_CONST char * const *, ...);
1313
PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list);
1414
PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
15-
const char *, char **, va_list);
15+
const char *, PY_CXX_CONST char * const *, va_list);
1616

1717
PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *);
1818
PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...);

Include/pyport.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,14 @@ extern "C" {
586586
# define ALIGNOF_MAX_ALIGN_T _Alignof(long double)
587587
#endif
588588

589+
#ifndef PY_CXX_CONST
590+
# ifdef __cplusplus
591+
# define PY_CXX_CONST const
592+
# else
593+
# define PY_CXX_CONST
594+
# endif
595+
#endif
596+
589597
#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
590598
# define _SGI_MP_SOURCE
591599
#endif
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Change the declaration of the *keywords* parameter of
2+
:c:func:`PyArg_ParseTupleAndKeywords` and
3+
:c:func:`PyArg_VaParseTupleAndKeywords` for better compatibility with C++.

Python/getargs.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
/* New getargs implementation */
33

4+
#define PY_CXX_CONST const
45
#include "Python.h"
56
#include "pycore_abstract.h" // _PyNumber_Index()
67
#include "pycore_dict.h" // _PyDict_HasOnlyStringKeys()
@@ -12,10 +13,10 @@
1213
PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...);
1314
PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
1415
PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
15-
const char *, char **, ...);
16+
const char *, const char * const *, ...);
1617
PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
1718
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
18-
const char *, char **, va_list);
19+
const char *, const char * const *, va_list);
1920

2021
#define FLAG_COMPAT 1
2122

@@ -54,7 +55,7 @@ static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **);
5455
static int getbuffer(PyObject *, Py_buffer *, const char**);
5556

5657
static int vgetargskeywords(PyObject *, PyObject *,
57-
const char *, char **, va_list *, int);
58+
const char *, const char * const *, va_list *, int);
5859
static int vgetargskeywordsfast(PyObject *, PyObject *,
5960
struct _PyArg_Parser *, va_list *, int);
6061
static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
@@ -1247,7 +1248,7 @@ int
12471248
PyArg_ParseTupleAndKeywords(PyObject *args,
12481249
PyObject *keywords,
12491250
const char *format,
1250-
char **kwlist, ...)
1251+
const char * const *kwlist, ...)
12511252
{
12521253
int retval;
12531254
va_list va;
@@ -1271,7 +1272,7 @@ int
12711272
_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
12721273
PyObject *keywords,
12731274
const char *format,
1274-
char **kwlist, ...)
1275+
const char * const *kwlist, ...)
12751276
{
12761277
int retval;
12771278
va_list va;
@@ -1297,7 +1298,7 @@ int
12971298
PyArg_VaParseTupleAndKeywords(PyObject *args,
12981299
PyObject *keywords,
12991300
const char *format,
1300-
char **kwlist, va_list va)
1301+
const char * const *kwlist, va_list va)
13011302
{
13021303
int retval;
13031304
va_list lva;
@@ -1322,7 +1323,7 @@ int
13221323
_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
13231324
PyObject *keywords,
13241325
const char *format,
1325-
char **kwlist, va_list va)
1326+
const char * const *kwlist, va_list va)
13261327
{
13271328
int retval;
13281329
va_list lva;
@@ -1460,7 +1461,7 @@ PyArg_ValidateKeywordArguments(PyObject *kwargs)
14601461

14611462
static int
14621463
vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1463-
char **kwlist, va_list *p_va, int flags)
1464+
const char * const *kwlist, va_list *p_va, int flags)
14641465
{
14651466
char msgbuf[512];
14661467
int levels[32];

0 commit comments

Comments
 (0)
0