Source code for contracts.library.variables

from ..interface import Contract, ContractNotRespected, RValue, describe_value
from ..syntax import (W, oneOf, FollowedBy, NotAny)

[docs]class BindVariable(Contract): def __init__(self, variable, allowed_types, where=None): assert isinstance(variable, str) and len(variable) == 1 assert allowed_types, '%r' % allowed_types Contract.__init__(self, where) self.variable = variable self.allowed_types = allowed_types
[docs] def check_contract(self, context, value, silent): if self.variable in context: expected = context[self.variable] if not (expected == value): # TODO: add where it was bound error = ( 'Expected value for %r was: %s\n' ' instead I received: %s' % (self.variable, describe_value(expected), describe_value(value))) raise ContractNotRespected(contract=self, error=error, value=value, context=context) else: # bound variable if not isinstance(value, self.allowed_types): error = ('Variable %r can only bind to %r, not %r.' % (self.variable, self.allowed_types, value.__class__.__name__)) raise ContractNotRespected(self, error, value, context) context[self.variable] = value
def __str__(self): return self.variable def __repr__(self): # XXX: invalid if tuple return 'BindVariable(%r,%s)' % (self.variable, self.allowed_types.__name__)
[docs] @staticmethod def parse_action(allowed_types): def parse(s, loc, tokens): where = W(s, loc) variable = tokens[0] assert len(variable) == 1, \ ('Wrong syntax, matched %r as variable in %r.' % (variable, s)) # print ('Matched %r as variable in %r.' % (variable, s)) return BindVariable(variable, allowed_types, where=where) return parse
[docs]class VariableRef(RValue): def __init__(self, variable, where=None): assert isinstance(variable, str) self.where = where self.variable = variable
[docs] def eval(self, context): # @ReservedAssignment var = self.variable if not var in context: raise ValueError('Unknown variable %r.' % var) return context[var]
def __repr__(self): return "VariableRef(%r)" % self.variable def __str__(self): return "%s" % self.variable
[docs] @staticmethod def parse_action(s, loc, tokens): where = W(s, loc) return VariableRef(tokens[0], where=where)
alphabetu = 'A B C D E F G H I J K L M N O P Q R S T U W V X Y Z ' alphabetl = 'a b c d e f g h i j k l m n o p q r s t u w v x y z ' # Special case: allow an expression like AxBxC nofollow = 'a b c d e f g h i j k l m n o p q r s t u w v y z' # also do not commit if part of word (SEn, a_2) nofollow += ' A B C D E F G H I J K L M N O P Q R S T U W V X Y Z ' nofollow += ' 0 1 2 3 4 5 6 7 8 9 _' # but recall 'axis_angle' int_variables = (oneOf(alphabetu.split()) + FollowedBy(NotAny(oneOf(nofollow.split())))) misc_variables = (oneOf(alphabetl.split()) + FollowedBy(NotAny(oneOf(nofollow.split() + ['x'])))) int_variables_ref = int_variables.copy().setParseAction( VariableRef.parse_action) misc_variables_ref = misc_variables.copy().setParseAction( VariableRef.parse_action) #int_variables = oneOf(alphabetu.split()) + FollowedBy(White() ^ 'x') # These must be followed by whitespace; punctuation #misc_variables = oneOf(alphabet.lower()) + FollowedBy(White()) nofollow = 'a b c d e f g h i j k l m n o p q r s t u w v y z ' nofollow += ' * - + / ' nofollow += ' A B C D E F G H I J K L M N O P Q R S T U W V X Y Z ' nofollow += ' 0 1 2 3 4 5 6 7 8 9 _' int_variables2 = (oneOf(alphabetu.split()) + FollowedBy(NotAny(oneOf(nofollow.split())))) misc_variables2 = (oneOf(alphabetl.split()) + FollowedBy(NotAny(oneOf(nofollow.split() + ['x'])))) int_variables_contract = int_variables2.setParseAction( BindVariable.parse_action(int)) misc_variables_contract = misc_variables2.setParseAction( BindVariable.parse_action(object))