【问题标题】:Doctest not recognizing __future__.divisionDoctest 无法识别 __future__.division
【发布时间】:2016-02-28 09:18:43
【问题描述】:

我写了以下 doctest x.doctest:

This is something:

    >>> x = 3 + 4

foo bar something else:

    >>> from __future__ import division
    >>> y = 15
    >>> z = int('24')
    >>> m = z / y
    >>> print (m)
    1.6

但是当我在 python 2.7.11 上运行python -m doctest x.doctest 时,doctest 无法识别from __future__ import division

**********************************************************************
File "x.doctest", line 11, in x.doctest
Failed example:
    print (m)
Expected:
    1.6
Got:
    1
**********************************************************************
1 items had failures:
   1 of   6 in x.doctest
***Test Failed*** 1 failures.

即使我将未来的导入语句移到第一行:

This is something:

    >>> from __future__ import division
    >>> x = 3 + 4

foo bar something else:

    >>> y = 15
    >>> z = int('24')
    >>> m = z / y
    >>> print (m)
    1.6

doctest 仍然失败:

**********************************************************************
File "x.doctest", line 11, in x.doctest
Failed example:
    print (m)
Expected:
    1.6
Got:
    1
**********************************************************************
1 items had failures:
   1 of   6 in x.doctest
***Test Failed*** 1 failures.

为什么会这样,我该如何解决?

doctest 是否有一个标志/选项要求确保from __future__ import division 被识别?

注意:我可以强制检查 print (int(m))y = 15. 并且 doctest 会通过,但这并不理想。

【问题讨论】:

    标签: python future division doctest


    【解决方案1】:

    Doctests 通过 Python 编译器独立运行每一行。这意味着在 doctest 中使用from __future__ import .. 语句指定的任何编译器标志 在 doctest 中都是无用的。

    但是,您可以将真实 __future__ module 中的名称添加到您的 doctest 全局变量中。如果您使用from __future__ import <name> 格式而是使用import __future__,则导入该实际模块,并且可以将其定义的对象的引用添加到doctest globsextraglobs字典:

     if __name__ == "__main__":
         import doctest
         import __future__
         doctest.testmod(extraglobs={'division': __future__.division})
    

    然后,DocTestRunner 将在从这些行编译各个行时为您设置正确的编译器标志。

    演示:

    >>> import doctest
    >>> import __future__
    >>> import sys
    >>> def foo():
    ...     """
    ...     >>> 1 / 2
    ...     0.5
    ...     """
    ...
    >>> doctest.testmod(sys.modules['__main__'])
    **********************************************************************
    File "__main__", line 3, in __main__.foo
    Failed example:
        1 / 2
    Expected:
        0.5
    Got:
        0
    **********************************************************************
    1 items had failures:
       1 of   1 in __main__.foo
    ***Test Failed*** 1 failures.
    TestResults(failed=1, attempted=1)
    >>> doctest.testmod(sys.modules['__main__'], extraglobs={'division': __future__.division})
    TestResults(failed=0, attempted=1)
    

    【讨论】:

    • 只是为了确认一些事实,if __name__ == 'main': 技巧只能在 x.py 文件中起作用,而不是在 x.doctest 中起作用,对吗?
    • @alvas:我不熟悉.doctest 文件。我怀疑您的项目使用DocFileSuite() 实例在某处明确加载了这些;在 that 上设置全局变量。
    • @alvas:当然,加载这些文件的代码本身可以执行一些解析逻辑,以根据文件内容将编译标志添加到全局变量中。
    • 感谢 Martijn 的解释!!
    【解决方案2】:

    您可以为 Python 解释器使用选项 -Q。设置为new

    python -Qnew -m doctest x.doctest
    

    通过以下方式获取有关 Python 命令行选项的帮助:

    python -h
    

    选定的输出:

    -Q arg:除法选项:-Qold(默认)、-Qwarn、-Qwarnall、-Qnew

    更多帮助详情here

    【讨论】:

    • 谢谢,您有指向-Q 文档的链接吗?有没有办法在x.doctest 文件中添加#doctest: 评论?
    • 添加了帮助链接。我不知道有任何#doctest: 指令。在基于 Unix 的系统上,您可以在文件中添加 shebang:#!/usr/bin/env python -Qnew -m doctest 并使用 ./x.doctest 执行。
    • -Qnew 是一个全局变化,但是,甚至影响到不应该使用真正除法的代码。引入真正除法的PEP 表示-Qnew 仅适用于教师想要真正除法但不希望学生必须在所有代码中包含from __future__ import division 的教育环境。
    猜你喜欢
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 2018-06-18
    • 2013-04-19
    • 2019-01-28
    • 2017-08-10
    相关资源
    最近更新 更多