Skip to content

Commit 89206ca

Browse files
committed
Add a doc for supporting 8.1.x|8.2.0
This uses `get_metavar` as an example, demonstrates how to feature-detect based on `kwargs` containing `"ctx"`, and shows simplified usage. A note block indicates how this same strategy applies to other ``ParamType`` methods. Section naming is setup to support: - future documentation of other version transitions - documentation of other transitional methods for 8.1 vs 8.2
1 parent a786ea7 commit 89206ca

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ How to Guides
7575

7676
entry-points
7777
setuptools
78+
support-multiple-versions
7879

7980
Conceptual Guides
8081
^^^^^^^^^^^^^^^^^^^

docs/support-multiple-versions.rst

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Supporting Multiple Versions
2+
============================
3+
4+
Supporting multiple versions of ``click`` in a single codebase is usually
5+
straightforward. Most features of ``click`` are stable across releases, and don't
6+
require special handling.
7+
8+
However, feature releases may deprecate and change APIs. Some features require special
9+
handling to function correctly across a range of versions.
10+
11+
click 8.1.x and 8.2.x
12+
---------------------
13+
14+
This section will help you support click version 8.1 and 8.2 simultaneously.
15+
16+
17+
``ParamType`` methods require ``ctx``
18+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19+
20+
In 8.2, several methods of ``ParamType`` now accept a ``ctx: click.Context`` argument.
21+
By way of example, this section covers ``ParamType.get_metavar``.
22+
23+
To handle this while supporting 8.1, you can define a decorator:
24+
25+
.. code-block:: python
26+
27+
import functools
28+
import typing as t
29+
30+
C = t.TypeVar("C", bound=t.Callable[..., t.Any])
31+
32+
def shim_get_metavar(f: C) -> C:
33+
@functools.wraps(f)
34+
def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any:
35+
if "ctx" not in kwargs:
36+
kwargs["ctx"] = click.get_current_context(silent=True)
37+
return f(*args, **kwargs)
38+
39+
return wrapper # type: ignore[return-value]
40+
41+
And then use the decorator on your ``ParamType`` to write a compatible ``get_metavar``
42+
method.
43+
For example:
44+
45+
.. code-block:: python
46+
47+
import click
48+
49+
class CommaDelimitedString(click.ParamType):
50+
@shim_get_metavar
51+
def get_metavar(self, param: click.Parameter, ctx: click.Context | None) -> str:
52+
return "TEXT,TEXT,..."
53+
54+
55+
.. note::
56+
57+
This methodology, creating a wrapper which does feature detection based on ``"ctx"``
58+
being in ``kwargs``, works for several other methods, e.g.
59+
``ParamType.get_missing_message``.

0 commit comments

Comments
 (0)