Skip to content

Commit 5709212

Browse files
Argument Clinic: document how to remove and rename a parameter
1 parent 708aa7c commit 5709212

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

development-tools/clinic/howto.rst

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,3 +1617,94 @@ and update your unit tests to reflect the new behaviour.
16171617
If you forget to update your input block during the alpha and beta phases,
16181618
the compiler warning will turn into a compiler error when the
16191619
release candidate phase begins.
1620+
1621+
1622+
.. _clinic-howto-remove-parameter:
1623+
1624+
How to remove a parameter
1625+
-------------------------
1626+
1627+
A parameter cannot be removed right away:
1628+
as mandated by Python's backwards-compatibility policy (see :pep:`387`),
1629+
passing it must first emit a :exc:`DeprecationWarning` for two releases.
1630+
The ``[until ...]`` prefix marks a parameter which is going away and names
1631+
the release in which it will be removed::
1632+
1633+
/*[clinic input]
1634+
module foo
1635+
myfunc
1636+
a: object
1637+
[until 3.18] b: object = None
1638+
* [from 3.18]
1639+
c: object = None
1640+
[clinic start generated code]*/
1641+
1642+
Passing an argument for *b* now emits:
1643+
1644+
.. code-block:: none
1645+
1646+
DeprecationWarning: Passing the argument 'b' to myfunc() is deprecated. It will be removed in Python 3.18.
1647+
1648+
A deprecated parameter must have a default value, because calls which do not
1649+
pass it must already be valid.
1650+
1651+
Removing a parameter shifts the position of every parameter which follows it,
1652+
so they should become keyword-only in the same release,
1653+
using the ``* [from ...]`` syntax described above.
1654+
This is why *c* is deprecated as a positional parameter in the example above.
1655+
Argument Clinic enforces this for positional-only parameters:
1656+
only the last of them can be deprecated, because there is no way to pass
1657+
a positional-only parameter which follows a removed one.
1658+
1659+
As with the ``[from ...]`` syntax described above, C preprocessor directives
1660+
are generated for emitting compiler warnings if the ``[until ...]`` prefix has
1661+
not been removed from the Argument Clinic input when the deprecation period is
1662+
over.
1663+
Then remove the parameter and the corresponding argument of the "impl"
1664+
function.
1665+
1666+
.. versionadded:: 3.16
1667+
1668+
1669+
.. _clinic-howto-rename-parameter:
1670+
1671+
How to rename a parameter
1672+
-------------------------
1673+
1674+
Renaming a positional-only parameter is backward compatible:
1675+
its name cannot be used in a call, so it is enough to change it.
1676+
1677+
For a positional-or-keyword or a keyword-only parameter the name is a part of
1678+
the API, so the old name can only be removed after a deprecation period.
1679+
Change the name of the parameter, and add an optional keyword-only parameter
1680+
with the old name, the C name of the renamed parameter and the ``[until ...]``
1681+
prefix::
1682+
1683+
/*[clinic input]
1684+
module foo
1685+
myfunc
1686+
source: object = None
1687+
flag: bool = False
1688+
*
1689+
[until 3.18] input as source: object = None
1690+
[clinic start generated code]*/
1691+
1692+
A parameter which shares the C variable of a preceding parameter is an
1693+
alternative name (an *alias*) of it:
1694+
both names fill the same argument of the "impl" function, and only one of them
1695+
can be used in a call, so ``myfunc(1, input=2)`` and
1696+
``myfunc(source=1, input=2)`` raise :exc:`TypeError`.
1697+
An alias is declared after all other parameters, but it fills the slot of
1698+
the parameter which it renames, so ``myfunc(input=1, flag=True)`` works.
1699+
It is not shown in the signature, which for the function above is
1700+
``($module, /, source=None, flag=False)``.
1701+
1702+
Passing an argument for the old name now emits:
1703+
1704+
.. code-block:: none
1705+
1706+
DeprecationWarning: Passing the argument 'input' to myfunc() is deprecated. Use 'source' instead. It will be removed in Python 3.18.
1707+
1708+
When the deprecation period is over, remove the alias.
1709+
1710+
.. versionadded:: 3.16

0 commit comments

Comments
 (0)