gpt4 book ai didi

python - 使用 "clinic"时如何为 python 模块创建新函数?

转载 作者:太空宇宙 更新时间:2023-11-04 03:25:18 25 4
gpt4 key购买 nike

出于某些原因,我必须扩展 python 的 ssl 模块。特别是我需要 C 中的第二个版本的 load_cert_chain()。

我的问题与 openssl 无关,而是如何应对“诊所”:在原始函数前面有一个 clinic-input:

/*[clinic input]
_ssl._SSLContext.load_cert_chain
certfile: object
keyfile: object = NULL
password: object = NULL

[clinic start generated code]*/

static PyObject *
_ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
PyObject *keyfile, PyObject *password)
/*[clinic end generated code: output=9480bc1c380e2095 input=7cf9ac673cbee6fc]*/
{
PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL;
pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback;
...

到目前为止,我知道 _ssl__SSLContext_load_cert_chain_impl 是 load_cert_chain 的实现,并在 _ssl__SSLContext_load_cert_chain 中调用,它在头文件 _ssl.c.h 中定义然而,这是由诊所自动生成的 - 不是吗?

既然一切都是自动创建的,那么我从哪里开始将我的新函数 load_cert_chain2 定义为原始函数的副本?

最佳答案

澄清一些误解:

不,参数 clinic 与将 C 函数链接到 Python 函数无关!

参数 clinic 只是为 C 函数创建函数签名。在你的例子中

/*[clinic input]
_ssl._SSLContext.load_cert_chain
certfile: object
keyfile: object = NULL
password: object = NULL

_ssl__SSLContext_load_cert_chain_impl C 函数将在签名中公开为 _ssl._SSLContext.load_cert_chain,三个参数需要一个 python 对象:certfile 作为位置参数,keyfile, password 作为可选参数,默认值为 NULL


调用函数的方式或时间与参数 clinic 无关。方法声明在 Modules/clinic/_ssl.c.h 中完成:

#define _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF    \
{"load_cert_chain", (PyCFunction)_ssl__SSLContext_load_cert_chain, METH_FASTCALL, _ssl__SSLContext_load_cert_chain__doc__}

static PyObject *
_ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
{
[...]
return_value = _ssl__SSLContext_load_cert_chain_impl(self, certfile, keyfile, password);
}

并且它作为方法显式添加到 Modules/_ssl.c 中的 _SSLContext 类:

static struct PyMethodDef context_methods[] = {
[...]
_SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF
[...]
{NULL, NULL} /* sentinel */
};

[...]

static PyTypeObject PySSLContext_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_ssl._SSLContext", /*tp_name*/
sizeof(PySSLContext), /*tp_basicsize*/
[...]
context_methods, /*tp_methods*/
[...]
};

因此参数 clinic 不负责将方法分配给类。这是通过围绕 _ssl__SSLContext_load_cert_chain_impl 的包装函数 _ssl__SSLContext_load_cert_chain 完成的,并使用分配给该类的 PyMethodDef 结构分配给该类。

现在您知道没有自动生成的链接,我不知道当您想要替换该功能时这是否有帮助。我不知道您如何在不重新编译 Python 或将所有相关文件复制到您的扩展中的情况下轻松地做到这一点(争论诊所或没有诊所)。

关于python - 使用 "clinic"时如何为 python 模块创建新函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41676808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com