summaryrefslogtreecommitdiff
path: root/Lib/test/test_pydoc.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_pydoc.py')
-rw-r--r--Lib/test/test_pydoc.py221
1 files changed, 217 insertions, 4 deletions
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 43f4163dae..cdf28a4d3d 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -11,6 +11,7 @@ import re
import string
import test.support
import time
+import types
import unittest
import xml.etree
import textwrap
@@ -29,10 +30,6 @@ try:
except ImportError:
threading = None
-# Just in case sys.modules["test"] has the optional attribute __loader__.
-if hasattr(pydoc_mod, "__loader__"):
- del pydoc_mod.__loader__
-
if test.support.HAVE_DOCSTRINGS:
expected_data_docstrings = (
'dictionary for instance variables (if defined)',
@@ -212,6 +209,75 @@ missing_pattern = "no Python documentation found for '%s'"
# output pattern for module with bad imports
badimport_pattern = "problem in %s - ImportError: No module named %r"
+expected_dynamicattribute_pattern = """
+Help on class DA in module %s:
+
+class DA(builtins.object)
+ | Data descriptors defined here:
+ |\x20\x20
+ | __dict__%s
+ |\x20\x20
+ | __weakref__%s
+ |\x20\x20
+ | ham
+ |\x20\x20
+ | ----------------------------------------------------------------------
+ | Data and other attributes inherited from Meta:
+ |\x20\x20
+ | ham = 'spam'
+""".strip()
+
+expected_virtualattribute_pattern1 = """
+Help on class Class in module %s:
+
+class Class(builtins.object)
+ | Data and other attributes inherited from Meta:
+ |\x20\x20
+ | LIFE = 42
+""".strip()
+
+expected_virtualattribute_pattern2 = """
+Help on class Class1 in module %s:
+
+class Class1(builtins.object)
+ | Data and other attributes inherited from Meta1:
+ |\x20\x20
+ | one = 1
+""".strip()
+
+expected_virtualattribute_pattern3 = """
+Help on class Class2 in module %s:
+
+class Class2(Class1)
+ | Method resolution order:
+ | Class2
+ | Class1
+ | builtins.object
+ |\x20\x20
+ | Data and other attributes inherited from Meta1:
+ |\x20\x20
+ | one = 1
+ |\x20\x20
+ | ----------------------------------------------------------------------
+ | Data and other attributes inherited from Meta3:
+ |\x20\x20
+ | three = 3
+ |\x20\x20
+ | ----------------------------------------------------------------------
+ | Data and other attributes inherited from Meta2:
+ |\x20\x20
+ | two = 2
+""".strip()
+
+expected_missingattribute_pattern = """
+Help on class C in module %s:
+
+class C(builtins.object)
+ | Data and other attributes defined here:
+ |\x20\x20
+ | here = 'present!'
+""".strip()
+
def run_pydoc(module_name, *args, **env):
"""
Runs pydoc on the specified module. Returns the stripped
@@ -421,6 +487,31 @@ class PydocDocTest(unittest.TestCase):
synopsis = pydoc.synopsis(TESTFN, {})
self.assertEqual(synopsis, 'line 1: h\xe9')
+ def test_splitdoc_with_description(self):
+ example_string = "I Am A Doc\n\n\nHere is my description"
+ self.assertEqual(pydoc.splitdoc(example_string),
+ ('I Am A Doc', '\nHere is my description'))
+
+ def test_is_object_or_method(self):
+ doc = pydoc.Doc()
+ # Bound Method
+ self.assertTrue(pydoc._is_some_method(doc.fail))
+ # Method Descriptor
+ self.assertTrue(pydoc._is_some_method(int.__add__))
+ # String
+ self.assertFalse(pydoc._is_some_method("I am not a method"))
+
+ def test_is_package_when_not_package(self):
+ with test.support.temp_cwd() as test_dir:
+ self.assertFalse(pydoc.ispackage(test_dir))
+
+ def test_is_package_when_is_package(self):
+ with test.support.temp_cwd() as test_dir:
+ init_path = os.path.join(test_dir, '__init__.py')
+ open(init_path, 'w').close()
+ self.assertTrue(pydoc.ispackage(test_dir))
+ os.remove(init_path)
+
def test_allmethods(self):
# issue 17476: allmethods was no longer returning unbound methods.
# This test is a bit fragile in the face of changes to object and type,
@@ -615,6 +706,127 @@ class TestHelper(unittest.TestCase):
self.assertEqual(sorted(pydoc.Helper.keywords),
sorted(keyword.kwlist))
+class PydocWithMetaClasses(unittest.TestCase):
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
+ 'trace function introduces __locals__ unexpectedly')
+ def test_DynamicClassAttribute(self):
+ class Meta(type):
+ def __getattr__(self, name):
+ if name == 'ham':
+ return 'spam'
+ return super().__getattr__(name)
+ class DA(metaclass=Meta):
+ @types.DynamicClassAttribute
+ def ham(self):
+ return 'eggs'
+ expected_text_data_docstrings = tuple('\n | ' + s if s else ''
+ for s in expected_data_docstrings)
+ output = StringIO()
+ helper = pydoc.Helper(output=output)
+ helper(DA)
+ expected_text = expected_dynamicattribute_pattern % (
+ (__name__,) + expected_text_data_docstrings[:2])
+ result = output.getvalue().strip()
+ if result != expected_text:
+ print_diffs(expected_text, result)
+ self.fail("outputs are not equal, see diff above")
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
+ 'trace function introduces __locals__ unexpectedly')
+ def test_virtualClassAttributeWithOneMeta(self):
+ class Meta(type):
+ def __dir__(cls):
+ return ['__class__', '__module__', '__name__', 'LIFE']
+ def __getattr__(self, name):
+ if name =='LIFE':
+ return 42
+ return super().__getattr(name)
+ class Class(metaclass=Meta):
+ pass
+ output = StringIO()
+ helper = pydoc.Helper(output=output)
+ helper(Class)
+ expected_text = expected_virtualattribute_pattern1 % __name__
+ result = output.getvalue().strip()
+ if result != expected_text:
+ print_diffs(expected_text, result)
+ self.fail("outputs are not equal, see diff above")
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
+ 'trace function introduces __locals__ unexpectedly')
+ def test_virtualClassAttributeWithTwoMeta(self):
+ class Meta1(type):
+ def __dir__(cls):
+ return ['__class__', '__module__', '__name__', 'one']
+ def __getattr__(self, name):
+ if name =='one':
+ return 1
+ return super().__getattr__(name)
+ class Meta2(type):
+ def __dir__(cls):
+ return ['__class__', '__module__', '__name__', 'two']
+ def __getattr__(self, name):
+ if name =='two':
+ return 2
+ return super().__getattr__(name)
+ class Meta3(Meta1, Meta2):
+ def __dir__(cls):
+ return list(sorted(set(
+ ['__class__', '__module__', '__name__', 'three'] +
+ Meta1.__dir__(cls) + Meta2.__dir__(cls))))
+ def __getattr__(self, name):
+ if name =='three':
+ return 3
+ return super().__getattr__(name)
+ class Class1(metaclass=Meta1):
+ pass
+ class Class2(Class1, metaclass=Meta3):
+ pass
+ fail1 = fail2 = False
+ output = StringIO()
+ helper = pydoc.Helper(output=output)
+ helper(Class1)
+ expected_text1 = expected_virtualattribute_pattern2 % __name__
+ result1 = output.getvalue().strip()
+ if result1 != expected_text1:
+ print_diffs(expected_text1, result1)
+ fail1 = True
+ output = StringIO()
+ helper = pydoc.Helper(output=output)
+ helper(Class2)
+ expected_text2 = expected_virtualattribute_pattern3 % __name__
+ result2 = output.getvalue().strip()
+ if result2 != expected_text2:
+ print_diffs(expected_text2, result2)
+ fail2 = True
+ if fail1 or fail2:
+ self.fail("outputs are not equal, see diff above")
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(),
+ 'trace function introduces __locals__ unexpectedly')
+ def test_buggy_dir(self):
+ class M(type):
+ def __dir__(cls):
+ return ['__class__', '__name__', 'missing', 'here']
+ class C(metaclass=M):
+ here = 'present!'
+ output = StringIO()
+ helper = pydoc.Helper(output=output)
+ helper(C)
+ expected_text = expected_missingattribute_pattern % __name__
+ result = output.getvalue().strip()
+ if result != expected_text:
+ print_diffs(expected_text, result)
+ self.fail("outputs are not equal, see diff above")
+
@reap_threads
def test_main():
try:
@@ -624,6 +836,7 @@ def test_main():
PydocServerTest,
PydocUrlHandlerTest,
TestHelper,
+ PydocWithMetaClasses,
)
finally:
reap_children()