Skip to content

Commit eec5f46

Browse files
erlend-aaslandAlexWaygoodserhiy-storchaka
authored
python/cpython#95065: Add Argument Clinic support for deprecating positional use of parameters (python/cpython#95151)
It is now possible to deprecate passing parameters positionally with Argument Clinic, using the new '* [from X.Y]' syntax. (To be read as "keyword-only from Python version X.Y") Co-authored-by: Alex Waygood <[email protected]> Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent ce3b69d commit eec5f46

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

Doc/howto/clinic.rst

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)