From 6793f3838077e3cf12d4e44059396478757522b2 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Mar 2022 15:21:26 +0800 Subject: [PATCH 01/23] Fix a bug which allows more than one varargs Python allows at most *one* vararg in one function. Remove the improper varargs check which allows function definition like ``` *vararg1: object *vararg2: object ``` in argument clinic. --- Tools/clinic/clinic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 14252b2514ea87..3acd46f45418f8 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -650,7 +650,7 @@ def output_templates(self, f): vararg = NO_VARARG pos_only = min_pos = max_pos = min_kw_only = pseudo_args = 0 for i, p in enumerate(parameters, 1): - if p.is_keyword_only() or vararg != NO_VARARG: + if p.is_keyword_only(): assert not p.is_positional_only() if not p.is_optional(): min_kw_only = i - max_pos From 620396279cf94e09bd7cd6e925e6e80471130d6f Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Mar 2022 15:48:09 +0800 Subject: [PATCH 02/23] Fix an array index out-of-bound bug Variable `vararg` indicates the index of vararg in parameter list. While copying kwargs to `buf`, the index `i` should not add `vararg`, which leads to an out-of-bound bug. When there are positional args, vararg and keyword args in a function definition, in which case `vararg` > 1, this bug can be triggered. e.g. ``` pos: object *args: object kw: object ``` --- Python/getargs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/getargs.c b/Python/getargs.c index a2ea4d7da45f83..c6c107a5c549fe 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2571,7 +2571,7 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, current_arg = NULL; } - buf[i + vararg + 1] = current_arg; + buf[i + 1] = current_arg; if (current_arg) { --nkwargs; From 03be6f909b429a7f78868271e9d4bf70a912f5fa Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Mar 2022 16:07:08 +0800 Subject: [PATCH 03/23] Fix a kwarg parse bug The calculation of noptargs is incorrect when there is a vararg. This bug prevents parsed arguments passing to XXXX_impl function. e.g. Define function ``` *args: object kw: object ``` and pass kw=1 to the function, the `kw` parameter won't receive the pass in value. --- Lib/test/clinic.test | 8 ++++---- Tools/clinic/clinic.py | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index d2934b3f211acf..0eaac925ebb711 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -3379,7 +3379,7 @@ test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject static const char * const _keywords[] = {"a", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg", 0}; PyObject *argsbuf[2]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; @@ -3398,7 +3398,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=f721025731c3bfe8 input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=f0b24e19c9dc129b input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -3429,7 +3429,7 @@ test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nar static const char * const _keywords[] = {"a", "b", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_default", 0}; PyObject *argsbuf[3]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; int b = 0; @@ -3458,7 +3458,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=63b34d3241c52fda input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=0065e7b11eeb4826 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 3acd46f45418f8..9aa6d25ca908f9 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -941,6 +941,7 @@ def parser_body(prototype, *fields, declarations=''): max_pos, min_kw_only ) + pre_buffer = "nargs" else: args_declaration = "_PyArg_UnpackKeywordsWithVararg", "%s, %s, %s, %s" % ( min_pos, @@ -948,6 +949,7 @@ def parser_body(prototype, *fields, declarations=''): min_kw_only, vararg ) + pre_buffer = f"Py_MIN(nargs, {max_pos})" if max_pos else "0" if not new_or_init: flags = "METH_FASTCALL|METH_KEYWORDS" parser_prototype = parser_prototype_fastcall_keywords @@ -958,7 +960,6 @@ def parser_body(prototype, *fields, declarations=''): PyObject *argsbuf[%s]; """ % len(converters)) if has_optional_kw: - pre_buffer = "0" if vararg != NO_VARARG else "nargs" declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (pre_buffer, min_pos + min_kw_only) parser_code = [normalize_snippet(""" args = %s(args, nargs, NULL, kwnames, &_parser, %s, argsbuf); @@ -979,7 +980,7 @@ def parser_body(prototype, *fields, declarations=''): Py_ssize_t nargs = PyTuple_GET_SIZE(args); """ % len(converters)) if has_optional_kw: - declarations += "\nPy_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (min_pos + min_kw_only) + declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (pre_buffer, min_pos + min_kw_only) parser_code = [normalize_snippet(""" fastargs = %s(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, %s, argsbuf); if (!fastargs) {{ From 45bde03d1306d65d30cf227457352765104d822e Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 11 Aug 2022 16:08:22 +0800 Subject: [PATCH 04/23] Regenerate clinic.test --- Lib/test/clinic.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index e981b5a28504ef..11c2d453d6c928 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -3373,7 +3373,7 @@ test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject static const char * const _keywords[] = {"a", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg", 0}; PyObject *argsbuf[2]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; @@ -3392,7 +3392,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=a2baf8c1fade41d2 input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=caf48e7cf5028a40 input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -3423,7 +3423,7 @@ test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nar static const char * const _keywords[] = {"a", "b", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_default", 0}; PyObject *argsbuf[3]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; int b = 0; @@ -3452,7 +3452,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=3821d282c29f8616 input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=32fb19dd6bcf9185 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults From bfc524195b1192b2cf8afc78a711149fb5c3b08c Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 11 Aug 2022 16:54:20 +0800 Subject: [PATCH 05/23] Replace `pre_buffer` to a more descriptive name `nargs` --- Tools/clinic/clinic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index ffd90d281f92d2..82d255d9379a78 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -956,7 +956,7 @@ def parser_body(prototype, *fields, declarations=''): max_pos, min_kw_only ) - pre_buffer = "nargs" + nargs = "nargs" else: args_declaration = "_PyArg_UnpackKeywordsWithVararg", "%s, %s, %s, %s" % ( min_pos, @@ -964,7 +964,7 @@ def parser_body(prototype, *fields, declarations=''): min_kw_only, vararg ) - pre_buffer = f"Py_MIN(nargs, {max_pos})" if max_pos else "0" + nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0" if not new_or_init: flags = "METH_FASTCALL|METH_KEYWORDS" parser_prototype = parser_prototype_fastcall_keywords @@ -975,7 +975,7 @@ def parser_body(prototype, *fields, declarations=''): PyObject *argsbuf[%s]; """ % len(converters)) if has_optional_kw: - declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (pre_buffer, min_pos + min_kw_only) + declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (nargs, min_pos + min_kw_only) parser_code = [normalize_snippet(""" args = %s(args, nargs, NULL, kwnames, &_parser, %s, argsbuf); if (!args) {{ @@ -995,7 +995,7 @@ def parser_body(prototype, *fields, declarations=''): Py_ssize_t nargs = PyTuple_GET_SIZE(args); """ % len(converters)) if has_optional_kw: - declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (pre_buffer, min_pos + min_kw_only) + declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (nargs, min_pos + min_kw_only) parser_code = [normalize_snippet(""" fastargs = %s(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, %s, argsbuf); if (!fastargs) {{ From 0b1523cca3cef8e3bcfb39991e71c84b9b4a7950 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 11 Aug 2022 09:58:16 +0000 Subject: [PATCH 06/23] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2-08-11-09-58-15.gh-issue-32092.PjwhM4.rst | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst new file mode 100644 index 00000000000000..9a3059e7372671 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst @@ -0,0 +1,42 @@ +Fixes 3 bugs of clinic.py + + +1. Fix a kwarg parse bug + +The calculation of noptargs is incorrect when there is a vararg. +This bug prevents parsed arguments passing to XXXX_impl function. + +e.g. +Define function with args:: + + *args: object + kw: object + +and pass kw=1 to the function, the `kw` parameter won't receive the pass in value. + + +2. Fix an array index out-of-bound bug + +Variable `vararg` indicates the index of vararg in parameter list. + +While copying kwargs to `buf`, the index `i` should not add `vararg`, which leads to an out-of-bound bug. + +When there are positional args, vararg and keyword args in a function definition, in which case `vararg` > 1, this bug can be triggered. + +e.g. +Define function with args:: + + pos: object + *args: object + kw: object + + +3. Fix a bug which allows more than one varargs + +More than *one* `vararg` should not be allowed. + +e.g. +Define function with args:: + + *vararg1: object + *vararg2: object From 411ad3738806cee75462967f7467a526f2cb57c3 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 11 Aug 2022 18:07:58 +0800 Subject: [PATCH 07/23] Replace inline literals with double backticks in news --- .../2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst index 9a3059e7372671..3429a95eb685b9 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst @@ -12,16 +12,16 @@ Define function with args:: *args: object kw: object -and pass kw=1 to the function, the `kw` parameter won't receive the pass in value. +and pass kw=1 to the function, the "kw" parameter won't receive the pass in value. 2. Fix an array index out-of-bound bug -Variable `vararg` indicates the index of vararg in parameter list. +Variable "vararg" indicates the index of vararg in parameter list. -While copying kwargs to `buf`, the index `i` should not add `vararg`, which leads to an out-of-bound bug. +While copying kwargs to "buf", the index "i" should not add "vararg", which leads to an out-of-bound bug. -When there are positional args, vararg and keyword args in a function definition, in which case `vararg` > 1, this bug can be triggered. +When there are positional args, vararg and keyword args in a function definition, in which case "vararg" > 1, this bug can be triggered. e.g. Define function with args:: @@ -33,10 +33,10 @@ Define function with args:: 3. Fix a bug which allows more than one varargs -More than *one* `vararg` should not be allowed. +More than *one* "vararg" should not be allowed. e.g. Define function with args:: *vararg1: object - *vararg2: object + *vararg2: object From c6a51714690a77245d92dffc9856583abf6b82cd Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 11 Aug 2022 18:18:14 +0800 Subject: [PATCH 08/23] Rename news --- ...-08-11-09-58-15.gh-issue-64490.PjwhM4.rst} | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) rename Misc/NEWS.d/next/Tools-Demos/{2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst => 2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst} (95%) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst similarity index 95% rename from Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst rename to Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst index 3429a95eb685b9..731b979bd7c99a 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-32092.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst @@ -1,42 +1,42 @@ -Fixes 3 bugs of clinic.py - - -1. Fix a kwarg parse bug - -The calculation of noptargs is incorrect when there is a vararg. -This bug prevents parsed arguments passing to XXXX_impl function. - -e.g. -Define function with args:: - - *args: object - kw: object - -and pass kw=1 to the function, the "kw" parameter won't receive the pass in value. - - -2. Fix an array index out-of-bound bug - -Variable "vararg" indicates the index of vararg in parameter list. - -While copying kwargs to "buf", the index "i" should not add "vararg", which leads to an out-of-bound bug. - -When there are positional args, vararg and keyword args in a function definition, in which case "vararg" > 1, this bug can be triggered. - -e.g. -Define function with args:: - - pos: object - *args: object - kw: object - - -3. Fix a bug which allows more than one varargs - -More than *one* "vararg" should not be allowed. - -e.g. -Define function with args:: - - *vararg1: object - *vararg2: object +Fixes 3 bugs of clinic.py + + +1. Fix a kwarg parse bug + +The calculation of noptargs is incorrect when there is a vararg. +This bug prevents parsed arguments passing to XXXX_impl function. + +e.g. +Define function with args:: + + *args: object + kw: object + +and pass kw=1 to the function, the "kw" parameter won't receive the pass in value. + + +2. Fix an array index out-of-bound bug + +Variable "vararg" indicates the index of vararg in parameter list. + +While copying kwargs to "buf", the index "i" should not add "vararg", which leads to an out-of-bound bug. + +When there are positional args, vararg and keyword args in a function definition, in which case "vararg" > 1, this bug can be triggered. + +e.g. +Define function with args:: + + pos: object + *args: object + kw: object + + +3. Fix a bug which allows more than one varargs + +More than *one* "vararg" should not be allowed. + +e.g. +Define function with args:: + + *vararg1: object + *vararg2: object From 7fdd501aab66e14634386d1949a5243da29023a9 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Fri, 12 Aug 2022 12:34:48 +0800 Subject: [PATCH 09/23] Simplify news --- ...2-08-11-09-58-15.gh-issue-64490.PjwhM4.rst | 45 ++----------------- 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst index 731b979bd7c99a..85ac26fd08fd6a 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst @@ -1,42 +1,3 @@ -Fixes 3 bugs of clinic.py - - -1. Fix a kwarg parse bug - -The calculation of noptargs is incorrect when there is a vararg. -This bug prevents parsed arguments passing to XXXX_impl function. - -e.g. -Define function with args:: - - *args: object - kw: object - -and pass kw=1 to the function, the "kw" parameter won't receive the pass in value. - - -2. Fix an array index out-of-bound bug - -Variable "vararg" indicates the index of vararg in parameter list. - -While copying kwargs to "buf", the index "i" should not add "vararg", which leads to an out-of-bound bug. - -When there are positional args, vararg and keyword args in a function definition, in which case "vararg" > 1, this bug can be triggered. - -e.g. -Define function with args:: - - pos: object - *args: object - kw: object - - -3. Fix a bug which allows more than one varargs - -More than *one* "vararg" should not be allowed. - -e.g. -Define function with args:: - - *vararg1: object - *vararg2: object +Fix an out-of-bound bug of :c:func:`_PyArg_UnpackKeywordsWithVararg`. +Fix a incorrect check which allows more than one varargs in clinic.py. +Fix a calculation error of ``noptargs`` in ArgumentClinic generated code. From 0aa4be4201599f8472c191d788b399fc782833b6 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Fri, 12 Aug 2022 19:21:56 +0800 Subject: [PATCH 10/23] Regenerate clinic.test --- Lib/test/clinic.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index 7169a3b0d17349..840f5f990d5ce2 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -4066,7 +4066,7 @@ test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; @@ -4085,7 +4085,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=ac4d536e5b76c9fa input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=3ca94c3a745862a5 input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -4149,7 +4149,7 @@ test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nar }; #undef KWTUPLE PyObject *argsbuf[3]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; int b = 0; @@ -4178,7 +4178,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=f0c70f7e2e1c0523 input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=2a4faf0f251b2348 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults From bbad2bb8730704aa9bbaa8161846228537f58386 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Mon, 15 Aug 2022 10:00:20 +0800 Subject: [PATCH 11/23] Add test "allow no more than one vararg" --- Lib/test/test_clinic.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 4aa9691a4829d1..ceebf8fc9429e9 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -730,6 +730,15 @@ def test_parameters_not_permitted_after_slash_for_now(self): x: int """) + def test_parameters_no_more_than_one_vararg(self): + s = self.parse_function_should_fail(""" +module foo +foo.bar + *vararg1: object + *vararg2: object +""") + self.assertEqual(s, "Error on line 0:\nToo many var args\n") + def test_function_not_at_column_0(self): function = self.parse_function(""" module foo From 4fb66ab02e3ad5167e125fb1fccf36ba4f9a9951 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Mon, 15 Aug 2022 10:15:06 +0800 Subject: [PATCH 12/23] Regenerate clinic.test --- Lib/test/clinic.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index c73a75b163fa37..fa9b8600d88648 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -3856,7 +3856,7 @@ test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; @@ -3875,7 +3875,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=6661f3ca97d85e8c input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=e98d5fe6742888b8 input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -3929,7 +3929,7 @@ test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nar }; #undef KWTUPLE PyObject *argsbuf[3]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; int b = 0; @@ -3958,7 +3958,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=5fe3cfccb1bef781 input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=291e9a5a09831128 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults From 8f1176553f0097fb5b90905c6583418b4d78d603 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Mon, 15 Aug 2022 18:32:06 +0800 Subject: [PATCH 13/23] Modify news --- .../Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst index 85ac26fd08fd6a..3d0d91a4e8d26c 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst @@ -1,3 +1,3 @@ -Fix an out-of-bound bug of :c:func:`_PyArg_UnpackKeywordsWithVararg`. +Fix an out-of-bound bug of :c:func:`!_PyArg_UnpackKeywordsWithVararg`. Fix a incorrect check which allows more than one varargs in clinic.py. Fix a calculation error of ``noptargs`` in ArgumentClinic generated code. From de5b2a48628866369eb70fefe85069db70d89275 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 15 Aug 2022 13:13:07 +0200 Subject: [PATCH 14/23] Update 2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst --- .../2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst index 3d0d91a4e8d26c..674492d83d2ee6 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst @@ -1,3 +1,5 @@ -Fix an out-of-bound bug of :c:func:`!_PyArg_UnpackKeywordsWithVararg`. -Fix a incorrect check which allows more than one varargs in clinic.py. -Fix a calculation error of ``noptargs`` in ArgumentClinic generated code. +Argument Clinic varargs bugfixes + +- Fix out-of-bounds error in :c:func:`!_PyArg_UnpackKeywordsWithVararg`. +- Fix incorrect check which allowed more than one varargs in clinic.py. +- Fix miscalculation of ``noptargs`` in generated code. From 85f98ca70a6ab30fae6d6920e6d49471eb0720f7 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 15 Aug 2022 13:18:27 +0200 Subject: [PATCH 15/23] Sphinx syntax/format fix --- .../2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst index 674492d83d2ee6..2e77c4965ed318 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst @@ -1,5 +1,5 @@ Argument Clinic varargs bugfixes -- Fix out-of-bounds error in :c:func:`!_PyArg_UnpackKeywordsWithVararg`. -- Fix incorrect check which allowed more than one varargs in clinic.py. -- Fix miscalculation of ``noptargs`` in generated code. +* Fix out-of-bounds error in :c:func:`!_PyArg_UnpackKeywordsWithVararg`. +* Fix incorrect check which allowed more than one varargs in clinic.py. +* Fix miscalculation of ``noptargs`` in generated code. From 58a3da5fa67ee56938f6fd15675dfab8d5947bee Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 15 Aug 2022 13:18:52 +0200 Subject: [PATCH 16/23] Missing blank line --- .../Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst index 2e77c4965ed318..78a0923e097314 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst @@ -3,3 +3,4 @@ Argument Clinic varargs bugfixes * Fix out-of-bounds error in :c:func:`!_PyArg_UnpackKeywordsWithVararg`. * Fix incorrect check which allowed more than one varargs in clinic.py. * Fix miscalculation of ``noptargs`` in generated code. + From 87314ff2731a1cdaa2b8cfb3e51650c3ea52ff14 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Nov 2022 13:23:51 +0800 Subject: [PATCH 17/23] Add Argument Clinic functional test cases --- .../pycore_global_objects_fini_generated.h | 5 + Include/internal/pycore_global_strings.h | 5 + .../internal/pycore_runtime_init_generated.h | 5 + .../internal/pycore_unicodeobject_generated.h | 10 + Lib/test/test_clinic.py | 33 ++ Modules/_testclinic.c | 129 ++++++ Modules/clinic/_testclinic.c.h | 404 +++++++++++++++++- 7 files changed, 590 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 494bcf293cdb7b..9951fa9951e67a 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -986,6 +986,9 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keyfile)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keys)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kind)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw2)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lambda)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_node)); @@ -1084,6 +1087,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pid)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(policy)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(print_file_and_line)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(priority)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index b0cb8365933e77..12144b02f45574 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -472,6 +472,9 @@ struct _Py_global_strings { STRUCT_FOR_ID(keyfile) STRUCT_FOR_ID(keys) STRUCT_FOR_ID(kind) + STRUCT_FOR_ID(kw) + STRUCT_FOR_ID(kw1) + STRUCT_FOR_ID(kw2) STRUCT_FOR_ID(lambda) STRUCT_FOR_ID(last) STRUCT_FOR_ID(last_node) @@ -570,6 +573,8 @@ struct _Py_global_strings { STRUCT_FOR_ID(pid) STRUCT_FOR_ID(policy) STRUCT_FOR_ID(pos) + STRUCT_FOR_ID(pos1) + STRUCT_FOR_ID(pos2) STRUCT_FOR_ID(print_file_and_line) STRUCT_FOR_ID(priority) STRUCT_FOR_ID(progress) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 4b128da54555b7..87b0f2ed8dfa8c 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -978,6 +978,9 @@ extern "C" { INIT_ID(keyfile), \ INIT_ID(keys), \ INIT_ID(kind), \ + INIT_ID(kw), \ + INIT_ID(kw1), \ + INIT_ID(kw2), \ INIT_ID(lambda), \ INIT_ID(last), \ INIT_ID(last_node), \ @@ -1076,6 +1079,8 @@ extern "C" { INIT_ID(pid), \ INIT_ID(policy), \ INIT_ID(pos), \ + INIT_ID(pos1), \ + INIT_ID(pos2), \ INIT_ID(print_file_and_line), \ INIT_ID(priority), \ INIT_ID(progress), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 7ef1f7e94ddead..80be342b5b3b44 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -850,6 +850,12 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(kind); PyUnicode_InternInPlace(&string); + string = &_Py_ID(kw); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(kw1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(kw2); + PyUnicode_InternInPlace(&string); string = &_Py_ID(lambda); PyUnicode_InternInPlace(&string); string = &_Py_ID(last); @@ -1046,6 +1052,10 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(pos); PyUnicode_InternInPlace(&string); + string = &_Py_ID(pos1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pos2); + PyUnicode_InternInPlace(&string); string = &_Py_ID(print_file_and_line); PyUnicode_InternInPlace(&string); string = &_Py_ID(priority); diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 8cbac5fc7dbdbf..0fad448df5246e 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -1220,6 +1220,39 @@ def test_keyword_only_parameter(self): ac_tester.keyword_only_parameter(1) self.assertEqual(ac_tester.keyword_only_parameter(a=1), (1,)) + def test_posonly_vararg(self): + with self.assertRaises(TypeError): + ac_tester.posonly_vararg() + self.assertEqual(ac_tester.posonly_vararg(1, 2), (1, 2, ())) + self.assertEqual(ac_tester.posonly_vararg(1, b=2), (1, 2, ())) + self.assertEqual(ac_tester.posonly_vararg(1, 2, 3, 4), (1, 2, (3, 4))) + + def test_vararg(self): + with self.assertRaises(TypeError): + ac_tester.vararg() + with self.assertRaises(TypeError): + ac_tester.vararg(1, b=2) + self.assertEqual(ac_tester.vararg(1, 2, 3, 4), (1, (2, 3, 4))) + + def test_vararg_with_default(self): + with self.assertRaises(TypeError): + ac_tester.vararg_with_default() + self.assertEqual(ac_tester.vararg_with_default(1, b=False), (1, (), False)) + self.assertEqual(ac_tester.vararg_with_default(1, 2, 3, 4), (1, (2, 3, 4), False)) + self.assertEqual(ac_tester.vararg_with_default(1, 2, 3, 4, b=True), (1, (2, 3, 4), True)) + + def test_vararg_with_only_defaults(self): + self.assertEqual(ac_tester.vararg_with_only_defaults(), ((), None)) + self.assertEqual(ac_tester.vararg_with_only_defaults(b=2), ((), 2)) + self.assertEqual(ac_tester.vararg_with_only_defaults(1, b=2), ((1, ), 2)) + self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4), ((1, 2, 3, 4), None)) + self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4, b=5), ((1, 2, 3, 4), 5)) + + def test_gh_32092_oob(self): + ac_tester.gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6) + + def test_gh_32092_kw_pass(self): + ac_tester.gh_32092_kw_pass(1, 2, 3) if __name__ == "__main__": unittest.main() diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index c9858e96445714..f0428b78c4fd62 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -892,6 +892,129 @@ keyword_only_parameter_impl(PyObject *module, PyObject *a) } +/*[clinic input] +posonly_vararg + + a: object + / + b: object + *args: object + +[clinic start generated code]*/ + +static PyObject * +posonly_vararg_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *args) +/*[clinic end generated code: output=ee6713acda6b954e input=783427fe7ec2b67a]*/ +{ + return pack_arguments_newref(3, a, b, args); +} + +/*[clinic input] +vararg + + a: object + *args: object + +[clinic start generated code]*/ + +static PyObject * +vararg_impl(PyObject *module, PyObject *a, PyObject *args) +/*[clinic end generated code: output=91ab7a0efc52dd5e input=02c0f772d05f591e]*/ +{ + return pack_arguments_newref(2, a, args); +} + + +/*[clinic input] +vararg_with_default + + a: object + *args: object + b: bool = False + +[clinic start generated code]*/ + +static PyObject * +vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, + int b) +/*[clinic end generated code: output=182c01035958ce92 input=68cafa6a79f89e36]*/ +{ + PyObject *obj_b = b ? Py_True : Py_False; + return pack_arguments_newref(3, a, args, obj_b); +} + + +/*[clinic input] +vararg_with_only_defaults + + *args: object + b: object = None + +[clinic start generated code]*/ + +static PyObject * +vararg_with_only_defaults_impl(PyObject *module, PyObject *args, PyObject *b) +/*[clinic end generated code: output=c06b1826d91f2f7b input=678c069bc67550e1]*/ +{ + return pack_arguments_newref(2, args, b); +} + + +/*[clinic input] +gh_32092_oob + + pos1: object + pos2: object + *varargs: object + kw1: object = None + kw2: object = None + +Proof-of-concept of GH-32092 OOB bug. + +Array index out-of-bound bug in function +`_PyArg_UnpackKeywordsWithVararg` . + +Calling this function by gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6) +to trigger this bug (crash). + +[clinic start generated code]*/ + +static PyObject * +gh_32092_oob_impl(PyObject *module, PyObject *pos1, PyObject *pos2, + PyObject *varargs, PyObject *kw1, PyObject *kw2) +/*[clinic end generated code: output=ee259c130054653f input=568c6276e3fdef62]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +gh_32092_kw_pass + + pos: object + *args: object + kw: object = None + +Proof-of-concept of GH-32092 keyword args passing bug. + +The calculation of `noptargs` in AC-generated function +`builtin_kw_pass_poc` is incorrect. + +Calling this function by gh_32092_kw_pass(1, 2, 3) +to trigger this bug (crash). + +[clinic start generated code]*/ + +static PyObject * +gh_32092_kw_pass_impl(PyObject *module, PyObject *pos, PyObject *args, + PyObject *kw) +/*[clinic end generated code: output=4a2bbe4f7c8604e9 input=5bfe6191e1e7a2fb]*/ +{ + Py_RETURN_NONE; +} + + static PyMethodDef tester_methods[] = { TEST_EMPTY_FUNCTION_METHODDEF OBJECTS_CONVERTER_METHODDEF @@ -933,6 +1056,12 @@ static PyMethodDef tester_methods[] = { POSONLY_KEYWORDS_OPT_KWONLY_OPT_METHODDEF POSONLY_OPT_KEYWORDS_OPT_KWONLY_OPT_METHODDEF KEYWORD_ONLY_PARAMETER_METHODDEF + POSONLY_VARARG_METHODDEF + VARARG_METHODDEF + VARARG_WITH_DEFAULT_METHODDEF + VARARG_WITH_ONLY_DEFAULTS_METHODDEF + GH_32092_OOB_METHODDEF + GH_32092_KW_PASS_METHODDEF {NULL, NULL} }; diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index b0ac4c2eef8340..9943d2c371a10b 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -2288,4 +2288,406 @@ keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=a9212f8e6ba18bba input=a9049054013a1b77]*/ + +PyDoc_STRVAR(posonly_vararg__doc__, +"posonly_vararg($module, a, /, b, *args)\n" +"--\n" +"\n"); + +#define POSONLY_VARARG_METHODDEF \ + {"posonly_vararg", _PyCFunction_CAST(posonly_vararg), METH_FASTCALL|METH_KEYWORDS, posonly_vararg__doc__}, + +static PyObject * +posonly_vararg_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *args); + +static PyObject * +posonly_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = Py_MIN(nargs, 2) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *a; + PyObject *b; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, 2, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + __clinic_args = args[2]; + return_value = posonly_vararg_impl(module, a, b, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(vararg__doc__, +"vararg($module, /, a, *args)\n" +"--\n" +"\n"); + +#define VARARG_METHODDEF \ + {"vararg", _PyCFunction_CAST(vararg), METH_FASTCALL|METH_KEYWORDS, vararg__doc__}, + +static PyObject * +vararg_impl(PyObject *module, PyObject *a, PyObject *args); + +static PyObject * +vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + __clinic_args = args[1]; + return_value = vararg_impl(module, a, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(vararg_with_default__doc__, +"vararg_with_default($module, /, a, *args, b=False)\n" +"--\n" +"\n"); + +#define VARARG_WITH_DEFAULT_METHODDEF \ + {"vararg_with_default", _PyCFunction_CAST(vararg_with_default), METH_FASTCALL|METH_KEYWORDS, vararg_with_default__doc__}, + +static PyObject * +vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, + int b); + +static PyObject * +vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg_with_default", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *__clinic_args = NULL; + int b = 0; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + __clinic_args = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + b = PyObject_IsTrue(args[2]); + if (b < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = vararg_with_default_impl(module, a, __clinic_args, b); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(vararg_with_only_defaults__doc__, +"vararg_with_only_defaults($module, /, *args, b=None)\n" +"--\n" +"\n"); + +#define VARARG_WITH_ONLY_DEFAULTS_METHODDEF \ + {"vararg_with_only_defaults", _PyCFunction_CAST(vararg_with_only_defaults), METH_FASTCALL|METH_KEYWORDS, vararg_with_only_defaults__doc__}, + +static PyObject * +vararg_with_only_defaults_impl(PyObject *module, PyObject *args, PyObject *b); + +static PyObject * +vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg_with_only_defaults", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *__clinic_args = NULL; + PyObject *b = Py_None; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + __clinic_args = args[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + b = args[1]; +skip_optional_kwonly: + return_value = vararg_with_only_defaults_impl(module, __clinic_args, b); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(gh_32092_oob__doc__, +"gh_32092_oob($module, /, pos1, pos2, *varargs, kw1=None, kw2=None)\n" +"--\n" +"\n" +"Proof-of-concept of GH-32092 OOB bug.\n" +"\n" +"Array index out-of-bound bug in function\n" +"`_PyArg_UnpackKeywordsWithVararg` .\n" +"\n" +"Calling this function by gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6)\n" +"to trigger this bug (crash)."); + +#define GH_32092_OOB_METHODDEF \ + {"gh_32092_oob", _PyCFunction_CAST(gh_32092_oob), METH_FASTCALL|METH_KEYWORDS, gh_32092_oob__doc__}, + +static PyObject * +gh_32092_oob_impl(PyObject *module, PyObject *pos1, PyObject *pos2, + PyObject *varargs, PyObject *kw1, PyObject *kw2); + +static PyObject * +gh_32092_oob(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pos1), &_Py_ID(pos2), &_Py_ID(kw1), &_Py_ID(kw2), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"pos1", "pos2", "kw1", "kw2", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "gh_32092_oob", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = Py_MIN(nargs, 2) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *pos1; + PyObject *pos2; + PyObject *varargs = NULL; + PyObject *kw1 = Py_None; + PyObject *kw2 = Py_None; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, 2, argsbuf); + if (!args) { + goto exit; + } + pos1 = args[0]; + pos2 = args[1]; + varargs = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + kw1 = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + kw2 = args[4]; +skip_optional_kwonly: + return_value = gh_32092_oob_impl(module, pos1, pos2, varargs, kw1, kw2); + +exit: + Py_XDECREF(varargs); + return return_value; +} + +PyDoc_STRVAR(gh_32092_kw_pass__doc__, +"gh_32092_kw_pass($module, /, pos, *args, kw=None)\n" +"--\n" +"\n" +"Proof-of-concept of GH-32092 keyword args passing bug.\n" +"\n" +"The calculation of `noptargs` in AC-generated function\n" +"`builtin_kw_pass_poc` is incorrect.\n" +"\n" +"Calling this function by gh_32092_kw_pass(1, 2, 3)\n" +"to trigger this bug (crash)."); + +#define GH_32092_KW_PASS_METHODDEF \ + {"gh_32092_kw_pass", _PyCFunction_CAST(gh_32092_kw_pass), METH_FASTCALL|METH_KEYWORDS, gh_32092_kw_pass__doc__}, + +static PyObject * +gh_32092_kw_pass_impl(PyObject *module, PyObject *pos, PyObject *args, + PyObject *kw); + +static PyObject * +gh_32092_kw_pass(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pos), &_Py_ID(kw), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"pos", "kw", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "gh_32092_kw_pass", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *pos; + PyObject *__clinic_args = NULL; + PyObject *kw = Py_None; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf); + if (!args) { + goto exit; + } + pos = args[0]; + __clinic_args = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + kw = args[2]; +skip_optional_kwonly: + return_value = gh_32092_kw_pass_impl(module, pos, __clinic_args, kw); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} +/*[clinic end generated code: output=8d776b1fc84b649e input=a9049054013a1b77]*/ From a48971dd8dc04e5712ff5bc78b20cf483c297d9d Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Nov 2022 13:24:16 +0800 Subject: [PATCH 18/23] Fix bug --- Python/getargs.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Python/getargs.c b/Python/getargs.c index cbf982a2817742..0167dd753d88f7 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -2598,7 +2598,25 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, current_arg = NULL; } - buf[i + 1] = current_arg; + /* If an arguments is passed in as a keyword argument, + * it should be placed before `buf[vararg]`. + * + * For example: + * def f(a, /, b, *args): + * pass + * f(1, b=2) + * + * This `buf` array should be: [1, 2, NULL]. + * In this case, nargs < vararg. + * + * Otherwise, we leave a place at `buf[vararg]` for vararg tuple + * so the index is `i + 1`. */ + if (nargs < vararg) { + buf[i] = current_arg; + } + else { + buf[i + 1] = current_arg; + } if (current_arg) { --nkwargs; From e6a4e13d8ed5bd1bd26491748e89d1ba82b4e67e Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Nov 2022 14:42:33 +0800 Subject: [PATCH 19/23] Do not generate unused `noptargs` --- Modules/clinic/_testclinic.c.h | 4 +--- Tools/clinic/clinic.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index 9943d2c371a10b..7ba6c60d7833c1 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -2331,7 +2331,6 @@ posonly_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje }; #undef KWTUPLE PyObject *argsbuf[3]; - Py_ssize_t noptargs = Py_MIN(nargs, 2) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; PyObject *b; PyObject *__clinic_args = NULL; @@ -2391,7 +2390,6 @@ vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwna }; #undef KWTUPLE PyObject *argsbuf[2]; - Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; @@ -2690,4 +2688,4 @@ gh_32092_kw_pass(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb Py_XDECREF(__clinic_args); return return_value; } -/*[clinic end generated code: output=8d776b1fc84b649e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6af75e9c44ffab5c input=a9049054013a1b77]*/ diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 57b9dedc8ec668..333c530ae2c4f9 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -1009,7 +1009,7 @@ def parser_body(prototype, *fields, declarations=''): parser_definition = parser_body(parser_prototype, *parser_code) else: - has_optional_kw = (max(pos_only, min_pos) + min_kw_only < len(converters)) + has_optional_kw = (max(pos_only, min_pos) + min_kw_only < len(converters) - int(vararg != NO_VARARG)) if vararg == NO_VARARG: args_declaration = "_PyArg_UnpackKeywords", "%s, %s, %s" % ( min_pos, From 8592676cdf9b6f6214b5f97718ed79dec8368089 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Nov 2022 14:50:32 +0800 Subject: [PATCH 20/23] Update news --- .../Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst index 78a0923e097314..4a308a9306055c 100644 --- a/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-11-09-58-15.gh-issue-64490.PjwhM4.rst @@ -3,4 +3,5 @@ Argument Clinic varargs bugfixes * Fix out-of-bounds error in :c:func:`!_PyArg_UnpackKeywordsWithVararg`. * Fix incorrect check which allowed more than one varargs in clinic.py. * Fix miscalculation of ``noptargs`` in generated code. +* Do not generate ``noptargs`` when there is a vararg argument and no optional argument. From 4c682bf1127b6af4398d99fb1a215a2d900f4f85 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Nov 2022 15:43:33 +0800 Subject: [PATCH 21/23] Update Lib/test/clinic.test --- Lib/test/clinic.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index 17065ae6e450ed..4c9ff02e45e6ab 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -3856,7 +3856,6 @@ test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; @@ -3875,7 +3874,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=e98d5fe6742888b8 input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=880365c61ae205d7 input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default From c3d6b73761cd3b1f5825eb17c7bbb5e806118867 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Nov 2022 19:28:19 +0800 Subject: [PATCH 22/23] Delete unnecessary function doc --- Modules/_testclinic.c | 16 ++-------------- Modules/clinic/_testclinic.c.h | 18 +++--------------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index f0428b78c4fd62..aad08fbfb5db96 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -972,18 +972,12 @@ gh_32092_oob Proof-of-concept of GH-32092 OOB bug. -Array index out-of-bound bug in function -`_PyArg_UnpackKeywordsWithVararg` . - -Calling this function by gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6) -to trigger this bug (crash). - [clinic start generated code]*/ static PyObject * gh_32092_oob_impl(PyObject *module, PyObject *pos1, PyObject *pos2, PyObject *varargs, PyObject *kw1, PyObject *kw2) -/*[clinic end generated code: output=ee259c130054653f input=568c6276e3fdef62]*/ +/*[clinic end generated code: output=ee259c130054653f input=46d15c881608f8ff]*/ { Py_RETURN_NONE; } @@ -998,18 +992,12 @@ gh_32092_kw_pass Proof-of-concept of GH-32092 keyword args passing bug. -The calculation of `noptargs` in AC-generated function -`builtin_kw_pass_poc` is incorrect. - -Calling this function by gh_32092_kw_pass(1, 2, 3) -to trigger this bug (crash). - [clinic start generated code]*/ static PyObject * gh_32092_kw_pass_impl(PyObject *module, PyObject *pos, PyObject *args, PyObject *kw) -/*[clinic end generated code: output=4a2bbe4f7c8604e9 input=5bfe6191e1e7a2fb]*/ +/*[clinic end generated code: output=4a2bbe4f7c8604e9 input=5c0bd5b9079a0cce]*/ { Py_RETURN_NONE; } diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index 7ba6c60d7833c1..8b148b8196abbe 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -2540,13 +2540,7 @@ PyDoc_STRVAR(gh_32092_oob__doc__, "gh_32092_oob($module, /, pos1, pos2, *varargs, kw1=None, kw2=None)\n" "--\n" "\n" -"Proof-of-concept of GH-32092 OOB bug.\n" -"\n" -"Array index out-of-bound bug in function\n" -"`_PyArg_UnpackKeywordsWithVararg` .\n" -"\n" -"Calling this function by gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6)\n" -"to trigger this bug (crash)."); +"Proof-of-concept of GH-32092 OOB bug."); #define GH_32092_OOB_METHODDEF \ {"gh_32092_oob", _PyCFunction_CAST(gh_32092_oob), METH_FASTCALL|METH_KEYWORDS, gh_32092_oob__doc__}, @@ -2621,13 +2615,7 @@ PyDoc_STRVAR(gh_32092_kw_pass__doc__, "gh_32092_kw_pass($module, /, pos, *args, kw=None)\n" "--\n" "\n" -"Proof-of-concept of GH-32092 keyword args passing bug.\n" -"\n" -"The calculation of `noptargs` in AC-generated function\n" -"`builtin_kw_pass_poc` is incorrect.\n" -"\n" -"Calling this function by gh_32092_kw_pass(1, 2, 3)\n" -"to trigger this bug (crash)."); +"Proof-of-concept of GH-32092 keyword args passing bug."); #define GH_32092_KW_PASS_METHODDEF \ {"gh_32092_kw_pass", _PyCFunction_CAST(gh_32092_kw_pass), METH_FASTCALL|METH_KEYWORDS, gh_32092_kw_pass__doc__}, @@ -2688,4 +2676,4 @@ gh_32092_kw_pass(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb Py_XDECREF(__clinic_args); return return_value; } -/*[clinic end generated code: output=6af75e9c44ffab5c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8895d3fff51da68a input=a9049054013a1b77]*/ From 3f88c54862c5fd12d5216d02ff6dc656af6a4f67 Mon Sep 17 00:00:00 2001 From: colorfulappl Date: Thu, 24 Nov 2022 22:13:24 +0800 Subject: [PATCH 23/23] Rerun make clinic --- Modules/clinic/_testclinic.c.h | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index bcd26b41272f38..21bde529470294 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -2387,9 +2387,9 @@ posonly_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } PyDoc_STRVAR(vararg_and_posonly__doc__, - "vararg_and_posonly($module, a, /, *args)\n" - "--\n" - "\n"); +"vararg_and_posonly($module, a, /, *args)\n" +"--\n" +"\n"); #define VARARG_AND_POSONLY_METHODDEF \ {"vararg_and_posonly", _PyCFunction_CAST(vararg_and_posonly), METH_FASTCALL, vararg_and_posonly__doc__}, @@ -2414,7 +2414,7 @@ vararg_and_posonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } return_value = vararg_and_posonly_impl(module, a, __clinic_args); - exit: +exit: Py_XDECREF(__clinic_args); return return_value; } @@ -2746,13 +2746,12 @@ gh_32092_kw_pass(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb Py_XDECREF(__clinic_args); return return_value; } -/*[clinic end generated code: output=8895d3fff51da68a input=a9049054013a1b77]*/ PyDoc_STRVAR(gh_99233_refcount__doc__, - "gh_99233_refcount($module, /, *args)\n" - "--\n" - "\n" - "Proof-of-concept of GH-99233 refcount error bug."); +"gh_99233_refcount($module, /, *args)\n" +"--\n" +"\n" +"Proof-of-concept of GH-99233 refcount error bug."); #define GH_99233_REFCOUNT_METHODDEF \ {"gh_99233_refcount", _PyCFunction_CAST(gh_99233_refcount), METH_FASTCALL, gh_99233_refcount__doc__}, @@ -2775,16 +2774,16 @@ gh_99233_refcount(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } return_value = gh_99233_refcount_impl(module, __clinic_args); - exit: +exit: Py_XDECREF(__clinic_args); return return_value; } PyDoc_STRVAR(gh_99240_double_free__doc__, - "gh_99240_double_free($module, a, b, /)\n" - "--\n" - "\n" - "Proof-of-concept of GH-99240 double-free bug."); +"gh_99240_double_free($module, a, b, /)\n" +"--\n" +"\n" +"Proof-of-concept of GH-99240 double-free bug."); #define GH_99240_DOUBLE_FREE_METHODDEF \ {"gh_99240_double_free", _PyCFunction_CAST(gh_99240_double_free), METH_FASTCALL, gh_99240_double_free__doc__}, @@ -2800,7 +2799,7 @@ gh_99240_double_free(PyObject *module, PyObject *const *args, Py_ssize_t nargs) char *b = NULL; if (!_PyArg_ParseStack(args, nargs, "eses:gh_99240_double_free", - "idna", &a, "idna", &b)) { + "idna", &a, "idna", &b)) { goto exit; } return_value = gh_99240_double_free_impl(module, a, b); @@ -2809,7 +2808,7 @@ gh_99240_double_free(PyObject *module, PyObject *const *args, Py_ssize_t nargs) /* Post parse cleanup for b */ PyMem_FREE(b); - exit: +exit: return return_value; } -/*[clinic end generated code: output=49dced2c99bcd0fb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a5ca5909c087102 input=a9049054013a1b77]*/