u# 格式字符从 Python 3.12 C-API 中删除,如何解释?

问题描述 投票:0回答:1

Python 3.12 C-API 中删除了一堆与 unicode 相关的功能。对我来说不幸的是,我们的库中有一段非常旧的代码(~2010)使用这些代码,我需要以某种方式将此功能迁移到 3.12,因为我们希望最终升级到 3.12。我特别纠结的一件事是删除

u#
参数。以下代码将解析传递给
foo
的任何位置参数(包括 unicode 字符串),并将它们存储在
input
中:

static PyObject *
foo(PyObject *self, PyObject *args) {
    Py_UNICODE *input;
    Py_ssize_t length;
    
    if (!PyArg_ParseTuple(args, "u#", &input, &length)) {
        return NULL;
    }
    ...
}

但是,根据 docs

u#
已被删除:

在版本 3.12 中进行了更改:删除了

u
u#
Z
Z#
,因为它们使用了旧版 Py_UNICODE* 表示形式。

当在纯 python 中编译和使用当前代码时,只会抛出类似

bad-format-character
的内容。

Py_UNICODE
只是
wchar_t
所以很容易修复。但是随着
u#
的删除,我不确定如何让
PyArg_ParseTuple
接受 unicode 输入参数。使用
s#
代替
u#
不起作用,因为它不能处理任何宽字符。如何在 Python 3.12 中迁移此调用?

python python-c-api
1个回答
0
投票

s#
可以很好地处理 Unicode,但它为您提供 UTF-8 而不是
wchar_t
。如果您特别需要 wchar 表示形式,可以使用
PyUnicode_AsWideCharString
:

从字符串对象中获取一个 wchar 表示形式
Py_ssize_t size;
wchar_t *wchar_representation = PyUnicode_AsWideCharString(stringobj, &size);

if (!wchar_representation) {
    // error occurred. do something about that.
}

// do stuff with wchar_representation, then once you're done,

PyMem_Free(wchar_representation);

与旧的

Py_UNICODE
API 不同,这会分配一个新的缓冲区,当您使用完它后,您必须使用
PyMem_Free
释放它。

© www.soinside.com 2019 - 2024. All rights reserved.