Python 带有 ANSI 转义符的 `doctest`
Python `doctest` with ANSI escapes
我有一些代码,我有一些 doctest,例如
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'
另一种可能性是 filter out ANSI escapes 就在 print()
:
里面
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'
或 capturing 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)
我有一些代码,我有一些 doctest,例如
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'
另一种可能性是 filter out ANSI escapes 就在 print()
:
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'
或 capturing 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)