From 2f311437cd51afaa68fd671bb99ff515cf7b029a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Aug 2023 10:13:35 +0300 Subject: [PATCH] gh-107704: Argument Clinic: add support for deprecating keyword use of parameters (GH-107984) It is now possible to deprecate passing keyword arguments for keyword-or-positional parameters with Argument Clinic, using the new '/ [from X.Y]' syntax. (To be read as "positional-only from Python version X.Y") Co-authored-by: Erlend E. Aasland Co-authored-by: Alex Waygood --- Doc/howto/clinic.rst | 65 +- Lib/test/test_clinic.py | 373 ++- ...-08-15-19-50-49.gh-issue-107704.Uu84vd.rst | 4 + Modules/_sqlite/clinic/connection.c.h | 37 +- Modules/_testclinic.c | 286 ++- Modules/clinic/_testclinic_depr.c.h | 2095 +++++++++++++++++ Modules/clinic/_testclinic_depr_star.c.h | 1140 --------- Tools/c-analyzer/cpython/globals-to-fix.tsv | 4 + Tools/clinic/clinic.py | 334 ++- 9 files changed, 2993 insertions(+), 1345 deletions(-) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2023-08-15-19-50-49.gh-issue-107704.Uu84vd.rst create mode 100644 Modules/clinic/_testclinic_depr.c.h delete mode 100644 Modules/clinic/_testclinic_depr_star.c.h diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 463a938fafa..667859e20a5 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1941,54 +1941,70 @@ The generated docstring ends up looking like this: .. _clinic-howto-deprecate-positional: +.. _clinic-howto-deprecate-keyword: -How to deprecate passing parameters positionally ------------------------------------------------- +How to deprecate passing parameters positionally or by keyword +-------------------------------------------------------------- Argument Clinic provides syntax that makes it possible to generate code that -deprecates passing :term:`arguments ` positionally. +deprecates passing :term:`arguments ` for positional-or-keyword +:term:`parameters ` positionally or by keyword. For example, say we've got a module-level function :py:func:`!foo.myfunc` -that has three :term:`parameters `: -positional-or-keyword parameters *a* and *b*, and a keyword-only parameter *c*:: +that has five parameters: a positional-only parameter *a*, three +positional-or-keyword parameters *b*, *c* and *d*, and a keyword-only +parameter *e*:: /*[clinic input] module foo myfunc a: int + / b: int - * c: int + d: int + * + e: int [clinic start generated output]*/ -We now want to make the *b* parameter keyword-only; -however, we'll have to wait two releases before making this change, +We now want to make the *b* parameter positional-only and the *d* parameter +keyword-only; +however, we'll have to wait two releases before making these changes, as mandated by Python's backwards-compatibility policy (see :pep:`387`). For this example, imagine we're in the development phase for Python 3.12: that means we'll be allowed to introduce deprecation warnings in Python 3.12 -whenever the *b* parameter is passed positionally, -and we'll be allowed to make it keyword-only in Python 3.14 at the earliest. +whenever an argument for the *b* parameter is passed by keyword or an argument +for the *d* parameter is passed positionally, and we'll be allowed to make +them positional-only and keyword-only respectively in Python 3.14 at +the earliest. We can use Argument Clinic to emit the desired deprecation warnings -using the ``* [from ...]`` syntax, -by adding the line ``* [from 3.14]`` right above the *b* parameter:: +using the ``[from ...]`` syntax, by adding the line ``/ [from 3.14]`` right +below the *b* parameter and adding the line ``* [from 3.14]`` right above +the *d* parameter:: /*[clinic input] module foo myfunc a: int - * [from 3.14] + / b: int - * + / [from 3.14] c: int + * [from 3.14] + d: int + * + e: int [clinic start generated output]*/ Next, regenerate Argument Clinic code (``make clinic``), and add unit tests for the new behaviour. The generated code will now emit a :exc:`DeprecationWarning` -when an :term:`argument` for the :term:`parameter` *b* is passed positionally. +when an :term:`argument` for the :term:`parameter` *d* is passed positionally +(e.g ``myfunc(1, 2, 3, 4, e=5)``) or an argument for the parameter *b* is +passed by keyword (e.g ``myfunc(1, b=2, c=3, d=4, e=5)``). C preprocessor directives are also generated for emitting -compiler warnings if the ``* [from ...]`` line has not been removed +compiler warnings if the ``[from ...]`` lines have not been removed from the Argument Clinic input when the deprecation period is over, which means when the alpha phase of the specified Python version kicks in. @@ -2001,21 +2017,26 @@ Luckily for us, compiler warnings are now generated: .. code-block:: none In file included from Modules/foomodule.c:139: - Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings] - # warning "In 'foomodule.c', update parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings]" + Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings] + # warning "In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]" ^ -We now close the deprecation phase by making *b* keyword-only; -replace the ``* [from ...]`` line above *b* -with the ``*`` from the line above *c*:: +We now close the deprecation phase by making *a* positional-only and *c* +keyword-only; +replace the ``/ [from ...]`` line below *b* with the ``/`` from the line +below *a* and the ``* [from ...]`` line above *d* with the ``*`` from +the line above *e*:: /*[clinic input] module foo myfunc a: int - * b: int + / c: int + * + d: int + e: int [clinic start generated output]*/ Finally, run ``make clinic`` to regenerate the Argument Clinic code, diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 38eabd2f7f2..934c1e3ffcc 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -1611,7 +1611,7 @@ class ClinicParserTest(TestCase): "module foo\nfoo.bar\n this: int\n *", "module foo\nfoo.bar\n this: int\n *\nDocstring.", ) - err = "Function 'foo.bar' specifies '*' without any parameters afterwards." + err = "Function 'bar' specifies '*' without following parameters." for block in dataset: with self.subTest(block=block): self.expect_failure(block, err) @@ -1679,7 +1679,7 @@ class ClinicParserTest(TestCase): Docstring. """ err = ( - "Function 'foo.bar': expected format '* [from major.minor]' " + "Function 'bar': expected format '[from major.minor]' " "where 'major' and 'minor' are integers; got '3'" ) self.expect_failure(block, err, lineno=3) @@ -1693,7 +1693,7 @@ class ClinicParserTest(TestCase): Docstring. """ err = ( - "Function 'foo.bar': expected format '* [from major.minor]' " + "Function 'bar': expected format '[from major.minor]' " "where 'major' and 'minor' are integers; got 'a.b'" ) self.expect_failure(block, err, lineno=3) @@ -1707,7 +1707,7 @@ class ClinicParserTest(TestCase): Docstring. """ err = ( - "Function 'foo.bar': expected format '* [from major.minor]' " + "Function 'bar': expected format '[from major.minor]' " "where 'major' and 'minor' are integers; got '1.2.3'" ) self.expect_failure(block, err, lineno=3) @@ -1721,8 +1721,24 @@ class ClinicParserTest(TestCase): Docstring. """ err = ( - "Function 'foo.bar' specifies '* [from ...]' without " - "any parameters afterwards" + "Function 'bar' specifies '* [from ...]' without " + "following parameters." + ) + self.expect_failure(block, err, lineno=4) + + def test_parameters_required_after_depr_star2(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + * + b: int + Docstring. + """ + err = ( + "Function 'bar' specifies '* [from ...]' without " + "following parameters." ) self.expect_failure(block, err, lineno=4) @@ -1735,7 +1751,7 @@ class ClinicParserTest(TestCase): * [from 3.14] Docstring. """ - err = "Function 'foo.bar': '* [from ...]' must come before '*'" + err = "Function 'bar': '* [from ...]' must come before '*'" self.expect_failure(block, err, lineno=4) def test_depr_star_duplicate(self): @@ -1749,7 +1765,49 @@ class ClinicParserTest(TestCase): c: int Docstring. """ - err = "Function 'foo.bar' uses '[from ...]' more than once" + err = "Function 'bar' uses '* [from ...]' more than once." + self.expect_failure(block, err, lineno=5) + + def test_depr_star_duplicate2(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + b: int + * [from 3.15] + c: int + Docstring. + """ + err = "Function 'bar' uses '* [from ...]' more than once." + self.expect_failure(block, err, lineno=5) + + def test_depr_slash_duplicate(self): + block = """ + module foo + foo.bar + a: int + / [from 3.14] + b: int + / [from 3.14] + c: int + Docstring. + """ + err = "Function 'bar' uses '/ [from ...]' more than once." + self.expect_failure(block, err, lineno=5) + + def test_depr_slash_duplicate2(self): + block = """ + module foo + foo.bar + a: int + / [from 3.14] + b: int + / [from 3.15] + c: int + Docstring. + """ + err = "Function 'bar' uses '/ [from ...]' more than once." self.expect_failure(block, err, lineno=5) def test_single_slash(self): @@ -1765,6 +1823,34 @@ class ClinicParserTest(TestCase): ) self.expect_failure(block, err) + def test_parameters_required_before_depr_slash(self): + block = """ + module foo + foo.bar + / [from 3.14] + Docstring. + """ + err = ( + "Function 'bar' specifies '/ [from ...]' without " + "preceding parameters." + ) + self.expect_failure(block, err, lineno=2) + + def test_parameters_required_before_depr_slash2(self): + block = """ + module foo + foo.bar + a: int + / + / [from 3.14] + Docstring. + """ + err = ( + "Function 'bar' specifies '/ [from ...]' without " + "preceding parameters." + ) + self.expect_failure(block, err, lineno=4) + def test_double_slash(self): block = """ module foo @@ -1787,12 +1873,61 @@ class ClinicParserTest(TestCase): z: int / """ - err = ( - "Function 'bar' mixes keyword-only and positional-only parameters, " - "which is unsupported." - ) + err = "Function 'bar': '/' must precede '*'" self.expect_failure(block, err) + def test_depr_star_must_come_after_slash(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + / + b: int + Docstring. + """ + err = "Function 'bar': '/' must precede '* [from ...]'" + self.expect_failure(block, err, lineno=4) + + def test_depr_star_must_come_after_depr_slash(self): + block = """ + module foo + foo.bar + a: int + * [from 3.14] + / [from 3.14] + b: int + Docstring. + """ + err = "Function 'bar': '/ [from ...]' must precede '* [from ...]'" + self.expect_failure(block, err, lineno=4) + + def test_star_must_come_after_depr_slash(self): + block = """ + module foo + foo.bar + a: int + * + / [from 3.14] + b: int + Docstring. + """ + err = "Function 'bar': '/ [from ...]' must precede '*'" + self.expect_failure(block, err, lineno=4) + + def test_depr_slash_must_come_after_slash(self): + block = """ + module foo + foo.bar + a: int + / [from 3.14] + / + b: int + Docstring. + """ + err = "Function 'bar': '/' must precede '/ [from ...]'" + self.expect_failure(block, err, lineno=4) + def test_parameters_not_permitted_after_slash_for_now(self): block = """ module foo @@ -2589,11 +2724,33 @@ class ClinicFunctionalTest(unittest.TestCase): locals().update((name, getattr(ac_tester, name)) for name in dir(ac_tester) if name.startswith('test_')) - def check_depr_star(self, pnames, fn, *args, **kwds): + def check_depr_star(self, pnames, fn, *args, name=None, **kwds): + if name is None: + name = fn.__qualname__ + if isinstance(fn, type): + name = f'{fn.__module__}.{name}' regex = ( fr"Passing( more than)?( [0-9]+)? positional argument(s)? to " - fr"{fn.__name__}\(\) is deprecated. Parameter(s)? {pnames} will " - fr"become( a)? keyword-only parameter(s)? in Python 3\.14" + fr"{re.escape(name)}\(\) is deprecated. Parameters? {pnames} will " + fr"become( a)? keyword-only parameters? in Python 3\.14" + ) + with self.assertWarnsRegex(DeprecationWarning, regex) as cm: + # Record the line number, so we're sure we've got the correct stack + # level on the deprecation warning. + _, lineno = fn(*args, **kwds), sys._getframe().f_lineno + self.assertEqual(cm.filename, __file__) + self.assertEqual(cm.lineno, lineno) + + def check_depr_kwd(self, pnames, fn, *args, name=None, **kwds): + if name is None: + name = fn.__qualname__ + if isinstance(fn, type): + name = f'{fn.__module__}.{name}' + pl = 's' if ' ' in pnames else '' + regex = ( + fr"Passing keyword argument{pl} {pnames} to " + fr"{re.escape(name)}\(\) is deprecated. Corresponding parameter{pl} " + fr"will become positional-only in Python 3\.14." ) with self.assertWarnsRegex(DeprecationWarning, regex) as cm: # Record the line number, so we're sure we've got the correct stack @@ -3067,46 +3224,67 @@ class ClinicFunctionalTest(unittest.TestCase): self.assertEqual(func(), name) def test_depr_star_new(self): - regex = re.escape( - "Passing positional arguments to _testclinic.DeprStarNew() is " - "deprecated. Parameter 'a' will become a keyword-only parameter " - "in Python 3.14." - ) - with self.assertWarnsRegex(DeprecationWarning, regex) as cm: - ac_tester.DeprStarNew(None) - self.assertEqual(cm.filename, __file__) + cls = ac_tester.DeprStarNew + cls() + cls(a=None) + self.check_depr_star("'a'", cls, None) def test_depr_star_new_cloned(self): - regex = re.escape( - "Passing positional arguments to _testclinic.DeprStarNew.cloned() " - "is deprecated. Parameter 'a' will become a keyword-only parameter " - "in Python 3.14." - ) - obj = ac_tester.DeprStarNew(a=None) - with self.assertWarnsRegex(DeprecationWarning, regex) as cm: - obj.cloned(None) - self.assertEqual(cm.filename, __file__) + fn = ac_tester.DeprStarNew().cloned + fn() + fn(a=None) + self.check_depr_star("'a'", fn, None, name='_testclinic.DeprStarNew.cloned') def test_depr_star_init(self): - regex = re.escape( - "Passing positional arguments to _testclinic.DeprStarInit() is " - "deprecated. Parameter 'a' will become a keyword-only parameter " - "in Python 3.14." - ) - with self.assertWarnsRegex(DeprecationWarning, regex) as cm: - ac_tester.DeprStarInit(None) - self.assertEqual(cm.filename, __file__) + cls = ac_tester.DeprStarInit + cls() + cls(a=None) + self.check_depr_star("'a'", cls, None) def test_depr_star_init_cloned(self): - regex = re.escape( - "Passing positional arguments to _testclinic.DeprStarInit.cloned() " - "is deprecated. Parameter 'a' will become a keyword-only parameter " - "in Python 3.14." - ) - obj = ac_tester.DeprStarInit(a=None) - with self.assertWarnsRegex(DeprecationWarning, regex) as cm: - obj.cloned(None) - self.assertEqual(cm.filename, __file__) + fn = ac_tester.DeprStarInit().cloned + fn() + fn(a=None) + self.check_depr_star("'a'", fn, None, name='_testclinic.DeprStarInit.cloned') + + def test_depr_star_init_noinline(self): + cls = ac_tester.DeprStarInitNoInline + self.assertRaises(TypeError, cls, "a") + cls(a="a", b="b") + cls(a="a", b="b", c="c") + cls("a", b="b") + cls("a", b="b", c="c") + check = partial(self.check_depr_star, "'b' and 'c'", cls) + check("a", "b") + check("a", "b", "c") + check("a", "b", c="c") + self.assertRaises(TypeError, cls, "a", "b", "c", "d") + + def test_depr_kwd_new(self): + cls = ac_tester.DeprKwdNew + cls() + cls(None) + self.check_depr_kwd("'a'", cls, a=None) + + def test_depr_kwd_init(self): + cls = ac_tester.DeprKwdInit + cls() + cls(None) + self.check_depr_kwd("'a'", cls, a=None) + + def test_depr_kwd_init_noinline(self): + cls = ac_tester.DeprKwdInitNoInline + cls = ac_tester.depr_star_noinline + self.assertRaises(TypeError, cls, "a") + cls(a="a", b="b") + cls(a="a", b="b", c="c") + cls("a", b="b") + cls("a", b="b", c="c") + check = partial(self.check_depr_star, "'b' and 'c'", cls) + check("a", "b") + check("a", "b", "c") + check("a", "b", c="c") + self.assertRaises(TypeError, cls, "a", "b", "c", "d") def test_depr_star_pos0_len1(self): fn = ac_tester.depr_star_pos0_len1 @@ -3177,6 +3355,103 @@ class ClinicFunctionalTest(unittest.TestCase): check("a", "b", "c", d=0, e=0) check("a", "b", "c", "d", e=0) + def test_depr_star_noinline(self): + fn = ac_tester.depr_star_noinline + self.assertRaises(TypeError, fn, "a") + fn(a="a", b="b") + fn(a="a", b="b", c="c") + fn("a", b="b") + fn("a", b="b", c="c") + check = partial(self.check_depr_star, "'b' and 'c'", fn) + check("a", "b") + check("a", "b", "c") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + + def test_depr_kwd_required_1(self): + fn = ac_tester.depr_kwd_required_1 + fn("a", "b") + self.assertRaises(TypeError, fn, "a") + self.assertRaises(TypeError, fn, "a", "b", "c") + check = partial(self.check_depr_kwd, "'b'", fn) + check("a", b="b") + self.assertRaises(TypeError, fn, a="a", b="b") + + def test_depr_kwd_required_2(self): + fn = ac_tester.depr_kwd_required_2 + fn("a", "b", "c") + self.assertRaises(TypeError, fn, "a", "b") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", "b", c="c") + check("a", b="b", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + + def test_depr_kwd_optional_1(self): + fn = ac_tester.depr_kwd_optional_1 + fn("a") + fn("a", "b") + self.assertRaises(TypeError, fn) + self.assertRaises(TypeError, fn, "a", "b", "c") + check = partial(self.check_depr_kwd, "'b'", fn) + check("a", b="b") + self.assertRaises(TypeError, fn, a="a", b="b") + + def test_depr_kwd_optional_2(self): + fn = ac_tester.depr_kwd_optional_2 + fn("a") + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn) + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", b="b") + check("a", c="c") + check("a", b="b", c="c") + check("a", c="c", b="b") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + + def test_depr_kwd_optional_3(self): + fn = ac_tester.depr_kwd_optional_3 + fn() + fn("a") + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'a', 'b' and 'c'", fn) + check("a", "b", c="c") + check("a", b="b") + check(a="a") + + def test_depr_kwd_required_optional(self): + fn = ac_tester.depr_kwd_required_optional + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn) + self.assertRaises(TypeError, fn, "a") + self.assertRaises(TypeError, fn, "a", "b", "c", "d") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", b="b") + check("a", b="b", c="c") + check("a", c="c", b="b") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, "a", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + + def test_depr_kwd_noinline(self): + fn = ac_tester.depr_kwd_noinline + fn("a", "b") + fn("a", "b", "c") + self.assertRaises(TypeError, fn, "a") + check = partial(self.check_depr_kwd, "'b' and 'c'", fn) + check("a", b="b") + check("a", b="b", c="c") + check("a", c="c", b="b") + check("a", "b", c="c") + self.assertRaises(TypeError, fn, "a", c="c") + self.assertRaises(TypeError, fn, a="a", b="b", c="c") + class PermutationTests(unittest.TestCase): """Test permutation support functions.""" diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-08-15-19-50-49.gh-issue-107704.Uu84vd.rst b/Misc/NEWS.d/next/Tools-Demos/2023-08-15-19-50-49.gh-issue-107704.Uu84vd.rst new file mode 100644 index 00000000000..ffdcfa6a429 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2023-08-15-19-50-49.gh-issue-107704.Uu84vd.rst @@ -0,0 +1,4 @@ +It is now possible to deprecate passing keyword arguments for +keyword-or-positional parameters with Argument Clinic, using the new ``/ +[from X.Y]`` syntax. (To be read as *"positional-only from Python version +X.Y"*.) See :ref:`clinic-howto-deprecate-keyword` for more information. diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index af98d61ea7c..fe2196d0f7e 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -16,6 +16,17 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, int cache_size, int uri, enum autocommit_mode autocommit); +// Emit compiler warnings when we get to Python 3.15. +#if PY_VERSION_HEX >= 0x030f00C0 +# error "Update the clinic input of '_sqlite3.Connection.__init__'." +#elif PY_VERSION_HEX >= 0x030f00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_sqlite3.Connection.__init__'.") +# else +# warning "Update the clinic input of '_sqlite3.Connection.__init__'." +# endif +#endif + static int pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -59,28 +70,6 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) int uri = 0; enum autocommit_mode autocommit = LEGACY_TRANSACTION_CONTROL; - // Emit compiler warnings when we get to Python 3.15. - #if PY_VERSION_HEX >= 0x030f00C0 - # error \ - "In connection.c, update parameter(s) 'timeout', 'detect_types', " \ - "'isolation_level', 'check_same_thread', 'factory', " \ - "'cached_statements' and 'uri' in the clinic input of " \ - "'_sqlite3.Connection.__init__' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030f00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In connection.c, update parameter(s) 'timeout', 'detect_types', " \ - "'isolation_level', 'check_same_thread', 'factory', " \ - "'cached_statements' and 'uri' in the clinic input of " \ - "'_sqlite3.Connection.__init__' to be keyword-only.") - # else - # warning \ - "In connection.c, update parameter(s) 'timeout', 'detect_types', " \ - "'isolation_level', 'check_same_thread', 'factory', " \ - "'cached_statements' and 'uri' in the clinic input of " \ - "'_sqlite3.Connection.__init__' to be keyword-only." - # endif - #endif if (nargs > 1 && nargs <= 8) { if (PyErr_WarnEx(PyExc_DeprecationWarning, "Passing more than 1 positional argument to _sqlite3.Connection()" @@ -89,7 +78,7 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) "'cached_statements' and 'uri' will become keyword-only " "parameters in Python 3.15.", 1)) { - goto exit; + goto exit; } } fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 8, 0, argsbuf); @@ -1692,4 +1681,4 @@ exit: #ifndef DESERIALIZE_METHODDEF #define DESERIALIZE_METHODDEF #endif /* !defined(DESERIALIZE_METHODDEF) */ -/*[clinic end generated code: output=5a05e5294ad9d2ce input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0ad9d55977a51b8f input=a9049054013a1b77]*/ diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index c33536234af..efec04d9902 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -1195,14 +1195,14 @@ clone_with_conv_f2_impl(PyObject *module, custom_t path) /*[clinic input] output push -destination deprstar new file '{dirname}/clinic/_testclinic_depr_star.c.h' +destination deprstar new file '{dirname}/clinic/_testclinic_depr.c.h' output everything deprstar #output methoddef_ifndef buffer 1 output docstring_prototype suppress output parser_prototype suppress output impl_definition block [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f88f37038e00fb0a]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=32116eac48a42d34]*/ // Mock Python version 3.8 @@ -1211,7 +1211,7 @@ output impl_definition block #define PY_VERSION_HEX 0x03080000 -#include "clinic/_testclinic_depr_star.c.h" +#include "clinic/_testclinic_depr.c.h" /*[clinic input] @@ -1219,13 +1219,13 @@ class _testclinic.DeprStarNew "PyObject *" "PyObject" @classmethod _testclinic.DeprStarNew.__new__ as depr_star_new * [from 3.14] - a: object + a: object = None The deprecation message should use the class name instead of __new__. [clinic start generated code]*/ static PyObject * depr_star_new_impl(PyTypeObject *type, PyObject *a) -/*[clinic end generated code: output=bdbb36244f90cf46 input=f4ae7dafbc23c378]*/ +/*[clinic end generated code: output=bdbb36244f90cf46 input=fdd640db964b4dc1]*/ { return type->tp_alloc(type, 0); } @@ -1260,13 +1260,13 @@ static PyTypeObject DeprStarNew = { class _testclinic.DeprStarInit "PyObject *" "PyObject" _testclinic.DeprStarInit.__init__ as depr_star_init * [from 3.14] - a: object + a: object = None The deprecation message should use the class name instead of __init__. [clinic start generated code]*/ static int depr_star_init_impl(PyObject *self, PyObject *a) -/*[clinic end generated code: output=8d27b43c286d3ecc input=659ebc748d87fa86]*/ +/*[clinic end generated code: output=8d27b43c286d3ecc input=5575b77229d5e2be]*/ { return 0; } @@ -1298,6 +1298,116 @@ static PyTypeObject DeprStarInit = { }; +/*[clinic input] +class _testclinic.DeprStarInitNoInline "PyObject *" "PyObject" +_testclinic.DeprStarInitNoInline.__init__ as depr_star_init_noinline + a: object + * [from 3.14] + b: object + c: object = None + * + # Force to use _PyArg_ParseTupleAndKeywordsFast. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static int +depr_star_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=9b31fc167f1bf9f7 input=5a887543122bca48]*/ +{ + return 0; +} + +static PyTypeObject DeprStarInitNoInline = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprStarInitNoInline", + .tp_basicsize = sizeof(PyObject), + .tp_new = PyType_GenericNew, + .tp_init = depr_star_init_noinline, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/*[clinic input] +class _testclinic.DeprKwdNew "PyObject *" "PyObject" +@classmethod +_testclinic.DeprKwdNew.__new__ as depr_kwd_new + a: object = None + / [from 3.14] +The deprecation message should use the class name instead of __new__. +[clinic start generated code]*/ + +static PyObject * +depr_kwd_new_impl(PyTypeObject *type, PyObject *a) +/*[clinic end generated code: output=618d07afc5616149 input=6c7d13c471013c10]*/ +{ + return type->tp_alloc(type, 0); +} + +static PyTypeObject DeprKwdNew = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprKwdNew", + .tp_basicsize = sizeof(PyObject), + .tp_new = depr_kwd_new, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/*[clinic input] +class _testclinic.DeprKwdInit "PyObject *" "PyObject" +_testclinic.DeprKwdInit.__init__ as depr_kwd_init + a: object = None + / [from 3.14] +The deprecation message should use the class name instead of __init__. +[clinic start generated code]*/ + +static int +depr_kwd_init_impl(PyObject *self, PyObject *a) +/*[clinic end generated code: output=6e02eb724a85d840 input=b9bf3c20f012d539]*/ +{ + return 0; +} + +static PyTypeObject DeprKwdInit = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprKwdInit", + .tp_basicsize = sizeof(PyObject), + .tp_new = PyType_GenericNew, + .tp_init = depr_kwd_init, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/*[clinic input] +class _testclinic.DeprKwdInitNoInline "PyObject *" "PyObject" +_testclinic.DeprKwdInitNoInline.__init__ as depr_kwd_init_noinline + a: object + / + b: object + c: object = None + / [from 3.14] + # Force to use _PyArg_ParseTupleAndKeywordsFast. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static int +depr_kwd_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=27759d70ddd25873 input=c19d982c8c70a930]*/ +{ + return 0; +} + +static PyTypeObject DeprKwdInitNoInline = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_testclinic.DeprKwdInitNoInline", + .tp_basicsize = sizeof(PyObject), + .tp_new = PyType_GenericNew, + .tp_init = depr_kwd_init_noinline, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + /*[clinic input] depr_star_pos0_len1 * [from 3.14] @@ -1450,6 +1560,148 @@ depr_star_pos2_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, } +/*[clinic input] +depr_star_noinline + a: object + * [from 3.14] + b: object + c: object = None + * + # Force to use _PyArg_ParseStackAndKeywords. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static PyObject * +depr_star_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=cc27dacf5c2754af input=d36cc862a2daef98]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_required_1 + a: object + / + b: object + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_required_1_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=1d8ab19ea78418af input=53f2c398b828462d]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_required_2 + a: object + / + b: object + c: object + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_required_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=44a89cb82509ddde input=a2b0ef37de8a01a7]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_optional_1 + a: object + / + b: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_optional_1_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=a8a3d67efcc7b058 input=e416981eb78c3053]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_optional_2 + a: object + / + b: object = None + c: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_optional_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=aa2d967f26fdb9f6 input=cae3afb783bfc855]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_optional_3 + a: object = None + b: object = None + c: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_optional_3_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=a26025bf6118fd07 input=c9183b2f9ccaf992]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_required_optional + a: object + / + b: object + c: object = None + / [from 3.14] +[clinic start generated code]*/ + +static PyObject * +depr_kwd_required_optional_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=e53a8b7a250d8ffc input=23237a046f8388f5]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +depr_kwd_noinline + a: object + / + b: object + c: object = None + / [from 3.14] + # Force to use _PyArg_ParseStackAndKeywords. + d: str(accept={str, robuffer}, zeroes=True) = '' +[clinic start generated code]*/ + +static PyObject * +depr_kwd_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length) +/*[clinic end generated code: output=f59da8113f2bad7c input=1d6db65bebb069d7]*/ +{ + Py_RETURN_NONE; +} + // Reset PY_VERSION_HEX #undef PY_VERSION_HEX #define PY_VERSION_HEX _SAVED_PY_VERSION @@ -1526,6 +1778,14 @@ static PyMethodDef tester_methods[] = { DEPR_STAR_POS2_LEN1_METHODDEF DEPR_STAR_POS2_LEN2_METHODDEF DEPR_STAR_POS2_LEN2_WITH_KWD_METHODDEF + DEPR_STAR_NOINLINE_METHODDEF + DEPR_KWD_REQUIRED_1_METHODDEF + DEPR_KWD_REQUIRED_2_METHODDEF + DEPR_KWD_OPTIONAL_1_METHODDEF + DEPR_KWD_OPTIONAL_2_METHODDEF + DEPR_KWD_OPTIONAL_3_METHODDEF + DEPR_KWD_REQUIRED_OPTIONAL_METHODDEF + DEPR_KWD_NOINLINE_METHODDEF {NULL, NULL} }; @@ -1549,6 +1809,18 @@ PyInit__testclinic(void) if (PyModule_AddType(m, &DeprStarInit) < 0) { goto error; } + if (PyModule_AddType(m, &DeprStarInitNoInline) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprKwdNew) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprKwdInit) < 0) { + goto error; + } + if (PyModule_AddType(m, &DeprKwdInitNoInline) < 0) { + goto error; + } return m; error: diff --git a/Modules/clinic/_testclinic_depr.c.h b/Modules/clinic/_testclinic_depr.c.h new file mode 100644 index 00000000000..661fdaf2a07 --- /dev/null +++ b/Modules/clinic/_testclinic_depr.c.h @@ -0,0 +1,2095 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(depr_star_new__doc__, +"DeprStarNew(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __new__.\n" +"\n" +"Note: Passing positional arguments to _testclinic.DeprStarNew() is\n" +"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +static PyObject * +depr_star_new_impl(PyTypeObject *type, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarNew.__new__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarNew.__new__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarNew.__new__'." +# endif +#endif + +static PyObject * +depr_star_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + 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 = "DeprStarNew", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to _testclinic.DeprStarNew() is " + "deprecated. Parameter 'a' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_star_new_impl(type, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_new_clone__doc__, +"cloned($self, /, a=None)\n" +"--\n" +"\n" +"Note: Passing positional arguments to _testclinic.DeprStarNew.cloned()\n" +"is deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_NEW_CLONE_METHODDEF \ + {"cloned", _PyCFunction_CAST(depr_star_new_clone), METH_FASTCALL|METH_KEYWORDS, depr_star_new_clone__doc__}, + +static PyObject * +depr_star_new_clone_impl(PyObject *type, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarNew.cloned'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarNew.cloned'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarNew.cloned'." +# endif +#endif + +static PyObject * +depr_star_new_clone(PyObject *type, 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 = "cloned", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to _testclinic.DeprStarNew.cloned()" + " is deprecated. Parameter 'a' will become a keyword-only " + "parameter in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = args[0]; +skip_optional_pos: + return_value = depr_star_new_clone_impl(type, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_init__doc__, +"DeprStarInit(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __init__.\n" +"\n" +"Note: Passing positional arguments to _testclinic.DeprStarInit() is\n" +"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +static int +depr_star_init_impl(PyObject *self, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarInit.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarInit.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarInit.__init__'." +# endif +#endif + +static int +depr_star_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #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 = "DeprStarInit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to _testclinic.DeprStarInit() is " + "deprecated. Parameter 'a' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_star_init_impl(self, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_init_clone__doc__, +"cloned($self, /, a=None)\n" +"--\n" +"\n" +"Note: Passing positional arguments to\n" +"_testclinic.DeprStarInit.cloned() is deprecated. Parameter \'a\' will\n" +"become a keyword-only parameter in Python 3.14.\n" +""); + +#define DEPR_STAR_INIT_CLONE_METHODDEF \ + {"cloned", _PyCFunction_CAST(depr_star_init_clone), METH_FASTCALL|METH_KEYWORDS, depr_star_init_clone__doc__}, + +static PyObject * +depr_star_init_clone_impl(PyObject *self, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarInit.cloned'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarInit.cloned'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarInit.cloned'." +# endif +#endif + +static PyObject * +depr_star_init_clone(PyObject *self, 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 = "cloned", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *a = Py_None; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to " + "_testclinic.DeprStarInit.cloned() is deprecated. Parameter 'a' " + "will become a keyword-only parameter in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + a = args[0]; +skip_optional_pos: + return_value = depr_star_init_clone_impl(self, a); + +exit: + return return_value; +} + +static int +depr_star_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprStarInitNoInline.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprStarInitNoInline.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprStarInitNoInline.__init__'." +# endif +#endif + +static int +depr_star_init_noinline(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #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", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|O$s#:DeprStarInitNoInline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (nargs > 1 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to " + "_testclinic.DeprStarInitNoInline() is deprecated. Parameters 'b'" + " and 'c' will become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + return_value = depr_star_init_noinline_impl(self, a, b, c, d, d_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_new__doc__, +"DeprKwdNew(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __new__.\n" +"\n" +"Note: Passing keyword argument \'a\' to _testclinic.DeprKwdNew() is\n" +"deprecated. Corresponding parameter will become positional-only in\n" +"Python 3.14.\n" +""); + +static PyObject * +depr_kwd_new_impl(PyTypeObject *type, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprKwdNew.__new__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprKwdNew.__new__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprKwdNew.__new__'." +# endif +#endif + +static PyObject * +depr_kwd_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + 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 = "DeprKwdNew", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (kwargs && PyDict_GET_SIZE(kwargs) && nargs < 1 && fastargs[0]) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'a' to _testclinic.DeprKwdNew() is " + "deprecated. Corresponding parameter will become positional-only " + "in Python 3.14.", 1)) + { + goto exit; + } + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_kwd_new_impl(type, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_init__doc__, +"DeprKwdInit(a=None)\n" +"--\n" +"\n" +"The deprecation message should use the class name instead of __init__.\n" +"\n" +"Note: Passing keyword argument \'a\' to _testclinic.DeprKwdInit() is\n" +"deprecated. Corresponding parameter will become positional-only in\n" +"Python 3.14.\n" +""); + +static int +depr_kwd_init_impl(PyObject *self, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprKwdInit.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprKwdInit.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprKwdInit.__init__'." +# endif +#endif + +static int +depr_kwd_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #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 = "DeprKwdInit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *a = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (kwargs && PyDict_GET_SIZE(kwargs) && nargs < 1 && fastargs[0]) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'a' to _testclinic.DeprKwdInit() is " + "deprecated. Corresponding parameter will become positional-only " + "in Python 3.14.", 1)) + { + goto exit; + } + } + if (!noptargs) { + goto skip_optional_pos; + } + a = fastargs[0]; +skip_optional_pos: + return_value = depr_kwd_init_impl(self, a); + +exit: + return return_value; +} + +static int +depr_kwd_init_noinline_impl(PyObject *self, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of '_testclinic.DeprKwdInitNoInline.__init__'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of '_testclinic.DeprKwdInitNoInline.__init__'.") +# else +# warning "Update the clinic input of '_testclinic.DeprKwdInitNoInline.__init__'." +# endif +#endif + +static int +depr_kwd_init_noinline(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + 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), &_Py_ID(c), &_Py_ID(d), }, + }; + #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", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|Os#:DeprKwdInitNoInline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + if (kwargs && PyDict_GET_SIZE(kwargs) && ((nargs < 2) || (nargs < 3 && PyDict_Contains(kwargs, &_Py_ID(c))))) { + if (PyErr_Occurred()) { // PyDict_Contains() above can fail + goto exit; + } + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to " + "_testclinic.DeprKwdInitNoInline() is deprecated. Corresponding " + "parameters will become positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + return_value = depr_kwd_init_noinline_impl(self, a, b, c, d, d_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos0_len1__doc__, +"depr_star_pos0_len1($module, /, a)\n" +"--\n" +"\n" +"Note: Passing positional arguments to depr_star_pos0_len1() is\n" +"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS0_LEN1_METHODDEF \ + {"depr_star_pos0_len1", _PyCFunction_CAST(depr_star_pos0_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len1__doc__}, + +static PyObject * +depr_star_pos0_len1_impl(PyObject *module, PyObject *a); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos0_len1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos0_len1'.") +# else +# warning "Update the clinic input of 'depr_star_pos0_len1'." +# endif +#endif + +static PyObject * +depr_star_pos0_len1(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 = "depr_star_pos0_len1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *a; + + if (nargs == 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to depr_star_pos0_len1() is " + "deprecated. Parameter 'a' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + return_value = depr_star_pos0_len1_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos0_len2__doc__, +"depr_star_pos0_len2($module, /, a, b)\n" +"--\n" +"\n" +"Note: Passing positional arguments to depr_star_pos0_len2() is\n" +"deprecated. Parameters \'a\' and \'b\' will become keyword-only parameters\n" +"in Python 3.14.\n" +""); + +#define DEPR_STAR_POS0_LEN2_METHODDEF \ + {"depr_star_pos0_len2", _PyCFunction_CAST(depr_star_pos0_len2), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len2__doc__}, + +static PyObject * +depr_star_pos0_len2_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos0_len2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos0_len2'.") +# else +# warning "Update the clinic input of 'depr_star_pos0_len2'." +# endif +#endif + +static PyObject * +depr_star_pos0_len2(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 = "depr_star_pos0_len2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + if (nargs > 0 && nargs <= 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to depr_star_pos0_len2() is " + "deprecated. Parameters 'a' and 'b' will become keyword-only " + "parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = depr_star_pos0_len2_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos0_len3_with_kwd__doc__, +"depr_star_pos0_len3_with_kwd($module, /, a, b, c, *, d)\n" +"--\n" +"\n" +"Note: Passing positional arguments to depr_star_pos0_len3_with_kwd()\n" +"is deprecated. Parameters \'a\', \'b\' and \'c\' will become keyword-only\n" +"parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS0_LEN3_WITH_KWD_METHODDEF \ + {"depr_star_pos0_len3_with_kwd", _PyCFunction_CAST(depr_star_pos0_len3_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len3_with_kwd__doc__}, + +static PyObject * +depr_star_pos0_len3_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos0_len3_with_kwd'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos0_len3_with_kwd'.") +# else +# warning "Update the clinic input of 'depr_star_pos0_len3_with_kwd'." +# endif +#endif + +static PyObject * +depr_star_pos0_len3_with_kwd(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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #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", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos0_len3_with_kwd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + + if (nargs > 0 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing positional arguments to depr_star_pos0_len3_with_kwd() " + "is deprecated. Parameters 'a', 'b' and 'c' will become " + "keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + return_value = depr_star_pos0_len3_with_kwd_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos1_len1_opt__doc__, +"depr_star_pos1_len1_opt($module, /, a, b=None)\n" +"--\n" +"\n" +"Note: Passing 2 positional arguments to depr_star_pos1_len1_opt() is\n" +"deprecated. Parameter \'b\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS1_LEN1_OPT_METHODDEF \ + {"depr_star_pos1_len1_opt", _PyCFunction_CAST(depr_star_pos1_len1_opt), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len1_opt__doc__}, + +static PyObject * +depr_star_pos1_len1_opt_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos1_len1_opt'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos1_len1_opt'.") +# else +# warning "Update the clinic input of 'depr_star_pos1_len1_opt'." +# endif +#endif + +static PyObject * +depr_star_pos1_len1_opt(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 = "depr_star_pos1_len1_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + + if (nargs == 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 2 positional arguments to depr_star_pos1_len1_opt() is " + "deprecated. Parameter 'b' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + b = args[1]; +skip_optional_pos: + return_value = depr_star_pos1_len1_opt_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos1_len1__doc__, +"depr_star_pos1_len1($module, /, a, b)\n" +"--\n" +"\n" +"Note: Passing 2 positional arguments to depr_star_pos1_len1() is\n" +"deprecated. Parameter \'b\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS1_LEN1_METHODDEF \ + {"depr_star_pos1_len1", _PyCFunction_CAST(depr_star_pos1_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len1__doc__}, + +static PyObject * +depr_star_pos1_len1_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos1_len1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos1_len1'.") +# else +# warning "Update the clinic input of 'depr_star_pos1_len1'." +# endif +#endif + +static PyObject * +depr_star_pos1_len1(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 = "depr_star_pos1_len1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + if (nargs == 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 2 positional arguments to depr_star_pos1_len1() is " + "deprecated. Parameter 'b' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = depr_star_pos1_len1_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos1_len2_with_kwd__doc__, +"depr_star_pos1_len2_with_kwd($module, /, a, b, c, *, d)\n" +"--\n" +"\n" +"Note: Passing more than 1 positional argument to\n" +"depr_star_pos1_len2_with_kwd() is deprecated. Parameters \'b\' and \'c\'\n" +"will become keyword-only parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS1_LEN2_WITH_KWD_METHODDEF \ + {"depr_star_pos1_len2_with_kwd", _PyCFunction_CAST(depr_star_pos1_len2_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len2_with_kwd__doc__}, + +static PyObject * +depr_star_pos1_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos1_len2_with_kwd'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos1_len2_with_kwd'.") +# else +# warning "Update the clinic input of 'depr_star_pos1_len2_with_kwd'." +# endif +#endif + +static PyObject * +depr_star_pos1_len2_with_kwd(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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #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", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos1_len2_with_kwd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + + if (nargs > 1 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to " + "depr_star_pos1_len2_with_kwd() is deprecated. Parameters 'b' and" + " 'c' will become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + return_value = depr_star_pos1_len2_with_kwd_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos2_len1__doc__, +"depr_star_pos2_len1($module, /, a, b, c)\n" +"--\n" +"\n" +"Note: Passing 3 positional arguments to depr_star_pos2_len1() is\n" +"deprecated. Parameter \'c\' will become a keyword-only parameter in\n" +"Python 3.14.\n" +""); + +#define DEPR_STAR_POS2_LEN1_METHODDEF \ + {"depr_star_pos2_len1", _PyCFunction_CAST(depr_star_pos2_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len1__doc__}, + +static PyObject * +depr_star_pos2_len1_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos2_len1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos2_len1'.") +# else +# warning "Update the clinic input of 'depr_star_pos2_len1'." +# endif +#endif + +static PyObject * +depr_star_pos2_len1(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 3 + 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), &_Py_ID(c), }, + }; + #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", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos2_len1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *a; + PyObject *b; + PyObject *c; + + if (nargs == 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 3 positional arguments to depr_star_pos2_len1() is " + "deprecated. Parameter 'c' will become a keyword-only parameter " + "in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + return_value = depr_star_pos2_len1_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos2_len2__doc__, +"depr_star_pos2_len2($module, /, a, b, c, d)\n" +"--\n" +"\n" +"Note: Passing more than 2 positional arguments to\n" +"depr_star_pos2_len2() is deprecated. Parameters \'c\' and \'d\' will\n" +"become keyword-only parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS2_LEN2_METHODDEF \ + {"depr_star_pos2_len2", _PyCFunction_CAST(depr_star_pos2_len2), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len2__doc__}, + +static PyObject * +depr_star_pos2_len2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos2_len2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos2_len2'.") +# else +# warning "Update the clinic input of 'depr_star_pos2_len2'." +# endif +#endif + +static PyObject * +depr_star_pos2_len2(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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #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", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos2_len2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + + if (nargs > 2 && nargs <= 4) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 2 positional arguments to " + "depr_star_pos2_len2() is deprecated. Parameters 'c' and 'd' will" + " become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + return_value = depr_star_pos2_len2_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_pos2_len2_with_kwd__doc__, +"depr_star_pos2_len2_with_kwd($module, /, a, b, c, d, *, e)\n" +"--\n" +"\n" +"Note: Passing more than 2 positional arguments to\n" +"depr_star_pos2_len2_with_kwd() is deprecated. Parameters \'c\' and \'d\'\n" +"will become keyword-only parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_POS2_LEN2_WITH_KWD_METHODDEF \ + {"depr_star_pos2_len2_with_kwd", _PyCFunction_CAST(depr_star_pos2_len2_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len2_with_kwd__doc__}, + +static PyObject * +depr_star_pos2_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d, PyObject *e); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_pos2_len2_with_kwd'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_pos2_len2_with_kwd'.") +# else +# warning "Update the clinic input of 'depr_star_pos2_len2_with_kwd'." +# endif +#endif + +static PyObject * +depr_star_pos2_len2_with_kwd(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 5 + 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), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #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", "c", "d", "e", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_star_pos2_len2_with_kwd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d; + PyObject *e; + + if (nargs > 2 && nargs <= 4) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 2 positional arguments to " + "depr_star_pos2_len2_with_kwd() is deprecated. Parameters 'c' and" + " 'd' will become keyword-only parameters in Python 3.14.", 1)) + { + goto exit; + } + } + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + d = args[3]; + e = args[4]; + return_value = depr_star_pos2_len2_with_kwd_impl(module, a, b, c, d, e); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_star_noinline__doc__, +"depr_star_noinline($module, /, a, b, c=None, *, d=\'\')\n" +"--\n" +"\n" +"Note: Passing more than 1 positional argument to depr_star_noinline()\n" +"is deprecated. Parameters \'b\' and \'c\' will become keyword-only\n" +"parameters in Python 3.14.\n" +""); + +#define DEPR_STAR_NOINLINE_METHODDEF \ + {"depr_star_noinline", _PyCFunction_CAST(depr_star_noinline), METH_FASTCALL|METH_KEYWORDS, depr_star_noinline__doc__}, + +static PyObject * +depr_star_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_star_noinline'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_star_noinline'.") +# else +# warning "Update the clinic input of 'depr_star_noinline'." +# endif +#endif + +static PyObject * +depr_star_noinline(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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #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", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|O$s#:depr_star_noinline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (nargs > 1 && nargs <= 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing more than 1 positional argument to depr_star_noinline() " + "is deprecated. Parameters 'b' and 'c' will become keyword-only " + "parameters in Python 3.14.", 1)) + { + goto exit; + } + } + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + return_value = depr_star_noinline_impl(module, a, b, c, d, d_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_required_1__doc__, +"depr_kwd_required_1($module, a, /, b)\n" +"--\n" +"\n" +"Note: Passing keyword argument \'b\' to depr_kwd_required_1() is\n" +"deprecated. Corresponding parameter will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_REQUIRED_1_METHODDEF \ + {"depr_kwd_required_1", _PyCFunction_CAST(depr_kwd_required_1), METH_FASTCALL|METH_KEYWORDS, depr_kwd_required_1__doc__}, + +static PyObject * +depr_kwd_required_1_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_required_1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_required_1'.") +# else +# warning "Update the clinic input of 'depr_kwd_required_1'." +# endif +#endif + +static PyObject * +depr_kwd_required_1(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 = "depr_kwd_required_1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 2) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'b' to depr_kwd_required_1() is " + "deprecated. Corresponding parameter will become positional-only " + "in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + return_value = depr_kwd_required_1_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_required_2__doc__, +"depr_kwd_required_2($module, a, /, b, c)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to depr_kwd_required_2()\n" +"is deprecated. Corresponding parameters will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_REQUIRED_2_METHODDEF \ + {"depr_kwd_required_2", _PyCFunction_CAST(depr_kwd_required_2), METH_FASTCALL|METH_KEYWORDS, depr_kwd_required_2__doc__}, + +static PyObject * +depr_kwd_required_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_required_2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_required_2'.") +# else +# warning "Update the clinic input of 'depr_kwd_required_2'." +# endif +#endif + +static PyObject * +depr_kwd_required_2(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(b), &_Py_ID(c), }, + }; + #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", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_required_2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *a; + PyObject *b; + PyObject *c; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 3) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to depr_kwd_required_2() " + "is deprecated. Corresponding parameters will become " + "positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + c = args[2]; + return_value = depr_kwd_required_2_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_optional_1__doc__, +"depr_kwd_optional_1($module, a, /, b=None)\n" +"--\n" +"\n" +"Note: Passing keyword argument \'b\' to depr_kwd_optional_1() is\n" +"deprecated. Corresponding parameter will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_OPTIONAL_1_METHODDEF \ + {"depr_kwd_optional_1", _PyCFunction_CAST(depr_kwd_optional_1), METH_FASTCALL|METH_KEYWORDS, depr_kwd_optional_1__doc__}, + +static PyObject * +depr_kwd_optional_1_impl(PyObject *module, PyObject *a, PyObject *b); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_optional_1'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_optional_1'.") +# else +# warning "Update the clinic input of 'depr_kwd_optional_1'." +# endif +#endif + +static PyObject * +depr_kwd_optional_1(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 = "depr_kwd_optional_1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && nargs < 2 && args[1]) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword argument 'b' to depr_kwd_optional_1() is " + "deprecated. Corresponding parameter will become positional-only " + "in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + b = args[1]; +skip_optional_pos: + return_value = depr_kwd_optional_1_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_optional_2__doc__, +"depr_kwd_optional_2($module, a, /, b=None, c=None)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to depr_kwd_optional_2()\n" +"is deprecated. Corresponding parameters will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_OPTIONAL_2_METHODDEF \ + {"depr_kwd_optional_2", _PyCFunction_CAST(depr_kwd_optional_2), METH_FASTCALL|METH_KEYWORDS, depr_kwd_optional_2__doc__}, + +static PyObject * +depr_kwd_optional_2_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_optional_2'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_optional_2'.") +# else +# warning "Update the clinic input of 'depr_kwd_optional_2'." +# endif +#endif + +static PyObject * +depr_kwd_optional_2(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(b), &_Py_ID(c), }, + }; + #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", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_optional_2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 2 && args[1]) || (nargs < 3 && args[2]))) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to depr_kwd_optional_2() " + "is deprecated. Corresponding parameters will become " + "positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + b = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + c = args[2]; +skip_optional_pos: + return_value = depr_kwd_optional_2_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_optional_3__doc__, +"depr_kwd_optional_3($module, /, a=None, b=None, c=None)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'a\', \'b\' and \'c\' to\n" +"depr_kwd_optional_3() is deprecated. Corresponding parameters will\n" +"become positional-only in Python 3.14.\n" +""); + +#define DEPR_KWD_OPTIONAL_3_METHODDEF \ + {"depr_kwd_optional_3", _PyCFunction_CAST(depr_kwd_optional_3), METH_FASTCALL|METH_KEYWORDS, depr_kwd_optional_3__doc__}, + +static PyObject * +depr_kwd_optional_3_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_optional_3'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_optional_3'.") +# else +# warning "Update the clinic input of 'depr_kwd_optional_3'." +# endif +#endif + +static PyObject * +depr_kwd_optional_3(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 3 + 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), &_Py_ID(c), }, + }; + #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", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_optional_3", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *a = Py_None; + PyObject *b = Py_None; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 1 && args[0]) || (nargs < 2 && args[1]) || (nargs < 3 && args[2]))) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'a', 'b' and 'c' to " + "depr_kwd_optional_3() is deprecated. Corresponding parameters " + "will become positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + a = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[1]) { + b = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + c = args[2]; +skip_optional_pos: + return_value = depr_kwd_optional_3_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_required_optional__doc__, +"depr_kwd_required_optional($module, a, /, b, c=None)\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to\n" +"depr_kwd_required_optional() is deprecated. Corresponding parameters\n" +"will become positional-only in Python 3.14.\n" +""); + +#define DEPR_KWD_REQUIRED_OPTIONAL_METHODDEF \ + {"depr_kwd_required_optional", _PyCFunction_CAST(depr_kwd_required_optional), METH_FASTCALL|METH_KEYWORDS, depr_kwd_required_optional__doc__}, + +static PyObject * +depr_kwd_required_optional_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_required_optional'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_required_optional'.") +# else +# warning "Update the clinic input of 'depr_kwd_required_optional'." +# endif +#endif + +static PyObject * +depr_kwd_required_optional(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(b), &_Py_ID(c), }, + }; + #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", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "depr_kwd_required_optional", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 2) || (nargs < 3 && args[2]))) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to " + "depr_kwd_required_optional() is deprecated. Corresponding " + "parameters will become positional-only in Python 3.14.", 1)) + { + goto exit; + } + } + a = args[0]; + b = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + c = args[2]; +skip_optional_pos: + return_value = depr_kwd_required_optional_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(depr_kwd_noinline__doc__, +"depr_kwd_noinline($module, a, /, b, c=None, d=\'\')\n" +"--\n" +"\n" +"Note: Passing keyword arguments \'b\' and \'c\' to depr_kwd_noinline() is\n" +"deprecated. Corresponding parameters will become positional-only in\n" +"Python 3.14.\n" +""); + +#define DEPR_KWD_NOINLINE_METHODDEF \ + {"depr_kwd_noinline", _PyCFunction_CAST(depr_kwd_noinline), METH_FASTCALL|METH_KEYWORDS, depr_kwd_noinline__doc__}, + +static PyObject * +depr_kwd_noinline_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, const char *d, Py_ssize_t d_length); + +// Emit compiler warnings when we get to Python 3.14. +#if PY_VERSION_HEX >= 0x030e00C0 +# error "Update the clinic input of 'depr_kwd_noinline'." +#elif PY_VERSION_HEX >= 0x030e00A0 +# ifdef _MSC_VER +# pragma message ("Update the clinic input of 'depr_kwd_noinline'.") +# else +# warning "Update the clinic input of 'depr_kwd_noinline'." +# endif +#endif + +static PyObject * +depr_kwd_noinline(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 3 + 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), &_Py_ID(c), &_Py_ID(d), }, + }; + #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", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "OO|Os#:depr_kwd_noinline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + const char *d = ""; + Py_ssize_t d_length; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &a, &b, &c, &d, &d_length)) { + goto exit; + } + if (kwnames && PyTuple_GET_SIZE(kwnames) && ((nargs < 2) || (nargs < 3 && PySequence_Contains(kwnames, &_Py_ID(c))))) { + if (PyErr_Occurred()) { // PySequence_Contains() above can fail + goto exit; + } + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing keyword arguments 'b' and 'c' to depr_kwd_noinline() is " + "deprecated. Corresponding parameters will become positional-only" + " in Python 3.14.", 1)) + { + goto exit; + } + } + return_value = depr_kwd_noinline_impl(module, a, b, c, d, d_length); + +exit: + return return_value; +} +/*[clinic end generated code: output=fc558c1efdcab076 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic_depr_star.c.h b/Modules/clinic/_testclinic_depr_star.c.h deleted file mode 100644 index 1aa42dd4059..00000000000 --- a/Modules/clinic/_testclinic_depr_star.c.h +++ /dev/null @@ -1,1140 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - - -PyDoc_STRVAR(depr_star_new__doc__, -"DeprStarNew(a)\n" -"--\n" -"\n" -"The deprecation message should use the class name instead of __new__.\n" -"\n" -"Note: Passing positional arguments to _testclinic.DeprStarNew() is\n" -"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" -"Python 3.14.\n" -""); - -static PyObject * -depr_star_new_impl(PyTypeObject *type, PyObject *a); - -static PyObject * -depr_star_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - 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 = "DeprStarNew", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject * const *fastargs; - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - PyObject *a; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarNew.__new__' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarNew.__new__' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarNew.__new__' to be keyword-only." - # endif - #endif - if (nargs == 1) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing positional arguments to _testclinic.DeprStarNew() is " - "deprecated. Parameter 'a' will become a keyword-only parameter " - "in Python 3.14.", 1)) - { - goto exit; - } - } - fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); - if (!fastargs) { - goto exit; - } - a = fastargs[0]; - return_value = depr_star_new_impl(type, a); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_new_clone__doc__, -"cloned($self, /, a)\n" -"--\n" -"\n" -"Note: Passing positional arguments to _testclinic.DeprStarNew.cloned()\n" -"is deprecated. Parameter \'a\' will become a keyword-only parameter in\n" -"Python 3.14.\n" -""); - -#define DEPR_STAR_NEW_CLONE_METHODDEF \ - {"cloned", _PyCFunction_CAST(depr_star_new_clone), METH_FASTCALL|METH_KEYWORDS, depr_star_new_clone__doc__}, - -static PyObject * -depr_star_new_clone_impl(PyObject *type, PyObject *a); - -static PyObject * -depr_star_new_clone(PyObject *type, 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 = "cloned", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *a; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarNew.cloned' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarNew.cloned' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarNew.cloned' to be keyword-only." - # endif - #endif - if (nargs == 1) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing positional arguments to _testclinic.DeprStarNew.cloned()" - " is deprecated. Parameter 'a' will become a keyword-only " - "parameter in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - return_value = depr_star_new_clone_impl(type, a); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_init__doc__, -"DeprStarInit(a)\n" -"--\n" -"\n" -"The deprecation message should use the class name instead of __init__.\n" -"\n" -"Note: Passing positional arguments to _testclinic.DeprStarInit() is\n" -"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" -"Python 3.14.\n" -""); - -static int -depr_star_init_impl(PyObject *self, PyObject *a); - -static int -depr_star_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - #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 = "DeprStarInit", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject * const *fastargs; - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - PyObject *a; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarInit.__init__' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarInit.__init__' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarInit.__init__' to be keyword-only." - # endif - #endif - if (nargs == 1) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing positional arguments to _testclinic.DeprStarInit() is " - "deprecated. Parameter 'a' will become a keyword-only parameter " - "in Python 3.14.", 1)) - { - goto exit; - } - } - fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); - if (!fastargs) { - goto exit; - } - a = fastargs[0]; - return_value = depr_star_init_impl(self, a); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_init_clone__doc__, -"cloned($self, /, a)\n" -"--\n" -"\n" -"Note: Passing positional arguments to\n" -"_testclinic.DeprStarInit.cloned() is deprecated. Parameter \'a\' will\n" -"become a keyword-only parameter in Python 3.14.\n" -""); - -#define DEPR_STAR_INIT_CLONE_METHODDEF \ - {"cloned", _PyCFunction_CAST(depr_star_init_clone), METH_FASTCALL|METH_KEYWORDS, depr_star_init_clone__doc__}, - -static PyObject * -depr_star_init_clone_impl(PyObject *self, PyObject *a); - -static PyObject * -depr_star_init_clone(PyObject *self, 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 = "cloned", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *a; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarInit.cloned' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarInit.cloned' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " '_testclinic.DeprStarInit.cloned' to be keyword-only." - # endif - #endif - if (nargs == 1) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing positional arguments to " - "_testclinic.DeprStarInit.cloned() is deprecated. Parameter 'a' " - "will become a keyword-only parameter in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - return_value = depr_star_init_clone_impl(self, a); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos0_len1__doc__, -"depr_star_pos0_len1($module, /, a)\n" -"--\n" -"\n" -"Note: Passing positional arguments to depr_star_pos0_len1() is\n" -"deprecated. Parameter \'a\' will become a keyword-only parameter in\n" -"Python 3.14.\n" -""); - -#define DEPR_STAR_POS0_LEN1_METHODDEF \ - {"depr_star_pos0_len1", _PyCFunction_CAST(depr_star_pos0_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len1__doc__}, - -static PyObject * -depr_star_pos0_len1_impl(PyObject *module, PyObject *a); - -static PyObject * -depr_star_pos0_len1(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 = "depr_star_pos0_len1", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *a; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " 'depr_star_pos0_len1' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " 'depr_star_pos0_len1' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'a' in the clinic input of" \ - " 'depr_star_pos0_len1' to be keyword-only." - # endif - #endif - if (nargs == 1) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing positional arguments to depr_star_pos0_len1() is " - "deprecated. Parameter 'a' will become a keyword-only parameter " - "in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - return_value = depr_star_pos0_len1_impl(module, a); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos0_len2__doc__, -"depr_star_pos0_len2($module, /, a, b)\n" -"--\n" -"\n" -"Note: Passing positional arguments to depr_star_pos0_len2() is\n" -"deprecated. Parameters \'a\' and \'b\' will become keyword-only parameters\n" -"in Python 3.14.\n" -""); - -#define DEPR_STAR_POS0_LEN2_METHODDEF \ - {"depr_star_pos0_len2", _PyCFunction_CAST(depr_star_pos0_len2), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len2__doc__}, - -static PyObject * -depr_star_pos0_len2_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -depr_star_pos0_len2(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 = "depr_star_pos0_len2", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; - PyObject *a; - PyObject *b; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'a' and 'b' in the clinic " \ - "input of 'depr_star_pos0_len2' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'a' and 'b' in the clinic " \ - "input of 'depr_star_pos0_len2' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'a' and 'b' in the clinic " \ - "input of 'depr_star_pos0_len2' to be keyword-only." - # endif - #endif - if (nargs > 0 && nargs <= 2) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing positional arguments to depr_star_pos0_len2() is " - "deprecated. Parameters 'a' and 'b' will become keyword-only " - "parameters in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - b = args[1]; - return_value = depr_star_pos0_len2_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos0_len3_with_kwd__doc__, -"depr_star_pos0_len3_with_kwd($module, /, a, b, c, *, d)\n" -"--\n" -"\n" -"Note: Passing positional arguments to depr_star_pos0_len3_with_kwd()\n" -"is deprecated. Parameters \'a\', \'b\' and \'c\' will become keyword-only\n" -"parameters in Python 3.14.\n" -""); - -#define DEPR_STAR_POS0_LEN3_WITH_KWD_METHODDEF \ - {"depr_star_pos0_len3_with_kwd", _PyCFunction_CAST(depr_star_pos0_len3_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos0_len3_with_kwd__doc__}, - -static PyObject * -depr_star_pos0_len3_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *c, PyObject *d); - -static PyObject * -depr_star_pos0_len3_with_kwd(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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, - }; - #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", "c", "d", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "depr_star_pos0_len3_with_kwd", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[4]; - PyObject *a; - PyObject *b; - PyObject *c; - PyObject *d; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'a', 'b' and 'c' in the " \ - "clinic input of 'depr_star_pos0_len3_with_kwd' to be " \ - "keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'a', 'b' and 'c' in the " \ - "clinic input of 'depr_star_pos0_len3_with_kwd' to be " \ - "keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'a', 'b' and 'c' in the " \ - "clinic input of 'depr_star_pos0_len3_with_kwd' to be " \ - "keyword-only." - # endif - #endif - if (nargs > 0 && nargs <= 3) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing positional arguments to depr_star_pos0_len3_with_kwd() " - "is deprecated. Parameters 'a', 'b' and 'c' will become " - "keyword-only parameters in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 1, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - b = args[1]; - c = args[2]; - d = args[3]; - return_value = depr_star_pos0_len3_with_kwd_impl(module, a, b, c, d); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos1_len1_opt__doc__, -"depr_star_pos1_len1_opt($module, /, a, b=None)\n" -"--\n" -"\n" -"Note: Passing 2 positional arguments to depr_star_pos1_len1_opt() is\n" -"deprecated. Parameter \'b\' will become a keyword-only parameter in\n" -"Python 3.14.\n" -""); - -#define DEPR_STAR_POS1_LEN1_OPT_METHODDEF \ - {"depr_star_pos1_len1_opt", _PyCFunction_CAST(depr_star_pos1_len1_opt), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len1_opt__doc__}, - -static PyObject * -depr_star_pos1_len1_opt_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -depr_star_pos1_len1_opt(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 = "depr_star_pos1_len1_opt", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *a; - PyObject *b = Py_None; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'b' in the clinic input of" \ - " 'depr_star_pos1_len1_opt' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'b' in the clinic input of" \ - " 'depr_star_pos1_len1_opt' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'b' in the clinic input of" \ - " 'depr_star_pos1_len1_opt' to be keyword-only." - # endif - #endif - if (nargs == 2) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing 2 positional arguments to depr_star_pos1_len1_opt() is " - "deprecated. Parameter 'b' will become a keyword-only parameter " - "in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - b = args[1]; -skip_optional_pos: - return_value = depr_star_pos1_len1_opt_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos1_len1__doc__, -"depr_star_pos1_len1($module, /, a, b)\n" -"--\n" -"\n" -"Note: Passing 2 positional arguments to depr_star_pos1_len1() is\n" -"deprecated. Parameter \'b\' will become a keyword-only parameter in\n" -"Python 3.14.\n" -""); - -#define DEPR_STAR_POS1_LEN1_METHODDEF \ - {"depr_star_pos1_len1", _PyCFunction_CAST(depr_star_pos1_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len1__doc__}, - -static PyObject * -depr_star_pos1_len1_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -depr_star_pos1_len1(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 = "depr_star_pos1_len1", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; - PyObject *a; - PyObject *b; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'b' in the clinic input of" \ - " 'depr_star_pos1_len1' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'b' in the clinic input of" \ - " 'depr_star_pos1_len1' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'b' in the clinic input of" \ - " 'depr_star_pos1_len1' to be keyword-only." - # endif - #endif - if (nargs == 2) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing 2 positional arguments to depr_star_pos1_len1() is " - "deprecated. Parameter 'b' will become a keyword-only parameter " - "in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - b = args[1]; - return_value = depr_star_pos1_len1_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos1_len2_with_kwd__doc__, -"depr_star_pos1_len2_with_kwd($module, /, a, b, c, *, d)\n" -"--\n" -"\n" -"Note: Passing more than 1 positional argument to\n" -"depr_star_pos1_len2_with_kwd() is deprecated. Parameters \'b\' and \'c\'\n" -"will become keyword-only parameters in Python 3.14.\n" -""); - -#define DEPR_STAR_POS1_LEN2_WITH_KWD_METHODDEF \ - {"depr_star_pos1_len2_with_kwd", _PyCFunction_CAST(depr_star_pos1_len2_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos1_len2_with_kwd__doc__}, - -static PyObject * -depr_star_pos1_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *c, PyObject *d); - -static PyObject * -depr_star_pos1_len2_with_kwd(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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, - }; - #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", "c", "d", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "depr_star_pos1_len2_with_kwd", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[4]; - PyObject *a; - PyObject *b; - PyObject *c; - PyObject *d; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'b' and 'c' in the clinic " \ - "input of 'depr_star_pos1_len2_with_kwd' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'b' and 'c' in the clinic " \ - "input of 'depr_star_pos1_len2_with_kwd' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'b' and 'c' in the clinic " \ - "input of 'depr_star_pos1_len2_with_kwd' to be keyword-only." - # endif - #endif - if (nargs > 1 && nargs <= 3) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing more than 1 positional argument to " - "depr_star_pos1_len2_with_kwd() is deprecated. Parameters 'b' and" - " 'c' will become keyword-only parameters in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 1, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - b = args[1]; - c = args[2]; - d = args[3]; - return_value = depr_star_pos1_len2_with_kwd_impl(module, a, b, c, d); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos2_len1__doc__, -"depr_star_pos2_len1($module, /, a, b, c)\n" -"--\n" -"\n" -"Note: Passing 3 positional arguments to depr_star_pos2_len1() is\n" -"deprecated. Parameter \'c\' will become a keyword-only parameter in\n" -"Python 3.14.\n" -""); - -#define DEPR_STAR_POS2_LEN1_METHODDEF \ - {"depr_star_pos2_len1", _PyCFunction_CAST(depr_star_pos2_len1), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len1__doc__}, - -static PyObject * -depr_star_pos2_len1_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *c); - -static PyObject * -depr_star_pos2_len1(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 3 - 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), &_Py_ID(c), }, - }; - #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", "c", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "depr_star_pos2_len1", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[3]; - PyObject *a; - PyObject *b; - PyObject *c; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'c' in the clinic input of" \ - " 'depr_star_pos2_len1' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'c' in the clinic input of" \ - " 'depr_star_pos2_len1' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'c' in the clinic input of" \ - " 'depr_star_pos2_len1' to be keyword-only." - # endif - #endif - if (nargs == 3) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing 3 positional arguments to depr_star_pos2_len1() is " - "deprecated. Parameter 'c' will become a keyword-only parameter " - "in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - b = args[1]; - c = args[2]; - return_value = depr_star_pos2_len1_impl(module, a, b, c); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos2_len2__doc__, -"depr_star_pos2_len2($module, /, a, b, c, d)\n" -"--\n" -"\n" -"Note: Passing more than 2 positional arguments to\n" -"depr_star_pos2_len2() is deprecated. Parameters \'c\' and \'d\' will\n" -"become keyword-only parameters in Python 3.14.\n" -""); - -#define DEPR_STAR_POS2_LEN2_METHODDEF \ - {"depr_star_pos2_len2", _PyCFunction_CAST(depr_star_pos2_len2), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len2__doc__}, - -static PyObject * -depr_star_pos2_len2_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *c, PyObject *d); - -static PyObject * -depr_star_pos2_len2(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(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, - }; - #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", "c", "d", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "depr_star_pos2_len2", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[4]; - PyObject *a; - PyObject *b; - PyObject *c; - PyObject *d; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'c' and 'd' in the clinic " \ - "input of 'depr_star_pos2_len2' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'c' and 'd' in the clinic " \ - "input of 'depr_star_pos2_len2' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'c' and 'd' in the clinic " \ - "input of 'depr_star_pos2_len2' to be keyword-only." - # endif - #endif - if (nargs > 2 && nargs <= 4) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing more than 2 positional arguments to " - "depr_star_pos2_len2() is deprecated. Parameters 'c' and 'd' will" - " become keyword-only parameters in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 0, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - b = args[1]; - c = args[2]; - d = args[3]; - return_value = depr_star_pos2_len2_impl(module, a, b, c, d); - -exit: - return return_value; -} - -PyDoc_STRVAR(depr_star_pos2_len2_with_kwd__doc__, -"depr_star_pos2_len2_with_kwd($module, /, a, b, c, d, *, e)\n" -"--\n" -"\n" -"Note: Passing more than 2 positional arguments to\n" -"depr_star_pos2_len2_with_kwd() is deprecated. Parameters \'c\' and \'d\'\n" -"will become keyword-only parameters in Python 3.14.\n" -""); - -#define DEPR_STAR_POS2_LEN2_WITH_KWD_METHODDEF \ - {"depr_star_pos2_len2_with_kwd", _PyCFunction_CAST(depr_star_pos2_len2_with_kwd), METH_FASTCALL|METH_KEYWORDS, depr_star_pos2_len2_with_kwd__doc__}, - -static PyObject * -depr_star_pos2_len2_with_kwd_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *c, PyObject *d, PyObject *e); - -static PyObject * -depr_star_pos2_len2_with_kwd(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 5 - 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), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, - }; - #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", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "depr_star_pos2_len2_with_kwd", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[5]; - PyObject *a; - PyObject *b; - PyObject *c; - PyObject *d; - PyObject *e; - - // Emit compiler warnings when we get to Python 3.14. - #if PY_VERSION_HEX >= 0x030e00C0 - # error \ - "In _testclinic.c, update parameter(s) 'c' and 'd' in the clinic " \ - "input of 'depr_star_pos2_len2_with_kwd' to be keyword-only." - #elif PY_VERSION_HEX >= 0x030e00A0 - # ifdef _MSC_VER - # pragma message ( \ - "In _testclinic.c, update parameter(s) 'c' and 'd' in the clinic " \ - "input of 'depr_star_pos2_len2_with_kwd' to be keyword-only.") - # else - # warning \ - "In _testclinic.c, update parameter(s) 'c' and 'd' in the clinic " \ - "input of 'depr_star_pos2_len2_with_kwd' to be keyword-only." - # endif - #endif - if (nargs > 2 && nargs <= 4) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Passing more than 2 positional arguments to " - "depr_star_pos2_len2_with_kwd() is deprecated. Parameters 'c' and" - " 'd' will become keyword-only parameters in Python 3.14.", 1)) - { - goto exit; - } - } - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 1, argsbuf); - if (!args) { - goto exit; - } - a = args[0]; - b = args[1]; - c = args[2]; - d = args[3]; - e = args[4]; - return_value = depr_star_pos2_len2_with_kwd_impl(module, a, b, c, d, e); - -exit: - return return_value; -} -/*[clinic end generated code: output=7a16fee4d6742d54 input=a9049054013a1b77]*/ diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 28bd2a4430d..58f9c8e8a3e 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -323,7 +323,11 @@ Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorNopGet_Type - Modules/_testcapi/vectorcall.c - MethodDescriptor2_Type - Modules/_testclinic.c - DeprStarInit - +Modules/_testclinic.c - DeprStarInitNoInline - Modules/_testclinic.c - DeprStarNew - +Modules/_testclinic.c - DeprKwdInit - +Modules/_testclinic.c - DeprKwdInitNoInline - +Modules/_testclinic.c - DeprKwdNew - ################################## diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 1593dc49e07..fe84e810760 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -849,25 +849,24 @@ class CLanguage(Language): #define {methoddef_name} #endif /* !defined({methoddef_name}) */ """) - DEPRECATED_POSITIONAL_PROTOTYPE: Final[str] = r""" + COMPILER_DEPRECATION_WARNING_PROTOTYPE: Final[str] = r""" // Emit compiler warnings when we get to Python {major}.{minor}. #if PY_VERSION_HEX >= 0x{major:02x}{minor:02x}00C0 - # error \ - {cpp_message} + # error {message} #elif PY_VERSION_HEX >= 0x{major:02x}{minor:02x}00A0 # ifdef _MSC_VER - # pragma message ( \ - {cpp_message}) + # pragma message ({message}) # else - # warning \ - {cpp_message} + # warning {message} # endif #endif - if ({condition}) {{{{ + """ + DEPRECATION_WARNING_PROTOTYPE: Final[str] = r""" + if ({condition}) {{{{{errcheck} if (PyErr_WarnEx(PyExc_DeprecationWarning, - {depr_message}, 1)) + {message}, 1)) {{{{ - goto exit; + goto exit; }}}} }}}} """ @@ -893,6 +892,30 @@ class CLanguage(Language): function = o return self.render_function(clinic, function) + def compiler_deprecated_warning( + self, + func: Function, + parameters: list[Parameter], + ) -> str | None: + minversion: VersionTuple | None = None + for p in parameters: + for version in p.deprecated_positional, p.deprecated_keyword: + if version and (not minversion or minversion > version): + minversion = version + if not minversion: + return None + + # Format the preprocessor warning and error messages. + assert isinstance(self.cpp.filename, str) + source = os.path.basename(self.cpp.filename) + message = f"Update the clinic input of {func.full_name!r}." + code = self.COMPILER_DEPRECATION_WARNING_PROTOTYPE.format( + major=minversion[0], + minor=minversion[1], + message=c_repr(message), + ) + return normalize_snippet(code) + def deprecate_positional_use( self, func: Function, @@ -910,15 +933,7 @@ class CLanguage(Language): assert first_param.deprecated_positional == last_param.deprecated_positional thenceforth = first_param.deprecated_positional assert thenceforth is not None - - # Format the preprocessor warning and error messages. - assert isinstance(self.cpp.filename, str) - source = os.path.basename(self.cpp.filename) major, minor = thenceforth - cpp_message = ( - f"In {source}, update parameter(s) {pstr} in the clinic " - f"input of {func.full_name!r} to be keyword-only." - ) # Format the deprecation message. if first_pos == 0: @@ -927,7 +942,7 @@ class CLanguage(Language): condition = f"nargs == {first_pos+1}" if first_pos: preamble = f"Passing {first_pos+1} positional arguments to " - depr_message = preamble + ( + message = preamble + ( f"{func.fulldisplayname}() is deprecated. Parameter {pstr} will " f"become a keyword-only parameter in Python {major}.{minor}." ) @@ -938,26 +953,93 @@ class CLanguage(Language): f"Passing more than {first_pos} positional " f"argument{'s' if first_pos != 1 else ''} to " ) - depr_message = preamble + ( + message = preamble + ( f"{func.fulldisplayname}() is deprecated. Parameters {pstr} will " f"become keyword-only parameters in Python {major}.{minor}." ) # Append deprecation warning to docstring. - lines = textwrap.wrap(f"Note: {depr_message}") - docstring = "\n".join(lines) + docstring = textwrap.fill(f"Note: {message}") func.docstring += f"\n\n{docstring}\n" - # Format and return the code block. - code = self.DEPRECATED_POSITIONAL_PROTOTYPE.format( + code = self.DEPRECATION_WARNING_PROTOTYPE.format( condition=condition, - major=major, - minor=minor, - cpp_message=wrapped_c_string_literal(cpp_message, suffix=" \\", - width=64, - subsequent_indent=16), - depr_message=wrapped_c_string_literal(depr_message, width=64, - subsequent_indent=20), + errcheck="", + message=wrapped_c_string_literal(message, width=64, + subsequent_indent=20), + ) + return normalize_snippet(code, indent=4) + + def deprecate_keyword_use( + self, + func: Function, + params: dict[int, Parameter], + argname_fmt: str | None, + ) -> str: + assert len(params) > 0 + names = [repr(p.name) for p in params.values()] + first_param = next(iter(params.values())) + last_param = next(reversed(params.values())) + + # Pretty-print list of names. + pstr = pprint_words(names) + + # For now, assume there's only one deprecation level. + assert first_param.deprecated_keyword == last_param.deprecated_keyword + thenceforth = first_param.deprecated_keyword + assert thenceforth is not None + major, minor = thenceforth + + # Format the deprecation message. + containscheck = "" + conditions = [] + for i, p in params.items(): + if p.is_optional(): + if argname_fmt: + conditions.append(f"nargs < {i+1} && {argname_fmt % i}") + elif func.kind.new_or_init: + conditions.append(f"nargs < {i+1} && PyDict_Contains(kwargs, &_Py_ID({p.name}))") + containscheck = "PyDict_Contains" + else: + conditions.append(f"nargs < {i+1} && PySequence_Contains(kwnames, &_Py_ID({p.name}))") + containscheck = "PySequence_Contains" + else: + conditions = [f"nargs < {i+1}"] + condition = ") || (".join(conditions) + if len(conditions) > 1: + condition = f"(({condition}))" + if last_param.is_optional(): + if func.kind.new_or_init: + condition = f"kwargs && PyDict_GET_SIZE(kwargs) && {condition}" + else: + condition = f"kwnames && PyTuple_GET_SIZE(kwnames) && {condition}" + if len(params) == 1: + what1 = "argument" + what2 = "parameter" + else: + what1 = "arguments" + what2 = "parameters" + message = ( + f"Passing keyword {what1} {pstr} to {func.fulldisplayname}() is deprecated. " + f"Corresponding {what2} will become positional-only in Python {major}.{minor}." + ) + if containscheck: + errcheck = f""" + if (PyErr_Occurred()) {{{{ // {containscheck}() above can fail + goto exit; + }}}}""" + else: + errcheck = "" + if argname_fmt: + # Append deprecation warning to docstring. + docstring = textwrap.fill(f"Note: {message}") + func.docstring += f"\n\n{docstring}\n" + # Format and return the code block. + code = self.DEPRECATION_WARNING_PROTOTYPE.format( + condition=condition, + errcheck=errcheck, + message=wrapped_c_string_literal(message, width=64, + subsequent_indent=20), ) return normalize_snippet(code, indent=4) @@ -1258,6 +1340,14 @@ class CLanguage(Language): parser_definition = parser_body(parser_prototype, *parser_code) else: + deprecated_positionals: dict[int, Parameter] = {} + deprecated_keywords: dict[int, Parameter] = {} + for i, p in enumerate(parameters): + if p.deprecated_positional: + deprecated_positionals[i] = p + if p.deprecated_keyword: + deprecated_keywords[i] = p + 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" % ( @@ -1310,7 +1400,10 @@ class CLanguage(Language): flags = 'METH_METHOD|' + flags parser_prototype = self.PARSER_PROTOTYPE_DEF_CLASS - deprecated_positionals: dict[int, Parameter] = {} + if deprecated_keywords: + code = self.deprecate_keyword_use(f, deprecated_keywords, argname_fmt) + parser_code.append(code) + add_label: str | None = None for i, p in enumerate(parameters): if isinstance(p.converter, defining_class_converter): @@ -1325,8 +1418,6 @@ class CLanguage(Language): parser_code.append("%s:" % add_label) add_label = None if not p.is_optional(): - if p.deprecated_positional: - deprecated_positionals[i] = p parser_code.append(normalize_snippet(parsearg, indent=4)) elif i < pos_only: add_label = 'skip_optional_posonly' @@ -1356,8 +1447,6 @@ class CLanguage(Language): goto %s; }} """ % add_label, indent=4)) - if p.deprecated_positional: - deprecated_positionals[i] = p if i + 1 == len(parameters): parser_code.append(normalize_snippet(parsearg, indent=4)) else: @@ -1373,12 +1462,6 @@ class CLanguage(Language): }} """ % add_label, indent=4)) - if deprecated_positionals: - code = self.deprecate_positional_use(f, deprecated_positionals) - assert parser_code is not None - # Insert the deprecation code before parameter parsing. - parser_code.insert(0, code) - if parser_code is not None: if add_label: parser_code.append("%s:" % add_label) @@ -1398,6 +1481,17 @@ class CLanguage(Language): goto exit; }} """, indent=4)] + if deprecated_positionals or deprecated_keywords: + declarations += "\nPy_ssize_t nargs = PyTuple_GET_SIZE(args);" + if deprecated_keywords: + code = self.deprecate_keyword_use(f, deprecated_keywords, None) + parser_code.append(code) + + if deprecated_positionals: + code = self.deprecate_positional_use(f, deprecated_positionals) + # Insert the deprecation code before parameter parsing. + parser_code.insert(0, code) + parser_definition = parser_body(parser_prototype, *parser_code, declarations=declarations) @@ -1478,6 +1572,10 @@ class CLanguage(Language): parser_definition = parser_definition.replace("{return_value_declaration}", return_value_declaration) + compiler_warning = self.compiler_deprecated_warning(f, parameters) + if compiler_warning: + parser_definition = compiler_warning + "\n\n" + parser_definition + d = { "docstring_prototype" : docstring_prototype, "docstring_definition" : docstring_definition, @@ -2739,6 +2837,7 @@ class Parameter: group: int = 0 # (`None` signifies that there is no deprecation) deprecated_positional: VersionTuple | None = None + deprecated_keyword: VersionTuple | None = None right_bracket_count: int = dc.field(init=False, default=0) def __repr__(self) -> str: @@ -4576,6 +4675,7 @@ class DSLParser: keyword_only: bool positional_only: bool deprecated_positional: VersionTuple | None + deprecated_keyword: VersionTuple | None group: int parameter_state: ParamState indent: IndentStack @@ -4583,11 +4683,7 @@ class DSLParser: coexist: bool parameter_continuation: str preserve_output: bool - star_from_version_re = create_regex( - before="* [from ", - after="]", - word=False, - ) + from_version_re = re.compile(r'([*/]) +\[from +(.+)\]') def __init__(self, clinic: Clinic) -> None: self.clinic = clinic @@ -4612,6 +4708,7 @@ class DSLParser: self.keyword_only = False self.positional_only = False self.deprecated_positional = None + self.deprecated_keyword = None self.group = 0 self.parameter_state: ParamState = ParamState.START self.indent = IndentStack() @@ -5089,21 +5186,22 @@ class DSLParser: return line = line.lstrip() - match = self.star_from_version_re.match(line) + version: VersionTuple | None = None + match = self.from_version_re.fullmatch(line) if match: - self.parse_deprecated_positional(match.group(1)) - return + line = match[1] + version = self.parse_version(match[2]) func = self.function match line: case '*': - self.parse_star(func) + self.parse_star(func, version) case '[': self.parse_opening_square_bracket(func) case ']': self.parse_closing_square_bracket(func) case '/': - self.parse_slash(func) + self.parse_slash(func, version) case param: self.parse_parameter(param) @@ -5404,29 +5502,36 @@ class DSLParser: "Annotations must be either a name, a function call, or a string." ) - def parse_deprecated_positional(self, thenceforth: str) -> None: + def parse_version(self, thenceforth: str) -> VersionTuple: + """Parse Python version in `[from ...]` marker.""" assert isinstance(self.function, Function) - fname = self.function.full_name - if self.keyword_only: - fail(f"Function {fname!r}: '* [from ...]' must come before '*'") - if self.deprecated_positional: - fail(f"Function {fname!r} uses '[from ...]' more than once.") try: major, minor = thenceforth.split(".") - self.deprecated_positional = int(major), int(minor) + return int(major), int(minor) except ValueError: fail( - f"Function {fname!r}: expected format '* [from major.minor]' " + f"Function {self.function.name!r}: expected format '[from major.minor]' " f"where 'major' and 'minor' are integers; got {thenceforth!r}" ) - def parse_star(self, function: Function) -> None: - """Parse keyword-only parameter marker '*'.""" - if self.keyword_only: - fail(f"Function {function.name!r} uses '*' more than once.") - self.deprecated_positional = None - self.keyword_only = True + def parse_star(self, function: Function, version: VersionTuple | None) -> None: + """Parse keyword-only parameter marker '*'. + + The 'version' parameter signifies the future version from which + the marker will take effect (None means it is already in effect). + """ + if version is None: + if self.keyword_only: + fail(f"Function {function.name!r} uses '*' more than once.") + self.check_remaining_star() + self.keyword_only = True + else: + if self.keyword_only: + fail(f"Function {function.name!r}: '* [from ...]' must come before '*'") + if self.deprecated_positional: + fail(f"Function {function.name!r} uses '* [from ...]' more than once.") + self.deprecated_positional = version def parse_opening_square_bracket(self, function: Function) -> None: """Parse opening parameter group symbol '['.""" @@ -5460,11 +5565,38 @@ class DSLParser: f"has an unsupported group configuration. " f"(Unexpected state {st}.c)") - def parse_slash(self, function: Function) -> None: - """Parse positional-only parameter marker '/'.""" - if self.positional_only: - fail(f"Function {function.name!r} uses '/' more than once.") + def parse_slash(self, function: Function, version: VersionTuple | None) -> None: + """Parse positional-only parameter marker '/'. + + The 'version' parameter signifies the future version from which + the marker will take effect (None means it is already in effect). + """ + if version is None: + if self.deprecated_keyword: + fail(f"Function {function.name!r}: '/' must precede '/ [from ...]'") + if self.deprecated_positional: + fail(f"Function {function.name!r}: '/' must precede '* [from ...]'") + if self.keyword_only: + fail(f"Function {function.name!r}: '/' must precede '*'") + if self.positional_only: + fail(f"Function {function.name!r} uses '/' more than once.") + else: + if self.deprecated_keyword: + fail(f"Function {function.name!r} uses '/ [from ...]' more than once.") + if self.deprecated_positional: + fail(f"Function {function.name!r}: '/ [from ...]' must precede '* [from ...]'") + if self.keyword_only: + fail(f"Function {function.name!r}: '/ [from ...]' must precede '*'") self.positional_only = True + self.deprecated_keyword = version + if version is not None: + found = False + for p in reversed(function.parameters.values()): + found = p.kind is inspect.Parameter.POSITIONAL_OR_KEYWORD + break + if not found: + fail(f"Function {function.name!r} specifies '/ [from ...]' " + f"without preceding parameters.") # REQUIRED and OPTIONAL are allowed here, that allows positional-only # without option groups to work (and have default values!) allowed = { @@ -5476,19 +5608,13 @@ class DSLParser: if (self.parameter_state not in allowed) or self.group: fail(f"Function {function.name!r} has an unsupported group configuration. " f"(Unexpected state {self.parameter_state}.d)") - if self.keyword_only: - fail(f"Function {function.name!r} mixes keyword-only and " - "positional-only parameters, which is unsupported.") # fixup preceding parameters for p in function.parameters.values(): - if p.is_vararg(): - continue - if (p.kind is not inspect.Parameter.POSITIONAL_OR_KEYWORD and - not isinstance(p.converter, self_converter) - ): - fail(f"Function {function.name!r} mixes keyword-only and " - "positional-only parameters, which is unsupported.") - p.kind = inspect.Parameter.POSITIONAL_ONLY + if p.kind is inspect.Parameter.POSITIONAL_OR_KEYWORD: + if version is None: + p.kind = inspect.Parameter.POSITIONAL_ONLY + else: + p.deprecated_keyword = version def state_parameter_docstring_start(self, line: str) -> None: assert self.indent.margin is not None, "self.margin.infer() has not yet been called to set the margin" @@ -5773,6 +5899,29 @@ class DSLParser: signature=signature, parameters=parameters).rstrip() + def check_remaining_star(self, lineno: int | None = None) -> None: + assert isinstance(self.function, Function) + + if self.keyword_only: + symbol = '*' + elif self.deprecated_positional: + symbol = '* [from ...]' + else: + return + + no_param_after_symbol = True + for p in reversed(self.function.parameters.values()): + if self.keyword_only: + if p.kind == inspect.Parameter.KEYWORD_ONLY: + return + elif self.deprecated_positional: + if p.deprecated_positional == self.deprecated_positional: + return + break + + fail(f"Function {self.function.name!r} specifies {symbol!r} " + f"without following parameters.", line_number=lineno) + def do_post_block_processing_cleanup(self, lineno: int) -> None: """ Called when processing the block is done. @@ -5780,28 +5929,7 @@ class DSLParser: if not self.function: return - def check_remaining( - symbol: str, - condition: Callable[[Parameter], bool] - ) -> None: - assert isinstance(self.function, Function) - - if values := self.function.parameters.values(): - last_param = next(reversed(values)) - no_param_after_symbol = condition(last_param) - else: - no_param_after_symbol = True - if no_param_after_symbol: - fname = self.function.full_name - fail(f"Function {fname!r} specifies {symbol!r} " - "without any parameters afterwards.", line_number=lineno) - - if self.keyword_only: - check_remaining("*", lambda p: p.kind != inspect.Parameter.KEYWORD_ONLY) - - if self.deprecated_positional: - check_remaining("* [from ...]", lambda p: not p.deprecated_positional) - + self.check_remaining_star(lineno) self.function.docstring = self.format_docstring()