summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/pkgutil.py14
-rw-r--r--Lib/test/test_pkgutil.py11
-rw-r--r--Lib/test/test_pydoc.py95
3 files changed, 75 insertions, 45 deletions
diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py
index c561c13..bdea23e 100644
--- a/Lib/pkgutil.py
+++ b/Lib/pkgutil.py
@@ -191,8 +191,11 @@ class ImpImporter:
yielded = {}
import inspect
-
- filenames = os.listdir(self.path)
+ try:
+ filenames = os.listdir(self.path)
+ except OSError:
+ # ignore unreadable directories like import does
+ filenames = []
filenames.sort() # handle packages before same-named modules
for fn in filenames:
@@ -205,7 +208,12 @@ class ImpImporter:
if not modname and os.path.isdir(path) and '.' not in fn:
modname = fn
- for fn in os.listdir(path):
+ try:
+ dircontents = os.listdir(path)
+ except OSError:
+ # ignore unreadable directories like import does
+ dircontents = []
+ for fn in dircontents:
subname = inspect.getmodulename(fn)
if subname=='__init__':
ispkg = True
diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py
index f69af5a..f755e67 100644
--- a/Lib/test/test_pkgutil.py
+++ b/Lib/test/test_pkgutil.py
@@ -84,6 +84,17 @@ class PkgutilTests(unittest.TestCase):
del sys.modules[pkg]
+ def test_unreadable_dir_on_syspath(self):
+ # issue7367 - walk_packages failed if unreadable dir on sys.path
+ package_name = "unreadable_package"
+ d = os.path.join(self.dirname, package_name)
+ # this does not appear to create an unreadable dir on Windows
+ # but the test should not fail anyway
+ os.mkdir(d, 0)
+ for t in pkgutil.walk_packages(path=[self.dirname]):
+ self.fail("unexpected package found")
+ os.rmdir(d)
+
class PkgutilPEP302Tests(unittest.TestCase):
class MyTestLoader(object):
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 6d3923f..3e5c450 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -7,7 +7,6 @@ import pydoc
import keyword
import re
import string
-import subprocess
import test.support
import time
import unittest
@@ -15,11 +14,9 @@ import xml.etree
import textwrap
from io import StringIO
from collections import namedtuple
-from contextlib import contextmanager
-
from test.script_helper import assert_python_ok
from test.support import (
- TESTFN, forget, rmtree, EnvironmentVarGuard,
+ TESTFN, rmtree,
reap_children, reap_threads, captured_output, captured_stdout, unlink
)
from test import pydoc_mod
@@ -209,7 +206,8 @@ def run_pydoc(module_name, *args, **env):
output of pydoc.
"""
args = args + (module_name,)
- rc, out, err = assert_python_ok(pydoc.__file__, *args, **env)
+ # do not write bytecode files to avoid caching errors
+ rc, out, err = assert_python_ok('-B', pydoc.__file__, *args, **env)
return out.strip()
def get_pydoc_html(module):
@@ -295,43 +293,6 @@ 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)
- try:
- yield
- finally:
- sys.path.pop(0)
- rmtree(dir)
-
- with newdirinpath(TESTFN):
- fullmodname = os.path.join(TESTFN, modname)
- sourcefn = fullmodname + os.extsep + "py"
- for importstring, expectedinmsg in testpairs:
- with open(sourcefn, 'w') as f:
- f.write("import {}\n".format(importstring))
- try:
- result = run_pydoc(modname, PYTHONPATH=TESTFN).decode("ascii")
- 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 = str(run_pydoc(missing_module), 'ascii')
@@ -409,6 +370,55 @@ class PydocDocTest(unittest.TestCase):
self.assertEqual(synopsis, 'line 1: h\xe9')
+class PydocImportTest(unittest.TestCase):
+
+ def setUp(self):
+ self.test_dir = os.mkdir(TESTFN)
+ self.addCleanup(rmtree, TESTFN)
+
+ 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),
+ )
+
+ sourcefn = os.path.join(TESTFN, modname) + os.extsep + "py"
+ for importstring, expectedinmsg in testpairs:
+ with open(sourcefn, 'w') as f:
+ f.write("import {}\n".format(importstring))
+ result = run_pydoc(modname, PYTHONPATH=TESTFN).decode("ascii")
+ expected = badimport_pattern % (modname, expectedinmsg)
+ self.assertEqual(expected, result)
+
+ def test_apropos_with_bad_package(self):
+ # Issue 7425 - pydoc -k failed when bad package on path
+ pkgdir = os.path.join(TESTFN, "syntaxerr")
+ os.mkdir(pkgdir)
+ badsyntax = os.path.join(pkgdir, "__init__") + os.extsep + "py"
+ with open(badsyntax, 'w') as f:
+ f.write("invalid python syntax = $1\n")
+ result = run_pydoc('nothing', '-k', PYTHONPATH=TESTFN)
+ self.assertEqual(b'', result)
+
+ def test_apropos_with_unreadable_dir(self):
+ # Issue 7367 - pydoc -k failed when unreadable dir on path
+ self.unreadable_dir = os.path.join(TESTFN, "unreadable")
+ os.mkdir(self.unreadable_dir, 0)
+ self.addCleanup(os.rmdir, self.unreadable_dir)
+ # Note, on Windows the directory appears to be still
+ # readable so this is not really testing the issue there
+ result = run_pydoc('nothing', '-k', PYTHONPATH=TESTFN)
+ self.assertEqual(b'', result)
+
+
class TestDescriptions(unittest.TestCase):
def test_module(self):
@@ -517,6 +527,7 @@ class TestHelper(unittest.TestCase):
def test_main():
try:
test.support.run_unittest(PydocDocTest,
+ PydocImportTest,
TestDescriptions,
PydocServerTest,
PydocUrlHandlerTest,