Package: pyadbc
===============================pyadbc===============================.. image:: https://badge.fury.io/py/pyadbc.png:target: http://badge.fury.io/py/pyadbc.. image:: https://travis-ci.org/tarmstrong/pyadbc.png?branch=master:target: https://travis-ci.org/tarmstrong/pyadbc.. image:: https://pypip.in/d/pyadbc/badge.png:target: https://crate.io/packages/pyadbc?version=latestPyADBC: Design by Contract in PythonPyADBC provides pure python support for `Design byContract <https://en.wikipedia.org/wiki/Design_by_contract>`__.Invariants, pre- and post-conditions are added using decorators.* Free software: BSD licenseUsage-----Invariants~~~~~~~~~~To define an invariant on a class (a condition that always holds afterthe object is instantiated), use the ``@invariant`` decorator. The``self`` passed into the passed lambda is the same ``self`` that wouldbe passed to a method.::@invariant(lambda self: self.capacity >= 0)class List(object):# ...Preconditions~~~~~~~~~~~~~Preconditions can be specified with ``@requires``. These are propertiesthat must evaluate to ``True`` *before* the method is run.::@requires(lambda self: self.size() < self.capacity)def append(self, bla):self._size += 1self.things.append(bla)Postconditions~~~~~~~~~~~~~~Postconditions can be specified with ``@ensures``:::@ensures(lambda self: self.size() == len(self.things))def append(self, bla):self._size += 1self.things.append(bla)These are properties that must evaluate to ``True`` *after* the methodhas run.``@old`` for before/after comparisons~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~In order to compare properties of the object before and after anoperation, PyADBC provides the ``@old`` decorator. You can use it to"cache" values for use in the postcondition.For example, the following method's postcondition guarantees that the``x`` instance attribute is increased by one. Dictionaries returned inthe functions passed to ``@old`` will be merged and passed as a secondargument to the postcondition functions.::@ensures(lambda self, old: old['x'] + 1 == self.x,lambda self, old: old['size'] < 0)@old(lambda self: {'x': self.x, 'size': self._size})def doThing(self):self.x -= 1Exceptions~~~~~~~~~~If any conditions defined by the above decorators evaluate to ``False``,one of the following exceptions will be raised based on what kind ofcondition it is:-  ``PreconditionFailedException``, which implies that the client of theclass failed to satisfy the class's contract.-  ``PostconditionFailedException``, which implies that the objectitself failed to satisfy its class's contract.-  ``InvariantFailedException``, which implies that the object hasentered an illegal state.``@dbcinherit`` for inheriting classes~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~An important feature of DBC is that it can validate the `LiskovSubstitutionPrinciple <https://en.wikipedia.org/wiki/Liskov_substitution_principle>`__.That is, if a child class ``CoolList`` inherits from the base class``List``, its operations should satsify ``List``'s contracts. This givessome assurance that the principle holds for the child class.To do this with PyADBC, you need to explicitly decorate the child class,e.g.:::@dbcinheritclass CoolList(List):# ...If ``CoolList`` overrides the ``append()`` method, the contract of``List``'s ``append()`` method will be applied to ``CoolList``'s``append()``.This also currently works with multiple inheritance.Other solutions----------------  `PyDBC <http://www.nongnu.org/pydbc/>`__, which uses a metaclass.-  `pycontract <http://www.wayforward.net/pycontract/>`__, which usesdocstrings. See the Python Enhancement Proposal (PEP) that referencesthis implementation`here <http://www.python.org/dev/peps/pep-0316/>`__.Contributing------------See ``TODO.md`` for missing features. Suggestions and bug reports arealways welcome.Acknowledgements----------------Thanks to-  Prof. Constantinos Constantinides, for his feedback regarding Liskovand for teaching me about DBC in the first placeHistory-------0.1.0 (2013-08-11)++++++++++++++++++* First release on PyPI.