summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xLib/pydoc.py7
-rw-r--r--Lib/test/test_pydoc.py42
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS4
4 files changed, 51 insertions, 3 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 76a2b64621..57071a1506 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -55,6 +55,7 @@ Richard Chamberlain, for the first implementation of textdoc.
import sys, imp, os, re, types, inspect, __builtin__, pkgutil
from repr import Repr
from string import expandtabs, find, join, lower, split, strip, rfind, rstrip
+from traceback import extract_tb
try:
from collections import deque
except ImportError:
@@ -299,9 +300,9 @@ def safeimport(path, forceload=0, cache={}):
elif exc is SyntaxError:
# A SyntaxError occurred before we could execute the module.
raise ErrorDuringImport(value.filename, info)
- elif exc is ImportError and \
- split(lower(str(value)))[:2] == ['no', 'module']:
- # The module was not found.
+ elif exc is ImportError and extract_tb(tb)[-1][2]=='safeimport':
+ # The import error occurred directly in this function,
+ # which means there is no such module in the path.
return None
else:
# Some other error occurred during the importing process.
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 7990d3a492..c1c19f6083 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -1,5 +1,6 @@
import sys
import os
+import os.path
import difflib
import subprocess
import re
@@ -7,6 +8,8 @@ import pydoc
import inspect
import unittest
import test.test_support
+from contextlib import contextmanager
+from test.test_support import TESTFN, forget, rmtree, EnvironmentVarGuard
from test import pydoc_mod
@@ -166,6 +169,9 @@ war</tt></dd></dl>
# output pattern for missing module
missing_pattern = "no Python documentation found for '%s'"
+# output pattern for module with bad imports
+badimport_pattern = "problem in %s - <type 'exceptions.ImportError'>: No module named %s"
+
def run_pydoc(module_name, *args):
"""
Runs pydoc on the specified module. Returns the stripped
@@ -237,6 +243,42 @@ class PyDocDocTest(unittest.TestCase):
self.assertEqual(expected, result,
"documentation for missing module found")
+ def test_badimport(self):
+ # This tests the fix for issue 5230, where if pydoc found the module
+ # but the module had an internal import error pydoc would report no doc
+ # found.
+ modname = 'testmod_xyzzy'
+ testpairs = (
+ ('i_am_not_here', 'i_am_not_here'),
+ ('test.i_am_not_here_either', 'i_am_not_here_either'),
+ ('test.i_am_not_here.neither_am_i', 'i_am_not_here.neither_am_i'),
+ ('i_am_not_here.{}'.format(modname), 'i_am_not_here.{}'.format(modname)),
+ ('test.{}'.format(modname), modname),
+ )
+
+ @contextmanager
+ def newdirinpath(dir):
+ os.mkdir(dir)
+ sys.path.insert(0, dir)
+ yield
+ sys.path.pop(0)
+ rmtree(dir)
+
+ with newdirinpath(TESTFN), EnvironmentVarGuard() as env:
+ env['PYTHONPATH'] = TESTFN
+ fullmodname = os.path.join(TESTFN, modname)
+ sourcefn = fullmodname + os.extsep + "py"
+ for importstring, expectedinmsg in testpairs:
+ f = open(sourcefn, 'w')
+ f.write("import {}\n".format(importstring))
+ f.close()
+ try:
+ result = run_pydoc(modname)
+ finally:
+ forget(modname)
+ expected = badimport_pattern % (modname, expectedinmsg)
+ self.assertEqual(expected, result)
+
def test_input_strip(self):
missing_module = " test.i_am_not_here "
result = run_pydoc(missing_module)
diff --git a/Misc/ACKS b/Misc/ACKS
index 82cd4a3c25..5cc07e5719 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -479,6 +479,7 @@ Andrew McNamara
Craig McPheeters
Lambert Meertens
Bill van Melle
+Lucas Prado Melo
Luke Mewburn
Mike Meyer
Steven Miale
diff --git a/Misc/NEWS b/Misc/NEWS
index 2985c3aa70..a4e92f4509 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -327,6 +327,10 @@ Core and Builtins
Library
-------
+- Issue #5230: pydoc would report no documentation found if a module generated
+ a 'not found' import error when loaded; it now reports the import errors.
+ Thanks to Lucas Prado Melo for initial fix and collaboration on the tests.
+
- Issue #6314: logging.basicConfig() performs extra checks on the "level"
argument.