Source code for contracts.library.tuple

from ..interface import Contract, ContractNotRespected
from ..syntax import(add_contract, W, contract_expression, O, S, ZeroOrMore,
                      Group, add_keyword, Keyword)
from .compositions import or_contract


[docs]class Tuple(Contract): def __init__(self, length=None, elements=None, where=None): Contract.__init__(self, where) self.length = length self.elements = elements assert elements is None or isinstance(elements, list) if elements: for e in elements: assert isinstance(e, Contract)
[docs] def check_contract(self, context, value, silent): if not isinstance(value, tuple): error = 'Expected a tuple, got %r.' % value.__class__.__name__ raise ContractNotRespected(contract=self, error=error, value=value, context=context) if self.length is not None: self.length._check_contract(context, len(value), silent) if self.elements is not None: if len(value) != len(self.elements): error = ('Expected a tuple of length ' '%s, got %r of length %s.' % (len(self.elements), value, len(value))) raise ContractNotRespected(contract=self, error=error, value=value, context=context) for i in range(len(value)): self.elements[i]._check_contract(context, value[i], silent)
def __repr__(self): return 'Tuple(%r,%r)' % (self.length, self.elements) def __str__(self): s = 'tuple' if self.length is not None: s += '[%s]' % self.length def rep(x): from .compositions import And if isinstance(x, And): return "(%s)" % x else: return "%s" % x if self.elements is not None: s += '(%s)' % ",".join(rep(x) for x in self.elements) return s
[docs] @staticmethod def parse_action(s, loc, tokens): where = W(s, loc) length = tokens.get('length', [None])[0] # elements = tokens.get('elements', [None])[0] if 'elements' in tokens: elements = list(tokens['elements']) else: elements = None assert elements is None or length is None assert length is None or isinstance(length, Contract), ("Wrong type %r" % length) if elements: for e in elements: assert isinstance(e, Contract), ("Wrong type %s (%r)" % (type(e), e)) return Tuple(length, elements, where=where)
# if you use contract instead of simple_contract, it will be matched as And inside = (S('(') - contract_expression - S(')')) | or_contract inside.setName('Any contract for tuple elements (use parenthesis for AND)') elements = (Group(S('(') - inside - ZeroOrMore(S(',') - inside) - S(')'))('elements')) elements.setName('Tuple elements contract.') length = Group(S('[') - contract_expression - S(']'))('length') length.setName('Tuple length contract.') tuple_contract = Keyword('tuple') - O(length | elements) tuple_contract.setName('tuple contract') add_contract(tuple_contract.setParseAction(Tuple.parse_action)) add_keyword('tuple')