Skip to content

Commit 3ab432c

Browse files
serhiy-storchakaerlend-aaslandAlexWaygood
committed
python/cpython#107704: Argument Clinic: add support for deprecating keyword use of parameters (python/cpython#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 <[email protected]> Co-authored-by: Alex Waygood <[email protected]>
1 parent 4baaf76 commit 3ab432c

File tree

1 file changed

+43
-22
lines changed

1 file changed

+43
-22
lines changed

development-tools/clinic.rst

+43-22
Original file line numberDiff line numberDiff line change
@@ -1935,54 +1935,70 @@ The generated docstring ends up looking like this:
19351935
19361936
19371937
.. _clinic-howto-deprecate-positional:
1938+
.. _clinic-howto-deprecate-keyword:
19381939

1939-
How to deprecate passing parameters positionally
1940-
------------------------------------------------
1940+
How to deprecate passing parameters positionally or by keyword
1941+
--------------------------------------------------------------
19411942

19421943
Argument Clinic provides syntax that makes it possible to generate code that
1943-
deprecates passing :term:`arguments <argument>` positionally.
1944+
deprecates passing :term:`arguments <argument>` for positional-or-keyword
1945+
:term:`parameters <parameter>` positionally or by keyword.
19441946
For example, say we've got a module-level function :py:func:`!foo.myfunc`
1945-
that has three :term:`parameters <parameter>`:
1946-
positional-or-keyword parameters *a* and *b*, and a keyword-only parameter *c*::
1947+
that has five parameters: a positional-only parameter *a*, three
1948+
positional-or-keyword parameters *b*, *c* and *d*, and a keyword-only
1949+
parameter *e*::
19471950

19481951
/*[clinic input]
19491952
module foo
19501953
myfunc
19511954
a: int
1955+
/
19521956
b: int
1953-
*
19541957
c: int
1958+
d: int
1959+
*
1960+
e: int
19551961
[clinic start generated output]*/
19561962

1957-
We now want to make the *b* parameter keyword-only;
1958-
however, we'll have to wait two releases before making this change,
1963+
We now want to make the *b* parameter positional-only and the *d* parameter
1964+
keyword-only;
1965+
however, we'll have to wait two releases before making these changes,
19591966
as mandated by Python's backwards-compatibility policy (see :pep:`387`).
19601967
For this example, imagine we're in the development phase for Python 3.12:
19611968
that means we'll be allowed to introduce deprecation warnings in Python 3.12
1962-
whenever the *b* parameter is passed positionally,
1963-
and we'll be allowed to make it keyword-only in Python 3.14 at the earliest.
1969+
whenever an argument for the *b* parameter is passed by keyword or an argument
1970+
for the *d* parameter is passed positionally, and we'll be allowed to make
1971+
them positional-only and keyword-only respectively in Python 3.14 at
1972+
the earliest.
19641973

19651974
We can use Argument Clinic to emit the desired deprecation warnings
1966-
using the ``* [from ...]`` syntax,
1967-
by adding the line ``* [from 3.14]`` right above the *b* parameter::
1975+
using the ``[from ...]`` syntax, by adding the line ``/ [from 3.14]`` right
1976+
below the *b* parameter and adding the line ``* [from 3.14]`` right above
1977+
the *d* parameter::
19681978

19691979
/*[clinic input]
19701980
module foo
19711981
myfunc
19721982
a: int
1973-
* [from 3.14]
1983+
/
19741984
b: int
1975-
*
1985+
/ [from 3.14]
19761986
c: int
1987+
* [from 3.14]
1988+
d: int
1989+
*
1990+
e: int
19771991
[clinic start generated output]*/
19781992

19791993
Next, regenerate Argument Clinic code (``make clinic``),
19801994
and add unit tests for the new behaviour.
19811995

19821996
The generated code will now emit a :exc:`DeprecationWarning`
1983-
when an :term:`argument` for the :term:`parameter` *b* is passed positionally.
1997+
when an :term:`argument` for the :term:`parameter` *d* is passed positionally
1998+
(e.g ``myfunc(1, 2, 3, 4, e=5)``) or an argument for the parameter *b* is
1999+
passed by keyword (e.g ``myfunc(1, b=2, c=3, d=4, e=5)``).
19842000
C preprocessor directives are also generated for emitting
1985-
compiler warnings if the ``* [from ...]`` line has not been removed
2001+
compiler warnings if the ``[from ...]`` lines have not been removed
19862002
from the Argument Clinic input when the deprecation period is over,
19872003
which means when the alpha phase of the specified Python version kicks in.
19882004

@@ -1995,21 +2011,26 @@ Luckily for us, compiler warnings are now generated:
19952011
.. code-block:: none
19962012
19972013
In file included from Modules/foomodule.c:139:
1998-
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]
1999-
# warning "In 'foomodule.c', update parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings]"
2014+
Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]
2015+
# warning "In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]"
20002016
^
20012017
2002-
We now close the deprecation phase by making *b* keyword-only;
2003-
replace the ``* [from ...]`` line above *b*
2004-
with the ``*`` from the line above *c*::
2018+
We now close the deprecation phase by making *a* positional-only and *c*
2019+
keyword-only;
2020+
replace the ``/ [from ...]`` line below *b* with the ``/`` from the line
2021+
below *a* and the ``* [from ...]`` line above *d* with the ``*`` from
2022+
the line above *e*::
20052023

20062024
/*[clinic input]
20072025
module foo
20082026
myfunc
20092027
a: int
2010-
*
20112028
b: int
2029+
/
20122030
c: int
2031+
*
2032+
d: int
2033+
e: int
20132034
[clinic start generated output]*/
20142035

20152036
Finally, run ``make clinic`` to regenerate the Argument Clinic code,

0 commit comments

Comments
 (0)