# Path: taipan/api/decorators.py
# def function_decorator(decor):
#     """Decorator for function decorators (sic), written either
#     as classes or functions.
# 
#     In either case, the decorator ``decor`` must be "doubly-callable":
# 
#         * for classes, this means implementing ``__call__`` method
#           in addition to possible ``__init__``
#         * for functions, this means returning a function that acts
#           as an actual decorator, i.e. taking a function and returning
#           its decorated version
# 
#     Although it works for any decorator, it's useful mainly for those
#     that should take optional arguments. If the decorator is adorned
#     with ``@function_decorator``, it's possible to use it without the pair of
#     empty parentheses::
# 
#         @enhanced  # rather than @enhanced()
#         def foo():
#             pass
# 
#     when we don't want to pass any arguments to it.
# 
#     .. note::
# 
#         :func:`function_decorator` makes decorator applicable
#         only to functions. Use :func:`decorator` or :func:`class_decorator`
#         for decorators that should be applicable to classes.
#     """
#     ensure_callable(decor)
#     return _wrap_decorator(decor, "functions", inspect.isfunction)
# 
# def method_decorator(decor):
#     """Decorator for function decorators (sic), written either
#     as classes or functions.
# 
#     In either case, the decorator ``decor`` must be "doubly-callable":
# 
#         * for classes, this means implementing ``__call__`` method
#           in addition to possible ``__init__``
#         * for functions, this means returning a function that acts
#           as an actual decorator, i.e. taking a function and returning
#           its decorated version
# 
#     Although it works for any decorator, it's useful mainly for those
#     that should take optional arguments. If the decorator is adorned
#     with ``@method_decorator``, it's possible to use it without the pair of
#     empty parentheses::
# 
#         class Foo(object):
#             @enhanced  # rather than @enhanced()
#             def foo(self):
#                 pass
# 
#     when we don't want to pass any arguments to it.
# 
#     .. note::
# 
#         :func:`function_decorator` makes decorator applicable
#         only to methods inside a class. Use :func:`decorator`,
#         :func:`function_decorator` or :func:`class_decorator` for decorators
#         that should be applicable to other language constructs.
# 
#     .. versionadded:: 0.0.3
#     """
#     ensure_callable(decor)
#     return _wrap_decorator(decor, "methods", is_method)
# 
# Path: taipan/strings.py
# def ensure_string(s):
#     """Checks whether ``s`` is a string of characters.
#     :return: ``s`` if it is a string of characters
#     :raise TypeError: When ``s` is not a string of characters
#     """
#     if not is_string(s):
#         raise TypeError("expected a string, got %s" % type(s).__name__)
#     return s


from taipan.api.decorators import function_decorator, method_decorator
from taipan.strings import ensure_string
# Specific stage decorators

@function_decorator
class setUpClass(_StageDecorator):
    """Decorator for test case methods which should be invoked at the time
    when the whole test case class is being set up.

    .. warning::

        Even though the decorated method is class-level, it should **not**
        be also decorated as ``@classmethod``!

    Example::

        class MyTest(TestCase):
            @setUpClass
            def do_some_class_setup(cls):
                ...

    Multiple methods decorated this way will be invoked in the order
    they were defined in the test case class.

    .. versionadded:: 0.0.4
    """
    stage = 'setUpClass'

#: Alias for :class:`setUpClass`.
beforeClass = setUpClass



# Path: taipan/api/decorators.py
# def function_decorator(decor):
#     """Decorator for function decorators (sic), written either
#     as classes or functions.
# 
#     In either case, the decorator ``decor`` must be "doubly-callable":
# 
#         * for classes, this means implementing ``__call__`` method
#           in addition to possible ``__init__``
#         * for functions, this means returning a function that acts
#           as an actual decorator, i.e. taking a function and returning
#           its decorated version
# 
#     Although it works for any decorator, it's useful mainly for those
#     that should take optional arguments. If the decorator is adorned
#     with ``@function_decorator``, it's possible to use it without the pair of
#     empty parentheses::
# 
#         @enhanced  # rather than @enhanced()
#         def foo():
#             pass
# 
#     when we don't want to pass any arguments to it.
# 
#     .. note::
# 
#         :func:`function_decorator` makes decorator applicable
#         only to functions. Use :func:`decorator` or :func:`class_decorator`
#         for decorators that should be applicable to classes.
#     """
#     ensure_callable(decor)
#     return _wrap_decorator(decor, "functions", inspect.isfunction)
# 
# def method_decorator(decor):
#     """Decorator for function decorators (sic), written either
#     as classes or functions.
# 
#     In either case, the decorator ``decor`` must be "doubly-callable":
# 
#         * for classes, this means implementing ``__call__`` method
#           in addition to possible ``__init__``
#         * for functions, this means returning a function that acts
#           as an actual decorator, i.e. taking a function and returning
#           its decorated version
# 
#     Although it works for any decorator, it's useful mainly for those
#     that should take optional arguments. If the decorator is adorned
#     with ``@method_decorator``, it's possible to use it without the pair of
#     empty parentheses::
# 
#         class Foo(object):
#             @enhanced  # rather than @enhanced()
#             def foo(self):
#                 pass
# 
#     when we don't want to pass any arguments to it.
# 
#     .. note::
# 
#         :func:`function_decorator` makes decorator applicable
#         only to methods inside a class. Use :func:`decorator`,
#         :func:`function_decorator` or :func:`class_decorator` for decorators
#         that should be applicable to other language constructs.
# 
#     .. versionadded:: 0.0.3
#     """
#     ensure_callable(decor)
#     return _wrap_decorator(decor, "methods", is_method)
# 
# Path: taipan/strings.py
# def ensure_string(s):
#     """Checks whether ``s`` is a string of characters.
#     :return: ``s`` if it is a string of characters
#     :raise TypeError: When ``s` is not a string of characters
#     """
#     if not is_string(s):
#         raise TypeError("expected a string, got %s" % type(s).__name__)
#     return s


# Path: taipan/testing/decorators.py
from taipan.api.decorators import function_decorator, method_decorator
from taipan.strings import ensure_string

# Specific stage decorators

@function_decorator
class setUpClass(_StageDecorator):
    """Decorator for test case methods which should be invoked at the time
    when the whole test case class is being set up.

    .. warning::

        Even though the decorated method is class-level, it should **not**
        be also decorated as ``@classmethod``!

    Example::

        class MyTest(TestCase):
            @setUpClass
            def do_some_class_setup(cls):
                ...

    Multiple methods decorated this way will be invoked in the order
    they were defined in the test case class.

    .. versionadded:: 0.0.4
    """
    stage = 'setUpClass'

#: Alias for :class:`setUpClass`.
beforeClass = setUpClass



@method_decorator