[pypy-svn] r40934 - in pypy/dist: demo pypy/lib
afayolle at codespeak.net
afayolle at codespeak.net
Wed Mar 21 15:09:31 CET 2007
Author: afayolle
Date: Wed Mar 21 15:09:30 2007
New Revision: 40934
Added:
pypy/dist/demo/contract_stack.py (contents, props changed)
pypy/dist/demo/contracts.py (contents, props changed)
pypy/dist/pypy/lib/dbc.py (contents, props changed)
Log:
simple design by contract module built on top of aop.py, and demo
Added: pypy/dist/demo/contract_stack.py
==============================================================================
--- (empty file)
+++ pypy/dist/demo/contract_stack.py Wed Mar 21 15:09:30 2007
@@ -0,0 +1,50 @@
+
+class Stack:
+ """A very simple stack interface
+ (not very useful in Python)
+ """
+
+ def __init__(self, max_size = 10):
+ self.max_size = max_size
+ self.elements = []
+
+ def _pre_pop(self):
+ return not self.is_empty()
+ def _post_pop(self, old, ret):
+ return ret == old.top() and \
+ self.size() == old.size() - 1
+ def pop(self):
+ return self.elements.pop()
+
+
+ def _pre_push(self, obj):
+ return obj is not None and not self.is_full()
+ def _post_push(self, old, ret, obj):
+ return not self.is_empty() and (self.top() == obj)
+ def push(self, obj):
+ self.elements.append(obj)
+
+
+ def top(self):
+ """Returns the top element of the stack
+ """
+ return self.elements[-1]
+
+ def is_empty(self):
+ """Tells whether or not the stack is empty
+ """
+ return not bool(self.elements)
+
+
+ def is_full(self):
+ """Tells whether or not the stack is full
+ """
+ return len(self.elements) == self.max_size
+
+ def size(self):
+ """Returns the current size of the stack
+ """
+ return len(self.elements)
+
+ def __str__(self):
+ return "elements = %s, max_size = %s" % (self.elements, self.max_size)
Added: pypy/dist/demo/contracts.py
==============================================================================
--- (empty file)
+++ pypy/dist/demo/contracts.py Wed Mar 21 15:09:30 2007
@@ -0,0 +1,41 @@
+from dbc import ContractAspect, ContractError
+ContractAspect()
+from contract_stack import Stack
+
+def run():
+ """This is an example of how contracts work
+ """
+ print "*"*30
+ print "Creating an empty stack (max_size = 3)"
+ stack = Stack(3)
+
+ try:
+ print "Empty stack, pop() should fail"
+ stack.pop()
+ except ContractError, excpt:
+ print "\t failed with %s, (OK)" % excpt
+ else:
+ print "\t did not failed, (XXX)"
+
+ print "\n\n\n"
+ stack.push(1)
+ print "push 1 done"
+ stack.push(2)
+ print "push 2 done"
+ stack.push(3)
+ print "push 3 done"
+
+ try:
+ print "The stack is full, push() should fail"
+ stack.push(4)
+ except ContractError, excpt:
+ print "\t failed with %s, (OK)" % excpt
+ else:
+ print "\t did not failed, (XXX)"
+
+ print "\n\n\n"
+
+
+
+if __name__ == '__main__':
+ run()
Added: pypy/dist/pypy/lib/dbc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/dbc.py Wed Mar 21 15:09:30 2007
@@ -0,0 +1,42 @@
+__all__ = ['ContractAspect', 'ContractError', 'PreconditionError', 'PostConditionError']
+from aop import *
+from copy import deepcopy
+class ContractAspect:
+ __metaclass__ = Aspect
+ def __init__(self):
+ self.initial_state = {}
+
+ @around(PointCut(func='[^_].*', klass='.+').execution())
+ def contract_check(self, tjp):
+ target = tjp.target()
+ args, kwargs = tjp.arguments()
+ try:
+ prefunc = getattr(target, '_pre_%s' % tjp.name())
+ except AttributeError:
+ prefunc = None
+ try:
+ postfunc = getattr(target, '_post_%s' % tjp.name())
+ except AttributeError:
+ postfunc = None
+ else:
+ oldtarget = deepcopy(target)
+
+ if prefunc is not None:
+ status = prefunc(*args, **kwargs)
+ if not status:
+ raise PreconditionError(tjp.name())
+ tjp.proceed(target, *args, **kwargs)
+ if postfunc is not None:
+ if not postfunc(oldtarget, tjp.result(), *args, **kwargs):
+ raise PostconditionError(tjp.name())
+ return tjp.result()
+
+
+class ContractError(StandardError):
+ pass
+
+class PreconditionError(ContractError):
+ pass
+
+class PostconditionError(ContractError):
+ pass
More information about the Pypy-commit
mailing list