Friday 11 November 2011

python-dbc - Design-By-Contract features for Python - Google Project Hosting

Summary

This project enables to use the basics of Design by Contract capabilities in Python, such as enforcing the contracts defined in the epydoc documentation. At the moment, it is highly work-in-progress, so you are not expected to use it successfully: but have a look and maybe assist me in getting it done!

Download

To checkout the project repository (assuming that you have Mercurial client installed), use the following command:

hg clone https://python-dbc.googlecode.com/hg/ python-dbc

Requirements

For the most important functionality of this module, you must have epydoc installed. Please refer to epydoc site or your Unix/Linux distribution regarding the installation details.

Though, you may use the more general helper functions like typed(), ntyped() or consists_of() from the module without using epydoc, if you just need to perform some simple type assertions.

Usage

Are you tired of declaring the same assertions twice, first in the epydoc declaration, then in the code?

def hypo(leg_a, leg_b):    """    @precondition: leg_a > 0    @precondition: leg_b > 0    @type leg_a: (int, float)    @type leg_b: (int, float)    @rtype: float    @postcondition: result > 0    """    assert leg_a > 0    assert leg_b > 0    assert isinstance(leg_a, (int, float))    assert isinstance(leg_b, (int, float))    result = math.sqrt(leg_a**2 + leg_b**2)    assert isinstance(result, float)    assert result > 0    return result

Don't waste the code anymore. Just do this instead:

from dbc import contract_epydoc@contract_epydocdef hypo(leg_a, leg_b):    """    @precondition: leg_a > 0    @precondition: leg_b > 0    @type leg_a: (int, float)    @type leg_b: (int, float)    @rtype: float    @postcondition: result > 0    """    return math.sqrt(leg_a**2 + leg_b**2)

And all the assumptions and assertions defined in the epydoc docstring for the function are automagically checked whenever the function is called!

Note that having to verify all the incomes and outcomes may significantly decrease the performance; therefore, these verifications (similarly to the only DbC-related Python builtin assert function) are completely disabled if the code is executed with optimization, i.e. via python -O or python -OO. The only runtime overhead from this module in optimized mode is calling the decorator itself once during the very first code interpretation pass.

Notes

Don't do this:

  @contract_epydoc  @staticmethod  def some_method(...

or

  @contract_epydoc  @classmethod  def some_method(cls, ...

Classmethods and staticmethods are not the proper functions, but the objects of special kind, so the function arguments cannot be checked for them.

Do this instead:

  @staticmethod  @contract_epydoc  def some_method(...

or

  @classmethod  @contract_epydoc  def some_method(cls, ...

Disclaimer

This code is highly experimental yet, hence no releases are yet available.

The code assumed to be working rather well with normal methods and functions; assumed to be non-working (yet, but maybe never) with the static and class methods; and may have (though may not have) difficulties with various nested functions, contract definitions using the variables from various nesting levels, and other complex cases.

Feel free to send me comments and (maybe) patches via amyodov@gmail.com.

Posted via email from kwhitefoot's posterous

No comments:

Post a Comment

Followers