Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/test/test_pydoc.py

    r2 r391  
     1import os
    12import sys
    2 import os
    3 import os.path
    43import difflib
    5 import subprocess
     4import __builtin__
    65import re
    76import pydoc
     7import contextlib
    88import inspect
     9import keyword
     10import pkgutil
    911import unittest
     12import xml.etree
    1013import test.test_support
    11 from contextlib import contextmanager
    12 from test.test_support import TESTFN, forget, rmtree, EnvironmentVarGuard
     14from collections import namedtuple
     15from test.script_helper import assert_python_ok
     16from test.test_support import (
     17    TESTFN, rmtree, reap_children, captured_stdout, captured_stderr)
    1318
    1419from test import pydoc_mod
     20
     21if 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        )
     26else:
     27    expected_data_docstrings = ('', '')
    1528
    1629expected_text_pattern = \
     
    3851     |  Data descriptors defined here:
    3952     |\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
    4556     |\x20\x20
    4657     |  ----------------------------------------------------------------------
     
    7283    Nobody
    7384""".strip()
     85
     86expected_text_data_docstrings = tuple('\n     |      ' + s if s else ''
     87                                      for s in expected_data_docstrings)
    7488
    7589expected_html_pattern = \
     
    119133<td width="100%%">Data descriptors defined here:<br>
    120134<dl><dt><strong>__dict__</strong></dt>
    121 <dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
     135<dd><tt>%s</tt></dd>
    122136</dl>
    123137<dl><dt><strong>__weakref__</strong></dt>
    124 <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
     138<dd><tt>%s</tt></dd>
    125139</dl>
    126140<hr>
     
    166180""".strip()
    167181
     182expected_html_data_docstrings = tuple(s.replace(' ', '&nbsp;')
     183                                      for s in expected_data_docstrings)
    168184
    169185# output pattern for missing module
     
    173189badimport_pattern = "problem in %s - <type 'exceptions.ImportError'>: No module named %s"
    174190
    175 def run_pydoc(module_name, *args):
     191def run_pydoc(module_name, *args, **env):
    176192    """
    177193    Runs pydoc on the specified module. Returns the stripped
    178194    output of pydoc.
    179195    """
    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()
    183200
    184201def get_pydoc_html(module):
     
    214231
    215232
    216 class PyDocDocTest(unittest.TestCase):
    217 
     233class 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
     256class PydocDocTest(unittest.TestCase):
     257
     258    @unittest.skipIf(sys.flags.optimize >= 2,
     259                     "Docstrings are omitted with -O2 and above")
    218260    def test_html_doc(self):
    219261        result, doc_loc = get_pydoc_html(pydoc_mod)
     
    224266        else:
    225267            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)
    227271        if result != expected_html:
    228272            print_diffs(expected_html, result)
    229273            self.fail("outputs are not equal, see diff above")
    230274
     275    @unittest.skipIf(sys.flags.optimize >= 2,
     276                     "Docstrings are omitted with -O2 and above")
    231277    def test_text_doc(self):
    232278        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)
    235282        if result != expected_text:
    236283            print_diffs(expected_text, result)
    237284            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)
    238301
    239302    def test_not_here(self):
     
    243306        self.assertEqual(expected, result,
    244307            "documentation for missing module found")
    245 
    246     def test_badimport(self):
    247         # This tests the fix for issue 5230, where if pydoc found the module
    248         # but the module had an internal import error pydoc would report no doc
    249         # 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         @contextmanager
    260         def newdirinpath(dir):
    261             os.mkdir(dir)
    262             sys.path.insert(0, dir)
    263             yield
    264             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)
    282308
    283309    def test_input_strip(self):
     
    303329
    304330
     331class 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
    305396class TestDescriptions(unittest.TestCase):
    306397
     
    309400        from test import pydocfodder
    310401        doc = pydoc.render_doc(pydocfodder)
    311         self.assert_("pydocfodder" in doc)
     402        self.assertIn("pydocfodder", doc)
    312403
    313404    def test_classic_class(self):
     
    317408        self.assertEqual(pydoc.describe(c), 'instance of C')
    318409        expected = 'instance of C in module %s' % __name__
    319         self.assert_(expected in pydoc.render_doc(c))
     410        self.assertIn(expected, pydoc.render_doc(c))
    320411
    321412    def test_class(self):
     
    326417        self.assertEqual(pydoc.describe(c), 'C')
    327418        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
     431class 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)
    329452
    330453
    331454def 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()
    334462
    335463if __name__ == "__main__":
Note: See TracChangeset for help on using the changeset viewer.