doctest.py

来自「mallet是自然语言处理、机器学习领域的一个开源项目。」· Python 代码 · 共 1,174 行 · 第 1/3 页

PY
1,174
字号
                    # The methods implementing the property have their                    # own docstrings -- but the property may have one too.                    if value.__doc__ is not None:                        d[tag] = str(value.__doc__)                elif kind == "data":                    # Grab nested classes.                    if _isclass(value):                        d[tag] = value                else:                    raise ValueError("teach doctest about %r" % kind)            f2, t2 = self.run__test__(d, name)            f += f2            t += t2        return f, t    def rundict(self, d, name, module=None):        """        d, name, module=None -> search for docstring examples in d.values().        For k, v in d.items() such that v is a function or class,        do self.rundoc(v, name + "." + k).  Whether this includes        objects with private names depends on the constructor's        "isprivate" argument.  If module is specified, functions and        classes that are not defined in module are excluded.        Return aggregate (#failures, #examples).        Build and populate two modules with sample functions to test that        exclusion of external functions and classes works.        >>> import new        >>> m1 = new.module('_m1')        >>> m2 = new.module('_m2')        >>> test_data = \"""        ... def _f():        ...     '''>>> assert 1 == 1        ...     '''        ... def g():        ...    '''>>> assert 2 != 1        ...    '''        ... class H:        ...    '''>>> assert 2 > 1        ...    '''        ...    def bar(self):        ...        '''>>> assert 1 < 2        ...        '''        ... \"""        >>> exec test_data in m1.__dict__        >>> exec test_data in m2.__dict__        >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H})        Tests that objects outside m1 are excluded:        >>> t = Tester(globs={}, verbose=0)        >>> t.rundict(m1.__dict__, "rundict_test", m1)  # _f, f2 and g2 and h2 skipped        (0, 3)        Again, but with a custom isprivate function allowing _f:        >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0)        >>> t.rundict(m1.__dict__, "rundict_test_pvt", m1)  # Only f2, g2 and h2 skipped        (0, 4)        And once more, not excluding stuff outside m1:        >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0)        >>> t.rundict(m1.__dict__, "rundict_test_pvt")  # None are skipped.        (0, 8)        The exclusion of objects from outside the designated module is        meant to be invoked automagically by testmod.        >>> testmod(m1)        (0, 3)        """        if not hasattr(d, "items"):            raise TypeError("Tester.rundict: d must support .items(); " +                            `d`)        f = t = 0        # Run the tests by alpha order of names, for consistency in        # verbose-mode output.        names = d.keys()        names.sort()        for thisname in names:            value = d[thisname]            if _isfunction(value) or _isclass(value):                if module and not _from_module(module, value):                    continue                f2, t2 = self.__runone(value, name + "." + thisname)                f = f + f2                t = t + t2        return f, t    def run__test__(self, d, name):        """d, name -> Treat dict d like module.__test__.        Return (#failures, #tries).        See testmod.__doc__ for details.        """        failures = tries = 0        prefix = name + "."        savepvt = self.isprivate        try:            self.isprivate = lambda *args: 0            # Run the tests by alpha order of names, for consistency in            # verbose-mode output.            keys = d.keys()            keys.sort()            for k in keys:                v = d[k]                thisname = prefix + k                if type(v) in _StringTypes:                    f, t = self.runstring(v, thisname)                elif _isfunction(v) or _isclass(v):                    f, t = self.rundoc(v, thisname)                else:                    raise TypeError("Tester.run__test__: values in "                            "dict must be strings, functions "                            "or classes; " + `v`)                failures = failures + f                tries = tries + t        finally:            self.isprivate = savepvt        return failures, tries    def summarize(self, verbose=None):        """        verbose=None -> summarize results, return (#failures, #tests).        Print summary of test results to stdout.        Optional arg 'verbose' controls how wordy this is.  By        default, use the verbose setting established by the        constructor.        """        if verbose is None:            verbose = self.verbose        notests = []        passed = []        failed = []        totalt = totalf = 0        for x in self.name2ft.items():            name, (f, t) = x            assert f <= t            totalt = totalt + t            totalf = totalf + f            if t == 0:                notests.append(name)            elif f == 0:                passed.append( (name, t) )            else:                failed.append(x)        if verbose:            if notests:                print len(notests), "items had no tests:"                notests.sort()                for thing in notests:                    print "   ", thing            if passed:                print len(passed), "items passed all tests:"                passed.sort()                for thing, count in passed:                    print " %3d tests in %s" % (count, thing)        if failed:            print "*" * 65            print len(failed), "items had failures:"            failed.sort()            for thing, (f, t) in failed:                print " %3d of %3d in %s" % (f, t, thing)        if verbose:            print totalt, "tests in", len(self.name2ft), "items."            print totalt - totalf, "passed and", totalf, "failed."        if totalf:            print "***Test Failed***", totalf, "failures."        elif verbose:            print "Test passed."        return totalf, totalt    def merge(self, other):        """        other -> merge in test results from the other Tester instance.        If self and other both have a test result for something        with the same name, the (#failures, #tests) results are        summed, and a warning is printed to stdout.        >>> from doctest import Tester        >>> t1 = Tester(globs={}, verbose=0)        >>> t1.runstring('''        ... >>> x = 12        ... >>> print x        ... 12        ... ''', "t1example")        (0, 2)        >>>        >>> t2 = Tester(globs={}, verbose=0)        >>> t2.runstring('''        ... >>> x = 13        ... >>> print x        ... 13        ... ''', "t2example")        (0, 2)        >>> common = ">>> assert 1 + 2 == 3\\n"        >>> t1.runstring(common, "common")        (0, 1)        >>> t2.runstring(common, "common")        (0, 1)        >>> t1.merge(t2)        *** Tester.merge: 'common' in both testers; summing outcomes.        >>> t1.summarize(1)        3 items passed all tests:           2 tests in common           2 tests in t1example           2 tests in t2example        6 tests in 3 items.        6 passed and 0 failed.        Test passed.        (0, 6)        >>>        """        d = self.name2ft        for name, (f, t) in other.name2ft.items():            if d.has_key(name):                print "*** Tester.merge: '" + name + "' in both" \                    " testers; summing outcomes."                f2, t2 = d[name]                f = f + f2                t = t + t2            d[name] = f, t    def __record_outcome(self, name, f, t):        if self.name2ft.has_key(name):            print "*** Warning: '" + name + "' was tested before;", \                "summing outcomes."            f2, t2 = self.name2ft[name]            f = f + f2            t = t + t2        self.name2ft[name] = f, t    def __runone(self, target, name):        if "." in name:            i = name.rindex(".")            prefix, base = name[:i], name[i+1:]        else:            prefix, base = "", base        if self.isprivate(prefix, base):            return 0, 0        return self.rundoc(target, name)master = Nonedef testmod(m, name=None, globs=None, verbose=None, isprivate=None,               report=1):    """m, name=None, globs=None, verbose=None, isprivate=None, report=1    Test examples in docstrings in functions and classes reachable from    module m, starting with m.__doc__.  Private names are skipped.    Also test examples reachable from dict m.__test__ if it exists and is    not None.  m.__dict__ maps names to functions, classes and strings;    function and class docstrings are tested even if the name is private;    strings are tested directly, as if they were docstrings.    Return (#failures, #tests).    See doctest.__doc__ for an overview.    Optional keyword arg "name" gives the name of the module; by default    use m.__name__.    Optional keyword arg "globs" gives a dict to be used as the globals    when executing examples; by default, use m.__dict__.  A copy of this    dict is actually used for each docstring, so that each docstring's    examples start with a clean slate.    Optional keyword arg "verbose" prints lots of stuff if true, prints    only failures if false; by default, it's true iff "-v" is in sys.argv.    Optional keyword arg "isprivate" specifies a function used to    determine whether a name is private.  The default function is    doctest.is_private; see its docs for details.    Optional keyword arg "report" prints a summary at the end when true,    else prints nothing at the end.  In verbose mode, the summary is    detailed, else very brief (in fact, empty if all tests passed).    Advanced tomfoolery:  testmod runs methods of a local instance of    class doctest.Tester, then merges the results into (or creates)    global Tester instance doctest.master.  Methods of doctest.master    can be called directly too, if you want to do something unusual.    Passing report=0 to testmod is especially useful then, to delay    displaying a summary.  Invoke doctest.master.summarize(verbose)    when you're done fiddling.    """    global master    if not _ismodule(m):        raise TypeError("testmod: module required; " + `m`)    if name is None:        name = m.__name__    tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate)    failures, tries = tester.rundoc(m, name)    f, t = tester.rundict(m.__dict__, name, m)    failures = failures + f    tries = tries + t    if hasattr(m, "__test__"):        testdict = m.__test__        if testdict:            if not hasattr(testdict, "items"):                raise TypeError("testmod: module.__test__ must support "                                ".items(); " + `testdict`)            f, t = tester.run__test__(testdict, name + ".__test__")            failures = failures + f            tries = tries + t    if report:        tester.summarize()    if master is None:        master = tester    else:        master.merge(tester)    return failures, triesclass _TestClass:    """    A pointless class, for sanity-checking of docstring testing.    Methods:        square()        get()    >>> _TestClass(13).get() + _TestClass(-12).get()    1    >>> hex(_TestClass(13).square().get())    '0xa9'    """    def __init__(self, val):        """val -> _TestClass object with associated value val.        >>> t = _TestClass(123)        >>> print t.get()        123        """        self.val = val    def square(self):        """square() -> square TestClass's associated value        >>> _TestClass(13).square().get()        169        """        self.val = self.val ** 2        return self    def get(self):        """get() -> return TestClass's associated value.        >>> x = _TestClass(-42)        >>> print x.get()        -42        """        return self.val__test__ = {"_TestClass": _TestClass,            "string": r"""                      Example of a string object, searched as-is.                      >>> x = 1; y = 2                      >>> x + y, x * y                      (3, 2)                      """           }def _test():    import doctest    return doctest.testmod(doctest)if __name__ == "__main__":    _test()

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?