测试类型注解与click参数类型是否匹配
项目描述
click-type-test
目录
概述
click-type-test
允许您测试您的 click
选项和参数是否与您的类型注解匹配。
它的命名来源于它所支持的三件事
click
:构建CLItype
:添加类型注解test
:测试前两个是否匹配
安装
click-type-test
仅适用于Python 3.10+。
在支持的Python版本上,应使用以下命令安装
pip install click-type-test
使用
安装包,然后使用 click_type_test
提取注解数据,并对其进行检查。
from click_type_test import check_param_annotations
from foopkg import mycommand
def test_mycommand_annotations():
check_param_annotations(mycommand)
check_param_annotations
如果注解不匹配,则引发 click_type_test.BadAnnotationError
。
版本保护
尽管 click-type-test
仅适用于某些Python版本,但这并不意味着您的应用程序,在经过测试后,也受到这些Python版本的限制。
您可以使用如下方式(在 pytest
下)来保护您的使用
import pytest
import sys
from foopkg import mycommand
@pytest.mark.skipif(
sys.version_info < (3, 10),
reason="click-type-test requires py3.10+",
)
def test_mycommand_annotations():
from click_type_test import check_param_annotations
check_param_annotations(mycommand)
类型确定逻辑
click-type-test
会尽力根据可用的信息确定运行时将传递给命令的类型。
-
如果参数实现了
AnnotatedParameter
并具有显式的注解,则将始终使用该值。这使得此值具有最高优先级的覆盖。
-
如果有具有返回类型注解的
callback
函数,则使用callback
的返回类型。这使得callback
返回类型成为第二高优先级的值。 -
之后,
click-type-test
必须检查已使用的参数类型、已设置的任何default
值、选项的multiple=True
和参数的nargs=-1
,并通常尝试正确推断类型。
对于参数类型评估,用户可以通过两种主要方式控制自定义类型的行
-
使用返回类型注解注释
convert
(如果可用,则使用此注解) -
实现
AnnotatedOption
并定义类型注解(这是参数类型的最高优先级值,因此可以用作覆盖)
作为一个简单的例子,click-type-test
能够正确处理以下逗号分隔的列表类型定义
class CommaDelimitedList(click.ParamType):
def get_metavar(self, param: click.Parameter) -> str:
return "TEXT,TEXT,..."
def convert(
self, value: str, param: click.Parameter | None, ctx: click.Context | None
) -> list[str]:
value = super().convert(value, param, ctx)
return value.split(",") if value else []
使用AnnotatedParamType和AnnotatedOption进行扩展和调整
click-type-test
所做的类型推断不一定总是正确的。但是,而不是跳过选项或参数,如果可能的话,最好传递所需的信息。
自定义参数类型可以通过实现AnnotatedParamType
协议来支持与click-type-test
一起使用。
类似地,自定义click.Option
子类可以通过实现AnnotatedOption
协议来支持特殊的使用。
您所采取的方法将取决于您的CLI的确切需求,但通常应该可以调整click-type-test
以正确理解您的CLI。
AnnotatedParamType
如果您有自定义的ParamType
,则扩展它以实现AnnotatedParamType
协议,它将在click-type-test
中获得一级支持。
这需要有一个方法,get_type_annotation
,它接受所使用的click.Parameter
并返回应作为注解期望的类型。
您可以使用简单的isinstance
检查来检查ParamType
是否实现了AnnotatedParamType
import click_type_test
isinstance(myparamtype, click_type_test.AnnotatedParamType)
AnnotatedParameter
如果您有子类Option
或Argument
,该子类产生特殊值,可能需要从该类提供类型信息。为了处理这种情况,只需让您的参数类实现AnnotatedParameter
协议。
这需要一个方法,has_explicit_annotation
和一个属性type_annotation
。没有参数的has_explicit_annotation
返回一个bool值。返回一个type
的type_annotation
。
有关示例,请参阅examples/explicitly_annotation_option.py
您可以使用简单的isinstance
检查来检查Parameter
是否实现了AnnotatedParameter
import click_type_test
isinstance(myparam, click_type_test.AnnotatedParameter)
API
以下值是click-type-test
的可消费API。没有其他值是接口的一部分。
-
AnnotatedParamType
:为提供显式类型信息的click.ParamType
子类提供的协议。它是运行时可检查的。 -
AnnotatedParameter
:为提供显式类型信息的click.Parameter
子类提供的协议。它是运行时可检查的。 -
deduce_type_from_parameter
:一个函数,它接受一个click.Parameter
并返回一个类型。在内部使用,但可用于单元测试自定义类。 -
check_param_annotations
:一个函数,它接受一个click.Command
并检查其回调上的类型注解与参数列表。 -
BadAnnotationError
:如果检查注解失败,则引发的错误类型。
许可协议
click-type-test
根据MIT许可证条款分发。