# Path: taipan/functional/combinators.py
# def uncurry(f):
# def flip(f):
# def compose(*fs):
#     def g(*args, **kwargs):
# def merge(arg, *rest, **kwargs):
# def not_(f):
# def and_(*fs):
#     def g(*args, **kwargs):
# def or_(*fs):
#     def g(*args, **kwargs):
# def nand(*fs):
#     def g(*args, **kwargs):
# def nor(*fs):
#     def g(*args, **kwargs):
# 
# Path: taipan/objective/modifiers.py
# def final(arg):
#     """Mark a class or method as _final_.
# 
#     Final classes are those that end the inheritance chain, i.e. forbid
#     further subclassing. A final class can thus be only instantiated,
#     not inherited from.
# 
#     Similarly, methods marked as final in a superclass cannot be overridden
#     in any of the subclasses.
# 
#     .. note::
# 
#         Final method itself can also be (in fact, it usually is) an overridden
#         method from a superclass. In those cases, it's recommended to place
#         @\ :func:`final` modifier before @\ :func:`override` for clarity::
# 
#             class Foo(Base):
#                 @final
#                 @override
#                 def florb(self):
#                     super(Foo, self).florb()
#                     # ...
# 
#     .. versionadded:: 0.0.3
#        Now applicable to methods in addition to classes
#     """
#     if inspect.isclass(arg):
#         if not isinstance(arg, ObjectMetaclass):
#             raise ValueError("@final can only be applied to a class "
#                              "that is a subclass of Object")
#     elif not is_method(arg):
#         raise TypeError("@final can only be applied to classes or methods")
# 
#     method = arg.method if isinstance(arg, _WrappedMethod) else arg
#     method.__final__ = True
# 
#     return arg
# 
# def override(base=ABSENT):
#     """Mark a method as overriding a corresponding method from superclass.
# 
#     :param base:
# 
#         Optional base class from which this method is being overridden.
#         If provided, it can be a class itself, or its (qualified) name.
# 
#     .. note::
# 
#         When overriding a :class:`classmethod`, remember to place ``@override``
#         above the ``@classmethod`` decorator::
# 
#             class Foo(Bar):
#                 @override
#                 @classmethod
#                 def florb(cls):
#                     pass
#     """
#     arg = base  # ``base`` is just for clean, user-facing argument name
# 
#     # direct application of the modifier through ``@override``
#     if inspect.isfunction(arg) or isinstance(arg, NonInstanceMethod):
#         _OverrideDecorator.maybe_signal_classmethod(arg)
#         decorator = _OverrideDecorator(None)
#         return decorator(arg)
# 
#     # indirect (but simple) application of the modifier through ``@override()``
#     if arg is ABSENT:
#         return _OverrideDecorator(None)
# 
#     # full-blown application, with base class specified
#     if is_class(arg) or is_string(arg):
#         return _OverrideDecorator(arg)
# 
#     raise TypeError("explicit base class for @override "
#                     "must be either a string or a class object")
# 
# Path: taipan/testing/testcase.py
# class TestCase(_TestCase, AssertsMixin):
#     """Augmented test case class.
# 
#     Includes few additional, convenience assertion methods,
#     as well as the capability to use test stage decorators,
#     such as :func:`setUp` and :func:`tearDown`.
#     """
#     # Python 3 changes name of the following assert function,
#     # so we provide backward and forward synonyms for compatibility
#     if IS_PY3:
#         assertItemsEqual = _TestCase.assertCountEqual
#     else:
#         assertCountEqual = _TestCase.assertItemsEqual


from contextlib import contextmanager
from taipan.functional.combinators import curry
from taipan.objective.modifiers import final, override
from taipan.testing import TestCase
import taipan.objective.base as __unit__
        with self.assertRaises(__unit__.ClassError) as r:
            yield r

        msg = str(r.exception)
        self.assertIn("final", msg)
        self.assertIn("hiding", msg)


class ObjectMetaclass(_UniversalBaseClass):
    """Test case to ensure ObjectMetaclass plays with other metaclasses
    that may inherit from it. This includes weird and obscure cases, such as:

        * diamond inheritance, where metaclass inherits from more than one
          other metaclass, which in turn inherit from ObjectMetaclass
        * branch inheritance, where metaclass inherits from ObjectMetaclass'
          subclass in addition to other metaclass that is NOT a subclass
          of ObjectMetaclass

    The latter case is distinctly more important, too, as it allows for
    ObjectMetaclass to be incorporated into existing metaclass hierarchy.
    """
    def test_noop_meta_base__empty_class(self):
        NoopMeta = self._create_noop_metaclass()
        Class = self._create_class(NoopMeta, 'Class')

        self.assertIsInstance(Class, __unit__.ObjectMetaclass)
        self.assertIsInstance(Class, NoopMeta)

    def test_noop_meta__inheritance_from_final(self):
        NoopMeta = self._create_noop_metaclass()

# Path: taipan/functional/combinators.py
# def uncurry(f):
# def flip(f):
# def compose(*fs):
#     def g(*args, **kwargs):
# def merge(arg, *rest, **kwargs):
# def not_(f):
# def and_(*fs):
#     def g(*args, **kwargs):
# def or_(*fs):
#     def g(*args, **kwargs):
# def nand(*fs):
#     def g(*args, **kwargs):
# def nor(*fs):
#     def g(*args, **kwargs):
# 
# Path: taipan/objective/modifiers.py
# def final(arg):
#     """Mark a class or method as _final_.
# 
#     Final classes are those that end the inheritance chain, i.e. forbid
#     further subclassing. A final class can thus be only instantiated,
#     not inherited from.
# 
#     Similarly, methods marked as final in a superclass cannot be overridden
#     in any of the subclasses.
# 
#     .. note::
# 
#         Final method itself can also be (in fact, it usually is) an overridden
#         method from a superclass. In those cases, it's recommended to place
#         @\ :func:`final` modifier before @\ :func:`override` for clarity::
# 
#             class Foo(Base):
#                 @final
#                 @override
#                 def florb(self):
#                     super(Foo, self).florb()
#                     # ...
# 
#     .. versionadded:: 0.0.3
#        Now applicable to methods in addition to classes
#     """
#     if inspect.isclass(arg):
#         if not isinstance(arg, ObjectMetaclass):
#             raise ValueError("@final can only be applied to a class "
#                              "that is a subclass of Object")
#     elif not is_method(arg):
#         raise TypeError("@final can only be applied to classes or methods")
# 
#     method = arg.method if isinstance(arg, _WrappedMethod) else arg
#     method.__final__ = True
# 
#     return arg
# 
# def override(base=ABSENT):
#     """Mark a method as overriding a corresponding method from superclass.
# 
#     :param base:
# 
#         Optional base class from which this method is being overridden.
#         If provided, it can be a class itself, or its (qualified) name.
# 
#     .. note::
# 
#         When overriding a :class:`classmethod`, remember to place ``@override``
#         above the ``@classmethod`` decorator::
# 
#             class Foo(Bar):
#                 @override
#                 @classmethod
#                 def florb(cls):
#                     pass
#     """
#     arg = base  # ``base`` is just for clean, user-facing argument name
# 
#     # direct application of the modifier through ``@override``
#     if inspect.isfunction(arg) or isinstance(arg, NonInstanceMethod):
#         _OverrideDecorator.maybe_signal_classmethod(arg)
#         decorator = _OverrideDecorator(None)
#         return decorator(arg)
# 
#     # indirect (but simple) application of the modifier through ``@override()``
#     if arg is ABSENT:
#         return _OverrideDecorator(None)
# 
#     # full-blown application, with base class specified
#     if is_class(arg) or is_string(arg):
#         return _OverrideDecorator(arg)
# 
#     raise TypeError("explicit base class for @override "
#                     "must be either a string or a class object")
# 
# Path: taipan/testing/testcase.py
# class TestCase(_TestCase, AssertsMixin):
#     """Augmented test case class.
# 
#     Includes few additional, convenience assertion methods,
#     as well as the capability to use test stage decorators,
#     such as :func:`setUp` and :func:`tearDown`.
#     """
#     # Python 3 changes name of the following assert function,
#     # so we provide backward and forward synonyms for compatibility
#     if IS_PY3:
#         assertItemsEqual = _TestCase.assertCountEqual
#     else:
#         assertCountEqual = _TestCase.assertItemsEqual


# Path: tests/test_objective/test_base.py
from contextlib import contextmanager
from taipan.functional.combinators import curry
from taipan.objective.modifiers import final, override
from taipan.testing import TestCase
import taipan.objective.base as __unit__

        with self.assertRaises(__unit__.ClassError) as r:
            yield r

        msg = str(r.exception)
        self.assertIn("final", msg)
        self.assertIn("hiding", msg)


class ObjectMetaclass(_UniversalBaseClass):
    """Test case to ensure ObjectMetaclass plays with other metaclasses
    that may inherit from it. This includes weird and obscure cases, such as:

        * diamond inheritance, where metaclass inherits from more than one
          other metaclass, which in turn inherit from ObjectMetaclass
        * branch inheritance, where metaclass inherits from ObjectMetaclass'
          subclass in addition to other metaclass that is NOT a subclass
          of ObjectMetaclass

    The latter case is distinctly more important, too, as it allows for
    ObjectMetaclass to be incorporated into existing metaclass hierarchy.
    """
    def test_noop_meta_base__empty_class(self):
        NoopMeta = self._create_noop_metaclass()
        Class = self._create_class(NoopMeta, 'Class')

        self.assertIsInstance(Class, __unit__.ObjectMetaclass)
        self.assertIsInstance(Class, NoopMeta)

    def test_noop_meta__inheritance_from_final(self):
        NoopMeta = self._create_noop_metaclass()

        FinalClass = final(self._create_class(NoopMeta, 'FinalClass'))