Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tools for defensive programming #5

Open
dag opened this issue Aug 4, 2011 · 2 comments
Open

Tools for defensive programming #5

dag opened this issue Aug 4, 2011 · 2 comments

Comments

@dag
Copy link
Owner

dag commented Aug 4, 2011

Embed constraints in code, that can be disabled in production for performance and fault-tolerance, but helpful in development / automated testing. Python supports this via the assert statement, which is stripped out if Python runs with optimizations (__debug__ is false), but assertions are rather low-level. A support package could provide tools for adding type constraints, design-by-contract etc, in a more high-level fashion than simple assertions. Python also strips out branches for code like if __debug__ when optimized which could allow constraints added via for example decorators to only have a slight overhead at "construction time", that is, usually only once on the first import.

Contracts with magical abuse of frames:

def double(x):
    return x * 2

@pre
def double(x):
    assert isinstance(x, numbers.Number)

@post
def double(r, x):
    assert isinstance(r, numbers.Number)
    assert r > x

Or using decorator arguments:

@accepts(x=numbers.Number)
@returns(numbers.Number, x=operator.gt)
def double(x):
    return x * 2

Annotations:

@constrained
def double(x: numbers.Number) -> numbers.Number, dict(x=operator.gt):
    return x * 2

Constrained attributes using descriptors:

class Person(object):

    name = Attribute(basestring)

When running with optimizations it could simply return None.

@dag
Copy link
Owner Author

dag commented Aug 5, 2011

Guido had an idea of using the function bodies in interfaces as design contract preconditions.

@dag
Copy link
Owner Author

dag commented Aug 5, 2011

As for postconditions, perhaps using generator.send()?

def double(x: Number) -> Number:
    assert x != 0
    res = yield
    assert res > x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant