1 | import os
|
---|
2 | import sys
|
---|
3 | import difflib
|
---|
4 | import __builtin__
|
---|
5 | import re
|
---|
6 | import pydoc
|
---|
7 | import contextlib
|
---|
8 | import inspect
|
---|
9 | import keyword
|
---|
10 | import pkgutil
|
---|
11 | import unittest
|
---|
12 | import xml.etree
|
---|
13 | import test.test_support
|
---|
14 | from collections import namedtuple
|
---|
15 | from test.script_helper import assert_python_ok
|
---|
16 | from test.test_support import (
|
---|
17 | TESTFN, rmtree, reap_children, captured_stdout, captured_stderr)
|
---|
18 |
|
---|
19 | from test import pydoc_mod
|
---|
20 |
|
---|
21 | if test.test_support.HAVE_DOCSTRINGS:
|
---|
22 | expected_data_docstrings = (
|
---|
23 | 'dictionary for instance variables (if defined)',
|
---|
24 | 'list of weak references to the object (if defined)',
|
---|
25 | )
|
---|
26 | else:
|
---|
27 | expected_data_docstrings = ('', '')
|
---|
28 |
|
---|
29 | expected_text_pattern = \
|
---|
30 | """
|
---|
31 | NAME
|
---|
32 | test.pydoc_mod - This is a test module for test_pydoc
|
---|
33 |
|
---|
34 | FILE
|
---|
35 | %s
|
---|
36 | %s
|
---|
37 | CLASSES
|
---|
38 | __builtin__.object
|
---|
39 | B
|
---|
40 | A
|
---|
41 | \x20\x20\x20\x20
|
---|
42 | class A
|
---|
43 | | Hello and goodbye
|
---|
44 | |\x20\x20
|
---|
45 | | Methods defined here:
|
---|
46 | |\x20\x20
|
---|
47 | | __init__()
|
---|
48 | | Wow, I have no function!
|
---|
49 | \x20\x20\x20\x20
|
---|
50 | class B(__builtin__.object)
|
---|
51 | | Data descriptors defined here:
|
---|
52 | |\x20\x20
|
---|
53 | | __dict__%s
|
---|
54 | |\x20\x20
|
---|
55 | | __weakref__%s
|
---|
56 | |\x20\x20
|
---|
57 | | ----------------------------------------------------------------------
|
---|
58 | | Data and other attributes defined here:
|
---|
59 | |\x20\x20
|
---|
60 | | NO_MEANING = 'eggs'
|
---|
61 |
|
---|
62 | FUNCTIONS
|
---|
63 | doc_func()
|
---|
64 | This function solves all of the world's problems:
|
---|
65 | hunger
|
---|
66 | lack of Python
|
---|
67 | war
|
---|
68 | \x20\x20\x20\x20
|
---|
69 | nodoc_func()
|
---|
70 |
|
---|
71 | DATA
|
---|
72 | __author__ = 'Benjamin Peterson'
|
---|
73 | __credits__ = 'Nobody'
|
---|
74 | __version__ = '1.2.3.4'
|
---|
75 |
|
---|
76 | VERSION
|
---|
77 | 1.2.3.4
|
---|
78 |
|
---|
79 | AUTHOR
|
---|
80 | Benjamin Peterson
|
---|
81 |
|
---|
82 | CREDITS
|
---|
83 | Nobody
|
---|
84 | """.strip()
|
---|
85 |
|
---|
86 | expected_text_data_docstrings = tuple('\n | ' + s if s else ''
|
---|
87 | for s in expected_data_docstrings)
|
---|
88 |
|
---|
89 | expected_html_pattern = \
|
---|
90 | """
|
---|
91 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
|
---|
92 | <tr bgcolor="#7799ee">
|
---|
93 | <td valign=bottom> <br>
|
---|
94 | <font color="#ffffff" face="helvetica, arial"> <br><big><big><strong><a href="test.html"><font color="#ffffff">test</font></a>.pydoc_mod</strong></big></big> (version 1.2.3.4)</font></td
|
---|
95 | ><td align=right valign=bottom
|
---|
96 | ><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:%s">%s</a>%s</font></td></tr></table>
|
---|
97 | <p><tt>This is a test module for test_pydoc</tt></p>
|
---|
98 | <p>
|
---|
99 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
---|
100 | <tr bgcolor="#ee77aa">
|
---|
101 | <td colspan=3 valign=bottom> <br>
|
---|
102 | <font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
|
---|
103 | \x20\x20\x20\x20
|
---|
104 | <tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td>
|
---|
105 | <td width="100%%"><dl>
|
---|
106 | <dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
|
---|
107 | </font></dt><dd>
|
---|
108 | <dl>
|
---|
109 | <dt><font face="helvetica, arial"><a href="test.pydoc_mod.html#B">B</a>
|
---|
110 | </font></dt></dl>
|
---|
111 | </dd>
|
---|
112 | <dt><font face="helvetica, arial"><a href="test.pydoc_mod.html#A">A</a>
|
---|
113 | </font></dt></dl>
|
---|
114 | <p>
|
---|
115 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
---|
116 | <tr bgcolor="#ffc8d8">
|
---|
117 | <td colspan=3 valign=bottom> <br>
|
---|
118 | <font color="#000000" face="helvetica, arial"><a name="A">class <strong>A</strong></a></font></td></tr>
|
---|
119 | \x20\x20\x20\x20
|
---|
120 | <tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td>
|
---|
121 | <td colspan=2><tt>Hello and goodbye<br> </tt></td></tr>
|
---|
122 | <tr><td> </td>
|
---|
123 | <td width="100%%">Methods defined here:<br>
|
---|
124 | <dl><dt><a name="A-__init__"><strong>__init__</strong></a>()</dt><dd><tt>Wow, I have no function!</tt></dd></dl>
|
---|
125 |
|
---|
126 | </td></tr></table> <p>
|
---|
127 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
---|
128 | <tr bgcolor="#ffc8d8">
|
---|
129 | <td colspan=3 valign=bottom> <br>
|
---|
130 | <font color="#000000" face="helvetica, arial"><a name="B">class <strong>B</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
|
---|
131 | \x20\x20\x20\x20
|
---|
132 | <tr><td bgcolor="#ffc8d8"><tt> </tt></td><td> </td>
|
---|
133 | <td width="100%%">Data descriptors defined here:<br>
|
---|
134 | <dl><dt><strong>__dict__</strong></dt>
|
---|
135 | <dd><tt>%s</tt></dd>
|
---|
136 | </dl>
|
---|
137 | <dl><dt><strong>__weakref__</strong></dt>
|
---|
138 | <dd><tt>%s</tt></dd>
|
---|
139 | </dl>
|
---|
140 | <hr>
|
---|
141 | Data and other attributes defined here:<br>
|
---|
142 | <dl><dt><strong>NO_MEANING</strong> = 'eggs'</dl>
|
---|
143 |
|
---|
144 | </td></tr></table></td></tr></table><p>
|
---|
145 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
---|
146 | <tr bgcolor="#eeaa77">
|
---|
147 | <td colspan=3 valign=bottom> <br>
|
---|
148 | <font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
|
---|
149 | \x20\x20\x20\x20
|
---|
150 | <tr><td bgcolor="#eeaa77"><tt> </tt></td><td> </td>
|
---|
151 | <td width="100%%"><dl><dt><a name="-doc_func"><strong>doc_func</strong></a>()</dt><dd><tt>This function solves all of the world's problems:<br>
|
---|
152 | hunger<br>
|
---|
153 | lack of Python<br>
|
---|
154 | war</tt></dd></dl>
|
---|
155 | <dl><dt><a name="-nodoc_func"><strong>nodoc_func</strong></a>()</dt></dl>
|
---|
156 | </td></tr></table><p>
|
---|
157 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
---|
158 | <tr bgcolor="#55aa55">
|
---|
159 | <td colspan=3 valign=bottom> <br>
|
---|
160 | <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
|
---|
161 | \x20\x20\x20\x20
|
---|
162 | <tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td>
|
---|
163 | <td width="100%%"><strong>__author__</strong> = 'Benjamin Peterson'<br>
|
---|
164 | <strong>__credits__</strong> = 'Nobody'<br>
|
---|
165 | <strong>__version__</strong> = '1.2.3.4'</td></tr></table><p>
|
---|
166 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
---|
167 | <tr bgcolor="#7799ee">
|
---|
168 | <td colspan=3 valign=bottom> <br>
|
---|
169 | <font color="#ffffff" face="helvetica, arial"><big><strong>Author</strong></big></font></td></tr>
|
---|
170 | \x20\x20\x20\x20
|
---|
171 | <tr><td bgcolor="#7799ee"><tt> </tt></td><td> </td>
|
---|
172 | <td width="100%%">Benjamin Peterson</td></tr></table><p>
|
---|
173 | <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
---|
174 | <tr bgcolor="#7799ee">
|
---|
175 | <td colspan=3 valign=bottom> <br>
|
---|
176 | <font color="#ffffff" face="helvetica, arial"><big><strong>Credits</strong></big></font></td></tr>
|
---|
177 | \x20\x20\x20\x20
|
---|
178 | <tr><td bgcolor="#7799ee"><tt> </tt></td><td> </td>
|
---|
179 | <td width="100%%">Nobody</td></tr></table>
|
---|
180 | """.strip()
|
---|
181 |
|
---|
182 | expected_html_data_docstrings = tuple(s.replace(' ', ' ')
|
---|
183 | for s in expected_data_docstrings)
|
---|
184 |
|
---|
185 | # output pattern for missing module
|
---|
186 | missing_pattern = "no Python documentation found for '%s'"
|
---|
187 |
|
---|
188 | # output pattern for module with bad imports
|
---|
189 | badimport_pattern = "problem in %s - <type 'exceptions.ImportError'>: No module named %s"
|
---|
190 |
|
---|
191 | def run_pydoc(module_name, *args, **env):
|
---|
192 | """
|
---|
193 | Runs pydoc on the specified module. Returns the stripped
|
---|
194 | output of pydoc.
|
---|
195 | """
|
---|
196 | args = args + (module_name,)
|
---|
197 | # do not write bytecode files to avoid caching errors
|
---|
198 | rc, out, err = assert_python_ok('-B', pydoc.__file__, *args, **env)
|
---|
199 | return out.strip()
|
---|
200 |
|
---|
201 | def get_pydoc_html(module):
|
---|
202 | "Returns pydoc generated output as html"
|
---|
203 | doc = pydoc.HTMLDoc()
|
---|
204 | output = doc.docmodule(module)
|
---|
205 | loc = doc.getdocloc(pydoc_mod) or ""
|
---|
206 | if loc:
|
---|
207 | loc = "<br><a href=\"" + loc + "\">Module Docs</a>"
|
---|
208 | return output.strip(), loc
|
---|
209 |
|
---|
210 | def get_pydoc_text(module):
|
---|
211 | "Returns pydoc generated output as text"
|
---|
212 | doc = pydoc.TextDoc()
|
---|
213 | loc = doc.getdocloc(pydoc_mod) or ""
|
---|
214 | if loc:
|
---|
215 | loc = "\nMODULE DOCS\n " + loc + "\n"
|
---|
216 |
|
---|
217 | output = doc.docmodule(module)
|
---|
218 |
|
---|
219 | # cleanup the extra text formatting that pydoc preforms
|
---|
220 | patt = re.compile('\b.')
|
---|
221 | output = patt.sub('', output)
|
---|
222 | return output.strip(), loc
|
---|
223 |
|
---|
224 | def print_diffs(text1, text2):
|
---|
225 | "Prints unified diffs for two texts"
|
---|
226 | lines1 = text1.splitlines(True)
|
---|
227 | lines2 = text2.splitlines(True)
|
---|
228 | diffs = difflib.unified_diff(lines1, lines2, n=0, fromfile='expected',
|
---|
229 | tofile='got')
|
---|
230 | print '\n' + ''.join(diffs)
|
---|
231 |
|
---|
232 |
|
---|
233 | class PydocBaseTest(unittest.TestCase):
|
---|
234 |
|
---|
235 | def _restricted_walk_packages(self, walk_packages, path=None):
|
---|
236 | """
|
---|
237 | A version of pkgutil.walk_packages() that will restrict itself to
|
---|
238 | a given path.
|
---|
239 | """
|
---|
240 | default_path = path or [os.path.dirname(__file__)]
|
---|
241 | def wrapper(path=None, prefix='', onerror=None):
|
---|
242 | return walk_packages(path or default_path, prefix, onerror)
|
---|
243 | return wrapper
|
---|
244 |
|
---|
245 | @contextlib.contextmanager
|
---|
246 | def restrict_walk_packages(self, path=None):
|
---|
247 | walk_packages = pkgutil.walk_packages
|
---|
248 | pkgutil.walk_packages = self._restricted_walk_packages(walk_packages,
|
---|
249 | path)
|
---|
250 | try:
|
---|
251 | yield
|
---|
252 | finally:
|
---|
253 | pkgutil.walk_packages = walk_packages
|
---|
254 |
|
---|
255 |
|
---|
256 | class PydocDocTest(unittest.TestCase):
|
---|
257 |
|
---|
258 | @unittest.skipIf(sys.flags.optimize >= 2,
|
---|
259 | "Docstrings are omitted with -O2 and above")
|
---|
260 | def test_html_doc(self):
|
---|
261 | result, doc_loc = get_pydoc_html(pydoc_mod)
|
---|
262 | mod_file = inspect.getabsfile(pydoc_mod)
|
---|
263 | if sys.platform == 'win32':
|
---|
264 | import nturl2path
|
---|
265 | mod_url = nturl2path.pathname2url(mod_file)
|
---|
266 | else:
|
---|
267 | mod_url = mod_file
|
---|
268 | expected_html = expected_html_pattern % (
|
---|
269 | (mod_url, mod_file, doc_loc) +
|
---|
270 | expected_html_data_docstrings)
|
---|
271 | if result != expected_html:
|
---|
272 | print_diffs(expected_html, result)
|
---|
273 | self.fail("outputs are not equal, see diff above")
|
---|
274 |
|
---|
275 | @unittest.skipIf(sys.flags.optimize >= 2,
|
---|
276 | "Docstrings are omitted with -O2 and above")
|
---|
277 | def test_text_doc(self):
|
---|
278 | result, doc_loc = get_pydoc_text(pydoc_mod)
|
---|
279 | expected_text = expected_text_pattern % (
|
---|
280 | (inspect.getabsfile(pydoc_mod), doc_loc) +
|
---|
281 | expected_text_data_docstrings)
|
---|
282 | if result != expected_text:
|
---|
283 | print_diffs(expected_text, result)
|
---|
284 | self.fail("outputs are not equal, see diff above")
|
---|
285 |
|
---|
286 | def test_issue8225(self):
|
---|
287 | # Test issue8225 to ensure no doc link appears for xml.etree
|
---|
288 | result, doc_loc = get_pydoc_text(xml.etree)
|
---|
289 | self.assertEqual(doc_loc, "", "MODULE DOCS incorrectly includes a link")
|
---|
290 |
|
---|
291 | def test_non_str_name(self):
|
---|
292 | # issue14638
|
---|
293 | # Treat illegal (non-str) name like no name
|
---|
294 | class A:
|
---|
295 | __name__ = 42
|
---|
296 | class B:
|
---|
297 | pass
|
---|
298 | adoc = pydoc.render_doc(A())
|
---|
299 | bdoc = pydoc.render_doc(B())
|
---|
300 | self.assertEqual(adoc.replace("A", "B"), bdoc)
|
---|
301 |
|
---|
302 | def test_not_here(self):
|
---|
303 | missing_module = "test.i_am_not_here"
|
---|
304 | result = run_pydoc(missing_module)
|
---|
305 | expected = missing_pattern % missing_module
|
---|
306 | self.assertEqual(expected, result,
|
---|
307 | "documentation for missing module found")
|
---|
308 |
|
---|
309 | def test_input_strip(self):
|
---|
310 | missing_module = " test.i_am_not_here "
|
---|
311 | result = run_pydoc(missing_module)
|
---|
312 | expected = missing_pattern % missing_module.strip()
|
---|
313 | self.assertEqual(expected, result,
|
---|
314 | "white space was not stripped from module name "
|
---|
315 | "or other error output mismatch")
|
---|
316 |
|
---|
317 | def test_stripid(self):
|
---|
318 | # test with strings, other implementations might have different repr()
|
---|
319 | stripid = pydoc.stripid
|
---|
320 | # strip the id
|
---|
321 | self.assertEqual(stripid('<function stripid at 0x88dcee4>'),
|
---|
322 | '<function stripid>')
|
---|
323 | self.assertEqual(stripid('<function stripid at 0x01F65390>'),
|
---|
324 | '<function stripid>')
|
---|
325 | # nothing to strip, return the same text
|
---|
326 | self.assertEqual(stripid('42'), '42')
|
---|
327 | self.assertEqual(stripid("<type 'exceptions.Exception'>"),
|
---|
328 | "<type 'exceptions.Exception'>")
|
---|
329 |
|
---|
330 |
|
---|
331 | class PydocImportTest(PydocBaseTest):
|
---|
332 |
|
---|
333 | def setUp(self):
|
---|
334 | self.test_dir = os.mkdir(TESTFN)
|
---|
335 | self.addCleanup(rmtree, TESTFN)
|
---|
336 |
|
---|
337 | def test_badimport(self):
|
---|
338 | # This tests the fix for issue 5230, where if pydoc found the module
|
---|
339 | # but the module had an internal import error pydoc would report no doc
|
---|
340 | # found.
|
---|
341 | modname = 'testmod_xyzzy'
|
---|
342 | testpairs = (
|
---|
343 | ('i_am_not_here', 'i_am_not_here'),
|
---|
344 | ('test.i_am_not_here_either', 'i_am_not_here_either'),
|
---|
345 | ('test.i_am_not_here.neither_am_i', 'i_am_not_here.neither_am_i'),
|
---|
346 | ('i_am_not_here.{}'.format(modname),
|
---|
347 | 'i_am_not_here.{}'.format(modname)),
|
---|
348 | ('test.{}'.format(modname), modname),
|
---|
349 | )
|
---|
350 |
|
---|
351 | sourcefn = os.path.join(TESTFN, modname) + os.extsep + "py"
|
---|
352 | for importstring, expectedinmsg in testpairs:
|
---|
353 | with open(sourcefn, 'w') as f:
|
---|
354 | f.write("import {}\n".format(importstring))
|
---|
355 | result = run_pydoc(modname, PYTHONPATH=TESTFN)
|
---|
356 | expected = badimport_pattern % (modname, expectedinmsg)
|
---|
357 | self.assertEqual(expected, result)
|
---|
358 |
|
---|
359 | def test_apropos_with_bad_package(self):
|
---|
360 | # Issue 7425 - pydoc -k failed when bad package on path
|
---|
361 | pkgdir = os.path.join(TESTFN, "syntaxerr")
|
---|
362 | os.mkdir(pkgdir)
|
---|
363 | badsyntax = os.path.join(pkgdir, "__init__") + os.extsep + "py"
|
---|
364 | with open(badsyntax, 'w') as f:
|
---|
365 | f.write("invalid python syntax = $1\n")
|
---|
366 | with self.restrict_walk_packages(path=[TESTFN]):
|
---|
367 | with captured_stdout() as out:
|
---|
368 | with captured_stderr() as err:
|
---|
369 | pydoc.apropos('xyzzy')
|
---|
370 | # No result, no error
|
---|
371 | self.assertEqual(out.getvalue(), '')
|
---|
372 | self.assertEqual(err.getvalue(), '')
|
---|
373 | # The package name is still matched
|
---|
374 | with captured_stdout() as out:
|
---|
375 | with captured_stderr() as err:
|
---|
376 | pydoc.apropos('syntaxerr')
|
---|
377 | self.assertEqual(out.getvalue().strip(), 'syntaxerr')
|
---|
378 | self.assertEqual(err.getvalue(), '')
|
---|
379 |
|
---|
380 | def test_apropos_with_unreadable_dir(self):
|
---|
381 | # Issue 7367 - pydoc -k failed when unreadable dir on path
|
---|
382 | self.unreadable_dir = os.path.join(TESTFN, "unreadable")
|
---|
383 | os.mkdir(self.unreadable_dir, 0)
|
---|
384 | self.addCleanup(os.rmdir, self.unreadable_dir)
|
---|
385 | # Note, on Windows the directory appears to be still
|
---|
386 | # readable so this is not really testing the issue there
|
---|
387 | with self.restrict_walk_packages(path=[TESTFN]):
|
---|
388 | with captured_stdout() as out:
|
---|
389 | with captured_stderr() as err:
|
---|
390 | pydoc.apropos('SOMEKEY')
|
---|
391 | # No result, no error
|
---|
392 | self.assertEqual(out.getvalue(), '')
|
---|
393 | self.assertEqual(err.getvalue(), '')
|
---|
394 |
|
---|
395 |
|
---|
396 | class TestDescriptions(unittest.TestCase):
|
---|
397 |
|
---|
398 | def test_module(self):
|
---|
399 | # Check that pydocfodder module can be described
|
---|
400 | from test import pydocfodder
|
---|
401 | doc = pydoc.render_doc(pydocfodder)
|
---|
402 | self.assertIn("pydocfodder", doc)
|
---|
403 |
|
---|
404 | def test_classic_class(self):
|
---|
405 | class C: "Classic class"
|
---|
406 | c = C()
|
---|
407 | self.assertEqual(pydoc.describe(C), 'class C')
|
---|
408 | self.assertEqual(pydoc.describe(c), 'instance of C')
|
---|
409 | expected = 'instance of C in module %s' % __name__
|
---|
410 | self.assertIn(expected, pydoc.render_doc(c))
|
---|
411 |
|
---|
412 | def test_class(self):
|
---|
413 | class C(object): "New-style class"
|
---|
414 | c = C()
|
---|
415 |
|
---|
416 | self.assertEqual(pydoc.describe(C), 'class C')
|
---|
417 | self.assertEqual(pydoc.describe(c), 'C')
|
---|
418 | expected = 'C in module %s object' % __name__
|
---|
419 | self.assertIn(expected, pydoc.render_doc(c))
|
---|
420 |
|
---|
421 | def test_namedtuple_public_underscore(self):
|
---|
422 | NT = namedtuple('NT', ['abc', 'def'], rename=True)
|
---|
423 | with captured_stdout() as help_io:
|
---|
424 | help(NT)
|
---|
425 | helptext = help_io.getvalue()
|
---|
426 | self.assertIn('_1', helptext)
|
---|
427 | self.assertIn('_replace', helptext)
|
---|
428 | self.assertIn('_asdict', helptext)
|
---|
429 |
|
---|
430 |
|
---|
431 | class TestHelper(unittest.TestCase):
|
---|
432 | def test_keywords(self):
|
---|
433 | self.assertEqual(sorted(pydoc.Helper.keywords),
|
---|
434 | sorted(keyword.kwlist))
|
---|
435 |
|
---|
436 | def test_builtin(self):
|
---|
437 | for name in ('str', 'str.translate', '__builtin__.str',
|
---|
438 | '__builtin__.str.translate'):
|
---|
439 | # test low-level function
|
---|
440 | self.assertIsNotNone(pydoc.locate(name))
|
---|
441 | # test high-level function
|
---|
442 | try:
|
---|
443 | pydoc.render_doc(name)
|
---|
444 | except ImportError:
|
---|
445 | self.fail('finding the doc of {!r} failed'.format(o))
|
---|
446 |
|
---|
447 | for name in ('not__builtin__', 'strrr', 'strr.translate',
|
---|
448 | 'str.trrrranslate', '__builtin__.strrr',
|
---|
449 | '__builtin__.str.trrranslate'):
|
---|
450 | self.assertIsNone(pydoc.locate(name))
|
---|
451 | self.assertRaises(ImportError, pydoc.render_doc, name)
|
---|
452 |
|
---|
453 |
|
---|
454 | def test_main():
|
---|
455 | try:
|
---|
456 | test.test_support.run_unittest(PydocDocTest,
|
---|
457 | PydocImportTest,
|
---|
458 | TestDescriptions,
|
---|
459 | TestHelper)
|
---|
460 | finally:
|
---|
461 | reap_children()
|
---|
462 |
|
---|
463 | if __name__ == "__main__":
|
---|
464 | test_main()
|
---|