PyContracts public API reference

This section provides a reference to PyContracts’ public interface.

Decorating a function

contracts.contract(*args, **kwargs)[source]

Decorator for adding contracts to functions.

It is smart enough to support functions with variable number of arguments and keyword arguments.

There are three ways to specify the contracts. In order of precedence:

  • As arguments to this decorator. For example:

    @contract(a='int,>0',b='list[N],N>0',returns='list[N]')
    def my_function(a, b):
        # ...
        pass
    
  • As annotations (supported only in Python 3):

    @contract
    def my_function(a:'int,>0', b:'list[N],N>0') -> 'list[N]':
        # ...
        pass
    
  • Using :type: and :rtype: tags in the function’s docstring:

    @contract
    def my_function(a, b):
    
contracts.decorate(function_, modify_docstring=True, **kwargs)

An explicit way to decorate a given function. The decorator decorate() calls this function internally.

Enabling/disabling

contracts.disable_all()[source]

Disables all contracts checks.

Exceptions

class contracts.ContractException[source]

The base class for the exceptions thrown by this module.

class contracts.ContractSyntaxError(error, where=None)[source]

Exception thrown when there is a syntax error in the contracts.

class contracts.ContractNotRespected(contract, error, value, context)[source]

Exception thrown when a value does not respect a contract.

Manually checking values

contracts.check(contract, object, desc=None, **context)[source]

Checks that object satisfies the contract described by contract.

Parameters:
  • contract (str) – The contract string.
  • object (*) – Any object.
  • desc (None|str) – An optional description of the error. If given, it is included in the error message.
contracts.check_multiple(couples, desc=None)[source]

Checks multiple couples of (contract, value) in the same context.

This means that the variables in each contract are shared with the others.

Parameters:
  • couples (list[>0](tuple(str, *))) – A list of tuple (contract, value) to check.
  • desc (None|str) – An optional description of the error. If given, it is included in the error message.
contracts.parse(spec)

spec can be either a Contract, a type, or a contract string. In the latter case, the usual parsing takes place

contracts.new_contract(*args)[source]

Defines a new contract type. Used both as a decorator and as a function.

1) Use as a function. The first parameter must be a string. The second parameter can be either a string or a callable function.

new_contract('new_contract_name', 'list[N]')
new_contract('new_contract_name', lambda x: isinstance(x, list) )
  • If it is a string, it is interpreted as contract expression; the given identifier will become an alias for that expression.

  • If it is a callable, it must accept one parameter, and either:

    • return True or None, to signify it accepts.
    • return False or raise ValueError or AssertionError, to signify it doesn’t.

    If ValueError is raised, its message is used in the error.

2) Use as a decorator.

Or, it can be used as a decorator (without arguments). The function name is used as the identifier.

@new_contract
def new_contract_name(x):
    return isinstance(x, list)

This function returns a Contract object. It might be useful to check right away if the declaration is what you meant, using Contract.check() and Contract.fail().

Parameters:
  • identifier (str) – The identifier must be a string not already in use (you cannot redefine list, tuple, etc.).
  • condition (type|callable|str) – Definition of the new contract.
Returns:

The equivalent contract – might be useful for debugging.

Return type:

Contract

class contracts.Contract(where)[source]
check(value)[source]

Checks that the value satisfies this contract.

Raise:ContractNotRespected
fail(value)[source]

Checks that the value does not respect this contract. Raises an exception if it does.

Raise:ValueError
__repr__()[source]

Returns a string representation of a contract that can be evaluated by Python’s eval().

It must hold that: eval(contract.__repr__()) == contract. This is checked in the unit-tests.

Example:

>>> from contracts import parse
>>> contract = parse('list[N]')
>>> contract.__repr__()
"List(BindVariable('N',int),None)"

All the symbols you need to eval() the expression are in contracts.library.

>>> from contracts.library import *
>>> contract == eval("%r"%contract)
True
__str__()[source]

Returns a string representation of a contract that can be reparsed by contracts.parse().

It must hold that: parse(str(contract)) == contract. This is checked in the unit-tests.

Example:

>>> from contracts import parse
>>> spec = 'list[N]'
>>> contract = parse(spec)
>>> contract
List(BindVariable('N',int),None)
>>> str(contract) == spec
True

The expressions generated by Contract.__str__() will be exactly the same as what was parsed (this is checked in the unittests as well) if and only if the expression is “minimal”. If it isn’t (there is whitespace or redundant symbols), the returned expression will be an equivalent minimal one.

Example with extra parenthesis and whitespace:

>>> from contracts import parse
>>> verbose_spec = 'list[((N))]( int, > 0)'
>>> contract = parse(verbose_spec)
>>> str(contract)
'list[N](int,>0)'

Example that removes extra parentheses around arithmetic operators:

>>> verbose_spec = '=1+(1*2)+(2+4)'
>>> str(parse(verbose_spec))
'=1+1*2+2+4'

This is an example with logical operators precedence. The AND operator , (comma) has more precedence than the OR (|).

>>> verbose_spec = '(a|(b,c)),e'
>>> str(parse(verbose_spec))
'(a|b,c),e'

Not that only the outer parenthesis is kept as it is the only one needed.

Miscellaneous

contracts.contract_expression

A PyParsing expression that can be used to include contracts expression in your own PyParsing grammar.