晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。   林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。   见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝)   既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。   南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。 sh-3ll

HOME


sh-3ll 1.0
DIR:/opt/hc_python/lib64/python3.12/site-packages/nose/plugins/
Upload File :
Current File : //opt/hc_python/lib64/python3.12/site-packages/nose/plugins/errorclass.py
"""
ErrorClass Plugins
------------------

ErrorClass plugins provide an easy way to add support for custom
handling of particular classes of exceptions.

An ErrorClass plugin defines one or more ErrorClasses and how each is
handled and reported on. Each error class is stored in a different
attribute on the result, and reported separately. Each error class must
indicate the exceptions that fall under that class, the label to use
for reporting, and whether exceptions of the class should be
considered as failures for the whole test run.

ErrorClasses use a declarative syntax. Assign an ErrorClass to the
attribute you wish to add to the result object, defining the
exceptions, label and isfailure attributes. For example, to declare an
ErrorClassPlugin that defines TodoErrors (and subclasses of TodoError)
as an error class with the label 'TODO' that is considered a failure,
do this:

    >>> class Todo(Exception):
    ...     pass
    >>> class TodoError(ErrorClassPlugin):
    ...     todo = ErrorClass(Todo, label='TODO', isfailure=True)

The MetaErrorClass metaclass translates the ErrorClass declarations
into the tuples used by the error handling and reporting functions in
the result. This is an internal format and subject to change; you
should always use the declarative syntax for attaching ErrorClasses to
an ErrorClass plugin.

    >>> TodoError.errorClasses # doctest: +ELLIPSIS
    ((<class ...Todo...>, ('todo', 'TODO', True)),)

Let's see the plugin in action. First some boilerplate.

    >>> import sys
    >>> import unittest
    >>> try:
    ...     # 2.7+
    ...     from unittest.runner import _WritelnDecorator
    ... except ImportError:
    ...     from unittest import _WritelnDecorator
    ... 
    >>> buf = _WritelnDecorator(sys.stdout)

Now define a test case that raises a Todo.

    >>> class TestTodo(unittest.TestCase):
    ...     def runTest(self):
    ...         raise Todo("I need to test something")
    >>> case = TestTodo()

Prepare the result using our plugin. Normally this happens during the
course of test execution within nose -- you won't be doing this
yourself. For the purposes of this testing document, I'm stepping
through the internal process of nose so you can see what happens at
each step.

    >>> plugin = TodoError()
    >>> from nose.result import _TextTestResult
    >>> result = _TextTestResult(stream=buf, descriptions=0, verbosity=2)
    >>> plugin.prepareTestResult(result)

Now run the test. TODO is printed.

    >>> _ = case(result) # doctest: +ELLIPSIS
    runTest (....TestTodo) ... TODO: I need to test something

Errors and failures are empty, but todo has our test:

    >>> result.errors
    []
    >>> result.failures
    []
    >>> result.todo # doctest: +ELLIPSIS
    [(<....TestTodo testMethod=runTest>, '...Todo: I need to test something\\n')]
    >>> result.printErrors() # doctest: +ELLIPSIS
    <BLANKLINE>
    ======================================================================
    TODO: runTest (....TestTodo)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    ...
    ...Todo: I need to test something
    <BLANKLINE>

Since we defined a Todo as a failure, the run was not successful.

    >>> result.wasSuccessful()
    False
"""

from nose.pyversion import make_instancemethod
from nose.plugins.base import Plugin
from nose.result import TextTestResult
from nose.util import isclass

class MetaErrorClass(type):
    """Metaclass for ErrorClassPlugins that allows error classes to be
    set up in a declarative manner.
    """
    def __init__(self, name, bases, attr):
        errorClasses = []
        for name, detail in list(attr.items()):
            if isinstance(detail, ErrorClass):
                attr.pop(name)
                for cls in detail:
                    errorClasses.append(
                        (cls, (name, detail.label, detail.isfailure)))
        super(MetaErrorClass, self).__init__(name, bases, attr)
        self.errorClasses = tuple(errorClasses)


class ErrorClass(object):
    def __init__(self, *errorClasses, **kw):
        self.errorClasses = errorClasses
        try:
            for key in ('label', 'isfailure'):
                setattr(self, key, kw.pop(key))
        except KeyError:
            raise TypeError("%r is a required named argument for ErrorClass"
                            % key)

    def __iter__(self):
        return iter(self.errorClasses)


class ErrorClassPlugin(Plugin, metaclass=MetaErrorClass):
    """
    Base class for ErrorClass plugins. Subclass this class and declare the
    exceptions that you wish to handle as attributes of the subclass.
    """
    score = 1000
    errorClasses = ()

    def addError(self, test, err):
        err_cls, a, b = err
        if not isclass(err_cls):
            return
        classes = [e[0] for e in self.errorClasses]
        if [c for c in classes if issubclass(err_cls, c)]:
            return True

    def prepareTestResult(self, result):
        if not hasattr(result, 'errorClasses'):
            self.patchResult(result)
        for cls, (storage_attr, label, isfail) in self.errorClasses:
            if cls not in result.errorClasses:
                storage = getattr(result, storage_attr, [])
                setattr(result, storage_attr, storage)
                result.errorClasses[cls] = (storage, label, isfail)

    def patchResult(self, result):
        result.printLabel = print_label_patch(result)
        result._orig_addError, result.addError = \
            result.addError, add_error_patch(result)
        result._orig_wasSuccessful, result.wasSuccessful = \
            result.wasSuccessful, wassuccessful_patch(result)
        if hasattr(result, 'printErrors'):
            result._orig_printErrors, result.printErrors = \
                result.printErrors, print_errors_patch(result)
        if hasattr(result, 'addSkip'):
            result._orig_addSkip, result.addSkip = \
                result.addSkip, add_skip_patch(result)
        result.errorClasses = {}


def add_error_patch(result):
    """Create a new addError method to patch into a result instance
    that recognizes the errorClasses attribute and deals with
    errorclasses correctly.
    """
    return make_instancemethod(TextTestResult.addError, result)


def print_errors_patch(result):
    """Create a new printErrors method that prints errorClasses items
    as well.
    """
    return make_instancemethod(TextTestResult.printErrors, result)


def print_label_patch(result):
    """Create a new printLabel method that prints errorClasses items
    as well.
    """
    return make_instancemethod(TextTestResult.printLabel, result)


def wassuccessful_patch(result):
    """Create a new wasSuccessful method that checks errorClasses for
    exceptions that were put into other slots than error or failure
    but that still count as not success.
    """
    return make_instancemethod(TextTestResult.wasSuccessful, result)


def add_skip_patch(result):
    """Create a new addSkip method to patch into a result instance
    that delegates to addError.
    """
    return make_instancemethod(TextTestResult.addSkip, result)


if __name__ == '__main__':
    import doctest
    doctest.testmod()