summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/doctest.py11
-rw-r--r--Lib/test/test_builtin.py21
-rw-r--r--Lib/test/test_doctest.py29
3 files changed, 40 insertions, 21 deletions
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 7836fd2..ee4e068 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -918,6 +918,8 @@ class DocTestFinder:
return module is inspect.getmodule(object)
elif inspect.isfunction(object):
return module.__dict__ is object.__globals__
+ elif inspect.ismethoddescriptor(object):
+ return module.__name__ == object.__objclass__.__module__
elif inspect.isclass(object):
return module.__name__ == object.__module__
elif hasattr(object, '__module__'):
@@ -950,7 +952,7 @@ class DocTestFinder:
for valname, val in obj.__dict__.items():
valname = '%s.%s' % (name, valname)
# Recurse to functions & classes.
- if ((inspect.isfunction(val) or inspect.isclass(val)) and
+ if ((inspect.isroutine(val) or inspect.isclass(val)) and
self._from_module(module, val)):
self._find(tests, val, valname, module, source_lines,
globs, seen)
@@ -962,9 +964,8 @@ class DocTestFinder:
raise ValueError("DocTestFinder.find: __test__ keys "
"must be strings: %r" %
(type(valname),))
- if not (inspect.isfunction(val) or inspect.isclass(val) or
- inspect.ismethod(val) or inspect.ismodule(val) or
- isinstance(val, str)):
+ if not (inspect.isroutine(val) or inspect.isclass(val) or
+ inspect.ismodule(val) or isinstance(val, str)):
raise ValueError("DocTestFinder.find: __test__ values "
"must be strings, functions, methods, "
"classes, or modules: %r" %
@@ -983,7 +984,7 @@ class DocTestFinder:
val = getattr(obj, valname).__func__
# Recurse to methods, properties, and nested classes.
- if ((inspect.isfunction(val) or inspect.isclass(val) or
+ if ((inspect.isroutine(val) or inspect.isclass(val) or
isinstance(val, property)) and
self._from_module(module, val)):
valname = '%s.%s' % (name, valname)
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 2411c9b..6843066 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1592,21 +1592,10 @@ class TestSorted(unittest.TestCase):
data = 'The quick Brown fox Jumped over The lazy Dog'.split()
self.assertRaises(TypeError, sorted, data, None, lambda x,y: 0)
-def test_main(verbose=None):
- test_classes = (BuiltinTest, TestSorted)
-
- run_unittest(*test_classes)
-
- # verify reference counting
- if verbose and hasattr(sys, "gettotalrefcount"):
- import gc
- counts = [None] * 5
- for i in range(len(counts)):
- run_unittest(*test_classes)
- gc.collect()
- counts[i] = sys.gettotalrefcount()
- print(counts)
-
+def load_tests(loader, tests, pattern):
+ from doctest import DocTestSuite
+ tests.addTest(DocTestSuite(builtins))
+ return tests
if __name__ == "__main__":
- test_main(verbose=True)
+ unittest.main()
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index d4ff049..d99a16a 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -644,6 +644,35 @@ DocTestFinder finds the line number of each example:
>>> test = doctest.DocTestFinder().find(f)[0]
>>> [e.lineno for e in test.examples]
[1, 9, 12]
+
+Finding Doctests in Modules Not Written in Python
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+DocTestFinder can also find doctests in most modules not written in Python.
+We'll use builtins as an example, since it almost certainly isn't written in
+plain ol' Python and is guaranteed to be available.
+
+ >>> import builtins
+ >>> tests = doctest.DocTestFinder().find(builtins)
+ >>> len(tests) # how many objects checked for doctests
+ 794
+ >>> real_tests = [t for t in tests if len(t.examples) > 0]
+ >>> len(real_tests) # how many objects actually have doctests
+ 8
+ >>> for t in real_tests:
+ ... print('{} {}'.format(len(t.examples), t.name))
+ ...
+ 1 builtins.bin
+ 3 builtins.float.as_integer_ratio
+ 2 builtins.float.fromhex
+ 2 builtins.float.hex
+ 1 builtins.hex
+ 1 builtins.int
+ 2 builtins.int.bit_length
+ 1 builtins.oct
+
+Note here that 'bin', 'oct', and 'hex' are functions; 'float.as_integer_ratio',
+'float.hex', and 'int.bit_length' are methods; 'float.fromhex' is a classmethod,
+and 'int' is a type.
"""
def test_DocTestParser(): r"""