Skip to content

bpo-44967: pydoc: return non-zero exit code when query is not found #27868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions Lib/pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1775,24 +1775,18 @@ def render_doc(thing, title='Python Library Documentation: %s', forceload=0,
def doc(thing, title='Python Library Documentation: %s', forceload=0,
output=None):
"""Display text documentation, given an object or a path to an object."""
try:
if output is None:
pager(render_doc(thing, title, forceload))
else:
output.write(render_doc(thing, title, forceload, plaintext))
except (ImportError, ErrorDuringImport) as value:
print(value)
if output is None:
pager(render_doc(thing, title, forceload))
else:
output.write(render_doc(thing, title, forceload, plaintext))

def writedoc(thing, forceload=0):
"""Write HTML documentation to a file in the current directory."""
try:
object, name = resolve(thing, forceload)
page = html.page(describe(object), html.document(object, name))
with open(name + '.html', 'w', encoding='utf-8') as file:
file.write(page)
print('wrote', name + '.html')
except (ImportError, ErrorDuringImport) as value:
print(value)
object, name = resolve(thing, forceload)
page = html.page(describe(object), html.document(object, name))
with open(name + '.html', 'w', encoding='utf-8') as file:
file.write(page)
print('wrote', name + '.html')

def writedocs(dir, pkgpath='', done=None):
"""Write out HTML documentation for all modules in a directory tree."""
Expand Down Expand Up @@ -2786,7 +2780,7 @@ class BadUsage(Exception): pass
for arg in args:
if ispath(arg) and not os.path.exists(arg):
print('file %r does not exist' % arg)
break
sys.exit(1)
try:
if ispath(arg) and os.path.isfile(arg):
arg = importfile(arg)
Expand All @@ -2797,8 +2791,9 @@ class BadUsage(Exception): pass
writedoc(arg)
else:
help.help(arg)
except ErrorDuringImport as value:
except (ImportError, ErrorDuringImport) as value:
print(value)
sys.exit(1)

except (getopt.error, BadUsage):
cmd = os.path.splitext(os.path.basename(sys.argv[0]))[0]
Expand Down
16 changes: 12 additions & 4 deletions Lib/test/test_pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from io import StringIO
from collections import namedtuple
from test.support import os_helper
from test.support.script_helper import assert_python_ok
from test.support.script_helper import assert_python_ok, assert_python_failure
from test.support import threading_helper
from test.support import (reap_children, captured_output, captured_stdout,
captured_stderr, requires_docstrings)
Expand Down Expand Up @@ -345,6 +345,14 @@ def run_pydoc(module_name, *args, **env):
rc, out, err = assert_python_ok('-B', pydoc.__file__, *args, **env)
return out.strip()

def run_pydoc_fail(module_name, *args, **env):
"""
Runs pydoc on the specified module expecting a failure.
"""
args = args + (module_name,)
rc, out, err = assert_python_failure('-B', pydoc.__file__, *args, **env)
return out.strip()

def get_pydoc_html(module):
"Returns pydoc generated output as html"
doc = pydoc.HTMLDoc()
Expand Down Expand Up @@ -487,7 +495,7 @@ class B:

def test_not_here(self):
missing_module = "test.i_am_not_here"
result = str(run_pydoc(missing_module), 'ascii')
result = str(run_pydoc_fail(missing_module), 'ascii')
expected = missing_pattern % missing_module
self.assertEqual(expected, result,
"documentation for missing module found")
Expand All @@ -501,7 +509,7 @@ def test_not_ascii(self):

def test_input_strip(self):
missing_module = " test.i_am_not_here "
result = str(run_pydoc(missing_module), 'ascii')
result = str(run_pydoc_fail(missing_module), 'ascii')
expected = missing_pattern % missing_module.strip()
self.assertEqual(expected, result)

Expand Down Expand Up @@ -902,7 +910,7 @@ def test_badimport(self):
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")
result = run_pydoc_fail(modname, PYTHONPATH=TESTFN).decode("ascii")
expected = badimport_pattern % (modname, expectedinmsg)
self.assertEqual(expected, result)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pydoc now returns a non-zero status code when a module cannot be found.