Supporting Multiple Versions¶
If you are a library maintainer, you may want to support multiple versions of Click. See the Pallets version policy for information about our version numbers and support policy.
Most features of Click are stable across releases, and don’t require special handling. However, feature releases may deprecate and change APIs. Occasionally, a change will require special handling.
Use Feature Detection¶
Prefer using feature detection. Looking at the version can be tempting, but is
often more brittle or results in more complicated code. Try to use if
or try
blocks to decide whether to use a new or old pattern.
If you do need to look at the version, use importlib.metadata.version()
,
the standardized way to get versions for any installed Python package.
Changes in 8.2¶
ParamType
methods require ctx
¶
In 8.2, several methods of ParamType
now have a ctx: click.Context
argument. Because this changes the signature of the methods from 8.1, it’s not
obvious how to support both when subclassing or calling.
This example uses ParamType.get_metavar
, and the same technique should be
applicable to other methods such as get_missing_message
.
Update your methods overrides to take the new ctx
argument. Use the
following decorator to wrap each method. In 8.1, it will get the context where
possible and pass it using the 8.2 signature.
import functools
import typing as t
import click
F = t.TypeVar("F", bound=t.Callable[..., t.Any])
def add_ctx_arg(f: F) -> F:
@functools.wraps(f)
def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any:
if "ctx" not in kwargs:
kwargs["ctx"] = click.get_current_context(silent=True)
return f(*args, **kwargs)
return wrapper # type: ignore[return-value]
Here’s an example ParamType
subclass which uses this:
class CommaDelimitedString(click.ParamType):
@add_ctx_arg
def get_metavar(self, param: click.Parameter, ctx: click.Context | None) -> str:
return "TEXT,TEXT,..."