???<!-- GIF89;a -->
123123123123
.....................................................................................................................................???<!-- GIF89;a -->
123123123123
.....................................................................................................................................ó
¿œ^c           @   s™   d  Z  d d l m Z m Z m Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ e d	 d i  ƒ Z d
 „  Z	 e
 d k r• e	 ƒ  n  d S(   sÐ  Support Eiffel-style preconditions and postconditions.

For example,

class C:
    def m1(self, arg):
        require arg > 0
        return whatever
        ensure Result > arg

can be written (clumsily, I agree) as:

class C(Eiffel):
    def m1(self, arg):
        return whatever
    def m1_pre(self, arg):
        assert arg > 0
    def m1_post(self, Result, arg):
        assert Result > arg

Pre- and post-conditions for a method, being implemented as methods
themselves, are inherited independently from the method.  This gives
much of the same effect of Eiffel, where pre- and post-conditions are
inherited when a method is overridden by a derived class.  However,
when a derived class in Python needs to extend a pre- or
post-condition, it must manually merge the base class' pre- or
post-condition with that defined in the derived class', for example:

class D(C):
    def m1(self, arg):
        return arg**2
    def m1_post(self, Result, arg):
        C.m1_post(self, Result, arg)
        assert Result < 100

This gives derived classes more freedom but also more responsibility
than in Eiffel, where the compiler automatically takes care of this.

In Eiffel, pre-conditions combine using contravariance, meaning a
derived class can only make a pre-condition weaker; in Python, this is
up to the derived class.  For example, a derived class that takes away
the requirement that arg > 0 could write:

    def m1_pre(self, arg):
        pass

but one could equally write a derived class that makes a stronger
requirement:

    def m1_pre(self, arg):
        require arg > 50

It would be easy to modify the classes shown here so that pre- and
post-conditions can be disabled (separately, on a per-class basis).

A different design would have the pre- or post-condition testing
functions return true for success and false for failure.  This would
make it possible to implement automatic combination of inherited
and new pre-/post-conditions.  All this is left as an exercise to the
reader.

iÿÿÿÿ(   t	   MetaClasst
   MetaHelpert   MetaMethodWrappert   EiffelMethodWrapperc           B   s   e  Z d  „  Z d „  Z RS(   c         C   s‹   t  j |  | | ƒ y t | |  j d ƒ |  _ Wn t k
 rL d  |  _ n Xy t | |  j d ƒ |  _ Wn t k
 r† d  |  _ n Xd  S(   Nt   _pret   _post(   R   t   __init__t   getattrt   __name__t   pret   AttributeErrort   Nonet   post(   t   selft   funct   inst(    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyR   D   s    c         O   sh   |  j  r t |  j  | | ƒ n  t |  j |  j f | | ƒ } |  j rd t |  j | f | | ƒ n  | S(   N(   R	   t   applyR   R   R   (   R   t   argst   kwt   Result(    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyt   __call__S   s    		(   R   t
   __module__R   R   (    (    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyR   B   s   	t   EiffelHelperc           B   s   e  Z e Z RS(    (   R   R   R   t   __methodwrapper__(    (    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyR   [   s   t   EiffelMetaClassc           B   s   e  Z e Z RS(    (   R   R   R   t
   __helper__(    (    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyR   ^   s   t   Eiffelc          C   s0   d t  f d „  ƒ  Y}  |  ƒ  } | j d ƒ d  S(   Nt   Cc           B   s#   e  Z d  „  Z d „  Z d „  Z RS(   c         S   s   | d S(   Ni   (    (   R   t   arg(    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyt   m1f   s    c         S   s   | d k s t  d ƒ ‚ d  S(   Ni    s   precondition for m1 failed(   t   AssertionError(   R   R   (    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyt   m1_preh   s    c         S   s   | | k s t  ‚ d  S(   N(   R   (   R   R   R   (    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyt   m1_postj   s    (   R   R   R   R   R    (    (    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyR   e   s   		i   (   R   R   (   R   t   x(    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyt   _testd   s    	t   __main__N(    (   t   __doc__t   MetaR    R   R   R   R   R   R   R"   R   (    (    (    s/   /usr/lib64/python2.7/Demo/metaclasses/Eiffel.pyt   <module>>   s   	