Commit 54237f9f authored by Benjamin Peterson's avatar Benjamin Peterson

fix pydoc.apropos and pydoc.synopsis on modules with empty docstrings (#21548)

Patch by Yuyang Guo and Berker Peksag.
parent 3584056c
...@@ -270,7 +270,7 @@ def synopsis(filename, cache={}): ...@@ -270,7 +270,7 @@ def synopsis(filename, cache={}):
except: except:
return None return None
del sys.modules['__temp__'] del sys.modules['__temp__']
result = (module.__doc__ or '').splitlines()[0] result = module.__doc__.splitlines()[0] if module.__doc__ else None
# Cache the result. # Cache the result.
cache[filename] = (mtime, result) cache[filename] = (mtime, result)
return result return result
...@@ -2075,7 +2075,7 @@ class ModuleScanner: ...@@ -2075,7 +2075,7 @@ class ModuleScanner:
if onerror: if onerror:
onerror(modname) onerror(modname)
continue continue
desc = (module.__doc__ or '').splitlines()[0] desc = module.__doc__.splitlines()[0] if module.__doc__ else ''
path = getattr(module,'__file__',None) path = getattr(module,'__file__',None)
name = modname + ' - ' + desc name = modname + ' - ' + desc
if name.lower().find(key) >= 0: if name.lower().find(key) >= 0:
......
...@@ -3,12 +3,15 @@ import sys ...@@ -3,12 +3,15 @@ import sys
import builtins import builtins
import contextlib import contextlib
import difflib import difflib
import importlib.util
import inspect import inspect
import pydoc import pydoc
import py_compile
import keyword import keyword
import _pickle import _pickle
import pkgutil import pkgutil
import re import re
import stat
import string import string
import test.support import test.support
import time import time
...@@ -557,6 +560,18 @@ class PydocDocTest(unittest.TestCase): ...@@ -557,6 +560,18 @@ class PydocDocTest(unittest.TestCase):
self.assertEqual(synopsis, expected) 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): def test_splitdoc_with_description(self):
example_string = "I Am A Doc\n\n\nHere is my description" example_string = "I Am A Doc\n\n\nHere is my description"
self.assertEqual(pydoc.splitdoc(example_string), self.assertEqual(pydoc.splitdoc(example_string),
...@@ -612,6 +627,7 @@ class PydocImportTest(PydocBaseTest): ...@@ -612,6 +627,7 @@ class PydocImportTest(PydocBaseTest):
def setUp(self): def setUp(self):
self.test_dir = os.mkdir(TESTFN) self.test_dir = os.mkdir(TESTFN)
self.addCleanup(rmtree, TESTFN) self.addCleanup(rmtree, TESTFN)
importlib.invalidate_caches()
def test_badimport(self): def test_badimport(self):
# This tests the fix for issue 5230, where if pydoc found the module # This tests the fix for issue 5230, where if pydoc found the module
...@@ -670,6 +686,22 @@ class PydocImportTest(PydocBaseTest): ...@@ -670,6 +686,22 @@ class PydocImportTest(PydocBaseTest):
self.assertEqual(out.getvalue(), '') self.assertEqual(out.getvalue(), '')
self.assertEqual(err.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)') @unittest.skip('causes undesireable side-effects (#20128)')
def test_modules(self): def test_modules(self):
# See Helper.listmodules(). # See Helper.listmodules().
......
...@@ -506,6 +506,7 @@ Eric Groo ...@@ -506,6 +506,7 @@ Eric Groo
Dag Gruneau Dag Gruneau
Filip Gruszczyński Filip Gruszczyński
Thomas Guettler Thomas Guettler
Yuyang Guo
Anuj Gupta Anuj Gupta
Michael Guravage Michael Guravage
Lars Gustäbel Lars Gustäbel
......
...@@ -13,6 +13,9 @@ Core and Builtins ...@@ -13,6 +13,9 @@ Core and Builtins
Library 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 - Issue #22885: Fixed arbitrary code execution vulnerability in the dbm.dumb
module. Original patch by Claudiu Popa. module. Original patch by Claudiu Popa.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment