Argument Clinic 是 CPython 中的一个代码生成工具,它自动化了 C 扩展模块的参数解析代码的创建。它减少了样板代码,确保了代码的一致性,并有助于维护 Python 的 C API 文档和实现之间的兼容性。
有关测试 C 扩展(包括通过 Argument Clinic 创建的扩展)的信息,请参阅 C 扩展测试。
使用 CPython 的 C API 编写正确的参数解析代码是冗长、易错且繁琐的。Argument Clinic 通过提供一种领域特定语言 (DSL) 来解决这个问题,该语言允许开发人员直接在 C 源文件中以类似 Python 的语法指定函数签名。然后,该工具会生成适当的参数解析代码、文档字符串和函数原型。
来源:Tools/clinic/clinic.py1-11 Tools/clinic/libclinic/app.py37-106
C代码中的Argument Clinic块示例如下:
clinic工具会处理这些块并为以下内容生成相应的C代码:
来源:Tools/clinic/libclinic/dsl_parser.py246-1117 Tools/clinic/libclinic/block_parser.py16-38
Argument Clinic 包含几个相互关联的组件,它们协同工作以解析函数规范并生成 C 代码
来源:Tools/clinic/libclinic/function.py23-310 Tools/clinic/libclinic/converter.py61-565 Tools/clinic/libclinic/parse_args.py17-941
块解析器从源文件中提取 Argument Clinic 块,识别输入部分和任何先前生成的代码。
来源:Tools/clinic/libclinic/block_parser.py16-257
DSL 解析器解释 Argument Clinic 语法,处理
来源:Tools/clinic/libclinic/dsl_parser.py246-1117
函数对象存储
来源:Tools/clinic/libclinic/function.py82-179
参数对象存储
来源:Tools/clinic/libclinic/function.py182-240
Argument Clinic 的一个关键部分是其类型转换系统,该系统负责在 Python 对象和 C 类型之间进行转换。
来源:Tools/clinic/libclinic/converter.py61-565 Tools/clinic/libclinic/converters.py20-1210 Tools/clinic/libclinic/return_converters.py44-152
内置转换器处理常见的 Python 类型
bool: 转换为 C int (0 或 1)int: 转换为 C int 并进行范围检查str: 转换为 C const char*float: 转换为 C doublebytes: 转换为 C char* 和长度object: 直接传递 Python 对象专用转换器
self_converter: 处理方法的隐式第一个参数defining_class_converter: 处理类方法的类参数来源:Tools/clinic/libclinic/converters.py20-1210
代码生成过程为每个函数创建了几个组件
来源:Tools/clinic/libclinic/parse_args.py193-941 Tools/clinic/libclinic/codegen.py18-73
对于每个函数,Argument Clinic 会生成:
PyArg_Parse* 来提取和验证参数的代码来源:Tools/clinic/libclinic/parse_args.py134-191 Tools/clinic/libclinic/clanguage.py72-396
Argument Clinic 支持各种参数类型和功能
/ 表示)* 表示)*args 表示)来源:Tools/clinic/libclinic/function.py182-240 Tools/clinic/libclinic/parse_args.py217-299
Argument Clinic 根据参数类型支持不同的调用约定
该工具根据函数签名自动选择最有效的调用约定。
来源:Tools/clinic/libclinic/function.py153-167 Tools/clinic/libclinic/parse_args.py263-287
下面是一个使用 Argument Clinic 的函数定义的简化示例
来源: Lib/test/clinic.test.c13-69 Modules/_testclinic.c107-123
Argument Clinic 使用校验和来检测何时需要更新生成的代码,确保规范的更改能够正确地更新生成的代码。
/*[clinic end generated code: output=checksumvalue input=checksumvalue]*/
来源: Tools/clinic/libclinic/utils.py32-36
该工具支持生成输出的不同目标
来源: Tools/clinic/libclinic/app.py108-155
预设配置输出的各个部分发送到哪里
来源: Tools/clinic/libclinic/app.py39-82
Argument Clinic 与 CPython 的构建过程深度集成
来源: Tools/clinic/clinic.py1-11 Tools/clinic/libclinic/cli.py49-114
来源: Tools/clinic/libclinic/app.py37-82
Argument Clinic 可以直接在源文件上运行
python -m clinic module.c
选项包括:
--limited-capi:生成与有限 C API 兼容的代码--output:指定输出文件--force:强制重新生成块来源: Tools/clinic/clinic.py1-11 Tools/clinic/libclinic/cli.py124-202
Argument Clinic 可以生成与 Python 的有限 C API 兼容的代码,该 API 为不同 Python 版本之间的二进制兼容性提供了保证。
来源: Tools/clinic/libclinic/parse_args.py324-332
支持生成带有临界区以实现线程安全的代码。
来源: Tools/clinic/libclinic/dsl_parser.py297-298 Tools/clinic/libclinic/function.py112
开发人员可以定义自定义转换器来处理专门的类型。
来源: Tools/clinic/libclinic/converter.py30-40 Tools/clinic/libclinic/dsl_parser.py287-288
Argument Clinic 是 CPython 开发生态系统中至关重要的工具,它通过自动化参数解析中容易出错的方面,使得 C 扩展代码更易于维护和更可靠。它弥合了 Python 用户友好界面与 C 的底层实现之间的差距,确保了文档字符串和实现保持同步。