@@ -1898,3 +1898,91 @@ blocks embedded in Python files look slightly different. They look like this:
1898
1898
#[python start generated code]*/
1899
1899
def foo(): pass
1900
1900
#/*[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