-
Notifications
You must be signed in to change notification settings - Fork 0
/
conftest.py
76 lines (55 loc) · 2.29 KB
/
conftest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# Copyright (c) 2024 t0.technology, Inc.
#
# Distributed under the terms of the BSD license. The full license is in the
# file LICENSE, distributed as part of this software.
import pytest
import IPython
import doctest
import functools
import operator
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config):
config.pluginmanager.register(DoctestRunner(), "ipythondoctestrunner")
config.pluginmanager.unregister(name="doctest")
class DoctestRunner:
def pytest_collect_file(self, file_path, parent):
if file_path.suffix == ".py":
return Module.from_parent(parent, path=file_path)
if file_path.suffix == ".rst":
return File.from_parent(parent, path=file_path)
class Module(pytest.Module):
def collect(self):
parser = doctest.DocTestParser()
finder = doctest.DocTestFinder(parser=parser)
for test in finder.find(self.obj):
yield DoctestItem.from_parent(parent=self, name=test.name, test=test)
class File(pytest.File):
def collect(self):
parser = doctest.DocTestParser()
test = parser.get_doctest(
self.fspath.read_text("utf-8"), {}, str(self.fspath), str(self.fspath), 0
)
yield DoctestItem.from_parent(parent=self, name=test.name, test=test)
class DoctestItem(pytest.Item):
def __init__(self, name, parent, test):
super().__init__(name, parent)
self.test = test
def runtest(self):
checker = doctest.OutputChecker()
shell = IPython.InteractiveShell.instance()
for example in self.test.examples:
if doctest.SKIP in example.options:
continue
with IPython.utils.capture.capture_output() as captured:
result = shell.run_cell(example.source)
optionflags = functools.reduce(
operator.or_,
example.options,
doctest.REPORT_NDIFF | doctest.ELLIPSIS,
)
if result.error_in_exec:
raise result.error_in_exec
want = example.want.strip()
got = captured.stdout.strip() if captured.stdout else ""
if not checker.check_output(want, got, optionflags):
raise AssertionError(f"Expected {want}, got {got}")