Changeset 391 for python/trunk/Lib/test/test_pydoc.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/test/test_pydoc.py
r2 r391 1 import os 1 2 import sys 2 import os3 import os.path4 3 import difflib 5 import subprocess4 import __builtin__ 6 5 import re 7 6 import pydoc 7 import contextlib 8 8 import inspect 9 import keyword 10 import pkgutil 9 11 import unittest 12 import xml.etree 10 13 import test.test_support 11 from contextlib import contextmanager 12 from test.test_support import TESTFN, forget, rmtree, EnvironmentVarGuard 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) 13 18 14 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 = ('', '') 15 28 16 29 expected_text_pattern = \ … … 38 51 | Data descriptors defined here: 39 52 |\x20\x20 40 | __dict__ 41 | dictionary for instance variables (if defined) 42 |\x20\x20 43 | __weakref__ 44 | list of weak references to the object (if defined) 53 | __dict__%s 54 |\x20\x20 55 | __weakref__%s 45 56 |\x20\x20 46 57 | ---------------------------------------------------------------------- … … 72 83 Nobody 73 84 """.strip() 85 86 expected_text_data_docstrings = tuple('\n | ' + s if s else '' 87 for s in expected_data_docstrings) 74 88 75 89 expected_html_pattern = \ … … 119 133 <td width="100%%">Data descriptors defined here:<br> 120 134 <dl><dt><strong>__dict__</strong></dt> 121 <dd><tt> dictionary for instance variables (if defined)</tt></dd>135 <dd><tt>%s</tt></dd> 122 136 </dl> 123 137 <dl><dt><strong>__weakref__</strong></dt> 124 <dd><tt> list of weak references to the object (if defined)</tt></dd>138 <dd><tt>%s</tt></dd> 125 139 </dl> 126 140 <hr> … … 166 180 """.strip() 167 181 182 expected_html_data_docstrings = tuple(s.replace(' ', ' ') 183 for s in expected_data_docstrings) 168 184 169 185 # output pattern for missing module … … 173 189 badimport_pattern = "problem in %s - <type 'exceptions.ImportError'>: No module named %s" 174 190 175 def run_pydoc(module_name, *args ):191 def run_pydoc(module_name, *args, **env): 176 192 """ 177 193 Runs pydoc on the specified module. Returns the stripped 178 194 output of pydoc. 179 195 """ 180 cmd = [sys.executable, pydoc.__file__, " ".join(args), module_name] 181 output = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout.read() 182 return output.strip() 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() 183 200 184 201 def get_pydoc_html(module): … … 214 231 215 232 216 class PyDocDocTest(unittest.TestCase): 217 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") 218 260 def test_html_doc(self): 219 261 result, doc_loc = get_pydoc_html(pydoc_mod) … … 224 266 else: 225 267 mod_url = mod_file 226 expected_html = expected_html_pattern % (mod_url, mod_file, doc_loc) 268 expected_html = expected_html_pattern % ( 269 (mod_url, mod_file, doc_loc) + 270 expected_html_data_docstrings) 227 271 if result != expected_html: 228 272 print_diffs(expected_html, result) 229 273 self.fail("outputs are not equal, see diff above") 230 274 275 @unittest.skipIf(sys.flags.optimize >= 2, 276 "Docstrings are omitted with -O2 and above") 231 277 def test_text_doc(self): 232 278 result, doc_loc = get_pydoc_text(pydoc_mod) 233 expected_text = expected_text_pattern % \ 234 (inspect.getabsfile(pydoc_mod), doc_loc) 279 expected_text = expected_text_pattern % ( 280 (inspect.getabsfile(pydoc_mod), doc_loc) + 281 expected_text_data_docstrings) 235 282 if result != expected_text: 236 283 print_diffs(expected_text, result) 237 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) 238 301 239 302 def test_not_here(self): … … 243 306 self.assertEqual(expected, result, 244 307 "documentation for missing module found") 245 246 def test_badimport(self):247 # This tests the fix for issue 5230, where if pydoc found the module248 # but the module had an internal import error pydoc would report no doc249 # found.250 modname = 'testmod_xyzzy'251 testpairs = (252 ('i_am_not_here', 'i_am_not_here'),253 ('test.i_am_not_here_either', 'i_am_not_here_either'),254 ('test.i_am_not_here.neither_am_i', 'i_am_not_here.neither_am_i'),255 ('i_am_not_here.{0}'.format(modname), 'i_am_not_here.{0}'.format(modname)),256 ('test.{0}'.format(modname), modname),257 )258 259 @contextmanager260 def newdirinpath(dir):261 os.mkdir(dir)262 sys.path.insert(0, dir)263 yield264 sys.path.pop(0)265 rmtree(dir)266 267 with newdirinpath(TESTFN):268 with EnvironmentVarGuard() as env:269 env.set('PYTHONPATH', TESTFN)270 fullmodname = os.path.join(TESTFN, modname)271 sourcefn = fullmodname + os.extsep + "py"272 for importstring, expectedinmsg in testpairs:273 f = open(sourcefn, 'w')274 f.write("import {0}\n".format(importstring))275 f.close()276 try:277 result = run_pydoc(modname)278 finally:279 forget(modname)280 expected = badimport_pattern % (modname, expectedinmsg)281 self.assertEqual(expected, result)282 308 283 309 def test_input_strip(self): … … 303 329 304 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 305 396 class TestDescriptions(unittest.TestCase): 306 397 … … 309 400 from test import pydocfodder 310 401 doc = pydoc.render_doc(pydocfodder) 311 self.assert _("pydocfodder" indoc)402 self.assertIn("pydocfodder", doc) 312 403 313 404 def test_classic_class(self): … … 317 408 self.assertEqual(pydoc.describe(c), 'instance of C') 318 409 expected = 'instance of C in module %s' % __name__ 319 self.assert _(expected inpydoc.render_doc(c))410 self.assertIn(expected, pydoc.render_doc(c)) 320 411 321 412 def test_class(self): … … 326 417 self.assertEqual(pydoc.describe(c), 'C') 327 418 expected = 'C in module %s object' % __name__ 328 self.assert_(expected in pydoc.render_doc(c)) 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) 329 452 330 453 331 454 def test_main(): 332 test.test_support.run_unittest(PyDocDocTest, 333 TestDescriptions) 455 try: 456 test.test_support.run_unittest(PydocDocTest, 457 PydocImportTest, 458 TestDescriptions, 459 TestHelper) 460 finally: 461 reap_children() 334 462 335 463 if __name__ == "__main__":
Note:
See TracChangeset
for help on using the changeset viewer.