晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
| DIR:/opt/cloudlinux/venv/lib64/python3.11/site-packages/testfixtures/ |
| Current File : //opt/cloudlinux/venv/lib64/python3.11/site-packages/testfixtures/outputcapture.py |
import os
import sys
from io import StringIO
from tempfile import TemporaryFile
from testfixtures.comparison import compare
class OutputCapture(object):
"""
A context manager for capturing output to the
:any:`sys.stdout` and :any:`sys.stderr` streams.
:param separate: If ``True``, ``stdout`` and ``stderr`` will be captured
separately and their expected values must be passed to
:meth:`~OutputCapture.compare`.
:param fd: If ``True``, the underlying file descriptors will be captured,
rather than just the attributes on :mod:`sys`. This allows
you to capture things like subprocesses that write directly
to the file descriptors, but is more invasive, so only use it
when you need it.
:param strip_whitespace:
When ``True``, which is the default, leading and training whitespace
is trimmed from both the expected and actual values when comparing.
.. note:: If ``separate`` is passed as ``True``,
:attr:`OutputCapture.captured` will be an empty string.
"""
original_stdout = None
original_stderr = None
def __init__(self, separate: bool = False, fd: bool = False, strip_whitespace: bool = True):
self.separate = separate
self.fd = fd
self.strip_whitespace = strip_whitespace
def __enter__(self):
if self.fd:
self.output = TemporaryFile()
self.stdout = TemporaryFile()
self.stderr = TemporaryFile()
else:
self.output = StringIO()
self.stdout = StringIO()
self.stderr = StringIO()
self.enable()
return self
def __exit__(self, *args):
self.disable()
def disable(self):
"Disable the output capture if it is enabled."
if self.fd:
for original, current in (
(self.original_stdout, sys.stdout),
(self.original_stderr, sys.stderr),
):
os.dup2(original, current.fileno())
os.close(original)
else:
sys.stdout = self.original_stdout
sys.stderr = self.original_stderr
def enable(self):
"Enable the output capture if it is disabled."
if self.original_stdout is None:
if self.fd:
self.original_stdout = os.dup(sys.stdout.fileno())
self.original_stderr = os.dup(sys.stderr.fileno())
else:
self.original_stdout = sys.stdout
self.original_stderr = sys.stderr
if self.separate:
if self.fd:
os.dup2(self.stdout.fileno(), sys.stdout.fileno())
os.dup2(self.stderr.fileno(), sys.stderr.fileno())
else:
sys.stdout = self.stdout
sys.stderr = self.stderr
else:
if self.fd:
os.dup2(self.output.fileno(), sys.stdout.fileno())
os.dup2(self.output.fileno(), sys.stderr.fileno())
else:
sys.stdout = sys.stderr = self.output
def _read(self, stream):
if self.fd:
stream.seek(0)
return stream.read().decode()
else:
return stream.getvalue()
@property
def captured(self) -> str:
"A property containing any output that has been captured so far."
return self._read(self.output)
def compare(self, expected: str = '', stdout: str = '', stderr: str = ''):
"""
Compare the captured output to that expected. If the output is
not the same, an :class:`AssertionError` will be raised.
:param expected: A string containing the expected combined output
of ``stdout`` and ``stderr``.
:param stdout: A string containing the expected output to ``stdout``.
:param stderr: A string containing the expected output to ``stderr``.
"""
expected_mapping = {}
actual_mapping = {}
for prefix, _expected, captured in (
('captured', expected, self.captured),
('stdout', stdout, self._read(self.stdout)),
('stderr', stderr, self._read(self.stderr)),
):
if self.strip_whitespace:
_expected = _expected.strip()
captured = captured.strip()
if _expected != captured:
expected_mapping[prefix] = _expected
actual_mapping[prefix] = captured
if len(expected_mapping) == 1:
compare(expected=tuple(expected_mapping.values())[0],
actual=tuple(actual_mapping.values())[0])
compare(expected=expected_mapping, actual=actual_mapping)
|