Trees | Indices | Help |
|
---|
|
Programming-by-contract for Python, based on Eiffel's DBC.
Programming by contract documents class and modules with invariants, expressions that must be true during the lifetime of a module or instance; and documents functions and methods with pre- and post- conditions that must be true during entry and return.
Copyright (c) 2003, Terence Way This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form.
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.Version: 1.1: October 19, 2005
Author: Terence Way
|
|||
Done | |||
tokenizer | |||
ContractViolationError | |||
PreconditionViolationError | |||
PostconditionViolationError | |||
InvariantViolationError | |||
InvalidPreconditionError Method pre-conditions can only weaken overridden methods' preconditions. |
|||
_holder Placeholder for arbitrary 'old' values. |
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|
|||
__email__ =
|
|||
MODULE =
|
|||
INV =
|
|||
PRE =
|
|||
POST =
|
|||
TYPE_CONTRACTS =
|
|||
CODE_CONTRACTS =
|
|||
OLD =
|
|||
RETURN =
|
|||
PREFIX =
|
|||
_ORIG =
|
|||
_SAVE =
|
|||
_CHK =
|
|||
_CONTRACTS =
|
|||
_re_start = re.compile(r'
|
|||
_RE_KEYWORD = 1
|
|||
_OPS =
|
|||
_EXCEPTIONS =
|
|||
__test__ = {'_ispublic': _ispublic, '_get_members': _get_membe
|
|||
CHECK_ALL = 3
|
|||
CHECK_DEFAULT = 0
|
|||
CHECK_NONE = 1
|
|||
CHECK_PRECONDITIONS = 2
|
|||
CO_VARARGS = 4
|
|||
CO_VARKEYWORDS = 8
|
|||
False = False
|
|||
True = True
|
|
Add invariant, pre- and post-condition checking to a module. pre:isstring(module) or isinstance(module, ModuleType) checklevel in [CHECK_DEFAULT, CHECK_NONE, CHECK_PRECONDITIONS, CHECK_ALL] |
Modify a class to add invariant checking. pre:isstring(code[0]) type(code[1]) == code[2] isinstance(code[0], MethodType) or isinstance(code[0], FunctionType) isinstance(path[0], ModuleType) forall(path[1:], isclass) |
Get function location as tuple (name, filename, lineno). pre:isinstance(f, MethodType) or isinstance(f, FunctionType)post[]: isstring(__return__[0]) isstring(__return__[1]) isinstance(__return__[2], int) |
Returns two lists (procs, types) where each list contains (name, value) tuples. For classes, only attributes defined by the specific class are returned, i.e. not inherited attributes. Attributes created by this module (prefixed by '__assert_') are skipped as well. Examples: >>> import contract >>> path = [contract] >>> hasattr(contract, '_re_start') 1 >>> '_re_start' in [x[0] for x in _get_members(contract, path)[0]] 0 >>> '_get_members' in [x[0] for x in _get_members(contract, path)[0]] 1 >>> 'checkmod' in [x[0] for x in _get_members(contract, path)[0]] 1 >>> class base: ... def foo(self): pass >>> class derived(base): ... def bar(self): pass hasattr can get inherited attributes: >>> hasattr(derived, 'foo') 1 but we don't: >>> path = [__import__('__main__')] >>> 'foo' in [x[0] for x in _get_members(derived, path)[0]] 0 |
Checks if a name is public (starts and ends with '__' or doesn't start with a _ at all). Examples: >>> _ispublic('__init__') 1 >>> _ispublic('foo') 1 >>> _ispublic('_ispublic') 0 |
Parse a docstring, looking for design-by-contract expressions. Returns a list of tuples: the list is the same length as keywords, and matches each keyword. The tuple is (keyword, [decls], [exprs]), namely the keyword, a list of string declarations, and a list of tuples (string, lineno). Examples:: >>> from pprint import pprint >>> pprint( parse_docstring(parse_docstring.__doc__, ['post', 'pre']) ) [('post', [], [('[ x [ 0 ] for x in __return__ ] == keywords', 22)]), ('pre', [], [('docstring is None or isstring ( docstring )', 18), ('forall ( keywords , isstring )', 19)])] pre:: docstring is None or isstring(docstring) forall(keywords, isstring) post[]:: [x[0] for x in __return__] == keywords |
Read an indented block of expressions startlineno is *zero* origined line number. pre:input.readline # must have readline function Examples: #>>> _read_block(StringIO('\tfoo:\n'), 0) #0 >>> _read_block(StringIO('\tpost[]: True\n'), 0) ('post', [], [('True', 1)], 1) >>> _read_block(StringIO('\tpre: 5 + 6 > 10\n'), 0) ('pre', [], [('5 + 6 > 10', 1)], 1) >>> _read_block(StringIO('\tpost:\n\t\t5 + 6 < 12\n\t\t2 + 2 == 4\n'), 0) ('post', [], [('5 + 6 < 12', 2), ('2 + 2 == 4', 3)], 3) >>> _read_block(StringIO('\tpost[foo.bar]: # changes\n' \ ... '\t\tlen(foo.bar) > 0\n'), 0) ('post', [['foo', 'bar']], [('len ( foo . bar ) > 0', 2)], 2) Handles double colons (for re-structured text):: >>> _read_block(StringIO('\tpre:: 5 + 6 > 10\n'), 0) ('pre', [], [('5 + 6 > 10', 1)], 1) |
Creates and installs a function/method checker. pre:contracts[0][0] == PRE and contracts[1][0] == POST isinstance(path[0], ModuleType) forall(path[1:], isclass) |
Define a function that does contract assertion checking. args is a string argument declaration (ex: 'a, b, c = 1, *va, **ka') contract is an element of the contracts list returned by parse_docstring module is the containing module (not parent class) Returns the newly-defined function. pre:isstring(name) isstring(args) contract[0] in _CONTRACTS len(contract[2]) > 0post: isinstance(__return__, FunctionType) __return__.__name__ == name |
Create a function that saves values into an __old__ variable. pre:: decls post:: isinstance(__return__, FunctionType) |
Formats an argument desc into a string suitable for both a function/ method declaration or a function call. This does *not* handle default arguments. Default arguments are already evaluated... use new.function() to create a function with pre-evaluated default arguments. Examples: >>> def foo(a, (b, c), d = 1, e = 2, *va, **ka): ... pass >>> a = getargspec(foo) >>> a (['a', '(b, c)', 'd', 'e'], 'va', 'ka', (1, 2)) >>> _format_args(a) 'a, (b, c), d, e, *va, **ka' pre:isinstance(arguments, list) rest is None or isstring(rest) keywords is None or isstring(keywords)post[]:: True |
>>> _format_arg(['a', 'b', 'c']) '(a, b, c)' >>> _format_arg(['a', ['b', 'c', 'd']]) '(a, (b, c, d))' >>> _format_arg(['a']) '(a,)' >>> _format_arg('a') 'a' |
Get argument information about a function. Returns a tuple (args, varargs, keywordvarargs, defaults) where args is a list of strings, varargs is None or the name of the *va argument, keywordvarargs is None or the name of the **ka argument, and defaults is a list of default values. This function is different from the Python-provided inspect.getargspec in that 1) tuple arguments are returned as a string grouping '(a, b, c)' instead of broken out "['a', 'b', 'c']" and 2) it works in Jython, which doesn't support inspect (yet).>>> getargspec(lambda a, b: a * b) (['a', 'b'], None, None, None) >>> getargspec(lambda a, (b, c, d) = (5, 6, 7), *va, **ka: a * b) (['a', '(b, c, d)'], 'va', 'ka', ((5, 6, 7),))pre: isinstance(function, FunctionType)post[]: # tuple of form (args, va, ka, defaults) isinstance(__return__, TupleType) and len(__return__) == 4 # args is a list of strings isinstance(__return__[0], ListType) forall(__return__[0], isstring) # va is None or a string __return__[1] is None or isstring(__return__[1]) # ka is None or a string __return__[2] is None or isstring(__return__[2]) # defaults is None or a tuple __return__[3] is None or isinstance(__return__[3], TupleType) |
Define a name combining a path and arbitrary strings. pre:isinstance(path[0], ModuleType) forall(path[1:], isclass)Examples: >>> import contract >>> _mkname([contract], 'test') '__assert_test' >>> class foo: ... pass >>> _mkname([contract, foo], 'func', 'pre') '__assert_foo_func_pre' |
Recursively output a dictionary into a set of 'old' assignments. The dictionary d is a tree of variable declarations. So, for example, the declaration [self, self.buf, self.obj.a] would turn into the dict {'self': {'buf': {}, 'obj': {'a': {}}}}, and would get output as __old__.self = contract._holder() __old__.self.buf = copy.copy(self.buf) __old__.self.obj = contract._holder() __old__.self.obj.a = copy.copy(self.obj.a) |
Converts a list of list of names into a hierarchy of dictionaries. Examples: >>> d = _decltodict([['self', 'buf'], ... ['self', 'item', 'a'], ... ['self', 'item', 'b']]) >>> d == {'self': {'buf': {}, 'item': {'a': {}, 'b': {}}}} 1 |
Check the invocation of a public function or static method. Checks module invariants on entry and exit. Checks any pre-conditions and post-conditions. |
Check the invocation of a public function or static method. Checks module invariants on entry. Checks any pre-conditions. |
Check the invocation of a private function or static method. Only checks pre-conditions and post-conditions. |
Check the invocation of a private function or static method. Only checks pre-conditions |
Check the invocation of a public method. Check this class and all super-classes invariants on entry and exit. Checks all post-conditions of this method and all over- ridden method. |
Check the invocation of a public method. Check this class and all super-classes invariants on entry. exit. |
Check the invocation of an __init__ constructor. Checks pre-conditions and post-conditions, and only checks invariants on successful completion. |
Check the invocation of an __init__ constructor. Checks pre-conditions and post-conditions, and only checks invariants on successful completion. |
Check the invocation of a __del__ destructor. Checks pre-conditions and post-conditions, and only checks invariants on entry. |
Check the invocation of a __del__ destructor. Checks pre-conditions and post-conditions, and only checks invariants on entry. |
Check the invocation of a private method call. Checks pre-conditions and post-conditions. |
Check the invocation of a private method call. Checks pre-conditions. |
Checks class invariants on an instance. mro - list of classes in method-resolution order instance - object to test pre:# instance must be an instance of each class in mro forall(mro, lambda x: isinstance(instance, x)) |
Check the invocation of a method. mro -- list/tuple of class objects in method resolution order |
Check the invocation of a method. mro -- list/tuple of class objects in method resolution order |
Test if a class has a named method. pre:isclass(cls) isstring(name)post:: __return__ == (hasattr(cls, name) and isinstance(getattr(cls, name), MethodType)) |
Checks that all elements in a sequence are true. Returns True(1) if all elements are true. Return False(0) otherwise. Examples: >>> forall([True, True, True]) 1 >>> forall( () ) 1 >>> forall([True, True, False, True]) 0 |
Checks that at least one element in a sequence is true. Returns True(1) if at least one element is true. Return False(0) otherwise. Examples: >>> exists([False, False, True]) 1 >>> exists([]) 0 >>> exists([False, 0, '', []]) 0 |
Logical implication. implies(x, y) should be read 'x implies y' or 'if x then y' implies(x, a, b) should be read 'if x then a else b' Examples: >>> implies(False, False) 1 >>> implies(False, True) 1 >>> implies(True, False) 0 >>> implies(True, True) 1 |
|
_EXCEPTIONS
|
__test__
|
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0beta1 on Wed Aug 13 15:25:27 2008 | http://epydoc.sourceforge.net |