【问题标题】:How can I make doctests triggered by pytest ignore unicode prefix `u'...'` of strings?如何使由 pytest 触发的 doctest 忽略字符串的 unicode 前缀 `u'...'`?
【发布时间】:2017-09-28 09:17:36
【问题描述】:

我希望我的代码在 Python 2 和 3 中工作。我使用 doctest 和

from __future__ import unicode_literals

是否有一个我可以设置的标志/一个插件使它忽略 Python 2 具有用于 unicode 字符串的 u 前缀?

示例

一个测试在 Python 3 中有效,但在 Python 2 中失败:

Expected:
    'Me \\& you.'
Got:
    u'Me \\& you.'

小例子

from __future__ import unicode_literals


def foo():
    """

    Returns
    -------
    unicode - for Python 2 and Python 3

    Examples
    --------
    >>> foo()
    'bar'
    """
    return 'bar'


if __name__ == '__main__':
    import doctest
    doctest.testmod()

【问题讨论】:

  • 在这种情况下,问题可能不是“u 前缀”,而是 "..." 与 @987654327 的 type 不同@。比较失败,因为您正在针对 unicode 值测试 str 值。
  • 因为 u"Me \\& you." 而不是 u'Me \\& you.' 也失败了,我很确定 doctests 会直接比较字符串。
  • 请提供一个最小的例子来重现这个问题。
  • 好吧,unicode_literals 意味着隐含的所有文字都是 u'' 文字。我想这不适用于 doctest,因为在 docstring 中写入的值不是文字(它是文字中的文字)并且 doctest 不考虑导入的unicode_literals。如果您将预期值声明为u'bar',它会起作用。
  • @deceze 不,将预期值声明为u'bar' 是行不通的。问题是我希望它像我在问题的第一句话中所写的那样在 Python 2 和 3 上运行。

标签: python-2.7 unicode pytest doctest


【解决方案1】:

如果您直接使用 doctest,则可以按照 Dirkjan Ochtman 的博文 Single-source Python 2/3 doctests 覆盖 OutputChecker:

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)

doctest.DocTestSuite(mod, checker=Py23DocChecker())

如果你使用 py.test,你可以在 pytest.ini 中指定doctest_optionflags = ALLOW_UNICODE。见https://docs.pytest.org/en/latest/doctest.html

【讨论】:

    猜你喜欢
    • 2019-05-30
    • 2010-10-20
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 2019-08-03
    相关资源
    最近更新 更多