簡體   English   中英

帶有ANSI轉義的Python`doctest`

[英]Python `doctest` with ANSI escapes

我有一些我有一些文檔測試的代碼,例如

def foo(x):
    """
    Examples:
        >>> s = foo()
        >>> print(repr(s))
        '\x1b[0;35mfoo\x1b[0m \x1b[0;36mbar\x1b[0m'
        >>> print(s)
        foo bar
    """
    return '\u001b[0;35mfoo\u001b[0m \u001b[0;36mbar\u001b[0m'

當然,在支持ANSI轉義的終端中,最后的print()實際上是彩色的。

但是,如果我在此處運行doctest ,則測試將失敗。 我該如何解決?

我希望有一種插入ANSI轉義的方法,或者最好是有一個doctest指令來忽略它們,但是我在docs中找不到與此有關的任何信息。

一個愚蠢的解決方法是使用代碼內比較而不是依賴doctests比較,例如:

def foo(x):
    """
    Examples:
        >>> s = foo()
        >>> print(repr(s))
        '\x1b[0;35mfoo\x1b[0m \x1b[0;36mbar\x1b[0m'
        >>> print(s == '\x1b[0;35mfoo\x1b[0m \x1b[0;36mbar\x1b[0m')
        True
    """
    return '\u001b[0;35mfoo\u001b[0m \u001b[0;36mbar\u001b[0m'

另一種可能性是在print()內部過濾掉ANSI轉義

import re


def remove_ansi_escapes(text):
    ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
    return ansi_escape.sub('', text)


def foo(x):
    """
    Examples:
        >>> s = foo()
        >>> print(repr(s))
        '\x1b[0;35mfoo\x1b[0m \x1b[0;36mbar\x1b[0m'
        >>> print(remove_ansi_escapes(s))
        foo bar
    """
    return '\u001b[0;35mfoo\u001b[0m \u001b[0;36mbar\u001b[0m'

或通過捕獲STDOUT如果打印在代碼中進行得更深):

from contextlib import redirect_stdout
import io


def foo(x):
    """
    Examples:
        >>> buffer = io.StringIO()
        >>> with redirect_stdout(buffer):
        ...     foo()
        >>> print(remove_ansi_escapes(buffer.getvalue()))
        foo bar
    """
    s = '\u001b[0;35mfoo\u001b[0m \u001b[0;36mbar\u001b[0m'
    print(s)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM