PEP new assert idiom
Fábio Mendes
niels_bohr at uol.com.br
Sun Nov 7 00:44:50 EST 2004
> Some time ago I found myself proposing a new "Validate" statement,
> which would work exactly like "assert", except:
>
> 1) it would throw a ValidationError instead of AssertionError
> if the condition failed
>
> 2) it would NOT be turned into a no-op by the optimizing compiler.
>
[...]
This sounds great. I like the validate syntax. This also sounds very
useful to me. If it doesn't go mainstream, it should, at least be a
parameter controlled at runtime:
>>> import validate
>>> validate.always_compile_assertions = True # this name sucks! I know!
Ideally, for me, python would support a decent DPC-like semantics:
>>> class foo_bar:
>>> contract, 'invariant':
>>> assert (something always true), 'Errormsg1'
>>> assert (more imutable truths), 'Errormsg2'
>>>
>>> def foo(self, var1, var2):
>>> contract, 'pre':
>>> # var1 and var2 are avaiable in this scope
>>> assert expr, 'Error string1'
>>> assert expr1, expr2, 'Error string2'
>>>
>>> contract, 'pos':
>>> # var1, var2, avaiable. 'old' is 'self' before calling foo
>>> # foo.return stands for the output of function foo (or None)
>>> # foo.error is any the exception the function had trown
>>> assert self.bar > old.bar
>>> assert foo == some result, 'Error string'
>>> if foo.error == some Exception:
>>> assert (condition to trow that exception), 'Error'
>>>
>>> (function implementation)
The (python) implementation of this syntax can be something like this.
If dbc is enable, foo method becames:
>>> def foo(self, var1, var2):
>>> try:
>>> contract invariant block
>>> ...
>>> except AssertionError, x:
>>> contractViolations.log('invariant', x)
>>>
>>> try:
>>> pre contract block
>>> ...
>>> except AssertionError, x:
>>> contractViolations.log('pre', x)
>>> try:
>>> foo.value = __old_foo(var1, var2)
>>> finally error, error_msg:
>>> if error: foo.value = None
>>> foo.error = error
>>> try:
>>> post contract block
>>> except AssertionError, x:
>>> contractViolations.log('pos', x)
>>> if error and not contract.fail_silently:
>>> raise error, error_msg
The program executes normally, then, if non fatal errors happens,
contracViolations.report() will print a nice formated report of what was
violated, similar to what unittest module does. This is not pure DBC I
guess, but is nice.
Thanks,
Fabio
More information about the Python-list
mailing list