"""Support Eiffel-style preconditions and postconditions."""

from new import function

class EiffelBaseMetaClass(type):

    def __new__(meta, name, bases, dict):
        meta.convert_methods(dict)
        return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases,
                                                        dict)

    def convert_methods(cls, dict):
        """Replace functions in dict with EiffelMethod wrappers.

        The dict is modified in place.

        If a method ends in _pre or _post, it is removed from the dict
        regardless of whether there is a corresponding method.
        """
        # find methods with pre or post conditions
        methods = []
        for k, v in dict.iteritems():
            if k.endswith('_pre') or k.endswith('_post'):
                assert isinstance(v, function)
            elif isinstance(v, function):
                methods.append(k)
        for m in methods:
            pre = dict.get("%s_pre" % m)
            post = dict.get("%s_post" % m)
            if pre or post:
                dict[k] = cls.make_eiffel_method(dict[m], pre, post)

    convert_methods = classmethod(convert_methods)

class EiffelMetaClass1(EiffelBaseMetaClass):
    # an implementation of the "eiffel" meta class that uses nested functions

    def make_eiffel_method(func, pre, post):
        def method(self, *args, **kwargs):
            if pre:
                pre(self, *args, **kwargs)
            x = func(self, *args, **kwargs)
            if post:
                post(self, x, *args, **kwargs)
            return x

        if func.__doc__:
            method.__doc__ = func.__doc__

        return method
    
    make_eiffel_method = staticmethod(make_eiffel_method)

class EiffelMethodWrapper:

    def __init__(self, inst, descr):
        self._inst = inst
        self._descr = descr

    def __call__(self, *args, **kwargs):
        return self._descr.callmethod(self._inst, args, kwargs)

class EiffelDescriptor(object):

    def __init__(self, func, pre, post):
        self._func = func
        self._pre = pre
        self._post = post
        
        self.__name__ = func.__name__
        self.__doc__ = func.__doc__

    def __get__(self, obj, cls):
        return EiffelMethodWrapper(obj, self)

    def callmethod(self, inst, args, kwargs):
        if self._pre:
            self._pre(inst, *args, **kwargs)
        x = self._func(inst, *args, **kwargs)
        if self._post:
            self._post(inst, x, *args, **kwargs)
        return x

class EiffelMetaClass2(EiffelBaseMetaClass):
    # an implementation of the "eiffel" meta class that uses descriptors

    make_eiffel_method = EiffelDescriptor

def _test(metaclass):
    class Eiffel:
        __metaclass__ = metaclass

    class Test(Eiffel):

        def m(self, arg):
            """Make it a little larger"""
            return arg + 1

        def m2(self, arg):
            """Make it a little larger"""
            return arg + 1

        def m2_pre(self, arg):
            assert arg > 0

        def m2_post(self, result, arg):
            assert result > arg

    class Sub(Test):
        def m2(self, arg):
            return arg**2
        def m2_post(self, Result, arg):
            super(Sub, self).m2_post(Result, arg)
            assert Result < 100

    t = Test()
    t.m(1)
    t.m2(1)
    try:
        t.m2(0)
    except AssertionError:
        pass
    else:
        assert False

    s = Sub()
    try:
        s.m2(1)
    except AssertionError:
        pass # result == arg
    else:
        assert False
    try:
        s.m2(10)
    except AssertionError:
        pass # result ==  100
    else:
        assert False
    s.m2(5)

if __name__ == "__main__":
    _test(EiffelMetaClass1)
    _test(EiffelMetaClass2)

