Skip to content

Commit 2f31143

Browse files
serhiy-storchakaerlend-aaslandAlexWaygood
authored
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 <erlend@python.org> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
1 parent eb953d6 commit 2f31143

File tree

9 files changed

+2992
-1344
lines changed

9 files changed

+2992
-1344
lines changed

Doc/howto/clinic.rst

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,54 +1941,70 @@ The generated docstring ends up looking like this:
19411941
19421942
19431943
.. _clinic-howto-deprecate-positional:
1944+
.. _clinic-howto-deprecate-keyword:
19441945

1945-
How to deprecate passing parameters positionally
1946-
------------------------------------------------
1946+
How to deprecate passing parameters positionally or by keyword
1947+
--------------------------------------------------------------
19471948

19481949
Argument Clinic provides syntax that makes it possible to generate code that
1949-
deprecates passing :term:`arguments <argument>` positionally.
1950+
deprecates passing :term:`arguments <argument>` for positional-or-keyword
1951+
:term:`parameters <parameter>` positionally or by keyword.
19501952
For example, say we've got a module-level function :py:func:`!foo.myfunc`
1951-
that has three :term:`parameters <parameter>`:
1952-
positional-or-keyword parameters *a* and *b*, and a keyword-only parameter *c*::
1953+
that has five parameters: a positional-only parameter *a*, three
1954+
positional-or-keyword parameters *b*, *c* and *d*, and a keyword-only
1955+
parameter *e*::
19531956

19541957
/*[clinic input]
19551958
module foo
19561959
myfunc
19571960
a: int
1961+
/
19581962
b: int
1959-
*
19601963
c: int
1964+
d: int
1965+
*
1966+
e: int
19611967
[clinic start generated output]*/
19621968

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

19711980
We can use Argument Clinic to emit the desired deprecation warnings
1972-
using the ``* [from ...]`` syntax,
1973-
by adding the line ``* [from 3.14]`` right above the *b* parameter::
1981+
using the ``[from ...]`` syntax, by adding the line ``/ [from 3.14]`` right
1982+
below the *b* parameter and adding the line ``* [from 3.14]`` right above
1983+
the *d* parameter::
19741984

19751985
/*[clinic input]
19761986
module foo
19771987
myfunc
19781988
a: int
1979-
* [from 3.14]
1989+
/
19801990
b: int
1981-
*
1991+
/ [from 3.14]
19821992
c: int
1993+
* [from 3.14]
1994+
d: int
1995+
*
1996+
e: int
19831997
[clinic start generated output]*/
19841998

19851999
Next, regenerate Argument Clinic code (``make clinic``),
19862000
and add unit tests for the new behaviour.
19872001

19882002
The generated code will now emit a :exc:`DeprecationWarning`
1989-
when an :term:`argument` for the :term:`parameter` *b* is passed positionally.
2003+
when an :term:`argument` for the :term:`parameter` *d* is passed positionally
2004+
(e.g ``myfunc(1, 2, 3, 4, e=5)``) or an argument for the parameter *b* is
2005+
passed by keyword (e.g ``myfunc(1, b=2, c=3, d=4, e=5)``).
19902006
C preprocessor directives are also generated for emitting
1991-
compiler warnings if the ``* [from ...]`` line has not been removed
2007+
compiler warnings if the ``[from ...]`` lines have not been removed
19922008
from the Argument Clinic input when the deprecation period is over,
19932009
which means when the alpha phase of the specified Python version kicks in.
19942010

@@ -2001,21 +2017,26 @@ Luckily for us, compiler warnings are now generated:
20012017
.. code-block:: none
20022018
20032019
In file included from Modules/foomodule.c:139:
2004-
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]
2005-
# warning "In 'foomodule.c', update parameter(s) 'a' and 'b' in the clinic input of 'mymod.myfunc' to be keyword-only. [-W#warnings]"
2020+
Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]
2021+
# warning "In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]"
20062022
^
20072023
2008-
We now close the deprecation phase by making *b* keyword-only;
2009-
replace the ``* [from ...]`` line above *b*
2010-
with the ``*`` from the line above *c*::
2024+
We now close the deprecation phase by making *a* positional-only and *c*
2025+
keyword-only;
2026+
replace the ``/ [from ...]`` line below *b* with the ``/`` from the line
2027+
below *a* and the ``* [from ...]`` line above *d* with the ``*`` from
2028+
the line above *e*::
20112029

20122030
/*[clinic input]
20132031
module foo
20142032
myfunc
20152033
a: int
2016-
*
20172034
b: int
2035+
/
20182036
c: int
2037+
*
2038+
d: int
2039+
e: int
20192040
[clinic start generated output]*/
20202041

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

0 commit comments

Comments
 (0)