支持多个版本

如果您是库维护人员,您可能想要支持多个版本的Click。查看托盘 [version policy] 有关我们的版本号和支持政策的信息。

Click的大多数功能在不同版本中都是稳定的,不需要特殊处理。然而,功能发布可能会弃用并更改API。有时,更改需要特殊处理。

使用特征检测

更喜欢使用特征检测。查看版本可能很诱人,但通常更脆弱或导致代码更复杂。尝试使用 iftry 块来决定是使用新模式还是旧模式。

如果您确实需要查看版本,请使用{func}' importlib. metal.Version ',这是获取任何已安装Python包版本的标准化方法。

8.2变化

ParamType methods require ctx

在8.2中,有几种方法 ParamType 现在有一个 ctx: click.Context 论点由于这改变了8.1中方法的签名,因此在进行子类化或调用时如何同时支持这两者并不明显。

此示例使用 ParamType.get_metavar ,并且相同的技术应该适用于其他方法,例如 get_missing_message .

更新您的方法覆盖以采用新的 ctx 论点使用以下装饰器包装每个方法。在8.1中,它将尽可能地获取上下文,并使用8.2签名传递它。

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]

这里有一个例子 ParamType 使用此功能的子类别:

class CommaDelimitedString(click.ParamType):
    @add_ctx_arg
    def get_metavar(self, param: click.Parameter, ctx: click.Context | None) -> str:
        return "TEXT,TEXT,..."