【问题标题】:Doctest fails due to unicode leading u由于 unicode 领先 u,Doctest 失败
【发布时间】:2023-09-10 13:16:01
【问题描述】:

我正在为一个输出标记化单词列表的函数编写一个文档测试。

r'''

>>> s = "This is a tokenized sentence s\u00f3"
>>> tokenizer.tokenize(s0)
['This', 'is', 'a', 'tokenized', 'sentence', 'só']

'''

使用 Python3.4 我的测试顺利通过。

使用 Python2.7 我得到:

Expected:
  ['This', 'is', 'a', 'tokenized', 'sentence', 'só']
Got:
  [u'This', u'is', u'a', u'tokenized', u'sentence', u's\xf3']

我的代码必须同时适用于 Python3.4 和 Python2.7。我该如何解决这个问题?

【问题讨论】:

  • 测试unicode 名称并相应地调整您的测试(如果已定义)?由于这些脆弱性,从不喜欢 doctest。
  • 你可以找到一个例子来做到这一点here
  • 看到这个答案*.com/questions/3627793/…
  • 最简单的方法是把test改成>>> tokenizer.tokenizer(s0) == [...]\nTrue

标签: python unicode portability doctest


【解决方案1】:

Python 3 对 Unicode 对象使用不同的字符串文字。没有 u 前缀(在规范表示中)并且一些非 ascii 字符按字面显示,例如,'só' 是 Python 3 中的 Unicode 字符串(如果您在输出中看到它,它是 Python 2 上的字节字符串) .

如果您感兴趣的是函数如何将输入文本拆分为标记;您可以在单独的行上打印每个标记,以使结果与 Python 2/3 兼容:

print("\n".join(tokenizer.tokenize(s0)))
This
is
a
tokenized
sentence
só

您也可以customize doctest.OutputChecker,例如:

#!/usr/bin/env python
r"""
>>> u"This is a tokenized sentence s\u00f3".split()
[u'This', u'is', u'a', u'tokenized', u'sentence', u's\xf3']
"""
import doctest
import re
import sys

class Py23DocChecker(doctest.OutputChecker):
    def check_output(self, want, got, optionflags):
        if sys.version_info[0] > 2:
            want = re.sub("u'(.*?)'", "'\\1'", want)
            want = re.sub('u"(.*?)"', '"\\1"', want)
        return doctest.OutputChecker.check_output(self, want, got, optionflags)

if __name__ == "__main__":
    import unittest

    suite = doctest.DocTestSuite(sys.modules['__main__'], checker=Py23DocChecker())
    sys.exit(len(unittest.TextTestRunner().run(suite).failures))

【讨论】: