Contract based programming (Python)
github.com
github.com
The lambdas are how you specify the constraints. How does operator module help here?
@ensure_args(a=lambda x: x > 10 and x < 100)
def foo(a):
pass
Here, the constraint is `a` should be greater than 10 and less than 100. Where does operator module comes in here?And the first example is using multiple lambdas to show the multiple use cases:
1. `a=lambda x: x > 10` is for the positional argument `a`.
2. `b=r'^?-\d+(\.\d+)$'` is to show if you need the arg to match a regex, you can directly pass it.
3. c=lambda x: x < 5) # `c` will be picked from `kwargs`.
And here, the comment clarifies that c isn't there in the positional args. But since arguments are looked for in both kwargs and positional args, this constraint will work.
@transform_args(a=lambda x: x*x)
def foo(a):
pass
This isn't validation and can't be turned off. The idea behind the project was the function should concentrate on logic and validations should happen declaratively. If the `verifyObject` sort of call comes inside the function, it impacts the declarative goal.The current validators throw Exception by default. They can be optionally take an `error_handler` to which they pass the errors. Bringing in inside the function will mean manually accumulating the errors from various validators.
Also, these validators are mostly for conditions which must be met. Say you are writing a sqrt function, then the pre-condition is the number shouldn't be negative and that isn't something that can be turned off.
I don't know how zope.interface works but this isn't supposed to be optional validation. It is basically about taking the manual checks from inside the function to above the function with convenient declarative syntax.
There also are a few modules out there that implement design-by-contract's pre-/post-conditions for class instances, for example http://code.activestate.com/recipes/436834/