mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
[3.12] gh-108303: Move all doctest related files and tests to Lib/test/test_doctest/ (GH-112109) (#114254)
gh-108303: Move all doctest related files and tests to `Lib/test/test_doctest/` (GH-112109)
(cherry picked from commit 9c93350f58)
Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
Co-authored-by: Brett Cannon <brett@python.org>
This commit is contained in:
parent
6d23b32374
commit
a76d0104d7
18 changed files with 153 additions and 117 deletions
|
|
@ -134,7 +134,7 @@ That's all you need to know to start making productive use of :mod:`doctest`!
|
|||
Jump in. The following sections provide full details. Note that there are many
|
||||
examples of doctests in the standard Python test suite and libraries.
|
||||
Especially useful examples can be found in the standard test file
|
||||
:file:`Lib/test/test_doctest.py`.
|
||||
:file:`Lib/test/test_doctest/test_doctest.py`.
|
||||
|
||||
|
||||
.. _doctest-simple-testmod:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
SPLITTESTDIRS: set[TestName] = {
|
||||
"test_asyncio",
|
||||
"test_concurrent_futures",
|
||||
"test_doctests",
|
||||
"test_future_stmt",
|
||||
"test_gdb",
|
||||
"test_inspect",
|
||||
|
|
|
|||
|
|
@ -58,3 +58,23 @@ def terminate(proc):
|
|||
input = b"" # Stop writing
|
||||
if not input:
|
||||
sel.modify(master, selectors.EVENT_READ)
|
||||
|
||||
|
||||
######################################################################
|
||||
## Fake stdin (for testing interactive debugging)
|
||||
######################################################################
|
||||
|
||||
class FakeInput:
|
||||
"""
|
||||
A fake input stream for pdb's interactive debugger. Whenever a
|
||||
line is read, print it (to simulate the user typing it), and then
|
||||
return it. The set of lines to return is specified in the
|
||||
constructor; they should not have trailing newlines.
|
||||
"""
|
||||
def __init__(self, lines):
|
||||
self.lines = lines
|
||||
|
||||
def readline(self):
|
||||
line = self.lines.pop(0)
|
||||
print(line)
|
||||
return line + '\n'
|
||||
|
|
|
|||
5
Lib/test/test_doctest/__init__.py
Normal file
5
Lib/test/test_doctest/__init__.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import os
|
||||
from test.support import load_package_tests
|
||||
|
||||
def load_tests(*args):
|
||||
return load_package_tests(os.path.dirname(__file__), *args)
|
||||
|
|
@ -32,8 +32,8 @@ def bar():
|
|||
def test_silly_setup():
|
||||
"""
|
||||
|
||||
>>> import test.test_doctest
|
||||
>>> test.test_doctest.sillySetup
|
||||
>>> import test.test_doctest.test_doctest
|
||||
>>> test.test_doctest.test_doctest.sillySetup
|
||||
True
|
||||
"""
|
||||
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support.pty_helper import FakeInput # used in doctests
|
||||
import doctest
|
||||
import functools
|
||||
import os
|
||||
|
|
@ -77,6 +78,15 @@ def get(self):
|
|||
"""
|
||||
return self.val
|
||||
|
||||
def setter(self, val):
|
||||
"""
|
||||
>>> s = SampleClass(-5)
|
||||
>>> s.setter(1)
|
||||
>>> print(s.val)
|
||||
1
|
||||
"""
|
||||
self.val = val
|
||||
|
||||
def a_staticmethod(v):
|
||||
"""
|
||||
>>> print(SampleClass.a_staticmethod(10))
|
||||
|
|
@ -95,7 +105,7 @@ def a_classmethod(cls, v):
|
|||
return v+2
|
||||
a_classmethod = classmethod(a_classmethod)
|
||||
|
||||
a_property = property(get, doc="""
|
||||
a_property = property(get, setter, doc="""
|
||||
>>> print(SampleClass(22).a_property)
|
||||
22
|
||||
""")
|
||||
|
|
@ -157,25 +167,6 @@ def get(self):
|
|||
"""
|
||||
return self.val
|
||||
|
||||
######################################################################
|
||||
## Fake stdin (for testing interactive debugging)
|
||||
######################################################################
|
||||
|
||||
class _FakeInput:
|
||||
"""
|
||||
A fake input stream for pdb's interactive debugger. Whenever a
|
||||
line is read, print it (to simulate the user typing it), and then
|
||||
return it. The set of lines to return is specified in the
|
||||
constructor; they should not have trailing newlines.
|
||||
"""
|
||||
def __init__(self, lines):
|
||||
self.lines = lines
|
||||
|
||||
def readline(self):
|
||||
line = self.lines.pop(0)
|
||||
print(line)
|
||||
return line+'\n'
|
||||
|
||||
######################################################################
|
||||
## Test Cases
|
||||
######################################################################
|
||||
|
|
@ -469,14 +460,14 @@ def basics(): r"""
|
|||
|
||||
We'll simulate a __file__ attr that ends in pyc:
|
||||
|
||||
>>> import test.test_doctest
|
||||
>>> old = test.test_doctest.__file__
|
||||
>>> test.test_doctest.__file__ = 'test_doctest.pyc'
|
||||
>>> from test.test_doctest import test_doctest
|
||||
>>> old = test_doctest.__file__
|
||||
>>> test_doctest.__file__ = 'test_doctest.pyc'
|
||||
|
||||
>>> tests = finder.find(sample_func)
|
||||
|
||||
>>> print(tests) # doctest: +ELLIPSIS
|
||||
[<DocTest sample_func from test_doctest.py:32 (1 example)>]
|
||||
[<DocTest sample_func from test_doctest.py:33 (1 example)>]
|
||||
|
||||
The exact name depends on how test_doctest was invoked, so allow for
|
||||
leading path components.
|
||||
|
|
@ -484,7 +475,7 @@ def basics(): r"""
|
|||
>>> tests[0].filename # doctest: +ELLIPSIS
|
||||
'...test_doctest.py'
|
||||
|
||||
>>> test.test_doctest.__file__ = old
|
||||
>>> test_doctest.__file__ = old
|
||||
|
||||
|
||||
>>> e = tests[0].examples[0]
|
||||
|
|
@ -538,6 +529,7 @@ def basics(): r"""
|
|||
1 SampleClass.a_staticmethod
|
||||
1 SampleClass.double
|
||||
1 SampleClass.get
|
||||
3 SampleClass.setter
|
||||
|
||||
New-style classes are also supported:
|
||||
|
||||
|
|
@ -577,10 +569,10 @@ def basics(): r"""
|
|||
... 'c': triple}})
|
||||
|
||||
>>> finder = doctest.DocTestFinder()
|
||||
>>> # Use module=test.test_doctest, to prevent doctest from
|
||||
>>> # Use module=test_doctest, to prevent doctest from
|
||||
>>> # ignoring the objects since they weren't defined in m.
|
||||
>>> import test.test_doctest
|
||||
>>> tests = finder.find(m, module=test.test_doctest)
|
||||
>>> from test.test_doctest import test_doctest
|
||||
>>> tests = finder.find(m, module=test_doctest)
|
||||
>>> for t in tests:
|
||||
... print('%2s %s' % (len(t.examples), t.name))
|
||||
1 some_module
|
||||
|
|
@ -594,23 +586,38 @@ def basics(): r"""
|
|||
1 some_module.SampleClass.a_staticmethod
|
||||
1 some_module.SampleClass.double
|
||||
1 some_module.SampleClass.get
|
||||
3 some_module.SampleClass.setter
|
||||
1 some_module.__test__.c
|
||||
2 some_module.__test__.d
|
||||
1 some_module.sample_func
|
||||
|
||||
However, doctest will ignore imported objects from other modules
|
||||
(without proper `module=`):
|
||||
|
||||
>>> import types
|
||||
>>> m = types.ModuleType('poluted_namespace')
|
||||
>>> m.__dict__.update({
|
||||
... 'sample_func': sample_func,
|
||||
... 'SampleClass': SampleClass,
|
||||
... })
|
||||
|
||||
>>> finder = doctest.DocTestFinder()
|
||||
>>> finder.find(m)
|
||||
[]
|
||||
|
||||
Duplicate Removal
|
||||
~~~~~~~~~~~~~~~~~
|
||||
If a single object is listed twice (under different names), then tests
|
||||
will only be generated for it once:
|
||||
|
||||
>>> from test import doctest_aliases
|
||||
>>> from test.test_doctest import doctest_aliases
|
||||
>>> assert doctest_aliases.TwoNames.f
|
||||
>>> assert doctest_aliases.TwoNames.g
|
||||
>>> tests = excl_empty_finder.find(doctest_aliases)
|
||||
>>> print(len(tests))
|
||||
2
|
||||
>>> print(tests[0].name)
|
||||
test.doctest_aliases.TwoNames
|
||||
test.test_doctest.doctest_aliases.TwoNames
|
||||
|
||||
TwoNames.f and TwoNames.g are bound to the same object.
|
||||
We can't guess which will be found in doctest's traversal of
|
||||
|
|
@ -636,6 +643,7 @@ def basics(): r"""
|
|||
1 SampleClass.a_staticmethod
|
||||
1 SampleClass.double
|
||||
1 SampleClass.get
|
||||
3 SampleClass.setter
|
||||
|
||||
By default, that excluded objects with no doctests. exclude_empty=False
|
||||
tells it to include (empty) tests for objects with no doctests. This feature
|
||||
|
|
@ -657,28 +665,29 @@ def basics(): r"""
|
|||
1 SampleClass.a_staticmethod
|
||||
1 SampleClass.double
|
||||
1 SampleClass.get
|
||||
3 SampleClass.setter
|
||||
|
||||
When used with `exclude_empty=False` we are also interested in line numbers
|
||||
of doctests that are empty.
|
||||
It used to be broken for quite some time until `bpo-28249`.
|
||||
|
||||
>>> from test import doctest_lineno
|
||||
>>> from test.test_doctest import doctest_lineno
|
||||
>>> tests = doctest.DocTestFinder(exclude_empty=False).find(doctest_lineno)
|
||||
>>> for t in tests:
|
||||
... print('%5s %s' % (t.lineno, t.name))
|
||||
None test.doctest_lineno
|
||||
22 test.doctest_lineno.ClassWithDocstring
|
||||
30 test.doctest_lineno.ClassWithDoctest
|
||||
None test.doctest_lineno.ClassWithoutDocstring
|
||||
None test.doctest_lineno.MethodWrapper
|
||||
53 test.doctest_lineno.MethodWrapper.classmethod_with_doctest
|
||||
39 test.doctest_lineno.MethodWrapper.method_with_docstring
|
||||
45 test.doctest_lineno.MethodWrapper.method_with_doctest
|
||||
None test.doctest_lineno.MethodWrapper.method_without_docstring
|
||||
61 test.doctest_lineno.MethodWrapper.property_with_doctest
|
||||
4 test.doctest_lineno.func_with_docstring
|
||||
12 test.doctest_lineno.func_with_doctest
|
||||
None test.doctest_lineno.func_without_docstring
|
||||
None test.test_doctest.doctest_lineno
|
||||
22 test.test_doctest.doctest_lineno.ClassWithDocstring
|
||||
30 test.test_doctest.doctest_lineno.ClassWithDoctest
|
||||
None test.test_doctest.doctest_lineno.ClassWithoutDocstring
|
||||
None test.test_doctest.doctest_lineno.MethodWrapper
|
||||
53 test.test_doctest.doctest_lineno.MethodWrapper.classmethod_with_doctest
|
||||
39 test.test_doctest.doctest_lineno.MethodWrapper.method_with_docstring
|
||||
45 test.test_doctest.doctest_lineno.MethodWrapper.method_with_doctest
|
||||
None test.test_doctest.doctest_lineno.MethodWrapper.method_without_docstring
|
||||
61 test.test_doctest.doctest_lineno.MethodWrapper.property_with_doctest
|
||||
4 test.test_doctest.doctest_lineno.func_with_docstring
|
||||
12 test.test_doctest.doctest_lineno.func_with_doctest
|
||||
None test.test_doctest.doctest_lineno.func_without_docstring
|
||||
|
||||
Turning off Recursion
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -1893,9 +1902,9 @@ def test_testsource(): r"""
|
|||
example code is converted to regular Python code. The surrounding
|
||||
words and expected output are converted to comments:
|
||||
|
||||
>>> import test.test_doctest
|
||||
>>> name = 'test.test_doctest.sample_func'
|
||||
>>> print(doctest.testsource(test.test_doctest, name))
|
||||
>>> from test.test_doctest import test_doctest
|
||||
>>> name = 'test.test_doctest.test_doctest.sample_func'
|
||||
>>> print(doctest.testsource(test_doctest, name))
|
||||
# Blah blah
|
||||
#
|
||||
print(sample_func(22))
|
||||
|
|
@ -1905,8 +1914,8 @@ def test_testsource(): r"""
|
|||
# Yee ha!
|
||||
<BLANKLINE>
|
||||
|
||||
>>> name = 'test.test_doctest.SampleNewStyleClass'
|
||||
>>> print(doctest.testsource(test.test_doctest, name))
|
||||
>>> name = 'test.test_doctest.test_doctest.SampleNewStyleClass'
|
||||
>>> print(doctest.testsource(test_doctest, name))
|
||||
print('1\n2\n3')
|
||||
# Expected:
|
||||
## 1
|
||||
|
|
@ -1914,8 +1923,8 @@ def test_testsource(): r"""
|
|||
## 3
|
||||
<BLANKLINE>
|
||||
|
||||
>>> name = 'test.test_doctest.SampleClass.a_classmethod'
|
||||
>>> print(doctest.testsource(test.test_doctest, name))
|
||||
>>> name = 'test.test_doctest.test_doctest.SampleClass.a_classmethod'
|
||||
>>> print(doctest.testsource(test_doctest, name))
|
||||
print(SampleClass.a_classmethod(10))
|
||||
# Expected:
|
||||
## 12
|
||||
|
|
@ -1938,7 +1947,7 @@ def test_debug(): r"""
|
|||
Create some fake stdin input, to feed to the debugger:
|
||||
|
||||
>>> real_stdin = sys.stdin
|
||||
>>> sys.stdin = _FakeInput(['next', 'print(x)', 'continue'])
|
||||
>>> sys.stdin = FakeInput(['next', 'print(x)', 'continue'])
|
||||
|
||||
Run the debugger on the docstring, and then restore sys.stdin.
|
||||
|
||||
|
|
@ -1981,7 +1990,7 @@ def test_pdb_set_trace():
|
|||
captures our debugger input:
|
||||
|
||||
>>> real_stdin = sys.stdin
|
||||
>>> sys.stdin = _FakeInput([
|
||||
>>> sys.stdin = FakeInput([
|
||||
... 'print(x)', # print data defined by the example
|
||||
... 'continue', # stop debugging
|
||||
... ''])
|
||||
|
|
@ -2008,7 +2017,7 @@ def test_pdb_set_trace():
|
|||
... '''
|
||||
>>> test = parser.get_doctest(doc, globals(), "foo-bar@baz", "foo-bar@baz.py", 0)
|
||||
>>> real_stdin = sys.stdin
|
||||
>>> sys.stdin = _FakeInput([
|
||||
>>> sys.stdin = FakeInput([
|
||||
... 'print(y)', # print data defined in the function
|
||||
... 'up', # out of function
|
||||
... 'print(x)', # print data defined by the example
|
||||
|
|
@ -2020,7 +2029,7 @@ def test_pdb_set_trace():
|
|||
... finally:
|
||||
... sys.stdin = real_stdin
|
||||
--Return--
|
||||
> <doctest test.test_doctest.test_pdb_set_trace[7]>(3)calls_set_trace()->None
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace[7]>(3)calls_set_trace()->None
|
||||
-> import pdb; pdb.set_trace()
|
||||
(Pdb) print(y)
|
||||
2
|
||||
|
|
@ -2045,7 +2054,7 @@ def test_pdb_set_trace():
|
|||
... '''
|
||||
>>> test = parser.get_doctest(doc, globals(), "foo-bar@baz", "foo-bar@baz.py", 0)
|
||||
>>> real_stdin = sys.stdin
|
||||
>>> sys.stdin = _FakeInput([
|
||||
>>> sys.stdin = FakeInput([
|
||||
... 'list', # list source from example 2
|
||||
... 'next', # return from g()
|
||||
... 'list', # list source from example 1
|
||||
|
|
@ -2117,7 +2126,7 @@ def test_pdb_set_trace_nested():
|
|||
>>> runner = doctest.DocTestRunner(verbose=False)
|
||||
>>> test = parser.get_doctest(doc, globals(), "foo-bar@baz", "foo-bar@baz.py", 0)
|
||||
>>> real_stdin = sys.stdin
|
||||
>>> sys.stdin = _FakeInput([
|
||||
>>> sys.stdin = FakeInput([
|
||||
... 'print(y)', # print data defined in the function
|
||||
... 'step', 'step', 'step', 'step', 'step', 'step', 'print(z)',
|
||||
... 'up', 'print(x)',
|
||||
|
|
@ -2131,39 +2140,39 @@ def test_pdb_set_trace_nested():
|
|||
... finally:
|
||||
... sys.stdin = real_stdin
|
||||
... # doctest: +REPORT_NDIFF
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
|
||||
-> self.f1()
|
||||
(Pdb) print(y)
|
||||
1
|
||||
(Pdb) step
|
||||
--Call--
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(7)f1()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(7)f1()
|
||||
-> def f1(self):
|
||||
(Pdb) step
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(8)f1()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(8)f1()
|
||||
-> x = 1
|
||||
(Pdb) step
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
|
||||
-> self.f2()
|
||||
(Pdb) step
|
||||
--Call--
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(11)f2()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(11)f2()
|
||||
-> def f2(self):
|
||||
(Pdb) step
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(12)f2()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(12)f2()
|
||||
-> z = 1
|
||||
(Pdb) step
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(13)f2()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(13)f2()
|
||||
-> z = 2
|
||||
(Pdb) print(z)
|
||||
1
|
||||
(Pdb) up
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
|
||||
-> self.f2()
|
||||
(Pdb) print(x)
|
||||
1
|
||||
(Pdb) up
|
||||
> <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
|
||||
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
|
||||
-> self.f1()
|
||||
(Pdb) print(y)
|
||||
1
|
||||
|
|
@ -2183,39 +2192,39 @@ def test_DocTestSuite():
|
|||
by passing a module object:
|
||||
|
||||
>>> import unittest
|
||||
>>> import test.sample_doctest
|
||||
>>> suite = doctest.DocTestSuite(test.sample_doctest)
|
||||
>>> import test.test_doctest.sample_doctest
|
||||
>>> suite = doctest.DocTestSuite(test.test_doctest.sample_doctest)
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=4>
|
||||
|
||||
We can also supply the module by name:
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest')
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest')
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=4>
|
||||
|
||||
The module need not contain any doctest examples:
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest_no_doctests')
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest_no_doctests')
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=0 errors=0 failures=0>
|
||||
|
||||
The module need not contain any docstrings either:
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest_no_docstrings')
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest_no_docstrings')
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=0 errors=0 failures=0>
|
||||
|
||||
We can use the current module:
|
||||
|
||||
>>> suite = test.sample_doctest.test_suite()
|
||||
>>> suite = test.test_doctest.sample_doctest.test_suite()
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=4>
|
||||
|
||||
We can also provide a DocTestFinder:
|
||||
|
||||
>>> finder = doctest.DocTestFinder()
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest',
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest',
|
||||
... test_finder=finder)
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=4>
|
||||
|
|
@ -2223,7 +2232,7 @@ def test_DocTestSuite():
|
|||
The DocTestFinder need not return any tests:
|
||||
|
||||
>>> finder = doctest.DocTestFinder()
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest_no_docstrings',
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest_no_docstrings',
|
||||
... test_finder=finder)
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=0 errors=0 failures=0>
|
||||
|
|
@ -2232,14 +2241,14 @@ def test_DocTestSuite():
|
|||
used instead of the module globals. Here we'll pass an empty
|
||||
globals, triggering an extra error:
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest', globs={})
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest', globs={})
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=5>
|
||||
|
||||
Alternatively, we can provide extra globals. Here we'll make an
|
||||
error go away by providing an extra global variable:
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest',
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest',
|
||||
... extraglobs={'y': 1})
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=3>
|
||||
|
|
@ -2247,7 +2256,7 @@ def test_DocTestSuite():
|
|||
You can pass option flags. Here we'll cause an extra error
|
||||
by disabling the blank-line feature:
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest',
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest',
|
||||
... optionflags=doctest.DONT_ACCEPT_BLANKLINE)
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=5>
|
||||
|
|
@ -2255,27 +2264,27 @@ def test_DocTestSuite():
|
|||
You can supply setUp and tearDown functions:
|
||||
|
||||
>>> def setUp(t):
|
||||
... import test.test_doctest
|
||||
... test.test_doctest.sillySetup = True
|
||||
... from test.test_doctest import test_doctest
|
||||
... test_doctest.sillySetup = True
|
||||
|
||||
>>> def tearDown(t):
|
||||
... import test.test_doctest
|
||||
... del test.test_doctest.sillySetup
|
||||
... from test.test_doctest import test_doctest
|
||||
... del test_doctest.sillySetup
|
||||
|
||||
Here, we installed a silly variable that the test expects:
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest',
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest',
|
||||
... setUp=setUp, tearDown=tearDown)
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=3>
|
||||
|
||||
But the tearDown restores sanity:
|
||||
|
||||
>>> import test.test_doctest
|
||||
>>> test.test_doctest.sillySetup
|
||||
>>> from test.test_doctest import test_doctest
|
||||
>>> test_doctest.sillySetup
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: module 'test.test_doctest' has no attribute 'sillySetup'
|
||||
AttributeError: module 'test.test_doctest.test_doctest' has no attribute 'sillySetup'
|
||||
|
||||
The setUp and tearDown functions are passed test objects. Here
|
||||
we'll use the setUp function to supply the missing variable y:
|
||||
|
|
@ -2283,7 +2292,7 @@ def test_DocTestSuite():
|
|||
>>> def setUp(test):
|
||||
... test.globs['y'] = 1
|
||||
|
||||
>>> suite = doctest.DocTestSuite('test.sample_doctest', setUp=setUp)
|
||||
>>> suite = doctest.DocTestSuite('test.test_doctest.sample_doctest', setUp=setUp)
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=3>
|
||||
|
||||
|
|
@ -2314,7 +2323,7 @@ def test_DocFileSuite():
|
|||
>>> suite = doctest.DocFileSuite('test_doctest.txt',
|
||||
... 'test_doctest2.txt',
|
||||
... 'test_doctest4.txt',
|
||||
... package='test')
|
||||
... package='test.test_doctest')
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=3 errors=0 failures=2>
|
||||
|
||||
|
|
@ -2330,7 +2339,7 @@ def test_DocFileSuite():
|
|||
... suite = doctest.DocFileSuite('test_doctest.txt',
|
||||
... 'test_doctest2.txt',
|
||||
... 'test_doctest4.txt',
|
||||
... package='test')
|
||||
... package='test.test_doctest')
|
||||
... suite.run(unittest.TestResult())
|
||||
... finally:
|
||||
... if added_loader:
|
||||
|
|
@ -2340,16 +2349,17 @@ def test_DocFileSuite():
|
|||
'/' should be used as a path separator. It will be converted
|
||||
to a native separator at run time:
|
||||
|
||||
>>> suite = doctest.DocFileSuite('../test/test_doctest.txt')
|
||||
>>> suite = doctest.DocFileSuite('../test_doctest/test_doctest.txt')
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=1 errors=0 failures=1>
|
||||
|
||||
If DocFileSuite is used from an interactive session, then files
|
||||
are resolved relative to the directory of sys.argv[0]:
|
||||
|
||||
>>> import types, os.path, test.test_doctest
|
||||
>>> import types, os.path
|
||||
>>> from test.test_doctest import test_doctest
|
||||
>>> save_argv = sys.argv
|
||||
>>> sys.argv = [test.test_doctest.__file__]
|
||||
>>> sys.argv = [test_doctest.__file__]
|
||||
>>> suite = doctest.DocFileSuite('test_doctest.txt',
|
||||
... package=types.ModuleType('__main__'))
|
||||
>>> sys.argv = save_argv
|
||||
|
|
@ -2359,7 +2369,7 @@ def test_DocFileSuite():
|
|||
working directory):
|
||||
|
||||
>>> # Get the absolute path of the test package.
|
||||
>>> test_doctest_path = os.path.abspath(test.test_doctest.__file__)
|
||||
>>> test_doctest_path = os.path.abspath(test_doctest.__file__)
|
||||
>>> test_pkg_path = os.path.split(test_doctest_path)[0]
|
||||
|
||||
>>> # Use it to find the absolute path of test_doctest.txt.
|
||||
|
|
@ -2399,12 +2409,12 @@ def test_DocFileSuite():
|
|||
And, you can provide setUp and tearDown functions:
|
||||
|
||||
>>> def setUp(t):
|
||||
... import test.test_doctest
|
||||
... test.test_doctest.sillySetup = True
|
||||
... from test.test_doctest import test_doctest
|
||||
... test_doctest.sillySetup = True
|
||||
|
||||
>>> def tearDown(t):
|
||||
... import test.test_doctest
|
||||
... del test.test_doctest.sillySetup
|
||||
... from test.test_doctest import test_doctest
|
||||
... del test_doctest.sillySetup
|
||||
|
||||
Here, we installed a silly variable that the test expects:
|
||||
|
||||
|
|
@ -2417,11 +2427,11 @@ def test_DocFileSuite():
|
|||
|
||||
But the tearDown restores sanity:
|
||||
|
||||
>>> import test.test_doctest
|
||||
>>> test.test_doctest.sillySetup
|
||||
>>> from test.test_doctest import test_doctest
|
||||
>>> test_doctest.sillySetup
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: module 'test.test_doctest' has no attribute 'sillySetup'
|
||||
AttributeError: module 'test.test_doctest.test_doctest' has no attribute 'sillySetup'
|
||||
|
||||
The setUp and tearDown functions are passed test objects.
|
||||
Here, we'll use a setUp function to set the favorite color in
|
||||
|
|
@ -3178,8 +3188,8 @@ def test_run_doctestsuite_multiple_times():
|
|||
http://bugs.python.org/issue9736
|
||||
|
||||
>>> import unittest
|
||||
>>> import test.sample_doctest
|
||||
>>> suite = doctest.DocTestSuite(test.sample_doctest)
|
||||
>>> import test.test_doctest.sample_doctest
|
||||
>>> suite = doctest.DocTestSuite(test.test_doctest.sample_doctest)
|
||||
>>> suite.run(unittest.TestResult())
|
||||
<unittest.result.TestResult run=9 errors=0 failures=4>
|
||||
>>> suite.run(unittest.TestResult())
|
||||
|
|
@ -3356,4 +3366,4 @@ def load_tests(loader, tests, pattern):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(module='test.test_doctest')
|
||||
unittest.main(module='test.test_doctest.test_doctest')
|
||||
|
|
@ -2,8 +2,8 @@ This is a sample doctest in a text file.
|
|||
|
||||
In this example, we'll rely on some silly setup:
|
||||
|
||||
>>> import test.test_doctest
|
||||
>>> test.test_doctest.sillySetup
|
||||
>>> import test.test_doctest.test_doctest
|
||||
>>> test.test_doctest.test_doctest.sillySetup
|
||||
True
|
||||
|
||||
This test also has some (random) encoded (utf-8) unicode text:
|
||||
|
|
@ -16,9 +16,7 @@
|
|||
from test import support
|
||||
from test.support import os_helper
|
||||
from test.support.import_helper import import_module
|
||||
from test.support.pty_helper import run_pty
|
||||
# This little helper class is essential for testing pdb under doctest.
|
||||
from test.test_doctest import _FakeInput
|
||||
from test.support.pty_helper import run_pty, FakeInput
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
|
|
@ -30,7 +28,7 @@ def __init__(self, input):
|
|||
|
||||
def __enter__(self):
|
||||
self.real_stdin = sys.stdin
|
||||
sys.stdin = _FakeInput(self.input)
|
||||
sys.stdin = FakeInput(self.input)
|
||||
self.orig_trace = sys.gettrace() if hasattr(sys, 'gettrace') else None
|
||||
|
||||
def __exit__(self, *exc):
|
||||
|
|
|
|||
|
|
@ -29,8 +29,9 @@
|
|||
# test_cmd_line_script (covers the zipimport support in runpy)
|
||||
|
||||
# Retrieve some helpers from other test cases
|
||||
from test import (test_doctest, sample_doctest, sample_doctest_no_doctests,
|
||||
sample_doctest_no_docstrings)
|
||||
from test.test_doctest import (test_doctest,
|
||||
sample_doctest, sample_doctest_no_doctests,
|
||||
sample_doctest_no_docstrings)
|
||||
|
||||
|
||||
def _run_object_doctest(obj, module):
|
||||
|
|
@ -100,18 +101,18 @@ def test_doctest_issue4197(self):
|
|||
# everything still works correctly
|
||||
test_src = inspect.getsource(test_doctest)
|
||||
test_src = test_src.replace(
|
||||
"from test import test_doctest",
|
||||
"from test.test_doctest import test_doctest",
|
||||
"import test_zipped_doctest as test_doctest")
|
||||
test_src = test_src.replace("test.test_doctest",
|
||||
test_src = test_src.replace("test.test_doctest.test_doctest",
|
||||
"test_zipped_doctest")
|
||||
test_src = test_src.replace("test.sample_doctest",
|
||||
test_src = test_src.replace("test.test_doctest.sample_doctest",
|
||||
"sample_zipped_doctest")
|
||||
# The sample doctest files rewritten to include in the zipped version.
|
||||
sample_sources = {}
|
||||
for mod in [sample_doctest, sample_doctest_no_doctests,
|
||||
sample_doctest_no_docstrings]:
|
||||
src = inspect.getsource(mod)
|
||||
src = src.replace("test.test_doctest", "test_zipped_doctest")
|
||||
src = src.replace("test.test_doctest.test_doctest", "test_zipped_doctest")
|
||||
# Rewrite the module name so that, for example,
|
||||
# "test.sample_doctest" becomes "sample_zipped_doctest".
|
||||
mod_name = mod.__name__.split(".")[-1]
|
||||
|
|
|
|||
|
|
@ -2143,6 +2143,7 @@ TESTSUBDIRS= idlelib/idle_test \
|
|||
test/test_cppext \
|
||||
test/test_ctypes \
|
||||
test/test_dataclasses \
|
||||
test/test_doctest \
|
||||
test/test_email \
|
||||
test/test_email/data \
|
||||
test/test_future_stmt \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue