]> granicus.if.org Git - python/commitdiff
fix pydoc.apropos and pydoc.synopsis on modules with empty docstrings (#21548)
authorBenjamin Peterson <benjamin@python.org>
Tue, 17 Feb 2015 00:45:01 +0000 (19:45 -0500)
committerBenjamin Peterson <benjamin@python.org>
Tue, 17 Feb 2015 00:45:01 +0000 (19:45 -0500)
Patch by Yuyang Guo and Berker Peksag.

Lib/pydoc.py
Lib/test/test_pydoc.py
Misc/ACKS
Misc/NEWS

index d53a1b4b7eb72b40ccc8a7ff58f8f8f28e709851..d37ebf12db70b146342056fe4c7e0cf89b010808 100755 (executable)
@@ -270,7 +270,7 @@ def synopsis(filename, cache={}):
             except:
                 return None
             del sys.modules['__temp__']
-            result = (module.__doc__ or '').splitlines()[0]
+            result = module.__doc__.splitlines()[0] if module.__doc__ else None
         # Cache the result.
         cache[filename] = (mtime, result)
     return result
@@ -2075,7 +2075,7 @@ class ModuleScanner:
                         if onerror:
                             onerror(modname)
                         continue
-                    desc = (module.__doc__ or '').splitlines()[0]
+                    desc = module.__doc__.splitlines()[0] if module.__doc__ else ''
                     path = getattr(module,'__file__',None)
                 name = modname + ' - ' + desc
                 if name.lower().find(key) >= 0:
index 8bf9b20ce91bf957abeddd822fd6295c6639c98c..1427c77fb1b15f4c0a140aa458accd8f7789c196 100644 (file)
@@ -3,12 +3,15 @@ import sys
 import builtins
 import contextlib
 import difflib
+import importlib.util
 import inspect
 import pydoc
+import py_compile
 import keyword
 import _pickle
 import pkgutil
 import re
+import stat
 import string
 import test.support
 import time
@@ -557,6 +560,18 @@ class PydocDocTest(unittest.TestCase):
 
         self.assertEqual(synopsis, expected)
 
+    def test_synopsis_sourceless_empty_doc(self):
+        with test.support.temp_cwd() as test_dir:
+            init_path = os.path.join(test_dir, 'foomod42.py')
+            cached_path = importlib.util.cache_from_source(init_path)
+            with open(init_path, 'w') as fobj:
+                fobj.write("foo = 1")
+            py_compile.compile(init_path)
+            synopsis = pydoc.synopsis(init_path, {})
+            self.assertIsNone(synopsis)
+            synopsis_cached = pydoc.synopsis(cached_path, {})
+            self.assertIsNone(synopsis_cached)
+
     def test_splitdoc_with_description(self):
         example_string = "I Am A Doc\n\n\nHere is my description"
         self.assertEqual(pydoc.splitdoc(example_string),
@@ -612,6 +627,7 @@ class PydocImportTest(PydocBaseTest):
     def setUp(self):
         self.test_dir = os.mkdir(TESTFN)
         self.addCleanup(rmtree, TESTFN)
+        importlib.invalidate_caches()
 
     def test_badimport(self):
         # This tests the fix for issue 5230, where if pydoc found the module
@@ -670,6 +686,22 @@ class PydocImportTest(PydocBaseTest):
         self.assertEqual(out.getvalue(), '')
         self.assertEqual(err.getvalue(), '')
 
+    def test_apropos_empty_doc(self):
+        pkgdir = os.path.join(TESTFN, 'walkpkg')
+        os.mkdir(pkgdir)
+        self.addCleanup(rmtree, pkgdir)
+        init_path = os.path.join(pkgdir, '__init__.py')
+        with open(init_path, 'w') as fobj:
+            fobj.write("foo = 1")
+        current_mode = stat.S_IMODE(os.stat(pkgdir).st_mode)
+        try:
+            os.chmod(pkgdir, current_mode & ~stat.S_IEXEC)
+            with self.restrict_walk_packages(path=[TESTFN]), captured_stdout() as stdout:
+                pydoc.apropos('')
+            self.assertIn('walkpkg', stdout.getvalue())
+        finally:
+            os.chmod(pkgdir, current_mode)
+
     @unittest.skip('causes undesireable side-effects (#20128)')
     def test_modules(self):
         # See Helper.listmodules().
index 65518db0d848877f4df005122b5facbc89053108..71f40483813c937ca061b4f412b892222e89024f 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -506,6 +506,7 @@ Eric Groo
 Dag Gruneau
 Filip Gruszczyński
 Thomas Guettler
+Yuyang Guo
 Anuj Gupta
 Michael Guravage
 Lars Gustäbel
index b453fe458d2f8af96d4761628f9224e2f4f3d1f6..3f50594e6a1ecbf43404670b8b7c71796024582c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #21548: Fix pydoc.synopsis() and pydoc.apropos() on modules with empty
+  docstrings.
+
 - Issue #22885: Fixed arbitrary code execution vulnerability in the dbm.dumb
   module.  Original patch by Claudiu Popa.