Improve Pydoc interactive browsing (#2001). Patch by Ron Adam.

* A -b option to start an enhanced browsing session.
* Allow -b and -p options to be used together.
* Specifying port 0 will pick an arbitrary unused socket port.
* A new browse() function to start the new server and browser.
* Show Python version information in the header.
* A *Get* field which takes the same input as the help() function.
* A *Search* field which replaces the Tkinter search box.
* Links to *Module Index*, *Topics*, and *Keywords*.
* Improved source file viewing.
* An HTMLDoc.filelink() method.
* The -g option and the gui() and serve() functions are deprecated.
This commit is contained in:
Nick Coghlan 2010-12-03 09:29:11 +00:00
parent 9af2a6e56f
commit 7bb30b72d8
6 changed files with 656 additions and 73 deletions

View file

@ -1,13 +1,14 @@
import sys
import os
import os.path
import sys
import difflib
import subprocess
import re
import pydoc
import inspect
import unittest
import pydoc
import re
import string
import subprocess
import test.support
import time
import unittest
import xml.etree
import textwrap
from io import StringIO
@ -221,19 +222,25 @@ def get_pydoc_text(module):
output = doc.docmodule(module)
# cleanup the extra text formatting that pydoc preforms
# clean up the extra text formatting that pydoc performs
patt = re.compile('\b.')
output = patt.sub('', output)
return output.strip(), loc
def print_diffs(text1, text2):
"Prints unified diffs for two texts"
# XXX now obsolete, use unittest built-in support
lines1 = text1.splitlines(True)
lines2 = text2.splitlines(True)
diffs = difflib.unified_diff(lines1, lines2, n=0, fromfile='expected',
tofile='got')
print('\n' + ''.join(diffs))
def get_html_title(text):
_, _, text = text.rpartition("<title>")
title, _, _ = text.rpartition("</title>")
return title
class PyDocDocTest(unittest.TestCase):
@ -373,16 +380,8 @@ class TestDescriptions(unittest.TestCase):
doc = pydoc.render_doc(pydocfodder)
self.assertIn("pydocfodder", doc)
def test_classic_class(self):
class C: "Classic class"
c = C()
self.assertEqual(pydoc.describe(C), 'class C')
self.assertEqual(pydoc.describe(c), 'C')
expected = 'C in module %s' % __name__
self.assertIn(expected, pydoc.render_doc(c))
def test_class(self):
class C(object): "New-style class"
class C: "New-style class"
c = C()
self.assertEqual(pydoc.describe(C), 'class C')
@ -391,8 +390,78 @@ class TestDescriptions(unittest.TestCase):
self.assertIn(expected, pydoc.render_doc(c))
class PyDocServerTest(unittest.TestCase):
"""Tests for pydoc._start_server"""
def test_server(self):
# Minimal test that starts the server, then stops it.
def my_url_handler(url, content_type):
text = 'the URL sent was: (%s, %s)' % (url, content_type)
return text
serverthread = pydoc._start_server(my_url_handler, port=0)
starttime = time.time()
timeout = 1 #seconds
while serverthread.serving:
time.sleep(.01)
if serverthread.serving and time.time() - starttime > timeout:
serverthread.stop()
break
self.assertEqual(serverthread.error, None)
class PyDocUrlHandlerTest(unittest.TestCase):
"""Tests for pydoc._url_handler"""
def test_content_type_err(self):
err = 'Error: unknown content type '
f = pydoc._url_handler
result = f("", "")
self.assertEqual(result, err + "''")
result = f("", "foobar")
self.assertEqual(result, err + "'foobar'")
def test_url_requests(self):
# Test for the correct title in the html pages returned.
# This tests the different parts of the URL handler without
# getting too picky about the exact html.
requests = [
("", "Python: Index of Modules"),
("get?key=", "Python: Index of Modules"),
("index", "Python: Index of Modules"),
("topics", "Python: Topics"),
("keywords", "Python: Keywords"),
("pydoc", "Python: module pydoc"),
("get?key=pydoc", "Python: module pydoc"),
("search?key=pydoc", "Python: Search Results"),
("def", "Python: KEYWORD def"),
("STRINGS", "Python: TOPIC STRINGS"),
("foobar", "Python: Error"),
("getfile?key=foobar", "Python: Read Error"),
]
for url, title in requests:
text = pydoc._url_handler(url, "text/html")
result = get_html_title(text)
self.assertEqual(result, title)
path = string.__file__
title = "Python: getfile /" + path
url = "getfile?key=" + path
text = pydoc._url_handler(url, "text/html")
result = get_html_title(text)
self.assertEqual(result, title)
def test_main():
test.support.run_unittest(PyDocDocTest, TestDescriptions)
test.support.run_unittest(PyDocDocTest,
TestDescriptions,
PyDocServerTest,
PyDocUrlHandlerTest,
)
if __name__ == "__main__":
test_main()