Index: Lib/pydoc.py =================================================================== --- Lib/pydoc.py (revision 86589) +++ Lib/pydoc.py (working copy) @@ -1310,6 +1310,11 @@ line += '\n' + self.indent(str(doc)) return line +class PlainTextDoc(TextDoc): + """Subclass of TextDoc which overrides string formatting""" + def bold(self,text): + return text + # --------------------------------------------------------- user interfaces def pager(text): @@ -1464,6 +1469,7 @@ # --------------------------------------- interactive interpreter interface text = TextDoc() +plaintext = PlainTextDoc() html = HTMLDoc() def resolve(thing, forceload=0): @@ -1476,8 +1482,10 @@ else: return thing, getattr(thing, '__name__', None) -def render_doc(thing, title='Python Library Documentation: %s', forceload=0): +def render_doc(thing, title='Python Library Documentation: %s', forceload=0, renderer=None): """Render text documentation, given an object or a path to an object.""" + if renderer is None: + renderer = text object, name = resolve(thing, forceload) desc = describe(object) module = inspect.getmodule(object) @@ -1496,12 +1504,15 @@ # document its available methods instead of its value. object = type(object) desc += ' object' - return title % desc + '\n\n' + text.document(object, name) + return title % desc + '\n\n' + renderer.document(object, name) -def 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: - pager(render_doc(thing, title, forceload)) + if output: + output.write(render_doc(thing, title, forceload, plaintext)) + else: + pager(render_doc(thing, title, forceload)) except (ImportError, ErrorDuringImport) as value: print(value) @@ -1754,9 +1765,9 @@ elif request in self.symbols: self.showsymbol(request) elif request in self.keywords: self.showtopic(request) elif request in self.topics: self.showtopic(request) - elif request: doc(request, 'Help on %s:') + elif request: doc(request, 'Help on %s:',output=self._output) elif isinstance(request, Helper): self() - else: doc(request, 'Help on %s:') + else: doc(request, 'Help on %s:',output=self._output) self.output.write('\n') def intro(self): Index: Lib/test/test_pydoc.py =================================================================== --- Lib/test/test_pydoc.py (revision 86589) +++ Lib/test/test_pydoc.py (working copy) @@ -9,6 +9,7 @@ import unittest import test.support import xml.etree +from io import StringIO from contextlib import contextmanager from test.support import ( TESTFN, forget, rmtree, EnvironmentVarGuard, reap_children) @@ -327,7 +328,41 @@ self.assertEqual(stripid(""), "") + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_help_output_redirect(self): + # issue 940286, if output is set in Helper, then output from + # Helper.help should be redirected + global expected_text_pattern + old_pattern = expected_text_pattern + getpager_old = pydoc.getpager + getpager_new = lambda: (lambda x: x) + pydoc.getpager = getpager_new + buf = StringIO() + helper = pydoc.Helper(output=buf) + unused, doc_loc = get_pydoc_text(pydoc_mod) + module = "test.pydoc_mod" + help_header = """ + Help on module test.pydoc_mod in test: + + """.lstrip().rstrip(' ') + expected_text_pattern = help_header + expected_text_pattern + + helper.help(module) + result = buf.getvalue().strip() + expected_text = expected_text_pattern % \ + (doc_loc, inspect.getabsfile(pydoc_mod)) + + expected_text_pattern = old_pattern + pydoc.getpager = getpager_old + + if result != expected_text: + print_diffs(expected_text, result) + self.fail("outputs are not equal, see diff above") + + + class TestDescriptions(unittest.TestCase): def test_module(self):