Python 无法使用 surrogateescape 进行编码

2023-12-28

我在 Python (3.4) 中遇到 Unicode 代理编码问题:

>>> b'\xCC'.decode('utf-16_be', 'surrogateescape').encode('utf-16_be', 'surrogateescape')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'utf-16-be' codec can't encode character '\udccc' in position 0: surrogates not allowed

如果我没记错的话,根据Python 文档 https://docs.python.org/3/library/codecs.html#error-handlers:

'surrogateescape':解码时,用单独的代理替换字节 代码范围从 U+DC80 到 U+DCFF。此代码将被退回 使用“surrogateescape”错误处理程序时进入同一字节 对数据进行编码时。

代码应该只生成源序列(b'\xCC')。那么为什么会引发异常呢?

这可能与我的第二个问题有关:

版本 3.4 中的更改:utf-16* 和 utf-32* 编码器不再允许对代理代码点 (U+D800–U+DFFF) 进行编码。

(From https://docs.python.org/3/library/codecs.html#standard-encodings https://docs.python.org/3/library/codecs.html#standard-encodings)

据我所知,如果没有代理对,就不可能将某些代码点编码为 UTF-16。那么这背后的原因是什么呢?


进行此更改是因为统一码标准明确禁止此类编码。看问题#12892 http://bugs.python.org/issue12892,但显然surrogateescape错误处理程序无法与 UTF-16 或 UTF-32 一起使用,因为这些编解码器与 ASCII 不兼容。

具体来说:

我测试了 utf_16_32_surrogates_4.patch: surrogateescape 作为编码器 不按预期工作。

>>> b'[\x00\x80\xdc]\x00'.decode('utf-16-le', 'ignore')
'[]'
>>> b'[\x00\x80\xdc]\x00'.decode('utf-16-le', 'replace')
'[�]'
>>> b'[\x00\x80\xdc]\x00'.decode('utf-16-le', 'surrogateescape')
'[\udc80\udcdc\uffff'

=> 我预计'[\udc80\udcdc]'.

得到的回应是:

是的,surrogateescape 不适用于 ASCII 不兼容的编码,也不能。首先,它不能代表解码的结果b'\x00\xd8'来自 utf-16-le 或b'ABCD'来自 utf-32*。这个问题值得在 Python-Dev 上单独发布(甚至 PEP)和讨论。

我相信surrogateescapehandler 更适合 UTF-8 数据;现在,解码为 UTF-16 或 UTF-32 也可以使用它,这是一个很好的额外功能,但显然它不能在另一个方向上工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 无法使用 surrogateescape 进行编码 的相关文章

随机推荐