Skip to content

Commit 9e5cd51

Browse files
committed
docs: Update the wrapping guide to the new deprecation style
The previous commit changed every deprecation notice in the repo but left the wrapping guide describing the old message form, `"<old FQCN> is deprecated. Use <new FQCN> instead."`, with no version and no cross-reference brackets. The guide is what a contributor reads before writing a new deprecation, so leaving it behind would reintroduce the old form. It now describes the form the code uses and why: the version in the sentence because a separate "since" line cannot be expressed through the decorator, the replacement as a bare `[name][]` cross-reference so the generated admonition links to it, no backticks because the same string is printed as a runtime warning, and implicit concatenation of single-line strings because a triple-quoted message carries its indentation into both the cross-reference and the terminal. The worked example is updated to match, and now escapes the brackets and dots in its `pytest.deprecated_call()` regex. That is easy to get wrong silently, because `match` is a search and an unescaped `[...]` is a character class that still matches something. Also added is the hand-written `Deprecated:` admonition for the cases the decorator cannot reach, which the guide never mentioned: an argument, an enum member, or construction being made stricter, all of which the repo now has. The `deprecated_member` paragraph says outright that the helper produces no admonition on its own, since that is the whole reason the members need one written by hand. Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
1 parent 9d09bca commit 9e5cd51

1 file changed

Lines changed: 33 additions & 8 deletions

File tree

‎docs/wrapping-guide/deprecation-and-compatibility.md‎

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,20 @@ define the wider 0.x versioning process.
99

1010
Mark the old public symbol with
1111
[`typing_extensions.deprecated`][typing_extensions.deprecated]. Use this exact
12-
message form: `"<old FQCN> is deprecated. Use <new FQCN> instead."`. Write both
13-
fully qualified names exactly. In the old API documentation, explain any change
14-
to the return type or behavior. A caller should know what to use from the
12+
message form: `"<old FQCN> is deprecated since v<X.Y.Z>. Use [<new FQCN>][]
13+
instead."`. Write both fully qualified names exactly, the old one plain and the
14+
replacement as a bare cross-reference so the rendered `Deprecated:` admonition
15+
links to it. The version belongs in the sentence: a separate "since" line
16+
cannot be expressed through the decorator, so the two would drift apart.
17+
18+
The same string is printed as a runtime warning, so keep it to a sentence or
19+
two and build it by concatenating single-line strings. A triple-quoted message
20+
keeps its indentation, which stops the cross-reference from resolving and
21+
prints an indented warning in the terminal. Do not put the names in backticks
22+
either: they buy code font in the documentation at the cost of noise in the
23+
console, where the reader cannot skip over them. Anything beyond "use X
24+
instead", such as a change to the return type or behavior, goes in the
25+
docstring body as prose. A caller should still know what to use from the
1526
warning alone.
1627

1728
This example gives the replacement conversion function a numeric-suffixed name
@@ -27,19 +38,31 @@ def thing_from_proto2(value: int) -> str:
2738

2839

2940
@deprecated(
30-
"example.thing_from_proto is deprecated. Use example.thing_from_proto2 instead."
41+
"example.thing_from_proto is deprecated since v0.4.1. "
42+
"Use [example.thing_from_proto2][] instead."
3143
)
3244
def thing_from_proto(value: int) -> str:
3345
return thing_from_proto2(value)
3446

3547

3648
with deprecated_call(
37-
match="example.thing_from_proto is deprecated. "
38-
"Use example.thing_from_proto2 instead."
49+
match=r"^example\.thing_from_proto is deprecated since v0\.4\.1\. "
50+
r"Use \[example\.thing_from_proto2\]\[\] instead\.$"
3951
):
4052
assert thing_from_proto(3) == "3"
4153
```
4254

55+
`match` is a regular expression, so the brackets of the cross-reference have to
56+
be escaped there, as do the dots of the qualified names.
57+
58+
Where the decorator cannot reach, such as a single argument, an enum member, or
59+
construction that is being made stricter, write the notice as a `Deprecated:`
60+
admonition in the docstring instead. Put it immediately after the summary line
61+
and give it no custom title (a title replaces
62+
the word "Deprecated" in the rendered output), and again state the version in
63+
the text. Never hand-write one for a symbol the decorator already marks, or the
64+
page shows the same notice twice.
65+
4366
## Check downstream adoption before removal
4467

4568
When possible, check downstream client releases to see if they import or expose
@@ -65,8 +88,10 @@ unsuffixed name while retaining a deprecated alias for the suffixed name.
6588

6689
For an enum-member change, use
6790
[`deprecated_member`][frequenz.core.enum.deprecated_member]. It keeps the old
68-
member temporarily and warns when code uses it. Document the representation new
69-
code should use.
91+
member temporarily and warns when code uses it, but it predates PEP 702 and
92+
griffe knows nothing about it, so the member also needs the hand-written
93+
`Deprecated:` admonition described above. Document the representation new code
94+
should use.
7095

7196
## Tighten invariants in stages
7297

0 commit comments

Comments
 (0)