@@ -1898,3 +1898,91 @@ blocks embedded in Python files look slightly different. They look like this:
18981898 #[python start generated code]*/
18991899 def foo(): pass
19001900 #/*[python checksum:...]*/
1901+
1902+
1903+ .. _clinic-howto-deprecate-positional :
1904+
1905+ How to deprecate passing parameters positionally
1906+ ------------------------------------------------
1907+
1908+ Argument Clinic provides syntax that makes it possible to generate code that
1909+ deprecates passing :term: `arguments <argument> ` positionally.
1910+ For example, say we've got a module-level function :py:func: `!foo.myfunc `
1911+ that has three :term: `parameters <parameter> `:
1912+ positional-or-keyword parameters *a * and *b *, and a keyword-only parameter *c *::
1913+
1914+ /*[clinic input]
1915+ module foo
1916+ myfunc
1917+ a: int
1918+ b: int
1919+ *
1920+ c: int
1921+ [clinic start generated output]*/
1922+
1923+ We now want to make the *b * parameter keyword-only;
1924+ however, we'll have to wait two releases before making this change,
1925+ as mandated by Python's backwards-compatibility policy (see :pep: `387 `).
1926+ For this example, imagine we're in the development phase for Python 3.12:
1927+ that means we'll be allowed to introduce deprecation warnings in Python 3.12
1928+ whenever the *b * parameter is passed positionally,
1929+ and we'll be allowed to make it keyword-only in Python 3.14 at the earliest.
1930+
1931+ We can use Argument Clinic to emit the desired deprecation warnings
1932+ using the ``* [from ...]` `` syntax,
1933+ by adding the line ``* [from 3.14] `` right above the *b * parameter::
1934+
1935+ /*[clinic input]
1936+ module foo
1937+ myfunc
1938+ a: int
1939+ * [from 3.14]
1940+ b: int
1941+ *
1942+ c: int
1943+ [clinic start generated output]*/
1944+
1945+ Next, regenerate Argument Clinic code (``make clinic ``),
1946+ and add unit tests for the new behaviour.
1947+
1948+ The generated code will now emit a :exc: `DeprecationWarning `
1949+ when an :term: `argument ` for the :term: `parameter ` *b * is passed positionally.
1950+ C preprocessor directives are also generated for emitting
1951+ compiler warnings if the ``* [from ...] `` line has not been removed
1952+ from the Argument Clinic input when the deprecation period is over,
1953+ which means when the alpha phase of the specified Python version kicks in.
1954+
1955+ Let's return to our example and skip ahead two years:
1956+ Python 3.14 development has now entered the alpha phase,
1957+ but we forgot all about updating the Argument Clinic code
1958+ for :py:func: `!myfunc `!
1959+ Luckily for us, compiler warnings are now generated:
1960+
1961+ .. code-block :: none
1962+
1963+ In file included from Modules/foomodule.c:139:
1964+ Modules/clinic/foomodule.c.h:83:8: warning: Update 'b' in 'myfunc' in 'foomodule.c' to be keyword-only. [-W#warnings]
1965+ # warning "Update 'b' in 'myfunc' in 'foomodule.c' to be keyword-only."
1966+ ^
1967+
1968+ We now close the deprecation phase by making *b * keyword-only;
1969+ replace the ``* [from ...]` `` line above *b *
1970+ with the ``* `` from the line above *c *::
1971+
1972+ /*[clinic input]
1973+ module foo
1974+ myfunc
1975+ a: int
1976+ *
1977+ b: int
1978+ c: int
1979+ [clinic start generated output]*/
1980+
1981+ Finally, run ``make clinic `` to regenerate the Argument Clinic code,
1982+ and update your unit tests to reflect the new behaviour.
1983+
1984+ .. note ::
1985+
1986+ If you forget to update your input block during the alpha and beta phases,
1987+ the compiler warning will turn into a compiler error when the
1988+ release candidate phase begins.
0 commit comments